Skip to content

Commit

Permalink
Code change for adding support to provision device using CSR file (#27)
Browse files Browse the repository at this point in the history
* Code change for adding support to provision device  using CSR file

* CLang Formatting Fleet Provisioning code

* Added Unit tests for StoreValueInFile method

* Added permissions for resources created using CSR

* CLang Formatting

* Code change to support CSR file path

* removed  dc-settings.json JSON config file from this PR

* basic update in FileUtils::createDirectoryWithPermissions

* quick fix to free memory allocated for wordexp_t struct

* resolving conflict in FileUtils.cpp

Co-authored-by: Matthew Paul <[email protected]>
  • Loading branch information
HarshGandhi-AWS and matthewpaul authored Dec 23, 2020
1 parent 9a44268 commit f361a4a
Show file tree
Hide file tree
Showing 10 changed files with 430 additions and 58 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ cmake ../ -DEXCLUDE_DD=ON

### Running the tests
```
./build/test-aws-iot-device-client
./build/test/test-aws-iot-device-client
```

## Setting Up The Device Client
Expand Down
3 changes: 2 additions & 1 deletion config-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
},
"fleet-provisioning": {
"enabled": false,
"template-name": "replace_with_template_name"
"template-name": "replace_with_template_name",
"csr-file": "<replace_with_csr-file-path>"
}
}
25 changes: 25 additions & 0 deletions setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,26 @@ if [ "$BUILD_CONFIG" = "y" ]; then
DD_ENABLED="false"
fi

### FP Config ###
echo "${PMPT}Enable Fleet Provisioning feature? y/n${NC}"
FP_ENABLED=""
read -r ENABLE_FP
if [ "$ENABLE_FP" = "y" ]; then
FP_ENABLED="true"
echo "${PMPT}Specify Fleet Provisioning Template name you want to use for Provisioning you device: ${NC}"
read -r TEMPLATE_NAME_TEMP
if [ "$TEMPLATE_NAME_TEMP" ]; then
FP_TEMPLATE_NAME=$TEMPLATE_NAME_TEMP
fi
echo "${PMPT}Specify absolute path to Certificate Signing Request (CSR) file used for creating new certificate while provisioning device by keeping private key secure: ${NC}"
read -r CSR_FILE_TEMP
if [ "$CSR_FILE_TEMP" ]; then
FP_CSR_FILE=$CSR_FILE_TEMP
fi
else
FP_ENABLED="false"
fi

CONFIG_OUTPUT="
{
\"endpoint\": \"$ENDPOINT\",
Expand All @@ -136,6 +156,11 @@ if [ "$BUILD_CONFIG" = "y" ]; then
\"device-defender\": {
\"enabled\": $DD_ENABLED,
\"interval-in-seconds\": $DD_INTERVAL
},
\"fleet-provisioning\": {
\"enabled\": $FP_ENABLED,
\"template-name\": \"$FP_TEMPLATE_NAME\",
\"csr-file\": \"$FP_CSR_FILE\"
}
}"

Expand Down
4 changes: 2 additions & 2 deletions source/SharedCrtResourceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ bool SharedCrtResourceManager::locateCredentials(const PlainConfig &config)
{
LOGM_ERROR(
TAG,
"Permissions for public key parent directory %s should be %d but found %d instead",
"Permissions for public cert parent directory %s should be %d but found %d instead",
parentDir.c_str(),
Permissions::CERT_DIR,
actualParentDirPermissions);
Expand All @@ -88,7 +88,7 @@ bool SharedCrtResourceManager::locateCredentials(const PlainConfig &config)
{
LOGM_ERROR(
TAG,
"Permissions for public key %s should be %d but found %d instead",
"Permissions for public cert %s should be %d but found %d instead",
config.cert->c_str(),
Permissions::PUBLIC_CERT,
actualPublicKeyPermissions);
Expand Down
35 changes: 31 additions & 4 deletions source/config/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,9 +600,11 @@ bool PlainConfig::DeviceDefender::Validate() const

constexpr char PlainConfig::FleetProvisioning::CLI_ENABLE_FLEET_PROVISIONING[];
constexpr char PlainConfig::FleetProvisioning::CLI_FLEET_PROVISIONING_TEMPLATE_NAME[];
constexpr char PlainConfig::FleetProvisioning::CLI_FLEET_PROVISIONING_CSR_FILE[];

constexpr char PlainConfig::FleetProvisioning::JSON_KEY_ENABLED[];
constexpr char PlainConfig::FleetProvisioning::JSON_KEY_TEMPLATE_NAME[];
constexpr char PlainConfig::FleetProvisioning::JSON_KEY_CSR_FILE[];

bool PlainConfig::FleetProvisioning::LoadFromJson(const Crt::JsonView &json)
{
Expand All @@ -618,6 +620,16 @@ bool PlainConfig::FleetProvisioning::LoadFromJson(const Crt::JsonView &json)
templateName = json.GetString(jsonKey).c_str();
}

jsonKey = JSON_KEY_CSR_FILE;
if (json.ValueExists(jsonKey))
{
wordexp_t word;
wordexp(json.GetString(jsonKey).c_str(), &word, 0);
string expandedPath = word.we_wordv[0];
wordfree(&word);
csrFile = expandedPath;
}

return true;
}

Expand All @@ -631,6 +643,14 @@ bool PlainConfig::FleetProvisioning::LoadFromCliArgs(const CliArgs &cliArgs)
{
templateName = cliArgs.at(PlainConfig::FleetProvisioning::CLI_FLEET_PROVISIONING_TEMPLATE_NAME).c_str();
}
if (cliArgs.count(PlainConfig::FleetProvisioning::CLI_FLEET_PROVISIONING_CSR_FILE))
{
wordexp_t word;
wordexp(cliArgs.at(PlainConfig::FleetProvisioning::CLI_FLEET_PROVISIONING_CSR_FILE).c_str(), &word, 0);
string expandedPath = word.we_wordv[0];
wordfree(&word);
csrFile = expandedPath;
}

return true;
}
Expand Down Expand Up @@ -764,6 +784,7 @@ bool Config::ParseCliArgs(int argc, char **argv, CliArgs &cliArgs)

{PlainConfig::FleetProvisioning::CLI_ENABLE_FLEET_PROVISIONING, false, false, nullptr},
{PlainConfig::FleetProvisioning::CLI_FLEET_PROVISIONING_TEMPLATE_NAME, true, false, nullptr},
{PlainConfig::FleetProvisioning::CLI_FLEET_PROVISIONING_CSR_FILE, true, false, nullptr},
};

map<string, ArgumentDefinition> argumentDefinitionMap;
Expand Down Expand Up @@ -981,7 +1002,10 @@ void Config::PrintHelpMessage()
"%s <service>:\t\t\t\t\t\tConnect secure tunnel to specific service\n"
"%s:\t\t\t\t\tDisable MQTT new tunnel notification for Secure Tunneling\n"
"%s <interval-in-seconds>:\t\t\tPositive integer to publish Device Defender metrics\n"
"%s <template-name>:\t\t\tUse specified Fleet Provisioning template name\n";
"%s <template-name>:\t\t\tUse specified Fleet Provisioning template name\n"
"%s <csr-file-path>:\t\t\tUse specified CSR file to generate a certificate by keeping user private key secure. "
"If CSR file is not provided, Client will use Claim Certificate and Private key to generate new Certificate "
"and Private Key while provisioning the device\n";

cout << FormatMessage(
helpMessageTemplate,
Expand All @@ -1006,7 +1030,8 @@ void Config::PrintHelpMessage()
PlainConfig::Tunneling::CLI_TUNNELING_SERVICE,
PlainConfig::Tunneling::CLI_TUNNELING_DISABLE_NOTIFICATION,
PlainConfig::DeviceDefender::CLI_DEVICE_DEFENDER_INTERVAL,
PlainConfig::FleetProvisioning::CLI_FLEET_PROVISIONING_TEMPLATE_NAME);
PlainConfig::FleetProvisioning::CLI_FLEET_PROVISIONING_TEMPLATE_NAME,
PlainConfig::FleetProvisioning::CLI_FLEET_PROVISIONING_CSR_FILE);
}

bool Config::ExportDefaultSetting(const string &file)
Expand All @@ -1030,7 +1055,8 @@ bool Config::ExportDefaultSetting(const string &file)
}
"%s": {
"%s": true,
"%s": "<replace_with_template_name>"
"%s": "<replace_with_template_name>",
"%s": "<replace_with_csr-file-path>"
}
}
)";
Expand All @@ -1057,7 +1083,8 @@ bool Config::ExportDefaultSetting(const string &file)
PlainConfig::DeviceDefender::JSON_KEY_INTERVAL,
PlainConfig::JSON_KEY_FLEET_PROVISIONING,
PlainConfig::FleetProvisioning::JSON_KEY_ENABLED,
PlainConfig::FleetProvisioning::JSON_KEY_TEMPLATE_NAME);
PlainConfig::FleetProvisioning::JSON_KEY_TEMPLATE_NAME,
PlainConfig::FleetProvisioning::JSON_KEY_CSR_FILE);

clientConfig.close();
LOGM_INFO(TAG, "Exported settings to: %s", file.c_str());
Expand Down
5 changes: 5 additions & 0 deletions source/config/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ namespace Aws
static constexpr int KEY_DIR = 700;
static constexpr int ROOT_CA_DIR = 700;
static constexpr int CERT_DIR = 700;
static constexpr int CSR_DIR = 700;
static constexpr int CONFIG_DIR = 745;
static constexpr int LOG_DIR = 745;

/** Files **/
static constexpr int PRIVATE_KEY = 600;
static constexpr int PUBLIC_CERT = 644;
static constexpr int ROOT_CA = 644;
static constexpr int CSR_FILE = 600;
static constexpr int LOG_FILE = 600;
static constexpr int CONFIG_FILE = 644;
static constexpr int RUNTIME_CONFIG_FILE = 644;
Expand Down Expand Up @@ -165,12 +167,15 @@ namespace Aws

static constexpr char CLI_ENABLE_FLEET_PROVISIONING[] = "--enable-fleet-provisioning";
static constexpr char CLI_FLEET_PROVISIONING_TEMPLATE_NAME[] = "--fleet-provisioning-template-name";
static constexpr char CLI_FLEET_PROVISIONING_CSR_FILE[] = "--csr-file";

static constexpr char JSON_KEY_ENABLED[] = "enabled";
static constexpr char JSON_KEY_TEMPLATE_NAME[] = "template-name";
static constexpr char JSON_KEY_CSR_FILE[] = "csr-file";

bool enabled{false};
Aws::Crt::Optional<std::string> templateName;
Aws::Crt::Optional<std::string> csrFile;
};
FleetProvisioning fleetProvisioning;

Expand Down
Loading

0 comments on commit f361a4a

Please sign in to comment.