CyaSSL is an SSL library for devices like mbed.
Dependents: cyassl-client Sync
coding.c
00001 /* coding.c 00002 * 00003 * Copyright (C) 2006-2009 Sawtooth Consulting Ltd. 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 00023 #include "coding.h" 00024 00025 00026 enum { 00027 BAD = 0xFF, /* invalid encoding */ 00028 PAD = '=', 00029 PEM_LINE_SZ = 64 00030 }; 00031 00032 00033 static 00034 const byte base64Decode[] = { 62, BAD, BAD, BAD, 63, /* + starts at 0x2B */ 00035 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 00036 BAD, BAD, BAD, BAD, BAD, BAD, BAD, 00037 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 00038 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 00039 20, 21, 22, 23, 24, 25, 00040 BAD, BAD, BAD, BAD, BAD, BAD, 00041 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 00042 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 00043 46, 47, 48, 49, 50, 51 00044 }; 00045 00046 00047 int Base64Decode(const byte* in, word32 inLen, byte* out, word32* outLen) 00048 { 00049 word32 i = 0; 00050 word32 j = 0; 00051 word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ ); 00052 00053 plainSz = (plainSz * 3 + 3) / 4; 00054 if (plainSz > *outLen) return -1; 00055 00056 while (inLen > 3) { 00057 byte b1, b2, b3; 00058 byte e1 = in[j++]; 00059 byte e2 = in[j++]; 00060 byte e3 = in[j++]; 00061 byte e4 = in[j++]; 00062 00063 int pad3 = 0; 00064 int pad4 = 0; 00065 00066 if (e1 == 0) /* end file 0's */ 00067 break; 00068 if (e3 == PAD) 00069 pad3 = 1; 00070 if (e4 == PAD) 00071 pad4 = 1; 00072 00073 e1 = base64Decode[e1 - 0x2B]; 00074 e2 = base64Decode[e2 - 0x2B]; 00075 e3 = (e3 == PAD) ? 0 : base64Decode[e3 - 0x2B]; 00076 e4 = (e4 == PAD) ? 0 : base64Decode[e4 - 0x2B]; 00077 00078 b1 = (e1 << 2) | (e2 >> 4); 00079 b2 = ((e2 & 0xF) << 4) | (e3 >> 2); 00080 b3 = ((e3 & 0x3) << 6) | e4; 00081 00082 out[i++] = b1; 00083 if (!pad3) 00084 out[i++] = b2; 00085 if (!pad4) 00086 out[i++] = b3; 00087 else 00088 break; 00089 00090 inLen -= 4; 00091 if (in[j] == ' ' || in[j] == '\r' || in[j] == '\n') { 00092 byte endLine = in[j++]; 00093 inLen--; 00094 while (endLine == ' ') { /* allow trailing whitespace */ 00095 endLine = in[j++]; 00096 inLen--; 00097 } 00098 if (endLine == '\r') { 00099 endLine = in[j++]; 00100 inLen--; 00101 } 00102 if (endLine != '\n') 00103 return -1; 00104 } 00105 } 00106 *outLen = i; 00107 00108 return 0; 00109 } 00110 00111 00112 #if defined(OPENSSL_EXTRA) || defined (SESSION_CERTS) || defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) 00113 00114 static 00115 const byte base64Encode[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 00116 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 00117 'U', 'V', 'W', 'X', 'Y', 'Z', 00118 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 00119 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 00120 'u', 'v', 'w', 'x', 'y', 'z', 00121 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 00122 '+', '/' 00123 }; 00124 00125 00126 /* porting assistance from yaSSL by Raphael HUCK */ 00127 int Base64Encode(const byte* in, word32 inLen, byte* out, word32* outLen) 00128 { 00129 word32 i = 0, 00130 j = 0, 00131 n = 0; /* new line counter */ 00132 00133 word32 outSz = (inLen + 3 - 1) / 3 * 4; 00134 outSz += (outSz + PEM_LINE_SZ - 1) / PEM_LINE_SZ; /* new lines */ 00135 00136 if (outSz > *outLen) return -1; 00137 00138 while (inLen > 2) { 00139 byte b1 = in[j++]; 00140 byte b2 = in[j++]; 00141 byte b3 = in[j++]; 00142 00143 /* encoded idx */ 00144 byte e1 = b1 >> 2; 00145 byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4); 00146 byte e3 = ((b2 & 0xF) << 2) | (b3 >> 6); 00147 byte e4 = b3 & 0x3F; 00148 00149 /* store */ 00150 out[i++] = base64Encode[e1]; 00151 out[i++] = base64Encode[e2]; 00152 out[i++] = base64Encode[e3]; 00153 out[i++] = base64Encode[e4]; 00154 00155 inLen -= 3; 00156 00157 if ((++n % (PEM_LINE_SZ / 4)) == 0 && inLen) 00158 out[i++] = '\n'; 00159 } 00160 00161 /* last integral */ 00162 if (inLen) { 00163 int twoBytes = (inLen == 2); 00164 00165 byte b1 = in[j++]; 00166 byte b2 = (twoBytes) ? in[j++] : 0; 00167 00168 byte e1 = b1 >> 2; 00169 byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4); 00170 byte e3 = (b2 & 0xF) << 2; 00171 00172 out[i++] = base64Encode[e1]; 00173 out[i++] = base64Encode[e2]; 00174 out[i++] = (twoBytes) ? base64Encode[e3] : PAD; 00175 out[i++] = PAD; 00176 } 00177 00178 out[i++] = '\n'; 00179 if (i != outSz) 00180 return -1; 00181 *outLen = outSz; 00182 00183 return 0; 00184 } 00185 00186 00187 static 00188 const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 00189 BAD, BAD, BAD, BAD, BAD, BAD, BAD, 00190 10, 11, 12, 13, 14, 15 00191 }; /* A starts at 0x41 not 0x3A */ 00192 00193 int Base16Decode(const byte* in, word32 inLen, byte* out, word32* outLen) 00194 { 00195 word32 inIdx = 0; 00196 word32 outIdx = 0; 00197 00198 if (inLen % 2) 00199 return -1; 00200 00201 if (*outLen < (inLen / 2)) 00202 return -1; 00203 00204 while (inLen) { 00205 byte b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */ 00206 byte b2 = in[inIdx++] - 0x30; 00207 00208 /* sanity checks */ 00209 if (b >= sizeof(hexDecode)/sizeof(hexDecode[0])) 00210 return -1; 00211 if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0])) 00212 return -1; 00213 00214 b = hexDecode[b]; 00215 b2 = hexDecode[b2]; 00216 00217 if (b == BAD || b2 == BAD) 00218 return -1; 00219 00220 out[outIdx++] = (b << 4) | b2; 00221 inLen -= 2; 00222 } 00223 00224 *outLen = outIdx; 00225 return 0; 00226 } 00227 00228 00229 #endif /* OPENSSL_EXTRA */
Generated on Tue Jul 12 2022 18:43:19 by 1.7.2