wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Committer:
wolfSSL
Date:
Fri Jun 05 00:11:07 2020 +0000
Revision:
17:a5f916481144
Parent:
16:8e0d178b1d1e
wolfSSL 4.4.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 15:117db924cf7c 1 /* coding.c
wolfSSL 15:117db924cf7c 2 *
wolfSSL 16:8e0d178b1d1e 3 * Copyright (C) 2006-2020 wolfSSL Inc.
wolfSSL 15:117db924cf7c 4 *
wolfSSL 15:117db924cf7c 5 * This file is part of wolfSSL.
wolfSSL 15:117db924cf7c 6 *
wolfSSL 15:117db924cf7c 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 15:117db924cf7c 8 * it under the terms of the GNU General Public License as published by
wolfSSL 15:117db924cf7c 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 15:117db924cf7c 10 * (at your option) any later version.
wolfSSL 15:117db924cf7c 11 *
wolfSSL 15:117db924cf7c 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 15:117db924cf7c 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 15:117db924cf7c 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 15:117db924cf7c 15 * GNU General Public License for more details.
wolfSSL 15:117db924cf7c 16 *
wolfSSL 15:117db924cf7c 17 * You should have received a copy of the GNU General Public License
wolfSSL 15:117db924cf7c 18 * along with this program; if not, write to the Free Software
wolfSSL 15:117db924cf7c 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 15:117db924cf7c 20 */
wolfSSL 15:117db924cf7c 21
wolfSSL 15:117db924cf7c 22
wolfSSL 15:117db924cf7c 23 #ifdef HAVE_CONFIG_H
wolfSSL 15:117db924cf7c 24 #include <config.h>
wolfSSL 15:117db924cf7c 25 #endif
wolfSSL 15:117db924cf7c 26
wolfSSL 15:117db924cf7c 27 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 15:117db924cf7c 28
wolfSSL 15:117db924cf7c 29 #ifndef NO_CODING
wolfSSL 15:117db924cf7c 30
wolfSSL 15:117db924cf7c 31 #include <wolfssl/wolfcrypt/coding.h>
wolfSSL 15:117db924cf7c 32 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 15:117db924cf7c 33 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 15:117db924cf7c 34
wolfSSL 15:117db924cf7c 35
wolfSSL 15:117db924cf7c 36 enum {
wolfSSL 15:117db924cf7c 37 BAD = 0xFF, /* invalid encoding */
wolfSSL 15:117db924cf7c 38 PAD = '=',
wolfSSL 16:8e0d178b1d1e 39 PEM_LINE_SZ = 64,
wolfSSL 16:8e0d178b1d1e 40 BASE64_MIN = 0x2B,
wolfSSL 16:8e0d178b1d1e 41 BASE16_MIN = 0x30,
wolfSSL 15:117db924cf7c 42 };
wolfSSL 15:117db924cf7c 43
wolfSSL 15:117db924cf7c 44
wolfSSL 16:8e0d178b1d1e 45 #ifdef WOLFSSL_BASE64_DECODE
wolfSSL 16:8e0d178b1d1e 46
wolfSSL 15:117db924cf7c 47 static
wolfSSL 15:117db924cf7c 48 const byte base64Decode[] = { 62, BAD, BAD, BAD, 63, /* + starts at 0x2B */
wolfSSL 15:117db924cf7c 49 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
wolfSSL 15:117db924cf7c 50 BAD, BAD, BAD, BAD, BAD, BAD, BAD,
wolfSSL 15:117db924cf7c 51 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
wolfSSL 15:117db924cf7c 52 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
wolfSSL 15:117db924cf7c 53 20, 21, 22, 23, 24, 25,
wolfSSL 15:117db924cf7c 54 BAD, BAD, BAD, BAD, BAD, BAD,
wolfSSL 15:117db924cf7c 55 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
wolfSSL 15:117db924cf7c 56 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
wolfSSL 15:117db924cf7c 57 46, 47, 48, 49, 50, 51
wolfSSL 15:117db924cf7c 58 };
wolfSSL 15:117db924cf7c 59
wolfSSL 16:8e0d178b1d1e 60 static WC_INLINE int Base64_SkipNewline(const byte* in, word32 *inLen, word32 *outJ)
wolfSSL 16:8e0d178b1d1e 61 {
wolfSSL 16:8e0d178b1d1e 62 word32 len = *inLen;
wolfSSL 16:8e0d178b1d1e 63 word32 j = *outJ;
wolfSSL 16:8e0d178b1d1e 64 if (len && (in[j] == ' ' || in[j] == '\r' || in[j] == '\n')) {
wolfSSL 16:8e0d178b1d1e 65 byte endLine = in[j++];
wolfSSL 16:8e0d178b1d1e 66 len--;
wolfSSL 16:8e0d178b1d1e 67 while (len && endLine == ' ') { /* allow trailing whitespace */
wolfSSL 16:8e0d178b1d1e 68 endLine = in[j++];
wolfSSL 16:8e0d178b1d1e 69 len--;
wolfSSL 16:8e0d178b1d1e 70 }
wolfSSL 16:8e0d178b1d1e 71 if (endLine == '\r') {
wolfSSL 16:8e0d178b1d1e 72 if (len) {
wolfSSL 16:8e0d178b1d1e 73 endLine = in[j++];
wolfSSL 16:8e0d178b1d1e 74 len--;
wolfSSL 16:8e0d178b1d1e 75 }
wolfSSL 16:8e0d178b1d1e 76 }
wolfSSL 16:8e0d178b1d1e 77 if (endLine != '\n') {
wolfSSL 16:8e0d178b1d1e 78 WOLFSSL_MSG("Bad end of line in Base64 Decode");
wolfSSL 16:8e0d178b1d1e 79 return ASN_INPUT_E;
wolfSSL 16:8e0d178b1d1e 80 }
wolfSSL 16:8e0d178b1d1e 81 }
wolfSSL 16:8e0d178b1d1e 82 if (!len) {
wolfSSL 16:8e0d178b1d1e 83 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 84 }
wolfSSL 16:8e0d178b1d1e 85 *inLen = len;
wolfSSL 16:8e0d178b1d1e 86 *outJ = j;
wolfSSL 16:8e0d178b1d1e 87 return 0;
wolfSSL 16:8e0d178b1d1e 88 }
wolfSSL 15:117db924cf7c 89
wolfSSL 15:117db924cf7c 90 int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
wolfSSL 15:117db924cf7c 91 {
wolfSSL 15:117db924cf7c 92 word32 i = 0;
wolfSSL 15:117db924cf7c 93 word32 j = 0;
wolfSSL 15:117db924cf7c 94 word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ );
wolfSSL 16:8e0d178b1d1e 95 int ret;
wolfSSL 16:8e0d178b1d1e 96 const byte maxIdx = (byte)sizeof(base64Decode) + BASE64_MIN - 1;
wolfSSL 15:117db924cf7c 97
wolfSSL 15:117db924cf7c 98 plainSz = (plainSz * 3 + 3) / 4;
wolfSSL 15:117db924cf7c 99 if (plainSz > *outLen) return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 100
wolfSSL 15:117db924cf7c 101 while (inLen > 3) {
wolfSSL 15:117db924cf7c 102 int pad3 = 0;
wolfSSL 15:117db924cf7c 103 int pad4 = 0;
wolfSSL 15:117db924cf7c 104
wolfSSL 16:8e0d178b1d1e 105 byte b1, b2, b3;
wolfSSL 16:8e0d178b1d1e 106 byte e1, e2, e3, e4;
wolfSSL 16:8e0d178b1d1e 107 if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) {
wolfSSL 16:8e0d178b1d1e 108 if (ret == BUFFER_E) {
wolfSSL 16:8e0d178b1d1e 109 /* Running out of buffer here is not an error */
wolfSSL 16:8e0d178b1d1e 110 break;
wolfSSL 16:8e0d178b1d1e 111 }
wolfSSL 16:8e0d178b1d1e 112 return ret;
wolfSSL 16:8e0d178b1d1e 113 }
wolfSSL 16:8e0d178b1d1e 114 e1 = in[j++];
wolfSSL 16:8e0d178b1d1e 115 if (e1 == '\0') {
wolfSSL 16:8e0d178b1d1e 116 break;
wolfSSL 16:8e0d178b1d1e 117 }
wolfSSL 16:8e0d178b1d1e 118 inLen--;
wolfSSL 16:8e0d178b1d1e 119 if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) {
wolfSSL 16:8e0d178b1d1e 120 return ret;
wolfSSL 16:8e0d178b1d1e 121 }
wolfSSL 16:8e0d178b1d1e 122 e2 = in[j++];
wolfSSL 16:8e0d178b1d1e 123 inLen--;
wolfSSL 16:8e0d178b1d1e 124 if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) {
wolfSSL 16:8e0d178b1d1e 125 return ret;
wolfSSL 16:8e0d178b1d1e 126 }
wolfSSL 16:8e0d178b1d1e 127 e3 = in[j++];
wolfSSL 16:8e0d178b1d1e 128 inLen--;
wolfSSL 16:8e0d178b1d1e 129 if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) {
wolfSSL 16:8e0d178b1d1e 130 return ret;
wolfSSL 16:8e0d178b1d1e 131 }
wolfSSL 16:8e0d178b1d1e 132 e4 = in[j++];
wolfSSL 16:8e0d178b1d1e 133 inLen--;
wolfSSL 16:8e0d178b1d1e 134
wolfSSL 15:117db924cf7c 135 if (e1 == 0) /* end file 0's */
wolfSSL 15:117db924cf7c 136 break;
wolfSSL 15:117db924cf7c 137 if (e3 == PAD)
wolfSSL 15:117db924cf7c 138 pad3 = 1;
wolfSSL 15:117db924cf7c 139 if (e4 == PAD)
wolfSSL 15:117db924cf7c 140 pad4 = 1;
wolfSSL 15:117db924cf7c 141
wolfSSL 16:8e0d178b1d1e 142 if (e1 < BASE64_MIN || e2 < BASE64_MIN || e3 < BASE64_MIN || e4 < BASE64_MIN) {
wolfSSL 15:117db924cf7c 143 WOLFSSL_MSG("Bad Base64 Decode data, too small");
wolfSSL 15:117db924cf7c 144 return ASN_INPUT_E;
wolfSSL 15:117db924cf7c 145 }
wolfSSL 15:117db924cf7c 146
wolfSSL 15:117db924cf7c 147 if (e1 > maxIdx || e2 > maxIdx || e3 > maxIdx || e4 > maxIdx) {
wolfSSL 15:117db924cf7c 148 WOLFSSL_MSG("Bad Base64 Decode data, too big");
wolfSSL 15:117db924cf7c 149 return ASN_INPUT_E;
wolfSSL 15:117db924cf7c 150 }
wolfSSL 15:117db924cf7c 151
wolfSSL 16:8e0d178b1d1e 152 if (i + 1 + !pad3 + !pad4 > *outLen) {
wolfSSL 16:8e0d178b1d1e 153 WOLFSSL_MSG("Bad Base64 Decode out buffer, too small");
wolfSSL 16:8e0d178b1d1e 154 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 155 }
wolfSSL 16:8e0d178b1d1e 156
wolfSSL 16:8e0d178b1d1e 157 e1 = base64Decode[e1 - BASE64_MIN];
wolfSSL 16:8e0d178b1d1e 158 e2 = base64Decode[e2 - BASE64_MIN];
wolfSSL 16:8e0d178b1d1e 159 e3 = (e3 == PAD) ? 0 : base64Decode[e3 - BASE64_MIN];
wolfSSL 16:8e0d178b1d1e 160 e4 = (e4 == PAD) ? 0 : base64Decode[e4 - BASE64_MIN];
wolfSSL 15:117db924cf7c 161
wolfSSL 15:117db924cf7c 162 b1 = (byte)((e1 << 2) | (e2 >> 4));
wolfSSL 15:117db924cf7c 163 b2 = (byte)(((e2 & 0xF) << 4) | (e3 >> 2));
wolfSSL 15:117db924cf7c 164 b3 = (byte)(((e3 & 0x3) << 6) | e4);
wolfSSL 15:117db924cf7c 165
wolfSSL 15:117db924cf7c 166 out[i++] = b1;
wolfSSL 15:117db924cf7c 167 if (!pad3)
wolfSSL 15:117db924cf7c 168 out[i++] = b2;
wolfSSL 15:117db924cf7c 169 if (!pad4)
wolfSSL 15:117db924cf7c 170 out[i++] = b3;
wolfSSL 15:117db924cf7c 171 else
wolfSSL 15:117db924cf7c 172 break;
wolfSSL 16:8e0d178b1d1e 173 }
wolfSSL 16:8e0d178b1d1e 174 /* If the output buffer has a room for an extra byte, add a null terminator */
wolfSSL 16:8e0d178b1d1e 175 if (out && *outLen > i)
wolfSSL 16:8e0d178b1d1e 176 out[i]= '\0';
wolfSSL 15:117db924cf7c 177
wolfSSL 15:117db924cf7c 178 *outLen = i;
wolfSSL 15:117db924cf7c 179
wolfSSL 15:117db924cf7c 180 return 0;
wolfSSL 15:117db924cf7c 181 }
wolfSSL 15:117db924cf7c 182
wolfSSL 16:8e0d178b1d1e 183 #endif /* WOLFSSL_BASE64_DECODE */
wolfSSL 15:117db924cf7c 184
wolfSSL 15:117db924cf7c 185 #if defined(WOLFSSL_BASE64_ENCODE)
wolfSSL 15:117db924cf7c 186
wolfSSL 15:117db924cf7c 187 static
wolfSSL 15:117db924cf7c 188 const byte base64Encode[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
wolfSSL 15:117db924cf7c 189 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
wolfSSL 15:117db924cf7c 190 'U', 'V', 'W', 'X', 'Y', 'Z',
wolfSSL 15:117db924cf7c 191 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
wolfSSL 15:117db924cf7c 192 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
wolfSSL 15:117db924cf7c 193 'u', 'v', 'w', 'x', 'y', 'z',
wolfSSL 15:117db924cf7c 194 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
wolfSSL 15:117db924cf7c 195 '+', '/'
wolfSSL 15:117db924cf7c 196 };
wolfSSL 15:117db924cf7c 197
wolfSSL 15:117db924cf7c 198
wolfSSL 15:117db924cf7c 199 /* make sure *i (idx) won't exceed max, store and possibly escape to out,
wolfSSL 15:117db924cf7c 200 * raw means use e w/o decode, 0 on success */
wolfSSL 15:117db924cf7c 201 static int CEscape(int escaped, byte e, byte* out, word32* i, word32 max,
wolfSSL 15:117db924cf7c 202 int raw, int getSzOnly)
wolfSSL 15:117db924cf7c 203 {
wolfSSL 15:117db924cf7c 204 int doEscape = 0;
wolfSSL 15:117db924cf7c 205 word32 needed = 1;
wolfSSL 15:117db924cf7c 206 word32 idx = *i;
wolfSSL 15:117db924cf7c 207
wolfSSL 15:117db924cf7c 208 byte basic;
wolfSSL 15:117db924cf7c 209 byte plus = 0;
wolfSSL 15:117db924cf7c 210 byte equals = 0;
wolfSSL 15:117db924cf7c 211 byte newline = 0;
wolfSSL 15:117db924cf7c 212
wolfSSL 15:117db924cf7c 213 if (raw)
wolfSSL 15:117db924cf7c 214 basic = e;
wolfSSL 15:117db924cf7c 215 else
wolfSSL 15:117db924cf7c 216 basic = base64Encode[e];
wolfSSL 15:117db924cf7c 217
wolfSSL 15:117db924cf7c 218 /* check whether to escape. Only escape for EncodeEsc */
wolfSSL 15:117db924cf7c 219 if (escaped == WC_ESC_NL_ENC) {
wolfSSL 15:117db924cf7c 220 switch ((char)basic) {
wolfSSL 15:117db924cf7c 221 case '+' :
wolfSSL 15:117db924cf7c 222 plus = 1;
wolfSSL 15:117db924cf7c 223 doEscape = 1;
wolfSSL 15:117db924cf7c 224 needed += 2;
wolfSSL 15:117db924cf7c 225 break;
wolfSSL 15:117db924cf7c 226 case '=' :
wolfSSL 15:117db924cf7c 227 equals = 1;
wolfSSL 15:117db924cf7c 228 doEscape = 1;
wolfSSL 15:117db924cf7c 229 needed += 2;
wolfSSL 15:117db924cf7c 230 break;
wolfSSL 15:117db924cf7c 231 case '\n' :
wolfSSL 15:117db924cf7c 232 newline = 1;
wolfSSL 15:117db924cf7c 233 doEscape = 1;
wolfSSL 15:117db924cf7c 234 needed += 2;
wolfSSL 15:117db924cf7c 235 break;
wolfSSL 15:117db924cf7c 236 default:
wolfSSL 15:117db924cf7c 237 /* do nothing */
wolfSSL 15:117db924cf7c 238 break;
wolfSSL 15:117db924cf7c 239 }
wolfSSL 15:117db924cf7c 240 }
wolfSSL 15:117db924cf7c 241
wolfSSL 15:117db924cf7c 242 /* check size */
wolfSSL 15:117db924cf7c 243 if ( (idx+needed) > max && !getSzOnly) {
wolfSSL 15:117db924cf7c 244 WOLFSSL_MSG("Escape buffer max too small");
wolfSSL 15:117db924cf7c 245 return BUFFER_E;
wolfSSL 15:117db924cf7c 246 }
wolfSSL 15:117db924cf7c 247
wolfSSL 15:117db924cf7c 248 /* store it */
wolfSSL 15:117db924cf7c 249 if (doEscape == 0) {
wolfSSL 15:117db924cf7c 250 if(getSzOnly)
wolfSSL 15:117db924cf7c 251 idx++;
wolfSSL 15:117db924cf7c 252 else
wolfSSL 15:117db924cf7c 253 out[idx++] = basic;
wolfSSL 15:117db924cf7c 254 }
wolfSSL 15:117db924cf7c 255 else {
wolfSSL 15:117db924cf7c 256 if(getSzOnly)
wolfSSL 15:117db924cf7c 257 idx+=3;
wolfSSL 15:117db924cf7c 258 else {
wolfSSL 15:117db924cf7c 259 out[idx++] = '%'; /* start escape */
wolfSSL 15:117db924cf7c 260
wolfSSL 15:117db924cf7c 261 if (plus) {
wolfSSL 15:117db924cf7c 262 out[idx++] = '2';
wolfSSL 15:117db924cf7c 263 out[idx++] = 'B';
wolfSSL 15:117db924cf7c 264 }
wolfSSL 15:117db924cf7c 265 else if (equals) {
wolfSSL 15:117db924cf7c 266 out[idx++] = '3';
wolfSSL 15:117db924cf7c 267 out[idx++] = 'D';
wolfSSL 15:117db924cf7c 268 }
wolfSSL 15:117db924cf7c 269 else if (newline) {
wolfSSL 15:117db924cf7c 270 out[idx++] = '0';
wolfSSL 15:117db924cf7c 271 out[idx++] = 'A';
wolfSSL 15:117db924cf7c 272 }
wolfSSL 15:117db924cf7c 273 }
wolfSSL 15:117db924cf7c 274 }
wolfSSL 15:117db924cf7c 275 *i = idx;
wolfSSL 15:117db924cf7c 276
wolfSSL 15:117db924cf7c 277 return 0;
wolfSSL 15:117db924cf7c 278 }
wolfSSL 15:117db924cf7c 279
wolfSSL 15:117db924cf7c 280
wolfSSL 15:117db924cf7c 281 /* internal worker, handles both escaped and normal line endings.
wolfSSL 15:117db924cf7c 282 If out buffer is NULL, will return sz needed in outLen */
wolfSSL 15:117db924cf7c 283 static int DoBase64_Encode(const byte* in, word32 inLen, byte* out,
wolfSSL 15:117db924cf7c 284 word32* outLen, int escaped)
wolfSSL 15:117db924cf7c 285 {
wolfSSL 15:117db924cf7c 286 int ret = 0;
wolfSSL 15:117db924cf7c 287 word32 i = 0,
wolfSSL 15:117db924cf7c 288 j = 0,
wolfSSL 15:117db924cf7c 289 n = 0; /* new line counter */
wolfSSL 15:117db924cf7c 290
wolfSSL 15:117db924cf7c 291 int getSzOnly = (out == NULL);
wolfSSL 15:117db924cf7c 292
wolfSSL 15:117db924cf7c 293 word32 outSz = (inLen + 3 - 1) / 3 * 4;
wolfSSL 15:117db924cf7c 294 word32 addSz = (outSz + PEM_LINE_SZ - 1) / PEM_LINE_SZ; /* new lines */
wolfSSL 15:117db924cf7c 295
wolfSSL 15:117db924cf7c 296 if (escaped == WC_ESC_NL_ENC)
wolfSSL 15:117db924cf7c 297 addSz *= 3; /* instead of just \n, we're doing %0A triplet */
wolfSSL 15:117db924cf7c 298 else if (escaped == WC_NO_NL_ENC)
wolfSSL 15:117db924cf7c 299 addSz = 0; /* encode without \n */
wolfSSL 15:117db924cf7c 300
wolfSSL 15:117db924cf7c 301 outSz += addSz;
wolfSSL 15:117db924cf7c 302
wolfSSL 15:117db924cf7c 303 /* if escaped we can't predetermine size for one pass encoding, but
wolfSSL 15:117db924cf7c 304 * make sure we have enough if no escapes are in input
wolfSSL 15:117db924cf7c 305 * Also need to ensure outLen valid before dereference */
wolfSSL 15:117db924cf7c 306 if (!outLen || (outSz > *outLen && !getSzOnly)) return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 307
wolfSSL 15:117db924cf7c 308 while (inLen > 2) {
wolfSSL 15:117db924cf7c 309 byte b1 = in[j++];
wolfSSL 15:117db924cf7c 310 byte b2 = in[j++];
wolfSSL 15:117db924cf7c 311 byte b3 = in[j++];
wolfSSL 15:117db924cf7c 312
wolfSSL 15:117db924cf7c 313 /* encoded idx */
wolfSSL 15:117db924cf7c 314 byte e1 = b1 >> 2;
wolfSSL 15:117db924cf7c 315 byte e2 = (byte)(((b1 & 0x3) << 4) | (b2 >> 4));
wolfSSL 15:117db924cf7c 316 byte e3 = (byte)(((b2 & 0xF) << 2) | (b3 >> 6));
wolfSSL 15:117db924cf7c 317 byte e4 = b3 & 0x3F;
wolfSSL 15:117db924cf7c 318
wolfSSL 15:117db924cf7c 319 /* store */
wolfSSL 15:117db924cf7c 320 ret = CEscape(escaped, e1, out, &i, *outLen, 0, getSzOnly);
wolfSSL 15:117db924cf7c 321 if (ret != 0) break;
wolfSSL 15:117db924cf7c 322 ret = CEscape(escaped, e2, out, &i, *outLen, 0, getSzOnly);
wolfSSL 15:117db924cf7c 323 if (ret != 0) break;
wolfSSL 15:117db924cf7c 324 ret = CEscape(escaped, e3, out, &i, *outLen, 0, getSzOnly);
wolfSSL 15:117db924cf7c 325 if (ret != 0) break;
wolfSSL 15:117db924cf7c 326 ret = CEscape(escaped, e4, out, &i, *outLen, 0, getSzOnly);
wolfSSL 15:117db924cf7c 327 if (ret != 0) break;
wolfSSL 15:117db924cf7c 328
wolfSSL 15:117db924cf7c 329 inLen -= 3;
wolfSSL 15:117db924cf7c 330
wolfSSL 15:117db924cf7c 331 /* Insert newline after PEM_LINE_SZ, unless no \n requested */
wolfSSL 16:8e0d178b1d1e 332 if (escaped != WC_NO_NL_ENC && (++n % (PEM_LINE_SZ/4)) == 0 && inLen) {
wolfSSL 15:117db924cf7c 333 ret = CEscape(escaped, '\n', out, &i, *outLen, 1, getSzOnly);
wolfSSL 15:117db924cf7c 334 if (ret != 0) break;
wolfSSL 15:117db924cf7c 335 }
wolfSSL 15:117db924cf7c 336 }
wolfSSL 15:117db924cf7c 337
wolfSSL 15:117db924cf7c 338 /* last integral */
wolfSSL 15:117db924cf7c 339 if (inLen && ret == 0) {
wolfSSL 15:117db924cf7c 340 int twoBytes = (inLen == 2);
wolfSSL 15:117db924cf7c 341
wolfSSL 15:117db924cf7c 342 byte b1 = in[j++];
wolfSSL 15:117db924cf7c 343 byte b2 = (twoBytes) ? in[j++] : 0;
wolfSSL 15:117db924cf7c 344
wolfSSL 15:117db924cf7c 345 byte e1 = b1 >> 2;
wolfSSL 15:117db924cf7c 346 byte e2 = (byte)(((b1 & 0x3) << 4) | (b2 >> 4));
wolfSSL 15:117db924cf7c 347 byte e3 = (byte)((b2 & 0xF) << 2);
wolfSSL 15:117db924cf7c 348
wolfSSL 15:117db924cf7c 349 ret = CEscape(escaped, e1, out, &i, *outLen, 0, getSzOnly);
wolfSSL 15:117db924cf7c 350 if (ret == 0)
wolfSSL 15:117db924cf7c 351 ret = CEscape(escaped, e2, out, &i, *outLen, 0, getSzOnly);
wolfSSL 15:117db924cf7c 352 if (ret == 0) {
wolfSSL 15:117db924cf7c 353 /* third */
wolfSSL 15:117db924cf7c 354 if (twoBytes)
wolfSSL 15:117db924cf7c 355 ret = CEscape(escaped, e3, out, &i, *outLen, 0, getSzOnly);
wolfSSL 15:117db924cf7c 356 else
wolfSSL 15:117db924cf7c 357 ret = CEscape(escaped, '=', out, &i, *outLen, 1, getSzOnly);
wolfSSL 15:117db924cf7c 358 }
wolfSSL 15:117db924cf7c 359 /* fourth always pad */
wolfSSL 15:117db924cf7c 360 if (ret == 0)
wolfSSL 15:117db924cf7c 361 ret = CEscape(escaped, '=', out, &i, *outLen, 1, getSzOnly);
wolfSSL 15:117db924cf7c 362 }
wolfSSL 15:117db924cf7c 363
wolfSSL 15:117db924cf7c 364 if (ret == 0 && escaped != WC_NO_NL_ENC)
wolfSSL 15:117db924cf7c 365 ret = CEscape(escaped, '\n', out, &i, *outLen, 1, getSzOnly);
wolfSSL 15:117db924cf7c 366
wolfSSL 15:117db924cf7c 367 if (i != outSz && escaped != 1 && ret == 0)
wolfSSL 15:117db924cf7c 368 return ASN_INPUT_E;
wolfSSL 16:8e0d178b1d1e 369 /* If the output buffer has a room for an extra byte, add a null terminator */
wolfSSL 16:8e0d178b1d1e 370 if (out && *outLen > i)
wolfSSL 16:8e0d178b1d1e 371 out[i]= '\0';
wolfSSL 15:117db924cf7c 372
wolfSSL 15:117db924cf7c 373 *outLen = i;
wolfSSL 16:8e0d178b1d1e 374
wolfSSL 16:8e0d178b1d1e 375 if (ret == 0)
wolfSSL 15:117db924cf7c 376 return getSzOnly ? LENGTH_ONLY_E : 0;
wolfSSL 16:8e0d178b1d1e 377
wolfSSL 15:117db924cf7c 378 return ret;
wolfSSL 15:117db924cf7c 379 }
wolfSSL 15:117db924cf7c 380
wolfSSL 15:117db924cf7c 381
wolfSSL 15:117db924cf7c 382 /* Base64 Encode, PEM style, with \n line endings */
wolfSSL 15:117db924cf7c 383 int Base64_Encode(const byte* in, word32 inLen, byte* out, word32* outLen)
wolfSSL 15:117db924cf7c 384 {
wolfSSL 15:117db924cf7c 385 return DoBase64_Encode(in, inLen, out, outLen, WC_STD_ENC);
wolfSSL 15:117db924cf7c 386 }
wolfSSL 15:117db924cf7c 387
wolfSSL 15:117db924cf7c 388
wolfSSL 15:117db924cf7c 389 /* Base64 Encode, with %0A escaped line endings instead of \n */
wolfSSL 15:117db924cf7c 390 int Base64_EncodeEsc(const byte* in, word32 inLen, byte* out, word32* outLen)
wolfSSL 15:117db924cf7c 391 {
wolfSSL 15:117db924cf7c 392 return DoBase64_Encode(in, inLen, out, outLen, WC_ESC_NL_ENC);
wolfSSL 15:117db924cf7c 393 }
wolfSSL 15:117db924cf7c 394
wolfSSL 15:117db924cf7c 395 int Base64_Encode_NoNl(const byte* in, word32 inLen, byte* out, word32* outLen)
wolfSSL 15:117db924cf7c 396 {
wolfSSL 15:117db924cf7c 397 return DoBase64_Encode(in, inLen, out, outLen, WC_NO_NL_ENC);
wolfSSL 15:117db924cf7c 398 }
wolfSSL 15:117db924cf7c 399
wolfSSL 15:117db924cf7c 400 #endif /* WOLFSSL_BASE64_ENCODE */
wolfSSL 15:117db924cf7c 401
wolfSSL 15:117db924cf7c 402
wolfSSL 15:117db924cf7c 403 #ifdef WOLFSSL_BASE16
wolfSSL 15:117db924cf7c 404
wolfSSL 15:117db924cf7c 405 static
wolfSSL 15:117db924cf7c 406 const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
wolfSSL 15:117db924cf7c 407 BAD, BAD, BAD, BAD, BAD, BAD, BAD,
wolfSSL 15:117db924cf7c 408 10, 11, 12, 13, 14, 15, /* upper case A-F */
wolfSSL 15:117db924cf7c 409 BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
wolfSSL 15:117db924cf7c 410 BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
wolfSSL 15:117db924cf7c 411 BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
wolfSSL 15:117db924cf7c 412 BAD, BAD, /* G - ` */
wolfSSL 15:117db924cf7c 413 10, 11, 12, 13, 14, 15 /* lower case a-f */
wolfSSL 15:117db924cf7c 414 }; /* A starts at 0x41 not 0x3A */
wolfSSL 15:117db924cf7c 415
wolfSSL 15:117db924cf7c 416 int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
wolfSSL 15:117db924cf7c 417 {
wolfSSL 15:117db924cf7c 418 word32 inIdx = 0;
wolfSSL 15:117db924cf7c 419 word32 outIdx = 0;
wolfSSL 15:117db924cf7c 420
wolfSSL 15:117db924cf7c 421 if (in == NULL || out == NULL || outLen == NULL)
wolfSSL 15:117db924cf7c 422 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 423
wolfSSL 15:117db924cf7c 424 if (inLen == 1 && *outLen && in) {
wolfSSL 16:8e0d178b1d1e 425 byte b = in[inIdx++] - BASE16_MIN; /* 0 starts at 0x30 */
wolfSSL 15:117db924cf7c 426
wolfSSL 15:117db924cf7c 427 /* sanity check */
wolfSSL 15:117db924cf7c 428 if (b >= sizeof(hexDecode)/sizeof(hexDecode[0]))
wolfSSL 15:117db924cf7c 429 return ASN_INPUT_E;
wolfSSL 15:117db924cf7c 430
wolfSSL 15:117db924cf7c 431 b = hexDecode[b];
wolfSSL 15:117db924cf7c 432
wolfSSL 15:117db924cf7c 433 if (b == BAD)
wolfSSL 15:117db924cf7c 434 return ASN_INPUT_E;
wolfSSL 15:117db924cf7c 435
wolfSSL 15:117db924cf7c 436 out[outIdx++] = b;
wolfSSL 15:117db924cf7c 437
wolfSSL 15:117db924cf7c 438 *outLen = outIdx;
wolfSSL 15:117db924cf7c 439 return 0;
wolfSSL 15:117db924cf7c 440 }
wolfSSL 15:117db924cf7c 441
wolfSSL 15:117db924cf7c 442 if (inLen % 2)
wolfSSL 15:117db924cf7c 443 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 444
wolfSSL 15:117db924cf7c 445 if (*outLen < (inLen / 2))
wolfSSL 15:117db924cf7c 446 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 447
wolfSSL 15:117db924cf7c 448 while (inLen) {
wolfSSL 16:8e0d178b1d1e 449 byte b = in[inIdx++] - BASE16_MIN; /* 0 starts at 0x30 */
wolfSSL 16:8e0d178b1d1e 450 byte b2 = in[inIdx++] - BASE16_MIN;
wolfSSL 15:117db924cf7c 451
wolfSSL 15:117db924cf7c 452 /* sanity checks */
wolfSSL 15:117db924cf7c 453 if (b >= sizeof(hexDecode)/sizeof(hexDecode[0]))
wolfSSL 15:117db924cf7c 454 return ASN_INPUT_E;
wolfSSL 15:117db924cf7c 455 if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0]))
wolfSSL 15:117db924cf7c 456 return ASN_INPUT_E;
wolfSSL 15:117db924cf7c 457
wolfSSL 15:117db924cf7c 458 b = hexDecode[b];
wolfSSL 15:117db924cf7c 459 b2 = hexDecode[b2];
wolfSSL 15:117db924cf7c 460
wolfSSL 15:117db924cf7c 461 if (b == BAD || b2 == BAD)
wolfSSL 15:117db924cf7c 462 return ASN_INPUT_E;
wolfSSL 15:117db924cf7c 463
wolfSSL 15:117db924cf7c 464 out[outIdx++] = (byte)((b << 4) | b2);
wolfSSL 15:117db924cf7c 465 inLen -= 2;
wolfSSL 15:117db924cf7c 466 }
wolfSSL 15:117db924cf7c 467
wolfSSL 15:117db924cf7c 468 *outLen = outIdx;
wolfSSL 15:117db924cf7c 469 return 0;
wolfSSL 15:117db924cf7c 470 }
wolfSSL 15:117db924cf7c 471
wolfSSL 15:117db924cf7c 472 int Base16_Encode(const byte* in, word32 inLen, byte* out, word32* outLen)
wolfSSL 15:117db924cf7c 473 {
wolfSSL 15:117db924cf7c 474 word32 outIdx = 0;
wolfSSL 15:117db924cf7c 475 word32 i;
wolfSSL 15:117db924cf7c 476 byte hb, lb;
wolfSSL 15:117db924cf7c 477
wolfSSL 15:117db924cf7c 478 if (in == NULL || out == NULL || outLen == NULL)
wolfSSL 15:117db924cf7c 479 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 480
wolfSSL 15:117db924cf7c 481 if (*outLen < (2 * inLen + 1))
wolfSSL 15:117db924cf7c 482 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 483
wolfSSL 15:117db924cf7c 484 for (i = 0; i < inLen; i++) {
wolfSSL 15:117db924cf7c 485 hb = in[i] >> 4;
wolfSSL 15:117db924cf7c 486 lb = in[i] & 0x0f;
wolfSSL 15:117db924cf7c 487
wolfSSL 15:117db924cf7c 488 /* ASCII value */
wolfSSL 15:117db924cf7c 489 hb += '0';
wolfSSL 15:117db924cf7c 490 if (hb > '9')
wolfSSL 15:117db924cf7c 491 hb += 7;
wolfSSL 15:117db924cf7c 492
wolfSSL 15:117db924cf7c 493 /* ASCII value */
wolfSSL 15:117db924cf7c 494 lb += '0';
wolfSSL 15:117db924cf7c 495 if (lb>'9')
wolfSSL 15:117db924cf7c 496 lb += 7;
wolfSSL 15:117db924cf7c 497
wolfSSL 15:117db924cf7c 498 out[outIdx++] = hb;
wolfSSL 15:117db924cf7c 499 out[outIdx++] = lb;
wolfSSL 15:117db924cf7c 500 }
wolfSSL 15:117db924cf7c 501
wolfSSL 15:117db924cf7c 502 /* force 0 at this end */
wolfSSL 15:117db924cf7c 503 out[outIdx++] = 0;
wolfSSL 15:117db924cf7c 504
wolfSSL 15:117db924cf7c 505 *outLen = outIdx;
wolfSSL 15:117db924cf7c 506 return 0;
wolfSSL 15:117db924cf7c 507 }
wolfSSL 15:117db924cf7c 508
wolfSSL 15:117db924cf7c 509 #endif /* WOLFSSL_BASE16 */
wolfSSL 15:117db924cf7c 510
wolfSSL 15:117db924cf7c 511 #endif /* !NO_CODING */
wolfSSL 15:117db924cf7c 512