Demo using MBED TLS

Dependencies:   EthernetInterface NTPClient iothub_amqp_transport iothub_client mbed-rtos mbed

Fork of iothub_client_sample_amqp by Azure IoT

Committer:
markrad
Date:
Thu Jan 05 00:20:03 2017 +0000
Revision:
58:f50b97b08851
Sample using MBED TLS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
markrad 58:f50b97b08851 1 // Copyright (c) Microsoft. All rights reserved.
markrad 58:f50b97b08851 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
markrad 58:f50b97b08851 3
markrad 58:f50b97b08851 4 #include <stdlib.h>
markrad 58:f50b97b08851 5 #ifdef _CRTDBG_MAP_ALLOC
markrad 58:f50b97b08851 6 #include <crtdbg.h>
markrad 58:f50b97b08851 7 #endif
markrad 58:f50b97b08851 8 #include <string.h>
markrad 58:f50b97b08851 9 #include "azure_uamqp_c/sasl_plain.h"
markrad 58:f50b97b08851 10 #include "azure_uamqp_c/amqpalloc.h"
markrad 58:f50b97b08851 11
markrad 58:f50b97b08851 12 typedef struct SASL_PLAIN_INSTANCE_TAG
markrad 58:f50b97b08851 13 {
markrad 58:f50b97b08851 14 unsigned char* init_bytes;
markrad 58:f50b97b08851 15 uint32_t init_bytes_length;
markrad 58:f50b97b08851 16 } SASL_PLAIN_INSTANCE;
markrad 58:f50b97b08851 17
markrad 58:f50b97b08851 18 static const SASL_MECHANISM_INTERFACE_DESCRIPTION saslplain_interface =
markrad 58:f50b97b08851 19 {
markrad 58:f50b97b08851 20 /* Codes_SRS_SASL_PLAIN_01_015: [**saslplain_get_interface shall return a pointer to a SASL_MECHANISM_INTERFACE_DESCRIPTION structure that contains pointers to the functions: saslplain_create, saslplain_destroy, saslplain_get_init_bytes, saslplain_get_mechanism_name, saslplain_challenge.] */
markrad 58:f50b97b08851 21 saslplain_create,
markrad 58:f50b97b08851 22 saslplain_destroy,
markrad 58:f50b97b08851 23 saslplain_get_init_bytes,
markrad 58:f50b97b08851 24 saslplain_get_mechanism_name,
markrad 58:f50b97b08851 25 saslplain_challenge
markrad 58:f50b97b08851 26 };
markrad 58:f50b97b08851 27
markrad 58:f50b97b08851 28 CONCRETE_SASL_MECHANISM_HANDLE saslplain_create(void* config)
markrad 58:f50b97b08851 29 {
markrad 58:f50b97b08851 30 SASL_PLAIN_INSTANCE* result;
markrad 58:f50b97b08851 31
markrad 58:f50b97b08851 32 if (config == NULL)
markrad 58:f50b97b08851 33 {
markrad 58:f50b97b08851 34 /* Codes_SRS_SASL_PLAIN_01_003: [If the config argument is NULL, then saslplain_create shall fail and return NULL.] */
markrad 58:f50b97b08851 35 result = NULL;
markrad 58:f50b97b08851 36 }
markrad 58:f50b97b08851 37 else
markrad 58:f50b97b08851 38 {
markrad 58:f50b97b08851 39 SASL_PLAIN_CONFIG* sasl_plain_config = (SASL_PLAIN_CONFIG*)config;
markrad 58:f50b97b08851 40
markrad 58:f50b97b08851 41 /* Codes_SRS_SASL_PLAIN_01_004: [If either the authcid or passwd member of the config structure is NULL, then saslplain_create shall fail and return NULL.] */
markrad 58:f50b97b08851 42 if ((sasl_plain_config->authcid == NULL) ||
markrad 58:f50b97b08851 43 (sasl_plain_config->passwd == NULL))
markrad 58:f50b97b08851 44 {
markrad 58:f50b97b08851 45 result = NULL;
markrad 58:f50b97b08851 46 }
markrad 58:f50b97b08851 47 else
markrad 58:f50b97b08851 48 {
markrad 58:f50b97b08851 49 size_t authzid_length = sasl_plain_config->authzid == NULL ? 0 : strlen(sasl_plain_config->authzid);
markrad 58:f50b97b08851 50 size_t authcid_length = strlen(sasl_plain_config->authcid);
markrad 58:f50b97b08851 51 size_t passwd_length = strlen(sasl_plain_config->passwd);
markrad 58:f50b97b08851 52
markrad 58:f50b97b08851 53 /* Codes_SRS_SASL_PLAIN_01_020: [ authcid = 1*SAFE ; MUST accept up to 255 octets] */
markrad 58:f50b97b08851 54 if ((authcid_length > 255) || (authcid_length == 0) ||
markrad 58:f50b97b08851 55 /* Codes_SRS_SASL_PLAIN_01_021: [ authzid = 1*SAFE ; MUST accept up to 255 octets] */
markrad 58:f50b97b08851 56 (authzid_length > 255) ||
markrad 58:f50b97b08851 57 /* Codes_SRS_SASL_PLAIN_01_022: [ passwd = 1*SAFE ; MUST accept up to 255 octets] */
markrad 58:f50b97b08851 58 (passwd_length > 255) || (passwd_length == 0))
markrad 58:f50b97b08851 59 {
markrad 58:f50b97b08851 60 result = NULL;
markrad 58:f50b97b08851 61 }
markrad 58:f50b97b08851 62 else
markrad 58:f50b97b08851 63 {
markrad 58:f50b97b08851 64 /* Codes_SRS_SASL_PLAIN_01_001: [saslplain_create shall return on success a non-NULL handle to a new SASL plain mechanism.] */
markrad 58:f50b97b08851 65 result = amqpalloc_malloc(sizeof(SASL_PLAIN_INSTANCE));
markrad 58:f50b97b08851 66 /* Codes_SRS_SASL_PLAIN_01_002: [If allocating the memory needed for the saslplain instance fails then saslplain_create shall return NULL.] */
markrad 58:f50b97b08851 67 if (result != NULL)
markrad 58:f50b97b08851 68 {
markrad 58:f50b97b08851 69 /* Ignore UTF8 for now */
markrad 58:f50b97b08851 70 result->init_bytes = (unsigned char*)amqpalloc_malloc(authzid_length + authcid_length + passwd_length + 2);
markrad 58:f50b97b08851 71 if (result->init_bytes == NULL)
markrad 58:f50b97b08851 72 {
markrad 58:f50b97b08851 73 /* Codes_SRS_SASL_PLAIN_01_002: [If allocating the memory needed for the saslplain instance fails then saslplain_create shall return NULL.] */
markrad 58:f50b97b08851 74 amqpalloc_free(result);
markrad 58:f50b97b08851 75 result = NULL;
markrad 58:f50b97b08851 76 }
markrad 58:f50b97b08851 77 else
markrad 58:f50b97b08851 78 {
markrad 58:f50b97b08851 79 /* Codes_SRS_SASL_PLAIN_01_016: [The mechanism consists of a single message, a string of [UTF-8] encoded [Unicode] characters, from the client to the server.] */
markrad 58:f50b97b08851 80 /* Codes_SRS_SASL_PLAIN_01_017: [The client presents the authorization identity (identity to act as), followed by a NUL (U+0000) character, followed by the authentication identity (identity whose password will be used), followed by a NUL (U+0000) character, followed by the clear-text password.] */
markrad 58:f50b97b08851 81 /* Codes_SRS_SASL_PLAIN_01_019: [ message = [authzid] UTF8NUL authcid UTF8NUL passwd] */
markrad 58:f50b97b08851 82 /* Codes_SRS_SASL_PLAIN_01_023: [The authorization identity (authzid), authentication identity (authcid), password (passwd), and NUL character deliminators SHALL be transferred as [UTF-8] encoded strings of [Unicode] characters.] */
markrad 58:f50b97b08851 83 /* Codes_SRS_SASL_PLAIN_01_024: [As the NUL (U+0000) character is used as a deliminator, the NUL (U+0000) character MUST NOT appear in authzid, authcid, or passwd productions.] */
markrad 58:f50b97b08851 84
markrad 58:f50b97b08851 85 /* Codes_SRS_SASL_PLAIN_01_018: [As with other SASL mechanisms, the client does not provide an authorization identity when it wishes the server to derive an identity from the credentials and use that as the authorization identity.] */
markrad 58:f50b97b08851 86 if (authzid_length > 0)
markrad 58:f50b97b08851 87 {
markrad 58:f50b97b08851 88 (void)memcpy(result->init_bytes, sasl_plain_config->authzid, authzid_length);
markrad 58:f50b97b08851 89 }
markrad 58:f50b97b08851 90
markrad 58:f50b97b08851 91 result->init_bytes[authzid_length] = 0;
markrad 58:f50b97b08851 92 (void)memcpy(result->init_bytes + authzid_length + 1, sasl_plain_config->authcid, authcid_length);
markrad 58:f50b97b08851 93 result->init_bytes[authzid_length + authcid_length + 1] = 0;
markrad 58:f50b97b08851 94 (void)memcpy(result->init_bytes + authzid_length + authcid_length + 2, sasl_plain_config->passwd, passwd_length);
markrad 58:f50b97b08851 95 result->init_bytes_length = (uint32_t)(authzid_length + authcid_length + passwd_length + 2);
markrad 58:f50b97b08851 96 }
markrad 58:f50b97b08851 97 }
markrad 58:f50b97b08851 98 }
markrad 58:f50b97b08851 99 }
markrad 58:f50b97b08851 100 }
markrad 58:f50b97b08851 101
markrad 58:f50b97b08851 102 return result;
markrad 58:f50b97b08851 103 }
markrad 58:f50b97b08851 104
markrad 58:f50b97b08851 105 void saslplain_destroy(CONCRETE_SASL_MECHANISM_HANDLE sasl_mechanism_concrete_handle)
markrad 58:f50b97b08851 106 {
markrad 58:f50b97b08851 107 if (sasl_mechanism_concrete_handle != NULL)
markrad 58:f50b97b08851 108 {
markrad 58:f50b97b08851 109 /* Codes_SRS_SASL_PLAIN_01_005: [saslplain_destroy shall free all resources associated with the SASL mechanism.] */
markrad 58:f50b97b08851 110 SASL_PLAIN_INSTANCE* sasl_plain_instance = (SASL_PLAIN_INSTANCE*)sasl_mechanism_concrete_handle;
markrad 58:f50b97b08851 111 if (sasl_plain_instance->init_bytes != NULL)
markrad 58:f50b97b08851 112 {
markrad 58:f50b97b08851 113 amqpalloc_free(sasl_plain_instance->init_bytes);
markrad 58:f50b97b08851 114 }
markrad 58:f50b97b08851 115
markrad 58:f50b97b08851 116 amqpalloc_free(sasl_plain_instance);
markrad 58:f50b97b08851 117 }
markrad 58:f50b97b08851 118 }
markrad 58:f50b97b08851 119
markrad 58:f50b97b08851 120 int saslplain_get_init_bytes(CONCRETE_SASL_MECHANISM_HANDLE sasl_mechanism_concrete_handle, SASL_MECHANISM_BYTES* init_bytes)
markrad 58:f50b97b08851 121 {
markrad 58:f50b97b08851 122 int result;
markrad 58:f50b97b08851 123
markrad 58:f50b97b08851 124 if ((sasl_mechanism_concrete_handle == NULL) ||
markrad 58:f50b97b08851 125 (init_bytes == NULL))
markrad 58:f50b97b08851 126 {
markrad 58:f50b97b08851 127 result = __LINE__;
markrad 58:f50b97b08851 128 }
markrad 58:f50b97b08851 129 else
markrad 58:f50b97b08851 130 {
markrad 58:f50b97b08851 131 SASL_PLAIN_INSTANCE* sasl_plain_instance = (SASL_PLAIN_INSTANCE*)sasl_mechanism_concrete_handle;
markrad 58:f50b97b08851 132
markrad 58:f50b97b08851 133 init_bytes->bytes = sasl_plain_instance->init_bytes;
markrad 58:f50b97b08851 134 init_bytes->length = sasl_plain_instance->init_bytes_length;
markrad 58:f50b97b08851 135
markrad 58:f50b97b08851 136 /* Codes_SRS_SASL_PLAIN_01_008: [On success saslplain_get_init_bytes shall return zero.] */
markrad 58:f50b97b08851 137 result = 0;
markrad 58:f50b97b08851 138 }
markrad 58:f50b97b08851 139
markrad 58:f50b97b08851 140 return result;
markrad 58:f50b97b08851 141 }
markrad 58:f50b97b08851 142
markrad 58:f50b97b08851 143 const char* saslplain_get_mechanism_name(CONCRETE_SASL_MECHANISM_HANDLE sasl_mechanism)
markrad 58:f50b97b08851 144 {
markrad 58:f50b97b08851 145 const char* result;
markrad 58:f50b97b08851 146
markrad 58:f50b97b08851 147 if (sasl_mechanism == NULL)
markrad 58:f50b97b08851 148 {
markrad 58:f50b97b08851 149 /* Codes_SRS_SASL_PLAIN_01_011: [If the argument concrete_sasl_mechanism is NULL, saslplain_get_mechanism_name shall return NULL.] */
markrad 58:f50b97b08851 150 result = NULL;
markrad 58:f50b97b08851 151 }
markrad 58:f50b97b08851 152 else
markrad 58:f50b97b08851 153 {
markrad 58:f50b97b08851 154 /* Codes_SRS_SASL_PLAIN_01_010: [saslplain_get_mechanism_name shall validate the argument concrete_sasl_mechanism and on success it shall return a pointer to the string "PLAIN".] */
markrad 58:f50b97b08851 155 result = "PLAIN";
markrad 58:f50b97b08851 156 }
markrad 58:f50b97b08851 157
markrad 58:f50b97b08851 158 return result;
markrad 58:f50b97b08851 159 }
markrad 58:f50b97b08851 160
markrad 58:f50b97b08851 161 int saslplain_challenge(CONCRETE_SASL_MECHANISM_HANDLE concrete_sasl_mechanism, const SASL_MECHANISM_BYTES* challenge_bytes, SASL_MECHANISM_BYTES* response_bytes)
markrad 58:f50b97b08851 162 {
markrad 58:f50b97b08851 163 int result;
markrad 58:f50b97b08851 164
markrad 58:f50b97b08851 165 (void)challenge_bytes;
markrad 58:f50b97b08851 166
markrad 58:f50b97b08851 167 /* Codes_SRS_SASL_PLAIN_01_014: [If the concrete_sasl_mechanism or response_bytes argument is NULL then saslplain_challenge shall fail and return a non-zero value.] */
markrad 58:f50b97b08851 168 if ((concrete_sasl_mechanism == NULL) ||
markrad 58:f50b97b08851 169 (response_bytes == NULL))
markrad 58:f50b97b08851 170 {
markrad 58:f50b97b08851 171 result = __LINE__;
markrad 58:f50b97b08851 172 }
markrad 58:f50b97b08851 173 else
markrad 58:f50b97b08851 174 {
markrad 58:f50b97b08851 175 /* Codes_SRS_SASL_PLAIN_01_012: [saslplain_challenge shall set the response_bytes buffer to NULL and 0 size as the PLAIN SASL mechanism does not implement challenge/response.] */
markrad 58:f50b97b08851 176 response_bytes->bytes = NULL;
markrad 58:f50b97b08851 177 response_bytes->length = 0;
markrad 58:f50b97b08851 178
markrad 58:f50b97b08851 179 /* Codes_SRS_SASL_PLAIN_01_013: [On success, saslplain_challenge shall return 0.] */
markrad 58:f50b97b08851 180 result = 0;
markrad 58:f50b97b08851 181 }
markrad 58:f50b97b08851 182
markrad 58:f50b97b08851 183 return result;
markrad 58:f50b97b08851 184 }
markrad 58:f50b97b08851 185
markrad 58:f50b97b08851 186 const SASL_MECHANISM_INTERFACE_DESCRIPTION* saslplain_get_interface(void)
markrad 58:f50b97b08851 187 {
markrad 58:f50b97b08851 188 return &saslplain_interface;
markrad 58:f50b97b08851 189 }