summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorinoguchi <>2019-11-06 10:35:40 +0000
committerinoguchi <>2019-11-06 10:35:40 +0000
commit4387a38c78919363c19dce6e2ee02c113ce1067c (patch)
treeb94a914301d91001cb198c72a963b753edcbfa40
parenta3c84c4fdb9bcb4c0f3deae9ffd5337219d44c1f (diff)
downloadopenbsd-4387a38c78919363c19dce6e2ee02c113ce1067c.tar.gz
openbsd-4387a38c78919363c19dce6e2ee02c113ce1067c.tar.bz2
openbsd-4387a38c78919363c19dce6e2ee02c113ce1067c.zip
Add -addext option to openssl(1) req subcommand
First step of adding -addext option to openssl(1) req from OpenSSL 1.1.1d. ok jsing@
-rw-r--r--src/usr.bin/openssl/req.c136
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);
141static int check_end(const char *str, const char *end); 142static int check_end(const char *str, const char *end);
142static EVP_PKEY_CTX *set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type, 143static EVP_PKEY_CTX *set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type,
143 long *pkeylen, char **palgnam); 144 long *pkeylen, char **palgnam);
145static unsigned long ext_name_hash(const OPENSSL_STRING *a);
146static int ext_name_cmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b);
147static void exts_cleanup(OPENSSL_STRING *x);
148static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv);
144static CONF *req_conf = NULL; 149static CONF *req_conf = NULL;
150static CONF *addext_conf = NULL;
145static int batch = 0; 151static int batch = 0;
146 152
147int 153int
@@ -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
1633static unsigned long
1634ext_name_hash(const OPENSSL_STRING *a)
1635{
1636 return lh_strhash((const char *)a);
1637}
1638
1639static int
1640ext_name_cmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b)
1641{
1642 return strcmp((const char *)a, (const char *)b);
1643}
1644
1645static void
1646exts_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 */
1655static int
1656duplicated(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}