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