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

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

Committer:
wolfSSL
Date:
Tue Aug 22 10:48:22 2017 +0000
Revision:
13:f67a6c6013ca
Parent:
11:cee25a834751
wolfSSL3.12.0 with TLS1.3

Who changed what in which revision?

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