1 /* $OpenBSD: x509.c,v 1.42 2025/01/19 13:14:22 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 #include <assert.h> 60 #include <limits.h> 61 #include <stdio.h> 62 #include <stdlib.h> 63 #include <string.h> 64 65 #include "apps.h" 66 67 #include <openssl/asn1.h> 68 #include <openssl/bio.h> 69 #include <openssl/bn.h> 70 #include <openssl/dsa.h> 71 #include <openssl/err.h> 72 #include <openssl/evp.h> 73 #include <openssl/objects.h> 74 #include <openssl/pem.h> 75 #include <openssl/rsa.h> 76 #include <openssl/x509.h> 77 #include <openssl/x509v3.h> 78 79 #define POSTFIX ".srl" 80 #define DEF_DAYS 30 81 82 static int callb(int ok, X509_STORE_CTX *ctx); 83 static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, 84 const EVP_MD *digest, CONF *conf, char *section, X509_NAME *issuer, 85 char *force_pubkey); 86 static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, 87 X509 *x, X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts, 88 char *serial, int create, int days, int clrext, CONF *conf, char *section, 89 ASN1_INTEGER *sno, X509_NAME *issuer); 90 static int purpose_print(BIO *bio, X509 *cert, const X509_PURPOSE *pt); 91 92 static struct { 93 char *alias; 94 int aliasout; 95 int badops; 96 int CA_createserial; 97 int CA_flag; 98 char *CAfile; 99 int CAformat; 100 char *CAkeyfile; 101 int CAkeyformat; 102 char *CAserial; 103 unsigned long certflag; 104 int checkend; 105 int checkoffset; 106 unsigned long chtype; 107 int clrext; 108 int clrreject; 109 int clrtrust; 110 int days; 111 const EVP_MD *digest; 112 int email; 113 int enddate; 114 char *extfile; 115 char *extsect; 116 int fingerprint; 117 char *force_pubkey; 118 char *infile; 119 int informat; 120 int issuer; 121 int issuer_hash; 122 #ifndef OPENSSL_NO_MD5 123 int issuer_hash_old; 124 #endif 125 char *keyfile; 126 int keyformat; 127 const EVP_MD *md_alg; 128 int modulus; 129 int multirdn; 130 int new; 131 int next_serial; 132 unsigned long nmflag; 133 int noout; 134 int num; 135 int ocspid; 136 ASN1_OBJECT *objtmp; 137 int ocsp_uri; 138 char *outfile; 139 int outformat; 140 char *passargin; 141 int pprint; 142 int pubkey; 143 STACK_OF(ASN1_OBJECT) *reject; 144 int reqfile; 145 int serial; 146 char *set_issuer; 147 char *set_subject; 148 int sign_flag; 149 STACK_OF(OPENSSL_STRING) *sigopts; 150 ASN1_INTEGER *sno; 151 int startdate; 152 int subject; 153 int subject_hash; 154 #ifndef OPENSSL_NO_MD5 155 int subject_hash_old; 156 #endif 157 int text; 158 STACK_OF(ASN1_OBJECT) *trust; 159 int trustout; 160 int x509req; 161 } cfg; 162 163 static int 164 x509_opt_addreject(char *arg) 165 { 166 if ((cfg.objtmp = OBJ_txt2obj(arg, 0)) == NULL) { 167 BIO_printf(bio_err, "Invalid reject object value %s\n", arg); 168 return (1); 169 } 170 171 if (cfg.reject == NULL && 172 (cfg.reject = sk_ASN1_OBJECT_new_null()) == NULL) 173 return (1); 174 175 if (!sk_ASN1_OBJECT_push(cfg.reject, cfg.objtmp)) 176 return (1); 177 178 cfg.trustout = 1; 179 return (0); 180 } 181 182 static int 183 x509_opt_addtrust(char *arg) 184 { 185 if ((cfg.objtmp = OBJ_txt2obj(arg, 0)) == NULL) { 186 BIO_printf(bio_err, "Invalid trust object value %s\n", arg); 187 return (1); 188 } 189 190 if (cfg.trust == NULL && 191 (cfg.trust = sk_ASN1_OBJECT_new_null()) == NULL) 192 return (1); 193 194 if (!sk_ASN1_OBJECT_push(cfg.trust, cfg.objtmp)) 195 return (1); 196 197 cfg.trustout = 1; 198 return (0); 199 } 200 201 static int 202 x509_opt_ca(char *arg) 203 { 204 cfg.CAfile = arg; 205 cfg.CA_flag = ++cfg.num; 206 return (0); 207 } 208 209 static int 210 x509_opt_certopt(char *arg) 211 { 212 if (!set_cert_ex(&cfg.certflag, arg)) 213 return (1); 214 215 return (0); 216 } 217 218 static int 219 x509_opt_checkend(char *arg) 220 { 221 const char *errstr; 222 223 cfg.checkoffset = strtonum(arg, 0, INT_MAX, &errstr); 224 if (errstr != NULL) { 225 BIO_printf(bio_err, "checkend unusable: %s\n", errstr); 226 return (1); 227 } 228 cfg.checkend = 1; 229 return (0); 230 } 231 232 static int 233 x509_opt_dates(void) 234 { 235 cfg.startdate = ++cfg.num; 236 cfg.enddate = ++cfg.num; 237 return (0); 238 } 239 240 static int 241 x509_opt_days(char *arg) 242 { 243 const char *errstr; 244 245 cfg.days = strtonum(arg, 1, INT_MAX, &errstr); 246 if (errstr != NULL) { 247 BIO_printf(bio_err, "bad number of days: %s\n", errstr); 248 return (1); 249 } 250 return (0); 251 } 252 253 static int 254 x509_opt_digest(int argc, char **argv, int *argsused) 255 { 256 char *name = argv[0]; 257 258 if (*name++ != '-') 259 return (1); 260 261 if ((cfg.md_alg = EVP_get_digestbyname(name)) != NULL) { 262 cfg.digest = cfg.md_alg; 263 } else { 264 BIO_printf(bio_err, "unknown option %s\n", *argv); 265 cfg.badops = 1; 266 return (1); 267 } 268 269 *argsused = 1; 270 return (0); 271 } 272 273 static int 274 x509_opt_nameopt(char *arg) 275 { 276 if (!set_name_ex(&cfg.nmflag, arg)) 277 return (1); 278 279 return (0); 280 } 281 282 static int 283 x509_opt_set_serial(char *arg) 284 { 285 ASN1_INTEGER_free(cfg.sno); 286 if ((cfg.sno = s2i_ASN1_INTEGER(NULL, arg)) == NULL) 287 return (1); 288 289 return (0); 290 } 291 292 static int 293 x509_opt_setalias(char *arg) 294 { 295 cfg.alias = arg; 296 cfg.trustout = 1; 297 return (0); 298 } 299 300 static int 301 x509_opt_signkey(char *arg) 302 { 303 cfg.keyfile = arg; 304 cfg.sign_flag = ++cfg.num; 305 return (0); 306 } 307 308 static int 309 x509_opt_sigopt(char *arg) 310 { 311 if (cfg.sigopts == NULL && 312 (cfg.sigopts = sk_OPENSSL_STRING_new_null()) == NULL) 313 return (1); 314 315 if (!sk_OPENSSL_STRING_push(cfg.sigopts, arg)) 316 return (1); 317 318 return (0); 319 } 320 321 static int 322 x509_opt_utf8(void) 323 { 324 cfg.chtype = MBSTRING_UTF8; 325 return (0); 326 } 327 328 static const struct option x509_options[] = { 329 { 330 .name = "addreject", 331 .argname = "arg", 332 .desc = "Reject certificate for a given purpose", 333 .type = OPTION_ARG_FUNC, 334 .opt.argfunc = x509_opt_addreject, 335 }, 336 { 337 .name = "addtrust", 338 .argname = "arg", 339 .desc = "Trust certificate for a given purpose", 340 .type = OPTION_ARG_FUNC, 341 .opt.argfunc = x509_opt_addtrust, 342 }, 343 { 344 .name = "alias", 345 .desc = "Output certificate alias", 346 .type = OPTION_ORDER, 347 .opt.order = &cfg.aliasout, 348 .order = &cfg.num, 349 }, 350 { 351 .name = "CA", 352 .argname = "file", 353 .desc = "CA certificate in PEM format unless -CAform is specified", 354 .type = OPTION_ARG_FUNC, 355 .opt.argfunc = x509_opt_ca, 356 }, 357 { 358 .name = "CAcreateserial", 359 .desc = "Create serial number file if it does not exist", 360 .type = OPTION_ORDER, 361 .opt.order = &cfg.CA_createserial, 362 .order = &cfg.num, 363 }, 364 { 365 .name = "CAform", 366 .argname = "fmt", 367 .desc = "CA format - default PEM", 368 .type = OPTION_ARG_FORMAT, 369 .opt.value = &cfg.CAformat, 370 }, 371 { 372 .name = "CAkey", 373 .argname = "file", 374 .desc = "CA key in PEM format unless -CAkeyform is specified\n" 375 "if omitted, the key is assumed to be in the CA file", 376 .type = OPTION_ARG, 377 .opt.arg = &cfg.CAkeyfile, 378 }, 379 { 380 .name = "CAkeyform", 381 .argname = "fmt", 382 .desc = "CA key format - default PEM", 383 .type = OPTION_ARG_FORMAT, 384 .opt.value = &cfg.CAkeyformat, 385 }, 386 { 387 .name = "CAserial", 388 .argname = "file", 389 .desc = "Serial file", 390 .type = OPTION_ARG, 391 .opt.arg = &cfg.CAserial, 392 }, 393 { 394 .name = "certopt", 395 .argname = "option", 396 .desc = "Various certificate text options", 397 .type = OPTION_ARG_FUNC, 398 .opt.argfunc = x509_opt_certopt, 399 }, 400 { 401 .name = "checkend", 402 .argname = "arg", 403 .desc = "Check whether the cert expires in the next arg seconds\n" 404 "exit 1 if so, 0 if not", 405 .type = OPTION_ARG_FUNC, 406 .opt.argfunc = x509_opt_checkend, 407 }, 408 { 409 .name = "clrext", 410 .desc = "Clear all extensions", 411 .type = OPTION_FLAG, 412 .opt.flag = &cfg.clrext, 413 }, 414 { 415 .name = "clrreject", 416 .desc = "Clear all rejected purposes", 417 .type = OPTION_ORDER, 418 .opt.order = &cfg.clrreject, 419 .order = &cfg.num, 420 }, 421 { 422 .name = "clrtrust", 423 .desc = "Clear all trusted purposes", 424 .type = OPTION_ORDER, 425 .opt.order = &cfg.clrtrust, 426 .order = &cfg.num, 427 }, 428 { 429 .name = "dates", 430 .desc = "Both Before and After dates", 431 .type = OPTION_FUNC, 432 .opt.func = x509_opt_dates, 433 }, 434 { 435 .name = "days", 436 .argname = "arg", 437 .desc = "How long till expiry of a signed certificate - def 30 days", 438 .type = OPTION_ARG_FUNC, 439 .opt.argfunc = x509_opt_days, 440 }, 441 { 442 .name = "email", 443 .desc = "Print email address(es)", 444 .type = OPTION_ORDER, 445 .opt.order = &cfg.email, 446 .order = &cfg.num, 447 }, 448 { 449 .name = "enddate", 450 .desc = "Print notAfter field", 451 .type = OPTION_ORDER, 452 .opt.order = &cfg.enddate, 453 .order = &cfg.num, 454 }, 455 { 456 .name = "extensions", 457 .argname = "section", 458 .desc = "Section from config file with X509V3 extensions to add", 459 .type = OPTION_ARG, 460 .opt.arg = &cfg.extsect, 461 }, 462 { 463 .name = "extfile", 464 .argname = "file", 465 .desc = "Configuration file with X509V3 extensions to add", 466 .type = OPTION_ARG, 467 .opt.arg = &cfg.extfile, 468 }, 469 { 470 .name = "fingerprint", 471 .desc = "Print the certificate fingerprint", 472 .type = OPTION_ORDER, 473 .opt.order = &cfg.fingerprint, 474 .order = &cfg.num, 475 }, 476 { 477 .name = "force_pubkey", 478 .argname = "key", 479 .desc = "Force the public key to be put in the certificate", 480 .type = OPTION_ARG, 481 .opt.arg = &cfg.force_pubkey, 482 }, 483 { 484 .name = "hash", 485 .desc = "Synonym for -subject_hash", 486 .type = OPTION_ORDER, 487 .opt.order = &cfg.subject_hash, 488 .order = &cfg.num, 489 }, 490 { 491 .name = "in", 492 .argname = "file", 493 .desc = "Input file - default stdin", 494 .type = OPTION_ARG, 495 .opt.arg = &cfg.infile, 496 }, 497 { 498 .name = "inform", 499 .argname = "fmt", 500 .desc = "Input format - default PEM (one of DER, NET or PEM)", 501 .type = OPTION_ARG_FORMAT, 502 .opt.value = &cfg.informat, 503 }, 504 { 505 .name = "issuer", 506 .desc = "Print issuer name", 507 .type = OPTION_ORDER, 508 .opt.order = &cfg.issuer, 509 .order = &cfg.num, 510 }, 511 { 512 .name = "issuer_hash", 513 .desc = "Print issuer hash value", 514 .type = OPTION_ORDER, 515 .opt.order = &cfg.issuer_hash, 516 .order = &cfg.num, 517 }, 518 #ifndef OPENSSL_NO_MD5 519 { 520 .name = "issuer_hash_old", 521 .desc = "Print old-style (MD5) issuer hash value", 522 .type = OPTION_ORDER, 523 .opt.order = &cfg.issuer_hash_old, 524 .order = &cfg.num, 525 }, 526 #endif 527 { 528 .name = "key", 529 .argname = "file", 530 .type = OPTION_ARG_FUNC, 531 .opt.argfunc = x509_opt_signkey, 532 }, 533 { 534 .name = "keyform", 535 .argname = "fmt", 536 .desc = "Private key format - default PEM", 537 .type = OPTION_ARG_FORMAT, 538 .opt.value = &cfg.keyformat, 539 }, 540 { 541 .name = "modulus", 542 .desc = "Print the RSA key modulus", 543 .type = OPTION_ORDER, 544 .opt.order = &cfg.modulus, 545 .order = &cfg.num, 546 }, 547 { 548 .name = "multivalue-rdn", 549 .desc = "Enable support for multivalued RDNs", 550 .type = OPTION_FLAG, 551 .opt.flag = &cfg.multirdn, 552 }, 553 { 554 .name = "nameopt", 555 .argname = "option", 556 .desc = "Various certificate name options", 557 .type = OPTION_ARG_FUNC, 558 .opt.argfunc = x509_opt_nameopt, 559 }, 560 { 561 .name = "new", 562 .desc = "Generate a new certificate", 563 .type = OPTION_FLAG, 564 .opt.flag = &cfg.new, 565 }, 566 { 567 .name = "next_serial", 568 .desc = "Print the next serial number", 569 .type = OPTION_ORDER, 570 .opt.order = &cfg.next_serial, 571 .order = &cfg.num, 572 }, 573 { 574 .name = "noout", 575 .desc = "No certificate output", 576 .type = OPTION_ORDER, 577 .opt.order = &cfg.noout, 578 .order = &cfg.num, 579 }, 580 { 581 .name = "ocsp_uri", 582 .desc = "Print OCSP Responder URL(s)", 583 .type = OPTION_ORDER, 584 .opt.order = &cfg.ocsp_uri, 585 .order = &cfg.num, 586 }, 587 { 588 .name = "ocspid", 589 .desc = "Print OCSP hash values for the subject name and public key", 590 .type = OPTION_ORDER, 591 .opt.order = &cfg.ocspid, 592 .order = &cfg.num, 593 }, 594 { 595 .name = "out", 596 .argname = "file", 597 .desc = "Output file - default stdout", 598 .type = OPTION_ARG, 599 .opt.arg = &cfg.outfile, 600 }, 601 { 602 .name = "outform", 603 .argname = "fmt", 604 .desc = "Output format - default PEM (one of DER, NET or PEM)", 605 .type = OPTION_ARG_FORMAT, 606 .opt.value = &cfg.outformat, 607 }, 608 { 609 .name = "passin", 610 .argname = "src", 611 .desc = "Private key password source", 612 .type = OPTION_ARG, 613 .opt.arg = &cfg.passargin, 614 }, 615 { 616 .name = "pubkey", 617 .desc = "Output the public key", 618 .type = OPTION_ORDER, 619 .opt.order = &cfg.pubkey, 620 .order = &cfg.num, 621 }, 622 { 623 .name = "purpose", 624 .desc = "Print out certificate purposes", 625 .type = OPTION_ORDER, 626 .opt.order = &cfg.pprint, 627 .order = &cfg.num, 628 }, 629 { 630 .name = "req", 631 .desc = "Input is a certificate request, sign and output", 632 .type = OPTION_FLAG, 633 .opt.flag = &cfg.reqfile, 634 }, 635 { 636 .name = "serial", 637 .desc = "Print serial number value", 638 .type = OPTION_ORDER, 639 .opt.order = &cfg.serial, 640 .order = &cfg.num, 641 }, 642 { 643 .name = "set_issuer", 644 .argname = "name", 645 .desc = "Set the issuer name", 646 .type = OPTION_ARG, 647 .opt.arg = &cfg.set_issuer, 648 }, 649 { 650 .name = "set_serial", 651 .argname = "n", 652 .desc = "Serial number to use", 653 .type = OPTION_ARG_FUNC, 654 .opt.argfunc = x509_opt_set_serial, 655 }, 656 { 657 .name = "set_subject", 658 .argname = "name", 659 .desc = "Set the subject name", 660 .type = OPTION_ARG, 661 .opt.arg = &cfg.set_subject, 662 }, 663 { 664 .name = "setalias", 665 .argname = "arg", 666 .desc = "Set certificate alias", 667 .type = OPTION_ARG_FUNC, 668 .opt.argfunc = x509_opt_setalias, 669 }, 670 { 671 .name = "signkey", 672 .argname = "file", 673 .desc = "Self sign cert with arg", 674 .type = OPTION_ARG_FUNC, 675 .opt.argfunc = x509_opt_signkey, 676 }, 677 { 678 .name = "sigopt", 679 .argname = "nm:v", 680 .desc = "Various signature algorithm options", 681 .type = OPTION_ARG_FUNC, 682 .opt.argfunc = x509_opt_sigopt, 683 }, 684 { 685 .name = "startdate", 686 .desc = "Print notBefore field", 687 .type = OPTION_ORDER, 688 .opt.order = &cfg.startdate, 689 .order = &cfg.num, 690 }, 691 { 692 .name = "subj", 693 .type = OPTION_ARG, 694 .opt.arg = &cfg.set_subject, 695 }, 696 { 697 .name = "subject", 698 .desc = "Print subject name", 699 .type = OPTION_ORDER, 700 .opt.order = &cfg.subject, 701 .order = &cfg.num, 702 }, 703 { 704 .name = "subject_hash", 705 .desc = "Print subject hash value", 706 .type = OPTION_ORDER, 707 .opt.order = &cfg.subject_hash, 708 .order = &cfg.num, 709 }, 710 #ifndef OPENSSL_NO_MD5 711 { 712 .name = "subject_hash_old", 713 .desc = "Print old-style (MD5) subject hash value", 714 .type = OPTION_ORDER, 715 .opt.order = &cfg.subject_hash_old, 716 .order = &cfg.num, 717 }, 718 #endif 719 { 720 .name = "text", 721 .desc = "Print the certificate in text form", 722 .type = OPTION_ORDER, 723 .opt.order = &cfg.text, 724 .order = &cfg.num, 725 }, 726 { 727 .name = "trustout", 728 .desc = "Output a trusted certificate", 729 .type = OPTION_FLAG, 730 .opt.flag = &cfg.trustout, 731 }, 732 { 733 .name = "utf8", 734 .desc = "Input characters are in UTF-8 (default ASCII)", 735 .type = OPTION_FUNC, 736 .opt.func = x509_opt_utf8, 737 }, 738 { 739 .name = "x509toreq", 740 .desc = "Output a certification request object", 741 .type = OPTION_ORDER, 742 .opt.order = &cfg.x509req, 743 .order = &cfg.num, 744 }, 745 { 746 .name = NULL, 747 .desc = "", 748 .type = OPTION_ARGV_FUNC, 749 .opt.argvfunc = x509_opt_digest, 750 }, 751 { NULL }, 752 }; 753 754 static void 755 x509_usage(void) 756 { 757 fprintf(stderr, "usage: x509 " 758 "[-addreject arg] [-addtrust arg] [-alias] [-CA file]\n" 759 " [-CAcreateserial] [-CAform der | pem] [-CAkey file]\n" 760 " [-CAkeyform der | pem] [-CAserial file] [-certopt option]\n" 761 " [-checkend arg] [-clrext] [-clrreject] [-clrtrust] [-dates]\n" 762 " [-days arg] [-email] [-enddate] [-extensions section]\n" 763 " [-extfile file] [-fingerprint] [-force_pubkey key] [-hash]\n" 764 " [-in file] [-inform der | net | pem] [-issuer]\n" 765 " [-issuer_hash] [-issuer_hash_old] [-keyform der | pem]\n" 766 " [-md5 | -sha1] [-modulus] [-multivalue-rdn]\n" 767 " [-nameopt option] [-new] [-next_serial] [-noout] [-ocsp_uri]\n" 768 " [-ocspid] [-out file] [-outform der | net | pem]\n" 769 " [-passin arg] [-pubkey] [-purpose] [-req] [-serial]\n" 770 " [-set_issuer name] [-set_serial n] [-set_subject name]\n" 771 " [-setalias arg] [-signkey file] [-sigopt nm:v] [-startdate]\n" 772 " [-subject] [-subject_hash] [-subject_hash_old] [-text]\n" 773 " [-trustout] [-utf8] [-x509toreq]\n"); 774 fprintf(stderr, "\n"); 775 options_usage(x509_options); 776 fprintf(stderr, "\n"); 777 } 778 779 int 780 x509_main(int argc, char **argv) 781 { 782 int ret = 1; 783 X509_REQ *req = NULL; 784 X509 *x = NULL, *xca = NULL; 785 X509_NAME *iname = NULL, *sname = NULL; 786 EVP_PKEY *Fpkey = NULL, *Upkey = NULL, *CApkey = NULL; 787 EVP_PKEY *pkey; 788 int i; 789 BIO *out = NULL; 790 BIO *STDout = NULL; 791 X509_STORE *ctx = NULL; 792 X509_REQ *rq = NULL; 793 CONF *extconf = NULL; 794 char *passin = NULL; 795 796 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) { 797 perror("pledge"); 798 exit(1); 799 } 800 801 memset(&cfg, 0, sizeof(cfg)); 802 cfg.chtype = MBSTRING_ASC; 803 cfg.days = DEF_DAYS; 804 cfg.informat = FORMAT_PEM; 805 cfg.outformat = FORMAT_PEM; 806 cfg.keyformat = FORMAT_PEM; 807 cfg.CAformat = FORMAT_PEM; 808 cfg.CAkeyformat = FORMAT_PEM; 809 810 STDout = BIO_new_fp(stdout, BIO_NOCLOSE); 811 812 ctx = X509_STORE_new(); 813 if (ctx == NULL) 814 goto end; 815 X509_STORE_set_verify_cb(ctx, callb); 816 817 if (options_parse(argc, argv, x509_options, NULL, NULL) != 0) 818 goto bad; 819 820 if (cfg.badops) { 821 bad: 822 x509_usage(); 823 goto end; 824 } 825 826 if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) { 827 BIO_printf(bio_err, "Error getting password\n"); 828 goto end; 829 } 830 if (!X509_STORE_set_default_paths(ctx)) { 831 ERR_print_errors(bio_err); 832 goto end; 833 } 834 if (cfg.CAkeyfile == NULL && cfg.CA_flag && cfg.CAformat == FORMAT_PEM) { 835 cfg.CAkeyfile = cfg.CAfile; 836 } else if (cfg.CA_flag && cfg.CAkeyfile == NULL) { 837 BIO_printf(bio_err, 838 "need to specify a CAkey if using the CA command\n"); 839 goto end; 840 } 841 if (cfg.extfile != NULL) { 842 long errorline = -1; 843 X509V3_CTX ctx2; 844 extconf = NCONF_new(NULL); 845 if (!NCONF_load(extconf, cfg.extfile, &errorline)) { 846 if (errorline <= 0) 847 BIO_printf(bio_err, 848 "error loading the config file '%s'\n", 849 cfg.extfile); 850 else 851 BIO_printf(bio_err, 852 "error on line %ld of config file '%s'\n", 853 errorline, cfg.extfile); 854 goto end; 855 } 856 if (cfg.extsect == NULL) { 857 cfg.extsect = NCONF_get_string(extconf, "default", 858 "extensions"); 859 if (cfg.extsect == NULL) { 860 ERR_clear_error(); 861 cfg.extsect = "default"; 862 } 863 } 864 X509V3_set_ctx_test(&ctx2); 865 X509V3_set_nconf(&ctx2, extconf); 866 if (!X509V3_EXT_add_nconf(extconf, &ctx2, cfg.extsect, NULL)) { 867 BIO_printf(bio_err, 868 "Error Loading extension section %s\n", cfg.extsect); 869 ERR_print_errors(bio_err); 870 goto end; 871 } 872 } 873 if (cfg.force_pubkey != NULL) { 874 if ((Fpkey = load_pubkey(bio_err, cfg.force_pubkey, 875 cfg.keyformat, 0, NULL, "Forced key")) == NULL) 876 goto end; 877 } 878 if (cfg.new) { 879 if (cfg.infile != NULL) { 880 BIO_printf(bio_err, "Can't combine -new and -in\n"); 881 goto end; 882 } 883 if (cfg.reqfile) { 884 BIO_printf(bio_err, "Can't combine -new and -req\n"); 885 goto end; 886 } 887 if (cfg.set_subject == NULL) { 888 BIO_printf(bio_err, "Must use -set_subject with -new\n"); 889 goto end; 890 } 891 if (cfg.keyfile == NULL) { 892 BIO_printf(bio_err, "Must use -signkey with -new\n"); 893 goto end; 894 } 895 if ((Upkey = load_key(bio_err, cfg.keyfile, cfg.keyformat, 0, 896 passin, "Private key")) == NULL) 897 goto end; 898 } 899 if (cfg.reqfile) { 900 BIO *in; 901 902 if (!cfg.sign_flag && !cfg.CA_flag) { 903 BIO_printf(bio_err, 904 "We need a private key to sign with\n"); 905 goto end; 906 } 907 in = BIO_new(BIO_s_file()); 908 if (in == NULL) { 909 ERR_print_errors(bio_err); 910 goto end; 911 } 912 if (cfg.infile == NULL) 913 BIO_set_fp(in, stdin, BIO_NOCLOSE | BIO_FP_TEXT); 914 else { 915 if (BIO_read_filename(in, cfg.infile) <= 0) { 916 perror(cfg.infile); 917 BIO_free(in); 918 goto end; 919 } 920 } 921 req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); 922 BIO_free(in); 923 924 if (req == NULL) { 925 ERR_print_errors(bio_err); 926 goto end; 927 } 928 if ((pkey = X509_REQ_get0_pubkey(req)) == NULL) { 929 BIO_printf(bio_err, "error unpacking public key\n"); 930 goto end; 931 } 932 i = X509_REQ_verify(req, pkey); 933 if (i < 0) { 934 BIO_printf(bio_err, "Signature verification error\n"); 935 ERR_print_errors(bio_err); 936 goto end; 937 } 938 if (i == 0) { 939 BIO_printf(bio_err, 940 "Signature did not match the certificate request\n"); 941 goto end; 942 } else 943 BIO_printf(bio_err, "Signature ok\n"); 944 945 print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), 946 cfg.nmflag); 947 948 } 949 if (cfg.reqfile || cfg.new) { 950 if ((x = X509_new()) == NULL) 951 goto end; 952 953 if (cfg.sno == NULL) { 954 cfg.sno = ASN1_INTEGER_new(); 955 if (cfg.sno == NULL || !rand_serial(NULL, cfg.sno)) 956 goto end; 957 if (!X509_set_serialNumber(x, cfg.sno)) 958 goto end; 959 ASN1_INTEGER_free(cfg.sno); 960 cfg.sno = NULL; 961 } else if (!X509_set_serialNumber(x, cfg.sno)) 962 goto end; 963 964 if (cfg.set_issuer != NULL) { 965 iname = parse_name(cfg.set_issuer, cfg.chtype, 966 cfg.multirdn); 967 if (iname == NULL) 968 goto end; 969 } 970 971 if (cfg.set_subject != NULL) 972 sname = parse_name(cfg.set_subject, cfg.chtype, 973 cfg.multirdn); 974 else 975 sname = X509_NAME_dup(X509_REQ_get_subject_name(req)); 976 if (sname == NULL) 977 goto end; 978 if (!X509_set_subject_name(x, sname)) 979 goto end; 980 981 if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL) 982 goto end; 983 if (X509_time_adj_ex(X509_get_notAfter(x), cfg.days, 0, 984 NULL) == NULL) 985 goto end; 986 987 if ((pkey = Fpkey) == NULL) 988 pkey = X509_REQ_get0_pubkey(req); 989 if (pkey == NULL) 990 pkey = Upkey; 991 if (pkey == NULL) 992 goto end; 993 if (!X509_set_pubkey(x, pkey)) 994 goto end; 995 } else { 996 x = load_cert(bio_err, cfg.infile, cfg.informat, NULL, 997 "Certificate"); 998 } 999 if (x == NULL) 1000 goto end; 1001 1002 if (cfg.CA_flag) { 1003 xca = load_cert(bio_err, cfg.CAfile, cfg.CAformat, NULL, 1004 "CA Certificate"); 1005 if (xca == NULL) 1006 goto end; 1007 } 1008 if (!cfg.noout || cfg.text || cfg.next_serial) { 1009 OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3"); 1010 1011 out = BIO_new(BIO_s_file()); 1012 if (out == NULL) { 1013 ERR_print_errors(bio_err); 1014 goto end; 1015 } 1016 if (cfg.outfile == NULL) { 1017 BIO_set_fp(out, stdout, BIO_NOCLOSE); 1018 } else { 1019 if (BIO_write_filename(out, cfg.outfile) <= 0) { 1020 perror(cfg.outfile); 1021 goto end; 1022 } 1023 } 1024 } 1025 if (cfg.alias != NULL) { 1026 if (!X509_alias_set1(x, (unsigned char *)cfg.alias, -1)) 1027 goto end; 1028 } 1029 1030 if (cfg.clrtrust) 1031 X509_trust_clear(x); 1032 if (cfg.clrreject) 1033 X509_reject_clear(x); 1034 1035 if (cfg.trust != NULL) { 1036 for (i = 0; i < sk_ASN1_OBJECT_num(cfg.trust); i++) { 1037 cfg.objtmp = sk_ASN1_OBJECT_value(cfg.trust, i); 1038 if (!X509_add1_trust_object(x, cfg.objtmp)) 1039 goto end; 1040 } 1041 } 1042 if (cfg.reject != NULL) { 1043 for (i = 0; i < sk_ASN1_OBJECT_num(cfg.reject); i++) { 1044 cfg.objtmp = sk_ASN1_OBJECT_value(cfg.reject, i); 1045 if (!X509_add1_reject_object(x, cfg.objtmp)) 1046 goto end; 1047 } 1048 } 1049 if (cfg.num) { 1050 for (i = 1; i <= cfg.num; i++) { 1051 if (cfg.issuer == i) { 1052 print_name(STDout, "issuer= ", 1053 X509_get_issuer_name(x), cfg.nmflag); 1054 } else if (cfg.subject == i) { 1055 print_name(STDout, "subject= ", 1056 X509_get_subject_name(x), cfg.nmflag); 1057 } else if (cfg.serial == i) { 1058 BIO_printf(STDout, "serial="); 1059 i2a_ASN1_INTEGER(STDout, 1060 X509_get_serialNumber(x)); 1061 BIO_printf(STDout, "\n"); 1062 } else if (cfg.next_serial == i) { 1063 BIGNUM *bnser; 1064 ASN1_INTEGER *ser; 1065 1066 ser = X509_get_serialNumber(x); 1067 if (ser == NULL) 1068 goto end; 1069 bnser = ASN1_INTEGER_to_BN(ser, NULL); 1070 if (bnser == NULL) 1071 goto end; 1072 if (!BN_add_word(bnser, 1)) { 1073 BN_free(bnser); 1074 goto end; 1075 } 1076 ser = BN_to_ASN1_INTEGER(bnser, NULL); 1077 if (ser == NULL) { 1078 BN_free(bnser); 1079 goto end; 1080 } 1081 BN_free(bnser); 1082 i2a_ASN1_INTEGER(out, ser); 1083 ASN1_INTEGER_free(ser); 1084 BIO_puts(out, "\n"); 1085 } else if (cfg.email == i || cfg.ocsp_uri == i) { 1086 STACK_OF(OPENSSL_STRING) *emlst; 1087 int j; 1088 1089 if (cfg.email == i) 1090 emlst = X509_get1_email(x); 1091 else 1092 emlst = X509_get1_ocsp(x); 1093 for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) 1094 BIO_printf(STDout, "%s\n", 1095 sk_OPENSSL_STRING_value(emlst, j)); 1096 X509_email_free(emlst); 1097 } else if (cfg.aliasout == i) { 1098 unsigned char *albuf; 1099 int buflen; 1100 albuf = X509_alias_get0(x, &buflen); 1101 if (albuf != NULL) 1102 BIO_printf(STDout, "%.*s\n", 1103 buflen, albuf); 1104 else 1105 BIO_puts(STDout, "<No Alias>\n"); 1106 } else if (cfg.subject_hash == i) { 1107 BIO_printf(STDout, "%08lx\n", 1108 X509_subject_name_hash(x)); 1109 } 1110 #ifndef OPENSSL_NO_MD5 1111 else if (cfg.subject_hash_old == i) { 1112 BIO_printf(STDout, "%08lx\n", 1113 X509_subject_name_hash_old(x)); 1114 } 1115 #endif 1116 else if (cfg.issuer_hash == i) { 1117 BIO_printf(STDout, "%08lx\n", 1118 X509_issuer_name_hash(x)); 1119 } 1120 #ifndef OPENSSL_NO_MD5 1121 else if (cfg.issuer_hash_old == i) { 1122 BIO_printf(STDout, "%08lx\n", 1123 X509_issuer_name_hash_old(x)); 1124 } 1125 #endif 1126 else if (cfg.pprint == i) { 1127 const X509_PURPOSE *ptmp; 1128 int j; 1129 1130 BIO_printf(STDout, "Certificate purposes:\n"); 1131 for (j = 0; j < X509_PURPOSE_get_count(); j++) { 1132 ptmp = X509_PURPOSE_get0(j); 1133 purpose_print(STDout, x, ptmp); 1134 } 1135 } else if (cfg.modulus == i) { 1136 EVP_PKEY *pubkey; 1137 1138 if ((pubkey = X509_get0_pubkey(x)) == NULL) { 1139 BIO_printf(bio_err, 1140 "Modulus=unavailable\n"); 1141 ERR_print_errors(bio_err); 1142 goto end; 1143 } 1144 BIO_printf(STDout, "Modulus="); 1145 if (EVP_PKEY_id(pubkey) == EVP_PKEY_RSA) { 1146 RSA *rsa = EVP_PKEY_get0_RSA(pubkey); 1147 const BIGNUM *n = NULL; 1148 1149 RSA_get0_key(rsa, &n, NULL, NULL); 1150 BN_print(STDout, n); 1151 } else if (EVP_PKEY_id(pubkey) == EVP_PKEY_DSA) { 1152 DSA *dsa = EVP_PKEY_get0_DSA(pubkey); 1153 const BIGNUM *dsa_pub_key = NULL; 1154 1155 DSA_get0_key(dsa, &dsa_pub_key, NULL); 1156 1157 BN_print(STDout, dsa_pub_key); 1158 } else 1159 BIO_printf(STDout, 1160 "Wrong Algorithm type"); 1161 BIO_printf(STDout, "\n"); 1162 } else if (cfg.pubkey == i) { 1163 EVP_PKEY *pubkey; 1164 1165 if ((pubkey = X509_get0_pubkey(x)) == NULL) { 1166 BIO_printf(bio_err, 1167 "Error getting public key\n"); 1168 ERR_print_errors(bio_err); 1169 goto end; 1170 } 1171 PEM_write_bio_PUBKEY(STDout, pubkey); 1172 } else if (cfg.text == i) { 1173 if(!X509_print_ex(STDout, x, cfg.nmflag, 1174 cfg.certflag)) 1175 goto end; 1176 } else if (cfg.startdate == i) { 1177 ASN1_TIME *nB = X509_get_notBefore(x); 1178 1179 BIO_puts(STDout, "notBefore="); 1180 if (!ASN1_TIME_to_tm(nB, NULL)) 1181 BIO_puts(STDout, 1182 "INVALID RFC5280 TIME"); 1183 else 1184 ASN1_TIME_print(STDout, nB); 1185 BIO_puts(STDout, "\n"); 1186 } else if (cfg.enddate == i) { 1187 ASN1_TIME *nA = X509_get_notAfter(x); 1188 1189 BIO_puts(STDout, "notAfter="); 1190 if (!ASN1_TIME_to_tm(nA, NULL)) 1191 BIO_puts(STDout, 1192 "INVALID RFC5280 TIME"); 1193 else 1194 ASN1_TIME_print(STDout, nA); 1195 BIO_puts(STDout, "\n"); 1196 } else if (cfg.fingerprint == i) { 1197 int j; 1198 unsigned int n; 1199 unsigned char md[EVP_MAX_MD_SIZE]; 1200 const EVP_MD *fdig = cfg.digest; 1201 1202 if (fdig == NULL) 1203 fdig = EVP_sha256(); 1204 1205 if (!X509_digest(x, fdig, md, &n)) { 1206 BIO_printf(bio_err, "out of memory\n"); 1207 goto end; 1208 } 1209 BIO_printf(STDout, "%s Fingerprint=", 1210 OBJ_nid2sn(EVP_MD_type(fdig))); 1211 for (j = 0; j < (int) n; j++) { 1212 BIO_printf(STDout, "%02X%c", md[j], 1213 (j + 1 == (int)n) ? '\n' : ':'); 1214 } 1215 } else if (cfg.sign_flag == i && cfg.x509req == 0) { 1216 if (Upkey == NULL) { 1217 Upkey = load_key(bio_err, cfg.keyfile, 1218 cfg.keyformat, 0, passin, 1219 "Private key"); 1220 if (Upkey == NULL) 1221 goto end; 1222 } 1223 if (!sign(x, Upkey, cfg.days, 1224 cfg.clrext, cfg.digest, 1225 extconf, cfg.extsect, iname, 1226 cfg.force_pubkey)) 1227 goto end; 1228 } else if (cfg.CA_flag == i) { 1229 if (cfg.CAkeyfile != NULL) { 1230 CApkey = load_key(bio_err, cfg.CAkeyfile, 1231 cfg.CAkeyformat, 0, passin, 1232 "CA Private Key"); 1233 if (CApkey == NULL) 1234 goto end; 1235 } 1236 if (!x509_certify(ctx, cfg.CAfile, cfg.digest, 1237 x, xca, CApkey, cfg.sigopts, cfg.CAserial, 1238 cfg.CA_createserial, cfg.days, cfg.clrext, 1239 extconf, cfg.extsect, cfg.sno, iname)) 1240 goto end; 1241 } else if (cfg.x509req == i) { 1242 EVP_PKEY *pk; 1243 1244 BIO_printf(bio_err, 1245 "Getting request Private Key\n"); 1246 if (cfg.keyfile == NULL) { 1247 BIO_printf(bio_err, 1248 "no request key file specified\n"); 1249 goto end; 1250 } else { 1251 pk = load_key(bio_err, cfg.keyfile, 1252 cfg.keyformat, 0, passin, 1253 "request key"); 1254 if (pk == NULL) 1255 goto end; 1256 } 1257 1258 BIO_printf(bio_err, 1259 "Generating certificate request\n"); 1260 1261 rq = X509_to_X509_REQ(x, pk, cfg.digest); 1262 EVP_PKEY_free(pk); 1263 if (rq == NULL) { 1264 ERR_print_errors(bio_err); 1265 goto end; 1266 } 1267 if (!cfg.noout) { 1268 if (!X509_REQ_print(out, rq)) 1269 goto end; 1270 if (!PEM_write_bio_X509_REQ(out, rq)) 1271 goto end; 1272 } 1273 cfg.noout = 1; 1274 } else if (cfg.ocspid == i) { 1275 if (!X509_ocspid_print(out, x)) 1276 goto end; 1277 } 1278 } 1279 } 1280 if (cfg.checkend) { 1281 time_t tcheck = time(NULL) + cfg.checkoffset; 1282 int timecheck = X509_cmp_time(X509_get_notAfter(x), &tcheck); 1283 if (timecheck == 0) { 1284 BIO_printf(out, "Certificate expiry time is invalid\n"); 1285 ret = 1; 1286 } else if (timecheck < 0) { 1287 BIO_printf(out, "Certificate will expire\n"); 1288 ret = 1; 1289 } else { 1290 BIO_printf(out, "Certificate will not expire\n"); 1291 ret = 0; 1292 } 1293 goto end; 1294 } 1295 if (cfg.noout) { 1296 ret = 0; 1297 goto end; 1298 } 1299 if (cfg.outformat == FORMAT_ASN1) 1300 i = i2d_X509_bio(out, x); 1301 else if (cfg.outformat == FORMAT_PEM) { 1302 if (cfg.trustout) 1303 i = PEM_write_bio_X509_AUX(out, x); 1304 else 1305 i = PEM_write_bio_X509(out, x); 1306 } else { 1307 BIO_printf(bio_err, 1308 "bad output format specified for outfile\n"); 1309 goto end; 1310 } 1311 if (!i) { 1312 BIO_printf(bio_err, "unable to write certificate\n"); 1313 ERR_print_errors(bio_err); 1314 goto end; 1315 } 1316 ret = 0; 1317 1318 end: 1319 OBJ_cleanup(); 1320 NCONF_free(extconf); 1321 BIO_free_all(out); 1322 BIO_free_all(STDout); 1323 X509_NAME_free(iname); 1324 X509_NAME_free(sname); 1325 X509_STORE_free(ctx); 1326 X509_REQ_free(req); 1327 X509_free(x); 1328 X509_free(xca); 1329 EVP_PKEY_free(Fpkey); 1330 EVP_PKEY_free(Upkey); 1331 EVP_PKEY_free(CApkey); 1332 sk_OPENSSL_STRING_free(cfg.sigopts); 1333 X509_REQ_free(rq); 1334 ASN1_INTEGER_free(cfg.sno); 1335 sk_ASN1_OBJECT_pop_free(cfg.trust, ASN1_OBJECT_free); 1336 sk_ASN1_OBJECT_pop_free(cfg.reject, ASN1_OBJECT_free); 1337 free(passin); 1338 1339 return (ret); 1340 } 1341 1342 static ASN1_INTEGER * 1343 x509_load_serial(char *CAfile, char *serialfile, int create) 1344 { 1345 char *buf = NULL, *p; 1346 ASN1_INTEGER *bs = NULL; 1347 BIGNUM *serial = NULL; 1348 size_t len; 1349 1350 len = ((serialfile == NULL) ? (strlen(CAfile) + strlen(POSTFIX) + 1) : 1351 (strlen(serialfile))) + 1; 1352 buf = malloc(len); 1353 if (buf == NULL) { 1354 BIO_printf(bio_err, "out of mem\n"); 1355 goto end; 1356 } 1357 if (serialfile == NULL) { 1358 strlcpy(buf, CAfile, len); 1359 for (p = buf; *p; p++) 1360 if (*p == '.') { 1361 *p = '\0'; 1362 break; 1363 } 1364 strlcat(buf, POSTFIX, len); 1365 } else 1366 strlcpy(buf, serialfile, len); 1367 1368 serial = load_serial(buf, create, NULL); 1369 if (serial == NULL) 1370 goto end; 1371 1372 if (!BN_add_word(serial, 1)) { 1373 BIO_printf(bio_err, "add_word failure\n"); 1374 goto end; 1375 } 1376 if (!save_serial(buf, NULL, serial, &bs)) 1377 goto end; 1378 1379 end: 1380 free(buf); 1381 BN_free(serial); 1382 1383 return bs; 1384 } 1385 1386 static int 1387 x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, X509 *x, 1388 X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts, 1389 char *serialfile, int create, int days, int clrext, CONF *conf, 1390 char *section, ASN1_INTEGER *sno, X509_NAME *issuer) 1391 { 1392 int ret = 0; 1393 ASN1_INTEGER *bs = NULL; 1394 X509_STORE_CTX *xsc = NULL; 1395 EVP_PKEY *upkey; 1396 1397 upkey = X509_get0_pubkey(xca); 1398 if (upkey == NULL) 1399 goto end; 1400 EVP_PKEY_copy_parameters(upkey, pkey); 1401 1402 if ((xsc = X509_STORE_CTX_new()) == NULL) 1403 goto end; 1404 if (!X509_STORE_CTX_init(xsc, ctx, x, NULL)) { 1405 BIO_printf(bio_err, "Error initialising X509 store\n"); 1406 goto end; 1407 } 1408 if (sno != NULL) 1409 bs = sno; 1410 else if ((bs = x509_load_serial(CAfile, serialfile, create)) == NULL) 1411 goto end; 1412 1413 /* if (!X509_STORE_add_cert(ctx,x)) goto end;*/ 1414 1415 /* 1416 * NOTE: this certificate can/should be self signed, unless it was a 1417 * certificate request in which case it is not. 1418 */ 1419 X509_STORE_CTX_set_cert(xsc, x); 1420 X509_STORE_CTX_set_flags(xsc, X509_V_FLAG_CHECK_SS_SIGNATURE); 1421 if (!cfg.reqfile && X509_verify_cert(xsc) <= 0) 1422 goto end; 1423 1424 if (!X509_check_private_key(xca, pkey)) { 1425 BIO_printf(bio_err, 1426 "CA certificate and CA private key do not match\n"); 1427 goto end; 1428 } 1429 1430 if (issuer == NULL) 1431 issuer = X509_get_subject_name(xca); 1432 if (issuer == NULL) 1433 goto end; 1434 if (!X509_set_issuer_name(x, issuer)) 1435 goto end; 1436 1437 if (!X509_set_serialNumber(x, bs)) 1438 goto end; 1439 1440 if (X509_gmtime_adj(X509_get_notBefore(x), 0L) == NULL) 1441 goto end; 1442 1443 /* hardwired expired */ 1444 if (X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL) == NULL) 1445 goto end; 1446 1447 if (clrext) { 1448 while (X509_get_ext_count(x) > 0) { 1449 if (X509_delete_ext(x, 0) == NULL) 1450 goto end; 1451 } 1452 } 1453 if (conf != NULL) { 1454 X509V3_CTX ctx2; 1455 if (!X509_set_version(x, 2)) /* version 3 certificate */ 1456 goto end; 1457 X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0); 1458 X509V3_set_nconf(&ctx2, conf); 1459 if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) 1460 goto end; 1461 } 1462 if (!do_X509_sign(bio_err, x, pkey, digest, sigopts)) 1463 goto end; 1464 1465 ret = 1; 1466 end: 1467 X509_STORE_CTX_free(xsc); 1468 if (!ret) 1469 ERR_print_errors(bio_err); 1470 if (sno == NULL) 1471 ASN1_INTEGER_free(bs); 1472 return ret; 1473 } 1474 1475 static int 1476 callb(int ok, X509_STORE_CTX *ctx) 1477 { 1478 int err; 1479 X509 *err_cert; 1480 1481 /* 1482 * it is ok to use a self signed certificate This case will catch 1483 * both the initial ok == 0 and the final ok == 1 calls to this 1484 * function 1485 */ 1486 err = X509_STORE_CTX_get_error(ctx); 1487 if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) 1488 return 1; 1489 1490 /* 1491 * BAD we should have gotten an error. Normally if everything worked 1492 * X509_STORE_CTX_get_error(ctx) will still be set to 1493 * DEPTH_ZERO_SELF_.... 1494 */ 1495 if (ok) { 1496 BIO_printf(bio_err, 1497 "error with certificate to be certified - should be self signed\n"); 1498 return 0; 1499 } else { 1500 err_cert = X509_STORE_CTX_get_current_cert(ctx); 1501 print_name(bio_err, NULL, X509_get_subject_name(err_cert), 0); 1502 BIO_printf(bio_err, 1503 "error with certificate - error %d at depth %d\n%s\n", 1504 err, X509_STORE_CTX_get_error_depth(ctx), 1505 X509_verify_cert_error_string(err)); 1506 return 1; 1507 } 1508 } 1509 1510 static int 1511 key_identifier_hash(EVP_PKEY *pkey, unsigned char *md, unsigned int *md_len) 1512 { 1513 X509_PUBKEY *x509_pubkey = NULL; 1514 const unsigned char *der; 1515 int der_len; 1516 int ret = 0; 1517 1518 if (*md_len < SHA_DIGEST_LENGTH) 1519 goto err; 1520 1521 if (!X509_PUBKEY_set(&x509_pubkey, pkey)) 1522 goto err; 1523 if (!X509_PUBKEY_get0_param(NULL, &der, &der_len, NULL, x509_pubkey)) 1524 goto err; 1525 if (!EVP_Digest(der, der_len, md, md_len, EVP_sha1(), NULL)) 1526 goto err; 1527 1528 ret = 1; 1529 1530 err: 1531 X509_PUBKEY_free(x509_pubkey); 1532 1533 return ret; 1534 } 1535 1536 static ASN1_OCTET_STRING * 1537 compute_key_identifier(EVP_PKEY *pkey) 1538 { 1539 ASN1_OCTET_STRING *ki = NULL; 1540 unsigned char md[EVP_MAX_MD_SIZE]; 1541 unsigned int md_len = EVP_MAX_MD_SIZE; 1542 1543 if (!key_identifier_hash(pkey, md, &md_len)) 1544 goto err; 1545 1546 if ((ki = ASN1_OCTET_STRING_new()) == NULL) 1547 goto err; 1548 if (!ASN1_STRING_set(ki, md, md_len)) 1549 goto err; 1550 1551 return ki; 1552 1553 err: 1554 ASN1_OCTET_STRING_free(ki); 1555 1556 return NULL; 1557 } 1558 1559 static ASN1_OCTET_STRING * 1560 compute_subject_key_identifier(EVP_PKEY *subject_key) 1561 { 1562 return compute_key_identifier(subject_key); 1563 } 1564 1565 static AUTHORITY_KEYID * 1566 compute_authority_key_identifier(EVP_PKEY *issuer_key) 1567 { 1568 AUTHORITY_KEYID *aki = NULL; 1569 1570 if ((aki = AUTHORITY_KEYID_new()) == NULL) 1571 goto err; 1572 if ((aki->keyid = compute_key_identifier(issuer_key)) == NULL) 1573 goto err; 1574 1575 return aki; 1576 1577 err: 1578 AUTHORITY_KEYID_free(aki); 1579 1580 return NULL; 1581 } 1582 1583 static int 1584 set_key_identifiers(X509 *cert, EVP_PKEY *issuer_key) 1585 { 1586 EVP_PKEY *subject_key; 1587 ASN1_OCTET_STRING *ski = NULL; 1588 AUTHORITY_KEYID *aki = NULL; 1589 int ret = 0; 1590 1591 if ((subject_key = X509_get0_pubkey(cert)) == NULL) 1592 goto err; 1593 1594 if ((ski = compute_subject_key_identifier(subject_key)) == NULL) 1595 goto err; 1596 if (!X509_add1_ext_i2d(cert, NID_subject_key_identifier, ski, 0, 1597 X509V3_ADD_REPLACE)) 1598 goto err; 1599 1600 /* 1601 * Historical OpenSSL behavior: don't set AKI if we're self-signing. 1602 * RFC 5280 says we MAY omit it, so this is ok. 1603 */ 1604 if (EVP_PKEY_cmp(subject_key, issuer_key) == 1) 1605 goto done; 1606 1607 if ((aki = compute_authority_key_identifier(issuer_key)) == NULL) 1608 goto err; 1609 if (!X509_add1_ext_i2d(cert, NID_authority_key_identifier, aki, 0, 1610 X509V3_ADD_REPLACE)) 1611 goto err; 1612 1613 done: 1614 ret = 1; 1615 1616 err: 1617 ASN1_OCTET_STRING_free(ski); 1618 AUTHORITY_KEYID_free(aki); 1619 1620 return ret; 1621 } 1622 1623 static int 1624 sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, 1625 CONF *conf, char *section, X509_NAME *issuer, char *force_pubkey) 1626 { 1627 EVP_PKEY *pktmp; 1628 1629 pktmp = X509_get0_pubkey(x); 1630 if (pktmp == NULL) 1631 goto err; 1632 EVP_PKEY_copy_parameters(pktmp, pkey); 1633 EVP_PKEY_save_parameters(pktmp, 1); 1634 1635 if (issuer == NULL) 1636 issuer = X509_get_subject_name(x); 1637 if (issuer == NULL) 1638 goto err; 1639 if (!X509_set_issuer_name(x, issuer)) 1640 goto err; 1641 if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL) 1642 goto err; 1643 1644 if (X509_gmtime_adj(X509_get_notAfter(x), 60L * 60 * 24 * days) == NULL) 1645 goto err; 1646 1647 if (force_pubkey == NULL) { 1648 if (!X509_set_pubkey(x, pkey)) 1649 goto err; 1650 } 1651 if (clrext) { 1652 while (X509_get_ext_count(x) > 0) { 1653 if (X509_delete_ext(x, 0) == NULL) 1654 goto err; 1655 } 1656 } 1657 if (conf != NULL) { 1658 X509V3_CTX ctx; 1659 1660 if (!X509_set_version(x, 2)) /* version 3 certificate */ 1661 goto err; 1662 X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0); 1663 X509V3_set_nconf(&ctx, conf); 1664 if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) 1665 goto err; 1666 if (force_pubkey != NULL) { 1667 /* 1668 * Set or fix up SKI and AKI. 1669 * 1670 * XXX - Doing this in a fully OpenSSL 3 compatible way 1671 * is extremely nasty: they hang an issuer_pubkey off 1672 * the X509V3_CTX and adjusted v2i_AUTHORITY_KEYID(). 1673 * Punt on this and make things work in the specific 1674 * situation we're interested in. Like OpenSSL, we only 1675 * support the keyid form of the AKI, which is what 1676 * RFC 5280 recommends, but unlike OpenSSL we replace 1677 * existing SKI and AKI rather than honoring the most 1678 * likely outdated ones already present in the cert. 1679 */ 1680 if (!set_key_identifiers(x, pkey)) 1681 goto err; 1682 } 1683 } 1684 if (!X509_sign(x, pkey, digest)) 1685 goto err; 1686 1687 return 1; 1688 1689 err: 1690 ERR_print_errors(bio_err); 1691 return 0; 1692 } 1693 1694 static int 1695 purpose_print(BIO *bio, X509 *cert, const X509_PURPOSE *pt) 1696 { 1697 int id, i, idret; 1698 const char *pname; 1699 1700 id = X509_PURPOSE_get_id(pt); 1701 pname = X509_PURPOSE_get0_name(pt); 1702 for (i = 0; i < 2; i++) { 1703 idret = X509_check_purpose(cert, id, i); 1704 BIO_printf(bio, "%s%s : ", pname, i ? " CA" : ""); 1705 if (idret == 1) 1706 BIO_printf(bio, "Yes\n"); 1707 else if (idret == 0) 1708 BIO_printf(bio, "No\n"); 1709 else 1710 BIO_printf(bio, "Yes (WARNING code=%d)\n", idret); 1711 } 1712 return 1; 1713 } 1714