diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/usr.bin/openssl/req.c | 136 |
1 files changed, 133 insertions, 3 deletions
diff --git a/src/usr.bin/openssl/req.c b/src/usr.bin/openssl/req.c index 6b7dfb98b9..29a47cbfed 100644 --- a/src/usr.bin/openssl/req.c +++ b/src/usr.bin/openssl/req.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: req.c,v 1.16 2019/07/03 03:24:02 deraadt Exp $ */ | 1 | /* $OpenBSD: req.c,v 1.17 2019/11/06 10:35:40 inoguchi Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -62,9 +62,10 @@ | |||
| 62 | #undef OPENSSL_NO_DEPRECATED | 62 | #undef OPENSSL_NO_DEPRECATED |
| 63 | #endif | 63 | #endif |
| 64 | 64 | ||
| 65 | #include <ctype.h> | ||
| 66 | #include <limits.h> | ||
| 65 | #include <stdio.h> | 67 | #include <stdio.h> |
| 66 | #include <stdlib.h> | 68 | #include <stdlib.h> |
| 67 | #include <limits.h> | ||
| 68 | #include <string.h> | 69 | #include <string.h> |
| 69 | #include <time.h> | 70 | #include <time.h> |
| 70 | 71 | ||
| @@ -141,7 +142,12 @@ static int req_check_len(int len, int n_min, int n_max); | |||
| 141 | static int check_end(const char *str, const char *end); | 142 | static int check_end(const char *str, const char *end); |
| 142 | static EVP_PKEY_CTX *set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type, | 143 | static EVP_PKEY_CTX *set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type, |
| 143 | long *pkeylen, char **palgnam); | 144 | long *pkeylen, char **palgnam); |
| 145 | static unsigned long ext_name_hash(const OPENSSL_STRING *a); | ||
| 146 | static int ext_name_cmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b); | ||
| 147 | static void exts_cleanup(OPENSSL_STRING *x); | ||
| 148 | static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv); | ||
| 144 | static CONF *req_conf = NULL; | 149 | static CONF *req_conf = NULL; |
| 150 | static CONF *addext_conf = NULL; | ||
| 145 | static int batch = 0; | 151 | static int batch = 0; |
| 146 | 152 | ||
| 147 | int | 153 | int |
| @@ -155,6 +161,7 @@ req_main(int argc, char **argv) | |||
| 155 | const char *keyalg = NULL; | 161 | const char *keyalg = NULL; |
| 156 | char *keyalgstr = NULL; | 162 | char *keyalgstr = NULL; |
| 157 | STACK_OF(OPENSSL_STRING) * pkeyopts = NULL, *sigopts = NULL; | 163 | STACK_OF(OPENSSL_STRING) * pkeyopts = NULL, *sigopts = NULL; |
| 164 | LHASH_OF(OPENSSL_STRING) *addexts = NULL; | ||
| 158 | EVP_PKEY *pkey = NULL; | 165 | EVP_PKEY *pkey = NULL; |
| 159 | int i = 0, badops = 0, newreq = 0, verbose = 0, pkey_type = -1; | 166 | int i = 0, badops = 0, newreq = 0, verbose = 0, pkey_type = -1; |
| 160 | long newkey = -1; | 167 | long newkey = -1; |
| @@ -163,6 +170,7 @@ req_main(int argc, char **argv) | |||
| 163 | int nodes = 0, kludge = 0, newhdr = 0, subject = 0, pubkey = 0; | 170 | int nodes = 0, kludge = 0, newhdr = 0, subject = 0, pubkey = 0; |
| 164 | char *infile, *outfile, *prog, *keyfile = NULL, *template = NULL, | 171 | char *infile, *outfile, *prog, *keyfile = NULL, *template = NULL, |
| 165 | *keyout = NULL; | 172 | *keyout = NULL; |
| 173 | BIO *addext_bio = NULL; | ||
| 166 | char *extensions = NULL; | 174 | char *extensions = NULL; |
| 167 | char *req_exts = NULL; | 175 | char *req_exts = NULL; |
| 168 | const EVP_CIPHER *cipher = NULL; | 176 | const EVP_CIPHER *cipher = NULL; |
| @@ -319,6 +327,23 @@ req_main(int argc, char **argv) | |||
| 319 | serial = s2i_ASN1_INTEGER(NULL, *(++argv)); | 327 | serial = s2i_ASN1_INTEGER(NULL, *(++argv)); |
| 320 | if (!serial) | 328 | if (!serial) |
| 321 | goto bad; | 329 | goto bad; |
| 330 | } else if (strcmp(*argv, "-addext") == 0) { | ||
| 331 | if (--argc < 1) | ||
| 332 | goto bad; | ||
| 333 | p = *(++argv); | ||
| 334 | if (addexts == NULL) { | ||
| 335 | addexts = (LHASH_OF(OPENSSL_STRING) *)lh_new( | ||
| 336 | (LHASH_HASH_FN_TYPE)ext_name_hash, | ||
| 337 | (LHASH_COMP_FN_TYPE)ext_name_cmp); | ||
| 338 | addext_bio = BIO_new(BIO_s_mem()); | ||
| 339 | if (addexts == NULL || addext_bio == NULL) | ||
| 340 | goto bad; | ||
| 341 | } | ||
| 342 | i = duplicated(addexts, p); | ||
| 343 | if (i == 1) | ||
| 344 | goto bad; | ||
| 345 | if (i < 0 || BIO_printf(addext_bio, "%s\n", p) < 0) | ||
| 346 | goto bad; | ||
| 322 | } else if (strcmp(*argv, "-extensions") == 0) { | 347 | } else if (strcmp(*argv, "-extensions") == 0) { |
| 323 | if (--argc < 1) | 348 | if (--argc < 1) |
| 324 | goto bad; | 349 | goto bad; |
| @@ -373,6 +398,7 @@ req_main(int argc, char **argv) | |||
| 373 | BIO_printf(bio_err, " -newhdr output \"NEW\" in the header lines\n"); | 398 | BIO_printf(bio_err, " -newhdr output \"NEW\" in the header lines\n"); |
| 374 | BIO_printf(bio_err, " -asn1-kludge Output the 'request' in a format that is wrong but some CA's\n"); | 399 | BIO_printf(bio_err, " -asn1-kludge Output the 'request' in a format that is wrong but some CA's\n"); |
| 375 | BIO_printf(bio_err, " have been reported as requiring\n"); | 400 | BIO_printf(bio_err, " have been reported as requiring\n"); |
| 401 | BIO_printf(bio_err, " -addext .. additional cert extension key=value pair (may be given more than once)\n"); | ||
| 376 | BIO_printf(bio_err, " -extensions .. specify certificate extension section (override value in config file)\n"); | 402 | BIO_printf(bio_err, " -extensions .. specify certificate extension section (override value in config file)\n"); |
| 377 | BIO_printf(bio_err, " -reqexts .. specify request extension section (override value in config file)\n"); | 403 | BIO_printf(bio_err, " -reqexts .. specify request extension section (override value in config file)\n"); |
| 378 | BIO_printf(bio_err, " -utf8 input characters are UTF8 (default ASCII)\n"); | 404 | BIO_printf(bio_err, " -utf8 input characters are UTF8 (default ASCII)\n"); |
| @@ -408,6 +434,21 @@ req_main(int argc, char **argv) | |||
| 408 | default_config_file); | 434 | default_config_file); |
| 409 | } | 435 | } |
| 410 | 436 | ||
| 437 | if (addext_bio != NULL) { | ||
| 438 | long errline = -1; | ||
| 439 | if (verbose) | ||
| 440 | BIO_printf(bio_err, | ||
| 441 | "Using additional configuration from command line\n"); | ||
| 442 | addext_conf = NCONF_new(NULL); | ||
| 443 | i = NCONF_load_bio(addext_conf, addext_bio, &errline); | ||
| 444 | if (i == 0) { | ||
| 445 | BIO_printf(bio_err, | ||
| 446 | "req: Error on line %ld of config input\n", | ||
| 447 | errline); | ||
| 448 | goto end; | ||
| 449 | } | ||
| 450 | } | ||
| 451 | |||
| 411 | if (req_conf != NULL) { | 452 | if (req_conf != NULL) { |
| 412 | if (!load_config(bio_err, req_conf)) | 453 | if (!load_config(bio_err, req_conf)) |
| 413 | goto end; | 454 | goto end; |
| @@ -457,6 +498,17 @@ req_main(int argc, char **argv) | |||
| 457 | goto end; | 498 | goto end; |
| 458 | } | 499 | } |
| 459 | } | 500 | } |
| 501 | if (addext_conf != NULL) { | ||
| 502 | /* Check syntax of command line extensions */ | ||
| 503 | X509V3_CTX ctx; | ||
| 504 | X509V3_set_ctx_test(&ctx); | ||
| 505 | X509V3_set_nconf(&ctx, addext_conf); | ||
| 506 | if (!X509V3_EXT_add_nconf(addext_conf, &ctx, "default", NULL)) { | ||
| 507 | BIO_printf(bio_err, | ||
| 508 | "Error Loading command line extensions\n"); | ||
| 509 | goto end; | ||
| 510 | } | ||
| 511 | } | ||
| 460 | if (!passin) { | 512 | if (!passin) { |
| 461 | passin = NCONF_get_string(req_conf, SECTION, "input_password"); | 513 | passin = NCONF_get_string(req_conf, SECTION, "input_password"); |
| 462 | if (!passin) | 514 | if (!passin) |
| @@ -660,7 +712,8 @@ req_main(int argc, char **argv) | |||
| 660 | goto end; | 712 | goto end; |
| 661 | 713 | ||
| 662 | /* Set version to V3 */ | 714 | /* Set version to V3 */ |
| 663 | if (extensions && !X509_set_version(x509ss, 2)) | 715 | if ((extensions != NULL || addext_conf != NULL) && |
| 716 | !X509_set_version(x509ss, 2)) | ||
| 664 | goto end; | 717 | goto end; |
| 665 | if (serial) { | 718 | if (serial) { |
| 666 | if (!X509_set_serialNumber(x509ss, serial)) | 719 | if (!X509_set_serialNumber(x509ss, serial)) |
| @@ -697,6 +750,13 @@ req_main(int argc, char **argv) | |||
| 697 | extensions); | 750 | extensions); |
| 698 | goto end; | 751 | goto end; |
| 699 | } | 752 | } |
| 753 | if (addext_conf != NULL && | ||
| 754 | !X509V3_EXT_add_nconf(addext_conf, &ext_ctx, | ||
| 755 | "default", x509ss)) { | ||
| 756 | BIO_printf(bio_err, | ||
| 757 | "Error Loading command line extensions\n"); | ||
| 758 | goto end; | ||
| 759 | } | ||
| 700 | i = do_X509_sign(bio_err, x509ss, pkey, digest, sigopts); | 760 | i = do_X509_sign(bio_err, x509ss, pkey, digest, sigopts); |
| 701 | if (!i) { | 761 | if (!i) { |
| 702 | ERR_print_errors(bio_err); | 762 | ERR_print_errors(bio_err); |
| @@ -718,6 +778,13 @@ req_main(int argc, char **argv) | |||
| 718 | req_exts); | 778 | req_exts); |
| 719 | goto end; | 779 | goto end; |
| 720 | } | 780 | } |
| 781 | if (addext_conf != NULL && | ||
| 782 | !X509V3_EXT_REQ_add_nconf(addext_conf, &ext_ctx, | ||
| 783 | "default", req)) { | ||
| 784 | BIO_printf(bio_err, | ||
| 785 | "Error Loading command line extensions\n"); | ||
| 786 | goto end; | ||
| 787 | } | ||
| 721 | i = do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts); | 788 | i = do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts); |
| 722 | if (!i) { | 789 | if (!i) { |
| 723 | ERR_print_errors(bio_err); | 790 | ERR_print_errors(bio_err); |
| @@ -864,6 +931,8 @@ req_main(int argc, char **argv) | |||
| 864 | } | 931 | } |
| 865 | if ((req_conf != NULL) && (req_conf != config)) | 932 | if ((req_conf != NULL) && (req_conf != config)) |
| 866 | NCONF_free(req_conf); | 933 | NCONF_free(req_conf); |
| 934 | NCONF_free(addext_conf); | ||
| 935 | BIO_free(addext_bio); | ||
| 867 | BIO_free(in); | 936 | BIO_free(in); |
| 868 | BIO_free_all(out); | 937 | BIO_free_all(out); |
| 869 | EVP_PKEY_free(pkey); | 938 | EVP_PKEY_free(pkey); |
| @@ -873,6 +942,8 @@ req_main(int argc, char **argv) | |||
| 873 | sk_OPENSSL_STRING_free(pkeyopts); | 942 | sk_OPENSSL_STRING_free(pkeyopts); |
| 874 | if (sigopts) | 943 | if (sigopts) |
| 875 | sk_OPENSSL_STRING_free(sigopts); | 944 | sk_OPENSSL_STRING_free(sigopts); |
| 945 | lh_OPENSSL_STRING_doall(addexts, (LHASH_DOALL_FN_TYPE)exts_cleanup); | ||
| 946 | lh_OPENSSL_STRING_free(addexts); | ||
| 876 | free(keyalgstr); | 947 | free(keyalgstr); |
| 877 | X509_REQ_free(req); | 948 | X509_REQ_free(req); |
| 878 | X509_free(x509ss); | 949 | X509_free(x509ss); |
| @@ -1558,3 +1629,62 @@ do_X509_CRL_sign(BIO * err, X509_CRL * x, EVP_PKEY * pkey, const EVP_MD * md, | |||
| 1558 | EVP_MD_CTX_cleanup(&mctx); | 1629 | EVP_MD_CTX_cleanup(&mctx); |
| 1559 | return rv > 0 ? 1 : 0; | 1630 | return rv > 0 ? 1 : 0; |
| 1560 | } | 1631 | } |
| 1632 | |||
| 1633 | static unsigned long | ||
| 1634 | ext_name_hash(const OPENSSL_STRING *a) | ||
| 1635 | { | ||
| 1636 | return lh_strhash((const char *)a); | ||
| 1637 | } | ||
| 1638 | |||
| 1639 | static int | ||
| 1640 | ext_name_cmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b) | ||
| 1641 | { | ||
| 1642 | return strcmp((const char *)a, (const char *)b); | ||
| 1643 | } | ||
| 1644 | |||
| 1645 | static void | ||
| 1646 | exts_cleanup(OPENSSL_STRING *x) | ||
| 1647 | { | ||
| 1648 | free((char *)x); | ||
| 1649 | } | ||
| 1650 | |||
| 1651 | /* | ||
| 1652 | * Is the |kv| key already duplicated ? This is remarkably tricky to get right. | ||
| 1653 | * Return 0 if unique, -1 on runtime error; 1 if found or a syntax error. | ||
| 1654 | */ | ||
| 1655 | static int | ||
| 1656 | duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv) | ||
| 1657 | { | ||
| 1658 | char *p; | ||
| 1659 | size_t off; | ||
| 1660 | |||
| 1661 | /* Check syntax. */ | ||
| 1662 | /* Skip leading whitespace, make a copy. */ | ||
| 1663 | while (*kv && isspace(*kv)) | ||
| 1664 | if (*++kv == '\0') | ||
| 1665 | return 1; | ||
| 1666 | if ((p = strchr(kv, '=')) == NULL) | ||
| 1667 | return 1; | ||
| 1668 | off = p - kv; | ||
| 1669 | if ((kv = strdup(kv)) == NULL) | ||
| 1670 | return -1; | ||
| 1671 | |||
| 1672 | /* Skip trailing space before the equal sign. */ | ||
| 1673 | for (p = kv + off; p > kv; --p) | ||
| 1674 | if (!isspace(p[-1])) | ||
| 1675 | break; | ||
| 1676 | if (p == kv) { | ||
| 1677 | free(kv); | ||
| 1678 | return 1; | ||
| 1679 | } | ||
| 1680 | *p = '\0'; | ||
| 1681 | |||
| 1682 | /* See if "key" is there by attempting to add it. */ | ||
| 1683 | if ((p = (char *)lh_OPENSSL_STRING_insert(addexts, (OPENSSL_STRING*)kv)) | ||
| 1684 | != NULL || lh_OPENSSL_STRING_error(addexts)) { | ||
| 1685 | free(p != NULL ? p : kv); | ||
| 1686 | return -1; | ||
| 1687 | } | ||
| 1688 | |||
| 1689 | return 0; | ||
| 1690 | } | ||
