BUFFER_HANDLE secure_dev_tpm_sign_data(SEC_DEVICE_HANDLE handle, const unsigned char* data, size_t data_len) { BUFFER_HANDLE result; /* Codes_SRS_SECURE_DEVICE_TPM_07_020: [ If handle or data is NULL or data_len is 0, secure_dev_tpm_sign_data shall return NULL. ] */ if (handle == NULL || data == NULL || data_len == 0) { LogError("Invalid handle value specified handle: %p, data: %p", handle, data); result = NULL; } else { BYTE data_signature[1024]; BYTE* data_copy = (unsigned char*)data; /* Codes_SRS_SECURE_DEVICE_TPM_07_021: [ secure_dev_tpm_sign_data shall call into the tpm to hash the supplied data value. ] */ uint32_t sign_len = SignData(&handle->tpm_device, &NullPwSession, data_copy, data_len, data_signature, sizeof(data_signature) ); if (sign_len == 0) { /* Codes_SRS_SECURE_DEVICE_TPM_07_023: [ If an error is encountered secure_dev_tpm_sign_data shall return NULL. ] */ LogError("Failure signing data from hash"); result = NULL; } else { /* Codes_SRS_SECURE_DEVICE_TPM_07_022: [ If hashing the data was successful, secure_dev_tpm_sign_data shall create a BUFFER_HANDLE with the supplied signed data. ] */ result = BUFFER_create(data_signature, sign_len); if (result == NULL) { /* Codes_SRS_SECURE_DEVICE_TPM_07_023: [ If an error is encountered secure_dev_tpm_sign_data shall return NULL. ] */ LogError("Failure allocating sign data"); } } } return result; }
static BUFFER_HANDLE constructDeviceJson(IOTHUB_ACCOUNT_INFO* accountInfo) { BUFFER_HANDLE result; size_t len = strlen(DEVICE_JSON_FMT) + strlen(accountInfo->deviceId); char* deviceJson = (char*)malloc(len + 1); if (deviceJson == NULL) { LogError("Failure allocating device Json.\r\n"); free(accountInfo->deviceId); } else { int dataLen = sprintf_s(deviceJson, len + 1, DEVICE_JSON_FMT, accountInfo->deviceId); if (dataLen <= 0) { LogError("Failure constructing device Json.\r\n"); free(accountInfo->deviceId); } else { result = BUFFER_create(deviceJson, dataLen); if (result == NULL) { LogError("Failure creating Json buffer.\r\n"); accountInfo->deviceId = NULL; } } free(deviceJson); } return result; }
BUFFER_HANDLE prov_auth_get_storage_key(PROV_AUTH_HANDLE handle) { BUFFER_HANDLE result; /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_024: [ If handle is NULL prov_auth_get_storage_key shall return NULL. ] */ if (handle == NULL) { LogError("Invalid handle parameter"); result = NULL; } else if (handle->sec_type != PROV_AUTH_TYPE_TPM) { /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_026: [ If the sec_type is PROV_AUTH_TYPE_X509, prov_auth_get_storage_key shall return NULL. ] */ LogError("Invalid type for operation"); result = NULL; } else { unsigned char* srk_value; size_t srk_len; if (handle->hsm_client_get_srk(handle->hsm_client_handle, &srk_value, &srk_len) != 0) { LogError("Failed getting storage root key"); result = NULL; } else { /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_025: [ prov_auth_get_storage_key shall return the endorsement key returned by the hsm_client_get_srk secure enclave function. ] */ result = BUFFER_create(srk_value, srk_len); if (result == NULL) { LogError("Failed creating BUFFER HANDLE"); } free(srk_value); } } return result; }
static BUFFER_HANDLE createMethodPayloadJson(const char* methodName, unsigned int timeout, const char* payload) { STRING_HANDLE stringHandle; const char* stringHandle_c_str; BUFFER_HANDLE result; if ((stringHandle = STRING_construct_sprintf(RELATIVE_PATH_FMT_DEVIECMETHOD_PAYLOAD, methodName, timeout, payload)) == NULL) { LogError("STRING_construct_sprintf failed"); result = NULL; } else if ((stringHandle_c_str = STRING_c_str(stringHandle)) == NULL) { LogError("STRING_c_str failed"); STRING_delete(stringHandle); result = NULL; } else { result = BUFFER_create((const unsigned char*)stringHandle_c_str, strlen(stringHandle_c_str)); STRING_delete(stringHandle); } return result; }
IOTHUB_MESSAGE_HANDLE IoTHubMessage_CreateFromByteArray(const unsigned char* byteArray, size_t size) { IOTHUB_MESSAGE_HANDLE_DATA* result; result = malloc(sizeof(IOTHUB_MESSAGE_HANDLE_DATA)); if (result == NULL) { LogError("unable to malloc\r\n"); /*Codes_SRS_IOTHUBMESSAGE_02_024: [If there are any errors then IoTHubMessage_CreateFromByteArray shall return NULL.] */ /*let it go through*/ } else { const unsigned char* source; unsigned char temp = 0x00; if (size != 0) { /*Codes_SRS_IOTHUBMESSAGE_06_002: [If size is NOT zero then byteArray MUST NOT be NULL*/ if (byteArray == NULL) { LogError("Attempted to create a Hub Message from a NULL pointer!\r\n"); free(result); result = NULL; source = NULL; } else { source = byteArray; } } else { /*Codes_SRS_IOTHUBMESSAGE_06_001: [If size is zero then byteArray may be NULL.]*/ source = &temp; } if (result != NULL) { /*Codes_SRS_IOTHUBMESSAGE_02_022: [IoTHubMessage_CreateFromByteArray shall call BUFFER_create passing byteArray and size as parameters.] */ if ((result->value.byteArray = BUFFER_create(source, size)) == NULL) { LogError("BUFFER_create failed\r\n"); /*Codes_SRS_IOTHUBMESSAGE_02_024: [If there are any errors then IoTHubMessage_CreateFromByteArray shall return NULL.] */ free(result); result = NULL; } /*Codes_SRS_IOTHUBMESSAGE_02_023: [IoTHubMessage_CreateFromByteArray shall call Map_Create to create the message properties.] */ else if ((result->properties = Map_Create(ValidateAsciiCharactersFilter)) == NULL) { LogError("Map_Create failed\r\n"); /*Codes_SRS_IOTHUBMESSAGE_02_024: [If there are any errors then IoTHubMessage_CreateFromByteArray shall return NULL.] */ BUFFER_delete(result->value.byteArray); free(result); result = NULL; } else { /*Codes_SRS_IOTHUBMESSAGE_02_025: [Otherwise, IoTHubMessage_CreateFromByteArray shall return a non-NULL handle.] */ /*Codes_SRS_IOTHUBMESSAGE_02_026: [The type of the new message shall be IOTHUBMESSAGE_BYTEARRAY.] */ result->contentType = IOTHUBMESSAGE_BYTEARRAY; result->messageId = NULL; result->correlationId = NULL; /*all is fine, return result*/ } } } return result; }
BLOB_RESULT Blob_UploadFromSasUri(const char* SASURI, const unsigned char* source, size_t size) { BLOB_RESULT result; /*Codes_SRS_BLOB_02_001: [ If SASURI is NULL then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ if (SASURI == NULL) { LogError("parameter SASURI is NULL"); result = BLOB_INVALID_ARG; } else { /*Codes_SRS_BLOB_02_002: [ If source is NULL and size is not zero then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ if ( (size > 0) && (source == NULL) ) { LogError("combination of source = %p and size = %zd is invalid", source, size); result = BLOB_INVALID_ARG; } /*Codes_SRS_BLOB_02_003: [ If size is bigger or equal to 64M then Blob_UploadFromSasUri shall fail and return BLOB_NOT_IMPLEMENTED. ]*/ else if (size >= 64 * 1024 * 1024) { LogError("upload of files greater than 64M is not implemented"); result = BLOB_NOT_IMPLEMENTED; } else { /*Codes_SRS_BLOB_02_004: [ Blob_UploadFromSasUri shall copy from SASURI the hostname to a new const char*. ]*/ /*to find the hostname, the following logic is applied:*/ /*the hostname starts at the first character after ":\\"*/ /*the hostname ends at the first character before the next "\" after ":\\"*/ const char* hostnameBegin = strstr(SASURI, ":\\\\"); if (hostnameBegin == NULL) { /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ LogError("hostname cannot be determined"); result = BLOB_INVALID_ARG; } else { hostnameBegin += 3; /*have to skip 3 characters which are ":\\"*/ const char* hostnameEnd = strchr(hostnameBegin, '\\'); if (hostnameEnd == NULL) { /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ LogError("hostname cannot be determined"); result = BLOB_INVALID_ARG; } else { size_t hostnameSize = hostnameEnd - hostnameBegin; char* hostname = (char*)malloc(hostnameSize + 1); /*+1 because of '\0' at the end*/ if (hostname == NULL) { /*Codes_SRS_BLOB_02_016: [ If the hostname copy cannot be made then then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("oom - out of memory"); result = BLOB_ERROR; } else { HTTPAPIEX_HANDLE httpApiExHandle; memcpy(hostname, hostnameBegin, hostnameSize); hostname[hostnameSize] = '\0'; /*Codes_SRS_BLOB_02_006: [ Blob_UploadFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/ httpApiExHandle = HTTPAPIEX_Create(hostname); if (httpApiExHandle == NULL) { /*Codes_SRS_BLOB_02_007: [ If HTTPAPIEX_Create fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/ LogError("unable to create a HTTPAPIEX_HANDLE"); result = BLOB_ERROR; } else { /*Codes_SRS_BLOB_02_008: [ Blob_UploadFromSasUri shall compute the relative path of the request from the SASURI parameter. ]*/ const char* relativePath = hostnameEnd; /*this is where the relative path begins in the SasUri*/ /*Codes_SRS_BLOB_02_010: [ Blob_UploadFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/ BUFFER_HANDLE requestBuffer = BUFFER_create(source, size); if (requestBuffer == NULL) { /*Codes_SRS_BLOB_02_011: [ If any of the previous steps related to building the HTTPAPI_EX_ExecuteRequest parameters fails, then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/ LogError("unable to BUFFER_create"); result = BLOB_ERROR; } else { /*Codes_SRS_BLOB_02_009: [ Blob_UploadFromSasUri shall create an HTTP_HEADERS_HANDLE for the request HTTP headers carrying the following headers: ]*/ HTTP_HEADERS_HANDLE requestHttpHeaders = HTTPHeaders_Alloc(); if (requestHttpHeaders == NULL) { /*Codes_SRS_BLOB_02_011: [ If any of the previous steps related to building the HTTPAPI_EX_ExecuteRequest parameters fails, then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/ LogError("unable to HTTPHeaders_Alloc"); result = BLOB_ERROR; } else { if (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, "x-ms-blob-type", "BlockBlob") != HTTP_HEADERS_OK) { /*Codes_SRS_BLOB_02_011: [ If any of the previous steps related to building the HTTPAPI_EX_ExecuteRequest parameters fails, then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/ LogError("unable to HTTPHeaders_AddHeaderNameValuePair"); result = BLOB_ERROR; } else { int statusCode; /*Codes_SRS_BLOB_02_012: [ Blob_UploadFromSasUri shall call HTTPAPIEX_ExecuteRequest passing the parameters previously build. ]*/ if (HTTPAPIEX_ExecuteRequest(httpApiExHandle, HTTPAPI_REQUEST_PUT, relativePath, requestHttpHeaders, requestBuffer, &statusCode, NULL, NULL) != HTTPAPIEX_OK) { /*Codes_SRS_BLOB_02_013: [ If HTTPAPIEX_ExecuteRequest fails, then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/ LogError("failed to HTTPAPIEX_ExecuteRequest"); result = BLOB_HTTP_ERROR; } else { if (statusCode >= 300) { /*Codes_SRS_BLOB_02_014: [ If the statusCode returned by HTTPAPIEX_ExecuteRequest is greater or equal to 300, then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/ LogError("server returns %d HTTP code", statusCode); result = BLOB_HTTP_ERROR; } else { /*Codes_SRS_BLOB_02_015: [ Otherwise, HTTPAPIEX_ExecuteRequest shall succeed and return BLOB_OK. ]*/ result = BLOB_OK; } } } HTTPHeaders_Free(requestHttpHeaders); } BUFFER_delete(requestBuffer); } HTTPAPIEX_Destroy(httpApiExHandle); } free(hostname); } } } } } return result; }
static void compile_file(const char *file) { int i; time_t time_src, time_form, time_pot, time_output; char *source; COMPILE_begin(file, main_trans, main_debug); if (!main_compile_all) { if (FILE_exist(JOB->output)) { time_src = FILE_get_time(JOB->name); time_output = FILE_get_time(JOB->output); if (JOB->form) time_form = FILE_get_time(JOB->form); else time_form = time_src; if (main_trans) time_pot = FILE_get_time(JOB->tname); else time_pot = time_src; if (time_src <= time_output && time_src <= time_pot && time_form <= time_output) goto _FIN; } } JOB->all = main_compile_all; JOB->exec = main_exec; JOB->verbose = main_verbose; JOB->warnings = main_warnings; JOB->swap = main_swap; JOB->public_module = main_public_module; JOB->no_old_read_syntax = main_no_old_read_syntax; //JOB->class_file = main_class_file; if (JOB->verbose) { putchar('\n'); for (i = 1; i <= 9; i++) printf("--------"); printf("\nCompiling %s...\n", FILE_get_name(JOB->name)); } JOB->first_line = 1; if (JOB->form) { JOB->first_line = FORM_FIRST_LINE; BUFFER_add(&JOB->source, "#Line " FORM_FIRST_LINE_STRING "\n", -1); BUFFER_create(&source); BUFFER_load_file(&source, JOB->form); BUFFER_add(&source, "\n\0", 2); switch (JOB->family->type) { case FORM_WEBPAGE: FORM_webpage(source); break; case FORM_NORMAL: default: FORM_do(source, main_public); break; } BUFFER_delete(&source); BUFFER_add(&JOB->source, "#Line 1\n", -1); } COMPILE_load(); BUFFER_add(&JOB->source, "\n\0", 2); #if 0 fprintf(stderr, "-----------------\n"); fputs(JOB->source, stderr); fprintf(stderr, "-----------------\n"); #endif READ_do(); #ifdef DEBUG TABLE_print(JOB->class->table, TRUE); #endif HEADER_do(); TRANS_code(); #ifdef DEBUG TABLE_print(JOB->class->string, FALSE); #endif OUTPUT_do(main_swap); CLASS_export(); _FIN: COMPILE_end(); }
BLOB_RESULT Blob_UploadFromSasUri(const char* SASURI, const unsigned char* source, size_t size, unsigned int* httpStatus, BUFFER_HANDLE httpResponse) { BLOB_RESULT result; /*Codes_SRS_BLOB_02_001: [ If SASURI is NULL then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ if (SASURI == NULL) { LogError("parameter SASURI is NULL"); result = BLOB_INVALID_ARG; } else { /*Codes_SRS_BLOB_02_002: [ If source is NULL and size is not zero then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ if ( (size > 0) && (source == NULL) ) { LogError("combination of source = %p and size = %zu is invalid", source, size); result = BLOB_INVALID_ARG; } /*Codes_SRS_BLOB_02_034: [ If size is bigger than 50000*4*1024*1024 then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ else if (size > 50000ULL * 4 * 1024 * 1024) /*https://msdn.microsoft.com/en-us/library/azure/dd179467.aspx says "Each block can be a different size, up to a maximum of 4 MB, and a block blob can include a maximum of 50,000 blocks."*/ { LogError("size too big (%zu)", size); result = BLOB_INVALID_ARG; } else { /*Codes_SRS_BLOB_02_017: [ Blob_UploadFromSasUri shall copy from SASURI the hostname to a new const char* ]*/ /*Codes_SRS_BLOB_02_004: [ Blob_UploadFromSasUri shall copy from SASURI the hostname to a new const char*. ]*/ /*to find the hostname, the following logic is applied:*/ /*the hostname starts at the first character after "://"*/ /*the hostname ends at the first character before the next "/" after "://"*/ const char* hostnameBegin = strstr(SASURI, "://"); if (hostnameBegin == NULL) { /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ LogError("hostname cannot be determined"); result = BLOB_INVALID_ARG; } else { hostnameBegin += 3; /*have to skip 3 characters which are "://"*/ const char* hostnameEnd = strchr(hostnameBegin, '/'); if (hostnameEnd == NULL) { /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ LogError("hostname cannot be determined"); result = BLOB_INVALID_ARG; } else { size_t hostnameSize = hostnameEnd - hostnameBegin; char* hostname = (char*)malloc(hostnameSize + 1); /*+1 because of '\0' at the end*/ if (hostname == NULL) { /*Codes_SRS_BLOB_02_016: [ If the hostname copy cannot be made then then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("oom - out of memory"); result = BLOB_ERROR; } else { HTTPAPIEX_HANDLE httpApiExHandle; memcpy(hostname, hostnameBegin, hostnameSize); hostname[hostnameSize] = '\0'; /*Codes_SRS_BLOB_02_006: [ Blob_UploadFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/ /*Codes_SRS_BLOB_02_018: [ Blob_UploadFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/ httpApiExHandle = HTTPAPIEX_Create(hostname); if (httpApiExHandle == NULL) { /*Codes_SRS_BLOB_02_007: [ If HTTPAPIEX_Create fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/ LogError("unable to create a HTTPAPIEX_HANDLE"); result = BLOB_ERROR; } else { /*Codes_SRS_BLOB_02_008: [ Blob_UploadFromSasUri shall compute the relative path of the request from the SASURI parameter. ]*/ /*Codes_SRS_BLOB_02_019: [ Blob_UploadFromSasUri shall compute the base relative path of the request from the SASURI parameter. ]*/ const char* relativePath = hostnameEnd; /*this is where the relative path begins in the SasUri*/ if (size < 64 * 1024 * 1024) /*code path for sizes <64MB*/ { /*Codes_SRS_BLOB_02_010: [ Blob_UploadFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/ BUFFER_HANDLE requestBuffer = BUFFER_create(source, size); if (requestBuffer == NULL) { /*Codes_SRS_BLOB_02_011: [ If any of the previous steps related to building the HTTPAPI_EX_ExecuteRequest parameters fails, then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/ LogError("unable to BUFFER_create"); result = BLOB_ERROR; } else { /*Codes_SRS_BLOB_02_009: [ Blob_UploadFromSasUri shall create an HTTP_HEADERS_HANDLE for the request HTTP headers carrying the following headers: ]*/ HTTP_HEADERS_HANDLE requestHttpHeaders = HTTPHeaders_Alloc(); if (requestHttpHeaders == NULL) { /*Codes_SRS_BLOB_02_011: [ If any of the previous steps related to building the HTTPAPI_EX_ExecuteRequest parameters fails, then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/ LogError("unable to HTTPHeaders_Alloc"); result = BLOB_ERROR; } else { if (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, "x-ms-blob-type", "BlockBlob") != HTTP_HEADERS_OK) { /*Codes_SRS_BLOB_02_011: [ If any of the previous steps related to building the HTTPAPI_EX_ExecuteRequest parameters fails, then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/ LogError("unable to HTTPHeaders_AddHeaderNameValuePair"); result = BLOB_ERROR; } else { /*Codes_SRS_BLOB_02_012: [ Blob_UploadFromSasUri shall call HTTPAPIEX_ExecuteRequest passing the parameters previously build, httpStatus and httpResponse ]*/ if (HTTPAPIEX_ExecuteRequest(httpApiExHandle, HTTPAPI_REQUEST_PUT, relativePath, requestHttpHeaders, requestBuffer, httpStatus, NULL, httpResponse) != HTTPAPIEX_OK) { /*Codes_SRS_BLOB_02_013: [ If HTTPAPIEX_ExecuteRequest fails, then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/ LogError("failed to HTTPAPIEX_ExecuteRequest"); result = BLOB_HTTP_ERROR; } else { /*Codes_SRS_BLOB_02_015: [ Otherwise, HTTPAPIEX_ExecuteRequest shall succeed and return BLOB_OK. ]*/ result = BLOB_OK; } } HTTPHeaders_Free(requestHttpHeaders); } BUFFER_delete(requestBuffer); } } else /*code path for size >= 64MB*/ { size_t toUpload = size; /*Codes_SRS_BLOB_02_028: [ Blob_UploadFromSasUri shall construct an XML string with the following content: ]*/ STRING_HANDLE xml = STRING_construct("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<BlockList>"); /*the XML "build as we go"*/ if (xml == NULL) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("failed to STRING_construct"); result = BLOB_HTTP_ERROR; } else { /*Codes_SRS_BLOB_02_021: [ For every block of 4MB the following operations shall happen: ]*/ unsigned int blockID = 0; result = BLOB_ERROR; int isError = 0; /*used to cleanly exit the loop*/ do { /*setting this block size*/ size_t thisBlockSize = (toUpload > BLOCK_SIZE) ? BLOCK_SIZE : toUpload; /*Codes_SRS_BLOB_02_020: [ Blob_UploadFromSasUri shall construct a BASE64 encoded string from the block ID (000000... 0499999) ]*/ char temp[7]; /*this will contain 000000... 049999*/ if (sprintf(temp, "%6u", (unsigned int)blockID) != 6) /*produces 000000... 049999*/ { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("failed to sprintf"); result = BLOB_ERROR; isError = 1; } else { STRING_HANDLE blockIdString = Base64_Encode_Bytes((const unsigned char*)temp, 6); if (blockIdString == NULL) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("unable to Base64_Encode_Bytes"); result = BLOB_ERROR; isError = 1; } else { /*add the blockId base64 encoded to the XML*/ if (!( (STRING_concat(xml, "<Latest>")==0) && (STRING_concat_with_STRING(xml, blockIdString)==0) && (STRING_concat(xml, "</Latest>") == 0) )) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("unable to STRING_concat"); result = BLOB_ERROR; isError = 1; } else { /*Codes_SRS_BLOB_02_022: [ Blob_UploadFromSasUri shall construct a new relativePath from following string: base relativePath + "&comp=block&blockid=BASE64 encoded string of blockId" ]*/ STRING_HANDLE newRelativePath = STRING_construct(relativePath); if (newRelativePath == NULL) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("unable to STRING_construct"); result = BLOB_ERROR; isError = 1; } else { if (!( (STRING_concat(newRelativePath, "&comp=block&blockid=") == 0) && (STRING_concat_with_STRING(newRelativePath, blockIdString) == 0) )) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("unable to STRING concatenate"); result = BLOB_ERROR; isError = 1; } else { /*Codes_SRS_BLOB_02_023: [ Blob_UploadFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/ BUFFER_HANDLE requestContent = BUFFER_create(source + (size - toUpload), thisBlockSize); if (requestContent == NULL) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("unable to BUFFER_create"); result = BLOB_ERROR; isError = 1; } else { /*Codes_SRS_BLOB_02_024: [ Blob_UploadFromSasUri shall call HTTPAPIEX_ExecuteRequest with a PUT operation, passing httpStatus and httpResponse. ]*/ if (HTTPAPIEX_ExecuteRequest( httpApiExHandle, HTTPAPI_REQUEST_PUT, STRING_c_str(newRelativePath), NULL, requestContent, httpStatus, NULL, httpResponse) != HTTPAPIEX_OK ) { /*Codes_SRS_BLOB_02_025: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/ LogError("unable to HTTPAPIEX_ExecuteRequest"); result = BLOB_HTTP_ERROR; isError = 1; } else if (*httpStatus >= 300) { /*Codes_SRS_BLOB_02_026: [ Otherwise, if HTTP response code is >=300 then Blob_UploadFromSasUri shall succeed and return BLOB_OK. ]*/ LogError("HTTP status from storage does not indicate success (%d)", (int)*httpStatus); result = BLOB_OK; isError = 1; } else { /*Codes_SRS_BLOB_02_027: [ Otherwise Blob_UploadFromSasUri shall continue execution. ]*/ } BUFFER_delete(requestContent); } } STRING_delete(newRelativePath); } } STRING_delete(blockIdString); } } blockID++; toUpload -= thisBlockSize; } while ((toUpload > 0) && !isError); if (isError) { /*do nothing, it will be reported "as is"*/ } else { /*complete the XML*/ if (STRING_concat(xml, "</BlockList>") != 0) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("failed to STRING_concat"); result = BLOB_ERROR; } else { /*Codes_SRS_BLOB_02_029: [Blob_UploadFromSasUri shall construct a new relativePath from following string : base relativePath + "&comp=blocklist"]*/ STRING_HANDLE newRelativePath = STRING_construct(relativePath); if (newRelativePath == NULL) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("failed to STRING_construct"); result = BLOB_ERROR; } else { if (STRING_concat(newRelativePath, "&comp=blocklist") != 0) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("failed to STRING_concat"); result = BLOB_ERROR; } else { /*Codes_SRS_BLOB_02_030: [ Blob_UploadFromSasUri shall call HTTPAPIEX_ExecuteRequest with a PUT operation, passing the new relativePath, httpStatus and httpResponse and the XML string as content. ]*/ const char* s = STRING_c_str(xml); BUFFER_HANDLE xmlAsBuffer = BUFFER_create((const unsigned char*)s, strlen(s)); if (xmlAsBuffer == NULL) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("failed to BUFFER_create"); result = BLOB_ERROR; } else { if (HTTPAPIEX_ExecuteRequest( httpApiExHandle, HTTPAPI_REQUEST_PUT, STRING_c_str(newRelativePath), NULL, xmlAsBuffer, httpStatus, NULL, httpResponse ) != HTTPAPIEX_OK) { /*Codes_SRS_BLOB_02_031: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/ LogError("unable to HTTPAPIEX_ExecuteRequest"); result = BLOB_HTTP_ERROR; } else { /*Codes_SRS_BLOB_02_032: [ Otherwise, Blob_UploadFromSasUri shall succeed and return BLOB_OK. ]*/ result = BLOB_OK; } BUFFER_delete(xmlAsBuffer); } } STRING_delete(newRelativePath); } } } STRING_delete(xml); } } HTTPAPIEX_Destroy(httpApiExHandle); } free(hostname); } } } } } return result; }
BLOB_RESULT Blob_UploadMultipleBlocksFromSasUri(const char* SASURI, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx, void* context, unsigned int* httpStatus, BUFFER_HANDLE httpResponse, const char* certificates, HTTP_PROXY_OPTIONS *proxyOptions) { BLOB_RESULT result; /*Codes_SRS_BLOB_02_001: [ If SASURI is NULL then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ if (SASURI == NULL) { LogError("parameter SASURI is NULL"); result = BLOB_INVALID_ARG; } else { /*Codes_SRS_BLOB_02_002: [ If getDataCallbackEx is NULL then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ if (getDataCallbackEx == NULL) { LogError("IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx is NULL"); result = BLOB_INVALID_ARG; } /*the below define avoid a "condition always false" on some compilers*/ else { /*Codes_SRS_BLOB_02_017: [ Blob_UploadMultipleBlocksFromSasUri shall copy from SASURI the hostname to a new const char* ]*/ /*to find the hostname, the following logic is applied:*/ /*the hostname starts at the first character after "://"*/ /*the hostname ends at the first character before the next "/" after "://"*/ const char* hostnameBegin = strstr(SASURI, "://"); if (hostnameBegin == NULL) { /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ LogError("hostname cannot be determined"); result = BLOB_INVALID_ARG; } else { hostnameBegin += 3; /*have to skip 3 characters which are "://"*/ const char* hostnameEnd = strchr(hostnameBegin, '/'); if (hostnameEnd == NULL) { /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ LogError("hostname cannot be determined"); result = BLOB_INVALID_ARG; } else { size_t hostnameSize = hostnameEnd - hostnameBegin; char* hostname = (char*)malloc(hostnameSize + 1); /*+1 because of '\0' at the end*/ if (hostname == NULL) { /*Codes_SRS_BLOB_02_016: [ If the hostname copy cannot be made then then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("oom - out of memory"); result = BLOB_ERROR; } else { HTTPAPIEX_HANDLE httpApiExHandle; (void)memcpy(hostname, hostnameBegin, hostnameSize); hostname[hostnameSize] = '\0'; /*Codes_SRS_BLOB_02_018: [ Blob_UploadMultipleBlocksFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/ httpApiExHandle = HTTPAPIEX_Create(hostname); if (httpApiExHandle == NULL) { /*Codes_SRS_BLOB_02_007: [ If HTTPAPIEX_Create fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR. ]*/ LogError("unable to create a HTTPAPIEX_HANDLE"); result = BLOB_ERROR; } else { if ((certificates != NULL)&& (HTTPAPIEX_SetOption(httpApiExHandle, "TrustedCerts", certificates) == HTTPAPIEX_ERROR)) { LogError("failure in setting trusted certificates"); result = BLOB_ERROR; } else if ((proxyOptions != NULL && proxyOptions->host_address != NULL) && HTTPAPIEX_SetOption(httpApiExHandle, OPTION_HTTP_PROXY, proxyOptions) == HTTPAPIEX_ERROR) { LogError("failure in setting proxy options"); result = BLOB_ERROR; } else { /*Codes_SRS_BLOB_02_019: [ Blob_UploadMultipleBlocksFromSasUri shall compute the base relative path of the request from the SASURI parameter. ]*/ const char* relativePath = hostnameEnd; /*this is where the relative path begins in the SasUri*/ /*Codes_SRS_BLOB_02_028: [ Blob_UploadMultipleBlocksFromSasUri shall construct an XML string with the following content: ]*/ STRING_HANDLE blockIDList = STRING_construct("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<BlockList>"); /*the XML "build as we go"*/ if (blockIDList == NULL) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("failed to STRING_construct"); result = BLOB_HTTP_ERROR; } else { /*Codes_SRS_BLOB_02_021: [ For every block returned by `getDataCallbackEx` the following operations shall happen: ]*/ unsigned int blockID = 0; /* incremented for each new block */ unsigned int isError = 0; /* set to 1 if a block upload fails or if getDataCallbackEx returns incorrect blocks to upload */ unsigned int uploadOneMoreBlock = 1; /* set to 1 while getDataCallbackEx returns correct blocks to upload */ unsigned char const * source; /* data set by getDataCallbackEx */ size_t size; /* source size set by getDataCallbackEx */ IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT getDataReturnValue; do { getDataReturnValue = getDataCallbackEx(FILE_UPLOAD_OK, &source, &size, context); if (getDataReturnValue == IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_ABORT) { /*Codes_SRS_BLOB_99_004: [ If `getDataCallbackEx` returns `IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT_ABORT`, then `Blob_UploadMultipleBlocksFromSasUri` shall exit the loop and return `BLOB_ABORTED`. ]*/ LogInfo("Upload to blob has been aborted by the user"); uploadOneMoreBlock = 0; result = BLOB_ABORTED; } else if (source == NULL || size == 0) { /*Codes_SRS_BLOB_99_002: [ If the size of the block returned by `getDataCallbackEx` is 0 or if the data is NULL, then `Blob_UploadMultipleBlocksFromSasUri` shall exit the loop. ]*/ uploadOneMoreBlock = 0; result = BLOB_OK; } else { if (size > BLOCK_SIZE) { /*Codes_SRS_BLOB_99_001: [ If the size of the block returned by `getDataCallbackEx` is bigger than 4MB, then `Blob_UploadMultipleBlocksFromSasUri` shall fail and return `BLOB_INVALID_ARG`. ]*/ LogError("tried to upload block of size %lu, max allowed size is %d", (unsigned long)size, BLOCK_SIZE); result = BLOB_INVALID_ARG; isError = 1; } else if (blockID >= MAX_BLOCK_COUNT) { /*Codes_SRS_BLOB_99_003: [ If `getDataCallbackEx` returns more than 50000 blocks, then `Blob_UploadMultipleBlocksFromSasUri` shall fail and return `BLOB_INVALID_ARG`. ]*/ LogError("unable to upload more than %lu blocks in one blob", (unsigned long)MAX_BLOCK_COUNT); result = BLOB_INVALID_ARG; isError = 1; } else { /*Codes_SRS_BLOB_02_023: [ Blob_UploadMultipleBlocksFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/ BUFFER_HANDLE requestContent = BUFFER_create(source, size); if (requestContent == NULL) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("unable to BUFFER_create"); result = BLOB_ERROR; isError = 1; } else { result = Blob_UploadBlock( httpApiExHandle, relativePath, requestContent, blockID, blockIDList, httpStatus, httpResponse); BUFFER_delete(requestContent); } /*Codes_SRS_BLOB_02_026: [ Otherwise, if HTTP response code is >=300 then Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/ if (result != BLOB_OK || *httpStatus >= 300) { LogError("unable to Blob_UploadBlock. Returned value=%d, httpStatus=%u", result, (unsigned int)*httpStatus); isError = 1; } } blockID++; } } while(uploadOneMoreBlock && !isError); if (isError || result != BLOB_OK) { /*do nothing, it will be reported "as is"*/ } else { /*complete the XML*/ if (STRING_concat(blockIDList, "</BlockList>") != 0) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("failed to STRING_concat"); result = BLOB_ERROR; } else { /*Codes_SRS_BLOB_02_029: [Blob_UploadMultipleBlocksFromSasUri shall construct a new relativePath from following string : base relativePath + "&comp=blocklist"]*/ STRING_HANDLE newRelativePath = STRING_construct(relativePath); if (newRelativePath == NULL) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("failed to STRING_construct"); result = BLOB_ERROR; } else { if (STRING_concat(newRelativePath, "&comp=blocklist") != 0) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("failed to STRING_concat"); result = BLOB_ERROR; } else { /*Codes_SRS_BLOB_02_030: [ Blob_UploadMultipleBlocksFromSasUri shall call HTTPAPIEX_ExecuteRequest with a PUT operation, passing the new relativePath, httpStatus and httpResponse and the XML string as content. ]*/ const char* s = STRING_c_str(blockIDList); BUFFER_HANDLE blockIDListAsBuffer = BUFFER_create((const unsigned char*)s, strlen(s)); if (blockIDListAsBuffer == NULL) { /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ LogError("failed to BUFFER_create"); result = BLOB_ERROR; } else { if (HTTPAPIEX_ExecuteRequest( httpApiExHandle, HTTPAPI_REQUEST_PUT, STRING_c_str(newRelativePath), NULL, blockIDListAsBuffer, httpStatus, NULL, httpResponse ) != HTTPAPIEX_OK) { /*Codes_SRS_BLOB_02_031: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/ LogError("unable to HTTPAPIEX_ExecuteRequest"); result = BLOB_HTTP_ERROR; } else { /*Codes_SRS_BLOB_02_032: [ Otherwise, Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/ result = BLOB_OK; } BUFFER_delete(blockIDListAsBuffer); } } STRING_delete(newRelativePath); } } } STRING_delete(blockIDList); } } HTTPAPIEX_Destroy(httpApiExHandle); } free(hostname); } } } } } return result; }
static void createMethodPayloadExpectedCalls() { STRICT_EXPECTED_CALL(STRING_c_str(IGNORED_PTR_ARG)); STRICT_EXPECTED_CALL(BUFFER_create(IGNORED_PTR_ARG, IGNORED_NUM_ARG)); STRICT_EXPECTED_CALL(STRING_delete(IGNORED_PTR_ARG)); //cannot fail }
static BUFFER_HANDLE decrypt_data(SEC_DEVICE_INFO* sec_info, const unsigned char* key, size_t key_len) { BUFFER_HANDLE result; TSS_SESSION ek_sess = { { TPM_RH_NULL } }; UINT32 max_tpm_data_size; if (create_tpm_session(sec_info, &ek_sess) != 0) { LogError("Failure: Starting EK policy session"); result = NULL; } else if ((max_tpm_data_size = TSS_GetTpmProperty(&sec_info->tpm_device, TPM_PT_INPUT_BUFFER)) == 0) { LogError("Failure: TSS_GetTpmProperty Input buffer"); result = NULL; } else { TPM2B_ID_OBJECT tpm_blob; TPM2B_ENCRYPTED_SECRET tpm_enc_secret; TPM2B_ENCRYPTED_SECRET tpm_enc_key; TPM2B_PRIVATE id_key_dup_blob; UINT16 enc_data_size = 0; TPM2B_PUBLIC id_key_Public = { TPM_ALG_NULL }; TPM2B_MAX_BUFFER* target_data = NULL; TPM2B_DIGEST inner_wrap_key = { 0 }; uint8_t* curr_pos = (uint8_t*)key; uint32_t act_size = (int32_t)key_len; DRS_UNMARSHAL(TPM2B_ID_OBJECT, &tpm_blob); DRS_UNMARSHAL(TPM2B_ENCRYPTED_SECRET, &tpm_enc_secret); DRS_UNMARSHAL(TPM2B_PRIVATE, &id_key_dup_blob); DRS_UNMARSHAL(TPM2B_ENCRYPTED_SECRET, &tpm_enc_key); DRS_UNMARSHAL_FLAGGED(TPM2B_PUBLIC, &id_key_Public); // The given TPM may support larger TPM2B_MAX_BUFFER than this API headers define. // So instead of unmarshaling data in a standalone data structure just reuse the // original activation buffer (after updating byte order of the UINT16 counter) DRS_UNMARSHAL(UINT16, &enc_data_size); if (enc_data_size > max_tpm_data_size) { LogError("Failure: The encrypted data len (%zu) is too long for tpm", enc_data_size); result = NULL; } else { target_data = (TPM2B_MAX_BUFFER*)(curr_pos - sizeof(UINT16)); target_data->t.size = enc_data_size; // Update local vars in case activation blob contains more data to unmarshal curr_pos += enc_data_size; act_size -= enc_data_size; // decrypts encrypted symmetric key ?encSecret? and returns it as 'tpm_blob'. // Later 'tpm_blob' is used as the inner wrapper key for import of the HMAC key blob. if (TPM2_ActivateCredential(&sec_info->tpm_device, &NullPwSession, &ek_sess, TPM_20_SRK_HANDLE, TPM_20_EK_HANDLE, &tpm_blob, &tpm_enc_secret, &inner_wrap_key) != TPM_RC_SUCCESS) { LogError("Failure: TPM2_ActivateCredential"); result = NULL; } else { result = BUFFER_create(tpm_blob.t.credential, tpm_blob.t.size); if (result == NULL) { LogError("Failure building buffer"); result = NULL; } } } } return result; }
int main(int argc, char** argv) { int result; (void)argc; (void)argv; if (platform_init() != 0) { result = -1; } else { XIO_HANDLE sasl_io; CONNECTION_HANDLE connection; SESSION_HANDLE session; LINK_HANDLE link; MESSAGE_SENDER_HANDLE message_sender; MESSAGE_HANDLE message; size_t last_memory_used = 0; /* create SASL PLAIN handler */ SASL_MECHANISM_HANDLE sasl_mechanism_handle = saslmechanism_create(saslmssbcbs_get_interface(), NULL); XIO_HANDLE tls_io; STRING_HANDLE sas_key_name; STRING_HANDLE sas_key_value; STRING_HANDLE resource_uri; STRING_HANDLE encoded_resource_uri; STRING_HANDLE sas_token; BUFFER_HANDLE buffer; TLSIO_CONFIG tls_io_config = { EH_HOST, 5671 }; const IO_INTERFACE_DESCRIPTION* tlsio_interface; SASLCLIENTIO_CONFIG sasl_io_config; time_t currentTime; size_t expiry_time; CBS_HANDLE cbs; AMQP_VALUE source; AMQP_VALUE target; unsigned char hello[] = { 'H', 'e', 'l', 'l', 'o' }; BINARY_DATA binary_data; gballoc_init(); /* create the TLS IO */ tlsio_interface = platform_get_default_tlsio(); tls_io = xio_create(tlsio_interface, &tls_io_config); /* create the SASL client IO using the TLS IO */ sasl_io_config.underlying_io = tls_io; sasl_io_config.sasl_mechanism = sasl_mechanism_handle; sasl_io = xio_create(saslclientio_get_interface_description(), &sasl_io_config); /* create the connection, session and link */ connection = connection_create(sasl_io, EH_HOST, "some", NULL, NULL); session = session_create(connection, NULL, NULL); session_set_incoming_window(session, 2147483647); session_set_outgoing_window(session, 65536); /* Construct a SAS token */ sas_key_name = STRING_construct(EH_KEY_NAME); /* unfortunately SASToken wants an encoded key - this should be fixed at a later time */ buffer = BUFFER_create((unsigned char*)EH_KEY, strlen(EH_KEY)); sas_key_value = Base64_Encoder(buffer); BUFFER_delete(buffer); resource_uri = STRING_construct("sb://" EH_HOST "/" EH_NAME "/publishers/" EH_PUBLISHER); encoded_resource_uri = URL_EncodeString(STRING_c_str(resource_uri)); /* Make a token that expires in one hour */ currentTime = time(NULL); expiry_time = (size_t)(difftime(currentTime, 0) + 3600); sas_token = SASToken_Create(sas_key_value, encoded_resource_uri, sas_key_name, expiry_time); cbs = cbs_create(session); if (cbs_open_async(cbs, on_cbs_open_complete, cbs, on_cbs_error, cbs) == 0) { (void)cbs_put_token_async(cbs, "servicebus.windows.net:sastoken", "sb://" EH_HOST "/" EH_NAME "/publishers/" EH_PUBLISHER, STRING_c_str(sas_token), on_cbs_put_token_complete, cbs); while (!auth) { size_t current_memory_used; size_t maximum_memory_used; connection_dowork(connection); current_memory_used = gballoc_getCurrentMemoryUsed(); maximum_memory_used = gballoc_getMaximumMemoryUsed(); if (current_memory_used != last_memory_used) { (void)printf("Current memory usage:%lu (max:%lu)\r\n", (unsigned long)current_memory_used, (unsigned long)maximum_memory_used); last_memory_used = current_memory_used; } } } STRING_delete(sas_token); STRING_delete(sas_key_name); STRING_delete(sas_key_value); STRING_delete(resource_uri); STRING_delete(encoded_resource_uri); source = messaging_create_source("ingress"); target = messaging_create_target("amqps://" EH_HOST "/" EH_NAME); link = link_create(session, "sender-link", role_sender, source, target); link_set_snd_settle_mode(link, sender_settle_mode_settled); (void)link_set_max_message_size(link, 65536); amqpvalue_destroy(source); amqpvalue_destroy(target); message = message_create(); binary_data.bytes = hello; binary_data.length = sizeof(hello); message_add_body_amqp_data(message, binary_data); /* create a message sender */ message_sender = messagesender_create(link, NULL, NULL); if (messagesender_open(message_sender) == 0) { uint32_t i; bool keep_running = true; tickcounter_ms_t start_time; TICK_COUNTER_HANDLE tick_counter = tickcounter_create(); if (tickcounter_get_current_ms(tick_counter, &start_time) != 0) { (void)printf("Error getting start time\r\n"); } else { for (i = 0; i < msg_count; i++) { (void)messagesender_send(message_sender, message, on_message_send_complete, message); } message_destroy(message); while (keep_running) { size_t current_memory_used; size_t maximum_memory_used; connection_dowork(connection); current_memory_used = gballoc_getCurrentMemoryUsed(); maximum_memory_used = gballoc_getMaximumMemoryUsed(); if (current_memory_used != last_memory_used) { (void)printf("Current memory usage:%lu (max:%lu)\r\n", (unsigned long)current_memory_used, (unsigned long)maximum_memory_used); last_memory_used = current_memory_used; } if (sent_messages == msg_count) { break; } } { tickcounter_ms_t end_time; if (tickcounter_get_current_ms(tick_counter, &end_time) != 0) { (void)printf("Error getting end time\r\n"); } else { (void)printf("Send %u messages in %lu ms: %.02f msgs/sec\r\n", (unsigned int)msg_count, (unsigned long)(end_time - start_time), (float)msg_count / ((float)(end_time - start_time) / 1000)); } } } } messagesender_destroy(message_sender); link_destroy(link); session_destroy(session); connection_destroy(connection); xio_destroy(sasl_io); xio_destroy(tls_io); saslmechanism_destroy(sasl_mechanism_handle); platform_deinit(); (void)printf("Max memory usage:%lu\r\n", (unsigned long)gballoc_getCurrentMemoryUsed()); (void)printf("Current memory usage:%lu\r\n", (unsigned long)gballoc_getMaximumMemoryUsed()); gballoc_deinit(); result = 0; } return result; }