summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/evp/encode.c165
1 files changed, 66 insertions, 99 deletions
diff --git a/src/lib/libcrypto/evp/encode.c b/src/lib/libcrypto/evp/encode.c
index ae107abb87..95dc79d70d 100644
--- a/src/lib/libcrypto/evp/encode.c
+++ b/src/lib/libcrypto/evp/encode.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: encode.c,v 1.26 2019/01/19 01:24:18 tb Exp $ */ 1/* $OpenBSD: encode.c,v 1.27 2020/03/03 15:03:14 inoguchi Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -92,6 +92,7 @@ abcdefghijklmnopqrstuvwxyz0123456789+/";
92#define B64_WS 0xE0 92#define B64_WS 0xE0
93#define B64_ERROR 0xFF 93#define B64_ERROR 0xFF
94#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3) 94#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3)
95#define B64_BASE64(a) !B64_NOT_BASE64(a)
95 96
96static const unsigned char data_ascii2bin[128] = { 97static const unsigned char data_ascii2bin[128] = {
97 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 98 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
@@ -231,151 +232,117 @@ EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
231void 232void
232EVP_DecodeInit(EVP_ENCODE_CTX *ctx) 233EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
233{ 234{
234 ctx->length = 30;
235 ctx->num = 0; 235 ctx->num = 0;
236 ctx->length = 0;
236 ctx->line_num = 0; 237 ctx->line_num = 0;
237 ctx->expect_nl = 0; 238 ctx->expect_nl = 0;
238} 239}
239 240
240/* -1 for error
241 * 0 for last line
242 * 1 for full line
243 */
244int 241int
245EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, 242EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
246 const unsigned char *in, int inl) 243 const unsigned char *in, int inl)
247{ 244{
248 int seof = -1, eof = 0, rv = -1, ret = 0, i, v, tmp, n, ln, exp_nl; 245 int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len;
249 unsigned char *d; 246 unsigned char *d;
250 247
251 n = ctx->num; 248 n = ctx->num;
252 d = ctx->enc_data; 249 d = ctx->enc_data;
253 ln = ctx->line_num;
254 exp_nl = ctx->expect_nl;
255 250
256 /* last line of input. */ 251 if (n > 0 && d[n - 1] == '=') {
257 if ((inl == 0) || ((n == 0) && (conv_ascii2bin(in[0]) == B64_EOF))) { 252 eof++;
253 if (n > 1 && d[n - 2] == '=')
254 eof++;
255 }
256
257 /* Legacy behaviour: an empty input chunk signals end of input. */
258 if (inl == 0) {
258 rv = 0; 259 rv = 0;
259 goto end; 260 goto end;
260 } 261 }
261 262
262 /* We parse the input data */
263 for (i = 0; i < inl; i++) { 263 for (i = 0; i < inl; i++) {
264 /* If the current line is > 80 characters, scream alot */ 264 tmp = *(in++);
265 if (ln >= 80) {
266 rv = -1;
267 goto end;
268 }
269
270 /* Get char and put it into the buffer */
271 tmp= *(in++);
272 v = conv_ascii2bin(tmp); 265 v = conv_ascii2bin(tmp);
273 /* only save the good data :-) */ 266 if (v == B64_ERROR) {
274 if (!B64_NOT_BASE64(v)) {
275 OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
276 d[n++] = tmp;
277 ln++;
278 } else if (v == B64_ERROR) {
279 rv = -1;
280 goto end;
281 }
282
283 /* There should not be base64 data after padding. */
284 if (eof && tmp != '=' && tmp != '\r' && tmp != '\n' &&
285 v != B64_EOF) {
286 rv = -1; 267 rv = -1;
287 goto end; 268 goto end;
288 } 269 }
289 270
290 /* have we seen a '=' which is 'definitely' the last
291 * input line. seof will point to the character that
292 * holds it. and eof will hold how many characters to
293 * chop off. */
294 if (tmp == '=') { 271 if (tmp == '=') {
295 if (seof == -1)
296 seof = n;
297 eof++; 272 eof++;
273 } else if (eof > 0 && B64_BASE64(v)) {
274 /* More data after padding. */
275 rv = -1;
276 goto end;
298 } 277 }
299 278
300 /* There should be no more than two padding markers. */
301 if (eof > 2) { 279 if (eof > 2) {
302 rv = -1; 280 rv = -1;
303 goto end; 281 goto end;
304 } 282 }
305 283
306 if (v == B64_CR) { 284 if (v == B64_EOF) {
307 ln = 0; 285 seof = 1;
308 if (exp_nl) 286 goto tail;
309 continue;
310 } 287 }
311 288
312 /* eoln */ 289 /* Only save valid base64 characters. */
313 if (v == B64_EOLN) { 290 if (B64_BASE64(v)) {
314 ln = 0; 291 if (n >= 64) {
315 if (exp_nl) { 292 /*
316 exp_nl = 0; 293 * We increment n once per loop, and empty the
317 continue; 294 * buffer as soon as we reach 64 characters, so
295 * this can only happen if someone's manually
296 * messed with the ctx. Refuse to write any
297 * more data.
298 */
299 rv = -1;
300 goto end;
318 } 301 }
319 } 302 OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
320 exp_nl = 0; 303 d[n++] = tmp;
321
322 /* If we are at the end of input and it looks like a
323 * line, process it. */
324 if (((i + 1) == inl) && (((n&3) == 0) || eof)) {
325 v = B64_EOF;
326 /* In case things were given us in really small
327 records (so two '=' were given in separate
328 updates), eof may contain the incorrect number
329 of ending bytes to skip, so let's redo the count */
330 eof = 0;
331 if (d[n-1] == '=')
332 eof++;
333 if (d[n-2] == '=')
334 eof++;
335 /* There will never be more than two '=' */
336 } 304 }
337 305
338 if ((v == B64_EOF && (n&3) == 0) || (n >= 64)) { 306 if (n == 64) {
339 /* This is needed to work correctly on 64 byte input 307 decoded_len = EVP_DecodeBlock(out, d, n);
340 * lines. We process the line and then need to 308 n = 0;
341 * accept the '\n' */ 309 if (decoded_len < 0 || eof > decoded_len) {
342 if ((v != B64_EOF) && (n >= 64)) 310 rv = -1;
343 exp_nl = 1;
344 if (n > 0) {
345 v = EVP_DecodeBlock(out, d, n);
346 n = 0;
347 if (v < 0) {
348 rv = 0;
349 goto end;
350 }
351 ret += (v - eof);
352 } else {
353 eof = 1;
354 v = 0;
355 }
356
357 /* This is the case where we have had a short
358 * but valid input line */
359 if ((v < ctx->length) && eof) {
360 rv = 0;
361 goto end; 311 goto end;
362 } else 312 }
363 ctx->length = v; 313 ret += decoded_len - eof;
314 out += decoded_len - eof;
315 }
316 }
364 317
365 if (seof >= 0) { 318 /*
366 rv = 0; 319 * Legacy behaviour: if the current line is a full base64-block (i.e.,
320 * has 0 mod 4 base64 characters), it is processed immediately. We keep
321 * this behaviour as applications may not be calling EVP_DecodeFinal
322 * properly.
323 */
324 tail:
325 if (n > 0) {
326 if ((n & 3) == 0) {
327 decoded_len = EVP_DecodeBlock(out, d, n);
328 n = 0;
329 if (decoded_len < 0 || eof > decoded_len) {
330 rv = -1;
367 goto end; 331 goto end;
368 } 332 }
369 out += v; 333 ret += (decoded_len - eof);
334 } else if (seof) {
335 /* EOF in the middle of a base64 block. */
336 rv = -1;
337 goto end;
370 } 338 }
371 } 339 }
372 rv = 1;
373 340
374end: 341 rv = seof || (n == 0 && eof) ? 0 : 1;
342 end:
343 /* Legacy behaviour. This should probably rather be zeroed on error. */
375 *outl = ret; 344 *outl = ret;
376 ctx->num = n; 345 ctx->num = n;
377 ctx->line_num = ln;
378 ctx->expect_nl = exp_nl;
379 return (rv); 346 return (rv);
380} 347}
381 348