summaryrefslogtreecommitdiff
path: root/src/usr.bin/openssl/x509.c
diff options
context:
space:
mode:
authorjob <>2024-01-12 11:24:03 +0000
committerjob <>2024-01-12 11:24:03 +0000
commita941bc4dee12272fae734d7e033698516cf7b2ee (patch)
treeb556349cae6f3fe4c0d9ea5f86f104a74c5349a1 /src/usr.bin/openssl/x509.c
parent11bbbc8e1d1d1cf5984fb74c05165cd1cfb0251c (diff)
downloadopenbsd-a941bc4dee12272fae734d7e033698516cf7b2ee.tar.gz
openbsd-a941bc4dee12272fae734d7e033698516cf7b2ee.tar.bz2
openbsd-a941bc4dee12272fae734d7e033698516cf7b2ee.zip
Add -force_pubkey -multivalue-rdn -set_issuer -set_subject -utf8 to x509 app
The -set_issuer, -set_subject, and -force_pubkey features can be used to 'rechain' PKIs, for more information see https://labs.apnic.net/nro-ta/ and https://blog.apnic.net/2023/12/14/models-of-trust-for-the-rpki/ OK tb@
Diffstat (limited to 'src/usr.bin/openssl/x509.c')
-rw-r--r--src/usr.bin/openssl/x509.c131
1 files changed, 108 insertions, 23 deletions
diff --git a/src/usr.bin/openssl/x509.c b/src/usr.bin/openssl/x509.c
index 7f60110c47..332399e7cc 100644
--- a/src/usr.bin/openssl/x509.c
+++ b/src/usr.bin/openssl/x509.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509.c,v 1.35 2023/11/21 17:56:19 tb Exp $ */ 1/* $OpenBSD: x509.c,v 1.36 2024/01/12 11:24:03 job 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 *
@@ -81,11 +81,11 @@
81 81
82static int callb(int ok, X509_STORE_CTX *ctx); 82static int callb(int ok, X509_STORE_CTX *ctx);
83static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, 83static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
84 const EVP_MD *digest, CONF *conf, char *section); 84 const EVP_MD *digest, CONF *conf, char *section, X509_NAME *issuer);
85static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, 85static 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, 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, 87 char *serial, int create, int days, int clrext, CONF *conf, char *section,
88 ASN1_INTEGER *sno); 88 ASN1_INTEGER *sno, X509_NAME *issuer);
89static int purpose_print(BIO *bio, X509 *cert, const X509_PURPOSE *pt); 89static int purpose_print(BIO *bio, X509 *cert, const X509_PURPOSE *pt);
90 90
91static struct { 91static struct {
@@ -103,6 +103,7 @@ static struct {
103 unsigned long certflag; 103 unsigned long certflag;
104 int checkend; 104 int checkend;
105 int checkoffset; 105 int checkoffset;
106 unsigned long chtype;
106 int clrext; 107 int clrext;
107 int clrreject; 108 int clrreject;
108 int clrtrust; 109 int clrtrust;
@@ -113,6 +114,7 @@ static struct {
113 char *extfile; 114 char *extfile;
114 char *extsect; 115 char *extsect;
115 int fingerprint; 116 int fingerprint;
117 char *force_pubkey;
116 char *infile; 118 char *infile;
117 int informat; 119 int informat;
118 int issuer; 120 int issuer;
@@ -124,6 +126,7 @@ static struct {
124 int keyformat; 126 int keyformat;
125 const EVP_MD *md_alg; 127 const EVP_MD *md_alg;
126 int modulus; 128 int modulus;
129 int multirdn;
127 int next_serial; 130 int next_serial;
128 unsigned long nmflag; 131 unsigned long nmflag;
129 int noout; 132 int noout;
@@ -139,6 +142,8 @@ static struct {
139 STACK_OF(ASN1_OBJECT) *reject; 142 STACK_OF(ASN1_OBJECT) *reject;
140 int reqfile; 143 int reqfile;
141 int serial; 144 int serial;
145 char *set_issuer;
146 char *set_subject;
142 int sign_flag; 147 int sign_flag;
143 STACK_OF(OPENSSL_STRING) *sigopts; 148 STACK_OF(OPENSSL_STRING) *sigopts;
144 ASN1_INTEGER *sno; 149 ASN1_INTEGER *sno;
@@ -312,6 +317,13 @@ x509_opt_sigopt(char *arg)
312 return (0); 317 return (0);
313} 318}
314 319
320static int
321x509_opt_utf8(void)
322{
323 cfg.chtype = MBSTRING_UTF8;
324 return (0);
325}
326
315static const struct option x509_options[] = { 327static const struct option x509_options[] = {
316 { 328 {
317 .name = "C", 329 .name = "C",
@@ -468,6 +480,13 @@ static const struct option x509_options[] = {
468 .order = &cfg.num, 480 .order = &cfg.num,
469 }, 481 },
470 { 482 {
483 .name = "force_pubkey",
484 .argname = "key",
485 .desc = "Force the public key to be put in the certificate",
486 .type = OPTION_ARG,
487 .opt.arg = &cfg.force_pubkey,
488 },
489 {
471 .name = "hash", 490 .name = "hash",
472 .desc = "Synonym for -subject_hash", 491 .desc = "Synonym for -subject_hash",
473 .type = OPTION_ORDER, 492 .type = OPTION_ORDER,
@@ -526,6 +545,12 @@ static const struct option x509_options[] = {
526 .order = &cfg.num, 545 .order = &cfg.num,
527 }, 546 },
528 { 547 {
548 .name = "multivalue-rdn",
549 .desc = "Enable support for multivalued RDNs",
550 .type = OPTION_FLAG,
551 .opt.flag = &cfg.multirdn,
552 },
553 {
529 .name = "nameopt", 554 .name = "nameopt",
530 .argname = "option", 555 .argname = "option",
531 .desc = "Various certificate name options", 556 .desc = "Various certificate name options",
@@ -609,6 +634,13 @@ static const struct option x509_options[] = {
609 .order = &cfg.num, 634 .order = &cfg.num,
610 }, 635 },
611 { 636 {
637 .name = "set_issuer",
638 .argname = "name",
639 .desc = "Set the issuer name",
640 .type = OPTION_ARG,
641 .opt.arg = &cfg.set_issuer,
642 },
643 {
612 .name = "set_serial", 644 .name = "set_serial",
613 .argname = "n", 645 .argname = "n",
614 .desc = "Serial number to use", 646 .desc = "Serial number to use",
@@ -616,6 +648,13 @@ static const struct option x509_options[] = {
616 .opt.argfunc = x509_opt_set_serial, 648 .opt.argfunc = x509_opt_set_serial,
617 }, 649 },
618 { 650 {
651 .name = "set_subject",
652 .argname = "name",
653 .desc = "Set the subject name",
654 .type = OPTION_ARG,
655 .opt.arg = &cfg.set_subject,
656 },
657 {
619 .name = "setalias", 658 .name = "setalias",
620 .argname = "arg", 659 .argname = "arg",
621 .desc = "Set certificate alias", 660 .desc = "Set certificate alias",
@@ -644,6 +683,11 @@ static const struct option x509_options[] = {
644 .order = &cfg.num, 683 .order = &cfg.num,
645 }, 684 },
646 { 685 {
686 .name = "subj",
687 .type = OPTION_ARG,
688 .opt.arg = &cfg.set_subject,
689 },
690 {
647 .name = "subject", 691 .name = "subject",
648 .desc = "Print subject name", 692 .desc = "Print subject name",
649 .type = OPTION_ORDER, 693 .type = OPTION_ORDER,
@@ -680,6 +724,12 @@ static const struct option x509_options[] = {
680 .opt.flag = &cfg.trustout, 724 .opt.flag = &cfg.trustout,
681 }, 725 },
682 { 726 {
727 .name = "utf8",
728 .desc = "Input characters are in UTF-8 (default ASCII)",
729 .type = OPTION_FUNC,
730 .opt.func = x509_opt_utf8,
731 },
732 {
683 .name = "x509toreq", 733 .name = "x509toreq",
684 .desc = "Output a certification request object", 734 .desc = "Output a certification request object",
685 .type = OPTION_ORDER, 735 .type = OPTION_ORDER,
@@ -704,16 +754,17 @@ x509_usage(void)
704 " [-CAkeyform der | pem] [-CAserial file] [-certopt option]\n" 754 " [-CAkeyform der | pem] [-CAserial file] [-certopt option]\n"
705 " [-checkend arg] [-clrext] [-clrreject] [-clrtrust] [-dates]\n" 755 " [-checkend arg] [-clrext] [-clrreject] [-clrtrust] [-dates]\n"
706 " [-days arg] [-email] [-enddate] [-extensions section]\n" 756 " [-days arg] [-email] [-enddate] [-extensions section]\n"
707 " [-extfile file] [-fingerprint] [-hash] [-in file]\n" 757 " [-extfile file] [-fingerprint] [-force_pubkey key] [-hash]\n"
708 " [-inform der | net | pem] [-issuer] [-issuer_hash]\n" 758 " [-in file] [-inform der | net | pem] [-issuer]\n"
709 " [-issuer_hash_old] [-keyform der | pem] [-md5 | -sha1]\n" 759 " [-issuer_hash] [-issuer_hash_old] [-keyform der | pem]\n"
710 " [-modulus] [-nameopt option] [-next_serial] [-noout]\n" 760 " [-md5 | -sha1] [-modulus] [-multivalue-rdn]\n"
711 " [-ocsp_uri] [-ocspid] [-out file]\n" 761 " [-nameopt option] [-next_serial] [-noout] [-ocsp_uri]\n"
712 " [-outform der | net | pem] [-passin arg] [-pubkey]\n" 762 " [-ocspid] [-out file] [-outform der | net | pem]\n"
713 " [-purpose] [-req] [-serial] [-set_serial n] [-setalias arg]\n" 763 " [-passin arg] [-pubkey] [-purpose] [-req] [-serial]\n"
714 " [-signkey file] [-sigopt nm:v] [-startdate] [-subject]\n" 764 " [-set_issuer name] [-set_serial n] [-set_subject name]\n"
715 " [-subject_hash] [-subject_hash_old] [-text] [-trustout]\n" 765 " [-setalias arg] [-signkey file] [-sigopt nm:v] [-startdate]\n"
716 " [-x509toreq]\n"); 766 " [-subject] [-subject_hash] [-subject_hash_old] [-text]\n"
767 " [-trustout] [-utf8] [-x509toreq]\n");
717 fprintf(stderr, "\n"); 768 fprintf(stderr, "\n");
718 options_usage(x509_options); 769 options_usage(x509_options);
719 fprintf(stderr, "\n"); 770 fprintf(stderr, "\n");
@@ -725,7 +776,8 @@ x509_main(int argc, char **argv)
725 int ret = 1; 776 int ret = 1;
726 X509_REQ *req = NULL; 777 X509_REQ *req = NULL;
727 X509 *x = NULL, *xca = NULL; 778 X509 *x = NULL, *xca = NULL;
728 EVP_PKEY *Upkey = NULL, *CApkey = NULL; 779 X509_NAME *iname = NULL, *sname = NULL;
780 EVP_PKEY *Fpkey = NULL, *Upkey = NULL, *CApkey = NULL;
729 int i; 781 int i;
730 BIO *out = NULL; 782 BIO *out = NULL;
731 BIO *STDout = NULL; 783 BIO *STDout = NULL;
@@ -741,6 +793,7 @@ x509_main(int argc, char **argv)
741 } 793 }
742 794
743 memset(&cfg, 0, sizeof(cfg)); 795 memset(&cfg, 0, sizeof(cfg));
796 cfg.chtype = MBSTRING_ASC;
744 cfg.days = DEF_DAYS; 797 cfg.days = DEF_DAYS;
745 cfg.informat = FORMAT_PEM; 798 cfg.informat = FORMAT_PEM;
746 cfg.outformat = FORMAT_PEM; 799 cfg.outformat = FORMAT_PEM;
@@ -811,6 +864,11 @@ x509_main(int argc, char **argv)
811 goto end; 864 goto end;
812 } 865 }
813 } 866 }
867 if (cfg.force_pubkey != NULL) {
868 if ((Fpkey = load_pubkey(bio_err, cfg.force_pubkey,
869 cfg.keyformat, 0, NULL, "Forced key")) == NULL)
870 goto end;
871 }
814 if (cfg.reqfile) { 872 if (cfg.reqfile) {
815 EVP_PKEY *pkey; 873 EVP_PKEY *pkey;
816 BIO *in; 874 BIO *in;
@@ -875,9 +933,21 @@ x509_main(int argc, char **argv)
875 } else if (!X509_set_serialNumber(x, cfg.sno)) 933 } else if (!X509_set_serialNumber(x, cfg.sno))
876 goto end; 934 goto end;
877 935
878 if (!X509_set_issuer_name(x, X509_REQ_get_subject_name(req))) 936 if (cfg.set_issuer != NULL) {
937 iname = parse_name(cfg.set_issuer, cfg.chtype,
938 cfg.multirdn);
939 if (iname == NULL)
940 goto end;
941 }
942
943 if (cfg.set_subject != NULL)
944 sname = parse_name(cfg.set_subject, cfg.chtype,
945 cfg.multirdn);
946 else
947 sname = X509_NAME_dup(X509_REQ_get_subject_name(req));
948 if (sname == NULL)
879 goto end; 949 goto end;
880 if (!X509_set_subject_name(x, X509_REQ_get_subject_name(req))) 950 if (!X509_set_subject_name(x, sname))
881 goto end; 951 goto end;
882 952
883 if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL) 953 if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL)
@@ -886,7 +956,9 @@ x509_main(int argc, char **argv)
886 NULL) == NULL) 956 NULL) == NULL)
887 goto end; 957 goto end;
888 958
889 if ((pkey = X509_REQ_get0_pubkey(req)) == NULL) 959 if ((pkey = Fpkey) == NULL)
960 pkey = X509_REQ_get0_pubkey(req);
961 if (pkey == NULL)
890 goto end; 962 goto end;
891 if (!X509_set_pubkey(x, pkey)) 963 if (!X509_set_pubkey(x, pkey))
892 goto end; 964 goto end;
@@ -1204,7 +1276,7 @@ x509_main(int argc, char **argv)
1204 } 1276 }
1205 if (!sign(x, Upkey, cfg.days, 1277 if (!sign(x, Upkey, cfg.days,
1206 cfg.clrext, cfg.digest, 1278 cfg.clrext, cfg.digest,
1207 extconf, cfg.extsect)) 1279 extconf, cfg.extsect, iname))
1208 goto end; 1280 goto end;
1209 } else if (cfg.CA_flag == i) { 1281 } else if (cfg.CA_flag == i) {
1210 BIO_printf(bio_err, "Getting CA Private Key\n"); 1282 BIO_printf(bio_err, "Getting CA Private Key\n");
@@ -1218,7 +1290,7 @@ x509_main(int argc, char **argv)
1218 if (!x509_certify(ctx, cfg.CAfile, cfg.digest, 1290 if (!x509_certify(ctx, cfg.CAfile, cfg.digest,
1219 x, xca, CApkey, cfg.sigopts, cfg.CAserial, 1291 x, xca, CApkey, cfg.sigopts, cfg.CAserial,
1220 cfg.CA_createserial, cfg.days, cfg.clrext, 1292 cfg.CA_createserial, cfg.days, cfg.clrext,
1221 extconf, cfg.extsect, cfg.sno)) 1293 extconf, cfg.extsect, cfg.sno, iname))
1222 goto end; 1294 goto end;
1223 } else if (cfg.x509req == i) { 1295 } else if (cfg.x509req == i) {
1224 EVP_PKEY *pk; 1296 EVP_PKEY *pk;
@@ -1302,10 +1374,13 @@ x509_main(int argc, char **argv)
1302 NCONF_free(extconf); 1374 NCONF_free(extconf);
1303 BIO_free_all(out); 1375 BIO_free_all(out);
1304 BIO_free_all(STDout); 1376 BIO_free_all(STDout);
1377 X509_NAME_free(iname);
1378 X509_NAME_free(sname);
1305 X509_STORE_free(ctx); 1379 X509_STORE_free(ctx);
1306 X509_REQ_free(req); 1380 X509_REQ_free(req);
1307 X509_free(x); 1381 X509_free(x);
1308 X509_free(xca); 1382 X509_free(xca);
1383 EVP_PKEY_free(Fpkey);
1309 EVP_PKEY_free(Upkey); 1384 EVP_PKEY_free(Upkey);
1310 EVP_PKEY_free(CApkey); 1385 EVP_PKEY_free(CApkey);
1311 sk_OPENSSL_STRING_free(cfg.sigopts); 1386 sk_OPENSSL_STRING_free(cfg.sigopts);
@@ -1366,7 +1441,7 @@ static int
1366x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, X509 *x, 1441x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, X509 *x,
1367 X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts, 1442 X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts,
1368 char *serialfile, int create, int days, int clrext, CONF *conf, 1443 char *serialfile, int create, int days, int clrext, CONF *conf,
1369 char *section, ASN1_INTEGER *sno) 1444 char *section, ASN1_INTEGER *sno, X509_NAME *issuer)
1370{ 1445{
1371 int ret = 0; 1446 int ret = 0;
1372 ASN1_INTEGER *bs = NULL; 1447 ASN1_INTEGER *bs = NULL;
@@ -1405,8 +1480,14 @@ x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, X509 *x,
1405 "CA certificate and CA private key do not match\n"); 1480 "CA certificate and CA private key do not match\n");
1406 goto end; 1481 goto end;
1407 } 1482 }
1408 if (!X509_set_issuer_name(x, X509_get_subject_name(xca))) 1483
1484 if (issuer == NULL)
1485 issuer = X509_get_subject_name(xca);
1486 if (issuer == NULL)
1487 goto end;
1488 if (!X509_set_issuer_name(x, issuer))
1409 goto end; 1489 goto end;
1490
1410 if (!X509_set_serialNumber(x, bs)) 1491 if (!X509_set_serialNumber(x, bs))
1411 goto end; 1492 goto end;
1412 1493
@@ -1483,7 +1564,7 @@ callb(int ok, X509_STORE_CTX *ctx)
1483/* self sign */ 1564/* self sign */
1484static int 1565static int
1485sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, 1566sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest,
1486 CONF *conf, char *section) 1567 CONF *conf, char *section, X509_NAME *issuer)
1487{ 1568{
1488 EVP_PKEY *pktmp; 1569 EVP_PKEY *pktmp;
1489 1570
@@ -1493,7 +1574,11 @@ sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest,
1493 EVP_PKEY_copy_parameters(pktmp, pkey); 1574 EVP_PKEY_copy_parameters(pktmp, pkey);
1494 EVP_PKEY_save_parameters(pktmp, 1); 1575 EVP_PKEY_save_parameters(pktmp, 1);
1495 1576
1496 if (!X509_set_issuer_name(x, X509_get_subject_name(x))) 1577 if (issuer == NULL)
1578 issuer = X509_get_subject_name(x);
1579 if (issuer == NULL)
1580 goto err;
1581 if (!X509_set_issuer_name(x, issuer))
1497 goto err; 1582 goto err;
1498 if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL) 1583 if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL)
1499 goto err; 1584 goto err;