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