From: Dr. David von Oheimb Date: Fri, 4 Dec 2020 10:09:29 +0000 (+0100) Subject: apps/{req,x509,ca}.c: Cleanup: move shared X509{,_REQ,_CRL} code to apps/lib/apps.c X-Git-Tag: openssl-3.0.0-alpha10~95 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6c9515b763aa19f11cfdc1d06cab338ae1ed5363;p=thirdparty%2Fopenssl.git apps/{req,x509,ca}.c: Cleanup: move shared X509{,_REQ,_CRL} code to apps/lib/apps.c Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/13614) --- diff --git a/apps/lib/apps.c b/apps/lib/apps.c index 699802044d3..703518ce8c5 100644 --- a/apps/lib/apps.c +++ b/apps/lib/apps.c @@ -1906,6 +1906,152 @@ void print_cert_checks(BIO *bio, X509 *x, } } +static int do_pkey_ctx_init(EVP_PKEY_CTX *pkctx, STACK_OF(OPENSSL_STRING) *opts) +{ + int i; + + if (opts == NULL) + return 1; + + for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { + char *opt = sk_OPENSSL_STRING_value(opts, i); + if (pkey_ctrl_string(pkctx, opt) <= 0) { + BIO_printf(bio_err, "parameter error \"%s\"\n", opt); + ERR_print_errors(bio_err); + return 0; + } + } + + return 1; +} + +static int do_x509_init(X509 *x, STACK_OF(OPENSSL_STRING) *opts) +{ + int i; + + if (opts == NULL) + return 1; + + for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { + char *opt = sk_OPENSSL_STRING_value(opts, i); + if (x509_ctrl_string(x, opt) <= 0) { + BIO_printf(bio_err, "parameter error \"%s\"\n", opt); + ERR_print_errors(bio_err); + return 0; + } + } + + return 1; +} + +static int do_x509_req_init(X509_REQ *x, STACK_OF(OPENSSL_STRING) *opts) +{ + int i; + + if (opts == NULL) + return 1; + + for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { + char *opt = sk_OPENSSL_STRING_value(opts, i); + if (x509_req_ctrl_string(x, opt) <= 0) { + BIO_printf(bio_err, "parameter error \"%s\"\n", opt); + ERR_print_errors(bio_err); + return 0; + } + } + + return 1; +} + +static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey, + const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts) +{ + EVP_PKEY_CTX *pkctx = NULL; + int def_nid; + + if (ctx == NULL) + return 0; + /* + * EVP_PKEY_get_default_digest_nid() returns 2 if the digest is mandatory + * for this algorithm. + */ + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) == 2 + && def_nid == NID_undef) { + /* The signing algorithm requires there to be no digest */ + md = NULL; + } + return EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey) + && do_pkey_ctx_init(pkctx, sigopts); +} + +/* Ensure RFC 5280 compliance and then sign the certificate info */ +int do_X509_sign(X509 *cert, EVP_PKEY *pkey, const EVP_MD *md, + STACK_OF(OPENSSL_STRING) *sigopts) +{ + const STACK_OF(X509_EXTENSION) *exts = X509_get0_extensions(cert); + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); + int rv = 0; + + if (sk_X509_EXTENSION_num(exts /* may be NULL */) > 0) { + /* Prevent X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 */ + if (!X509_set_version(cert, 2)) /* Make sure cert is X509 v3 */ + goto end; + + /* TODO any further measures for ensuring default RFC 5280 compliance */ + } + + if (mctx != NULL && do_sign_init(mctx, pkey, md, sigopts) > 0) + rv = (X509_sign_ctx(cert, mctx) > 0); + end: + EVP_MD_CTX_free(mctx); + return rv; +} + +/* Sign the certificate request info */ +int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, + STACK_OF(OPENSSL_STRING) *sigopts) +{ + int rv = 0; + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); + + if (do_sign_init(mctx, pkey, md, sigopts) > 0) + rv = (X509_REQ_sign_ctx(x, mctx) > 0); + EVP_MD_CTX_free(mctx); + return rv; +} + +/* Sign the CRL info */ +int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, + STACK_OF(OPENSSL_STRING) *sigopts) +{ + int rv = 0; + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); + + if (do_sign_init(mctx, pkey, md, sigopts) > 0) + rv = (X509_CRL_sign_ctx(x, mctx) > 0); + EVP_MD_CTX_free(mctx); + return rv; +} + +int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts) +{ + int rv = 0; + + if (do_x509_init(x, vfyopts) > 0) + rv = (X509_verify(x, pkey) > 0); + return rv; +} + +int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey, + STACK_OF(OPENSSL_STRING) *vfyopts) +{ + int rv = 0; + + if (do_x509_req_init(x, vfyopts) > 0) + rv = (X509_REQ_verify(x, pkey) > 0); + return rv; +} + /* Get first http URL from a DIST_POINT structure */ static const char *get_dp_url(DIST_POINT *dp) diff --git a/apps/req.c b/apps/req.c index 27cfbd6017c..bc23c7d3a53 100644 --- a/apps/req.c +++ b/apps/req.c @@ -1626,147 +1626,3 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx) (void)BIO_flush(b); return 1; } - -static int do_pkey_ctx_init(EVP_PKEY_CTX *pkctx, STACK_OF(OPENSSL_STRING) *opts) -{ - int i; - - if (opts == NULL) - return 1; - - for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { - char *opt = sk_OPENSSL_STRING_value(opts, i); - if (pkey_ctrl_string(pkctx, opt) <= 0) { - BIO_printf(bio_err, "parameter error \"%s\"\n", opt); - ERR_print_errors(bio_err); - return 0; - } - } - - return 1; -} - -static int do_x509_init(X509 *x, STACK_OF(OPENSSL_STRING) *opts) -{ - int i; - - if (opts == NULL) - return 1; - - for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { - char *opt = sk_OPENSSL_STRING_value(opts, i); - if (x509_ctrl_string(x, opt) <= 0) { - BIO_printf(bio_err, "parameter error \"%s\"\n", opt); - ERR_print_errors(bio_err); - return 0; - } - } - - return 1; -} - -static int do_x509_req_init(X509_REQ *x, STACK_OF(OPENSSL_STRING) *opts) -{ - int i; - - if (opts == NULL) - return 1; - - for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { - char *opt = sk_OPENSSL_STRING_value(opts, i); - if (x509_req_ctrl_string(x, opt) <= 0) { - BIO_printf(bio_err, "parameter error \"%s\"\n", opt); - ERR_print_errors(bio_err); - return 0; - } - } - - return 1; -} - -static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey, - const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts) -{ - EVP_PKEY_CTX *pkctx = NULL; - int def_nid; - - if (ctx == NULL) - return 0; - /* - * EVP_PKEY_get_default_digest_nid() returns 2 if the digest is mandatory - * for this algorithm. - */ - if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) == 2 - && def_nid == NID_undef) { - /* The signing algorithm requires there to be no digest */ - md = NULL; - } - return EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey) - && do_pkey_ctx_init(pkctx, sigopts); -} - -/* Ensure RFC 5280 compliance and then sign the certificate info */ -int do_X509_sign(X509 *cert, EVP_PKEY *pkey, const EVP_MD *md, - STACK_OF(OPENSSL_STRING) *sigopts) -{ - const STACK_OF(X509_EXTENSION) *exts = X509_get0_extensions(cert); - EVP_MD_CTX *mctx = EVP_MD_CTX_new(); - int rv = 0; - - if (sk_X509_EXTENSION_num(exts /* may be NULL */) > 0) { - /* Prevent X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 */ - if (!X509_set_version(cert, 2)) /* Make sure cert is X509 v3 */ - goto end; - - /* TODO any further measures for ensuring default RFC 5280 compliance */ - } - - if (mctx != NULL && do_sign_init(mctx, pkey, md, sigopts) > 0) - rv = (X509_sign_ctx(cert, mctx) > 0); - end: - EVP_MD_CTX_free(mctx); - return rv; -} - -int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, - STACK_OF(OPENSSL_STRING) *sigopts) -{ - int rv = 0; - EVP_MD_CTX *mctx = EVP_MD_CTX_new(); - - if (do_sign_init(mctx, pkey, md, sigopts) > 0) - rv = (X509_REQ_sign_ctx(x, mctx) > 0); - EVP_MD_CTX_free(mctx); - return rv; -} - -int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts) -{ - int rv = 0; - - if (do_x509_init(x, vfyopts) > 0) - rv = (X509_verify(x, pkey) > 0); - return rv; -} - -int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey, - STACK_OF(OPENSSL_STRING) *vfyopts) -{ - int rv = 0; - - if (do_x509_req_init(x, vfyopts) > 0) - rv = (X509_REQ_verify(x, pkey) > 0); - return rv; -} - -int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, - STACK_OF(OPENSSL_STRING) *sigopts) -{ - int rv = 0; - EVP_MD_CTX *mctx = EVP_MD_CTX_new(); - - if (do_sign_init(mctx, pkey, md, sigopts) > 0) - rv = (X509_CRL_sign_ctx(x, mctx) > 0); - EVP_MD_CTX_free(mctx); - return rv; -}