source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/encode.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 10.8 KB
Line 
1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stdio.h>
11#include <limits.h>
12#include "internal/cryptlib.h"
13#include <openssl/evp.h>
14#include "evp_locl.h"
15
16static unsigned char conv_ascii2bin(unsigned char a);
17#ifndef CHARSET_EBCDIC
18# define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f])
19#else
20/*
21 * We assume that PEM encoded files are EBCDIC files (i.e., printable text
22 * files). Convert them here while decoding. When encoding, output is EBCDIC
23 * (text) format again. (No need for conversion in the conv_bin2ascii macro,
24 * as the underlying textstring data_bin2ascii[] is already EBCDIC)
25 */
26# define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f])
27#endif
28
29/*-
30 * 64 char lines
31 * pad input with 0
32 * left over chars are set to =
33 * 1 byte => xx==
34 * 2 bytes => xxx=
35 * 3 bytes => xxxx
36 */
37#define BIN_PER_LINE (64/4*3)
38#define CHUNKS_PER_LINE (64/4)
39#define CHAR_PER_LINE (64+1)
40
41static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\
42abcdefghijklmnopqrstuvwxyz0123456789+/";
43
44/*-
45 * 0xF0 is a EOLN
46 * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
47 * 0xF2 is EOF
48 * 0xE0 is ignore at start of line.
49 * 0xFF is error
50 */
51
52#define B64_EOLN 0xF0
53#define B64_CR 0xF1
54#define B64_EOF 0xF2
55#define B64_WS 0xE0
56#define B64_ERROR 0xFF
57#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3)
58#define B64_BASE64(a) (!B64_NOT_BASE64(a))
59
60static const unsigned char data_ascii2bin[128] = {
61 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
62 0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF,
63 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
64 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
65 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
66 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
67 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
68 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
69 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
70 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
71 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
72 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
73 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
74 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
75 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
76 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
77};
78
79#ifndef CHARSET_EBCDIC
80static unsigned char conv_ascii2bin(unsigned char a)
81{
82 if (a & 0x80)
83 return B64_ERROR;
84 return data_ascii2bin[a];
85}
86#else
87static unsigned char conv_ascii2bin(unsigned char a)
88{
89 a = os_toascii[a];
90 if (a & 0x80)
91 return B64_ERROR;
92 return data_ascii2bin[a];
93}
94#endif
95
96EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void)
97{
98 return OPENSSL_zalloc(sizeof(EVP_ENCODE_CTX));
99}
100
101void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx)
102{
103 OPENSSL_free(ctx);
104}
105
106int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, EVP_ENCODE_CTX *sctx)
107{
108 memcpy(dctx, sctx, sizeof(EVP_ENCODE_CTX));
109
110 return 1;
111}
112
113int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx)
114{
115 return ctx->num;
116}
117
118void EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
119{
120 ctx->length = 48;
121 ctx->num = 0;
122 ctx->line_num = 0;
123}
124
125int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
126 const unsigned char *in, int inl)
127{
128 int i, j;
129 size_t total = 0;
130
131 *outl = 0;
132 if (inl <= 0)
133 return 0;
134 OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
135 if (ctx->length - ctx->num > inl) {
136 memcpy(&(ctx->enc_data[ctx->num]), in, inl);
137 ctx->num += inl;
138 return 1;
139 }
140 if (ctx->num != 0) {
141 i = ctx->length - ctx->num;
142 memcpy(&(ctx->enc_data[ctx->num]), in, i);
143 in += i;
144 inl -= i;
145 j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
146 ctx->num = 0;
147 out += j;
148 *(out++) = '\n';
149 *out = '\0';
150 total = j + 1;
151 }
152 while (inl >= ctx->length && total <= INT_MAX) {
153 j = EVP_EncodeBlock(out, in, ctx->length);
154 in += ctx->length;
155 inl -= ctx->length;
156 out += j;
157 *(out++) = '\n';
158 *out = '\0';
159 total += j + 1;
160 }
161 if (total > INT_MAX) {
162 /* Too much output data! */
163 *outl = 0;
164 return 0;
165 }
166 if (inl != 0)
167 memcpy(&(ctx->enc_data[0]), in, inl);
168 ctx->num = inl;
169 *outl = total;
170
171 return 1;
172}
173
174void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
175{
176 unsigned int ret = 0;
177
178 if (ctx->num != 0) {
179 ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
180 out[ret++] = '\n';
181 out[ret] = '\0';
182 ctx->num = 0;
183 }
184 *outl = ret;
185}
186
187int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
188{
189 int i, ret = 0;
190 unsigned long l;
191
192 for (i = dlen; i > 0; i -= 3) {
193 if (i >= 3) {
194 l = (((unsigned long)f[0]) << 16L) |
195 (((unsigned long)f[1]) << 8L) | f[2];
196 *(t++) = conv_bin2ascii(l >> 18L);
197 *(t++) = conv_bin2ascii(l >> 12L);
198 *(t++) = conv_bin2ascii(l >> 6L);
199 *(t++) = conv_bin2ascii(l);
200 } else {
201 l = ((unsigned long)f[0]) << 16L;
202 if (i == 2)
203 l |= ((unsigned long)f[1] << 8L);
204
205 *(t++) = conv_bin2ascii(l >> 18L);
206 *(t++) = conv_bin2ascii(l >> 12L);
207 *(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L);
208 *(t++) = '=';
209 }
210 ret += 4;
211 f += 3;
212 }
213
214 *t = '\0';
215 return (ret);
216}
217
218void EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
219{
220 /* Only ctx->num is used during decoding. */
221 ctx->num = 0;
222 ctx->length = 0;
223 ctx->line_num = 0;
224 ctx->expect_nl = 0;
225}
226
227/*-
228 * -1 for error
229 * 0 for last line
230 * 1 for full line
231 *
232 * Note: even though EVP_DecodeUpdate attempts to detect and report end of
233 * content, the context doesn't currently remember it and will accept more data
234 * in the next call. Therefore, the caller is responsible for checking and
235 * rejecting a 0 return value in the middle of content.
236 *
237 * Note: even though EVP_DecodeUpdate has historically tried to detect end of
238 * content based on line length, this has never worked properly. Therefore,
239 * we now return 0 when one of the following is true:
240 * - Padding or B64_EOF was detected and the last block is complete.
241 * - Input has zero-length.
242 * -1 is returned if:
243 * - Invalid characters are detected.
244 * - There is extra trailing padding, or data after padding.
245 * - B64_EOF is detected after an incomplete base64 block.
246 */
247int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
248 const unsigned char *in, int inl)
249{
250 int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len;
251 unsigned char *d;
252
253 n = ctx->num;
254 d = ctx->enc_data;
255
256 if (n > 0 && d[n - 1] == '=') {
257 eof++;
258 if (n > 1 && d[n - 2] == '=')
259 eof++;
260 }
261
262 /* Legacy behaviour: an empty input chunk signals end of input. */
263 if (inl == 0) {
264 rv = 0;
265 goto end;
266 }
267
268 for (i = 0; i < inl; i++) {
269 tmp = *(in++);
270 v = conv_ascii2bin(tmp);
271 if (v == B64_ERROR) {
272 rv = -1;
273 goto end;
274 }
275
276 if (tmp == '=') {
277 eof++;
278 } else if (eof > 0 && B64_BASE64(v)) {
279 /* More data after padding. */
280 rv = -1;
281 goto end;
282 }
283
284 if (eof > 2) {
285 rv = -1;
286 goto end;
287 }
288
289 if (v == B64_EOF) {
290 seof = 1;
291 goto tail;
292 }
293
294 /* Only save valid base64 characters. */
295 if (B64_BASE64(v)) {
296 if (n >= 64) {
297 /*
298 * We increment n once per loop, and empty the buffer as soon as
299 * we reach 64 characters, so this can only happen if someone's
300 * manually messed with the ctx. Refuse to write any more data.
301 */
302 rv = -1;
303 goto end;
304 }
305 OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
306 d[n++] = tmp;
307 }
308
309 if (n == 64) {
310 decoded_len = EVP_DecodeBlock(out, d, n);
311 n = 0;
312 if (decoded_len < 0 || eof > decoded_len) {
313 rv = -1;
314 goto end;
315 }
316 ret += decoded_len - eof;
317 out += decoded_len - eof;
318 }
319 }
320
321 /*
322 * Legacy behaviour: if the current line is a full base64-block (i.e., has
323 * 0 mod 4 base64 characters), it is processed immediately. We keep this
324 * behaviour as applications may not be calling EVP_DecodeFinal properly.
325 */
326tail:
327 if (n > 0) {
328 if ((n & 3) == 0) {
329 decoded_len = EVP_DecodeBlock(out, d, n);
330 n = 0;
331 if (decoded_len < 0 || eof > decoded_len) {
332 rv = -1;
333 goto end;
334 }
335 ret += (decoded_len - eof);
336 } else if (seof) {
337 /* EOF in the middle of a base64 block. */
338 rv = -1;
339 goto end;
340 }
341 }
342
343 rv = seof || (n == 0 && eof) ? 0 : 1;
344end:
345 /* Legacy behaviour. This should probably rather be zeroed on error. */
346 *outl = ret;
347 ctx->num = n;
348 return (rv);
349}
350
351int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
352{
353 int i, ret = 0, a, b, c, d;
354 unsigned long l;
355
356 /* trim white space from the start of the line. */
357 while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) {
358 f++;
359 n--;
360 }
361
362 /*
363 * strip off stuff at the end of the line ascii2bin values B64_WS,
364 * B64_EOLN, B64_EOLN and B64_EOF
365 */
366 while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1]))))
367 n--;
368
369 if (n % 4 != 0)
370 return (-1);
371
372 for (i = 0; i < n; i += 4) {
373 a = conv_ascii2bin(*(f++));
374 b = conv_ascii2bin(*(f++));
375 c = conv_ascii2bin(*(f++));
376 d = conv_ascii2bin(*(f++));
377 if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80))
378 return (-1);
379 l = ((((unsigned long)a) << 18L) |
380 (((unsigned long)b) << 12L) |
381 (((unsigned long)c) << 6L) | (((unsigned long)d)));
382 *(t++) = (unsigned char)(l >> 16L) & 0xff;
383 *(t++) = (unsigned char)(l >> 8L) & 0xff;
384 *(t++) = (unsigned char)(l) & 0xff;
385 ret += 3;
386 }
387 return (ret);
388}
389
390int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
391{
392 int i;
393
394 *outl = 0;
395 if (ctx->num != 0) {
396 i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
397 if (i < 0)
398 return (-1);
399 ctx->num = 0;
400 *outl = i;
401 return (1);
402 } else
403 return (1);
404}
Note: See TracBrowser for help on using the repository browser.