4f0e19eed3434250dbec14544dcb2410c80f75a6
[openssl.git] / crypto / evp / bio_b64.c
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 <errno.h>
12 #include "internal/cryptlib.h"
13 #include <openssl/buffer.h>
14 #include <openssl/evp.h>
15 #include "internal/bio.h"
16
17 static int b64_write(BIO *h, const char *buf, int num);
18 static int b64_read(BIO *h, char *buf, int size);
19 static int b64_puts(BIO *h, const char *str);
20 /*
21  * static int b64_gets(BIO *h, char *str, int size);
22  */
23 static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2);
24 static int b64_new(BIO *h);
25 static int b64_free(BIO *data);
26 static long b64_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
27 #define B64_BLOCK_SIZE  1024
28 #define B64_BLOCK_SIZE2 768
29 #define B64_NONE        0
30 #define B64_ENCODE      1
31 #define B64_DECODE      2
32
33 typedef struct b64_struct {
34     /*
35      * BIO *bio; moved to the BIO structure
36      */
37     int buf_len;
38     int buf_off;
39     int tmp_len;                /* used to find the start when decoding */
40     int tmp_nl;                 /* If true, scan until '\n' */
41     int encode;
42     int start;                  /* have we started decoding yet? */
43     int cont;                   /* <= 0 when finished */
44     EVP_ENCODE_CTX *base64;
45     char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10];
46     char tmp[B64_BLOCK_SIZE];
47 } BIO_B64_CTX;
48
49 static const BIO_METHOD methods_b64 = {
50     BIO_TYPE_BASE64, "base64 encoding",
51     /* TODO: Convert to new style write function */
52     bwrite_conv,
53     b64_write,
54     /* TODO: Convert to new style read function */
55     bread_conv,
56     b64_read,
57     b64_puts,
58     NULL,                       /* b64_gets, */
59     b64_ctrl,
60     b64_new,
61     b64_free,
62     b64_callback_ctrl,
63 };
64
65
66 const BIO_METHOD *BIO_f_base64(void)
67 {
68     return &methods_b64;
69 }
70
71 static int b64_new(BIO *bi)
72 {
73     BIO_B64_CTX *ctx;
74
75     ctx = OPENSSL_zalloc(sizeof(*ctx));
76     if (ctx == NULL)
77         return 0;
78
79     ctx->cont = 1;
80     ctx->start = 1;
81     ctx->base64 = EVP_ENCODE_CTX_new();
82     if (ctx->base64 == NULL) {
83         OPENSSL_free(ctx);
84         return 0;
85     }
86
87     BIO_set_data(bi, ctx);
88     BIO_set_init(bi, 1);
89
90     return 1;
91 }
92
93 static int b64_free(BIO *a)
94 {
95     BIO_B64_CTX *ctx;
96     if (a == NULL)
97         return 0;
98
99     ctx = BIO_get_data(a);
100     if (ctx == NULL)
101         return 0;
102
103     EVP_ENCODE_CTX_free(ctx->base64);
104     OPENSSL_free(ctx);
105     BIO_set_data(a, NULL);
106     BIO_set_init(a, 0);
107
108     return 1;
109 }
110
111 static int b64_read(BIO *b, char *out, int outl)
112 {
113     int ret = 0, i, ii, j, k, x, n, num, ret_code = 0;
114     BIO_B64_CTX *ctx;
115     unsigned char *p, *q;
116     BIO *next;
117
118     if (out == NULL)
119         return (0);
120     ctx = (BIO_B64_CTX *)BIO_get_data(b);
121
122     next = BIO_next(b);
123     if ((ctx == NULL) || (next == NULL))
124         return 0;
125
126     BIO_clear_retry_flags(b);
127
128     if (ctx->encode != B64_DECODE) {
129         ctx->encode = B64_DECODE;
130         ctx->buf_len = 0;
131         ctx->buf_off = 0;
132         ctx->tmp_len = 0;
133         EVP_DecodeInit(ctx->base64);
134     }
135
136     /* First check if there are bytes decoded/encoded */
137     if (ctx->buf_len > 0) {
138         OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
139         i = ctx->buf_len - ctx->buf_off;
140         if (i > outl)
141             i = outl;
142         OPENSSL_assert(ctx->buf_off + i < (int)sizeof(ctx->buf));
143         memcpy(out, &(ctx->buf[ctx->buf_off]), i);
144         ret = i;
145         out += i;
146         outl -= i;
147         ctx->buf_off += i;
148         if (ctx->buf_len == ctx->buf_off) {
149             ctx->buf_len = 0;
150             ctx->buf_off = 0;
151         }
152     }
153
154     /*
155      * At this point, we have room of outl bytes and an empty buffer, so we
156      * should read in some more.
157      */
158
159     ret_code = 0;
160     while (outl > 0) {
161         if (ctx->cont <= 0)
162             break;
163
164         i = BIO_read(next, &(ctx->tmp[ctx->tmp_len]),
165                      B64_BLOCK_SIZE - ctx->tmp_len);
166
167         if (i <= 0) {
168             ret_code = i;
169
170             /* Should we continue next time we are called? */
171             if (!BIO_should_retry(next)) {
172                 ctx->cont = i;
173                 /* If buffer empty break */
174                 if (ctx->tmp_len == 0)
175                     break;
176                 /* Fall through and process what we have */
177                 else
178                     i = 0;
179             }
180             /* else we retry and add more data to buffer */
181             else
182                 break;
183         }
184         i += ctx->tmp_len;
185         ctx->tmp_len = i;
186
187         /*
188          * We need to scan, a line at a time until we have a valid line if we
189          * are starting.
190          */
191         if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) {
192             /* ctx->start=1; */
193             ctx->tmp_len = 0;
194         } else if (ctx->start) {
195             q = p = (unsigned char *)ctx->tmp;
196             num = 0;
197             for (j = 0; j < i; j++) {
198                 if (*(q++) != '\n')
199                     continue;
200
201                 /*
202                  * due to a previous very long line, we need to keep on
203                  * scanning for a '\n' before we even start looking for
204                  * base64 encoded stuff.
205                  */
206                 if (ctx->tmp_nl) {
207                     p = q;
208                     ctx->tmp_nl = 0;
209                     continue;
210                 }
211
212                 k = EVP_DecodeUpdate(ctx->base64,
213                                      (unsigned char *)ctx->buf,
214                                      &num, p, q - p);
215                 if ((k <= 0) && (num == 0) && (ctx->start))
216                     EVP_DecodeInit(ctx->base64);
217                 else {
218                     if (p != (unsigned char *)
219                         &(ctx->tmp[0])) {
220                         i -= (p - (unsigned char *)
221                               &(ctx->tmp[0]));
222                         for (x = 0; x < i; x++)
223                             ctx->tmp[x] = p[x];
224                     }
225                     EVP_DecodeInit(ctx->base64);
226                     ctx->start = 0;
227                     break;
228                 }
229                 p = q;
230             }
231
232             /* we fell off the end without starting */
233             if ((j == i) && (num == 0)) {
234                 /*
235                  * Is this is one long chunk?, if so, keep on reading until a
236                  * new line.
237                  */
238                 if (p == (unsigned char *)&(ctx->tmp[0])) {
239                     /* Check buffer full */
240                     if (i == B64_BLOCK_SIZE) {
241                         ctx->tmp_nl = 1;
242                         ctx->tmp_len = 0;
243                     }
244                 } else if (p != q) { /* finished on a '\n' */
245                     n = q - p;
246                     for (ii = 0; ii < n; ii++)
247                         ctx->tmp[ii] = p[ii];
248                     ctx->tmp_len = n;
249                 }
250                 /* else finished on a '\n' */
251                 continue;
252             } else {
253                 ctx->tmp_len = 0;
254             }
255         } else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) {
256             /*
257              * If buffer isn't full and we can retry then restart to read in
258              * more data.
259              */
260             continue;
261         }
262
263         if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
264             int z, jj;
265
266             jj = i & ~3;        /* process per 4 */
267             z = EVP_DecodeBlock((unsigned char *)ctx->buf,
268                                 (unsigned char *)ctx->tmp, jj);
269             if (jj > 2) {
270                 if (ctx->tmp[jj - 1] == '=') {
271                     z--;
272                     if (ctx->tmp[jj - 2] == '=')
273                         z--;
274                 }
275             }
276             /*
277              * z is now number of output bytes and jj is the number consumed
278              */
279             if (jj != i) {
280                 memmove(ctx->tmp, &ctx->tmp[jj], i - jj);
281                 ctx->tmp_len = i - jj;
282             }
283             ctx->buf_len = 0;
284             if (z > 0) {
285                 ctx->buf_len = z;
286             }
287             i = z;
288         } else {
289             i = EVP_DecodeUpdate(ctx->base64,
290                                  (unsigned char *)ctx->buf, &ctx->buf_len,
291                                  (unsigned char *)ctx->tmp, i);
292             ctx->tmp_len = 0;
293         }
294         ctx->buf_off = 0;
295         if (i < 0) {
296             ret_code = 0;
297             ctx->buf_len = 0;
298             break;
299         }
300
301         if (ctx->buf_len <= outl)
302             i = ctx->buf_len;
303         else
304             i = outl;
305
306         memcpy(out, ctx->buf, i);
307         ret += i;
308         ctx->buf_off = i;
309         if (ctx->buf_off == ctx->buf_len) {
310             ctx->buf_len = 0;
311             ctx->buf_off = 0;
312         }
313         outl -= i;
314         out += i;
315     }
316     /* BIO_clear_retry_flags(b); */
317     BIO_copy_next_retry(b);
318     return ((ret == 0) ? ret_code : ret);
319 }
320
321 static int b64_write(BIO *b, const char *in, int inl)
322 {
323     int ret = 0;
324     int n;
325     int i;
326     BIO_B64_CTX *ctx;
327     BIO *next;
328
329     ctx = (BIO_B64_CTX *)BIO_get_data(b);
330     next = BIO_next(b);
331     if ((ctx == NULL) || (next == NULL))
332         return 0;
333
334     BIO_clear_retry_flags(b);
335
336     if (ctx->encode != B64_ENCODE) {
337         ctx->encode = B64_ENCODE;
338         ctx->buf_len = 0;
339         ctx->buf_off = 0;
340         ctx->tmp_len = 0;
341         EVP_EncodeInit(ctx->base64);
342     }
343
344     OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf));
345     OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
346     OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
347     n = ctx->buf_len - ctx->buf_off;
348     while (n > 0) {
349         i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
350         if (i <= 0) {
351             BIO_copy_next_retry(b);
352             return (i);
353         }
354         OPENSSL_assert(i <= n);
355         ctx->buf_off += i;
356         OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
357         OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
358         n -= i;
359     }
360     /* at this point all pending data has been written */
361     ctx->buf_off = 0;
362     ctx->buf_len = 0;
363
364     if ((in == NULL) || (inl <= 0))
365         return (0);
366
367     while (inl > 0) {
368         n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl;
369
370         if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
371             if (ctx->tmp_len > 0) {
372                 OPENSSL_assert(ctx->tmp_len <= 3);
373                 n = 3 - ctx->tmp_len;
374                 /*
375                  * There's a theoretical possibility for this
376                  */
377                 if (n > inl)
378                     n = inl;
379                 memcpy(&(ctx->tmp[ctx->tmp_len]), in, n);
380                 ctx->tmp_len += n;
381                 ret += n;
382                 if (ctx->tmp_len < 3)
383                     break;
384                 ctx->buf_len =
385                     EVP_EncodeBlock((unsigned char *)ctx->buf,
386                                     (unsigned char *)ctx->tmp, ctx->tmp_len);
387                 OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
388                 OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
389                 /*
390                  * Since we're now done using the temporary buffer, the
391                  * length should be 0'd
392                  */
393                 ctx->tmp_len = 0;
394             } else {
395                 if (n < 3) {
396                     memcpy(ctx->tmp, in, n);
397                     ctx->tmp_len = n;
398                     ret += n;
399                     break;
400                 }
401                 n -= n % 3;
402                 ctx->buf_len =
403                     EVP_EncodeBlock((unsigned char *)ctx->buf,
404                                     (const unsigned char *)in, n);
405                 OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
406                 OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
407                 ret += n;
408             }
409         } else {
410             if (!EVP_EncodeUpdate(ctx->base64,
411                                  (unsigned char *)ctx->buf, &ctx->buf_len,
412                                  (unsigned char *)in, n))
413                 return ((ret == 0) ? -1 : ret);
414             OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
415             OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
416             ret += n;
417         }
418         inl -= n;
419         in += n;
420
421         ctx->buf_off = 0;
422         n = ctx->buf_len;
423         while (n > 0) {
424             i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
425             if (i <= 0) {
426                 BIO_copy_next_retry(b);
427                 return ((ret == 0) ? i : ret);
428             }
429             OPENSSL_assert(i <= n);
430             n -= i;
431             ctx->buf_off += i;
432             OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
433             OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
434         }
435         ctx->buf_len = 0;
436         ctx->buf_off = 0;
437     }
438     return (ret);
439 }
440
441 static long b64_ctrl(BIO *b, int cmd, long num, void *ptr)
442 {
443     BIO_B64_CTX *ctx;
444     long ret = 1;
445     int i;
446     BIO *next;
447
448     ctx = (BIO_B64_CTX *)BIO_get_data(b);
449     next = BIO_next(b);
450     if ((ctx == NULL) || (next == NULL))
451         return 0;
452
453     switch (cmd) {
454     case BIO_CTRL_RESET:
455         ctx->cont = 1;
456         ctx->start = 1;
457         ctx->encode = B64_NONE;
458         ret = BIO_ctrl(next, cmd, num, ptr);
459         break;
460     case BIO_CTRL_EOF:         /* More to read */
461         if (ctx->cont <= 0)
462             ret = 1;
463         else
464             ret = BIO_ctrl(next, cmd, num, ptr);
465         break;
466     case BIO_CTRL_WPENDING:    /* More to write in buffer */
467         OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
468         ret = ctx->buf_len - ctx->buf_off;
469         if ((ret == 0) && (ctx->encode != B64_NONE)
470             && (EVP_ENCODE_CTX_num(ctx->base64) != 0))
471             ret = 1;
472         else if (ret <= 0)
473             ret = BIO_ctrl(next, cmd, num, ptr);
474         break;
475     case BIO_CTRL_PENDING:     /* More to read in buffer */
476         OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
477         ret = ctx->buf_len - ctx->buf_off;
478         if (ret <= 0)
479             ret = BIO_ctrl(next, cmd, num, ptr);
480         break;
481     case BIO_CTRL_FLUSH:
482         /* do a final write */
483  again:
484         while (ctx->buf_len != ctx->buf_off) {
485             i = b64_write(b, NULL, 0);
486             if (i < 0)
487                 return i;
488         }
489         if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
490             if (ctx->tmp_len != 0) {
491                 ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf,
492                                                (unsigned char *)ctx->tmp,
493                                                ctx->tmp_len);
494                 ctx->buf_off = 0;
495                 ctx->tmp_len = 0;
496                 goto again;
497             }
498         } else if (ctx->encode != B64_NONE
499                    && EVP_ENCODE_CTX_num(ctx->base64) != 0) {
500             ctx->buf_off = 0;
501             EVP_EncodeFinal(ctx->base64,
502                             (unsigned char *)ctx->buf, &(ctx->buf_len));
503             /* push out the bytes */
504             goto again;
505         }
506         /* Finally flush the underlying BIO */
507         ret = BIO_ctrl(next, cmd, num, ptr);
508         break;
509
510     case BIO_C_DO_STATE_MACHINE:
511         BIO_clear_retry_flags(b);
512         ret = BIO_ctrl(next, cmd, num, ptr);
513         BIO_copy_next_retry(b);
514         break;
515
516     case BIO_CTRL_DUP:
517         break;
518     case BIO_CTRL_INFO:
519     case BIO_CTRL_GET:
520     case BIO_CTRL_SET:
521     default:
522         ret = BIO_ctrl(next, cmd, num, ptr);
523         break;
524     }
525     return ret;
526 }
527
528 static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
529 {
530     long ret = 1;
531     BIO *next = BIO_next(b);
532
533     if (next == NULL)
534         return 0;
535     switch (cmd) {
536     default:
537         ret = BIO_callback_ctrl(next, cmd, fp);
538         break;
539     }
540     return (ret);
541 }
542
543 static int b64_puts(BIO *b, const char *str)
544 {
545     return b64_write(b, str, strlen(str));
546 }