Add X509_getm_notBefore, X509_getm_notAfter
[openssl.git] / crypto / asn1 / bio_asn1.c
1 /*
2  * Copyright 2006-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 /*
11  * Experimental ASN1 BIO. When written through the data is converted to an
12  * ASN1 string type: default is OCTET STRING. Additional functions can be
13  * provided to add prefix and suffix data.
14  */
15
16 #include <string.h>
17 #include <internal/bio.h>
18 #include <openssl/asn1.h>
19
20 /* Must be large enough for biggest tag+length */
21 #define DEFAULT_ASN1_BUF_SIZE 20
22
23 typedef enum {
24     ASN1_STATE_START,
25     ASN1_STATE_PRE_COPY,
26     ASN1_STATE_HEADER,
27     ASN1_STATE_HEADER_COPY,
28     ASN1_STATE_DATA_COPY,
29     ASN1_STATE_POST_COPY,
30     ASN1_STATE_DONE
31 } asn1_bio_state_t;
32
33 typedef struct BIO_ASN1_EX_FUNCS_st {
34     asn1_ps_func *ex_func;
35     asn1_ps_func *ex_free_func;
36 } BIO_ASN1_EX_FUNCS;
37
38 typedef struct BIO_ASN1_BUF_CTX_t {
39     /* Internal state */
40     asn1_bio_state_t state;
41     /* Internal buffer */
42     unsigned char *buf;
43     /* Size of buffer */
44     int bufsize;
45     /* Current position in buffer */
46     int bufpos;
47     /* Current buffer length */
48     int buflen;
49     /* Amount of data to copy */
50     int copylen;
51     /* Class and tag to use */
52     int asn1_class, asn1_tag;
53     asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
54     /* Extra buffer for prefix and suffix data */
55     unsigned char *ex_buf;
56     int ex_len;
57     int ex_pos;
58     void *ex_arg;
59 } BIO_ASN1_BUF_CTX;
60
61 static int asn1_bio_write(BIO *h, const char *buf, int num);
62 static int asn1_bio_read(BIO *h, char *buf, int size);
63 static int asn1_bio_puts(BIO *h, const char *str);
64 static int asn1_bio_gets(BIO *h, char *str, int size);
65 static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
66 static int asn1_bio_new(BIO *h);
67 static int asn1_bio_free(BIO *data);
68 static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
69
70 static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
71 static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
72                              asn1_ps_func *cleanup, asn1_bio_state_t next);
73 static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
74                              asn1_ps_func *setup,
75                              asn1_bio_state_t ex_state,
76                              asn1_bio_state_t other_state);
77
78 static const BIO_METHOD methods_asn1 = {
79     BIO_TYPE_ASN1,
80     "asn1",
81     asn1_bio_write,
82     asn1_bio_read,
83     asn1_bio_puts,
84     asn1_bio_gets,
85     asn1_bio_ctrl,
86     asn1_bio_new,
87     asn1_bio_free,
88     asn1_bio_callback_ctrl,
89 };
90
91 const BIO_METHOD *BIO_f_asn1(void)
92 {
93     return (&methods_asn1);
94 }
95
96 static int asn1_bio_new(BIO *b)
97 {
98     BIO_ASN1_BUF_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
99
100     if (ctx == NULL)
101         return 0;
102     if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
103         OPENSSL_free(ctx);
104         return 0;
105     }
106     BIO_set_data(b, ctx);
107     BIO_set_init(b, 1);
108
109     return 1;
110 }
111
112 static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
113 {
114     ctx->buf = OPENSSL_malloc(size);
115     if (ctx->buf == NULL)
116         return 0;
117     ctx->bufsize = size;
118     ctx->asn1_class = V_ASN1_UNIVERSAL;
119     ctx->asn1_tag = V_ASN1_OCTET_STRING;
120     ctx->state = ASN1_STATE_START;
121     return 1;
122 }
123
124 static int asn1_bio_free(BIO *b)
125 {
126     BIO_ASN1_BUF_CTX *ctx;
127
128     if (b == NULL)
129         return 0;
130
131     ctx = BIO_get_data(b);
132     if (ctx == NULL)
133         return 0;
134
135     OPENSSL_free(ctx->buf);
136     OPENSSL_free(ctx);
137     BIO_set_data(b, NULL);
138     BIO_set_init(b, 0);
139
140     return 1;
141 }
142
143 static int asn1_bio_write(BIO *b, const char *in, int inl)
144 {
145     BIO_ASN1_BUF_CTX *ctx;
146     int wrmax, wrlen, ret;
147     unsigned char *p;
148     BIO *next;
149
150     ctx = BIO_get_data(b);
151     next = BIO_next(b);
152     if (in == NULL || inl < 0 || ctx == NULL || next == NULL)
153         return 0;
154
155     wrlen = 0;
156     ret = -1;
157
158     for (;;) {
159         switch (ctx->state) {
160
161             /* Setup prefix data, call it */
162         case ASN1_STATE_START:
163             if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
164                                    ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
165                 return 0;
166             break;
167
168             /* Copy any pre data first */
169         case ASN1_STATE_PRE_COPY:
170
171             ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
172                                     ASN1_STATE_HEADER);
173
174             if (ret <= 0)
175                 goto done;
176
177             break;
178
179         case ASN1_STATE_HEADER:
180             ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
181             OPENSSL_assert(ctx->buflen <= ctx->bufsize);
182             p = ctx->buf;
183             ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class);
184             ctx->copylen = inl;
185             ctx->state = ASN1_STATE_HEADER_COPY;
186
187             break;
188
189         case ASN1_STATE_HEADER_COPY:
190             ret = BIO_write(next, ctx->buf + ctx->bufpos, ctx->buflen);
191             if (ret <= 0)
192                 goto done;
193
194             ctx->buflen -= ret;
195             if (ctx->buflen)
196                 ctx->bufpos += ret;
197             else {
198                 ctx->bufpos = 0;
199                 ctx->state = ASN1_STATE_DATA_COPY;
200             }
201
202             break;
203
204         case ASN1_STATE_DATA_COPY:
205
206             if (inl > ctx->copylen)
207                 wrmax = ctx->copylen;
208             else
209                 wrmax = inl;
210             ret = BIO_write(next, in, wrmax);
211             if (ret <= 0)
212                 break;
213             wrlen += ret;
214             ctx->copylen -= ret;
215             in += ret;
216             inl -= ret;
217
218             if (ctx->copylen == 0)
219                 ctx->state = ASN1_STATE_HEADER;
220
221             if (inl == 0)
222                 goto done;
223
224             break;
225
226         default:
227             BIO_clear_retry_flags(b);
228             return 0;
229
230         }
231
232     }
233
234  done:
235     BIO_clear_retry_flags(b);
236     BIO_copy_next_retry(b);
237
238     return (wrlen > 0) ? wrlen : ret;
239
240 }
241
242 static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
243                              asn1_ps_func *cleanup, asn1_bio_state_t next)
244 {
245     int ret;
246
247     if (ctx->ex_len <= 0)
248         return 1;
249     for (;;) {
250         ret = BIO_write(BIO_next(b), ctx->ex_buf + ctx->ex_pos, ctx->ex_len);
251         if (ret <= 0)
252             break;
253         ctx->ex_len -= ret;
254         if (ctx->ex_len > 0)
255             ctx->ex_pos += ret;
256         else {
257             if (cleanup)
258                 cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg);
259             ctx->state = next;
260             ctx->ex_pos = 0;
261             break;
262         }
263     }
264     return ret;
265 }
266
267 static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
268                              asn1_ps_func *setup,
269                              asn1_bio_state_t ex_state,
270                              asn1_bio_state_t other_state)
271 {
272     if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) {
273         BIO_clear_retry_flags(b);
274         return 0;
275     }
276     if (ctx->ex_len > 0)
277         ctx->state = ex_state;
278     else
279         ctx->state = other_state;
280     return 1;
281 }
282
283 static int asn1_bio_read(BIO *b, char *in, int inl)
284 {
285     BIO *next = BIO_next(b);
286     if (next == NULL)
287         return 0;
288     return BIO_read(next, in, inl);
289 }
290
291 static int asn1_bio_puts(BIO *b, const char *str)
292 {
293     return asn1_bio_write(b, str, strlen(str));
294 }
295
296 static int asn1_bio_gets(BIO *b, char *str, int size)
297 {
298     BIO *next = BIO_next(b);
299     if (next == NULL)
300         return 0;
301     return BIO_gets(next, str, size);
302 }
303
304 static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
305 {
306     BIO *next = BIO_next(b);
307     if (next == NULL)
308         return 0;
309     return BIO_callback_ctrl(next, cmd, fp);
310 }
311
312 static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
313 {
314     BIO_ASN1_BUF_CTX *ctx;
315     BIO_ASN1_EX_FUNCS *ex_func;
316     long ret = 1;
317     BIO *next;
318
319     ctx = BIO_get_data(b);
320     if (ctx == NULL)
321         return 0;
322     next = BIO_next(b);
323     switch (cmd) {
324
325     case BIO_C_SET_PREFIX:
326         ex_func = arg2;
327         ctx->prefix = ex_func->ex_func;
328         ctx->prefix_free = ex_func->ex_free_func;
329         break;
330
331     case BIO_C_GET_PREFIX:
332         ex_func = arg2;
333         ex_func->ex_func = ctx->prefix;
334         ex_func->ex_free_func = ctx->prefix_free;
335         break;
336
337     case BIO_C_SET_SUFFIX:
338         ex_func = arg2;
339         ctx->suffix = ex_func->ex_func;
340         ctx->suffix_free = ex_func->ex_free_func;
341         break;
342
343     case BIO_C_GET_SUFFIX:
344         ex_func = arg2;
345         ex_func->ex_func = ctx->suffix;
346         ex_func->ex_free_func = ctx->suffix_free;
347         break;
348
349     case BIO_C_SET_EX_ARG:
350         ctx->ex_arg = arg2;
351         break;
352
353     case BIO_C_GET_EX_ARG:
354         *(void **)arg2 = ctx->ex_arg;
355         break;
356
357     case BIO_CTRL_FLUSH:
358         if (next == NULL)
359             return 0;
360
361         /* Call post function if possible */
362         if (ctx->state == ASN1_STATE_HEADER) {
363             if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
364                                    ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
365                 return 0;
366         }
367
368         if (ctx->state == ASN1_STATE_POST_COPY) {
369             ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
370                                     ASN1_STATE_DONE);
371             if (ret <= 0)
372                 return ret;
373         }
374
375         if (ctx->state == ASN1_STATE_DONE)
376             return BIO_ctrl(next, cmd, arg1, arg2);
377         else {
378             BIO_clear_retry_flags(b);
379             return 0;
380         }
381
382     default:
383         if (next == NULL)
384             return 0;
385         return BIO_ctrl(next, cmd, arg1, arg2);
386
387     }
388
389     return ret;
390 }
391
392 static int asn1_bio_set_ex(BIO *b, int cmd,
393                            asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
394 {
395     BIO_ASN1_EX_FUNCS extmp;
396     extmp.ex_func = ex_func;
397     extmp.ex_free_func = ex_free_func;
398     return BIO_ctrl(b, cmd, 0, &extmp);
399 }
400
401 static int asn1_bio_get_ex(BIO *b, int cmd,
402                            asn1_ps_func **ex_func,
403                            asn1_ps_func **ex_free_func)
404 {
405     BIO_ASN1_EX_FUNCS extmp;
406     int ret;
407     ret = BIO_ctrl(b, cmd, 0, &extmp);
408     if (ret > 0) {
409         *ex_func = extmp.ex_func;
410         *ex_free_func = extmp.ex_free_func;
411     }
412     return ret;
413 }
414
415 int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
416                         asn1_ps_func *prefix_free)
417 {
418     return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
419 }
420
421 int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
422                         asn1_ps_func **pprefix_free)
423 {
424     return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
425 }
426
427 int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
428                         asn1_ps_func *suffix_free)
429 {
430     return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
431 }
432
433 int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
434                         asn1_ps_func **psuffix_free)
435 {
436     return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
437 }