Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

Committer:
XinZhangMS
Date:
Thu Aug 23 06:52:14 2018 +0000
Revision:
0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI

Who changed what in which revision?

UserRevisionLine numberNew contents of line
XinZhangMS 0:f7f1f0d76dd6 1 // Copyright (c) Microsoft. All rights reserved.
XinZhangMS 0:f7f1f0d76dd6 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
XinZhangMS 0:f7f1f0d76dd6 3
XinZhangMS 0:f7f1f0d76dd6 4 #include <stdlib.h>
XinZhangMS 0:f7f1f0d76dd6 5 #include <string.h>
XinZhangMS 0:f7f1f0d76dd6 6 #include "azure_c_shared_utility/optimize_size.h"
XinZhangMS 0:f7f1f0d76dd6 7 #include "azure_c_shared_utility/gballoc.h"
XinZhangMS 0:f7f1f0d76dd6 8 #include "azure_c_shared_utility/xlogging.h"
XinZhangMS 0:f7f1f0d76dd6 9 #include "azure_uamqp_c/sasl_plain.h"
XinZhangMS 0:f7f1f0d76dd6 10
XinZhangMS 0:f7f1f0d76dd6 11 typedef struct SASL_PLAIN_INSTANCE_TAG
XinZhangMS 0:f7f1f0d76dd6 12 {
XinZhangMS 0:f7f1f0d76dd6 13 unsigned char* init_bytes;
XinZhangMS 0:f7f1f0d76dd6 14 uint32_t init_bytes_length;
XinZhangMS 0:f7f1f0d76dd6 15 } SASL_PLAIN_INSTANCE;
XinZhangMS 0:f7f1f0d76dd6 16
XinZhangMS 0:f7f1f0d76dd6 17 CONCRETE_SASL_MECHANISM_HANDLE saslplain_create(void* config)
XinZhangMS 0:f7f1f0d76dd6 18 {
XinZhangMS 0:f7f1f0d76dd6 19 SASL_PLAIN_INSTANCE* result;
XinZhangMS 0:f7f1f0d76dd6 20
XinZhangMS 0:f7f1f0d76dd6 21 if (config == NULL)
XinZhangMS 0:f7f1f0d76dd6 22 {
XinZhangMS 0:f7f1f0d76dd6 23 /* Codes_SRS_SASL_PLAIN_01_003: [If the `config` argument is NULL, then `saslplain_create` shall fail and return NULL.] */
XinZhangMS 0:f7f1f0d76dd6 24 LogError("NULL config");
XinZhangMS 0:f7f1f0d76dd6 25 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 26 }
XinZhangMS 0:f7f1f0d76dd6 27 else
XinZhangMS 0:f7f1f0d76dd6 28 {
XinZhangMS 0:f7f1f0d76dd6 29 SASL_PLAIN_CONFIG* sasl_plain_config = (SASL_PLAIN_CONFIG*)config;
XinZhangMS 0:f7f1f0d76dd6 30
XinZhangMS 0:f7f1f0d76dd6 31 /* Codes_SRS_SASL_PLAIN_01_025: [ `authzid` shall be optional. ]*/
XinZhangMS 0:f7f1f0d76dd6 32 if ((sasl_plain_config->authcid == NULL) ||
XinZhangMS 0:f7f1f0d76dd6 33 (sasl_plain_config->passwd == NULL))
XinZhangMS 0:f7f1f0d76dd6 34 {
XinZhangMS 0:f7f1f0d76dd6 35 /* 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.] */
XinZhangMS 0:f7f1f0d76dd6 36 LogError("Bad configuration: authcid = %p, passwd = %p",
XinZhangMS 0:f7f1f0d76dd6 37 sasl_plain_config->authcid, sasl_plain_config->passwd);
XinZhangMS 0:f7f1f0d76dd6 38 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 39 }
XinZhangMS 0:f7f1f0d76dd6 40 else
XinZhangMS 0:f7f1f0d76dd6 41 {
XinZhangMS 0:f7f1f0d76dd6 42 size_t authzid_length = sasl_plain_config->authzid == NULL ? 0 : strlen(sasl_plain_config->authzid);
XinZhangMS 0:f7f1f0d76dd6 43 size_t authcid_length = strlen(sasl_plain_config->authcid);
XinZhangMS 0:f7f1f0d76dd6 44 size_t passwd_length = strlen(sasl_plain_config->passwd);
XinZhangMS 0:f7f1f0d76dd6 45
XinZhangMS 0:f7f1f0d76dd6 46 /* Codes_SRS_SASL_PLAIN_01_020: [ authcid = 1*SAFE ; MUST accept up to 255 octets] */
XinZhangMS 0:f7f1f0d76dd6 47 if ((authcid_length > 255) || (authcid_length == 0) ||
XinZhangMS 0:f7f1f0d76dd6 48 /* Codes_SRS_SASL_PLAIN_01_021: [ authzid = 1*SAFE ; MUST accept up to 255 octets] */
XinZhangMS 0:f7f1f0d76dd6 49 (authzid_length > 255) ||
XinZhangMS 0:f7f1f0d76dd6 50 /* Codes_SRS_SASL_PLAIN_01_022: [ passwd = 1*SAFE ; MUST accept up to 255 octets] */
XinZhangMS 0:f7f1f0d76dd6 51 (passwd_length > 255) || (passwd_length == 0))
XinZhangMS 0:f7f1f0d76dd6 52 {
XinZhangMS 0:f7f1f0d76dd6 53 LogError("Bad configuration: authcid length = %u, passwd length = %u",
XinZhangMS 0:f7f1f0d76dd6 54 (unsigned int)authcid_length, (unsigned int)passwd_length);
XinZhangMS 0:f7f1f0d76dd6 55 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 56 }
XinZhangMS 0:f7f1f0d76dd6 57 else
XinZhangMS 0:f7f1f0d76dd6 58 {
XinZhangMS 0:f7f1f0d76dd6 59 /* Codes_SRS_SASL_PLAIN_01_001: [`saslplain_create` shall return on success a non-NULL handle to a new SASL plain mechanism.] */
XinZhangMS 0:f7f1f0d76dd6 60 result = (SASL_PLAIN_INSTANCE*)malloc(sizeof(SASL_PLAIN_INSTANCE));
XinZhangMS 0:f7f1f0d76dd6 61 if (result == NULL)
XinZhangMS 0:f7f1f0d76dd6 62 {
XinZhangMS 0:f7f1f0d76dd6 63 /* Codes_SRS_SASL_PLAIN_01_002: [If allocating the memory needed for the saslplain instance fails then `saslplain_create` shall return NULL.] */
XinZhangMS 0:f7f1f0d76dd6 64 LogError("Cannot allocate memory for SASL plain instance");
XinZhangMS 0:f7f1f0d76dd6 65 }
XinZhangMS 0:f7f1f0d76dd6 66 else
XinZhangMS 0:f7f1f0d76dd6 67 {
XinZhangMS 0:f7f1f0d76dd6 68 /* Ignore UTF8 for now */
XinZhangMS 0:f7f1f0d76dd6 69 result->init_bytes = (unsigned char*)malloc(authzid_length + authcid_length + passwd_length + 2);
XinZhangMS 0:f7f1f0d76dd6 70 if (result->init_bytes == NULL)
XinZhangMS 0:f7f1f0d76dd6 71 {
XinZhangMS 0:f7f1f0d76dd6 72 /* Codes_SRS_SASL_PLAIN_01_002: [If allocating the memory needed for the saslplain instance fails then `saslplain_create` shall return NULL.] */
XinZhangMS 0:f7f1f0d76dd6 73 LogError("Cannot allocate init bytes");
XinZhangMS 0:f7f1f0d76dd6 74 free(result);
XinZhangMS 0:f7f1f0d76dd6 75 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 76 }
XinZhangMS 0:f7f1f0d76dd6 77 else
XinZhangMS 0:f7f1f0d76dd6 78 {
XinZhangMS 0:f7f1f0d76dd6 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.] */
XinZhangMS 0:f7f1f0d76dd6 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.] */
XinZhangMS 0:f7f1f0d76dd6 81 /* Codes_SRS_SASL_PLAIN_01_019: [ message = [authzid] UTF8NUL authcid UTF8NUL passwd] */
XinZhangMS 0:f7f1f0d76dd6 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.] */
XinZhangMS 0:f7f1f0d76dd6 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.] */
XinZhangMS 0:f7f1f0d76dd6 84
XinZhangMS 0:f7f1f0d76dd6 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.] */
XinZhangMS 0:f7f1f0d76dd6 86 if (authzid_length > 0)
XinZhangMS 0:f7f1f0d76dd6 87 {
XinZhangMS 0:f7f1f0d76dd6 88 (void)memcpy(result->init_bytes, sasl_plain_config->authzid, authzid_length);
XinZhangMS 0:f7f1f0d76dd6 89 }
XinZhangMS 0:f7f1f0d76dd6 90
XinZhangMS 0:f7f1f0d76dd6 91 result->init_bytes[authzid_length] = 0;
XinZhangMS 0:f7f1f0d76dd6 92 (void)memcpy(result->init_bytes + authzid_length + 1, sasl_plain_config->authcid, authcid_length);
XinZhangMS 0:f7f1f0d76dd6 93 result->init_bytes[authzid_length + authcid_length + 1] = 0;
XinZhangMS 0:f7f1f0d76dd6 94 (void)memcpy(result->init_bytes + authzid_length + authcid_length + 2, sasl_plain_config->passwd, passwd_length);
XinZhangMS 0:f7f1f0d76dd6 95 result->init_bytes_length = (uint32_t)(authzid_length + authcid_length + passwd_length + 2);
XinZhangMS 0:f7f1f0d76dd6 96 }
XinZhangMS 0:f7f1f0d76dd6 97 }
XinZhangMS 0:f7f1f0d76dd6 98 }
XinZhangMS 0:f7f1f0d76dd6 99 }
XinZhangMS 0:f7f1f0d76dd6 100 }
XinZhangMS 0:f7f1f0d76dd6 101
XinZhangMS 0:f7f1f0d76dd6 102 return result;
XinZhangMS 0:f7f1f0d76dd6 103 }
XinZhangMS 0:f7f1f0d76dd6 104
XinZhangMS 0:f7f1f0d76dd6 105 void saslplain_destroy(CONCRETE_SASL_MECHANISM_HANDLE sasl_mechanism_concrete_handle)
XinZhangMS 0:f7f1f0d76dd6 106 {
XinZhangMS 0:f7f1f0d76dd6 107 if (sasl_mechanism_concrete_handle == NULL)
XinZhangMS 0:f7f1f0d76dd6 108 {
XinZhangMS 0:f7f1f0d76dd6 109 /* Codes_SRS_SASL_PLAIN_01_006: [If the argument `concrete_sasl_mechanism` is NULL, `saslplain_destroy` shall do nothing.] */
XinZhangMS 0:f7f1f0d76dd6 110 LogError("NULL sasl_mechanism_concrete_handle");
XinZhangMS 0:f7f1f0d76dd6 111 }
XinZhangMS 0:f7f1f0d76dd6 112 else
XinZhangMS 0:f7f1f0d76dd6 113 {
XinZhangMS 0:f7f1f0d76dd6 114 /* Codes_SRS_SASL_PLAIN_01_005: [`saslplain_destroy` shall free all resources associated with the SASL mechanism.] */
XinZhangMS 0:f7f1f0d76dd6 115 SASL_PLAIN_INSTANCE* sasl_plain_instance = (SASL_PLAIN_INSTANCE*)sasl_mechanism_concrete_handle;
XinZhangMS 0:f7f1f0d76dd6 116 if (sasl_plain_instance->init_bytes != NULL)
XinZhangMS 0:f7f1f0d76dd6 117 {
XinZhangMS 0:f7f1f0d76dd6 118 free(sasl_plain_instance->init_bytes);
XinZhangMS 0:f7f1f0d76dd6 119 }
XinZhangMS 0:f7f1f0d76dd6 120
XinZhangMS 0:f7f1f0d76dd6 121 free(sasl_plain_instance);
XinZhangMS 0:f7f1f0d76dd6 122 }
XinZhangMS 0:f7f1f0d76dd6 123 }
XinZhangMS 0:f7f1f0d76dd6 124
XinZhangMS 0:f7f1f0d76dd6 125 int saslplain_get_init_bytes(CONCRETE_SASL_MECHANISM_HANDLE sasl_mechanism_concrete_handle, SASL_MECHANISM_BYTES* init_bytes)
XinZhangMS 0:f7f1f0d76dd6 126 {
XinZhangMS 0:f7f1f0d76dd6 127 int result;
XinZhangMS 0:f7f1f0d76dd6 128
XinZhangMS 0:f7f1f0d76dd6 129 if ((sasl_mechanism_concrete_handle == NULL) ||
XinZhangMS 0:f7f1f0d76dd6 130 (init_bytes == NULL))
XinZhangMS 0:f7f1f0d76dd6 131 {
XinZhangMS 0:f7f1f0d76dd6 132 /* Codes_SRS_SASL_PLAIN_01_009: [If any argument is NULL, `saslplain_get_init_bytes` shall return a non-zero value.] */
XinZhangMS 0:f7f1f0d76dd6 133 LogError("Bad arguments: sasl_mechanism_concrete_handle = %p, init_bytes = %p",
XinZhangMS 0:f7f1f0d76dd6 134 sasl_mechanism_concrete_handle, init_bytes);
XinZhangMS 0:f7f1f0d76dd6 135 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 136 }
XinZhangMS 0:f7f1f0d76dd6 137 else
XinZhangMS 0:f7f1f0d76dd6 138 {
XinZhangMS 0:f7f1f0d76dd6 139 SASL_PLAIN_INSTANCE* sasl_plain_instance = (SASL_PLAIN_INSTANCE*)sasl_mechanism_concrete_handle;
XinZhangMS 0:f7f1f0d76dd6 140
XinZhangMS 0:f7f1f0d76dd6 141 /* Codes_SRS_SASL_PLAIN_01_007: [`saslplain_get_init_bytes` shall construct the initial bytes per the RFC 4616.] */
XinZhangMS 0:f7f1f0d76dd6 142 init_bytes->bytes = sasl_plain_instance->init_bytes;
XinZhangMS 0:f7f1f0d76dd6 143 init_bytes->length = sasl_plain_instance->init_bytes_length;
XinZhangMS 0:f7f1f0d76dd6 144
XinZhangMS 0:f7f1f0d76dd6 145 /* Codes_SRS_SASL_PLAIN_01_008: [On success `saslplain_get_init_bytes` shall return zero.] */
XinZhangMS 0:f7f1f0d76dd6 146 result = 0;
XinZhangMS 0:f7f1f0d76dd6 147 }
XinZhangMS 0:f7f1f0d76dd6 148
XinZhangMS 0:f7f1f0d76dd6 149 return result;
XinZhangMS 0:f7f1f0d76dd6 150 }
XinZhangMS 0:f7f1f0d76dd6 151
XinZhangMS 0:f7f1f0d76dd6 152 const char* saslplain_get_mechanism_name(CONCRETE_SASL_MECHANISM_HANDLE sasl_mechanism)
XinZhangMS 0:f7f1f0d76dd6 153 {
XinZhangMS 0:f7f1f0d76dd6 154 const char* result;
XinZhangMS 0:f7f1f0d76dd6 155
XinZhangMS 0:f7f1f0d76dd6 156 if (sasl_mechanism == NULL)
XinZhangMS 0:f7f1f0d76dd6 157 {
XinZhangMS 0:f7f1f0d76dd6 158 /* Codes_SRS_SASL_PLAIN_01_011: [If the argument `concrete_sasl_mechanism` is NULL, `saslplain_get_mechanism_name` shall return NULL.] */
XinZhangMS 0:f7f1f0d76dd6 159 LogError("NULL sasl_mechanism");
XinZhangMS 0:f7f1f0d76dd6 160 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 161 }
XinZhangMS 0:f7f1f0d76dd6 162 else
XinZhangMS 0:f7f1f0d76dd6 163 {
XinZhangMS 0:f7f1f0d76dd6 164 /* 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".] */
XinZhangMS 0:f7f1f0d76dd6 165 result = "PLAIN";
XinZhangMS 0:f7f1f0d76dd6 166 }
XinZhangMS 0:f7f1f0d76dd6 167
XinZhangMS 0:f7f1f0d76dd6 168 return result;
XinZhangMS 0:f7f1f0d76dd6 169 }
XinZhangMS 0:f7f1f0d76dd6 170
XinZhangMS 0:f7f1f0d76dd6 171 int saslplain_challenge(CONCRETE_SASL_MECHANISM_HANDLE concrete_sasl_mechanism, const SASL_MECHANISM_BYTES* challenge_bytes, SASL_MECHANISM_BYTES* response_bytes)
XinZhangMS 0:f7f1f0d76dd6 172 {
XinZhangMS 0:f7f1f0d76dd6 173 int result;
XinZhangMS 0:f7f1f0d76dd6 174
XinZhangMS 0:f7f1f0d76dd6 175 (void)challenge_bytes;
XinZhangMS 0:f7f1f0d76dd6 176
XinZhangMS 0:f7f1f0d76dd6 177 /* 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.] */
XinZhangMS 0:f7f1f0d76dd6 178 if ((concrete_sasl_mechanism == NULL) ||
XinZhangMS 0:f7f1f0d76dd6 179 (response_bytes == NULL))
XinZhangMS 0:f7f1f0d76dd6 180 {
XinZhangMS 0:f7f1f0d76dd6 181 LogError("Bad arguments: concrete_sasl_mechanism = %p, response_bytes = %p",
XinZhangMS 0:f7f1f0d76dd6 182 concrete_sasl_mechanism, response_bytes);
XinZhangMS 0:f7f1f0d76dd6 183 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 184 }
XinZhangMS 0:f7f1f0d76dd6 185 else
XinZhangMS 0:f7f1f0d76dd6 186 {
XinZhangMS 0:f7f1f0d76dd6 187 /* 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.] */
XinZhangMS 0:f7f1f0d76dd6 188 response_bytes->bytes = NULL;
XinZhangMS 0:f7f1f0d76dd6 189 response_bytes->length = 0;
XinZhangMS 0:f7f1f0d76dd6 190
XinZhangMS 0:f7f1f0d76dd6 191 /* Codes_SRS_SASL_PLAIN_01_013: [On success, `saslplain_challenge` shall return 0.] */
XinZhangMS 0:f7f1f0d76dd6 192 result = 0;
XinZhangMS 0:f7f1f0d76dd6 193 }
XinZhangMS 0:f7f1f0d76dd6 194
XinZhangMS 0:f7f1f0d76dd6 195 return result;
XinZhangMS 0:f7f1f0d76dd6 196 }
XinZhangMS 0:f7f1f0d76dd6 197
XinZhangMS 0:f7f1f0d76dd6 198 static const SASL_MECHANISM_INTERFACE_DESCRIPTION saslplain_interface =
XinZhangMS 0:f7f1f0d76dd6 199 {
XinZhangMS 0:f7f1f0d76dd6 200 /* 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`.] */
XinZhangMS 0:f7f1f0d76dd6 201 saslplain_create,
XinZhangMS 0:f7f1f0d76dd6 202 saslplain_destroy,
XinZhangMS 0:f7f1f0d76dd6 203 saslplain_get_init_bytes,
XinZhangMS 0:f7f1f0d76dd6 204 saslplain_get_mechanism_name,
XinZhangMS 0:f7f1f0d76dd6 205 saslplain_challenge
XinZhangMS 0:f7f1f0d76dd6 206 };
XinZhangMS 0:f7f1f0d76dd6 207
XinZhangMS 0:f7f1f0d76dd6 208 const SASL_MECHANISM_INTERFACE_DESCRIPTION* saslplain_get_interface(void)
XinZhangMS 0:f7f1f0d76dd6 209 {
XinZhangMS 0:f7f1f0d76dd6 210 return &saslplain_interface;
XinZhangMS 0:f7f1f0d76dd6 211 }