Skip to content

Commit 581a92e

Browse files
authored
Support mutual TLS using a certificate from a Windows cert store (#408)
Add the ability to use a client certificate located in a Windows certificate store. Previously, the client certificate and private key had to be passed by filepath or file contents. With this change, certificates and keys stored on TPM devices can be used. Add new `windows_cert_pub_sub` sample to show this in action.
1 parent 43d8d1b commit 581a92e

File tree

5 files changed

+358
-4
lines changed

5 files changed

+358
-4
lines changed

.builder/actions/build_samples.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def run(self, env):
2020
'samples/mqtt/basic_pub_sub',
2121
'samples/mqtt/pkcs11_pub_sub',
2222
'samples/mqtt/raw_pub_sub',
23+
'samples/mqtt/windows_cert_pub_sub',
2324
'samples/shadow/shadow_sync',
2425
'samples/greengrass/basic_discovery',
2526
'samples/identity/fleet_provisioning',

samples/README.md

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
* [Basic MQTT Pub-Sub](#basic-mqtt-pub-sub)
44
* [PKCS#11 MQTT Pub-Sub](#pkcs11-mqtt-pub-sub)
5+
* [Windows Certificate MQTT Pub-Sub](#windows-certificate-mqtt-pub-sub)
56
* [Raw MQTT Pub-Sub](#raw-mqtt-pub-sub)
67
* [Fleet provisioning](#fleet-provisioning)
78
* [Shadow](#shadow)
@@ -121,7 +122,7 @@ but the private key for mutual TLS is stored on a PKCS#11 compatible smart card
121122

122123
WARNING: Unix only. Currently, TLS integration with PKCS#11 is only available on Unix devices.
123124

124-
source: `samples/mqtt/pkcs11_pub_sub/main/cpp`
125+
source: `samples/mqtt/pkcs11_pub_sub/main.cpp`
125126

126127
To run this sample using [SoftHSM2](https://www.opendnssec.org/softhsm/) as the PKCS#11 device:
127128

@@ -144,9 +145,9 @@ To run this sample using [SoftHSM2](https://www.opendnssec.org/softhsm/) as the
144145
145146
If this spits out an error message, create a config file:
146147
* Default location: `~/.config/softhsm2/softhsm2.conf`
147-
* This file must specify token dir, default value is:
148+
* This file must specify a valid token directory:
148149
```
149-
directories.tokendir = /usr/local/var/lib/softhsm/tokens/
150+
directories.tokendir = /path/for/my/softhsm/tokens/
150151
```
151152
152153
4) Create token and import private key.
@@ -167,6 +168,68 @@ To run this sample using [SoftHSM2](https://www.opendnssec.org/softhsm/) as the
167168
./pkcs11-pub-sub --endpoint <xxxx-ats.iot.xxxx.amazonaws.com> --ca_file <AmazonRootCA.pem> --cert <certificate.pem.crt> --pkcs11_lib <libsofthsm2.so> --pin <user-pin> --token_label <token-label> --key_label <key-label>
168169
```
169170
171+
## Windows Certificate MQTT Pub-Sub
172+
173+
WARNING: Windows only
174+
175+
This sample is similar to the [Basic Pub-Sub](#basic-mqtt-pub-sub),
176+
but your certificate and private key are in a
177+
[Windows certificate store](https://docs.microsoft.com/en-us/windows-hardware/drivers/install/certificate-stores),
178+
rather than simply being files on disk.
179+
180+
To run this sample you need the path to your certificate in the store,
181+
which will look something like:
182+
"CurrentUser\MY\A11F8A9B5DF5B98BA3508FBCA575D09570E0D2C6"
183+
(where "CurrentUser\MY" is the store and "A11F8A9B5DF5B98BA3508FBCA575D09570E0D2C6" is the certificate's thumbprint)
184+
185+
If your certificate and private key are in a
186+
[TPM](https://docs.microsoft.com/en-us/windows/security/information-protection/tpm/trusted-platform-module-overview),
187+
you would use them by passing their certificate store path.
188+
189+
source: `samples/mqtt/windows_cert_pub_sub/main.cpp`
190+
191+
To run this sample with a basic certificate from AWS IoT Core:
192+
193+
1) Create an IoT Thing with a certificate and key if you haven't already.
194+
195+
2) Combine the certificate and private key into a single .pfx file.
196+
197+
You will be prompted for a password while creating this file. Remember it for the next step.
198+
199+
If you have OpenSSL installed:
200+
```powershell
201+
openssl pkcs12 -in certificate.pem.crt -inkey private.pem.key -out certificate.pfx
202+
```
203+
204+
Otherwise use [CertUtil](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certutil).
205+
```powershell
206+
certutil -mergePFX certificate.pem.crt,private.pem.key certificate.pfx
207+
```
208+
209+
3) Add the .pfx file to a Windows certificate store using PowerShell's
210+
[Import-PfxCertificate](https://docs.microsoft.com/en-us/powershell/module/pki/import-pfxcertificate)
211+
212+
In this example we're adding it to "CurrentUser\MY"
213+
214+
```powershell
215+
$mypwd = Get-Credential -UserName 'Enter password below' -Message 'Enter password below'
216+
Import-PfxCertificate -FilePath certificate.pfx -CertStoreLocation Cert:\CurrentUser\MY -Password $mypwd.Password
217+
```
218+
219+
Note the certificate thumbprint that is printed out:
220+
```
221+
Thumbprint Subject
222+
---------- -------
223+
A11F8A9B5DF5B98BA3508FBCA575D09570E0D2C6 CN=AWS IoT Certificate
224+
```
225+
226+
So this certificate's path would be: "CurrentUser\MY\A11F8A9B5DF5B98BA3508FBCA575D09570E0D2C6"
227+
228+
4) Now you can run the sample:
229+
230+
```
231+
.\windows-cert-pub-sub.exe --endpoint xxxx-ats.iot.xxxx.amazonaws.com --ca_file AmazonRootCA.pem --cert CurrentUser\My\A11F8A9B5DF5B98BA3508FBCA575D09570E0D2C6
232+
```
170233

171234
## Raw MQTT Pub-Sub
172235

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
cmake_minimum_required(VERSION 3.1)
2+
# note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12
3+
project(windows-cert-pub-sub CXX)
4+
5+
file(GLOB SRC_FILES
6+
"*.cpp"
7+
"../../utils/CommandLineUtils.cpp"
8+
"../../utils/CommandLineUtils.h"
9+
)
10+
11+
add_executable(${PROJECT_NAME} ${SRC_FILES})
12+
13+
set_target_properties(${PROJECT_NAME} PROPERTIES
14+
CXX_STANDARD 14)
15+
16+
# set warnings
17+
if (MSVC)
18+
target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX /wd4068)
19+
else ()
20+
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wno-long-long -pedantic -Werror)
21+
endif ()
22+
23+
find_package(aws-crt-cpp REQUIRED)
24+
25+
target_link_libraries(${PROJECT_NAME} PRIVATE AWS::aws-crt-cpp)

0 commit comments

Comments
 (0)