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