2
Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; version 2 of the License.
8
This program is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License
14
along with this program; see the file COPYING. If not, write to the
15
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
19
/* coding.cpp implements hex and base64 encoding/decoing
22
#include "runtime.hpp"
32
const byte bad = 0xFF; // invalid encoding
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
41
}; // A starts at 0x41 not 0x3A
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, // + starts at 0x2B
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; // 0 starts at 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; // new lines
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();
204
if (e1 == 0) // end file 0's
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 == ' ') { // remove possible whitespace
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_);