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
This commit is contained in:
Tobias Brunner
2023-05-17 15:56:12 +02:00
parent 7fa85ff379
commit 5f8eb09dd6
2 changed files with 51 additions and 43 deletions
+50 -42
View File
@@ -215,21 +215,23 @@ static int scep()
if (client_cert_file && !client_key_file) 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; goto usage;
} }
if (!dn) if (!dn && !client_cert_file)
{ {
error = "--dn is required"; error = "--dn is required if --cert is not set";
goto usage; goto usage;
} }
else if (dn)
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"); subject = identification_create_from_string(dn);
goto err; 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 */ /* load RSA private key from file or stdin */
@@ -329,37 +331,6 @@ static int scep()
} }
DBG2(DBG_APP, "HTTP POST %ssupported", http_post ? "" : "not "); 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))
{
DBG1(DBG_APP, "encoding certificate request failed");
pkcs10->destroy(pkcs10);
goto err;
}
pkcs10->destroy(pkcs10);
if (!scep_generate_transaction_id(public, &transID, &serialNumber)) if (!scep_generate_transaction_id(public, &transID, &serialNumber))
{ {
DBG1(DBG_APP, "generating transaction ID failed"); DBG1(DBG_APP, "generating transaction ID failed");
@@ -367,6 +338,13 @@ static int scep()
} }
DBG1(DBG_APP, "transaction ID: %.*s", (int)transID.len, transID.ptr); DBG1(DBG_APP, "transaction ID: %.*s", (int)transID.len, transID.ptr);
scheme = get_signature_scheme(private, digest_alg, pss);
if (!scheme)
{
DBG1(DBG_APP, "no signature scheme found");
goto err;
}
if (client_cert_file) if (client_cert_file)
{ {
/* check support of Renewal Operation */ /* check support of Renewal Operation */
@@ -401,6 +379,12 @@ static int scep()
x509_signer->destroy(x509_signer); x509_signer->destroy(x509_signer);
goto err; goto err;
} }
if (!subject)
{
subject = x509_signer->get_subject(x509_signer);
subject = subject->clone(subject);
}
} }
else else
{ {
@@ -435,6 +419,30 @@ static int scep()
client_creds->add_cert(client_creds, FALSE, x509_signer); client_creds->add_cert(client_creds, FALSE, x509_signer);
client_creds->add_key(client_creds, priv_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 */ /* load CA or RA certificate used for encryption */
x509_ca_enc = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, x509_ca_enc = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_FROM_FILE, ca_enc_file, BUILD_END); BUILD_FROM_FILE, ca_enc_file, BUILD_END);
@@ -622,17 +630,17 @@ static void __attribute__ ((constructor))reg()
command_register((command_t) { command_register((command_t) {
scep, 'S', "scep", scep, 'S', "scep",
"Enroll an X.509 certificate with a SCEP server", "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]", "[--profile profile] [--password password]",
" --cacert-enc file --cacert-sig file [--cacert file]+", " --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]", "[--digest sha256|sha384|sha512|sha224|sha1] [--rsa-padding pkcs1|pss]",
"[--interval time] [--maxpolltime time] [--outform der|pem]"}, "[--interval time] [--maxpolltime time] [--outform der|pem]"},
{ {
{"help", 'h', 0, "show usage information"}, {"help", 'h', 0, "show usage information"},
{"url", 'u', 1, "URL of the SCEP server"}, {"url", 'u', 1, "URL of the SCEP server"},
{"in", 'i', 1, "RSA private key input file, default: stdin"}, {"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"}, {"san", 'a', 1, "subjectAltName to include in cert request"},
{"profile", 'P', 1, "certificate profile name 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"}, {"password", 'p', 1, "challengePassword to include in cert request"},
+1 -1
View File
@@ -70,7 +70,7 @@ URL of the SCEP server.
RSA private key. If not given the key is read from \fISTDIN\fR. RSA private key. If not given the key is read from \fISTDIN\fR.
.TP .TP
.BI "\-d, \-\-dn " distinguished-name .BI "\-d, \-\-dn " distinguished-name
Subject distinguished name (DN). Required. Subject distinguished name (DN). Required unless \-\-cert is given.
.TP .TP
.BI "\-a, \-\-san " subjectAltName .BI "\-a, \-\-san " subjectAltName
subjectAltName extension to include in request. Can be used multiple times. subjectAltName extension to include in request. Can be used multiple times.