1 /* $OpenBSD: asn1_item.c,v 1.5 2022/05/24 20:20:19 tb Exp $ */ 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 /* ==================================================================== 59 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 60 * 61 * Redistribution and use in source and binary forms, with or without 62 * modification, are permitted provided that the following conditions 63 * are met: 64 * 65 * 1. Redistributions of source code must retain the above copyright 66 * notice, this list of conditions and the following disclaimer. 67 * 68 * 2. Redistributions in binary form must reproduce the above copyright 69 * notice, this list of conditions and the following disclaimer in 70 * the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3. All advertising materials mentioning features or use of this 74 * software must display the following acknowledgment: 75 * "This product includes software developed by the OpenSSL Project 76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77 * 78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79 * endorse or promote products derived from this software without 80 * prior written permission. For written permission, please contact 81 * openssl-core@openssl.org. 82 * 83 * 5. Products derived from this software may not be called "OpenSSL" 84 * nor may "OpenSSL" appear in their names without prior written 85 * permission of the OpenSSL Project. 86 * 87 * 6. Redistributions of any form whatsoever must retain the following 88 * acknowledgment: 89 * "This product includes software developed by the OpenSSL Project 90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91 * 92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103 * OF THE POSSIBILITY OF SUCH DAMAGE. 104 * ==================================================================== 105 * 106 * This product includes cryptographic software written by Eric Young 107 * (eay@cryptsoft.com). This product includes software written by Tim 108 * Hudson (tjh@cryptsoft.com). 109 * 110 */ 111 112 #include <limits.h> 113 114 #include <openssl/buffer.h> 115 #include <openssl/err.h> 116 #include <openssl/evp.h> 117 #include <openssl/x509.h> 118 119 #include "asn1_locl.h" 120 #include "evp_locl.h" 121 122 /* 123 * ASN1_ITEM version of dup: this follows the model above except we don't need 124 * to allocate the buffer. At some point this could be rewritten to directly dup 125 * the underlying structure instead of doing and encode and decode. 126 */ 127 128 int 129 ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn, 130 unsigned char *md, unsigned int *len) 131 { 132 int i; 133 unsigned char *str = NULL; 134 135 i = ASN1_item_i2d(asn, &str, it); 136 if (!str) 137 return (0); 138 139 if (!EVP_Digest(str, i, md, len, type, NULL)) { 140 free(str); 141 return (0); 142 } 143 144 free(str); 145 return (1); 146 } 147 148 void * 149 ASN1_item_dup(const ASN1_ITEM *it, void *x) 150 { 151 unsigned char *b = NULL; 152 const unsigned char *p; 153 long i; 154 void *ret; 155 156 if (x == NULL) 157 return (NULL); 158 159 i = ASN1_item_i2d(x, &b, it); 160 if (b == NULL) { 161 ASN1error(ERR_R_MALLOC_FAILURE); 162 return (NULL); 163 } 164 p = b; 165 ret = ASN1_item_d2i(NULL, &p, i, it); 166 free(b); 167 return (ret); 168 } 169 170 /* Pack an ASN1 object into an ASN1_STRING. */ 171 ASN1_STRING * 172 ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct) 173 { 174 ASN1_STRING *octmp; 175 176 if (!oct || !*oct) { 177 if (!(octmp = ASN1_STRING_new ())) { 178 ASN1error(ERR_R_MALLOC_FAILURE); 179 return NULL; 180 } 181 } else 182 octmp = *oct; 183 184 free(octmp->data); 185 octmp->data = NULL; 186 187 if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) { 188 ASN1error(ASN1_R_ENCODE_ERROR); 189 goto err; 190 } 191 if (!octmp->data) { 192 ASN1error(ERR_R_MALLOC_FAILURE); 193 goto err; 194 } 195 if (oct) 196 *oct = octmp; 197 return octmp; 198 err: 199 if (!oct || octmp != *oct) 200 ASN1_STRING_free(octmp); 201 return NULL; 202 } 203 204 /* Extract an ASN1 object from an ASN1_STRING. */ 205 void * 206 ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it) 207 { 208 const unsigned char *p; 209 void *ret; 210 211 p = oct->data; 212 if (!(ret = ASN1_item_d2i(NULL, &p, oct->length, it))) 213 ASN1error(ASN1_R_DECODE_ERROR); 214 return ret; 215 } 216 217 int 218 ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, 219 ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey, const EVP_MD *type) 220 { 221 EVP_MD_CTX ctx; 222 EVP_MD_CTX_init(&ctx); 223 if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) { 224 EVP_MD_CTX_cleanup(&ctx); 225 return 0; 226 } 227 return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx); 228 } 229 230 int 231 ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, 232 ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) 233 { 234 const EVP_MD *type; 235 EVP_PKEY *pkey; 236 unsigned char *buf_in = NULL, *buf_out = NULL; 237 size_t buf_out_len = 0; 238 int in_len = 0, out_len = 0; 239 int signid, paramtype; 240 int rv = 2; 241 int ret = 0; 242 243 type = EVP_MD_CTX_md(ctx); 244 pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); 245 246 if (!type || !pkey) { 247 ASN1error(ASN1_R_CONTEXT_NOT_INITIALISED); 248 return 0; 249 } 250 251 if (pkey->ameth->item_sign) { 252 rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, 253 signature); 254 if (rv == 1) 255 out_len = signature->length; 256 /* Return value meanings: 257 * <=0: error. 258 * 1: method does everything. 259 * 2: carry on as normal. 260 * 3: ASN1 method sets algorithm identifiers: just sign. 261 */ 262 if (rv <= 0) 263 ASN1error(ERR_R_EVP_LIB); 264 if (rv <= 1) 265 goto err; 266 } 267 268 if (rv == 2) { 269 if (!pkey->ameth || 270 !OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), 271 pkey->ameth->pkey_id)) { 272 ASN1error(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); 273 return 0; 274 } 275 276 if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) 277 paramtype = V_ASN1_NULL; 278 else 279 paramtype = V_ASN1_UNDEF; 280 281 if (algor1) 282 X509_ALGOR_set0(algor1, 283 OBJ_nid2obj(signid), paramtype, NULL); 284 if (algor2) 285 X509_ALGOR_set0(algor2, 286 OBJ_nid2obj(signid), paramtype, NULL); 287 288 } 289 290 if ((in_len = ASN1_item_i2d(asn, &buf_in, it)) <= 0) { 291 in_len = 0; 292 goto err; 293 } 294 295 if ((out_len = EVP_PKEY_size(pkey)) <= 0) { 296 out_len = 0; 297 goto err; 298 } 299 300 if ((buf_out = malloc(out_len)) == NULL) { 301 ASN1error(ERR_R_MALLOC_FAILURE); 302 goto err; 303 } 304 305 buf_out_len = out_len; 306 if (!EVP_DigestSignUpdate(ctx, buf_in, in_len) || 307 !EVP_DigestSignFinal(ctx, buf_out, &buf_out_len)) { 308 ASN1error(ERR_R_EVP_LIB); 309 goto err; 310 } 311 312 if (buf_out_len > INT_MAX) { 313 ASN1error(ASN1_R_TOO_LONG); 314 goto err; 315 } 316 317 ASN1_STRING_set0(signature, buf_out, (int)buf_out_len); 318 buf_out = NULL; 319 320 if (!asn1_abs_set_unused_bits(signature, 0)) { 321 ASN1error(ERR_R_ASN1_LIB); 322 goto err; 323 } 324 325 ret = (int)buf_out_len; 326 err: 327 EVP_MD_CTX_cleanup(ctx); 328 freezero(buf_in, in_len); 329 freezero(buf_out, out_len); 330 331 return ret; 332 } 333 334 int 335 ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, 336 ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) 337 { 338 EVP_MD_CTX ctx; 339 unsigned char *buf_in = NULL; 340 int ret = -1, inl; 341 342 int mdnid, pknid; 343 344 if (!pkey) { 345 ASN1error(ERR_R_PASSED_NULL_PARAMETER); 346 return -1; 347 } 348 349 if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) 350 { 351 ASN1error(ASN1_R_INVALID_BIT_STRING_BITS_LEFT); 352 return -1; 353 } 354 355 EVP_MD_CTX_init(&ctx); 356 357 /* Convert signature OID into digest and public key OIDs */ 358 if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) { 359 ASN1error(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); 360 goto err; 361 } 362 if (mdnid == NID_undef) { 363 if (!pkey->ameth || !pkey->ameth->item_verify) { 364 ASN1error(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); 365 goto err; 366 } 367 ret = pkey->ameth->item_verify(&ctx, it, asn, a, 368 signature, pkey); 369 /* Return value of 2 means carry on, anything else means we 370 * exit straight away: either a fatal error of the underlying 371 * verification routine handles all verification. 372 */ 373 if (ret != 2) 374 goto err; 375 ret = -1; 376 } else { 377 const EVP_MD *type; 378 type = EVP_get_digestbynid(mdnid); 379 if (type == NULL) { 380 ASN1error(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); 381 goto err; 382 } 383 384 /* Check public key OID matches public key type */ 385 if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { 386 ASN1error(ASN1_R_WRONG_PUBLIC_KEY_TYPE); 387 goto err; 388 } 389 390 if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) { 391 ASN1error(ERR_R_EVP_LIB); 392 ret = 0; 393 goto err; 394 } 395 396 } 397 398 inl = ASN1_item_i2d(asn, &buf_in, it); 399 400 if (buf_in == NULL) { 401 ASN1error(ERR_R_MALLOC_FAILURE); 402 goto err; 403 } 404 405 if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) { 406 ASN1error(ERR_R_EVP_LIB); 407 ret = 0; 408 goto err; 409 } 410 411 freezero(buf_in, (unsigned int)inl); 412 413 if (EVP_DigestVerifyFinal(&ctx, signature->data, 414 (size_t)signature->length) <= 0) { 415 ASN1error(ERR_R_EVP_LIB); 416 ret = 0; 417 goto err; 418 } 419 /* we don't need to zero the 'ctx' because we just checked 420 * public information */ 421 /* memset(&ctx,0,sizeof(ctx)); */ 422 ret = 1; 423 424 err: 425 EVP_MD_CTX_cleanup(&ctx); 426 return (ret); 427 } 428 429 #define HEADER_SIZE 8 430 #define ASN1_CHUNK_INITIAL_SIZE (16 * 1024) 431 int 432 asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) 433 { 434 BUF_MEM *b; 435 unsigned char *p; 436 const unsigned char *q; 437 long slen; 438 int i, inf, tag, xclass; 439 size_t want = HEADER_SIZE; 440 int eos = 0; 441 size_t off = 0; 442 size_t len = 0; 443 444 b = BUF_MEM_new(); 445 if (b == NULL) { 446 ASN1error(ERR_R_MALLOC_FAILURE); 447 return -1; 448 } 449 450 ERR_clear_error(); 451 for (;;) { 452 if (want >= (len - off)) { 453 want -= (len - off); 454 455 if (len + want < len || 456 !BUF_MEM_grow_clean(b, len + want)) { 457 ASN1error(ERR_R_MALLOC_FAILURE); 458 goto err; 459 } 460 i = BIO_read(in, &(b->data[len]), want); 461 if ((i < 0) && ((len - off) == 0)) { 462 ASN1error(ASN1_R_NOT_ENOUGH_DATA); 463 goto err; 464 } 465 if (i > 0) { 466 if (len + i < len) { 467 ASN1error(ASN1_R_TOO_LONG); 468 goto err; 469 } 470 len += i; 471 } 472 } 473 /* else data already loaded */ 474 475 p = (unsigned char *) & (b->data[off]); 476 q = p; 477 inf = ASN1_get_object(&q, &slen, &tag, &xclass, len - off); 478 if (inf & 0x80) { 479 unsigned long e; 480 481 e = ERR_GET_REASON(ERR_peek_error()); 482 if (e != ASN1_R_TOO_LONG) 483 goto err; 484 else 485 ERR_clear_error(); /* clear error */ 486 } 487 i = q - p; /* header length */ 488 off += i; /* end of data */ 489 490 if (inf & 1) { 491 /* no data body so go round again */ 492 eos++; 493 if (eos < 0) { 494 ASN1error(ASN1_R_HEADER_TOO_LONG); 495 goto err; 496 } 497 want = HEADER_SIZE; 498 } else if (eos && slen == 0 && tag == V_ASN1_EOC) { 499 /* eos value, so go back and read another header */ 500 eos--; 501 if (eos <= 0) 502 break; 503 else 504 want = HEADER_SIZE; 505 } else { 506 /* suck in slen bytes of data */ 507 want = slen; 508 if (want > (len - off)) { 509 size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE; 510 511 want -= (len - off); 512 if (want > INT_MAX /* BIO_read takes an int length */ || 513 len+want < len) { 514 ASN1error(ASN1_R_TOO_LONG); 515 goto err; 516 } 517 while (want > 0) { 518 /* 519 * Read content in chunks of increasing size 520 * so we can return an error for EOF without 521 * having to allocate the entire content length 522 * in one go. 523 */ 524 size_t chunk = want > chunk_max ? chunk_max : want; 525 526 if (!BUF_MEM_grow_clean(b, len + chunk)) { 527 ASN1error(ERR_R_MALLOC_FAILURE); 528 goto err; 529 } 530 want -= chunk; 531 while (chunk > 0) { 532 i = BIO_read(in, &(b->data[len]), chunk); 533 if (i <= 0) { 534 ASN1error(ASN1_R_NOT_ENOUGH_DATA); 535 goto err; 536 } 537 /* 538 * This can't overflow because |len+want| 539 * didn't overflow. 540 */ 541 len += i; 542 chunk -= i; 543 } 544 if (chunk_max < INT_MAX/2) 545 chunk_max *= 2; 546 } 547 } 548 if (off + slen < off) { 549 ASN1error(ASN1_R_TOO_LONG); 550 goto err; 551 } 552 off += slen; 553 if (eos <= 0) { 554 break; 555 } else 556 want = HEADER_SIZE; 557 } 558 } 559 560 if (off > INT_MAX) { 561 ASN1error(ASN1_R_TOO_LONG); 562 goto err; 563 } 564 565 *pb = b; 566 return off; 567 568 err: 569 if (b != NULL) 570 BUF_MEM_free(b); 571 return -1; 572 } 573 574 void * 575 ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) 576 { 577 BUF_MEM *b = NULL; 578 const unsigned char *p; 579 void *ret = NULL; 580 int len; 581 582 len = asn1_d2i_read_bio(in, &b); 583 if (len < 0) 584 goto err; 585 586 p = (const unsigned char *)b->data; 587 ret = ASN1_item_d2i(x, &p, len, it); 588 589 err: 590 if (b != NULL) 591 BUF_MEM_free(b); 592 return (ret); 593 } 594 595 void * 596 ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) 597 { 598 BIO *b; 599 char *ret; 600 601 if ((b = BIO_new(BIO_s_file())) == NULL) { 602 ASN1error(ERR_R_BUF_LIB); 603 return (NULL); 604 } 605 BIO_set_fp(b, in, BIO_NOCLOSE); 606 ret = ASN1_item_d2i_bio(it, b, x); 607 BIO_free(b); 608 return (ret); 609 } 610 611 int 612 ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) 613 { 614 unsigned char *b = NULL; 615 int i, j = 0, n, ret = 1; 616 617 n = ASN1_item_i2d(x, &b, it); 618 if (b == NULL) { 619 ASN1error(ERR_R_MALLOC_FAILURE); 620 return (0); 621 } 622 623 for (;;) { 624 i = BIO_write(out, &(b[j]), n); 625 if (i == n) 626 break; 627 if (i <= 0) { 628 ret = 0; 629 break; 630 } 631 j += i; 632 n -= i; 633 } 634 free(b); 635 return (ret); 636 } 637 638 int 639 ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x) 640 { 641 BIO *b; 642 int ret; 643 644 if ((b = BIO_new(BIO_s_file())) == NULL) { 645 ASN1error(ERR_R_BUF_LIB); 646 return (0); 647 } 648 BIO_set_fp(b, out, BIO_NOCLOSE); 649 ret = ASN1_item_i2d_bio(it, b, x); 650 BIO_free(b); 651 return (ret); 652 } 653