From: Tobias Brunner Date: Thu, 11 May 2023 10:29:10 +0000 (+0200) Subject: pki: Make --dn optional for certificate renewals via --scep command X-Git-Tag: 5.9.11rc1~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5f8eb09dd665a242fbebd55e47a0080c2f983704;p=thirdparty%2Fstrongswan.git pki: Make --dn optional for certificate renewals via --scep command 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 --- diff --git a/src/pki/commands/scep.c b/src/pki/commands/scep.c index 3f58336f40..f5cc93084d 100644 --- a/src/pki/commands/scep.c +++ b/src/pki/commands/scep.c @@ -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"}, diff --git a/src/pki/man/pki---scep.1.in b/src/pki/man/pki---scep.1.in index 8817cffc11..16870fa354 100644 --- a/src/pki/man/pki---scep.1.in +++ b/src/pki/man/pki---scep.1.in @@ -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.