3 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
5 * This file is part of CyaSSL.
7 * CyaSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * CyaSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
26 #include <cyassl/ctaocrypt/coding.h>
27 #include <cyassl/ctaocrypt/error.h>
28 #include <cyassl/ctaocrypt/logging.h>
32 BAD = 0xFF, /* invalid encoding */
39 const byte base64Decode[] = { 62, BAD, BAD, BAD, 63, /* + starts at 0x2B */
40 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
41 BAD, BAD, BAD, BAD, BAD, BAD, BAD,
42 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
43 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
44 20, 21, 22, 23, 24, 25,
45 BAD, BAD, BAD, BAD, BAD, BAD,
46 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
47 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
48 46, 47, 48, 49, 50, 51
52 int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
56 word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ );
58 plainSz = (plainSz * 3 + 3) / 4;
59 if (plainSz > *outLen) return BAD_FUNC_ARG;
71 if (e1 == 0) /* end file 0's */
78 e1 = base64Decode[e1 - 0x2B];
79 e2 = base64Decode[e2 - 0x2B];
80 e3 = (e3 == PAD) ? 0 : base64Decode[e3 - 0x2B];
81 e4 = (e4 == PAD) ? 0 : base64Decode[e4 - 0x2B];
83 b1 = (e1 << 2) | (e2 >> 4);
84 b2 = ((e2 & 0xF) << 4) | (e3 >> 2);
85 b3 = ((e3 & 0x3) << 6) | e4;
96 if (in[j] == ' ' || in[j] == '\r' || in[j] == '\n') {
97 byte endLine = in[j++];
99 while (endLine == ' ') { /* allow trailing whitespace */
103 if (endLine == '\r') {
107 if (endLine != '\n') {
108 CYASSL_MSG("Bad end of line in Base64 Decode");
119 #if defined(OPENSSL_EXTRA) || defined (SESSION_CERTS) || defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) || defined(HAVE_WEBSERVER)
122 const byte base64Encode[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
123 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
124 'U', 'V', 'W', 'X', 'Y', 'Z',
125 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
126 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
127 'u', 'v', 'w', 'x', 'y', 'z',
128 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
133 /* porting assistance from yaSSL by Raphael HUCK */
134 int Base64_Encode(const byte* in, word32 inLen, byte* out, word32* outLen)
138 n = 0; /* new line counter */
140 word32 outSz = (inLen + 3 - 1) / 3 * 4;
141 outSz += (outSz + PEM_LINE_SZ - 1) / PEM_LINE_SZ; /* new lines */
143 if (outSz > *outLen) return BAD_FUNC_ARG;
152 byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4);
153 byte e3 = ((b2 & 0xF) << 2) | (b3 >> 6);
157 out[i++] = base64Encode[e1];
158 out[i++] = base64Encode[e2];
159 out[i++] = base64Encode[e3];
160 out[i++] = base64Encode[e4];
164 if ((++n % (PEM_LINE_SZ / 4)) == 0 && inLen)
170 int twoBytes = (inLen == 2);
173 byte b2 = (twoBytes) ? in[j++] : 0;
176 byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4);
177 byte e3 = (b2 & 0xF) << 2;
179 out[i++] = base64Encode[e1];
180 out[i++] = base64Encode[e2];
181 out[i++] = (twoBytes) ? base64Encode[e3] : PAD;
195 const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
196 BAD, BAD, BAD, BAD, BAD, BAD, BAD,
197 10, 11, 12, 13, 14, 15
198 }; /* A starts at 0x41 not 0x3A */
200 int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
205 if (inLen == 1 && *outLen && in) {
206 byte b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */
209 if (b >= sizeof(hexDecode)/sizeof(hexDecode[0]))
226 if (*outLen < (inLen / 2))
230 byte b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */
231 byte b2 = in[inIdx++] - 0x30;
234 if (b >= sizeof(hexDecode)/sizeof(hexDecode[0]))
236 if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0]))
242 if (b == BAD || b2 == BAD)
245 out[outIdx++] = (b << 4) | b2;
254 #endif /* OPENSSL_EXTRA */