1 /* 2 * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (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 bwrite_conv, 83 asn1_bio_write, 84 bread_conv, 85 asn1_bio_read, 86 asn1_bio_puts, 87 asn1_bio_gets, 88 asn1_bio_ctrl, 89 asn1_bio_new, 90 asn1_bio_free, 91 asn1_bio_callback_ctrl, 92 }; 93 94 const BIO_METHOD *BIO_f_asn1(void) 95 { 96 return &methods_asn1; 97 } 98 99 static int asn1_bio_new(BIO *b) 100 { 101 BIO_ASN1_BUF_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); 102 103 if (ctx == NULL) { 104 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 105 return 0; 106 } 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 (size <= 0 || (ctx->buf = OPENSSL_malloc(size)) == NULL) { 120 ERR_raise(ERR_LIB_ASN1, 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 if (ctx->prefix_free != NULL) 142 ctx->prefix_free(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg); 143 if (ctx->suffix_free != NULL) 144 ctx->suffix_free(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg); 145 146 OPENSSL_free(ctx->buf); 147 OPENSSL_free(ctx); 148 BIO_set_data(b, NULL); 149 BIO_set_init(b, 0); 150 151 return 1; 152 } 153 154 static int asn1_bio_write(BIO *b, const char *in, int inl) 155 { 156 BIO_ASN1_BUF_CTX *ctx; 157 int wrmax, wrlen, ret; 158 unsigned char *p; 159 BIO *next; 160 161 ctx = BIO_get_data(b); 162 next = BIO_next(b); 163 if (in == NULL || inl < 0 || ctx == NULL || next == NULL) 164 return 0; 165 166 wrlen = 0; 167 ret = -1; 168 169 for (;;) { 170 switch (ctx->state) { 171 /* Setup prefix data, call it */ 172 case ASN1_STATE_START: 173 if (!asn1_bio_setup_ex(b, ctx, ctx->prefix, 174 ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER)) 175 return -1; 176 break; 177 178 /* Copy any pre data first */ 179 case ASN1_STATE_PRE_COPY: 180 181 ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free, 182 ASN1_STATE_HEADER); 183 184 if (ret <= 0) 185 goto done; 186 187 break; 188 189 case ASN1_STATE_HEADER: 190 ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl; 191 if (!ossl_assert(ctx->buflen <= ctx->bufsize)) 192 return -1; 193 p = ctx->buf; 194 ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class); 195 ctx->copylen = inl; 196 ctx->state = ASN1_STATE_HEADER_COPY; 197 198 break; 199 200 case ASN1_STATE_HEADER_COPY: 201 ret = BIO_write(next, ctx->buf + ctx->bufpos, ctx->buflen); 202 if (ret <= 0) 203 goto done; 204 205 ctx->buflen -= ret; 206 if (ctx->buflen) 207 ctx->bufpos += ret; 208 else { 209 ctx->bufpos = 0; 210 ctx->state = ASN1_STATE_DATA_COPY; 211 } 212 213 break; 214 215 case ASN1_STATE_DATA_COPY: 216 217 if (inl > ctx->copylen) 218 wrmax = ctx->copylen; 219 else 220 wrmax = inl; 221 ret = BIO_write(next, in, wrmax); 222 if (ret <= 0) 223 goto done; 224 wrlen += ret; 225 ctx->copylen -= ret; 226 in += ret; 227 inl -= ret; 228 229 if (ctx->copylen == 0) 230 ctx->state = ASN1_STATE_HEADER; 231 232 if (inl == 0) 233 goto done; 234 235 break; 236 237 case ASN1_STATE_POST_COPY: 238 case ASN1_STATE_DONE: 239 BIO_clear_retry_flags(b); 240 return 0; 241 242 } 243 244 } 245 246 done: 247 BIO_clear_retry_flags(b); 248 BIO_copy_next_retry(b); 249 250 return (wrlen > 0) ? wrlen : ret; 251 252 } 253 254 static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, 255 asn1_ps_func *cleanup, asn1_bio_state_t next) 256 { 257 int ret; 258 259 if (ctx->ex_len <= 0) 260 return 1; 261 for (;;) { 262 ret = BIO_write(BIO_next(b), ctx->ex_buf + ctx->ex_pos, ctx->ex_len); 263 if (ret <= 0) 264 break; 265 ctx->ex_len -= ret; 266 if (ctx->ex_len > 0) 267 ctx->ex_pos += ret; 268 else { 269 if (cleanup) 270 cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg); 271 ctx->state = next; 272 ctx->ex_pos = 0; 273 break; 274 } 275 } 276 return ret; 277 } 278 279 static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, 280 asn1_ps_func *setup, 281 asn1_bio_state_t ex_state, 282 asn1_bio_state_t other_state) 283 { 284 if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) { 285 BIO_clear_retry_flags(b); 286 return 0; 287 } 288 if (ctx->ex_len > 0) 289 ctx->state = ex_state; 290 else 291 ctx->state = other_state; 292 return 1; 293 } 294 295 static int asn1_bio_read(BIO *b, char *in, int inl) 296 { 297 BIO *next = BIO_next(b); 298 if (next == NULL) 299 return 0; 300 return BIO_read(next, in, inl); 301 } 302 303 static int asn1_bio_puts(BIO *b, const char *str) 304 { 305 return asn1_bio_write(b, str, strlen(str)); 306 } 307 308 static int asn1_bio_gets(BIO *b, char *str, int size) 309 { 310 BIO *next = BIO_next(b); 311 if (next == NULL) 312 return 0; 313 return BIO_gets(next, str, size); 314 } 315 316 static long asn1_bio_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) 317 { 318 BIO *next = BIO_next(b); 319 if (next == NULL) 320 return 0; 321 return BIO_callback_ctrl(next, cmd, fp); 322 } 323 324 static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2) 325 { 326 BIO_ASN1_BUF_CTX *ctx; 327 BIO_ASN1_EX_FUNCS *ex_func; 328 long ret = 1; 329 BIO *next; 330 331 ctx = BIO_get_data(b); 332 if (ctx == NULL) 333 return 0; 334 next = BIO_next(b); 335 switch (cmd) { 336 337 case BIO_C_SET_PREFIX: 338 ex_func = arg2; 339 ctx->prefix = ex_func->ex_func; 340 ctx->prefix_free = ex_func->ex_free_func; 341 break; 342 343 case BIO_C_GET_PREFIX: 344 ex_func = arg2; 345 ex_func->ex_func = ctx->prefix; 346 ex_func->ex_free_func = ctx->prefix_free; 347 break; 348 349 case BIO_C_SET_SUFFIX: 350 ex_func = arg2; 351 ctx->suffix = ex_func->ex_func; 352 ctx->suffix_free = ex_func->ex_free_func; 353 break; 354 355 case BIO_C_GET_SUFFIX: 356 ex_func = arg2; 357 ex_func->ex_func = ctx->suffix; 358 ex_func->ex_free_func = ctx->suffix_free; 359 break; 360 361 case BIO_C_SET_EX_ARG: 362 ctx->ex_arg = arg2; 363 break; 364 365 case BIO_C_GET_EX_ARG: 366 *(void **)arg2 = ctx->ex_arg; 367 break; 368 369 case BIO_CTRL_FLUSH: 370 if (next == NULL) 371 return 0; 372 373 /* Call post function if possible */ 374 if (ctx->state == ASN1_STATE_HEADER) { 375 if (!asn1_bio_setup_ex(b, ctx, ctx->suffix, 376 ASN1_STATE_POST_COPY, ASN1_STATE_DONE)) 377 return 0; 378 } 379 380 if (ctx->state == ASN1_STATE_POST_COPY) { 381 ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free, 382 ASN1_STATE_DONE); 383 if (ret <= 0) 384 return ret; 385 } 386 387 if (ctx->state == ASN1_STATE_DONE) 388 return BIO_ctrl(next, cmd, arg1, arg2); 389 else { 390 BIO_clear_retry_flags(b); 391 return 0; 392 } 393 394 default: 395 if (next == NULL) 396 return 0; 397 return BIO_ctrl(next, cmd, arg1, arg2); 398 399 } 400 401 return ret; 402 } 403 404 static int asn1_bio_set_ex(BIO *b, int cmd, 405 asn1_ps_func *ex_func, asn1_ps_func *ex_free_func) 406 { 407 BIO_ASN1_EX_FUNCS extmp; 408 extmp.ex_func = ex_func; 409 extmp.ex_free_func = ex_free_func; 410 return BIO_ctrl(b, cmd, 0, &extmp); 411 } 412 413 static int asn1_bio_get_ex(BIO *b, int cmd, 414 asn1_ps_func **ex_func, 415 asn1_ps_func **ex_free_func) 416 { 417 BIO_ASN1_EX_FUNCS extmp; 418 int ret; 419 ret = BIO_ctrl(b, cmd, 0, &extmp); 420 if (ret > 0) { 421 *ex_func = extmp.ex_func; 422 *ex_free_func = extmp.ex_free_func; 423 } 424 return ret; 425 } 426 427 int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, 428 asn1_ps_func *prefix_free) 429 { 430 return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free); 431 } 432 433 int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, 434 asn1_ps_func **pprefix_free) 435 { 436 return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free); 437 } 438 439 int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, 440 asn1_ps_func *suffix_free) 441 { 442 return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free); 443 } 444 445 int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, 446 asn1_ps_func **psuffix_free) 447 { 448 return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free); 449 } 450