APPS: Move load_csr_autofmt() from apps/cmp.c to apps.c and use it also for apps...
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Tue, 6 Jul 2021 10:28:22 +0000 (12:28 +0200)
committerDr. David von Oheimb <dev@ddvo.net>
Tue, 20 Sep 2022 18:59:50 +0000 (20:59 +0200)
Also add related references to FR #15725.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
(Merged from https://github.com/openssl/openssl/pull/18900)

apps/ca.c
apps/cmp.c
apps/include/apps.h
apps/lib/apps.c
apps/req.c
apps/x509.c
doc/man1/openssl-ca.pod.in
doc/man1/openssl-req.pod.in
doc/man1/openssl-x509.pod.in

index ff4a8d91e8283dd11a5e9392622cf7329ffd61fe..e60ce6410cb5c9c6545a08330e1a2fa14c3d63d3 100644 (file)
--- 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) {
index ccfd7fcc23ca544ecc80f385c70a356d89ec18aa..bac54f1265896edac640a2b810e4b33c893d9149 100644 (file)
@@ -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;
index 44892dc3e56949e038a143b5c4809c5ca75b581d..335e80775ca5c3361296e69776cfdd0c6977476d 100644 (file)
@@ -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)
index 0721120ab222a2605530c47d876570d45de04ec2..9d65797a91b3dea22320de0568a31bcdefadd2c9 100644 (file)
@@ -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)
index 3b24ca35b03eaa9192eb5790795204b51649f3c5..65dc6b8bb5120d1e70f90df5a9ca1bf448797531 100644 (file)
@@ -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) {
index a7b01edb0933eb69afc01749de774e7009d424f6..71c622b8c61021cdc29a90aa642b542c840bb4a9 100644 (file)
@@ -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;
 
index 58b121678d881a89513705c74c260070200593eb..955bac8fd3bd83c182a57c75739e0a25d4e559ab 100644 (file)
@@ -119,8 +119,8 @@ signed by the CA.
 
 =item B<-inform> B<DER>|B<PEM>
 
-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<openssl-format-options(1)> for details.
 
 =item B<-ss_cert> I<filename>
index fcb533a29e39915fc886ce771f25157bb5e41098..2f525f411bd073c6563cc88d6917acafbcd61567 100644 (file)
@@ -70,9 +70,14 @@ for use as root CAs for example.
 
 Print out a usage message.
 
-=item B<-inform> B<DER>|B<PEM>, B<-outform> B<DER>|B<PEM>
+=item B<-inform> B<DER>|B<PEM>
 
-The input and output formats; unspecified by default.
+The CSR input file format to use; by default PEM is tried first.
+See L<openssl-format-options(1)> for details.
+
+=item B<-outform> B<DER>|B<PEM>
+
+The output format; unspecified by default.
 See L<openssl-format-options(1)> for details.
 
 The data is a PKCS#10 object.
index d05f380bdeaf7dc1f02d9c17c53d44699a0bec45..5facce254d372a980a8141a452dfd7002793aa55 100644 (file)
@@ -155,7 +155,7 @@ The B<-ext> option can be used to further restrict which extensions to copy.
 
 =item B<-inform> B<DER>|B<PEM>
 
-The input file format; unspecified by default.
+The input file format to use; by default PEM is tried first.
 See L<openssl-format-options(1)> for details.
 
 =item B<-vfyopt> I<nm>:I<v>