Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
util_tx_test/src/base64.c@0:9002b89157da, 2018-04-11 (annotated)
- Committer:
- dgabino
- Date:
- Wed Apr 11 14:47:16 2018 +0000
- Revision:
- 0:9002b89157da
Initial commit
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| dgabino | 0:9002b89157da | 1 | /* |
| dgabino | 0:9002b89157da | 2 | / _____) _ | | |
| dgabino | 0:9002b89157da | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ |
| dgabino | 0:9002b89157da | 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ |
| dgabino | 0:9002b89157da | 5 | _____) ) ____| | | || |_| ____( (___| | | | |
| dgabino | 0:9002b89157da | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| |
| dgabino | 0:9002b89157da | 7 | (C)2013 Semtech-Cycleo |
| dgabino | 0:9002b89157da | 8 | |
| dgabino | 0:9002b89157da | 9 | Description: |
| dgabino | 0:9002b89157da | 10 | Base64 encoding & decoding library |
| dgabino | 0:9002b89157da | 11 | |
| dgabino | 0:9002b89157da | 12 | License: Revised BSD License, see LICENSE.TXT file include in the project |
| dgabino | 0:9002b89157da | 13 | Maintainer: Sylvain Miermont |
| dgabino | 0:9002b89157da | 14 | */ |
| dgabino | 0:9002b89157da | 15 | |
| dgabino | 0:9002b89157da | 16 | |
| dgabino | 0:9002b89157da | 17 | /* -------------------------------------------------------------------------- */ |
| dgabino | 0:9002b89157da | 18 | /* --- DEPENDANCIES --------------------------------------------------------- */ |
| dgabino | 0:9002b89157da | 19 | |
| dgabino | 0:9002b89157da | 20 | #include <stdio.h> |
| dgabino | 0:9002b89157da | 21 | #include <stdlib.h> |
| dgabino | 0:9002b89157da | 22 | #include <stdint.h> |
| dgabino | 0:9002b89157da | 23 | |
| dgabino | 0:9002b89157da | 24 | #include "base64.h" |
| dgabino | 0:9002b89157da | 25 | |
| dgabino | 0:9002b89157da | 26 | /* -------------------------------------------------------------------------- */ |
| dgabino | 0:9002b89157da | 27 | /* --- PRIVATE MACROS ------------------------------------------------------- */ |
| dgabino | 0:9002b89157da | 28 | |
| dgabino | 0:9002b89157da | 29 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) |
| dgabino | 0:9002b89157da | 30 | #define CRIT(a) fprintf(stderr, "\nCRITICAL file:%s line:%d msg:%s\n", __FILE__, __LINE__, a);exit(EXIT_FAILURE) |
| dgabino | 0:9002b89157da | 31 | |
| dgabino | 0:9002b89157da | 32 | //#define DEBUG(args...) fprintf(stderr,"debug: " args) /* diagnostic message that is destined to the user */ |
| dgabino | 0:9002b89157da | 33 | #define DEBUG(args...) |
| dgabino | 0:9002b89157da | 34 | |
| dgabino | 0:9002b89157da | 35 | /* -------------------------------------------------------------------------- */ |
| dgabino | 0:9002b89157da | 36 | /* --- PRIVATE CONSTANTS ---------------------------------------------------- */ |
| dgabino | 0:9002b89157da | 37 | |
| dgabino | 0:9002b89157da | 38 | /* -------------------------------------------------------------------------- */ |
| dgabino | 0:9002b89157da | 39 | /* --- PRIVATE MODULE-WIDE VARIABLES ---------------------------------------- */ |
| dgabino | 0:9002b89157da | 40 | |
| dgabino | 0:9002b89157da | 41 | static char code_62 = '+'; /* RFC 1421 standard character for code 62 */ |
| dgabino | 0:9002b89157da | 42 | static char code_63 = '/'; /* RFC 1421 standard character for code 63 */ |
| dgabino | 0:9002b89157da | 43 | static char code_pad = '='; /* RFC 1421 padding character if padding */ |
| dgabino | 0:9002b89157da | 44 | |
| dgabino | 0:9002b89157da | 45 | /* -------------------------------------------------------------------------- */ |
| dgabino | 0:9002b89157da | 46 | /* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */ |
| dgabino | 0:9002b89157da | 47 | |
| dgabino | 0:9002b89157da | 48 | /** |
| dgabino | 0:9002b89157da | 49 | @brief Convert a code in the range 0-63 to an ASCII character |
| dgabino | 0:9002b89157da | 50 | */ |
| dgabino | 0:9002b89157da | 51 | char code_to_char(uint8_t x); |
| dgabino | 0:9002b89157da | 52 | |
| dgabino | 0:9002b89157da | 53 | /** |
| dgabino | 0:9002b89157da | 54 | @brief Convert an ASCII character to a code in the range 0-63 |
| dgabino | 0:9002b89157da | 55 | */ |
| dgabino | 0:9002b89157da | 56 | uint8_t char_to_code(char x); |
| dgabino | 0:9002b89157da | 57 | |
| dgabino | 0:9002b89157da | 58 | /* -------------------------------------------------------------------------- */ |
| dgabino | 0:9002b89157da | 59 | /* --- PRIVATE FUNCTIONS DEFINITION ----------------------------------------- */ |
| dgabino | 0:9002b89157da | 60 | |
| dgabino | 0:9002b89157da | 61 | char code_to_char(uint8_t x) { |
| dgabino | 0:9002b89157da | 62 | if (x <= 25) { |
| dgabino | 0:9002b89157da | 63 | return 'A' + x; |
| dgabino | 0:9002b89157da | 64 | } else if ((x >= 26) && (x <= 51)) { |
| dgabino | 0:9002b89157da | 65 | return 'a' + (x - 26); |
| dgabino | 0:9002b89157da | 66 | } else if ((x >= 52) && (x <= 61)) { |
| dgabino | 0:9002b89157da | 67 | return '0' + (x - 52); |
| dgabino | 0:9002b89157da | 68 | } else if (x == 62) { |
| dgabino | 0:9002b89157da | 69 | return code_62; |
| dgabino | 0:9002b89157da | 70 | } else if (x == 63) { |
| dgabino | 0:9002b89157da | 71 | return code_63; |
| dgabino | 0:9002b89157da | 72 | } else { |
| dgabino | 0:9002b89157da | 73 | DEBUG("ERROR: %i IS OUT OF RANGE 0-63 FOR BASE64 ENCODING\n", x); |
| dgabino | 0:9002b89157da | 74 | exit(EXIT_FAILURE); |
| dgabino | 0:9002b89157da | 75 | } //TODO: improve error management |
| dgabino | 0:9002b89157da | 76 | } |
| dgabino | 0:9002b89157da | 77 | |
| dgabino | 0:9002b89157da | 78 | uint8_t char_to_code(char x) { |
| dgabino | 0:9002b89157da | 79 | if ((x >= 'A') && (x <= 'Z')) { |
| dgabino | 0:9002b89157da | 80 | return (uint8_t)x - (uint8_t)'A'; |
| dgabino | 0:9002b89157da | 81 | } else if ((x >= 'a') && (x <= 'z')) { |
| dgabino | 0:9002b89157da | 82 | return (uint8_t)x - (uint8_t)'a' + 26; |
| dgabino | 0:9002b89157da | 83 | } else if ((x >= '0') && (x <= '9')) { |
| dgabino | 0:9002b89157da | 84 | return (uint8_t)x - (uint8_t)'0' + 52; |
| dgabino | 0:9002b89157da | 85 | } else if (x == code_62) { |
| dgabino | 0:9002b89157da | 86 | return 62; |
| dgabino | 0:9002b89157da | 87 | } else if (x == code_63) { |
| dgabino | 0:9002b89157da | 88 | return 63; |
| dgabino | 0:9002b89157da | 89 | } else { |
| dgabino | 0:9002b89157da | 90 | DEBUG("ERROR: %c (0x%x) IS INVALID CHARACTER FOR BASE64 DECODING\n", x, x); |
| dgabino | 0:9002b89157da | 91 | exit(EXIT_FAILURE); |
| dgabino | 0:9002b89157da | 92 | } //TODO: improve error management |
| dgabino | 0:9002b89157da | 93 | } |
| dgabino | 0:9002b89157da | 94 | |
| dgabino | 0:9002b89157da | 95 | /* -------------------------------------------------------------------------- */ |
| dgabino | 0:9002b89157da | 96 | /* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */ |
| dgabino | 0:9002b89157da | 97 | |
| dgabino | 0:9002b89157da | 98 | int bin_to_b64_nopad(const uint8_t * in, int size, char * out, int max_len) { |
| dgabino | 0:9002b89157da | 99 | int i; |
| dgabino | 0:9002b89157da | 100 | int result_len; /* size of the result */ |
| dgabino | 0:9002b89157da | 101 | int full_blocks; /* number of 3 unsigned chars / 4 characters blocks */ |
| dgabino | 0:9002b89157da | 102 | int last_bytes; /* number of unsigned chars <3 in the last block */ |
| dgabino | 0:9002b89157da | 103 | int last_chars; /* number of characters <4 in the last block */ |
| dgabino | 0:9002b89157da | 104 | uint32_t b; |
| dgabino | 0:9002b89157da | 105 | |
| dgabino | 0:9002b89157da | 106 | /* check input values */ |
| dgabino | 0:9002b89157da | 107 | if ((out == NULL) || (in == NULL)) { |
| dgabino | 0:9002b89157da | 108 | DEBUG("ERROR: NULL POINTER AS OUTPUT IN BIN_TO_B64\n"); |
| dgabino | 0:9002b89157da | 109 | return -1; |
| dgabino | 0:9002b89157da | 110 | } |
| dgabino | 0:9002b89157da | 111 | if (size == 0) { |
| dgabino | 0:9002b89157da | 112 | *out = 0; /* null string */ |
| dgabino | 0:9002b89157da | 113 | return 0; |
| dgabino | 0:9002b89157da | 114 | } |
| dgabino | 0:9002b89157da | 115 | |
| dgabino | 0:9002b89157da | 116 | /* calculate the number of base64 'blocks' */ |
| dgabino | 0:9002b89157da | 117 | full_blocks = size / 3; |
| dgabino | 0:9002b89157da | 118 | last_bytes = size % 3; |
| dgabino | 0:9002b89157da | 119 | switch (last_bytes) { |
| dgabino | 0:9002b89157da | 120 | case 0: /* no byte left to encode */ |
| dgabino | 0:9002b89157da | 121 | last_chars = 0; |
| dgabino | 0:9002b89157da | 122 | break; |
| dgabino | 0:9002b89157da | 123 | case 1: /* 1 byte left to encode -> +2 chars */ |
| dgabino | 0:9002b89157da | 124 | last_chars = 2; |
| dgabino | 0:9002b89157da | 125 | break; |
| dgabino | 0:9002b89157da | 126 | case 2: /* 2 bytes left to encode -> +3 chars */ |
| dgabino | 0:9002b89157da | 127 | last_chars = 3; |
| dgabino | 0:9002b89157da | 128 | break; |
| dgabino | 0:9002b89157da | 129 | default: |
| dgabino | 0:9002b89157da | 130 | CRIT("switch default that should not be possible"); |
| dgabino | 0:9002b89157da | 131 | } |
| dgabino | 0:9002b89157da | 132 | |
| dgabino | 0:9002b89157da | 133 | /* check if output buffer is big enough */ |
| dgabino | 0:9002b89157da | 134 | result_len = (4 * full_blocks) + last_chars; |
| dgabino | 0:9002b89157da | 135 | if (max_len < (result_len + 1)) { /* 1 char added for string terminator */ |
| dgabino | 0:9002b89157da | 136 | DEBUG("ERROR: OUTPUT BUFFER TOO SMALL IN BIN_TO_B64\n"); |
| dgabino | 0:9002b89157da | 137 | return -1; |
| dgabino | 0:9002b89157da | 138 | } |
| dgabino | 0:9002b89157da | 139 | |
| dgabino | 0:9002b89157da | 140 | /* process all the full blocks */ |
| dgabino | 0:9002b89157da | 141 | for (i = 0; i < full_blocks; ++i) { |
| dgabino | 0:9002b89157da | 142 | b = (0xFF & in[3 * i] ) << 16; |
| dgabino | 0:9002b89157da | 143 | b |= (0xFF & in[3 * i + 1]) << 8; |
| dgabino | 0:9002b89157da | 144 | b |= 0xFF & in[3 * i + 2]; |
| dgabino | 0:9002b89157da | 145 | out[4 * i + 0] = code_to_char((b >> 18) & 0x3F); |
| dgabino | 0:9002b89157da | 146 | out[4 * i + 1] = code_to_char((b >> 12) & 0x3F); |
| dgabino | 0:9002b89157da | 147 | out[4 * i + 2] = code_to_char((b >> 6 ) & 0x3F); |
| dgabino | 0:9002b89157da | 148 | out[4 * i + 3] = code_to_char( b & 0x3F); |
| dgabino | 0:9002b89157da | 149 | } |
| dgabino | 0:9002b89157da | 150 | |
| dgabino | 0:9002b89157da | 151 | /* process the last 'partial' block and terminate string */ |
| dgabino | 0:9002b89157da | 152 | i = full_blocks; |
| dgabino | 0:9002b89157da | 153 | if (last_chars == 0) { |
| dgabino | 0:9002b89157da | 154 | out[4 * i] = 0; /* null character to terminate string */ |
| dgabino | 0:9002b89157da | 155 | } else if (last_chars == 2) { |
| dgabino | 0:9002b89157da | 156 | b = (0xFF & in[3 * i] ) << 16; |
| dgabino | 0:9002b89157da | 157 | out[4 * i + 0] = code_to_char((b >> 18) & 0x3F); |
| dgabino | 0:9002b89157da | 158 | out[4 * i + 1] = code_to_char((b >> 12) & 0x3F); |
| dgabino | 0:9002b89157da | 159 | out[4 * i + 2] = 0; /* null character to terminate string */ |
| dgabino | 0:9002b89157da | 160 | } else if (last_chars == 3) { |
| dgabino | 0:9002b89157da | 161 | b = (0xFF & in[3 * i] ) << 16; |
| dgabino | 0:9002b89157da | 162 | b |= (0xFF & in[3 * i + 1]) << 8; |
| dgabino | 0:9002b89157da | 163 | out[4 * i + 0] = code_to_char((b >> 18) & 0x3F); |
| dgabino | 0:9002b89157da | 164 | out[4 * i + 1] = code_to_char((b >> 12) & 0x3F); |
| dgabino | 0:9002b89157da | 165 | out[4 * i + 2] = code_to_char((b >> 6 ) & 0x3F); |
| dgabino | 0:9002b89157da | 166 | out[4 * i + 3] = 0; /* null character to terminate string */ |
| dgabino | 0:9002b89157da | 167 | } |
| dgabino | 0:9002b89157da | 168 | |
| dgabino | 0:9002b89157da | 169 | return result_len; |
| dgabino | 0:9002b89157da | 170 | } |
| dgabino | 0:9002b89157da | 171 | |
| dgabino | 0:9002b89157da | 172 | int b64_to_bin_nopad(const char * in, int size, uint8_t * out, int max_len) { |
| dgabino | 0:9002b89157da | 173 | int i; |
| dgabino | 0:9002b89157da | 174 | int result_len; /* size of the result */ |
| dgabino | 0:9002b89157da | 175 | int full_blocks; /* number of 3 unsigned chars / 4 characters blocks */ |
| dgabino | 0:9002b89157da | 176 | int last_chars; /* number of characters <4 in the last block */ |
| dgabino | 0:9002b89157da | 177 | int last_bytes; /* number of unsigned chars <3 in the last block */ |
| dgabino | 0:9002b89157da | 178 | uint32_t b; |
| dgabino | 0:9002b89157da | 179 | ; |
| dgabino | 0:9002b89157da | 180 | |
| dgabino | 0:9002b89157da | 181 | /* check input values */ |
| dgabino | 0:9002b89157da | 182 | if ((out == NULL) || (in == NULL)) { |
| dgabino | 0:9002b89157da | 183 | DEBUG("ERROR: NULL POINTER AS OUTPUT OR INPUT IN B64_TO_BIN\n"); |
| dgabino | 0:9002b89157da | 184 | return -1; |
| dgabino | 0:9002b89157da | 185 | } |
| dgabino | 0:9002b89157da | 186 | if (size == 0) { |
| dgabino | 0:9002b89157da | 187 | return 0; |
| dgabino | 0:9002b89157da | 188 | } |
| dgabino | 0:9002b89157da | 189 | |
| dgabino | 0:9002b89157da | 190 | /* calculate the number of base64 'blocks' */ |
| dgabino | 0:9002b89157da | 191 | full_blocks = size / 4; |
| dgabino | 0:9002b89157da | 192 | last_chars = size % 4; |
| dgabino | 0:9002b89157da | 193 | switch (last_chars) { |
| dgabino | 0:9002b89157da | 194 | case 0: /* no char left to decode */ |
| dgabino | 0:9002b89157da | 195 | last_bytes = 0; |
| dgabino | 0:9002b89157da | 196 | break; |
| dgabino | 0:9002b89157da | 197 | case 1: /* only 1 char left is an error */ |
| dgabino | 0:9002b89157da | 198 | DEBUG("ERROR: ONLY ONE CHAR LEFT IN B64_TO_BIN\n"); |
| dgabino | 0:9002b89157da | 199 | return -1; |
| dgabino | 0:9002b89157da | 200 | case 2: /* 2 chars left to decode -> +1 byte */ |
| dgabino | 0:9002b89157da | 201 | last_bytes = 1; |
| dgabino | 0:9002b89157da | 202 | break; |
| dgabino | 0:9002b89157da | 203 | case 3: /* 3 chars left to decode -> +2 bytes */ |
| dgabino | 0:9002b89157da | 204 | last_bytes = 2; |
| dgabino | 0:9002b89157da | 205 | break; |
| dgabino | 0:9002b89157da | 206 | default: |
| dgabino | 0:9002b89157da | 207 | CRIT("switch default that should not be possible"); |
| dgabino | 0:9002b89157da | 208 | } |
| dgabino | 0:9002b89157da | 209 | |
| dgabino | 0:9002b89157da | 210 | /* check if output buffer is big enough */ |
| dgabino | 0:9002b89157da | 211 | result_len = (3 * full_blocks) + last_bytes; |
| dgabino | 0:9002b89157da | 212 | if (max_len < result_len) { |
| dgabino | 0:9002b89157da | 213 | DEBUG("ERROR: OUTPUT BUFFER TOO SMALL IN B64_TO_BIN\n"); |
| dgabino | 0:9002b89157da | 214 | return -1; |
| dgabino | 0:9002b89157da | 215 | } |
| dgabino | 0:9002b89157da | 216 | |
| dgabino | 0:9002b89157da | 217 | /* process all the full blocks */ |
| dgabino | 0:9002b89157da | 218 | for (i = 0; i < full_blocks; ++i) { |
| dgabino | 0:9002b89157da | 219 | b = (0x3F & char_to_code(in[4 * i] )) << 18; |
| dgabino | 0:9002b89157da | 220 | b |= (0x3F & char_to_code(in[4 * i + 1])) << 12; |
| dgabino | 0:9002b89157da | 221 | b |= (0x3F & char_to_code(in[4 * i + 2])) << 6; |
| dgabino | 0:9002b89157da | 222 | b |= 0x3F & char_to_code(in[4 * i + 3]); |
| dgabino | 0:9002b89157da | 223 | out[3 * i + 0] = (b >> 16) & 0xFF; |
| dgabino | 0:9002b89157da | 224 | out[3 * i + 1] = (b >> 8 ) & 0xFF; |
| dgabino | 0:9002b89157da | 225 | out[3 * i + 2] = b & 0xFF; |
| dgabino | 0:9002b89157da | 226 | } |
| dgabino | 0:9002b89157da | 227 | |
| dgabino | 0:9002b89157da | 228 | /* process the last 'partial' block */ |
| dgabino | 0:9002b89157da | 229 | i = full_blocks; |
| dgabino | 0:9002b89157da | 230 | if (last_bytes == 1) { |
| dgabino | 0:9002b89157da | 231 | b = (0x3F & char_to_code(in[4 * i] )) << 18; |
| dgabino | 0:9002b89157da | 232 | b |= (0x3F & char_to_code(in[4 * i + 1])) << 12; |
| dgabino | 0:9002b89157da | 233 | out[3 * i + 0] = (b >> 16) & 0xFF; |
| dgabino | 0:9002b89157da | 234 | if (((b >> 12) & 0x0F) != 0) { |
| dgabino | 0:9002b89157da | 235 | DEBUG("WARNING: last character contains unusable bits\n"); |
| dgabino | 0:9002b89157da | 236 | } |
| dgabino | 0:9002b89157da | 237 | } else if (last_bytes == 2) { |
| dgabino | 0:9002b89157da | 238 | b = (0x3F & char_to_code(in[4 * i] )) << 18; |
| dgabino | 0:9002b89157da | 239 | b |= (0x3F & char_to_code(in[4 * i + 1])) << 12; |
| dgabino | 0:9002b89157da | 240 | b |= (0x3F & char_to_code(in[4 * i + 2])) << 6; |
| dgabino | 0:9002b89157da | 241 | out[3 * i + 0] = (b >> 16) & 0xFF; |
| dgabino | 0:9002b89157da | 242 | out[3 * i + 1] = (b >> 8 ) & 0xFF; |
| dgabino | 0:9002b89157da | 243 | if (((b >> 6) & 0x03) != 0) { |
| dgabino | 0:9002b89157da | 244 | DEBUG("WARNING: last character contains unusable bits\n"); |
| dgabino | 0:9002b89157da | 245 | } |
| dgabino | 0:9002b89157da | 246 | } |
| dgabino | 0:9002b89157da | 247 | |
| dgabino | 0:9002b89157da | 248 | return result_len; |
| dgabino | 0:9002b89157da | 249 | } |
| dgabino | 0:9002b89157da | 250 | |
| dgabino | 0:9002b89157da | 251 | int bin_to_b64(const uint8_t * in, int size, char * out, int max_len) { |
| dgabino | 0:9002b89157da | 252 | int ret; |
| dgabino | 0:9002b89157da | 253 | |
| dgabino | 0:9002b89157da | 254 | ret = bin_to_b64_nopad(in, size, out, max_len); |
| dgabino | 0:9002b89157da | 255 | |
| dgabino | 0:9002b89157da | 256 | if (ret == -1) { |
| dgabino | 0:9002b89157da | 257 | return -1; |
| dgabino | 0:9002b89157da | 258 | } |
| dgabino | 0:9002b89157da | 259 | switch (ret % 4) { |
| dgabino | 0:9002b89157da | 260 | case 0: /* nothing to do */ |
| dgabino | 0:9002b89157da | 261 | return ret; |
| dgabino | 0:9002b89157da | 262 | case 1: |
| dgabino | 0:9002b89157da | 263 | DEBUG("ERROR: INVALID UNPADDED BASE64 STRING\n"); |
| dgabino | 0:9002b89157da | 264 | return -1; |
| dgabino | 0:9002b89157da | 265 | case 2: /* 2 chars in last block, must add 2 padding char */ |
| dgabino | 0:9002b89157da | 266 | if (max_len >= (ret + 2 + 1)) { |
| dgabino | 0:9002b89157da | 267 | out[ret] = code_pad; |
| dgabino | 0:9002b89157da | 268 | out[ret + 1] = code_pad; |
| dgabino | 0:9002b89157da | 269 | out[ret + 2] = 0; |
| dgabino | 0:9002b89157da | 270 | return ret + 2; |
| dgabino | 0:9002b89157da | 271 | } else { |
| dgabino | 0:9002b89157da | 272 | DEBUG("ERROR: not enough room to add padding in bin_to_b64\n"); |
| dgabino | 0:9002b89157da | 273 | return -1; |
| dgabino | 0:9002b89157da | 274 | } |
| dgabino | 0:9002b89157da | 275 | case 3: /* 3 chars in last block, must add 1 padding char */ |
| dgabino | 0:9002b89157da | 276 | if (max_len >= (ret + 1 + 1)) { |
| dgabino | 0:9002b89157da | 277 | out[ret] = code_pad; |
| dgabino | 0:9002b89157da | 278 | out[ret + 1] = 0; |
| dgabino | 0:9002b89157da | 279 | return ret + 1; |
| dgabino | 0:9002b89157da | 280 | } else { |
| dgabino | 0:9002b89157da | 281 | DEBUG("ERROR: not enough room to add padding in bin_to_b64\n"); |
| dgabino | 0:9002b89157da | 282 | return -1; |
| dgabino | 0:9002b89157da | 283 | } |
| dgabino | 0:9002b89157da | 284 | default: |
| dgabino | 0:9002b89157da | 285 | CRIT("switch default that should not be possible"); |
| dgabino | 0:9002b89157da | 286 | } |
| dgabino | 0:9002b89157da | 287 | } |
| dgabino | 0:9002b89157da | 288 | |
| dgabino | 0:9002b89157da | 289 | int b64_to_bin(const char * in, int size, uint8_t * out, int max_len) { |
| dgabino | 0:9002b89157da | 290 | if (in == NULL) { |
| dgabino | 0:9002b89157da | 291 | DEBUG("ERROR: NULL POINTER AS OUTPUT OR INPUT IN B64_TO_BIN\n"); |
| dgabino | 0:9002b89157da | 292 | return -1; |
| dgabino | 0:9002b89157da | 293 | } |
| dgabino | 0:9002b89157da | 294 | if ((size % 4 == 0) && (size >= 4)) { /* potentially padded Base64 */ |
| dgabino | 0:9002b89157da | 295 | if (in[size - 2] == code_pad) { /* 2 padding char to ignore */ |
| dgabino | 0:9002b89157da | 296 | return b64_to_bin_nopad(in, size - 2, out, max_len); |
| dgabino | 0:9002b89157da | 297 | } else if (in[size - 1] == code_pad) { /* 1 padding char to ignore */ |
| dgabino | 0:9002b89157da | 298 | return b64_to_bin_nopad(in, size - 1, out, max_len); |
| dgabino | 0:9002b89157da | 299 | } else { /* no padding to ignore */ |
| dgabino | 0:9002b89157da | 300 | return b64_to_bin_nopad(in, size, out, max_len); |
| dgabino | 0:9002b89157da | 301 | } |
| dgabino | 0:9002b89157da | 302 | } else { /* treat as unpadded Base64 */ |
| dgabino | 0:9002b89157da | 303 | return b64_to_bin_nopad(in, size, out, max_len); |
| dgabino | 0:9002b89157da | 304 | } |
| dgabino | 0:9002b89157da | 305 | } |
| dgabino | 0:9002b89157da | 306 | |
| dgabino | 0:9002b89157da | 307 | |
| dgabino | 0:9002b89157da | 308 | /* --- EOF ------------------------------------------------------------------ */ |