diff options
author | Dr. David von Oheimb <David.von.Oheimb@siemens.com> | 2020-12-04 11:09:29 +0100 |
---|---|---|
committer | Dr. David von Oheimb <David.von.Oheimb@siemens.com> | 2020-12-10 15:19:55 +0100 |
commit | 6c9515b763aa19f11cfdc1d06cab338ae1ed5363 (patch) | |
tree | 5d39860d273b522c1ada443eeb7378db99332c33 /apps/lib/apps.c | |
parent | d858e743a9efa9d6282fdb84f3160b485bafc866 (diff) |
apps/{req,x509,ca}.c: Cleanup: move shared X509{,_REQ,_CRL} code to apps/lib/apps.c
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/13614)
Diffstat (limited to 'apps/lib/apps.c')
-rw-r--r-- | apps/lib/apps.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/apps/lib/apps.c b/apps/lib/apps.c index 699802044d..703518ce8c 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) |