]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/evp/encode.c
Remove /* foo.c */ comments
[thirdparty/openssl.git] / crypto / evp / encode.c
CommitLineData
58964a49 1/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
d02b48c6
RE
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
0f113f3e 7 *
d02b48c6
RE
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
0f113f3e 14 *
d02b48c6
RE
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
0f113f3e 21 *
d02b48c6
RE
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
0f113f3e 36 * 4. If you include any Windows specific code (or a derivative thereof) from
d02b48c6
RE
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
0f113f3e 39 *
d02b48c6
RE
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
0f113f3e 51 *
d02b48c6
RE
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 */
57
58#include <stdio.h>
b39fc560 59#include "internal/cryptlib.h"
ec577822 60#include <openssl/evp.h>
a0be4fd1 61#include "evp_locl.h"
d02b48c6 62
b785504a 63static unsigned char conv_ascii2bin(unsigned char a);
a53955d8 64#ifndef CHARSET_EBCDIC
0f113f3e 65# define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f])
a53955d8 66#else
0f113f3e
MC
67/*
68 * We assume that PEM encoded files are EBCDIC files (i.e., printable text
69 * files). Convert them here while decoding. When encoding, output is EBCDIC
70 * (text) format again. (No need for conversion in the conv_bin2ascii macro,
71 * as the underlying textstring data_bin2ascii[] is already EBCDIC)
a53955d8 72 */
0f113f3e 73# define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f])
a53955d8 74#endif
d02b48c6 75
1d97c843
TH
76/*-
77 * 64 char lines
d02b48c6
RE
78 * pad input with 0
79 * left over chars are set to =
80 * 1 byte => xx==
81 * 2 bytes => xxx=
82 * 3 bytes => xxxx
83 */
84#define BIN_PER_LINE (64/4*3)
85#define CHUNKS_PER_LINE (64/4)
86#define CHAR_PER_LINE (64+1)
87
0f113f3e 88static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\
d02b48c6
RE
89abcdefghijklmnopqrstuvwxyz0123456789+/";
90
1d97c843
TH
91/*-
92 * 0xF0 is a EOLN
d02b48c6
RE
93 * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
94 * 0xF2 is EOF
95 * 0xE0 is ignore at start of line.
96 * 0xFF is error
97 */
98
0f113f3e
MC
99#define B64_EOLN 0xF0
100#define B64_CR 0xF1
101#define B64_EOF 0xF2
102#define B64_WS 0xE0
103#define B64_ERROR 0xFF
104#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3)
3cdd1e94 105#define B64_BASE64(a) !B64_NOT_BASE64(a)
0f113f3e
MC
106
107static const unsigned char data_ascii2bin[128] = {
108 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
109 0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF,
110 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
111 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
112 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
113 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
114 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
115 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
116 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
117 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
118 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
119 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
120 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
121 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
122 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
123 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
124};
d02b48c6 125
b785504a
EK
126#ifndef CHARSET_EBCDIC
127static unsigned char conv_ascii2bin(unsigned char a)
128{
129 if (a & 0x80)
130 return B64_ERROR;
131 return data_ascii2bin[a];
132}
133#else
134static unsigned char conv_ascii2bin(unsigned char a)
135{
136 a = os_toascii[a];
137 if (a & 0x80)
138 return B64_ERROR;
139 return data_ascii2bin[a];
140}
141#endif
142
a0be4fd1
RL
143EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void)
144{
145 return (EVP_ENCODE_CTX *)OPENSSL_zalloc(sizeof(EVP_ENCODE_CTX));
146}
147
148void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx)
149{
150 OPENSSL_free(ctx);
151}
152int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx)
153{
154 return ctx->num;
155}
156
6b691a5c 157void EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
0f113f3e
MC
158{
159 ctx->length = 48;
160 ctx->num = 0;
161 ctx->line_num = 0;
162}
d02b48c6 163
6b691a5c 164void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
0f113f3e
MC
165 const unsigned char *in, int inl)
166{
167 int i, j;
168 unsigned int total = 0;
169
170 *outl = 0;
b86d7dca 171 if (inl <= 0)
0f113f3e
MC
172 return;
173 OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
174 if ((ctx->num + inl) < ctx->length) {
175 memcpy(&(ctx->enc_data[ctx->num]), in, inl);
176 ctx->num += inl;
177 return;
178 }
179 if (ctx->num != 0) {
180 i = ctx->length - ctx->num;
181 memcpy(&(ctx->enc_data[ctx->num]), in, i);
182 in += i;
183 inl -= i;
184 j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
185 ctx->num = 0;
186 out += j;
187 *(out++) = '\n';
188 *out = '\0';
189 total = j + 1;
190 }
191 while (inl >= ctx->length) {
192 j = EVP_EncodeBlock(out, in, ctx->length);
193 in += ctx->length;
194 inl -= ctx->length;
195 out += j;
196 *(out++) = '\n';
197 *out = '\0';
198 total += j + 1;
199 }
200 if (inl != 0)
201 memcpy(&(ctx->enc_data[0]), in, inl);
202 ctx->num = inl;
203 *outl = total;
204}
d02b48c6 205
6b691a5c 206void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
0f113f3e
MC
207{
208 unsigned int ret = 0;
209
210 if (ctx->num != 0) {
211 ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
212 out[ret++] = '\n';
213 out[ret] = '\0';
214 ctx->num = 0;
215 }
216 *outl = ret;
217}
d02b48c6 218
6343829a 219int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
0f113f3e
MC
220{
221 int i, ret = 0;
222 unsigned long l;
223
224 for (i = dlen; i > 0; i -= 3) {
225 if (i >= 3) {
226 l = (((unsigned long)f[0]) << 16L) |
227 (((unsigned long)f[1]) << 8L) | f[2];
228 *(t++) = conv_bin2ascii(l >> 18L);
229 *(t++) = conv_bin2ascii(l >> 12L);
230 *(t++) = conv_bin2ascii(l >> 6L);
231 *(t++) = conv_bin2ascii(l);
232 } else {
233 l = ((unsigned long)f[0]) << 16L;
234 if (i == 2)
235 l |= ((unsigned long)f[1] << 8L);
236
237 *(t++) = conv_bin2ascii(l >> 18L);
238 *(t++) = conv_bin2ascii(l >> 12L);
239 *(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L);
240 *(t++) = '=';
241 }
242 ret += 4;
243 f += 3;
244 }
245
246 *t = '\0';
247 return (ret);
248}
d02b48c6 249
6b691a5c 250void EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
0f113f3e 251{
3cdd1e94 252 /* Only ctx->num is used during decoding. */
0f113f3e 253 ctx->num = 0;
3cdd1e94 254 ctx->length = 0;
0f113f3e
MC
255 ctx->line_num = 0;
256 ctx->expect_nl = 0;
257}
d02b48c6 258
1d97c843
TH
259/*-
260 * -1 for error
d02b48c6
RE
261 * 0 for last line
262 * 1 for full line
3cdd1e94
EK
263 *
264 * Note: even though EVP_DecodeUpdate attempts to detect and report end of
265 * content, the context doesn't currently remember it and will accept more data
266 * in the next call. Therefore, the caller is responsible for checking and
267 * rejecting a 0 return value in the middle of content.
268 *
269 * Note: even though EVP_DecodeUpdate has historically tried to detect end of
270 * content based on line length, this has never worked properly. Therefore,
271 * we now return 0 when one of the following is true:
272 * - Padding or B64_EOF was detected and the last block is complete.
273 * - Input has zero-length.
274 * -1 is returned if:
275 * - Invalid characters are detected.
276 * - There is extra trailing padding, or data after padding.
277 * - B64_EOF is detected after an incomplete base64 block.
d02b48c6 278 */
6b691a5c 279int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
0f113f3e
MC
280 const unsigned char *in, int inl)
281{
3cdd1e94 282 int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len;
0f113f3e
MC
283 unsigned char *d;
284
285 n = ctx->num;
286 d = ctx->enc_data;
0f113f3e 287
3cdd1e94
EK
288 if (n > 0 && d[n - 1] == '=') {
289 eof++;
290 if (n > 1 && d[n - 2] == '=')
291 eof++;
292 }
293
294 /* Legacy behaviour: an empty input chunk signals end of input. */
295 if (inl == 0) {
0f113f3e
MC
296 rv = 0;
297 goto end;
298 }
299
0f113f3e 300 for (i = 0; i < inl; i++) {
0f113f3e
MC
301 tmp = *(in++);
302 v = conv_ascii2bin(tmp);
3cdd1e94 303 if (v == B64_ERROR) {
0f113f3e
MC
304 rv = -1;
305 goto end;
306 }
307
0f113f3e 308 if (tmp == '=') {
0f113f3e 309 eof++;
3cdd1e94
EK
310 } else if (eof > 0 && B64_BASE64(v)) {
311 /* More data after padding. */
312 rv = -1;
313 goto end;
0f113f3e
MC
314 }
315
3cdd1e94
EK
316 if (eof > 2) {
317 rv = -1;
318 goto end;
0f113f3e
MC
319 }
320
3cdd1e94
EK
321 if (v == B64_EOF) {
322 seof = 1;
323 goto tail;
0f113f3e
MC
324 }
325
3cdd1e94
EK
326 /* Only save valid base64 characters. */
327 if (B64_BASE64(v)) {
328 if (n >= 64) {
329 /*
330 * We increment n once per loop, and empty the buffer as soon as
331 * we reach 64 characters, so this can only happen if someone's
332 * manually messed with the ctx. Refuse to write any more data.
333 */
334 rv = -1;
0f113f3e 335 goto end;
3cdd1e94
EK
336 }
337 OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
338 d[n++] = tmp;
339 }
0f113f3e 340
3cdd1e94
EK
341 if (n == 64) {
342 decoded_len = EVP_DecodeBlock(out, d, n);
343 n = 0;
344 if (decoded_len < 0 || eof > decoded_len) {
345 rv = -1;
0f113f3e
MC
346 goto end;
347 }
3cdd1e94
EK
348 ret += decoded_len - eof;
349 out += decoded_len - eof;
0f113f3e
MC
350 }
351 }
3cdd1e94
EK
352
353 /*
354 * Legacy behaviour: if the current line is a full base64-block (i.e., has
355 * 0 mod 4 base64 characters), it is processed immediately. We keep this
356 * behaviour as applications may not be calling EVP_DecodeFinal properly.
357 */
358tail:
359 if (n > 0) {
360 if ((n & 3) == 0) {
4fe1cbdf
VD
361 decoded_len = EVP_DecodeBlock(out, d, n);
362 n = 0;
363 if (decoded_len < 0 || eof > decoded_len) {
364 rv = -1;
365 goto end;
366 }
367 ret += (decoded_len - eof);
3cdd1e94
EK
368 } else if (seof) {
369 /* EOF in the middle of a base64 block. */
370 rv = -1;
371 goto end;
372 }
373 }
374
375 rv = seof || (n == 0 && eof) ? 0 : 1;
376end:
377 /* Legacy behaviour. This should probably rather be zeroed on error. */
0f113f3e
MC
378 *outl = ret;
379 ctx->num = n;
0f113f3e
MC
380 return (rv);
381}
d02b48c6 382
6343829a 383int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
0f113f3e
MC
384{
385 int i, ret = 0, a, b, c, d;
386 unsigned long l;
387
388 /* trim white space from the start of the line. */
389 while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) {
390 f++;
391 n--;
392 }
393
394 /*
395 * strip off stuff at the end of the line ascii2bin values B64_WS,
396 * B64_EOLN, B64_EOLN and B64_EOF
397 */
398 while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1]))))
399 n--;
400
401 if (n % 4 != 0)
402 return (-1);
403
404 for (i = 0; i < n; i += 4) {
405 a = conv_ascii2bin(*(f++));
406 b = conv_ascii2bin(*(f++));
407 c = conv_ascii2bin(*(f++));
408 d = conv_ascii2bin(*(f++));
409 if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80))
410 return (-1);
411 l = ((((unsigned long)a) << 18L) |
412 (((unsigned long)b) << 12L) |
413 (((unsigned long)c) << 6L) | (((unsigned long)d)));
414 *(t++) = (unsigned char)(l >> 16L) & 0xff;
415 *(t++) = (unsigned char)(l >> 8L) & 0xff;
416 *(t++) = (unsigned char)(l) & 0xff;
417 ret += 3;
418 }
419 return (ret);
420}
d02b48c6 421
6b691a5c 422int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
0f113f3e
MC
423{
424 int i;
425
426 *outl = 0;
427 if (ctx->num != 0) {
428 i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
429 if (i < 0)
430 return (-1);
431 ctx->num = 0;
432 *outl = i;
433 return (1);
434 } else
435 return (1);
436}