This is a port of cyaSSL 2.7.0.
Dependents: CyaSSL_DTLS_Cellular CyaSSL_DTLS_Ethernet
coding.c
00001 /* coding.c 00002 * 00003 * Copyright (C) 2006-2013 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include <cyassl/ctaocrypt/settings.h> 00027 00028 #ifndef NO_CODING 00029 00030 #include <cyassl/ctaocrypt/coding.h> 00031 #include <cyassl/ctaocrypt/ctaoerror2.h> 00032 #include <cyassl/ctaocrypt/logging.h> 00033 00034 00035 enum { 00036 BAD = 0xFF, /* invalid encoding */ 00037 PAD = '=', 00038 PEM_LINE_SZ = 64 00039 }; 00040 00041 00042 static 00043 const byte base64Decode[] = { 62, BAD, BAD, BAD, 63, /* + starts at 0x2B */ 00044 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 00045 BAD, BAD, BAD, BAD, BAD, BAD, BAD, 00046 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 00047 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 00048 20, 21, 22, 23, 24, 25, 00049 BAD, BAD, BAD, BAD, BAD, BAD, 00050 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 00051 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 00052 46, 47, 48, 49, 50, 51 00053 }; 00054 00055 00056 int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) 00057 { 00058 word32 i = 0; 00059 word32 j = 0; 00060 word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ ); 00061 const byte maxIdx = (byte)sizeof(base64Decode) + 0x2B - 1; 00062 00063 plainSz = (plainSz * 3 + 3) / 4; 00064 if (plainSz > *outLen) return BAD_FUNC_ARG; 00065 00066 while (inLen > 3) { 00067 byte b1, b2, b3; 00068 byte e1 = in[j++]; 00069 byte e2 = in[j++]; 00070 byte e3 = in[j++]; 00071 byte e4 = in[j++]; 00072 00073 int pad3 = 0; 00074 int pad4 = 0; 00075 00076 if (e1 == 0) /* end file 0's */ 00077 break; 00078 if (e3 == PAD) 00079 pad3 = 1; 00080 if (e4 == PAD) 00081 pad4 = 1; 00082 00083 if (e1 < 0x2B || e2 < 0x2B || e3 < 0x2B || e4 < 0x2B) { 00084 CYASSL_MSG("Bad Base64 Decode data, too small"); 00085 return ASN_INPUT_E; 00086 } 00087 00088 if (e1 > maxIdx || e2 > maxIdx || e3 > maxIdx || e4 > maxIdx) { 00089 CYASSL_MSG("Bad Base64 Decode data, too big"); 00090 return ASN_INPUT_E; 00091 } 00092 00093 e1 = base64Decode[e1 - 0x2B]; 00094 e2 = base64Decode[e2 - 0x2B]; 00095 e3 = (e3 == PAD) ? 0 : base64Decode[e3 - 0x2B]; 00096 e4 = (e4 == PAD) ? 0 : base64Decode[e4 - 0x2B]; 00097 00098 b1 = (e1 << 2) | (e2 >> 4); 00099 b2 = ((e2 & 0xF) << 4) | (e3 >> 2); 00100 b3 = ((e3 & 0x3) << 6) | e4; 00101 00102 out[i++] = b1; 00103 if (!pad3) 00104 out[i++] = b2; 00105 if (!pad4) 00106 out[i++] = b3; 00107 else 00108 break; 00109 00110 inLen -= 4; 00111 if (inLen && (in[j] == ' ' || in[j] == '\r' || in[j] == '\n')) { 00112 byte endLine = in[j++]; 00113 inLen--; 00114 while (inLen && endLine == ' ') { /* allow trailing whitespace */ 00115 endLine = in[j++]; 00116 inLen--; 00117 } 00118 if (endLine == '\r') { 00119 if (inLen) { 00120 endLine = in[j++]; 00121 inLen--; 00122 } 00123 } 00124 if (endLine != '\n') { 00125 CYASSL_MSG("Bad end of line in Base64 Decode"); 00126 return ASN_INPUT_E; 00127 } 00128 } 00129 } 00130 *outLen = i; 00131 00132 return 0; 00133 } 00134 00135 00136 #if defined(OPENSSL_EXTRA) || defined (SESSION_CERTS) || defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) || defined(HAVE_WEBSERVER) 00137 00138 static 00139 const byte base64Encode[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 00140 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 00141 'U', 'V', 'W', 'X', 'Y', 'Z', 00142 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 00143 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 00144 'u', 'v', 'w', 'x', 'y', 'z', 00145 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 00146 '+', '/' 00147 }; 00148 00149 00150 /* porting assistance from yaSSL by Raphael HUCK */ 00151 int Base64_Encode(const byte* in, word32 inLen, byte* out, word32* outLen) 00152 { 00153 word32 i = 0, 00154 j = 0, 00155 n = 0; /* new line counter */ 00156 00157 word32 outSz = (inLen + 3 - 1) / 3 * 4; 00158 outSz += (outSz + PEM_LINE_SZ - 1) / PEM_LINE_SZ; /* new lines */ 00159 00160 if (outSz > *outLen) return BAD_FUNC_ARG; 00161 00162 while (inLen > 2) { 00163 byte b1 = in[j++]; 00164 byte b2 = in[j++]; 00165 byte b3 = in[j++]; 00166 00167 /* encoded idx */ 00168 byte e1 = b1 >> 2; 00169 byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4); 00170 byte e3 = ((b2 & 0xF) << 2) | (b3 >> 6); 00171 byte e4 = b3 & 0x3F; 00172 00173 /* store */ 00174 out[i++] = base64Encode[e1]; 00175 out[i++] = base64Encode[e2]; 00176 out[i++] = base64Encode[e3]; 00177 out[i++] = base64Encode[e4]; 00178 00179 inLen -= 3; 00180 00181 if ((++n % (PEM_LINE_SZ / 4)) == 0 && inLen) 00182 out[i++] = '\n'; 00183 } 00184 00185 /* last integral */ 00186 if (inLen) { 00187 int twoBytes = (inLen == 2); 00188 00189 byte b1 = in[j++]; 00190 byte b2 = (twoBytes) ? in[j++] : 0; 00191 00192 byte e1 = b1 >> 2; 00193 byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4); 00194 byte e3 = (b2 & 0xF) << 2; 00195 00196 out[i++] = base64Encode[e1]; 00197 out[i++] = base64Encode[e2]; 00198 out[i++] = (twoBytes) ? base64Encode[e3] : PAD; 00199 out[i++] = PAD; 00200 } 00201 00202 out[i++] = '\n'; 00203 if (i != outSz) 00204 return ASN_INPUT_E; 00205 *outLen = outSz; 00206 00207 return 0; 00208 } 00209 00210 00211 static 00212 const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 00213 BAD, BAD, BAD, BAD, BAD, BAD, BAD, 00214 10, 11, 12, 13, 14, 15 00215 }; /* A starts at 0x41 not 0x3A */ 00216 00217 int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) 00218 { 00219 word32 inIdx = 0; 00220 word32 outIdx = 0; 00221 00222 if (inLen == 1 && *outLen && in) { 00223 byte b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */ 00224 00225 /* sanity check */ 00226 if (b >= sizeof(hexDecode)/sizeof(hexDecode[0])) 00227 return ASN_INPUT_E; 00228 00229 b = hexDecode[b]; 00230 00231 if (b == BAD) 00232 return ASN_INPUT_E; 00233 00234 out[outIdx++] = b; 00235 00236 *outLen = outIdx; 00237 return 0; 00238 } 00239 00240 if (inLen % 2) 00241 return BAD_FUNC_ARG; 00242 00243 if (*outLen < (inLen / 2)) 00244 return BAD_FUNC_ARG; 00245 00246 while (inLen) { 00247 byte b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */ 00248 byte b2 = in[inIdx++] - 0x30; 00249 00250 /* sanity checks */ 00251 if (b >= sizeof(hexDecode)/sizeof(hexDecode[0])) 00252 return ASN_INPUT_E; 00253 if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0])) 00254 return ASN_INPUT_E; 00255 00256 b = hexDecode[b]; 00257 b2 = hexDecode[b2]; 00258 00259 if (b == BAD || b2 == BAD) 00260 return ASN_INPUT_E; 00261 00262 out[outIdx++] = (b << 4) | b2; 00263 inLen -= 2; 00264 } 00265 00266 *outLen = outIdx; 00267 return 0; 00268 } 00269 00270 00271 #endif /* defined(OPENSSL_EXTRA) || defined (SESSION_CERTS) || defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) || defined(HAVE_WEBSERVER) */ 00272 #endif /* NO_CODING */
Generated on Tue Jul 12 2022 20:44:50 by 1.7.2