Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
sPymbed
Date:
Tue Nov 19 14:32:16 2019 +0000
Revision:
16:048e5e270a58
Parent:
15:117db924cf7c
working ssl

Who changed what in which revision?

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