22 #include "runtime.hpp"
32 const byte bad = 0xFF;
34 const byte hexEncode[] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
35 'A',
'B',
'C',
'D',
'E',
'F'
38 const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
39 bad, bad, bad, bad, bad, bad, bad,
40 10, 11, 12, 13, 14, 15
44 const byte base64Encode[] = {
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
45 'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
46 'U',
'V',
'W',
'X',
'Y',
'Z',
47 'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
48 'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
49 'u',
'v',
'w',
'x',
'y',
'z',
50 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
54 const byte base64Decode[] = { 62, bad, bad, bad, 63,
55 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
56 bad, bad, bad, bad, bad, bad, bad,
57 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
58 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
59 20, 21, 22, 23, 24, 25,
60 bad, bad, bad, bad, bad, bad,
61 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
62 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
63 46, 47, 48, 49, 50, 51
67 const int pemLineSz = 64;
73 void HexEncoder::Encode()
75 word32 bytes = plain_.size();
76 encoded_.New(bytes * 2);
81 byte p = plain_.next();
86 encoded_[i++] = hexEncode[b];
87 encoded_[i++] = hexEncode[b2];
90 plain_.reset(encoded_);
95 void HexDecoder::Decode()
97 word32 bytes = coded_.size();
98 decoded_.New(bytes / 2);
103 byte b = coded_.next() - 0x30;
104 byte b2 = coded_.next() - 0x30;
107 if (b >=
sizeof(hexDecode)/
sizeof(hexDecode[0])) {
108 coded_.SetError(PEM_E);
111 if (b2 >=
sizeof(hexDecode)/
sizeof(hexDecode[0])) {
112 coded_.SetError(PEM_E);
119 decoded_[i++] = (b << 4) | b2;
123 coded_.reset(decoded_);
128 void Base64Encoder::Encode()
130 word32 bytes = plain_.size();
131 word32 outSz = (bytes + 3 - 1) / 3 * 4;
133 outSz += (outSz + pemLineSz - 1) / pemLineSz;
140 byte b1 = plain_.next();
141 byte b2 = plain_.next();
142 byte b3 = plain_.next();
146 byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4);
147 byte e3 = ((b2 & 0xF) << 2) | (b3 >> 6);
151 encoded_[i++] = base64Encode[e1];
152 encoded_[i++] = base64Encode[e2];
153 encoded_[i++] = base64Encode[e3];
154 encoded_[i++] = base64Encode[e4];
158 if ((++j % 16) == 0 && bytes)
159 encoded_[i++] =
'\n';
164 bool twoBytes = (bytes == 2);
166 byte b1 = plain_.next();
167 byte b2 = (twoBytes) ? plain_.next() : 0;
170 byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4);
171 byte e3 = (b2 & 0xF) << 2;
173 encoded_[i++] = base64Encode[e1];
174 encoded_[i++] = base64Encode[e2];
175 encoded_[i++] = (twoBytes) ? base64Encode[e3] : pad;
179 encoded_[i++] =
'\n';
182 plain_.reset(encoded_);
187 void Base64Decoder::Decode()
189 word32 bytes = coded_.size();
190 word32 plainSz = bytes - ((bytes + (pemLineSz - 1)) / pemLineSz);
191 const byte maxIdx = (byte)
sizeof(base64Decode) + 0x2B - 1;
192 plainSz = ((plainSz * 3) / 4) + 3;
193 decoded_.New(plainSz);
199 byte e1 = coded_.next();
200 byte e2 = coded_.next();
201 byte e3 = coded_.next();
202 byte e4 = coded_.next();
214 if (e1 < 0x2B || e2 < 0x2B || e3 < 0x2B || e4 < 0x2B) {
215 coded_.SetError(PEM_E);
219 if (e1 > maxIdx || e2 > maxIdx || e3 > maxIdx || e4 > maxIdx) {
220 coded_.SetError(PEM_E);
224 e1 = base64Decode[e1 - 0x2B];
225 e2 = base64Decode[e2 - 0x2B];
226 e3 = (e3 == pad) ? 0 : base64Decode[e3 - 0x2B];
227 e4 = (e4 == pad) ? 0 : base64Decode[e4 - 0x2B];
229 byte b1 = (e1 << 2) | (e2 >> 4);
230 byte b2 = ((e2 & 0xF) << 4) | (e3 >> 2);
231 byte b3 = ((e3 & 0x3) << 6) | e4;
242 if ((++j % 16) == 0) {
243 byte endLine = coded_.next();
245 while (endLine ==
' ') {
246 endLine = coded_.next();
249 if (endLine ==
'\r') {
250 endLine = coded_.next();
253 if (endLine !=
'\n') {
254 coded_.SetError(PEM_E);
260 if (i != decoded_.size())
262 coded_.reset(decoded_);