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 //
markrad 58:f50b97b08851 5 // PUT NO INCLUDES BEFORE HERE !!!!
markrad 58:f50b97b08851 6 //
markrad 58:f50b97b08851 7 #include <stdlib.h>
markrad 58:f50b97b08851 8 #ifdef _CRTDBG_MAP_ALLOC
markrad 58:f50b97b08851 9 #include <crtdbg.h>
markrad 58:f50b97b08851 10 #endif
markrad 58:f50b97b08851 11 #include "azure_c_shared_utility/gballoc.h"
markrad 58:f50b97b08851 12
markrad 58:f50b97b08851 13 #include <stddef.h>
markrad 58:f50b97b08851 14 #include <string.h>
markrad 58:f50b97b08851 15 #include <stdint.h>
markrad 58:f50b97b08851 16 //
markrad 58:f50b97b08851 17 // PUT NO CLIENT LIBRARY INCLUDES BEFORE HERE !!!!
markrad 58:f50b97b08851 18 //
markrad 58:f50b97b08851 19 #include "azure_c_shared_utility/base64.h"
markrad 58:f50b97b08851 20 #include "azure_c_shared_utility/xlogging.h"
markrad 58:f50b97b08851 21
markrad 58:f50b97b08851 22
markrad 58:f50b97b08851 23 #define splitInt(intVal, bytePos) (char)((intVal >> (bytePos << 3)) & 0xFF)
markrad 58:f50b97b08851 24 #define joinChars(a, b, c, d) (uint32_t)((uint32_t)a + ((uint32_t)b << 8) + ((uint32_t)c << 16) + ((uint32_t)d << 24))
markrad 58:f50b97b08851 25
markrad 58:f50b97b08851 26 static char base64char(unsigned char val)
markrad 58:f50b97b08851 27 {
markrad 58:f50b97b08851 28 char result;
markrad 58:f50b97b08851 29
markrad 58:f50b97b08851 30 if (val < 26)
markrad 58:f50b97b08851 31 {
markrad 58:f50b97b08851 32 result = 'A' + (char)val;
markrad 58:f50b97b08851 33 }
markrad 58:f50b97b08851 34 else if (val < 52)
markrad 58:f50b97b08851 35 {
markrad 58:f50b97b08851 36 result = 'a' + ((char)val - 26);
markrad 58:f50b97b08851 37 }
markrad 58:f50b97b08851 38 else if (val < 62)
markrad 58:f50b97b08851 39 {
markrad 58:f50b97b08851 40 result = '0' + ((char)val - 52);
markrad 58:f50b97b08851 41 }
markrad 58:f50b97b08851 42 else if (val == 62)
markrad 58:f50b97b08851 43 {
markrad 58:f50b97b08851 44 result = '+';
markrad 58:f50b97b08851 45 }
markrad 58:f50b97b08851 46 else
markrad 58:f50b97b08851 47 {
markrad 58:f50b97b08851 48 result = '/';
markrad 58:f50b97b08851 49 }
markrad 58:f50b97b08851 50
markrad 58:f50b97b08851 51 return result;
markrad 58:f50b97b08851 52 }
markrad 58:f50b97b08851 53
markrad 58:f50b97b08851 54 static char base64b16(unsigned char val)
markrad 58:f50b97b08851 55 {
markrad 58:f50b97b08851 56 const uint32_t base64b16values[4] = {
markrad 58:f50b97b08851 57 joinChars('A', 'E', 'I', 'M'),
markrad 58:f50b97b08851 58 joinChars('Q', 'U', 'Y', 'c'),
markrad 58:f50b97b08851 59 joinChars('g', 'k', 'o', 's'),
markrad 58:f50b97b08851 60 joinChars('w', '0', '4', '8')
markrad 58:f50b97b08851 61 };
markrad 58:f50b97b08851 62 return splitInt(base64b16values[val >> 2], (val & 0x03));
markrad 58:f50b97b08851 63 }
markrad 58:f50b97b08851 64
markrad 58:f50b97b08851 65 static char base64b8(unsigned char val)
markrad 58:f50b97b08851 66 {
markrad 58:f50b97b08851 67 const uint32_t base64b8values = joinChars('A', 'Q', 'g', 'w');
markrad 58:f50b97b08851 68 return splitInt(base64b8values, val);
markrad 58:f50b97b08851 69 }
markrad 58:f50b97b08851 70
markrad 58:f50b97b08851 71 static int base64toValue(char base64character, unsigned char* value)
markrad 58:f50b97b08851 72 {
markrad 58:f50b97b08851 73 int result = 0;
markrad 58:f50b97b08851 74 if (('A' <= base64character) && (base64character <= 'Z'))
markrad 58:f50b97b08851 75 {
markrad 58:f50b97b08851 76 *value = base64character - 'A';
markrad 58:f50b97b08851 77 }
markrad 58:f50b97b08851 78 else if (('a' <= base64character) && (base64character <= 'z'))
markrad 58:f50b97b08851 79 {
markrad 58:f50b97b08851 80 *value = ('Z' - 'A') + 1 + (base64character - 'a');
markrad 58:f50b97b08851 81 }
markrad 58:f50b97b08851 82 else if (('0' <= base64character) && (base64character <= '9'))
markrad 58:f50b97b08851 83 {
markrad 58:f50b97b08851 84 *value = ('Z' - 'A') + 1 + ('z' - 'a') + 1 + (base64character - '0');
markrad 58:f50b97b08851 85 }
markrad 58:f50b97b08851 86 else if ('+' == base64character)
markrad 58:f50b97b08851 87 {
markrad 58:f50b97b08851 88 *value = 62;
markrad 58:f50b97b08851 89 }
markrad 58:f50b97b08851 90 else if ('/' == base64character)
markrad 58:f50b97b08851 91 {
markrad 58:f50b97b08851 92 *value = 63;
markrad 58:f50b97b08851 93 }
markrad 58:f50b97b08851 94 else
markrad 58:f50b97b08851 95 {
markrad 58:f50b97b08851 96 *value = 0;
markrad 58:f50b97b08851 97 result = -1;
markrad 58:f50b97b08851 98 }
markrad 58:f50b97b08851 99 return result;
markrad 58:f50b97b08851 100 }
markrad 58:f50b97b08851 101
markrad 58:f50b97b08851 102 static size_t numberOfBase64Characters(const char* encodedString)
markrad 58:f50b97b08851 103 {
markrad 58:f50b97b08851 104 size_t length = 0;
markrad 58:f50b97b08851 105 unsigned char junkChar;
markrad 58:f50b97b08851 106 while (base64toValue(encodedString[length],&junkChar) != -1)
markrad 58:f50b97b08851 107 {
markrad 58:f50b97b08851 108 length++;
markrad 58:f50b97b08851 109 }
markrad 58:f50b97b08851 110 return length;
markrad 58:f50b97b08851 111 }
markrad 58:f50b97b08851 112
markrad 58:f50b97b08851 113 /*returns the count of original bytes before being base64 encoded*/
markrad 58:f50b97b08851 114 /*notice NO validation of the content of encodedString. Its length is validated to be a multiple of 4.*/
markrad 58:f50b97b08851 115 static size_t Base64decode_len(const char *encodedString)
markrad 58:f50b97b08851 116 {
markrad 58:f50b97b08851 117 size_t result;
markrad 58:f50b97b08851 118 size_t sourceLength = strlen(encodedString);
markrad 58:f50b97b08851 119
markrad 58:f50b97b08851 120 if (sourceLength == 0)
markrad 58:f50b97b08851 121 {
markrad 58:f50b97b08851 122 result = 0;
markrad 58:f50b97b08851 123 }
markrad 58:f50b97b08851 124 else
markrad 58:f50b97b08851 125 {
markrad 58:f50b97b08851 126 result = sourceLength / 4 * 3;
markrad 58:f50b97b08851 127 if (encodedString[sourceLength - 1] == '=')
markrad 58:f50b97b08851 128 {
markrad 58:f50b97b08851 129 if (encodedString[sourceLength - 2] == '=')
markrad 58:f50b97b08851 130 {
markrad 58:f50b97b08851 131 result --;
markrad 58:f50b97b08851 132 }
markrad 58:f50b97b08851 133 result--;
markrad 58:f50b97b08851 134 }
markrad 58:f50b97b08851 135 }
markrad 58:f50b97b08851 136 return result;
markrad 58:f50b97b08851 137 }
markrad 58:f50b97b08851 138
markrad 58:f50b97b08851 139 static void Base64decode(unsigned char *decodedString, const char *base64String)
markrad 58:f50b97b08851 140 {
markrad 58:f50b97b08851 141
markrad 58:f50b97b08851 142 size_t numberOfEncodedChars;
markrad 58:f50b97b08851 143 size_t indexOfFirstEncodedChar;
markrad 58:f50b97b08851 144 size_t decodedIndex;
markrad 58:f50b97b08851 145
markrad 58:f50b97b08851 146 //
markrad 58:f50b97b08851 147 // We can only operate on individual bytes. If we attempt to work
markrad 58:f50b97b08851 148 // on anything larger we could get an alignment fault on some
markrad 58:f50b97b08851 149 // architectures
markrad 58:f50b97b08851 150 //
markrad 58:f50b97b08851 151
markrad 58:f50b97b08851 152 numberOfEncodedChars = numberOfBase64Characters(base64String);
markrad 58:f50b97b08851 153 indexOfFirstEncodedChar = 0;
markrad 58:f50b97b08851 154 decodedIndex = 0;
markrad 58:f50b97b08851 155 while (numberOfEncodedChars >= 4)
markrad 58:f50b97b08851 156 {
markrad 58:f50b97b08851 157 unsigned char c1;
markrad 58:f50b97b08851 158 unsigned char c2;
markrad 58:f50b97b08851 159 unsigned char c3;
markrad 58:f50b97b08851 160 unsigned char c4;
markrad 58:f50b97b08851 161 (void)base64toValue(base64String[indexOfFirstEncodedChar], &c1);
markrad 58:f50b97b08851 162 (void)base64toValue(base64String[indexOfFirstEncodedChar + 1], &c2);
markrad 58:f50b97b08851 163 (void)base64toValue(base64String[indexOfFirstEncodedChar + 2], &c3);
markrad 58:f50b97b08851 164 (void)base64toValue(base64String[indexOfFirstEncodedChar + 3], &c4);
markrad 58:f50b97b08851 165 decodedString[decodedIndex] = (c1 << 2) | (c2 >> 4);
markrad 58:f50b97b08851 166 decodedIndex++;
markrad 58:f50b97b08851 167 decodedString[decodedIndex] = ((c2 & 0x0f) << 4) | (c3 >> 2);
markrad 58:f50b97b08851 168 decodedIndex++;
markrad 58:f50b97b08851 169 decodedString[decodedIndex] = ((c3 & 0x03) << 6) | c4;
markrad 58:f50b97b08851 170 decodedIndex++;
markrad 58:f50b97b08851 171 numberOfEncodedChars -= 4;
markrad 58:f50b97b08851 172 indexOfFirstEncodedChar += 4;
markrad 58:f50b97b08851 173
markrad 58:f50b97b08851 174 }
markrad 58:f50b97b08851 175
markrad 58:f50b97b08851 176 if (numberOfEncodedChars == 2)
markrad 58:f50b97b08851 177 {
markrad 58:f50b97b08851 178 unsigned char c1;
markrad 58:f50b97b08851 179 unsigned char c2;
markrad 58:f50b97b08851 180 (void)base64toValue(base64String[indexOfFirstEncodedChar], &c1);
markrad 58:f50b97b08851 181 (void)base64toValue(base64String[indexOfFirstEncodedChar + 1], &c2);
markrad 58:f50b97b08851 182 decodedString[decodedIndex] = (c1 << 2) | (c2 >> 4);
markrad 58:f50b97b08851 183 }
markrad 58:f50b97b08851 184 else if (numberOfEncodedChars == 3)
markrad 58:f50b97b08851 185 {
markrad 58:f50b97b08851 186 unsigned char c1;
markrad 58:f50b97b08851 187 unsigned char c2;
markrad 58:f50b97b08851 188 unsigned char c3;
markrad 58:f50b97b08851 189 (void)base64toValue(base64String[indexOfFirstEncodedChar], &c1);
markrad 58:f50b97b08851 190 (void)base64toValue(base64String[indexOfFirstEncodedChar + 1], &c2);
markrad 58:f50b97b08851 191 (void)base64toValue(base64String[indexOfFirstEncodedChar + 2], &c3);
markrad 58:f50b97b08851 192 decodedString[decodedIndex] = (c1 << 2) | (c2 >> 4);
markrad 58:f50b97b08851 193 decodedIndex++;
markrad 58:f50b97b08851 194 decodedString[decodedIndex] = ((c2 & 0x0f) << 4) | (c3 >> 2);
markrad 58:f50b97b08851 195 }
markrad 58:f50b97b08851 196 }
markrad 58:f50b97b08851 197
markrad 58:f50b97b08851 198 BUFFER_HANDLE Base64_Decoder(const char* source)
markrad 58:f50b97b08851 199 {
markrad 58:f50b97b08851 200 BUFFER_HANDLE result;
markrad 58:f50b97b08851 201 /*Codes_SRS_BASE64_06_008: [If source is NULL then Base64_Decode shall return NULL.]*/
markrad 58:f50b97b08851 202 if (source == NULL)
markrad 58:f50b97b08851 203 {
markrad 58:f50b97b08851 204 LogError("invalid parameter const char* source=%p", source);
markrad 58:f50b97b08851 205 result = NULL;
markrad 58:f50b97b08851 206 }
markrad 58:f50b97b08851 207 else
markrad 58:f50b97b08851 208 {
markrad 58:f50b97b08851 209 if ((strlen(source) % 4) != 0)
markrad 58:f50b97b08851 210 {
markrad 58:f50b97b08851 211 /*Codes_SRS_BASE64_06_011: [If the source string has an invalid length for a base 64 encoded string then Base64_Decode shall return NULL.]*/
markrad 58:f50b97b08851 212 LogError("Invalid length Base64 string!");
markrad 58:f50b97b08851 213 result = NULL;
markrad 58:f50b97b08851 214 }
markrad 58:f50b97b08851 215 else
markrad 58:f50b97b08851 216 {
markrad 58:f50b97b08851 217 if ((result = BUFFER_new()) == NULL)
markrad 58:f50b97b08851 218 {
markrad 58:f50b97b08851 219 /*Codes_SRS_BASE64_06_010: [If there is any memory allocation failure during the decode then Base64_Decode shall return NULL.]*/
markrad 58:f50b97b08851 220 LogError("Could not create a buffer to decoding.");
markrad 58:f50b97b08851 221 }
markrad 58:f50b97b08851 222 else
markrad 58:f50b97b08851 223 {
markrad 58:f50b97b08851 224 size_t sizeOfOutputBuffer = Base64decode_len(source);
markrad 58:f50b97b08851 225 /*Codes_SRS_BASE64_06_009: [If the string pointed to by source is zero length then the handle returned shall refer to a zero length buffer.]*/
markrad 58:f50b97b08851 226 if (sizeOfOutputBuffer > 0)
markrad 58:f50b97b08851 227 {
markrad 58:f50b97b08851 228 if (BUFFER_pre_build(result, sizeOfOutputBuffer) != 0)
markrad 58:f50b97b08851 229 {
markrad 58:f50b97b08851 230 /*Codes_SRS_BASE64_06_010: [If there is any memory allocation failure during the decode then Base64_Decode shall return NULL.]*/
markrad 58:f50b97b08851 231 LogError("Could not prebuild a buffer for base 64 decoding.");
markrad 58:f50b97b08851 232 BUFFER_delete(result);
markrad 58:f50b97b08851 233 result = NULL;
markrad 58:f50b97b08851 234 }
markrad 58:f50b97b08851 235 else
markrad 58:f50b97b08851 236 {
markrad 58:f50b97b08851 237 Base64decode(BUFFER_u_char(result), source);
markrad 58:f50b97b08851 238 }
markrad 58:f50b97b08851 239 }
markrad 58:f50b97b08851 240 }
markrad 58:f50b97b08851 241 }
markrad 58:f50b97b08851 242 }
markrad 58:f50b97b08851 243 return result;
markrad 58:f50b97b08851 244 }
markrad 58:f50b97b08851 245
markrad 58:f50b97b08851 246
markrad 58:f50b97b08851 247 static STRING_HANDLE Base64_Encode_Internal(const unsigned char* source, size_t size)
markrad 58:f50b97b08851 248 {
markrad 58:f50b97b08851 249 STRING_HANDLE result;
markrad 58:f50b97b08851 250 size_t neededSize = 0;
markrad 58:f50b97b08851 251 char* encoded;
markrad 58:f50b97b08851 252 size_t currentPosition = 0;
markrad 58:f50b97b08851 253 neededSize += (size == 0) ? (0) : ((((size - 1) / 3) + 1) * 4);
markrad 58:f50b97b08851 254 neededSize += 1; /*+1 because \0 at the end of the string*/
markrad 58:f50b97b08851 255 /*Codes_SRS_BASE64_06_006: [If when allocating memory to produce the encoding a failure occurs then Base64_Encode shall return NULL.]*/
markrad 58:f50b97b08851 256 encoded = (char*)malloc(neededSize);
markrad 58:f50b97b08851 257 if (encoded == NULL)
markrad 58:f50b97b08851 258 {
markrad 58:f50b97b08851 259 result = NULL;
markrad 58:f50b97b08851 260 LogError("Base64_Encode:: Allocation failed.");
markrad 58:f50b97b08851 261 }
markrad 58:f50b97b08851 262 else
markrad 58:f50b97b08851 263 {
markrad 58:f50b97b08851 264 /*b0 b1(+1) b2(+2)
markrad 58:f50b97b08851 265 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
markrad 58:f50b97b08851 266 |----c1---| |----c2---| |----c3---| |----c4---|
markrad 58:f50b97b08851 267 */
markrad 58:f50b97b08851 268
markrad 58:f50b97b08851 269 size_t destinationPosition = 0;
markrad 58:f50b97b08851 270 while (size - currentPosition >= 3)
markrad 58:f50b97b08851 271 {
markrad 58:f50b97b08851 272 char c1 = base64char(source[currentPosition] >> 2);
markrad 58:f50b97b08851 273 char c2 = base64char(
markrad 58:f50b97b08851 274 ((source[currentPosition] & 3) << 4) |
markrad 58:f50b97b08851 275 (source[currentPosition + 1] >> 4)
markrad 58:f50b97b08851 276 );
markrad 58:f50b97b08851 277 char c3 = base64char(
markrad 58:f50b97b08851 278 ((source[currentPosition + 1] & 0x0F) << 2) |
markrad 58:f50b97b08851 279 ((source[currentPosition + 2] >> 6) & 3)
markrad 58:f50b97b08851 280 );
markrad 58:f50b97b08851 281 char c4 = base64char(
markrad 58:f50b97b08851 282 source[currentPosition + 2] & 0x3F
markrad 58:f50b97b08851 283 );
markrad 58:f50b97b08851 284 currentPosition += 3;
markrad 58:f50b97b08851 285 encoded[destinationPosition++] = c1;
markrad 58:f50b97b08851 286 encoded[destinationPosition++] = c2;
markrad 58:f50b97b08851 287 encoded[destinationPosition++] = c3;
markrad 58:f50b97b08851 288 encoded[destinationPosition++] = c4;
markrad 58:f50b97b08851 289
markrad 58:f50b97b08851 290 }
markrad 58:f50b97b08851 291 if (size - currentPosition == 2)
markrad 58:f50b97b08851 292 {
markrad 58:f50b97b08851 293 char c1 = base64char(source[currentPosition] >> 2);
markrad 58:f50b97b08851 294 char c2 = base64char(
markrad 58:f50b97b08851 295 ((source[currentPosition] & 0x03) << 4) |
markrad 58:f50b97b08851 296 (source[currentPosition + 1] >> 4)
markrad 58:f50b97b08851 297 );
markrad 58:f50b97b08851 298 char c3 = base64b16(source[currentPosition + 1] & 0x0F);
markrad 58:f50b97b08851 299 encoded[destinationPosition++] = c1;
markrad 58:f50b97b08851 300 encoded[destinationPosition++] = c2;
markrad 58:f50b97b08851 301 encoded[destinationPosition++] = c3;
markrad 58:f50b97b08851 302 encoded[destinationPosition++] = '=';
markrad 58:f50b97b08851 303 }
markrad 58:f50b97b08851 304 else if (size - currentPosition == 1)
markrad 58:f50b97b08851 305 {
markrad 58:f50b97b08851 306 char c1 = base64char(source[currentPosition] >> 2);
markrad 58:f50b97b08851 307 char c2 = base64b8(source[currentPosition] & 0x03);
markrad 58:f50b97b08851 308 encoded[destinationPosition++] = c1;
markrad 58:f50b97b08851 309 encoded[destinationPosition++] = c2;
markrad 58:f50b97b08851 310 encoded[destinationPosition++] = '=';
markrad 58:f50b97b08851 311 encoded[destinationPosition++] = '=';
markrad 58:f50b97b08851 312 }
markrad 58:f50b97b08851 313
markrad 58:f50b97b08851 314 /*null terminating the string*/
markrad 58:f50b97b08851 315 encoded[destinationPosition] = '\0';
markrad 58:f50b97b08851 316 /*Codes_SRS_BASE64_06_007: [Otherwise Base64_Encode shall return a pointer to STRING, that string contains the base 64 encoding of input.]*/
markrad 58:f50b97b08851 317 result = STRING_new_with_memory(encoded);
markrad 58:f50b97b08851 318 if (result == NULL)
markrad 58:f50b97b08851 319 {
markrad 58:f50b97b08851 320 free(encoded);
markrad 58:f50b97b08851 321 LogError("Base64_Encode:: Allocation failed for return value.");
markrad 58:f50b97b08851 322 }
markrad 58:f50b97b08851 323 }
markrad 58:f50b97b08851 324 return result;
markrad 58:f50b97b08851 325 }
markrad 58:f50b97b08851 326
markrad 58:f50b97b08851 327 STRING_HANDLE Base64_Encode_Bytes(const unsigned char* source, size_t size)
markrad 58:f50b97b08851 328 {
markrad 58:f50b97b08851 329 STRING_HANDLE result;
markrad 58:f50b97b08851 330 /*Codes_SRS_BASE64_02_001: [If source is NULL then Base64_Encode_Bytes shall return NULL.] */
markrad 58:f50b97b08851 331 if (source == NULL)
markrad 58:f50b97b08851 332 {
markrad 58:f50b97b08851 333 result = NULL;
markrad 58:f50b97b08851 334 }
markrad 58:f50b97b08851 335 /*Codes_SRS_BASE64_02_002: [If source is not NULL and size is zero, then Base64_Encode_Bytes shall produce an empty STRING_HANDLE.] */
markrad 58:f50b97b08851 336 else if (size == 0)
markrad 58:f50b97b08851 337 {
markrad 58:f50b97b08851 338 result = STRING_new(); /*empty string*/
markrad 58:f50b97b08851 339 }
markrad 58:f50b97b08851 340 else
markrad 58:f50b97b08851 341 {
markrad 58:f50b97b08851 342 result = Base64_Encode_Internal(source, size);
markrad 58:f50b97b08851 343 }
markrad 58:f50b97b08851 344 return result;
markrad 58:f50b97b08851 345 }
markrad 58:f50b97b08851 346
markrad 58:f50b97b08851 347 STRING_HANDLE Base64_Encode(BUFFER_HANDLE input)
markrad 58:f50b97b08851 348 {
markrad 58:f50b97b08851 349 STRING_HANDLE result;
markrad 58:f50b97b08851 350 /*the following will happen*/
markrad 58:f50b97b08851 351 /*1. the "data" of the binary shall be "eaten" 3 characters at a time and produce 4 base64 encoded characters for as long as there are more than 3 characters still to process*/
markrad 58:f50b97b08851 352 /*2. the remaining characters (1 or 2) shall be encoded.*/
markrad 58:f50b97b08851 353 /*there's a level of assumption that 'a' corresponds to 0b000000 and that '_' corresponds to 0b111111*/
markrad 58:f50b97b08851 354 /*the encoding will use the optional [=] or [==] at the end of the encoded string, so that other less standard aware libraries can do their work*/
markrad 58:f50b97b08851 355 /*these are the bits of the 3 normal bytes to be encoded*/
markrad 58:f50b97b08851 356
markrad 58:f50b97b08851 357 /*Codes_SRS_BASE64_06_001: [If input is NULL then Base64_Encode shall return NULL.]*/
markrad 58:f50b97b08851 358 if (input == NULL)
markrad 58:f50b97b08851 359 {
markrad 58:f50b97b08851 360 result = NULL;
markrad 58:f50b97b08851 361 LogError("Base64_Encode:: NULL input");
markrad 58:f50b97b08851 362 }
markrad 58:f50b97b08851 363 else
markrad 58:f50b97b08851 364 {
markrad 58:f50b97b08851 365 size_t inputSize;
markrad 58:f50b97b08851 366 const unsigned char* inputBinary;
markrad 58:f50b97b08851 367 if ((BUFFER_content(input, &inputBinary) != 0) ||
markrad 58:f50b97b08851 368 (BUFFER_size(input, &inputSize) != 0))
markrad 58:f50b97b08851 369 {
markrad 58:f50b97b08851 370 result = NULL;
markrad 58:f50b97b08851 371 LogError("Base64_Encode:: BUFFER_routines failure.");
markrad 58:f50b97b08851 372 }
markrad 58:f50b97b08851 373 else
markrad 58:f50b97b08851 374 {
markrad 58:f50b97b08851 375 result = Base64_Encode_Internal(inputBinary, inputSize);
markrad 58:f50b97b08851 376 }
markrad 58:f50b97b08851 377 }
markrad 58:f50b97b08851 378 return result;
markrad 58:f50b97b08851 379 }