From b65384233947686b880c36d784387253ae5e5e4f Mon Sep 17 00:00:00 2001 From: "Dr. David von Oheimb" Date: Tue, 15 Oct 2024 20:03:30 +0200 Subject: [PATCH] APPS/x509 and X509_sign_ctx(): add -nosig option placing pseudo algorithm 'noSignature' --- apps/lib/apps.c | 16 +++++++++++++--- apps/x509.c | 19 ++++++++++++++----- crypto/x509/x_all.c | 8 ++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/apps/lib/apps.c b/apps/lib/apps.c index 38f031197478a2..77c1b48b82166c 100644 --- a/apps/lib/apps.c +++ b/apps/lib/apps.c @@ -2335,7 +2335,7 @@ int do_X509_sign(X509 *cert, int force_v1, EVP_PKEY *pkey, const char *md, STACK_OF(OPENSSL_STRING) *sigopts, X509V3_CTX *ext_ctx) { EVP_MD_CTX *mctx = EVP_MD_CTX_new(); - int self_sign; + int add_default; int rv = 0; if (!force_v1) { @@ -2350,17 +2350,23 @@ int do_X509_sign(X509 *cert, int force_v1, EVP_PKEY *pkey, const char *md, if (!adapt_keyid_ext(cert, ext_ctx, "subjectKeyIdentifier", "hash", 1)) goto end; /* Prevent X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER */ - self_sign = cert_matches_key(cert, pkey); + add_default = pkey != NULL && !cert_matches_key(cert, pkey); if (!adapt_keyid_ext(cert, ext_ctx, "authorityKeyIdentifier", - "keyid, issuer", !self_sign)) + "keyid, issuer", add_default)) goto end; } /* May add further measures for ensuring RFC 5280 compliance, see #19805 */ + if (pkey == NULL) { + rv = X509_sign_ctx(cert, NULL); + goto end; + } if (mctx != NULL && do_sign_init(mctx, pkey, md, sigopts) > 0) rv = (X509_sign_ctx(cert, mctx) > 0); end: EVP_MD_CTX_free(mctx); + if (!rv) + BIO_printf(bio_err, "Error signing certificate\n"); return rv; } @@ -2374,6 +2380,8 @@ int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const char *md, if (do_sign_init(mctx, pkey, md, sigopts) > 0) rv = (X509_REQ_sign_ctx(x, mctx) > 0); EVP_MD_CTX_free(mctx); + if (!rv) + BIO_printf(bio_err, "Error signing PKCS#10 CSR\n"); return rv; } @@ -2387,6 +2395,8 @@ int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const char *md, if (do_sign_init(mctx, pkey, md, sigopts) > 0) rv = (X509_CRL_sign_ctx(x, mctx) > 0); EVP_MD_CTX_free(mctx); + if (!rv) + BIO_printf(bio_err, "Error signing CRL\n"); return rv; } diff --git a/apps/x509.c b/apps/x509.c index cd5b7bf796bfeb..f2cbe66f1b1565 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -43,7 +43,7 @@ typedef enum OPTION_choice { OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_KEYFORM, OPT_REQ, OPT_CAFORM, OPT_CAKEYFORM, OPT_VFYOPT, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE, - OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_KEY, OPT_SIGNKEY, OPT_CA, OPT_CAKEY, + OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_KEY, OPT_SIGNKEY, OPT_NOSIG, OPT_CA, OPT_CAKEY, OPT_CASERIAL, OPT_SET_SERIAL, OPT_NEW, OPT_FORCE_PUBKEY, OPT_ISSU, OPT_SUBJ, OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_DATEOPT, OPT_NAMEOPT, OPT_EMAIL, OPT_OCSP_URI, OPT_SERIAL, OPT_NEXT_SERIAL, @@ -78,6 +78,8 @@ const OPTIONS x509_options[] = { "Key for signing, and to include unless using -force_pubkey"}, {"signkey", OPT_SIGNKEY, 's', "Same as -key"}, + {"nosig", OPT_NOSIG, '-', + "Do not sign but use pseudo algorithm 'noSignature'"}, {"keyform", OPT_KEYFORM, 'E', "Key input format (ENGINE, other values ignored)"}, {"out", OPT_OUT, '>', "Output file - default stdout"}, @@ -292,7 +294,7 @@ int x509_main(int argc, char **argv) int fingerprint = 0, reqfile = 0, checkend = 0; int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, keyformat = FORMAT_UNDEF; int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0; - int noout = 0, CA_createserial = 0, email = 0; + int nosig = 0, noout = 0, CA_createserial = 0, email = 0; int ocsp_uri = 0, trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0; int ret = 1, i, j, num = 0, badsig = 0, clrext = 0, nocert = 0; int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0, ext = 0; @@ -416,6 +418,9 @@ int x509_main(int argc, char **argv) case OPT_SIGNKEY: privkeyfile = opt_arg(); break; + case OPT_NOSIG: + nosig = 1; + break; case OPT_CA: CAfile = opt_arg(); break; @@ -665,6 +670,10 @@ int x509_main(int argc, char **argv) "explicitly set public key")) == NULL) goto end; } + if (nosig && badsig) { + BIO_printf(bio_err, "Cannot use bot -nosig and -basig options\n"); + goto err; + } if (newcert) { if (subj == NULL) { @@ -762,10 +771,10 @@ int x509_main(int argc, char **argv) BIO_printf(bio_err, "Warning: ignoring -preserve_dates option with -req or -new\n"); preserve_dates = 0; - if (privkeyfile == NULL && CAkeyfile == NULL) { + if (privkeyfile == NULL && CAkeyfile == NULL && !nosig) { BIO_printf(bio_err, "We need a private key to sign with, use -key or -CAkey or -CA with private key\n"); - goto err; + goto end; } if ((x = X509_new_ex(app_get0_libctx(), app_get0_propq())) == NULL) goto end; @@ -939,7 +948,7 @@ int x509_main(int argc, char **argv) if (!do_X509_sign(x, 0, CAkey, digest, sigopts, &ext_ctx)) goto end; - } else if (privkey != NULL) { + } else if (privkey != NULL || nosig) { if (!do_X509_sign(x, 0, privkey, digest, sigopts, &ext_ctx)) goto end; } diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c index d3f79591d74d10..163044455c477f 100644 --- a/crypto/x509/x_all.c +++ b/crypto/x509/x_all.c @@ -107,6 +107,14 @@ int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) && !X509_set_version(x, X509_VERSION_3)) return 0; x->cert_info.enc.modified = 1; + if (ctx == NULL) { + ASN1_OBJECT *oid = OBJ_nid2obj(NID_id_alg_noSignature); + + /* TODO alg parameters MUST be present and MUST be encoded as NULL */ + return X509_ALGOR_set0(&x->cert_info.signature, oid, V_ASN1_UNDEF, NULL) + && X509_ALGOR_set0(&x->sig_alg, oid, V_ASN1_UNDEF, NULL) + && ASN1_BIT_STRING_set(&x->signature, NULL, 0); + } return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF), &x->cert_info.signature, &x->sig_alg, &x->signature, &x->cert_info, ctx);