source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/bio_asn1.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 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
23typedef 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
33typedef 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
38typedef 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
61static int asn1_bio_write(BIO *h, const char *buf, int num);
62static int asn1_bio_read(BIO *h, char *buf, int size);
63static int asn1_bio_puts(BIO *h, const char *str);
64static int asn1_bio_gets(BIO *h, char *str, int size);
65static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
66static int asn1_bio_new(BIO *h);
67static int asn1_bio_free(BIO *data);
68static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
69
70static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
71static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
72 asn1_ps_func *cleanup, asn1_bio_state_t next);
73static 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
78static 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
91const BIO_METHOD *BIO_f_asn1(void)
92{
93 return (&methods_asn1);
94}
95
96static 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
112static 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
124static 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
143static 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
242static 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
267static 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
283static 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
291static int asn1_bio_puts(BIO *b, const char *str)
292{
293 return asn1_bio_write(b, str, strlen(str));
294}
295
296static 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
304static 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
312static 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
392static 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
401static 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
415int 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
421int 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
427int 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
433int 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}
Note: See TracBrowser for help on using the repository browser.