diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/usr.bin/openssl/ca.c | 190 |
1 files changed, 3 insertions, 187 deletions
diff --git a/src/usr.bin/openssl/ca.c b/src/usr.bin/openssl/ca.c index c0e011e7ad..80561712ff 100644 --- a/src/usr.bin/openssl/ca.c +++ b/src/usr.bin/openssl/ca.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ca.c,v 1.59 2024/06/23 07:50:52 tb Exp $ */ | 1 | /* $OpenBSD: ca.c,v 1.60 2024/07/08 05:56:17 tb 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 | * |
| @@ -135,12 +135,6 @@ static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, | |||
| 135 | char *enddate, long days, int batch, char *ext_sect, CONF *conf, | 135 | char *enddate, long days, int batch, char *ext_sect, CONF *conf, |
| 136 | int verbose, unsigned long certopt, unsigned long nameopt, int default_op, | 136 | int verbose, unsigned long certopt, unsigned long nameopt, int default_op, |
| 137 | int ext_copy); | 137 | int ext_copy); |
| 138 | static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, | ||
| 139 | X509 *x509, const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, | ||
| 140 | STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj, | ||
| 141 | unsigned long chtype, int multirdn, int email_dn, char *startdate, | ||
| 142 | char *enddate, long days, char *ext_sect, CONF *conf, int verbose, | ||
| 143 | unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy); | ||
| 144 | static int write_new_certificate(BIO *bp, X509 *x, int output_der, | 138 | static int write_new_certificate(BIO *bp, X509 *x, int output_der, |
| 145 | int notext); | 139 | int notext); |
| 146 | static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, | 140 | static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, |
| @@ -202,7 +196,6 @@ static struct { | |||
| 202 | char *section; | 196 | char *section; |
| 203 | int selfsign; | 197 | int selfsign; |
| 204 | STACK_OF(OPENSSL_STRING) *sigopts; | 198 | STACK_OF(OPENSSL_STRING) *sigopts; |
| 205 | char *spkac_file; | ||
| 206 | char *ss_cert_file; | 199 | char *ss_cert_file; |
| 207 | char *startdate; | 200 | char *startdate; |
| 208 | char *subj; | 201 | char *subj; |
| @@ -289,14 +282,6 @@ ca_opt_sigopt(char *arg) | |||
| 289 | } | 282 | } |
| 290 | 283 | ||
| 291 | static int | 284 | static int |
| 292 | ca_opt_spkac(char *arg) | ||
| 293 | { | ||
| 294 | cfg.spkac_file = arg; | ||
| 295 | cfg.req = 1; | ||
| 296 | return (0); | ||
| 297 | } | ||
| 298 | |||
| 299 | static int | ||
| 300 | ca_opt_ss_cert(char *arg) | 285 | ca_opt_ss_cert(char *arg) |
| 301 | { | 286 | { |
| 302 | cfg.ss_cert_file = arg; | 287 | cfg.ss_cert_file = arg; |
| @@ -552,13 +537,6 @@ static const struct option ca_options[] = { | |||
| 552 | .opt.argfunc = ca_opt_sigopt, | 537 | .opt.argfunc = ca_opt_sigopt, |
| 553 | }, | 538 | }, |
| 554 | { | 539 | { |
| 555 | .name = "spkac", | ||
| 556 | .argname = "file", | ||
| 557 | .desc = "File contains DN and signed public key and challenge", | ||
| 558 | .type = OPTION_ARG_FUNC, | ||
| 559 | .opt.argfunc = ca_opt_spkac, | ||
| 560 | }, | ||
| 561 | { | ||
| 562 | .name = "ss_cert", | 540 | .name = "ss_cert", |
| 563 | .argname = "file", | 541 | .argname = "file", |
| 564 | .desc = "File contains a self signed certificate to sign", | 542 | .desc = "File contains a self signed certificate to sign", |
| @@ -621,7 +599,7 @@ ca_usage(void) | |||
| 621 | " [-md alg] [-multivalue-rdn] [-name section]\n" | 599 | " [-md alg] [-multivalue-rdn] [-name section]\n" |
| 622 | " [-noemailDN] [-notext] [-out file] [-outdir directory]\n" | 600 | " [-noemailDN] [-notext] [-out file] [-outdir directory]\n" |
| 623 | " [-passin arg] [-policy name] [-preserveDN] [-revoke file]\n" | 601 | " [-passin arg] [-policy name] [-preserveDN] [-revoke file]\n" |
| 624 | " [-selfsign] [-sigopt nm:v] [-spkac file] [-ss_cert file]\n" | 602 | " [-selfsign] [-sigopt nm:v] [-ss_cert file]\n" |
| 625 | " [-startdate date] [-status serial] [-subj arg] [-updatedb]\n" | 603 | " [-startdate date] [-status serial] [-subj arg] [-updatedb]\n" |
| 626 | " [-utf8] [-verbose]\n\n"); | 604 | " [-utf8] [-verbose]\n\n"); |
| 627 | options_usage(ca_options); | 605 | options_usage(ca_options); |
| @@ -824,8 +802,7 @@ ca_main(int argc, char **argv) | |||
| 824 | } | 802 | } |
| 825 | /*****************************************************************/ | 803 | /*****************************************************************/ |
| 826 | /* we need a certificate */ | 804 | /* we need a certificate */ |
| 827 | if (!cfg.selfsign || cfg.spkac_file != NULL || | 805 | if (!cfg.selfsign || cfg.ss_cert_file != NULL || cfg.gencrl) { |
| 828 | cfg.ss_cert_file != NULL || cfg.gencrl) { | ||
| 829 | if ((cfg.certfile == NULL) && | 806 | if ((cfg.certfile == NULL) && |
| 830 | ((cfg.certfile = NCONF_get_string(conf, | 807 | ((cfg.certfile = NCONF_get_string(conf, |
| 831 | cfg.section, ENV_CERTIFICATE)) == NULL)) { | 808 | cfg.section, ENV_CERTIFICATE)) == NULL)) { |
| @@ -1163,34 +1140,6 @@ ca_main(int argc, char **argv) | |||
| 1163 | BIO_printf(bio_err, "Memory allocation failure\n"); | 1140 | BIO_printf(bio_err, "Memory allocation failure\n"); |
| 1164 | goto err; | 1141 | goto err; |
| 1165 | } | 1142 | } |
| 1166 | if (cfg.spkac_file != NULL) { | ||
| 1167 | total++; | ||
| 1168 | j = certify_spkac(&x, cfg.spkac_file, pkey, x509, | ||
| 1169 | dgst, cfg.sigopts, attribs, db, serial, | ||
| 1170 | cfg.subj, cfg.chtype, | ||
| 1171 | cfg.multirdn, cfg.email_dn, | ||
| 1172 | cfg.startdate, cfg.enddate, | ||
| 1173 | cfg.days, cfg.extensions, conf, | ||
| 1174 | cfg.verbose, certopt, nameopt, default_op, | ||
| 1175 | ext_copy); | ||
| 1176 | if (j < 0) | ||
| 1177 | goto err; | ||
| 1178 | if (j > 0) { | ||
| 1179 | total_done++; | ||
| 1180 | BIO_printf(bio_err, "\n"); | ||
| 1181 | if (!BN_add_word(serial, 1)) | ||
| 1182 | goto err; | ||
| 1183 | if (!sk_X509_push(cert_sk, x)) { | ||
| 1184 | BIO_printf(bio_err, | ||
| 1185 | "Memory allocation failure\n"); | ||
| 1186 | goto err; | ||
| 1187 | } | ||
| 1188 | if (cfg.outfile != NULL) { | ||
| 1189 | output_der = 1; | ||
| 1190 | cfg.batch = 1; | ||
| 1191 | } | ||
| 1192 | } | ||
| 1193 | } | ||
| 1194 | if (cfg.ss_cert_file != NULL) { | 1143 | if (cfg.ss_cert_file != NULL) { |
| 1195 | total++; | 1144 | total++; |
| 1196 | j = certify_cert(&x, cfg.ss_cert_file, pkey, x509, | 1145 | j = certify_cert(&x, cfg.ss_cert_file, pkey, x509, |
| @@ -2295,139 +2244,6 @@ write_new_certificate(BIO *bp, X509 *x, int output_der, int notext) | |||
| 2295 | } | 2244 | } |
| 2296 | 2245 | ||
| 2297 | static int | 2246 | static int |
| 2298 | certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, | ||
| 2299 | const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, | ||
| 2300 | STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj, | ||
| 2301 | unsigned long chtype, int multirdn, int email_dn, char *startdate, | ||
| 2302 | char *enddate, long days, char *ext_sect, CONF *lconf, int verbose, | ||
| 2303 | unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy) | ||
| 2304 | { | ||
| 2305 | STACK_OF(CONF_VALUE) *sk = NULL; | ||
| 2306 | LHASH_OF(CONF_VALUE) *parms = NULL; | ||
| 2307 | X509_REQ *req = NULL; | ||
| 2308 | CONF_VALUE *cv = NULL; | ||
| 2309 | NETSCAPE_SPKI *spki = NULL; | ||
| 2310 | char *type, *buf; | ||
| 2311 | EVP_PKEY *pktmp = NULL; | ||
| 2312 | X509_NAME *n = NULL; | ||
| 2313 | int ok = -1, i, j; | ||
| 2314 | long errline; | ||
| 2315 | int nid; | ||
| 2316 | |||
| 2317 | /* | ||
| 2318 | * Load input file into a hash table. (This is just an easy | ||
| 2319 | * way to read and parse the file, then put it into a convenient | ||
| 2320 | * STACK format). | ||
| 2321 | */ | ||
| 2322 | parms = CONF_load(NULL, infile, &errline); | ||
| 2323 | if (parms == NULL) { | ||
| 2324 | BIO_printf(bio_err, "error on line %ld of %s\n", | ||
| 2325 | errline, infile); | ||
| 2326 | ERR_print_errors(bio_err); | ||
| 2327 | goto err; | ||
| 2328 | } | ||
| 2329 | sk = CONF_get_section(parms, "default"); | ||
| 2330 | if (sk_CONF_VALUE_num(sk) == 0) { | ||
| 2331 | BIO_printf(bio_err, "no name/value pairs found in %s\n", | ||
| 2332 | infile); | ||
| 2333 | goto err; | ||
| 2334 | } | ||
| 2335 | /* | ||
| 2336 | * Now create a dummy X509 request structure. We don't actually | ||
| 2337 | * have an X509 request, but we have many of the components | ||
| 2338 | * (a public key, various DN components). The idea is that we | ||
| 2339 | * put these components into the right X509 request structure | ||
| 2340 | * and we can use the same code as if you had a real X509 request. | ||
| 2341 | */ | ||
| 2342 | req = X509_REQ_new(); | ||
| 2343 | if (req == NULL) { | ||
| 2344 | ERR_print_errors(bio_err); | ||
| 2345 | goto err; | ||
| 2346 | } | ||
| 2347 | /* | ||
| 2348 | * Build up the subject name set. | ||
| 2349 | */ | ||
| 2350 | n = X509_REQ_get_subject_name(req); | ||
| 2351 | |||
| 2352 | for (i = 0;; i++) { | ||
| 2353 | if (sk_CONF_VALUE_num(sk) <= i) | ||
| 2354 | break; | ||
| 2355 | |||
| 2356 | cv = sk_CONF_VALUE_value(sk, i); | ||
| 2357 | type = cv->name; | ||
| 2358 | /* | ||
| 2359 | * Skip past any leading X. X: X, etc to allow for multiple | ||
| 2360 | * instances | ||
| 2361 | */ | ||
| 2362 | for (buf = cv->name; *buf; buf++) { | ||
| 2363 | if ((*buf == ':') || (*buf == ',') || (*buf == '.')) { | ||
| 2364 | buf++; | ||
| 2365 | if (*buf) | ||
| 2366 | type = buf; | ||
| 2367 | break; | ||
| 2368 | } | ||
| 2369 | } | ||
| 2370 | |||
| 2371 | buf = cv->value; | ||
| 2372 | if ((nid = OBJ_txt2nid(type)) == NID_undef) { | ||
| 2373 | if (strcmp(type, "SPKAC") == 0) { | ||
| 2374 | spki = NETSCAPE_SPKI_b64_decode(cv->value, -1); | ||
| 2375 | if (spki == NULL) { | ||
| 2376 | BIO_printf(bio_err, | ||
| 2377 | "unable to load Netscape SPKAC structure\n"); | ||
| 2378 | ERR_print_errors(bio_err); | ||
| 2379 | goto err; | ||
| 2380 | } | ||
| 2381 | } | ||
| 2382 | continue; | ||
| 2383 | } | ||
| 2384 | if (!X509_NAME_add_entry_by_NID(n, nid, chtype, | ||
| 2385 | (unsigned char *)buf, -1, -1, 0)) | ||
| 2386 | goto err; | ||
| 2387 | } | ||
| 2388 | if (spki == NULL) { | ||
| 2389 | BIO_printf(bio_err, | ||
| 2390 | "Netscape SPKAC structure not found in %s\n", infile); | ||
| 2391 | goto err; | ||
| 2392 | } | ||
| 2393 | /* | ||
| 2394 | * Now extract the key from the SPKI structure. | ||
| 2395 | */ | ||
| 2396 | |||
| 2397 | BIO_printf(bio_err, | ||
| 2398 | "Check that the SPKAC request matches the signature\n"); | ||
| 2399 | |||
| 2400 | if ((pktmp = NETSCAPE_SPKI_get_pubkey(spki)) == NULL) { | ||
| 2401 | BIO_printf(bio_err, "error unpacking SPKAC public key\n"); | ||
| 2402 | goto err; | ||
| 2403 | } | ||
| 2404 | j = NETSCAPE_SPKI_verify(spki, pktmp); | ||
| 2405 | if (j <= 0) { | ||
| 2406 | BIO_printf(bio_err, | ||
| 2407 | "signature verification failed on SPKAC public key\n"); | ||
| 2408 | goto err; | ||
| 2409 | } | ||
| 2410 | BIO_printf(bio_err, "Signature ok\n"); | ||
| 2411 | |||
| 2412 | if (!X509_REQ_set_pubkey(req, pktmp)) { | ||
| 2413 | EVP_PKEY_free(pktmp); | ||
| 2414 | goto err; | ||
| 2415 | } | ||
| 2416 | EVP_PKEY_free(pktmp); | ||
| 2417 | ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, | ||
| 2418 | subj, chtype, multirdn, email_dn, startdate, enddate, days, 1, | ||
| 2419 | verbose, req, ext_sect, lconf, certopt, nameopt, default_op, | ||
| 2420 | ext_copy, 0); | ||
| 2421 | |||
| 2422 | err: | ||
| 2423 | X509_REQ_free(req); | ||
| 2424 | CONF_free(parms); | ||
| 2425 | NETSCAPE_SPKI_free(spki); | ||
| 2426 | |||
| 2427 | return (ok); | ||
| 2428 | } | ||
| 2429 | |||
| 2430 | static int | ||
| 2431 | check_time_format(const char *str) | 2247 | check_time_format(const char *str) |
| 2432 | { | 2248 | { |
| 2433 | return ASN1_TIME_set_string(NULL, str); | 2249 | return ASN1_TIME_set_string(NULL, str); |
