From: Dr. David von Oheimb Date: Tue, 6 Jul 2021 10:28:22 +0000 (+0200) Subject: APPS: Move load_csr_autofmt() from apps/cmp.c to apps.c and use it also for apps... X-Git-Tag: openssl-3.2.0-alpha1~2059 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=200d844782956b4c6db9bdd92a53113d9c2dc3c7;p=thirdparty%2Fopenssl.git APPS: Move load_csr_autofmt() from apps/cmp.c to apps.c and use it also for apps, too Also add related references to FR #15725. Reviewed-by: Dmitry Belyavskiy Reviewed-by: Tomas Mraz Reviewed-by: David von Oheimb (Merged from https://github.com/openssl/openssl/pull/18900) --- diff --git a/apps/ca.c b/apps/ca.c index ff4a8d91e82..e60ce6410cb 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -168,7 +168,8 @@ const OPTIONS ca_options[] = { {"quiet", OPT_QUIET, '-', "Terse output during processing"}, {"outdir", OPT_OUTDIR, '/', "Where to put output cert"}, {"in", OPT_IN, '<', "The input cert request(s)"}, - {"inform", OPT_INFORM, 'F', "CSR input format (DER or PEM); default PEM"}, + {"inform", OPT_INFORM, 'F', + "CSR input format to use (PEM or DER; by default try PEM first)"}, {"infiles", OPT_INFILES, '-', "The last argument, requests to process"}, {"out", OPT_OUT, '>', "Where to put the output file(s)"}, {"dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."}, @@ -1374,7 +1375,7 @@ static int certify(X509 **xret, const char *infile, int informat, EVP_PKEY *pktmp = NULL; int ok = -1, i; - req = load_csr(infile, informat, "certificate request"); + req = load_csr_autofmt(infile, informat, "certificate request"); if (req == NULL) goto end; if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL) { diff --git a/apps/cmp.c b/apps/cmp.c index ccfd7fcc23c..bac54f12658 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -691,34 +691,6 @@ static X509 *load_cert_pwd(const char *uri, const char *pass, const char *desc) return cert; } -static X509_REQ *load_csr_autofmt(const char *infile, const char *desc) -{ - X509_REQ *csr; - BIO *bio_bak = bio_err; - - bio_err = NULL; /* do not show errors on more than one try */ - csr = load_csr(infile, FORMAT_PEM, desc); - bio_err = bio_bak; - if (csr == NULL) { - ERR_clear_error(); - csr = load_csr(infile, FORMAT_ASN1, desc); - } - if (csr == NULL) { - ERR_print_errors(bio_err); - BIO_printf(bio_err, "error: unable to load %s from file '%s'\n", desc, - infile); - } else { - EVP_PKEY *pkey = X509_REQ_get0_pubkey(csr); - int ret = do_X509_REQ_verify(csr, pkey, NULL /* vfyopts */); - - if (pkey == NULL || ret < 0) - CMP_warn("error while verifying CSR self-signature"); - else if (ret == 0) - CMP_warn("CSR self-signature does not match the contents"); - } - return csr; -} - /* set expected hostname/IP addr and clears the email addr in the given ts */ static int truststore_set_host_etc(X509_STORE *ts, const char *host) { @@ -1641,7 +1613,8 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) if (opt_cmd == CMP_GENM) { CMP_warn("-csr option is ignored for command 'genm'"); } else { - if ((csr = load_csr_autofmt(opt_csr, "PKCS#10 CSR")) == NULL) + csr = load_csr_autofmt(opt_csr, FORMAT_UNDEF, "PKCS#10 CSR"); + if (csr == NULL) return 0; if (!OSSL_CMP_CTX_set1_p10CSR(ctx, csr)) goto oom; diff --git a/apps/include/apps.h b/apps/include/apps.h index 44892dc3e56..335e80775ca 100644 --- a/apps/include/apps.h +++ b/apps/include/apps.h @@ -114,6 +114,7 @@ char *get_passwd(const char *pass, const char *desc); int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2); int add_oid_section(CONF *conf); X509_REQ *load_csr(const char *file, int format, const char *desc); +X509_REQ *load_csr_autofmt(const char *infile, int format, const char *desc); X509 *load_cert_pass(const char *uri, int format, int maybe_stdin, const char *pass, const char *desc); #define load_cert(uri, format, desc) load_cert_pass(uri, format, 1, NULL, desc) diff --git a/apps/lib/apps.c b/apps/lib/apps.c index 0721120ab22..9d65797a91b 100644 --- a/apps/lib/apps.c +++ b/apps/lib/apps.c @@ -496,6 +496,7 @@ X509_CRL *load_crl(const char *uri, int format, int maybe_stdin, return crl; } +/* Could be simplified if OSSL_STORE supported CSRs, see FR #15725 */ X509_REQ *load_csr(const char *file, int format, const char *desc) { X509_REQ *req = NULL; @@ -503,8 +504,6 @@ X509_REQ *load_csr(const char *file, int format, const char *desc) if (format == FORMAT_UNDEF) format = FORMAT_PEM; - if (desc == NULL) - desc = "CSR"; in = bio_open_default(file, 'r', format); if (in == NULL) goto end; @@ -519,12 +518,48 @@ X509_REQ *load_csr(const char *file, int format, const char *desc) end: if (req == NULL) { ERR_print_errors(bio_err); - BIO_printf(bio_err, "Unable to load %s\n", desc); + if (desc != NULL) + BIO_printf(bio_err, "Unable to load %s\n", desc); } BIO_free(in); return req; } +/* Better extend OSSL_STORE to support CSRs, see FR #15725 */ +X509_REQ *load_csr_autofmt(const char *infile, int format, const char *desc) +{ + X509_REQ *csr; + + if (format != FORMAT_UNDEF) { + csr = load_csr(infile, format, desc); + } else { /* try PEM, then DER */ + BIO *bio_bak = bio_err; + + bio_err = NULL; /* do not show errors on more than one try */ + csr = load_csr(infile, FORMAT_PEM, NULL /* desc */); + bio_err = bio_bak; + if (csr == NULL) { + ERR_clear_error(); + csr = load_csr(infile, FORMAT_ASN1, NULL /* desc */); + } + if (csr == NULL) { + BIO_printf(bio_err, "error: unable to load %s from file '%s'\n", + desc, infile); + } + } + if (csr != NULL) { + EVP_PKEY *pkey = X509_REQ_get0_pubkey(csr); + int ret = do_X509_REQ_verify(csr, pkey, NULL /* vfyopts */); + + if (pkey == NULL || ret < 0) + BIO_puts(bio_err, "Warning: error while verifying CSR self-signature"); + else if (ret == 0) + BIO_puts(bio_err, "Warning: CSR self-signature does not match the contents"); + return csr; + } + return csr; +} + void cleanse(char *str) { if (str != NULL) diff --git a/apps/req.c b/apps/req.c index 3b24ca35b03..65dc6b8bb51 100644 --- a/apps/req.c +++ b/apps/req.c @@ -103,7 +103,8 @@ const OPTIONS req_options[] = { "Specify engine to be used for key generation operations"}, #endif {"in", OPT_IN, '<', "X.509 request input file (default stdin)"}, - {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, + {"inform", OPT_INFORM, 'F', + "CSR input format to use (PEM or DER; by default try PEM first)"}, {"verify", OPT_VERIFY, '-', "Verify self-signature on the request"}, OPT_SECTION("Certificate"), @@ -729,8 +730,8 @@ int req_main(int argc, char **argv) if (keyfile != NULL) BIO_printf(bio_err, "Warning: Not placing -key in cert or request since request is used\n"); - req = load_csr(infile /* if NULL, reads from stdin */, - informat, "X509 request"); + req = load_csr_autofmt(infile /* if NULL, reads from stdin */, + informat, "X509 request"); if (req == NULL) goto end; } else if (infile != NULL) { diff --git a/apps/x509.c b/apps/x509.c index a7b01edb093..71c622b8c61 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -70,7 +70,7 @@ const OPTIONS x509_options[] = { {"copy_extensions", OPT_COPY_EXTENSIONS, 's', "copy extensions when converting from CSR to x509 or vice versa"}, {"inform", OPT_INFORM, 'f', - "CSR input file format (DER or PEM) - default PEM"}, + "CSR input format to use (PEM or DER; by default try PEM first)"}, {"vfyopt", OPT_VFYOPT, 's', "CSR verification parameter in n:v form"}, {"key", OPT_KEY, 's', "Key for signing, and to include unless using -force_pubkey"}, @@ -706,7 +706,7 @@ int x509_main(int argc, char **argv) if (infile == NULL) BIO_printf(bio_err, "Warning: Reading cert request from stdin since no -in option is given\n"); - req = load_csr(infile, informat, "certificate request input"); + req = load_csr_autofmt(infile, informat, "certificate request input"); if (req == NULL) goto end; diff --git a/doc/man1/openssl-ca.pod.in b/doc/man1/openssl-ca.pod.in index 58b121678d8..955bac8fd3b 100644 --- a/doc/man1/openssl-ca.pod.in +++ b/doc/man1/openssl-ca.pod.in @@ -119,8 +119,8 @@ signed by the CA. =item B<-inform> B|B -The format of the data in certificate request input files; -unspecified by default. +The format to use when loading certificate request (CSR) input files; +by default PEM is tried first. See L for details. =item B<-ss_cert> I diff --git a/doc/man1/openssl-req.pod.in b/doc/man1/openssl-req.pod.in index fcb533a29e3..2f525f411bd 100644 --- a/doc/man1/openssl-req.pod.in +++ b/doc/man1/openssl-req.pod.in @@ -70,9 +70,14 @@ for use as root CAs for example. Print out a usage message. -=item B<-inform> B|B, B<-outform> B|B +=item B<-inform> B|B -The input and output formats; unspecified by default. +The CSR input file format to use; by default PEM is tried first. +See L for details. + +=item B<-outform> B|B + +The output format; unspecified by default. See L for details. The data is a PKCS#10 object. diff --git a/doc/man1/openssl-x509.pod.in b/doc/man1/openssl-x509.pod.in index d05f380bdea..5facce254d3 100644 --- a/doc/man1/openssl-x509.pod.in +++ b/doc/man1/openssl-x509.pod.in @@ -155,7 +155,7 @@ The B<-ext> option can be used to further restrict which extensions to copy. =item B<-inform> B|B -The input file format; unspecified by default. +The input file format to use; by default PEM is tried first. See L for details. =item B<-vfyopt> I:I