-
Notifications
You must be signed in to change notification settings - Fork 108
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add PKCS12 sample * Fix CI yaml * Need to compile sample * Fix error due to struct initialization * Is the sample stalling or getting the credentials? * Adjust PKCS12 file paths * Run the sample directly to, hopefully, see sample logs * Try PKCS12 key path a different way * Revert back to PKCS12 CI code from JS * Pipe the output from running the sample to hopefully see why it is stalling in CI but not locally nor in other SDKs * Try adding a timeout to see the output? * Try turning on logs * Print the output on timeout * Use a pipe to get the output? * Output to CRT logs and try to print that file * Try a relative path for the log file? * Does it even hit the executable? Try passing --help to see if that works * Try running directly with logging * Pass the endpoint directly to see if that resolves the endpoint address * Try a hard-coded PKCS12 password to see if it makes a difference * Try relative paths? * Try again * Revert back to how Python does it again * Modified wrong file path * Try getting the PKCS12 key from S3 * use a tmp pkcs12 key file path * test with sudo python3 * update permission * test with logs * update security permision * update key file path * test with sudo * test github action * test github security * fix yml * fix yaml * fix import pkcs12 key path * try access identity from keychain * test identity * test different keychain * try create local pkcs12 file * fix yaml * remove comments * update pkcs12 passworkd * test with identity file * kick ci * clean up the secrets and sample * kick ci * fix file path * clean up commands * improve ci.ym; * remove unnecssary file --------- Co-authored-by: Zhihui Xia <zhvxia@amazon.com>
- Loading branch information
1 parent
e065cff
commit 11855fc
Showing
11 changed files
with
303 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"language": "CPP", | ||
"sample_file": "./aws-iot-device-sdk-cpp-v2/build/samples/mqtt/pkcs12_connect/pkcs12-connect", | ||
"sample_region": "us-east-1", | ||
"sample_main_class": "", | ||
"arguments": [ | ||
{ | ||
"name": "--endpoint", | ||
"secret": "ci/endpoint" | ||
}, | ||
{ | ||
"name": "--pkcs12_file", | ||
"data": "./iot_pkcs12_key.p12" | ||
}, | ||
{ | ||
"name": "--pkcs12_password", | ||
"secret": "ci/PubSub/key_pkcs12_password" | ||
}, | ||
{ | ||
"name": "--verbosity", | ||
"data": "Trace" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
cmake_minimum_required(VERSION 3.1) | ||
# note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 | ||
project(pkcs12-connect CXX) | ||
|
||
file(GLOB SRC_FILES | ||
"*.cpp" | ||
"../../utils/CommandLineUtils.cpp" | ||
"../../utils/CommandLineUtils.h" | ||
) | ||
|
||
add_executable(${PROJECT_NAME} ${SRC_FILES}) | ||
|
||
set_target_properties(${PROJECT_NAME} PROPERTIES | ||
CXX_STANDARD 14) | ||
|
||
#set warnings | ||
if (MSVC) | ||
target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX /wd4068) | ||
else () | ||
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wno-long-long -pedantic -Werror) | ||
endif () | ||
|
||
find_package(aws-crt-cpp REQUIRED) | ||
|
||
target_link_libraries(${PROJECT_NAME} AWS::aws-crt-cpp) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# PKCS12 Connect | ||
|
||
[**Return to main sample list**](../README.md) | ||
|
||
This sample is similar to the [Basic Connect](../basic_connect/README.md) sample, in that it connects via Mutual TLS (mTLS) using a certificate and key file. However, unlike the Basic Connect where the certificate and private key file are stored on disk, this sample uses a PKCS#12 file instead. | ||
|
||
**WARNING: MacOS only**. Currently, TLS integration with PKCS12 is only available on MacOS devices. | ||
|
||
Your IoT Core Thing's [Policy](https://docs.aws.amazon.com/iot/latest/developerguide/iot-policies.html) must provide privileges for this sample to connect. Below is a sample policy that can be used on your IoT Core Thing that will allow this sample to run as intended. | ||
|
||
<details> | ||
<summary>(see sample policy)</summary> | ||
<pre> | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Effect": "Allow", | ||
"Action": [ | ||
"iot:Connect" | ||
], | ||
"Resource": [ | ||
"arn:aws:iot:<b>region</b>:<b>account</b>:client/test-*" | ||
] | ||
} | ||
] | ||
} | ||
</pre> | ||
|
||
Replace with the following with the data from your AWS account: | ||
* `<region>`: The AWS IoT Core region where you created your AWS IoT Core thing you wish to use with this sample. For example `us-east-1`. | ||
* `<account>`: Your AWS IoT Core account ID. This is the set of numbers in the top right next to your AWS account name when using the AWS IoT Core website. | ||
|
||
Note that in a real application, you may want to avoid the use of wildcards in your ClientID or use them selectively. Please follow best practices when working with AWS on production applications using the SDK. Also, for the purposes of this sample, please make sure your policy allows a client ID of `test-*` to connect or use `--client_id <client ID here>` to send the client ID your policy supports. | ||
|
||
</details> | ||
|
||
## How to run | ||
|
||
This sample can be run using the following command: | ||
|
||
```sh | ||
./pkcs12-connect --endpoint <endpoint> --pkcs12_file <path to PKCS12 file> --pkcs12_password <password for PKCS12 file> | ||
``` | ||
|
||
You can also pass a Certificate Authority file (CA) if your certificate and key combination requires it: | ||
|
||
```sh | ||
./pkcs12-connect --endpoint <endpoint> --pkcs12_file <path to PKCS12 file> --pkcs12_password <password for PKCS12 file> --ca_file <path to CA file> | ||
``` | ||
|
||
### How to setup and run | ||
|
||
To use the certificate and key files provided by AWS IoT Core, you will need to convert them into PKCS#12 format and then import them into your Java keystore. You can convert the certificate and key file to PKCS12 using the following command: | ||
|
||
```sh | ||
openssl pkcs12 -export -in <my-certificate.pem.crt> -inkey <my-private-key.pem.key> -out <my-pkcs12-key.pem.key> -name <alias here> -password pass:<password here> | ||
``` | ||
|
||
Once converted, you can then run the PKCS12 connect sample with the following: | ||
|
||
```sh | ||
./pkcs12-connect --endpoint <endpoint> --pkcs12_file <path to PKCS12 file> --pkcs12_password <password for PKCS12 file> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/** | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0. | ||
*/ | ||
#include <aws/crt/Api.h> | ||
#include <aws/crt/UUID.h> | ||
#include <aws/crt/io/Pkcs11.h> | ||
|
||
#include "../../utils/CommandLineUtils.h" | ||
|
||
using namespace Aws::Crt; | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
|
||
/************************ Setup ****************************/ | ||
|
||
// Do the global initialization for the API. | ||
ApiHandle apiHandle; | ||
|
||
/** | ||
* cmdData is the arguments/input from the command line placed into a single struct for | ||
* use in this sample. This handles all of the command line parsing, validating, etc. | ||
* See the Utils/CommandLineUtils for more information. | ||
*/ | ||
Utils::cmdData cmdData = Utils::parseSampleInputPKCS12Connect(argc, argv, &apiHandle); | ||
|
||
// Create the MQTT builder and populate it with data from cmdData. | ||
Aws::Iot::MqttClient client; | ||
struct Aws::Iot::Pkcs12Options options; | ||
options.pkcs12_file = cmdData.input_pkcs12File; | ||
options.pkcs12_password = cmdData.input_pkcs12Password; | ||
Aws::Iot::MqttClientConnectionConfigBuilder clientConfigBuilder(options); | ||
if (!clientConfigBuilder) | ||
{ | ||
fprintf( | ||
stderr, | ||
"MqttClientConnectionConfigBuilder failed: %s\n", | ||
Aws::Crt::ErrorDebugString(Aws::Crt::LastError())); | ||
exit(-1); | ||
} | ||
if (cmdData.input_ca != "") | ||
{ | ||
clientConfigBuilder.WithCertificateAuthority(cmdData.input_ca.c_str()); | ||
} | ||
clientConfigBuilder.WithEndpoint(cmdData.input_endpoint); | ||
|
||
// Create the MQTT connection from the MQTT builder | ||
auto clientConfig = clientConfigBuilder.Build(); | ||
if (!clientConfig) | ||
{ | ||
fprintf( | ||
stderr, | ||
"Client Configuration initialization failed with error %s\n", | ||
Aws::Crt::ErrorDebugString(clientConfig.LastError())); | ||
exit(-1); | ||
} | ||
auto connection = client.NewConnection(clientConfig); | ||
if (!*connection) | ||
{ | ||
fprintf( | ||
stderr, | ||
"MQTT Connection Creation failed with error %s\n", | ||
Aws::Crt::ErrorDebugString(connection->LastError())); | ||
exit(-1); | ||
} | ||
|
||
/** | ||
* In a real world application you probably don't want to enforce synchronous behavior | ||
* but this is a sample console application, so we'll just do that with a condition variable. | ||
*/ | ||
std::promise<bool> connectionCompletedPromise; | ||
std::promise<void> connectionClosedPromise; | ||
|
||
// Invoked when a MQTT connect has completed or failed | ||
auto onConnectionCompleted = | ||
[&](Aws::Crt::Mqtt::MqttConnection &, int errorCode, Aws::Crt::Mqtt::ReturnCode returnCode, bool) { | ||
if (errorCode) | ||
{ | ||
fprintf(stdout, "Connection failed with error %s\n", Aws::Crt::ErrorDebugString(errorCode)); | ||
connectionCompletedPromise.set_value(false); | ||
} | ||
else | ||
{ | ||
fprintf(stdout, "Connection completed with return code %d\n", returnCode); | ||
connectionCompletedPromise.set_value(true); | ||
} | ||
}; | ||
|
||
// Invoked when a MQTT connection was interrupted/lost | ||
auto onInterrupted = [&](Aws::Crt::Mqtt::MqttConnection &, int error) { | ||
fprintf(stdout, "Connection interrupted with error %s\n", Aws::Crt::ErrorDebugString(error)); | ||
}; | ||
|
||
// Invoked when a MQTT connection was interrupted/lost, but then reconnected successfully | ||
auto onResumed = [&](Aws::Crt::Mqtt::MqttConnection &, Aws::Crt::Mqtt::ReturnCode, bool) { | ||
fprintf(stdout, "Connection resumed\n"); | ||
}; | ||
|
||
// Invoked when a disconnect message has completed. | ||
auto onDisconnect = [&](Aws::Crt::Mqtt::MqttConnection &) { | ||
fprintf(stdout, "Disconnect completed\n"); | ||
connectionClosedPromise.set_value(); | ||
}; | ||
|
||
// Assign callbacks | ||
connection->OnConnectionCompleted = std::move(onConnectionCompleted); | ||
connection->OnDisconnect = std::move(onDisconnect); | ||
connection->OnConnectionInterrupted = std::move(onInterrupted); | ||
connection->OnConnectionResumed = std::move(onResumed); | ||
|
||
/************************ Run the sample ****************************/ | ||
|
||
// Connect | ||
fprintf(stdout, "Connecting...\n"); | ||
if (!connection->Connect(cmdData.input_clientId.c_str(), false /*cleanSession*/, 1000 /*keepAliveTimeSecs*/)) | ||
{ | ||
fprintf(stderr, "MQTT Connection failed with error %s\n", Aws::Crt::ErrorDebugString(connection->LastError())); | ||
exit(-1); | ||
} | ||
|
||
// wait for the OnConnectionCompleted callback to fire, which sets connectionCompletedPromise... | ||
if (connectionCompletedPromise.get_future().get() == false) | ||
{ | ||
fprintf(stderr, "Connection failed\n"); | ||
exit(-1); | ||
} | ||
|
||
// Disconnect | ||
if (connection->Disconnect()) | ||
{ | ||
connectionClosedPromise.get_future().wait(); | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters