]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
pki: Make --dn optional for certificate renewals via --scep command
authorTobias Brunner <tobias@strongswan.org>
Thu, 11 May 2023 10:29:10 +0000 (12:29 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 17 May 2023 13:56:12 +0000 (15:56 +0200)
When using OpenXPKI, the subject DN in the renewal request has to match
the previous DN exactly.  However, because OpenXPKI may add a bunch of
DC/O RDNs to subjects of issued certificates, running --scep with the
same --dn that was used for the original request won't work (results in
a "Client error / malformed request badRequest" error even after enabling
`renewal_via_pkcs_req`).  This simplifies renewals as --dn can just be
omitted and extracted from the original certificate to avoid this issue.

References strongswan/strongswan#1689

src/pki/commands/scep.c
src/pki/man/pki---scep.1.in

index 3f58336f40c45ec6a861ed9adcb025317e36336e..f5cc93084df1c3eab53cc39ee0a461ab28b4914e 100644 (file)
@@ -215,21 +215,23 @@ static int scep()
 
        if (client_cert_file && !client_key_file)
        {
-               error = "--oldkey is required if --oldcert is set";
+               error = "--key is required if --cert is set";
                goto usage;
        }
 
-       if (!dn)
+       if (!dn && !client_cert_file)
        {
-               error = "--dn is required";
+               error = "--dn is required if --cert is not set";
                goto usage;
        }
-
-       subject = identification_create_from_string(dn);
-       if (subject->get_type(subject) != ID_DER_ASN1_DN)
+       else if (dn)
        {
-               DBG1(DBG_APP, "supplied --dn is not a distinguished name");
-               goto err;
+               subject = identification_create_from_string(dn);
+               if (subject->get_type(subject) != ID_DER_ASN1_DN)
+               {
+                       DBG1(DBG_APP, "supplied --dn is not a distinguished name");
+                       goto err;
+               }
        }
 
        /* load RSA private key from file or stdin */
@@ -329,43 +331,19 @@ static int scep()
        }
        DBG2(DBG_APP, "HTTP POST %ssupported", http_post ? "" : "not ");
 
-       scheme = get_signature_scheme(private, digest_alg, pss);
-       if (!scheme)
-       {
-               DBG1(DBG_APP, "no signature scheme found");
-               goto err;
-       }
-
-       /* generate PKCS#10 certificate request */
-       pkcs10 = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST,
-                                                       BUILD_SIGNING_KEY, private,
-                                                       BUILD_SUBJECT, subject,
-                                                       BUILD_SUBJECT_ALTNAMES, san,
-                                                       BUILD_CHALLENGE_PWD, challenge_password,
-                                                       BUILD_CERT_TYPE_EXT, cert_type,
-                                                       BUILD_SIGNATURE_SCHEME, scheme,
-                                                       BUILD_END);
-       if (!pkcs10)
-       {
-               DBG1(DBG_APP, "generating certificate request failed");
-               goto err;
-       }
-
-       /* generate PKCS#10 encoding */
-       if (!pkcs10->get_encoding(pkcs10, CERT_ASN1_DER, &pkcs10_encoding))
+       if (!scep_generate_transaction_id(public, &transID, &serialNumber))
        {
-               DBG1(DBG_APP, "encoding certificate request failed");
-               pkcs10->destroy(pkcs10);
+               DBG1(DBG_APP, "generating transaction ID failed");
                goto err;
        }
-       pkcs10->destroy(pkcs10);
+       DBG1(DBG_APP, "transaction ID: %.*s", (int)transID.len, transID.ptr);
 
-       if (!scep_generate_transaction_id(public, &transID, &serialNumber))
+       scheme = get_signature_scheme(private, digest_alg, pss);
+       if (!scheme)
        {
-               DBG1(DBG_APP, "generating transaction ID failed");
+               DBG1(DBG_APP, "no signature scheme found");
                goto err;
        }
-       DBG1(DBG_APP, "transaction ID: %.*s", (int)transID.len, transID.ptr);
 
        if (client_cert_file)
        {
@@ -401,6 +379,12 @@ static int scep()
                        x509_signer->destroy(x509_signer);
                        goto err;
                }
+
+               if (!subject)
+               {
+                       subject = x509_signer->get_subject(x509_signer);
+                       subject = subject->clone(subject);
+               }
        }
        else
        {
@@ -435,6 +419,30 @@ static int scep()
        client_creds->add_cert(client_creds, FALSE, x509_signer);
        client_creds->add_key(client_creds, priv_signer);
 
+       /* generate PKCS#10 certificate request */
+       pkcs10 = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST,
+                                                       BUILD_SIGNING_KEY, private,
+                                                       BUILD_SUBJECT, subject,
+                                                       BUILD_SUBJECT_ALTNAMES, san,
+                                                       BUILD_CHALLENGE_PWD, challenge_password,
+                                                       BUILD_CERT_TYPE_EXT, cert_type,
+                                                       BUILD_SIGNATURE_SCHEME, scheme,
+                                                       BUILD_END);
+       if (!pkcs10)
+       {
+               DBG1(DBG_APP, "generating certificate request failed");
+               goto err;
+       }
+
+       /* generate PKCS#10 encoding */
+       if (!pkcs10->get_encoding(pkcs10, CERT_ASN1_DER, &pkcs10_encoding))
+       {
+               DBG1(DBG_APP, "encoding certificate request failed");
+               pkcs10->destroy(pkcs10);
+               goto err;
+       }
+       pkcs10->destroy(pkcs10);
+
        /* load CA or RA certificate used for encryption */
        x509_ca_enc = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
                                                                        BUILD_FROM_FILE, ca_enc_file, BUILD_END);
@@ -622,17 +630,17 @@ static void __attribute__ ((constructor))reg()
        command_register((command_t) {
                scep, 'S', "scep",
                "Enroll an X.509 certificate with a SCEP server",
-               {"--url url [--in file] --dn distinguished-name [--san subjectAltName]+",
+               {"--url url [--in file] [--dn distinguished-name] [--san subjectAltName]+",
                 "[--profile profile] [--password password]",
                 " --cacert-enc file --cacert-sig file [--cacert file]+",
-                " --oldcert file --oldkey file] [--cipher aes|des3]",
+                " --cert file --key file] [--cipher aes|des3]",
                 "[--digest sha256|sha384|sha512|sha224|sha1] [--rsa-padding pkcs1|pss]",
                 "[--interval time] [--maxpolltime time] [--outform der|pem]"},
                {
                        {"help",        'h', 0, "show usage information"},
                        {"url",         'u', 1, "URL of the SCEP server"},
                        {"in",          'i', 1, "RSA private key input file, default: stdin"},
-                       {"dn",          'd', 1, "subject distinguished name"},
+                       {"dn",          'd', 1, "subject distinguished name (optional if --cert is given)"},
                        {"san",         'a', 1, "subjectAltName to include in cert request"},
                        {"profile",     'P', 1, "certificate profile name to include in cert request"},
                        {"password",    'p', 1, "challengePassword to include in cert request"},
index 8817cffc11f16c016ce7002763c64012213d4297..16870fa3542bfef9ededa01b9c393ff4e818d70e 100644 (file)
@@ -70,7 +70,7 @@ URL of the SCEP server.
 RSA private key. If not given the key is read from \fISTDIN\fR.
 .TP
 .BI "\-d, \-\-dn " distinguished-name
-Subject distinguished name (DN). Required.
+Subject distinguished name (DN). Required unless \-\-cert is given.
 .TP
 .BI "\-a, \-\-san " subjectAltName
 subjectAltName extension to include in request. Can be used multiple times.