Device provisioning code examples
Disconnected provisioning examples
Guardian supports C#, C++, and C for disconnected provisioning.
C# example
public static void DisconnectedProvisioning()
{
medcrypt.guardian.ProvisionFilesInput provisioningFilesInput =
new medcrypt.guardian.ProvisionFilesInput();
/* Customer data about the provisioning system */
string componentHandle = "my_component_handle";
string systemId = "my_system_name";
string hardwareId = "my_serial_number";
/* Load provisioning files to input file storage buffers */
provisioningFilesInput.trustStore =
File.ReadAllBytes(@"TrustStore.mcts");
provisioningFilesInput.privateIdentity =
File.ReadAllBytes(@"PrivateIdentity.mcpip");
provisioningFilesInput.certifiedProfile =
File.ReadAllBytes(@"CertifiedProvisioningProfile.mcpp");
/* Create Guardian */
medcrypt.guardian.Guardian gdn = new medcrypt.guardian.Guardian();
/* Create default options */
medcrypt.guardian.ProvisioningGenerateOptions options =
new medcrypt.guardian.ProvisioningGenerateOptions();
/* Call generate provision request */
medcrypt.guardian.ProvisionFilesOutput provisioningOutputFiles =
gdn.GenerateProvisionRequest(
provisioningFilesInput,
options,
componentHandle,
systemId,
hardwareId);
/* Persist provision request and generated private identity */
File.WriteAllBytes(
@"GeneratedPrivateIdentity.mcpi",
provisioningOutputFiles.generatedPrivateIdentity);
File.WriteAllBytes(
@"ProvisionRequest.mcpr",
provisioningOutputFiles.provisionRequest);
}
C++ example
#include "medcrypt/guardian/GuardianSystem.h"
#include "medcrypt/guardian/Utilities/Files/FileHelpers.h"
#define MSG(x) { printf x; printf("\n"); }
#define MSG_INFO(x) { MSG(x); }
#define MSG_ERROR(x) { printf("ERROR: "); MSG(x); }
#define MSG_WARNING(x) { printf("WARNING: "); MSG(x); }
#define ARBITRARY_BUF_SIZE 2 * 1024
static const char kPrFilename[] = "ProvisionRequest.mcpr";
static const char kPiFilename[] = "PrivateIdentity.mcpi";
static bool WriteBufferToFile(
const std::string& in_filepath,
const char* in_file_contents,
const size_t in_file_size);
bool DisconnectedProvisioning()
{
medcrypt::guardian::utilities::ProvisionFiles files;
std::string in_component_handle = "my_component_handle";
std::string in_hardware_id = "my_serial_number";
std::string in_provisioning_profile_folder =
"/home/user/guardian/profiles/initial_profile";
/* Retrieve provisioning files, for an initial provision these are the actual provisioning profile files */
if (!medcrypt::guardian::utilities::GetProvisionFilesFromPath(
in_provisioning_profile_folder,
true,
&files)) {
MSG_ERROR(("could not retrieve provisioning files"));
return false;
}
/* Assign buffers to outputs */
char pr_buf[ARBITRARY_BUF_SIZE] = {0};
char gpi_buf[ARBITRARY_BUF_SIZE] = {0};
files.ProvisionRequest = pr_buf;
files.ProvisionRequestSize = sizeof(pr_buf);
files.GeneratedPrivateIdentity = gpi_buf;
files.GeneratedPrivateIdentitySize = sizeof(gpi_buf);
/* Create Guardian */
medcrypt::guardian::Guardian guardian;
medcrypt::guardian::Status status;
/* Accept input options, or create default, alias hardware id to system name, actually generate the provision request */
status = guardian.GenerateProvisionRequest(
files,
medcrypt::guardian::ProvisioningGenerateOptions(),
in_component_handle.c_str(),
in_hardware_id.c_str(),
in_hardware_id.c_str());
/* Check and print non-OK error code */
if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
MSG_ERROR(("could not generate provision request [%s]",
medcrypt::guardian::GuardianStatusEnum::NameOf(
EXTRACT_STATUS(status)).c_str()));
return false;
}
/* Write the provision request to disk */
if (!WriteBufferToFile(
in_provisioning_profile_folder + kPrFilename,
files.ProvisionRequest,
files.ProvisionRequestSize))
{
MSG_ERROR(("could not write generated provision request"));
return false;
}
/* Write the private identity to disk */
if (!WriteBufferToFile(
in_provisioning_profile_folder + kPiFilename,
files.GeneratedPrivateIdentity,
files.GeneratedPrivateIdentitySize))
{
MSG_ERROR(("could not write generated private identity"));
return false;
}
return true;
}
static bool
WriteBufferToFile(
const std::string& in_filepath,
const char* in_file_contents,
const size_t in_file_size)
{
bool return_value = false;
std::ofstream output(in_filepath, std::ios::binary);
if( output.good() &&
in_file_size <= (std::numeric_limits<std::streamsize>::max)())
{
output.write(in_file_contents, static_cast<std::streamsize>(in_file_size));
output.close();
return_value = true;
}
return return_value;
}
C example
The C interface uses streams for all large inputs and outputs. The example below will show these streams backed by buffers. Output buffers will be arbitrarily sized.
#define MAX_GDN_SIZE 15 * 1024 /* Increase as necessary, this memory does not have to be on the stack */
#define ARBITRARY_BUF_SIZE 5 * 1024 /* Increase as necessary */
static bool disconnected_provisioning()
{
mcg_status status = 0;
/* Create Guardian memory region, this memory can come from any source but must be a continuous block */
mcg_memory_t mcg_memory = {NULL, 0, 0};
uint8_t memory_buffer[MAX_GDN_SIZE] = {0};
/* Initialize file pointer storage structs along with input and output streams */
mcg_provision_files_t prov_files = {0};
mcg_provisioning_generate_options_t p_options = {0};
mcg_guardian_istream_t ts, pi, cp;
mcg_guardian_ostream_t pr = {0};
mcg_guardian_ostream_t gpi = {0};
/* Customer data about this provisioning system */
char component_handle[] = "my_component";
char system_name[] = "my_system_name";
char hardware_id[] = "my_serial_number";
mcg_memory.mem = &memory_buffer[0];
mcg_memory.size = sizeof(memory_buffer);
/* Read trust store into this buffer, and set in_ts_len to actual size */
uint8_t in_ts[ARBITRARY_BUF_SIZE] = {0};
size_t in_ts_len = 1234;
/* Read private identity into this buffer, and set in_pi_len to actual size */
uint8_t in_pi[ARBITRARY_BUF_SIZE] = {0};
size_t in_pi_len = 1234;
/* Read certified profile into this buffer, and set in_cp_len to actual size */
uint8_t in_cp_prov[ARBITRARY_BUF_SIZE] = {0};
size_t in_cp_prov_len = 1234;
/* Allocate memory for provision request and generated private identity output */
uint8_t io_pr[ARBITRARY_BUF_SIZE] = {0};
size_t io_pr_len = sizeof(pr);
uint8_t io_gpi[ARBITRARY_BUF_SIZE] = {0};
size_t io_gpi_len = sizeof(gpi);
/* Create streams from provided ts/pi/cp byte buffers */
ts = mcg_istream_from_buffer(in_ts, in_ts_len);
pi = mcg_istream_from_buffer(in_pi, in_pi_len);
cp = mcg_istream_from_buffer(in_cp_prov, in_cp_prov_len);
/* Create output streams for provision request and generated private
identity */
pr = mcg_ostream_from_buffer(io_pr, io_pr_len);
gpi = mcg_ostream_from_buffer(io_gpi, io_gpi_len);
/* Load streams into mcg_provision_files_t */
prov_files.trust_store = &ts;
prov_files.private_identity = π
prov_files.certified_profile = &cp;
prov_files.provision_request = ≺
prov_files.generated_private_identity = &gpi;
status = mcg_gdn_generate_provision_request(&mcg_memory,
&prov_files,
&p_options,
component_handle,
system_name,
hardware_id);
if (status != MCG_STATUS_OK) {
return false;
}
io_pr_len = pr.bytes_written;
io_gpi_len = gpi.bytes_written;
/* Persist PR (io_pr/io_pr_len) and GPI (io_gpi/io_gpi_len) to storage */
return true;
}
Connected device provisioning examples
Guardian supports C# and C++ for connected provisioning.
C# example
public static void ConnectedProvisioning()
{
public static void ConnectedProvisioning()
{
medcrypt.guardian.ProvisionFilesInput provisioningFilesInput =
new medcrypt.guardian.ProvisionFilesInput();
medcrypt.guardian.ProvisionFilesOutput provisioningOutputFiles =
new medcrypt.guardian.ProvisionFilesOutput();
// Complete Disconnected Provisioning as in DisconnectedProvisioning()
// The data in provisioningFilesInput and provisioningOutputFiles should
// come from the DisconnectedProvisioning() function.
//
// The static text is reproduced in this function for readability.
string componentHandle = "my_component_handle";
string hardwareId = "my_serial_number";
/* copy provisioning profile files to initialization file storage */
medcrypt.guardian.InitializeFiles initializeFiles =
new medcrypt.guardian.InitializeFiles();
initializeFiles.trustStore = provisioningFilesInput.trustStore;
initializeFiles.privateIdentity = provisioningFilesInput.privateIdentity;
initializeFiles.certifiedProfile = provisioningFilesInput.certifiedProfile;
/* initialize guardian for configured operations (connecting to backend)*/
medcrypt.guardian.Guardian gdn = new medcrypt.guardian.Guardian();
gdn.Initialize(
initializeFiles,
componentHandle,
hardwareId,
new medcrypt.guardian.InitializeOptions());
/* create default options */
medcrypt.guardian.ProvisioningOnlineOptions options =
new medcrypt.guardian.ProvisioningOnlineOptions();
/* load provision request into online files structure */
medcrypt.guardian.ProvisioningFilesOnline onlineFiles =
new medcrypt.guardian.ProvisioningFilesOnline();
onlineFiles.provisionRequest =
provisioningOutputFiles.provisionRequest;
/* start connected provisioning state machine */
gdn.StartProvisioningOnline(onlineFiles, options);
gdn.Run();
/* wait for provisioning to complete, error, or timeout to occur */
DateTime start = DateTime.Now;
TimeSpan timeout = TimeSpan.FromMinutes(2);
while (gdn.IsProvisioningRunning() &&
System.DateTime.Now - start < timeout)
{
gdn.Run();
System.Threading.Thread.Sleep(500);
}
/* persist provisioned profile */
File.WriteAllBytes(
@"CertifiedProfile.mcp",
gdn.GetProvisionedProfile());
}
}
C++ example
#define ARBITRARY_BUF_SIZE 10 * 1024
static const char kCpFilename[] = "CertifiedProfile.mcp";
bool ConnectedProvisioning()
{
The static text is reproduced in this function for readability. */
// Complete Disconnected Provisioning as in DisconnectedProvisioning()
// The data in DisconnectedProvisioning()'s "files" object should be copied
// to "in_files" in this function.
//
// The static text is reproduced in this function for readability.
medcrypt::guardian::utilities::ProvisionFiles in_files;
std::string in_component_handle = "my_component_handle";
std::string in_hardware_id = "my_serial_number";
std::string in_provisioning_profile_folder = "/home/user/guardian/profiles/initial_profile";
/* Create Guardian */
medcrypt::guardian::Guardian guardian;
medcrypt::guardian::Status status;
/* Initialize Guardian with the provided provisioning profile to enable connecting to medcrypt backend infrastructure */
medcrypt::guardian::utilities::InitializeFiles init_files;
init_files.TrustStore = in_files.TrustStore;
init_files.TrustStoreSize = in_files.TrustStoreSize;
init_files.PrivateIdentity = in_files.PrivateIdentity;
init_files.PrivateIdentitySize = in_files.PrivateIdentitySize;
init_files.CertifiedProfile = in_files.CertifiedProfile;
init_files.CertifiedProfileSize = in_files.CertifiedProfileSize;
/* Initialize provided Guardian */
status = guardian.Initialize(
init_files,
in_component_handle.c_str(),
in_hardware_id.c_str(),
medcrypt::guardian::InitializeOptions());
/* Check and print non-OK error code */
if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
MSG_ERROR(("could not initialize guardian [%s]",
medcrypt::guardian::GuardianStatusEnum::NameOf(
EXTRACT_STATUS(status)).c_str()));
return false;
}
/* Start the internal online provisioning state machine by providing it with the generated provision request */
medcrypt::guardian::utilities::ProvisionOnlineFiles online_files;
online_files.ProvisionRequest = in_files.ProvisionRequest;
online_files.ProvisionRequestSize = in_files.ProvisionRequestSize;
status = guardian.StartProvisioningOnline(
online_files,
medcrypt::guardian::ProvisioningOptions());
/* Check and print non-OK error code */
if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
MSG_ERROR(("could not start online provisioning [%s]",
medcrypt::guardian::GuardianStatusEnum::NameOf(
EXTRACT_STATUS(status)).c_str()));
return false;
}
/* Engage internal state machine */
status = guardian.Run();
/* Check and print non-OK error code */
if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
MSG_ERROR(("could not run guardian [%s]",
medcrypt::guardian::GuardianStatusEnum::NameOf(
EXTRACT_STATUS(status)).c_str()));
return false;
}
/* Wait for provisioning to complete, error, or timeout to occur */
auto start = std::chrono::steady_clock::now();
auto timeout = std::chrono::minutes(2);
while (guardian.IsProvisioningRunning() &&
((std::chrono::steady_clock::now() - start) < timeout)) {
guardian.Run();
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
/* Retrieve the received provisioned profile */
char profile[ARBITRARY_BUF_SIZE] = {0};
size_t profile_size = sizeof(profile);
status = guardian.GetProvisionedProfile(
profile,
&profile_size);
/* Check and print non-OK error code */
if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
MSG_ERROR(("could not complete online provisioning [%s]",
medcrypt::guardian::GuardianStatusEnum::NameOf(
EXTRACT_STATUS(status)).c_str()));
return false;
}
/* Write the provisioned profile to disk */
if (!WriteBufferToFile(
in_provisioning_profile_folder + kCpFilename,
profile,
profile_size))
{
MSG_ERROR(("could not write provisioned profile"));
return false;
}
return true;
}
Proxy device provisioning examples
Guardian supports C# and C++ for proxy provisioning. Since Guardian does not support connected provisioning, it cannot proxy a provision request.
C# example
public static void ConnectedProvisioning()
{
public static void ConnectedProvisioning()
{
medcrypt.guardian.ProvisionFilesInput provisioningFilesInput =
new medcrypt.guardian.ProvisionFilesInput();
medcrypt.guardian.ProvisionFilesOutput provisioningOutputFiles =
new medcrypt.guardian.ProvisionFilesOutput();
// Complete Disconnected Provisioning as in DisconnectedProvisioning()
// The data in provisioningFilesInput and provisioningOutputFiles should
// come from the DisconnectedProvisioning() function.
//
// The static text is reproduced in this function for readability.
string componentHandle = "my_component_handle";
string hardwareId = "my_serial_number";
/* Copy provisioning profile files to initialization file storage */
medcrypt.guardian.InitializeFiles initializeFiles =
new medcrypt.guardian.InitializeFiles();
initializeFiles.trustStore = provisioningFilesInput.trustStore;
initializeFiles.privateIdentity = provisioningFilesInput.privateIdentity;
initializeFiles.certifiedProfile = provisioningFilesInput.certifiedProfile;
/* Initialize Guardian for configured operations (connecting to backend)*/
medcrypt.guardian.Guardian gdn = new medcrypt.guardian.Guardian();
gdn.Initialize(
initializeFiles,
componentHandle,
hardwareId,
new medcrypt.guardian.InitializeOptions());
/* Create default options */
medcrypt.guardian.ProvisioningOnlineOptions options =
new medcrypt.guardian.ProvisioningOnlineOptions();
/* Load provision request into online files structure */
medcrypt.guardian.ProvisioningFilesOnline onlineFiles =
new medcrypt.guardian.ProvisioningFilesOnline();
onlineFiles.provisionRequest =
File.ReadAllBytes(@"ProxiedProvisionRequest.mcpr");
/* Start connected provisioning state machine */
gdn.StartProvisioningOnline(onlineFiles, options);
gdn.Run();
/* Wait for provisioning to complete, error, or timeout to occur */
DateTime start = DateTime.Now;
TimeSpan timeout = TimeSpan.FromMinutes(2);
while (gdn.IsProvisioningRunning() &&
System.DateTime.Now - start < timeout)
{
gdn.Run();
System.Threading.Thread.Sleep(500);
}
/* Persist provisioned profile */
File.WriteAllBytes(
@"CertifiedProfile.mcp",
gdn.GetProvisionedProfile());
}
}
C++ example
#define ARBITRARY_BUF_SIZE 10 * 1024
static const char kCpFilename[] = "CertifiedProfile.mcp";
bool ConnectedProvisioning()
{
/* Complete Disconnected Provisioning as in DisconnectedProvisioning(). The data in from DisconnectedProvisioning()'s "files" object should be copied to "in_files" in this function.
The static text is reproduced in this function for readability. */
medcrypt::guardian::utilities::ProvisionFiles in_files;
std::string in_component_handle = "my_component_handle";
std::string in_hardware_id = "my_serial_number";
std::string in_provisioning_profile_folder = "/home/user/guardian/profiles/initial_profile";
/* Create Guardian */
medcrypt::guardian::Guardian guardian;
medcrypt::guardian::Status status;
/* Initialize Guardian with the provided provisioning profile to enable connecting to medcrypt backend infrastructure */
medcrypt::guardian::utilities::InitializeFiles init_files;
init_files.TrustStore = in_files.TrustStore;
init_files.TrustStoreSize = in_files.TrustStoreSize;
init_files.PrivateIdentity = in_files.PrivateIdentity;
init_files.PrivateIdentitySize = in_files.PrivateIdentitySize;
init_files.CertifiedProfile = in_files.CertifiedProfile;
init_files.CertifiedProfileSize = in_files.CertifiedProfileSize;
/* Initialize provided Guardian */
status = guardian.Initialize(
init_files,
in_component_handle.c_str(),
in_hardware_id.c_str(),
medcrypt::guardian::InitializeOptions());
/* Check and print non-OK error code */
if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
MSG_ERROR(("could not initialize guardian [%s]",
medcrypt::guardian::GuardianStatusEnum::NameOf(
EXTRACT_STATUS(status)).c_str()));
return false;
}
/* Start the internal online provisioning state machine by providing it with the generated provision request */
medcrypt::guardian::utilities::ProvisionOnlineFiles online_files;
online_files.ProvisionRequest = in_files.ProvisionRequest;
online_files.ProvisionRequestSize = in_files.ProvisionRequestSize;
/* Load proxy Provision Request to a buffer and size here */
char pr_buf[2048] = {0};
size_t pr_buf_size = sizeof(buf);
/* Start the internal online provisioning state machine by
providing it with the generated disconnected provision request */
medcrypt::guardian::utilities::ProvisionOnlineFiles online_files;
online_files.ProvisionRequest = pr_buf;
online_files.ProvisionRequestSize = pr_buf_size;
status = guardian.StartProvisioningOnline(
online_files,
medcrypt::guardian::ProvisioningOptions());
/* Check and print non-OK error code */
if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
MSG_ERROR(("could not start online provisioning [%s]",
medcrypt::guardian::GuardianStatusEnum::NameOf(
EXTRACT_STATUS(status)).c_str()));
return false;
}
/* Engage internal state machine */
status = guardian.Run();
/* Check and print non_OK error code */
if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
MSG_ERROR(("could not run guardian [%s]",
medcrypt::guardian::GuardianStatusEnum::NameOf(
EXTRACT_STATUS(status)).c_str()));
return false;
}
/* Wait for provisioning to complete, error, or timeout to occur */
auto start = std::chrono::steady_clock::now();
auto timeout = std::chrono::minutes(2);
while (guardian.IsProvisioningRunning() &&
((std::chrono::steady_clock::now() - start) < timeout)) {
guardian.Run();
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
/* Retrieve the received provisioned profile*/
char profile[ARBITRARY_BUF_SIZE] = {0};
size_t profile_size = sizeof(profile);
status = guardian.GetProvisionedProfile(
profile,
&profile_size);
/* Check and print non-OK error code */
if (EXTRACT_STATUS(status) != medcrypt::guardian::GuardianStatusEnum::OK) {
MSG_ERROR(("could not complete online provisioning [%s]",
medcrypt::guardian::GuardianStatusEnum::NameOf(
EXTRACT_STATUS(status)).c_str()));
return false;
}
/* Write the provisioned profile to disk */
if (!WriteBufferToFile(
in_provisioning_profile_folder + kCpFilename,
profile,
profile_size))
{
MSG_ERROR(("could not write provisioned profile"));
return false;
}
return true;
}
Last updated
Was this helpful?