23 Commits

Author SHA1 Message Date
Mudit Vats
96f4c68ecc feat: Fix formatting 2021-08-16 17:48:53 -07:00
Mudit Vats
87ca74fdf3 feat: Treat data to/from RPS and AMT as binary. 2021-08-16 17:43:07 -07:00
Mudit Vats
185cdceadb feat: check for provisioning state on shbc failure and reset if necessary 2021-08-11 09:56:36 -07:00
Mudit Vats
706a512bc7 feat: tick up protocol minor version, always return response on shbc config so RPS can fall-back to non-shbc configuration. 2021-08-06 09:18:54 -07:00
Mudit Vats
e0fe219646 feat: shbc configuration 2021-08-05 10:54:18 -07:00
Mike
f0682c4588 Merge pull request #60 from open-amt-cloud-toolkit/fix_klockwork_opens
fix: klockwork reported success / failure check fix
2021-07-21 10:39:29 -07:00
Mudit Vats
913fa41b17 fix: klockwork reported success / failure check fix 2021-07-19 13:25:33 -07:00
Mike
f6666d857b Merge pull request #55 from open-amt-cloud-toolkit/feature_wireless
feat: add AMT wireless adapter info to amtinfo LAN settings.
2021-07-07 10:46:44 -07:00
Mike
e51dc9f1f7 Merge branch 'master' into feature_wireless 2021-07-07 10:20:14 -07:00
Mike
a4929a2d08 Merge pull request #53 from open-amt-cloud-toolkit/update-readme
docs(readme): update readme
2021-07-07 10:20:01 -07:00
Mike
615e9156dc Merge branch 'master' into feature_wireless 2021-07-07 10:19:14 -07:00
Matt Primrose
373a560b1a Merge branch 'master' into update-readme 2021-07-06 17:17:08 -07:00
Matt Primrose
0f8050b6bf Merge pull request #56 from open-amt-cloud-toolkit/changelog_automation
ci(changelog): add automation for changelog generation
2021-07-06 17:16:43 -07:00
Matt Primrose
c70335ae2e Merge branch 'master' into update-readme 2021-07-06 16:21:30 -07:00
Matt Primrose
d94302543b Merge branch 'master' into changelog_automation 2021-07-06 16:20:35 -07:00
Matt Primrose
dea97dec64 Merge pull request #59 from bill-mahoney/master
ci: update scanning
2021-07-06 16:18:24 -07:00
mpvats-intel
cd2887a992 Merge branch 'master' into feature_wireless 2021-07-01 06:16:05 -07:00
Bill Mahoney
33abb9d2d2 ci: update scanning
Signed-off-by: Bill Mahoney <bill.mahoney@intel.com>
2021-06-30 11:18:27 -07:00
bwendlandt-intel
34981ad2c7 docs(readme): wording 2021-06-28 11:42:37 -07:00
Mike
bea1eb22ef Merge branch 'master' into changelog_automation 2021-06-23 11:01:46 -07:00
Mike
ec1374280b ci(changelog): add automation for changelog generation 2021-06-22 16:43:53 -07:00
Mudit Vats
f7dc3f4faa feat: add AMT wireless adapter info to amtinfo LAN settings. 2021-06-22 15:37:11 -07:00
bwendlandt-intel
491f5087de docs(readme): update readme 2021-06-18 15:37:41 -07:00
20 changed files with 729 additions and 188 deletions

20
.github/workflows/changelog.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: Changelog Generator
on:
pull_request:
branches: [ master ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- run: docker run -v $PWD:/workdir quay.io/git-chglog/git-chglog --next-tag vNext --output CHANGELOG-new.md vNext..
- name: GitHub Upload Release Artifacts
uses: actions/upload-artifact@v2
with:
name: CHANGELOG-new.md
path: |
./CHANGELOG-new.md

View File

@@ -1,3 +1,18 @@
<a name="v1.2.2"></a>
## [v1.2.2] - 2021-06-22
### Ci
- remove Jenkins chron
- **changelog:** add automation for changelog generation
### Fix
- update examples text and version
<a name="v1.2.1"></a>
## [v1.2.1] - 2021-05-06
### Fix
**docker:** add missing ca-certs
<a name="v1.2.0"></a> <a name="v1.2.0"></a>
## v1.2.0 ## v1.2.0

View File

@@ -98,6 +98,8 @@ add_executable (rpc
commands.cpp commands.cpp
activation.h activation.h
activation.cpp activation.cpp
shbc.h
shbc.cpp
heartbeat.h heartbeat.h
heartbeat.cpp heartbeat.cpp
lms.h lms.h

195
Jenkinsfile vendored
View File

@@ -1,61 +1,33 @@
pipeline { pipeline {
agent none agent {
label 'docker-amt'
}
options { options {
buildDiscarder(logRotator(numToKeepStr: '5', daysToKeepStr: '30')) buildDiscarder(logRotator(numToKeepStr: '5', daysToKeepStr: '30'))
timestamps() timestamps()
timeout(unit: 'HOURS', time: 2) timeout(unit: 'HOURS', time: 2)
} }
stages { stages {
stage ('Parallel') { stage ('Cloning Repository') {
parallel {
stage ('Linux') {
agent { label 'docker-amt' }
stages {
stage ('Cloning Repository') {
steps {
script {
scmCheckout {
clean = true
}
}
}
}
}
}
stage ('Windows') {
agent { label 'openamt-win' }
stages {
stage ('Cloning Repository') {
steps {
script {
scmCheckout {
clean = true
}
}
}
}
}
}
}
}
stage ('Static Code Scan - Protex') {
agent { label 'docker-amt' }
steps { steps {
script { script {
staticCodeScan { scmCheckout {
// generic clean = true
scanners = ['protex']
scannerType = ['c','c++']
protexProjectName = 'OpenAMT - RPC'
// internal, do not change
protexBuildName = 'rrs-generic-protex-build'
} }
} }
} }
} }
stage('Static Code Scan - Protex') {
environment{
PROJECT_NAME = 'OpenAMT - RPC'
SCANNERS = 'protex'
}
steps {
rbheStaticCodeScan()
}
}
stage ('Parallel Builds') { stage ('Parallel Builds') {
parallel { parallel {
stage ('Linux') { stage ('Linux') {
@@ -71,6 +43,7 @@ pipeline {
steps { steps {
sh './scripts/jenkins-pre-build.sh' sh './scripts/jenkins-pre-build.sh'
sh './scripts/jenkins-build.sh' sh './scripts/jenkins-build.sh'
stash includes: 'build/rpc', name: 'linux-rpc-app'
} }
} }
stage ('Archive') { stage ('Archive') {
@@ -78,7 +51,6 @@ pipeline {
archiveArtifacts allowEmptyArchive: true, artifacts: 'build/rpc', caseSensitive: false, onlyIfSuccessful: true archiveArtifacts allowEmptyArchive: true, artifacts: 'build/rpc', caseSensitive: false, onlyIfSuccessful: true
} }
} }
} }
} }
stage ('Windows') { stage ('Windows') {
@@ -89,7 +61,7 @@ pipeline {
bat 'scripts\\jenkins-pre-build.cmd' bat 'scripts\\jenkins-pre-build.cmd'
bat 'scripts\\jenkins-build.cmd' bat 'scripts\\jenkins-build.cmd'
// prepare stash for the binary scan // prepare stash for the binary scan
stash includes: "**/*.exe", name: 'rpc-app' stash includes: '**/*.exe', name: 'win-rpc-app'
} }
} }
stage ('Archive') { stage ('Archive') {
@@ -101,71 +73,82 @@ pipeline {
} }
} }
} }
stage ('Parallel Scans') {
parallel {
stage ('Static Code Scan Linux') {
agent { label 'docker-amt' }
steps {
script {
staticCodeScan {
// generic
scanners = ['bdba','klocwork']
scannerType = 'c++'
protecodeGroup = '25' stage('Prep Binary') {
protecodeScanName = 'rpc-zip' steps {
protecodeDirectory = './build/rpc' sh 'mkdir -p ./bin'
dir('./bin') {
klockworkPreBuildScript = './scripts/jenkins-pre-build.sh' unstash 'linux-rpc-app'
klockworkBuildCommand = './scripts/jenkins-build.sh' unstash 'win-rpc-app'
klockworkProjectName = 'Panther Point Creek'
klockworkIgnoreCompileErrors = true
}
}
}
} }
stage ('Static Code Scan Windows') { }
stages { }
stage ('Static Code Scan Windows - Klockwork') { stage('Linux Scans') {
agent { label 'openamt-win' } environment{
steps { PROJECT_NAME = 'OpenAMT - RPC - Linux'
script { SCANNERS = 'bdba,klocwork'
staticCodeScan {
// generic // protecode details
scanners = ['klocwork'] PROTECODE_BIN_DIR = './bin'
scannerType = 'c++' PROTECODE_INCLUDE_SUB_DIRS = true
klockworkPreBuildScript = 'scripts\\jenkins-pre-build.cmd' // klocwork details
klockworkBuildCommand = 'scripts\\jenkins-build.cmd' KLOCWORK_SCAN_TYPE = 'c++'
klockworkProjectName = 'Panther Point Creek' KLOCWORK_PRE_BUILD_SCRIPT = './scripts/jenkins-pre-build.sh'
klockworkIgnoreCompileErrors = true KLOCWORK_BUILD_COMMAND = './scripts/jenkins-build.sh'
} KLOCWORK_IGNORE_COMPILE_ERRORS = true
}
} // publishArtifacts details
} PUBLISH_TO_ARTIFACTORY = true
stage ('Static Code Scan Windows - BDBA') { }
agent { label 'docker-amt' } steps {
steps { rbheStaticCodeScan()
script { dir('artifacts/Klockwork'){
sh "mkdir -p bdbaScanDir" sh 'cp kw_report.html kw_report_linux.html'
dir("bdbaScanDir") { sh 'cp kw_report.csv kw_report_linux.csv'
unstash 'rpc-app' archiveArtifacts allowEmptyArchive: true, artifacts: 'kw_report_linux.html'
} archiveArtifacts allowEmptyArchive: true, artifacts: 'kw_report_linux.csv'
staticCodeScan { }
// generic
scanners = ['bdba'] }
scannerType = 'c++' }
stage('Windows Scans'){
protecodeGroup = '25' agent { label 'openamt-win' }
protecodeScanName = 'rpc-zip' stages{
protecodeDirectory = 'bdbaScanDir' stage ('Windows Scans - klocwork') {
} environment {
} PROJECT_NAME = 'OpenAMT - RPC - Windows'
} SCANNERS = 'klocwork'
// klocwork details
KLOCWORK_SCAN_TYPE = 'c++'
KLOCWORK_PRE_BUILD_SCRIPT = 'scripts\\jenkins-pre-build.cmd'
KLOCWORK_BUILD_COMMAND = 'scripts\\jenkins-build.cmd'
KLOCWORK_IGNORE_COMPILE_ERRORS = true
// publishArtifacts details
PUBLISH_TO_ARTIFACTORY = true
}
steps {
rbheStaticCodeScan()
dir('artifacts\\Klockwork'){
bat 'copy kw_report.html kw_report_windows.html'
bat 'copy kw_report.csv kw_report_windows.csv'
stash includes: 'kw_report_windows.*', name: 'win-kwreports'
archiveArtifacts allowEmptyArchive: true, artifacts: 'kw_report_windows.html'
archiveArtifacts allowEmptyArchive: true, artifacts: 'kw_report_windows.csv'
} }
} }
} }
} }
} }
stage('Publish Artifacts'){
steps{
dir('artifacts/Klockwork'){
unstash 'win-kwreports'
}
publishArtifacts()
}
}
} }
} }

View File

@@ -171,6 +171,10 @@ const PTHI_MESSAGE_HEADER GET_UUID_REQUEST_HEADER = {
{AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, 0, {{GET_UUID_REQUEST}}, 0 {AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, 0, {{GET_UUID_REQUEST}}, 0
}; };
const PTHI_MESSAGE_HEADER GET_START_CONFIG_HBASED_REQUEST_HEADER = {
{AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, 0, {{GET_START_CONFIG_HBASED_REQUEST}}, 396
};
AMT_STATUS _call(const unsigned char *command, UINT32 command_size, UINT8 **readBuffer, UINT32 rcmd, unsigned int expSize) AMT_STATUS _call(const unsigned char *command, UINT32 command_size, UINT8 **readBuffer, UINT32 rcmd, unsigned int expSize)
{ {
UINT32 inBuffSize; UINT32 inBuffSize;
@@ -1502,4 +1506,43 @@ AMT_STATUS pthi_GetUUID(AMT_UUID *uuid)
return status; return status;
} }
/*
* Start Configuration Host Based
* Arguments:
* request - host based configuration input parameters provided by the caller
* response - host based configuration output parameters returned to the caller
* Return values: (A status code returned in a response message that indicates whether the operation specified in the corresponding request message succeeded or failed. If the operation failed, this code indicates the specific reason for failure. Possible values described below.)
* AMT_STATUS_SUCCESS - Request succeeded.
* AMT_STATUS_INTERNAL_ERROR - An internal error to the AMT device has occurred. This may indicate an interface error, or a AMT application error.
* AMT_STATUS_INVALID_MESSAGE_LENGTH - Length field of header is invalid.
*
*/
AMT_STATUS pthi_StartConfigHBased(CFG_START_CONFIG_HBASED_REQUEST_INFO *request, CFG_START_CONFIG_HBASED_RESPONSE_INFO *response)
{
UINT8* readBuffer = NULL;
UINT32 command_size = sizeof(CFG_START_CONFIG_HBASED_REQUEST);
unsigned char command[sizeof(CFG_START_CONFIG_HBASED_REQUEST)];
AMT_STATUS status;
CFG_START_CONFIG_HBASED_RESPONSE* tmp_response;
memset(command, 0, sizeof(CFG_START_CONFIG_HBASED_REQUEST));
memcpy_s(command, sizeof(command), (char*)&(GET_START_CONFIG_HBASED_REQUEST_HEADER), sizeof(GET_START_CONFIG_HBASED_REQUEST_HEADER));
((CFG_START_CONFIG_HBASED_REQUEST*)command)->Info.ServerHashAlgorithm = request->ServerHashAlgorithm;
((CFG_START_CONFIG_HBASED_REQUEST*)command)->Info.HostVPNEnable = request->HostVPNEnable;
((CFG_START_CONFIG_HBASED_REQUEST*)command)->Info.SuffixListLen = request->SuffixListLen;
memcpy_s(((CFG_START_CONFIG_HBASED_REQUEST*)command)->Info.ServerCertHash, 64, request->ServerCertHash, 64);
memcpy_s(((CFG_START_CONFIG_HBASED_REQUEST*)command)->Info.NetworkDnsSuffixList, 320, request->NetworkDnsSuffixList, 320);
status = _call(command, command_size, &readBuffer, GET_START_CONFIG_HBASED_RESPONSE, sizeof(CFG_START_CONFIG_HBASED_RESPONSE));
if (status == AMT_STATUS_SUCCESS)
{
tmp_response = (CFG_START_CONFIG_HBASED_RESPONSE*)readBuffer;
memcpy_s(response, sizeof(CFG_START_CONFIG_HBASED_RESPONSE_INFO), &(tmp_response->Info), sizeof(CFG_START_CONFIG_HBASED_RESPONSE_INFO));
}
if (readBuffer != NULL) free(readBuffer);
return status;
}
#endif #endif

View File

@@ -479,6 +479,8 @@ typedef enum
CERT_HASH_ALGORITHM_MD5 = 0, // 16 bytes CERT_HASH_ALGORITHM_MD5 = 0, // 16 bytes
CERT_HASH_ALGORITHM_SHA1, // 20 bytes CERT_HASH_ALGORITHM_SHA1, // 20 bytes
CERT_HASH_ALGORITHM_SHA256, // 32 bytes CERT_HASH_ALGORITHM_SHA256, // 32 bytes
CERT_HASH_ALGORITHM_SHA384, // 48 bytes
CERT_HASH_ALGORITHM_SHA224, // 28 bytes
CERT_HASH_ALGORITHM_SHA512, // 64 bytes CERT_HASH_ALGORITHM_SHA512, // 64 bytes
} CERT_HASH_ALGORITHM; } CERT_HASH_ALGORITHM;
@@ -664,6 +666,36 @@ typedef struct _CFG_GET_UUID_RESPONSE
AMT_UUID UUID; AMT_UUID UUID;
} CFG_GET_UUID_RESPONSE; } CFG_GET_UUID_RESPONSE;
typedef struct _CFG_START_CONFIG_HBASED_REQUEST_INFO
{
CERT_HASH_ALGORITHM ServerHashAlgorithm;
UINT8 ServerCertHash[CERT_HASH_MAX_LENGTH];
AMT_BOOLEAN HostVPNEnable;
UINT32 SuffixListLen;
CHAR NetworkDnsSuffixList[320];
} CFG_START_CONFIG_HBASED_REQUEST_INFO;
typedef struct _CFG_START_CONFIG_HBASED_REQUEST
{
PTHI_MESSAGE_HEADER Header;
CFG_START_CONFIG_HBASED_REQUEST_INFO Info;
} CFG_START_CONFIG_HBASED_REQUEST;
typedef struct _CFG_START_CONFIG_HBASED_RESPONSE_INFO
{
UINT8 HashAlgorithm;
UINT8 AMTCertHash[CERT_HASH_MAX_LENGTH];
} CFG_START_CONFIG_HBASED_RESPONSE_INFO;
typedef struct _CFG_START_CONFIG_HBASED_RESPONSE
{
PTHI_RESPONSE_MESSAGE_HEADER Header;
CFG_START_CONFIG_HBASED_RESPONSE_INFO Info;
} CFG_START_CONFIG_HBASED_RESPONSE;
#pragma pack() #pragma pack()
@@ -701,6 +733,7 @@ AMT_STATUS pthi_Unprovision(CFG_PROVISIONING_MODE provisionMode);
AMT_STATUS pthi_GetStateEHBC(AMT_EHBC_STATE *state); AMT_STATUS pthi_GetStateEHBC(AMT_EHBC_STATE *state);
AMT_STATUS pthi_GetControlMode(int *state); AMT_STATUS pthi_GetControlMode(int *state);
AMT_STATUS pthi_GetUUID(AMT_UUID *uuid); AMT_STATUS pthi_GetUUID(AMT_UUID *uuid);
AMT_STATUS pthi_StartConfigHBased(CFG_START_CONFIG_HBASED_REQUEST_INFO* request, CFG_START_CONFIG_HBASED_RESPONSE_INFO* response);
#define PROVISIONING_MODE_REQUEST 0x04000008 #define PROVISIONING_MODE_REQUEST 0x04000008
#define PROVISIONING_MODE_RESPONSE 0x04800008 #define PROVISIONING_MODE_RESPONSE 0x04800008
@@ -831,6 +864,9 @@ const PTHI_MESSAGE_HEADER GET_CONTROL_MODE_HEADER;
#define GET_UUID_REQUEST 0x400005c #define GET_UUID_REQUEST 0x400005c
#define GET_UUID_RESPONSE 0x480005c #define GET_UUID_RESPONSE 0x480005c
#define GET_START_CONFIG_HBASED_REQUEST 0x400008b
#define GET_START_CONFIG_HBASED_RESPONSE 0x480008b
#endif #endif
#endif #endif

View File

@@ -4,26 +4,43 @@
The Remote Provisioning Client (RPC) is an application that enables remote capabilities for Intel® AMT, such as as device activation and configuration. To accomplish this, RPC communicates with the Remote Provisioning Server (RPS) to activate and connect the edge device. The Remote Provisioning Client (RPC) is an application that enables remote capabilities for Intel® AMT, such as as device activation and configuration. To accomplish this, RPC communicates with the Remote Provisioning Server (RPS) to activate and connect the edge device.
<br><br>
**For detailed documentation** about RPC or other features of the Open AMT Cloud Toolkit, see the [docs](https://open-amt-cloud-toolkit.github.io/docs/). **For detailed documentation** about RPC or other features of the Open AMT Cloud Toolkit, see the [docs](https://open-amt-cloud-toolkit.github.io/docs/).
<br>
## Prerequisites ## Prerequisites
We leverage GitHub Actions as a means to build RPC automatically leveraging Github's CI/CD Infrastructure. This avoids having to deal with the challenges of getting your build environment just right on your local machine and allows you to get up and running much faster. Read more about GitHub Actions [here](https://github.blog/2019-08-08-github-actions-now-supports-ci-cd/#:~:text=GitHub%20Actions%20is%20an%20API,every%20step%20along%20the%20way.) We leverage GitHub Actions as a means to build RPC automatically leveraging Github's CI/CD Infrastructure. This avoids having to deal with the challenges of getting your build environment just right on your local machine and allows you to get up and running much faster. Read more about GitHub Actions [here](https://github.blog/2019-08-08-github-actions-now-supports-ci-cd/#:~:text=GitHub%20Actions%20is%20an%20API,every%20step%20along%20the%20way.)
## Build the Remote Provisioning Client (RPC)
<p align="center"> <p align="center">
<img src="assets/animations/forkandbuild.gif" width="650" /> <img src="assets/animations/forkandbuild.gif" width="650" />
</p> </p>
1. Create a fork of the rpc repository [here](https://github.com/open-amt-cloud-toolkit/rpc/fork) or via the Fork button in the top-right corner of the rpc repository. ## Build the Remote Provisioning Client (RPC)
2. Click on "Actions" and Select "Build RPC (Native)" Workflow. 1. <a href="https://github.com/open-amt-cloud-toolkit/rpc/fork" target="_blank">Create a fork of rpc on GitHub.</a>
3. Click "Run Workflow", select branch "master", and click "Run Workflow". 2. Click on the **Actions** tab at the top and select **Build RPC (Native) Debug/Release**.
4. Grab a coffee. The build for Windows will take approximately 30 minutes and the build for Linux will take approximately 5 minutes. 3. Click the **Run Workflow** dropdown.
5. Once complete, click the completed job, and download the appropriate RPC for your OS under the "Artifacts" section. 4. Select the **Branch: master**, or a preferred version, from the **Use workflow from** dropdown.
For detailed documentation about RPC and using it to activate a device, see the [docs](https://open-amt-cloud-toolkit.github.io/docs/) 5. By default, the Build Type should be **release**.
6. Click the **Run Workflow** button. Grab a coffee and take a break! The build time ranges from 15 to 20 minutes.
8. Once the download is complete, click the completed job which will feature a green checkmark.
9. Download the appropriate RPC for your managed device's OS under the **Artifacts** section.
### To Delete your workflow run
1. Click the ellipsis ( **...** ) menu for the workflow.
2. Choose the **Delete workflow run** option.
For detailed documentation about RPC and using it to activate a device, see the [docs](https://open-amt-cloud-toolkit.github.io/docs/)

View File

@@ -264,7 +264,12 @@ bool act_create_request(std::string commands, std::string dns_suffix, std::strin
// serialize payload // serialize payload
std::string serializedPayload = utility::conversions::to_utf8string(activationPayload.serialize()); std::string serializedPayload = utility::conversions::to_utf8string(activationPayload.serialize());
std::string encodedPayload = util_encode_base64(serializedPayload); std::vector<unsigned char> serializedPayloadVector;
for (int i = 0; i < serializedPayload.size(); i++)
{
serializedPayloadVector.push_back(serializedPayload[i]);
}
std::string encodedPayload = util_encode_base64(serializedPayloadVector);
utility::string_t payload = utility::conversions::to_string_t(encodedPayload); utility::string_t payload = utility::conversions::to_string_t(encodedPayload);
msg[U("payload")] = web::json::value::string(payload); msg[U("payload")] = web::json::value::string(payload);
@@ -274,7 +279,7 @@ bool act_create_request(std::string commands, std::string dns_suffix, std::strin
return true; return true;
} }
bool act_create_response(std::string payload, std::string& response) bool act_create_response(std::vector<unsigned char> payload, std::string& response)
{ {
web::json::value msg; web::json::value msg;

View File

@@ -7,8 +7,9 @@
#define __ACTIVATION_H__ #define __ACTIVATION_H__
#include <string> #include <string>
#include <vector>
#define PROTOCOL_VERSION "4.0.0" #define PROTOCOL_VERSION "4.1.0"
#ifdef _WIN32 #ifdef _WIN32
#define convertstring to_utf16string #define convertstring to_utf16string
@@ -17,6 +18,6 @@
#endif #endif
bool act_create_request(std::string commands, std::string dns_suffix, std::string& request); bool act_create_request(std::string commands, std::string dns_suffix, std::string& request);
bool act_create_response(std::string payload, std::string& response); bool act_create_response(std::vector<unsigned char> payload, std::string& response);
#endif #endif

View File

@@ -282,51 +282,54 @@ bool cmd_get_certificate_hashes(std::vector<cert_hash_entry>& hash_entries)
for (int i = 0; i < (int) amt_hash_handles.Length; i++) for (int i = 0; i < (int) amt_hash_handles.Length; i++)
{ {
// get each entry // get each entry
AMT_STATUS status = pthi_GetCertificateHashEntry(amt_hash_handles.Handles[i], &certhash_entry); AMT_STATUS amt_status = pthi_GetCertificateHashEntry(amt_hash_handles.Handles[i], &certhash_entry);
int hashSize; if (amt_status == 0)
cert_hash_entry tmp;
switch (certhash_entry.HashAlgorithm) {
case 0: // MD5
hashSize = 16;
tmp.algorithm = "MD5";
break;
case 1: // SHA1
hashSize = 20;
tmp.algorithm = "SHA1";
break;
case 2: // SHA256
hashSize = 32;
tmp.algorithm = "SHA256";
break;
case 3: // SHA512
hashSize = 64;
tmp.algorithm = "SHA512";
break;
default:
hashSize = 0;
tmp.algorithm = "UNKNOWN";
break;
}
if (certhash_entry.IsActive == 1)
{ {
std::string cert_name(certhash_entry.Name.Buffer, certhash_entry.Name.Length); int hashSize;
tmp.name = cert_name; cert_hash_entry tmp;
tmp.is_default = certhash_entry.IsDefault; switch (certhash_entry.HashAlgorithm) {
tmp.is_active = certhash_entry.IsActive; case 0: // MD5
hashSize = 16;
std::string hashString; tmp.algorithm = "MD5";
for (int i = 0; i < hashSize; i++) break;
{ case 1: // SHA1
char hex[10]; hashSize = 20;
snprintf(hex, 10, "%02x", certhash_entry.CertificateHash[i]); tmp.algorithm = "SHA1";
hashString += hex; break;
case 2: // SHA256
hashSize = 32;
tmp.algorithm = "SHA256";
break;
case 3: // SHA512
hashSize = 64;
tmp.algorithm = "SHA512";
break;
default:
hashSize = 0;
tmp.algorithm = "UNKNOWN";
break;
} }
tmp.hash = hashString; if (certhash_entry.IsActive == 1)
{
std::string cert_name(certhash_entry.Name.Buffer, certhash_entry.Name.Length);
tmp.name = cert_name;
tmp.is_default = certhash_entry.IsDefault;
tmp.is_active = certhash_entry.IsActive;
hash_entries.push_back(tmp); std::string hashString;
for (int i = 0; i < hashSize; i++)
{
char hex[10];
snprintf(hex, 10, "%02x", certhash_entry.CertificateHash[i]);
hashString += hex;
}
tmp.hash = hashString;
hash_entries.push_back(tmp);
}
} }
} }
@@ -377,14 +380,14 @@ bool cmd_get_remote_access_connection_status(int& network_status, int& remote_st
return false; return false;
} }
bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settings) bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settings, bool wired_interface)
{ {
// initialize HECI interface // initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false; if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get wired interface // get wired interface
LAN_SETTINGS lan_settings; LAN_SETTINGS lan_settings;
UINT32 interface_settings = 0; // wired=0, wireless=1 UINT32 interface_settings = (wired_interface) ? 0 : 1; // wired=0, wireless=1
AMT_STATUS amt_status = pthi_GetLanInterfaceSettings(interface_settings, &lan_settings); AMT_STATUS amt_status = pthi_GetLanInterfaceSettings(interface_settings, &lan_settings);
if (amt_status == 0) if (amt_status == 0)
{ {
@@ -393,11 +396,13 @@ bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settin
lan_interface_settings.dhcp_enabled = lan_settings.DhcpEnabled; lan_interface_settings.dhcp_enabled = lan_settings.DhcpEnabled;
lan_interface_settings.link_status = lan_settings.LinkStatus; lan_interface_settings.link_status = lan_settings.LinkStatus;
lan_interface_settings.ip_address.clear();
lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address >> 24) & 0xff); lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address >> 24) & 0xff);
lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address >> 16) & 0xff); lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address >> 16) & 0xff);
lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address >> 8) & 0xff); lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address >> 8) & 0xff);
lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address) & 0xff); lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address) & 0xff);
lan_interface_settings.mac_address.clear();
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[0]); lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[0]);
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[1]); lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[1]);
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[2]); lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[2]);
@@ -410,3 +415,114 @@ bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settin
return false; return false;
} }
bool cmd_start_config_host_based(config_host_based_settings& server_cert, config_host_based_settings& amt_cert)
{
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
CFG_START_CONFIG_HBASED_REQUEST_INFO request;
CFG_START_CONFIG_HBASED_RESPONSE_INFO response;
memset(&request, 0, sizeof(CFG_START_CONFIG_HBASED_REQUEST_INFO));
memset(&response, 0, sizeof(CFG_START_CONFIG_HBASED_RESPONSE_INFO));
if (server_cert.algorithm == "MD5")
{
request.ServerHashAlgorithm = CERT_HASH_ALGORITHM_MD5;
}
else if (server_cert.algorithm == "SHA1")
{
request.ServerHashAlgorithm = CERT_HASH_ALGORITHM_SHA1;
}
else if (server_cert.algorithm == "SHA256")
{
request.ServerHashAlgorithm = CERT_HASH_ALGORITHM_SHA256;
}
else if (server_cert.algorithm == "SHA512")
{
request.ServerHashAlgorithm = CERT_HASH_ALGORITHM_SHA512;
}
else
{
return false;
}
int hashSize;
std::vector<unsigned char> cert_bytes;
util_hex_string_to_bytes(server_cert.hash, cert_bytes);
std::copy(std::begin(cert_bytes), std::end(cert_bytes), request.ServerCertHash);
// start secure host based configuration
AMT_STATUS amt_status = pthi_StartConfigHBased(&request, &response);
if (amt_status == 0)
{
switch (response.HashAlgorithm)
{
case CERT_HASH_ALGORITHM_MD5:
amt_cert.algorithm = "MD5";
hashSize = 16;
break;
case CERT_HASH_ALGORITHM_SHA1:
amt_cert.algorithm = "SHA1";
hashSize = 20;
break;
case CERT_HASH_ALGORITHM_SHA256:
amt_cert.algorithm = "SHA256";
hashSize = 32;
break;
case CERT_HASH_ALGORITHM_SHA512:
amt_cert.algorithm = "SHA512";
hashSize = 64;
break;
default:
case CERT_HASH_ALGORITHM_SHA384:
case CERT_HASH_ALGORITHM_SHA224:
return false;
}
std::vector<unsigned char> hash;
hash.resize(hashSize);
std::copy(response.AMTCertHash, response.AMTCertHash + hashSize, std::begin(hash));
util_bytes_to_hex_string(hash, amt_cert.hash);
return true;
}
return false;
}
bool cmd_get_provisioning_state(int& state)
{
state = 0;
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get Control Mode
AMT_PROVISIONING_STATE provisioningState;
AMT_STATUS amt_status = pthi_GetProvisioningState(&provisioningState);
if (amt_status == 0)
{
state = provisioningState;
return true;
}
return false;
}
bool cmd_stop_configuration()
{
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
AMT_STATUS amt_status = pthi_StopConfiguration();
if (amt_status == 0)
{
return true;
}
return false;
}

View File

@@ -37,6 +37,12 @@ struct fqdn_settings
std::string fqdn; std::string fqdn;
}; };
struct config_host_based_settings
{
std::string hash;
std::string algorithm;
};
bool cmd_is_admin(); bool cmd_is_admin();
bool cmd_get_version(std::string& version); bool cmd_get_version(std::string& version);
bool cmd_get_build_number(std::string& version); bool cmd_get_build_number(std::string& version);
@@ -49,6 +55,9 @@ bool cmd_get_dns_suffix(std::string& suffix);
bool cmd_get_wired_mac_address(std::vector<unsigned char>& address); bool cmd_get_wired_mac_address(std::vector<unsigned char>& address);
bool cmd_get_certificate_hashes(std::vector<cert_hash_entry>& hash_entries); bool cmd_get_certificate_hashes(std::vector<cert_hash_entry>& hash_entries);
bool cmd_get_remote_access_connection_status(int& network_status, int& remote_status, int& remote_trigger, std::string& mps_hostname); bool cmd_get_remote_access_connection_status(int& network_status, int& remote_status, int& remote_trigger, std::string& mps_hostname);
bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settings); bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settings, bool wired_interface = true);
bool cmd_start_config_host_based(config_host_based_settings& server_cert, config_host_based_settings& amt_cert);
bool cmd_get_provisioning_state(int& state);
bool cmd_stop_configuration();
#endif #endif

View File

@@ -20,7 +20,7 @@ void out_text(const std::string name, const std::vector<unsigned char> value, co
for (unsigned char tmp : value) for (unsigned char tmp : value)
{ {
(hex) ? std::cout << std::setfill('0') << std::setw(2) << std::hex << (unsigned int)tmp (hex) ? std::cout << std::setfill('0') << std::setw(2) << std::hex << (unsigned int)tmp
: std::cout << (unsigned int)tmp; : std::cout << std::dec << (unsigned int)tmp;
if (char_count++ < value.size()) if (char_count++ < value.size())
{ {
@@ -270,15 +270,41 @@ bool info_get_lan_interface_settings()
tmp.ip_address.clear(); tmp.ip_address.clear();
tmp.mac_address.clear(); tmp.mac_address.clear();
if (!cmd_get_lan_interface_settings(tmp)) return false; bool hasWired = cmd_get_lan_interface_settings(tmp);
if (hasWired)
{
out_text("LAN Inteface", "wired");
out_text("DHCP Enabled", (tmp.dhcp_enabled) ? "true" : "false");
out_text("DHCP Mode", (tmp.dhcp_mode == 1) ? "active" : "passive");
out_text("Link Status", (tmp.link_status) ? "up" : "down");
out_text("IP Address", tmp.ip_address, '.', false);
out_text("MAC Address", tmp.mac_address, ':');
}
tmp.is_enabled = false;
tmp.link_status = false;
tmp.dhcp_enabled = false;
tmp.dhcp_mode = 0;
tmp.ip_address.clear();
tmp.mac_address.clear();
out_text("DHCP Enabled", (tmp.dhcp_enabled) ? "true" : "false"); bool hasWireless = cmd_get_lan_interface_settings(tmp, false);
out_text("DHCP Mode", (tmp.dhcp_mode == 1) ? "active" : "passive"); if (hasWireless)
out_text("Link Status", (tmp.link_status) ? "up" : "down"); {
out_text("IP Address", tmp.ip_address, '.', false); out_text("LAN Inteface", "wireless");
out_text("MAC Address", tmp.mac_address, ':'); out_text("DHCP Enabled", (tmp.dhcp_enabled) ? "true" : "false");
out_text("DHCP Mode", (tmp.dhcp_mode == 1) ? "active" : "passive");
out_text("Link Status", (tmp.link_status) ? "up" : "down");
out_text("IP Address", tmp.ip_address, '.', false);
out_text("MAC Address", tmp.mac_address, ':');
}
return true; if (hasWired || hasWireless)
{
return true;
}
return false;
} }
bool info_get(const std::string info) bool info_get(const std::string info)

13
lms.cpp
View File

@@ -15,13 +15,22 @@
#include <netdb.h> #include <netdb.h>
#endif #endif
SOCKET lms_connect() SOCKET lms_connect(bool securePort)
{ {
std::string lmsAddress = "localhost"; std::string lmsAddress = "localhost";
std::string lmsPort = "16992"; std::string lmsPort;
SOCKET s = INVALID_SOCKET; SOCKET s = INVALID_SOCKET;
struct addrinfo *addr, hints; struct addrinfo *addr, hints;
if (securePort)
{
lmsPort = "16993";
}
else
{
lmsPort = "16992";
}
#ifdef _WIN32 #ifdef _WIN32
WSADATA wsa; WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)

2
lms.h
View File

@@ -28,6 +28,6 @@ static inline int closesocket(int fd)
#define SD_BOTH SHUT_RDWR #define SD_BOTH SHUT_RDWR
#endif #endif
SOCKET lms_connect(); SOCKET lms_connect(bool securePort = false);
#endif #endif

141
main.cpp
View File

@@ -11,6 +11,7 @@
#include "lms.h" #include "lms.h"
#include "commands.h" #include "commands.h"
#include "activation.h" #include "activation.h"
#include "shbc.h"
#include "heartbeat.h" #include "heartbeat.h"
#include "utils.h" #include "utils.h"
#include "usage.h" #include "usage.h"
@@ -62,6 +63,7 @@ int main(int argc, char* argv[])
std::string arg_info; std::string arg_info;
bool arg_verbose = false; bool arg_verbose = false;
bool arg_nocertcheck = false; bool arg_nocertcheck = false;
bool shbc_config = false;
if (argc == 1) if (argc == 1)
{ {
@@ -185,7 +187,7 @@ int main(int argc, char* argv[])
memset(&lms_socket, 0, sizeof(SOCKET)); memset(&lms_socket, 0, sizeof(SOCKET));
// set receive handler // set receive handler
client.set_message_handler([&client, &mx, &cv, &lms_socket, arg_verbose](web::websockets::client::websocket_incoming_message ret_msg) client.set_message_handler([&client, &mx, &cv, &lms_socket, arg_verbose, &shbc_config](web::websockets::client::websocket_incoming_message ret_msg)
{ {
// kick the timer // kick the timer
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now(); std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
@@ -210,7 +212,7 @@ int main(int argc, char* argv[])
std::string msgStatus = ""; std::string msgStatus = "";
std::string msgMessage = ""; std::string msgMessage = "";
std::string msgPayload = ""; std::string msgPayload = "";
std::string payloadDecoded = ""; std::vector<unsigned char> payloadDecoded;
if ( !parsed.has_field(U("method")) || !parsed.has_field(U("apiKey")) || !parsed.has_field(U("appVersion")) || if ( !parsed.has_field(U("method")) || !parsed.has_field(U("apiKey")) || !parsed.has_field(U("appVersion")) ||
!parsed.has_field(U("protocolVersion")) || !parsed.has_field(U("status")) || !parsed.has_field(U("message")) || !parsed.has_field(U("protocolVersion")) || !parsed.has_field(U("status")) || !parsed.has_field(U("message")) ||
@@ -262,6 +264,79 @@ int main(int argc, char* argv[])
return; return;
} }
if (msgMethod.compare("secure_config_request") == 0)
{
std::string certAlgo;
std::string certHash;
// get server configuration
try
{
tmp = parsed[U("payload")].as_string();
web::json::value parsed_cert_info = web::json::value::parse(tmp);
out = parsed_cert_info[U("algorithm")].as_string();
certAlgo = utility::conversions::to_utf8string(out);
out = parsed_cert_info[U("hash")].as_string();
certHash = utility::conversions::to_utf8string(out);
}
catch (...)
{
std::cerr << std::endl << "JSON format error. Unable to parse message." << std::endl;
return;
}
// send secure config request
config_host_based_settings server_cert;
config_host_based_settings amt_cert;
server_cert.algorithm = certAlgo;
server_cert.hash = certHash;
bool sbhc_success = cmd_start_config_host_based(server_cert, amt_cert);
// wait for configuration to settle down
std::this_thread::sleep_for(std::chrono::seconds(1));
if (!sbhc_success)
{
int state;
if (cmd_get_provisioning_state(state))
{
switch (state) {
case 0:
std::cout << "Provisioning state already in pre-provisioning." << std::endl;
break;
case 1:
std::cout << "Provisioning state is in-provisioning." << std::endl;
(cmd_stop_configuration()) ? std::cout << "Provisioning state succesfully reset." << std::endl : std::cout << "Provisioning state could not be reset." << std::endl;
break;
case 2:
std::cout << "Provisioning state is post-provisioning." << std::endl;
(cmd_stop_configuration()) ? std::cout << "Provisioning state succesfully reset." << std::endl : std::cout << "Provisioning state could not be reset." << std::endl;
break;
default:
break;
}
}
}
// create the response
std::string response;
if (!shbc_create_response(amt_cert.algorithm, amt_cert.hash, sbhc_success, response)) return;
// send it
web::websockets::client::websocket_outgoing_message send_websocket_msg;
std::string send_websocket_buffer(response);
send_websocket_msg.set_utf8_message(send_websocket_buffer);
client.send(send_websocket_msg).wait();
// use secure host post for LMS going forward
shbc_config = sbhc_success;
return;
}
// process any messages we can // process any messages we can
// - if success, done // - if success, done
// - if error, get out // - if error, get out
@@ -312,7 +387,7 @@ int main(int argc, char* argv[])
try try
{ {
// conntect to lms // conntect to lms
lms_socket = lms_connect(); lms_socket = lms_connect(shbc_config);
} }
catch (...) catch (...)
{ {
@@ -323,11 +398,34 @@ int main(int argc, char* argv[])
if (arg_verbose) if (arg_verbose)
{ {
std::cout << std::endl << "vvv -- message to AMT -- vvv" << std::endl; std::cout << std::endl << "vvv -- message to AMT -- vvv" << std::endl;
std::cout << payloadDecoded << std::endl;
if (shbc_config)
{
std::cout << "message size is " << payloadDecoded.size() << " bytes." << std::endl;
for (int i = 0; i < payloadDecoded.size(); i++)
{
printf("%02x ", payloadDecoded[i]);
if ((i > 0) && ((i+1) % 32 == 0))
{
std::cout << std::endl;
}
}
std::cout << std::endl;
}
else
{
for (int i = 0; i < payloadDecoded.size(); i++)
{
printf("%c", payloadDecoded[i]);
}
}
std::cout << std::endl;
} }
// send message to LMS // send message to LMS
if (send(lms_socket, payloadDecoded.c_str(), (int)payloadDecoded.length(), 0) < 0) int sendPayloudStatus = send(lms_socket, (const char *) payloadDecoded.data(), payloadDecoded.size(), 0);
if (sendPayloudStatus < 0)
{ {
throw std::runtime_error("error: socket send"); throw std::runtime_error("error: socket send");
} }
@@ -346,7 +444,8 @@ int main(int argc, char* argv[])
// read until connection is closed by LMS // read until connection is closed by LMS
while (1) while (1)
{ {
std::string superBuffer = ""; std::vector<unsigned char> superBuffer;
superBuffer.clear();
while (1) while (1)
{ {
int res = select(fd, &rset, NULL, NULL, &timeout); int res = select(fd, &rset, NULL, NULL, &timeout);
@@ -364,7 +463,9 @@ int main(int argc, char* argv[])
res = recv(lms_socket, recv_buffer, 4096, 0); res = recv(lms_socket, recv_buffer, 4096, 0);
if (res > 0) if (res > 0)
{ {
superBuffer += recv_buffer; for (int i = 0; i < res; i++) {
superBuffer.push_back(recv_buffer[i]);
}
} }
else if (res < 0) else if (res < 0)
{ {
@@ -380,16 +481,36 @@ int main(int argc, char* argv[])
} // while select() } // while select()
// if there is some data send it // if there is some data send it
if (superBuffer.length() > 0) if (superBuffer.size() > 0)
{ {
if (arg_verbose) if (arg_verbose)
{ {
std::cout << std::endl << "^^^ -- message from AMT -- ^^^" << std::endl; std::cout << std::endl << "^^^ -- message from AMT -- ^^^" << std::endl;
std::cout << superBuffer << std::endl; if (shbc_config)
{
std::cout << "message size is " << superBuffer.size() << " bytes." << std::endl;
for (int i = 0; i < superBuffer.size(); i++)
{
printf("%02x ", superBuffer[i]);
if ((i > 0) && ((i + 1) % 32 == 0))
{
std::cout << std::endl;
}
}
std::cout << std::endl;
}
else
{
for (int i = 0; i < superBuffer.size(); i++)
{
printf("%c", superBuffer[i]);
}
}
std::cout << std::endl;
} }
std::string response; std::string response;
if (!act_create_response(superBuffer.c_str(), response)) return; if (!act_create_response(superBuffer, response)) return;
web::websockets::client::websocket_outgoing_message send_websocket_msg; web::websockets::client::websocket_outgoing_message send_websocket_msg;
std::string send_websocket_buffer(response); std::string send_websocket_buffer(response);

88
shbc.cpp Normal file
View File

@@ -0,0 +1,88 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#include "activation.h"
#include <cpprest/ws_client.h>
#include <cpprest/json.h>
#include <cpprest/streams.h>
#include <iostream>
#include <string>
#include "version.h"
#include "commands.h"
#include "network.h"
#include "utils.h"
bool get_response_payload(std::string cert_algo, std::string cert_hash, web::json::value& payload)
{
web::json::value value;
utility::string_t tmp;
web::json::value configParams;
// get client string
tmp = utility::conversions::convertstring(cert_algo);
configParams[U("algorithm")] = web::json::value::string(tmp);
// get certificate hashes
tmp = utility::conversions::convertstring(cert_hash);
configParams[U("hash")] = web::json::value::string(tmp);
payload = configParams;
return true;
}
bool shbc_create_response(std::string cert_algo, std::string cert_hash, bool config_status, std::string& response)
{
web::json::value msg;
utility::string_t tmp = utility::conversions::convertstring("secure_config_response");
msg[U("method")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring("");
msg[U("apiKey")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring(PROJECT_VER);
msg[U("appVersion")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring(PROTOCOL_VERSION);
msg[U("protocolVersion")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring("");
msg[U("message")] = web::json::value::string(tmp);
if (config_status)
{
// get the activation payload
web::json::value responsePayload;
if (!get_response_payload(cert_algo, cert_hash, responsePayload)) return false;
// serialize payload
std::string serializedPayload = utility::conversions::to_utf8string(responsePayload.serialize());
std::vector<unsigned char> serializedPayloadVector;
for (int i = 0; i < serializedPayload.size(); i++)
{
serializedPayloadVector.push_back(serializedPayload[i]);
}
std::string encodedPayload = util_encode_base64(serializedPayloadVector);
utility::string_t payload = utility::conversions::to_string_t(encodedPayload);
msg[U("payload")] = web::json::value::string(payload);
tmp = utility::conversions::convertstring("success");
msg[U("status")] = web::json::value::string(tmp);
}
else
{
tmp = utility::conversions::convertstring("");
msg[U("payload")] = web::json::value::string(tmp);
tmp = utility::conversions::convertstring("failed");
msg[U("status")] = web::json::value::string(tmp);
}
// serialize the entire message
response = utility::conversions::to_utf8string(msg.serialize());
return true;
}

19
shbc.h Normal file
View File

@@ -0,0 +1,19 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#ifndef __SHBC_H__
#define __SHBC_H__
#include <string>
#ifdef _WIN32
#define convertstring to_utf16string
#else
#define convertstring to_utf8string
#endif
bool shbc_create_response(std::string cert_algo, std::string cert_hash, bool config_status, std::string& response);
#endif

View File

@@ -29,7 +29,7 @@ TEST(testUtils, isPrintableTestInvalid)
EXPECT_EQ(false, util_is_printable(s)); EXPECT_EQ(false, util_is_printable(s));
} }
/*
// Test encode of base64 string // Test encode of base64 string
TEST(testUtils, encodebase64) TEST(testUtils, encodebase64)
{ {
@@ -41,7 +41,7 @@ TEST(testUtils, decodebase64)
{ {
EXPECT_EQ(plainText, util_decode_base64(encodedText)); EXPECT_EQ(plainText, util_decode_base64(encodedText));
} }
*/
// Test return value of util_format_uuid // Test return value of util_format_uuid
TEST(testUtils, formatUUIDSuccess) TEST(testUtils, formatUUIDSuccess)
{ {

View File

@@ -8,7 +8,7 @@
#include <string> #include <string>
#include <cpprest/streams.h> #include <cpprest/streams.h>
std::string util_encode_base64(std::string str) std::string util_encode_base64(std::vector<unsigned char> str)
{ {
std::vector<unsigned char> strVector(str.begin(), str.end()); std::vector<unsigned char> strVector(str.begin(), str.end());
utility::string_t base64 = utility::conversions::to_base64(strVector); utility::string_t base64 = utility::conversions::to_base64(strVector);
@@ -17,11 +17,11 @@ std::string util_encode_base64(std::string str)
return encodedString; return encodedString;
} }
std::string util_decode_base64(std::string str) std::vector<unsigned char> util_decode_base64(std::string str)
{ {
utility::string_t serializedData = utility::conversions::to_string_t(str); utility::string_t serializedData = utility::conversions::to_string_t(str);
std::vector<unsigned char> strVector = utility::conversions::from_base64(serializedData); std::vector<unsigned char> strVector = utility::conversions::from_base64(serializedData);
std::string decodedString(strVector.begin(), strVector.end()); std::vector<unsigned char> decodedString(strVector.begin(), strVector.end());
return decodedString; return decodedString;
} }
@@ -57,3 +57,32 @@ bool util_format_uuid(std::vector<unsigned char> uuid_bytes, std::string& uuid_s
return true; return true;
} }
bool util_hex_string_to_bytes(std::string hex_string, std::vector<unsigned char>& hex_bytes)
{
hex_bytes.clear();
for (int i = 0; i < hex_string.length(); i += 2)
{
std::string byte_string = hex_string.substr(i, 2);
byte_string[0] = tolower(byte_string[0]);
byte_string[1] = tolower(byte_string[1]);
unsigned char value = (char)strtol(byte_string.c_str(), NULL, 16);
hex_bytes.push_back(value);
}
return true;
}
bool util_bytes_to_hex_string(std::vector<unsigned char> hex_bytes, std::string& hex_string)
{
hex_string.clear();
for (unsigned char hex_char : hex_bytes)
{
char hex[10];
snprintf(hex, 10, "%02x", hex_char);
hex_string += hex;
}
return true;
}

View File

@@ -9,9 +9,11 @@
#include <string> #include <string>
#include <vector> #include <vector>
std::string util_encode_base64(std::string str); std::string util_encode_base64(std::vector<unsigned char> str);
std::string util_decode_base64(std::string str); std::vector<unsigned char> util_decode_base64(std::string str);
bool util_is_printable(std::string str); bool util_is_printable(std::string str);
bool util_format_uuid(std::vector<unsigned char> uuid_bytes, std::string& uuid_string); bool util_format_uuid(std::vector<unsigned char> uuid_bytes, std::string& uuid_string);
bool util_hex_string_to_bytes(std::string hex_string, std::vector<unsigned char>& hex_bytes);
bool util_bytes_to_hex_string(std::vector<unsigned char> hex_bytes, std::string& hex_string);
#endif #endif