diff options
author | Andy Fiddaman <omnios@citrus-it.co.uk> | 2018-01-16 21:39:56 +0000 |
---|---|---|
committer | Dan McDonald <danmcd@joyent.com> | 2018-05-02 22:06:02 -0400 |
commit | 300fdee27f8b59b381c1a0316bdee52fdfdb9213 (patch) | |
tree | b1968149c7837343badd37f984681a0d007b598e | |
parent | bb1f424574ac8e08069d0ba993c2a41ffe796794 (diff) | |
download | illumos-joyent-300fdee27f8b59b381c1a0316bdee52fdfdb9213.tar.gz |
8982 Support building with OpenSSL 1.1
Reviewed by: Dominik Hassler <hadfl@omniosce.org>
Reviewed by: Igor Kozhukhov <igor@dilos.org>
Reviewed by: Ken Mays <maybird1776@yahoo.com>
Reviewed by: Jason King <jason.king@joyent.com>
Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r-- | usr/src/Makefile | 11 | ||||
-rw-r--r-- | usr/src/Makefile.master | 2 | ||||
-rw-r--r-- | usr/src/cmd/sendmail/src/tls.c | 255 | ||||
-rw-r--r-- | usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 696 | ||||
-rw-r--r-- | usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h | 22 | ||||
-rw-r--r-- | usr/src/lib/libkmf/plugins/kmf_openssl/Makefile.com | 2 | ||||
-rw-r--r-- | usr/src/lib/libkmf/plugins/kmf_openssl/common/compat.c | 446 | ||||
-rw-r--r-- | usr/src/lib/libkmf/plugins/kmf_openssl/common/compat.h | 91 | ||||
-rw-r--r-- | usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c | 683 | ||||
-rw-r--r-- | usr/src/tools/scripts/nightly.sh | 3 |
10 files changed, 1496 insertions, 715 deletions
diff --git a/usr/src/Makefile b/usr/src/Makefile index 26e0988215..ab1aedfc46 100644 --- a/usr/src/Makefile +++ b/usr/src/Makefile @@ -26,6 +26,7 @@ # Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2016 Toomas Soome <tsoome@me.com> # Copyright 2017 Joyent, Inc. +# Copyright 2018 OmniOS Community Edition (OmniOSce) Association. # # @@ -286,3 +287,13 @@ java-version: $(ECHO) No Java compiler found; \ exit 1; \ fi + +openssl-version: + @if [ -x "$(OPENSSL)" ]; then \ + $(ECHO) $(OPENSSL); \ + $(OPENSSL) version; \ + $(OPENSSL) version -f | \ + $(SED) -n '/_API/{s/.*_API/ API/;s/ -.*//;p;}'; \ + else \ + $(ECHO) No OpenSSL utility found; \ + fi diff --git a/usr/src/Makefile.master b/usr/src/Makefile.master index b59ba05d1e..a264148c67 100644 --- a/usr/src/Makefile.master +++ b/usr/src/Makefile.master @@ -27,6 +27,7 @@ # Copyright 2015 Gary Mills # Copyright 2015 Igor Kozhukhov <ikozhukhov@gmail.com> # Copyright 2016 Toomas Soome <tsoome@me.com> +# Copyright 2018 OmniOS Community Edition (OmniOSce) Association. # # @@ -207,6 +208,7 @@ MSGFMT= /usr/bin/msgfmt -s LCDEF= $(ONBLD_TOOLS)/bin/$(MACH)/localedef TIC= $(ONBLD_TOOLS)/bin/$(MACH)/tic ZIC= $(ONBLD_TOOLS)/bin/$(MACH)/zic +OPENSSL= /usr/bin/openssl FILEMODE= 644 DIRMODE= 755 diff --git a/usr/src/cmd/sendmail/src/tls.c b/usr/src/cmd/sendmail/src/tls.c index af53754750..605d91635a 100644 --- a/usr/src/cmd/sendmail/src/tls.c +++ b/usr/src/cmd/sendmail/src/tls.c @@ -2,6 +2,7 @@ * Copyright (c) 2000-2006, 2008, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved. + * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of @@ -17,34 +18,66 @@ SM_RCSID("@(#)$Id: tls.c,v 8.114 2009/08/10 15:11:09 ca Exp $") # include <openssl/err.h> # include <openssl/bio.h> # include <openssl/pem.h> +# include <openssl/bn.h> # ifndef HASURANDOMDEV # include <openssl/rand.h> # endif /* ! HASURANDOMDEV */ # if !TLS_NO_RSA +# include <openssl/rsa.h> static RSA *rsa_tmp = NULL; /* temporary RSA key */ -static RSA *tmp_rsa_key __P((SSL *, int, int)); # endif /* !TLS_NO_RSA */ -# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L -static int tls_verify_cb __P((X509_STORE_CTX *)); -# else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */ static int tls_verify_cb __P((X509_STORE_CTX *, void *)); -# endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */ - -# if OPENSSL_VERSION_NUMBER > 0x00907000L static int x509_verify_cb __P((int, X509_STORE_CTX *)); -# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ -# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L -# define CONST097 -# else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */ # define CONST097 const -# endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */ static void apps_ssl_info_cb __P((CONST097 SSL *, int , int)); static bool tls_ok_f __P((char *, char *, int)); static bool tls_safe_f __P((char *, long, bool)); static int tls_verify_log __P((int, X509_STORE_CTX *, char *)); # if !NO_DH +# include <openssl/dh.h> +# include <openssl/dsa.h> + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + +/* + * This compatibility function is taken from + * https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes + * #Adding_forward-compatible_code_to_older_versions + */ + +#define DH_set0_pqg __DH_set0_pqg +int __DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + /* If the fields p and g in d are NULL, the corresponding input + * parameters MUST be non-NULL. q may remain NULL. + */ + if ((dh->p == NULL && p == NULL) + || (dh->g == NULL && g == NULL)) + return 0; + + if (p != NULL) { + BN_free(dh->p); + dh->p = p; + } + if (q != NULL) { + BN_free(dh->q); + dh->q = q; + } + if (g != NULL) { + BN_free(dh->g); + dh->g = g; + } + + if (q != NULL) { + dh->length = BN_num_bits(q); + } + + return 1; +} +#endif + static DH *get_dh512 __P((void)); static unsigned char dh512_p[] = @@ -65,13 +98,21 @@ static DH * get_dh512() { DH *dh = NULL; + BIGNUM *p, *g; if ((dh = DH_new()) == NULL) return NULL; - dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL); - dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL); - if ((dh->p == NULL) || (dh->g == NULL)) + p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL); + g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL); + if ((p == NULL) || (g == NULL)) { + BN_free(p); + BN_free(g); + DH_free(dh); return NULL; + } + + DH_set0_pqg(dh, p, NULL, g); + return dh; } # endif /* !NO_DH */ @@ -278,8 +319,11 @@ bool init_tls_library() { /* basic TLS initialization, ignore result for now */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L + /* No longer available (nor necessary) in OpenSSL 1.1 */ SSL_library_init(); SSL_load_error_strings(); +#endif # if 0 /* this is currently a macro for SSL_library_init */ SSLeay_add_ssl_algorithms(); @@ -508,13 +552,6 @@ tls_safe_f(var, sff, srv) static char server_session_id_context[] = "sendmail8"; -/* 0.9.8a and b have a problem with SSL_OP_TLS_BLOCK_PADDING_BUG */ -#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) -# define SM_SSL_OP_TLS_BLOCK_PADDING_BUG 1 -#else -# define SM_SSL_OP_TLS_BLOCK_PADDING_BUG 0 -#endif - bool inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) SSL_CTX **ctx; @@ -536,15 +573,9 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar # if SM_CONF_SHM extern int ShmId; # endif /* SM_CONF_SHM */ -# if OPENSSL_VERSION_NUMBER > 0x00907000L BIO *crl_file; X509_CRL *crl; X509_STORE *store; -# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ -#if SM_SSL_OP_TLS_BLOCK_PADDING_BUG - long rt_version; - STACK_OF(SSL_COMP) *comp_methods; -#endif status = TLS_S_NONE; who = srv ? "server" : "client"; @@ -593,11 +624,8 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar TLS_S_CERTP_EX, TLS_T_OTHER); TLS_OK_F(cacertfile, "CACertFile", bitset(TLS_I_CERTF_EX, req), TLS_S_CERTF_EX, TLS_T_OTHER); - -# if OPENSSL_VERSION_NUMBER > 0x00907000L TLS_OK_F(CRLFile, "CRLFile", bitset(TLS_I_CRLF_EX, req), TLS_S_CRLF_EX, TLS_T_OTHER); -# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ # if _FFR_TLS_1 /* @@ -679,11 +707,9 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar TLS_SAFE_F(dhparam, sff | TLS_UNR(TLS_I_DHPAR_UNR, req), bitset(TLS_I_DHPAR_EX, req), bitset(TLS_S_DHPAR_EX, status), TLS_S_DHPAR_OK, srv); -# if OPENSSL_VERSION_NUMBER > 0x00907000L TLS_SAFE_F(CRLFile, sff | TLS_UNR(TLS_I_CRLF_UNR, req), bitset(TLS_I_CRLF_EX, req), bitset(TLS_S_CRLF_EX, status), TLS_S_CRLF_OK, srv); -# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ if (!ok) return ok; # if _FFR_TLS_1 @@ -714,12 +740,11 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar return false; } -# if OPENSSL_VERSION_NUMBER > 0x00907000L if (CRLFile != NULL) { /* get a pointer to the current certificate validation store */ store = SSL_CTX_get_cert_store(*ctx); /* does not fail */ - crl_file = BIO_new(BIO_s_file_internal()); + crl_file = BIO_new(BIO_s_file()); if (crl_file != NULL) { if (BIO_read_filename(crl_file, CRLFile) >= 0) @@ -776,7 +801,6 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); } # endif /* _FFR_CRLPATH */ -# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ # if TLS_NO_RSA /* turn off backward compatibility, required for no-rsa */ @@ -795,23 +819,33 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar if (bitset(TLS_I_RSA_TMP, req) # if SM_CONF_SHM - && ShmId != SM_SHM_NO_ID && - (rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL, - NULL)) == NULL + && ShmId != SM_SHM_NO_ID # else /* SM_CONF_SHM */ && 0 /* no shared memory: no need to generate key now */ # endif /* SM_CONF_SHM */ - ) + ) { - if (LogLevel > 7) + BIGNUM *e = BN_new(); + BN_set_word(e, RSA_F4); + + if ((rsa_tmp = RSA_new()) == NULL || RSA_generate_key_ex( + rsa_tmp, RSA_KEYLENGTH, e, NULL) == 0) { - sm_syslog(LOG_WARNING, NOQID, - "STARTTLS=%s, error: RSA_generate_key failed", - who); - if (LogLevel > 9) - tlslogerr(who); + BN_free(e); + if (rsa_tmp != NULL) + RSA_free(rsa_tmp); + rsa_tmp = NULL; + if (LogLevel > 7) + { + sm_syslog(LOG_WARNING, NOQID, + "STARTTLS=%s, error: RSA_generate_key failed", + who); + if (LogLevel > 9) + tlslogerr(who); + } + return false; } - return false; + BN_free(e); } # endif /* !TLS_NO_RSA */ @@ -919,26 +953,6 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar /* SSL_CTX_set_quiet_shutdown(*ctx, 1); violation of standard? */ -#if SM_SSL_OP_TLS_BLOCK_PADDING_BUG - - /* - ** In OpenSSL 0.9.8[ab], enabling zlib compression breaks the - ** padding bug work-around, leading to false positives and - ** failed connections. We may not interoperate with systems - ** with the bug, but this is better than breaking on all 0.9.8[ab] - ** systems that have zlib support enabled. - ** Note: this checks the runtime version of the library, not - ** just the compile time version. - */ - - rt_version = SSLeay(); - if (rt_version >= 0x00908000L && rt_version <= 0x0090802fL) - { - comp_methods = SSL_COMP_get_compression_methods(); - if (comp_methods != NULL && sk_SSL_COMP_num(comp_methods) > 0) - options &= ~SSL_OP_TLS_BLOCK_PADDING_BUG; - } -#endif SSL_CTX_set_options(*ctx, options); # if !NO_DH @@ -980,16 +994,19 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar } if (dh == NULL && bitset(TLS_I_DH1024, req)) { - DSA *dsa; + DSA *dsa = NULL; /* this takes a while! (7-130s on a 450MHz AMD K6-2) */ - dsa = DSA_generate_parameters(1024, NULL, 0, NULL, - NULL, 0, NULL); - dh = DSA_dup_DH(dsa); - DSA_free(dsa); + if ((dsa = DSA_new()) == NULL || + DSA_generate_parameters_ex(dsa, 1024, + NULL, 0, NULL, 0, NULL) == 0) + dh = NULL; + else + dh = DSA_dup_DH(dsa); + if (dsa != NULL) + DSA_free(dsa); } - else - if (dh == NULL && bitset(TLS_I_DH512, req)) + else if (dh == NULL && bitset(TLS_I_DH512, req)) dh = get_dh512(); if (dh == NULL) @@ -1046,11 +1063,6 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar if ((r = SSL_CTX_load_verify_locations(*ctx, cacertfile, cacertpath)) == 1) { -# if !TLS_NO_RSA - if (bitset(TLS_I_RSA_TMP, req)) - SSL_CTX_set_tmp_rsa_callback(*ctx, tmp_rsa_key); -# endif /* !TLS_NO_RSA */ - /* ** We have to install our own verify callback: ** SSL_VERIFY_PEER requests a client cert but even @@ -1186,7 +1198,7 @@ tls_get_info(ssl, srv, host, mac, certreq) macdefine(mac, A_TEMP, macid("{cipher_bits}"), bitstr); (void) sm_snprintf(bitstr, sizeof(bitstr), "%d", r); macdefine(mac, A_TEMP, macid("{alg_bits}"), bitstr); - s = SSL_CIPHER_get_version(c); + s = (char *)SSL_CIPHER_get_version(c); if (s == NULL) s = "UNKNOWN"; macdefine(mac, A_TEMP, macid("{tls_version}"), s); @@ -1380,7 +1392,6 @@ endtls(ssl, side) } ret = EX_SOFTWARE; } -# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER > 0x0090602fL /* ** Bug in OpenSSL (at least up to 0.9.6b): @@ -1429,78 +1440,12 @@ endtls(ssl, side) } ret = EX_SOFTWARE; } -# endif /* !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER > 0x0090602fL */ SSL_free(ssl); ssl = NULL; } return ret; } -# if !TLS_NO_RSA -/* -** TMP_RSA_KEY -- return temporary RSA key -** -** Parameters: -** s -- TLS connection structure -** export -- -** keylength -- -** -** Returns: -** temporary RSA key. -*/ - -# ifndef MAX_RSA_TMP_CNT -# define MAX_RSA_TMP_CNT 1000 /* XXX better value? */ -# endif /* ! MAX_RSA_TMP_CNT */ - -/* ARGUSED0 */ -static RSA * -tmp_rsa_key(s, export, keylength) - SSL *s; - int export; - int keylength; -{ -# if SM_CONF_SHM - extern int ShmId; - extern int *PRSATmpCnt; - - if (ShmId != SM_SHM_NO_ID && rsa_tmp != NULL && - ++(*PRSATmpCnt) < MAX_RSA_TMP_CNT) - return rsa_tmp; -# endif /* SM_CONF_SHM */ - - if (rsa_tmp != NULL) - RSA_free(rsa_tmp); - rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL, NULL); - if (rsa_tmp == NULL) - { - if (LogLevel > 0) - sm_syslog(LOG_ERR, NOQID, - "STARTTLS=server, tmp_rsa_key: RSA_generate_key failed!"); - } - else - { -# if SM_CONF_SHM -# if 0 - /* - ** XXX we can't (yet) share the new key... - ** The RSA structure contains pointers hence it can't be - ** easily kept in shared memory. It must be transformed - ** into a continous memory region first, then stored, - ** and later read out again (each time re-transformed). - */ - - if (ShmId != SM_SHM_NO_ID) - *PRSATmpCnt = 0; -# endif /* 0 */ -# endif /* SM_CONF_SHM */ - if (LogLevel > 9) - sm_syslog(LOG_ERR, NOQID, - "STARTTLS=server, tmp_rsa_key: new temp RSA key"); - } - return rsa_tmp; -} -# endif /* !TLS_NO_RSA */ /* ** APPS_SSL_INFO_CB -- info callback for TLS connections ** @@ -1629,14 +1574,9 @@ tls_verify_log(ok, ctx, name) */ static int -# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L -tls_verify_cb(ctx) - X509_STORE_CTX *ctx; -# else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */ tls_verify_cb(ctx, unused) X509_STORE_CTX *ctx; void *unused; -# endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */ { int ok; @@ -1675,7 +1615,11 @@ tlslogerr(who) char buf[256]; # define CP (const char **) +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + es = 0; +#else es = CRYPTO_thread_id(); +#endif while ((l = ERR_get_error_line_data(CP &file, &line, CP &data, &flags)) != 0) { @@ -1687,7 +1631,6 @@ tlslogerr(who) } } -# if OPENSSL_VERSION_NUMBER > 0x00907000L /* ** X509_VERIFY_CB -- verify callback ** @@ -1708,13 +1651,13 @@ x509_verify_cb(ok, ctx) { if (LogLevel > 13) tls_verify_log(ok, ctx, "x509"); - if (ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL) + if (X509_STORE_CTX_get_error(ctx) + == X509_V_ERR_UNABLE_TO_GET_CRL) { - ctx->error = 0; + X509_STORE_CTX_set_error(ctx, 0); return 1; /* override it */ } } return ok; } -# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ #endif /* STARTTLS */ diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c index fa903130e9..00ad9a3afc 100644 --- a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c +++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c @@ -31,6 +31,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved. + * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. */ #include <errno.h> @@ -369,6 +370,101 @@ unsigned char pkinit_4096_dhprime[4096/8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +#if OPENSSL_VERSION_NUMBER < 0x10100000L +/* + * Many things have changed in OpenSSL 1.1. The code in this file has been + * updated to use the v1.1 APIs but some are new and require emulation + * for older OpenSSL versions. + */ + +/* EVP_MD_CTX construct and destructor names have changed */ + +#define EVP_MD_CTX_new EVP_MD_CTX_create +#define EVP_MD_CTX_free EVP_MD_CTX_destroy + +/* ASN1_STRING_data is deprecated */ +#define ASN1_STRING_get0_data ASN1_STRING_data + +/* X509_STORE_CTX_trusted_stack is deprecated */ +#define X509_STORE_CTX_set0_trusted_stack X509_STORE_CTX_trusted_stack + +/* get_rfc2409_prime_1024() has been renamed. */ +#define BN_get_rfc2409_prime_1024 get_rfc2409_prime_1024 + +#define OBJ_get0_data(o) ((o)->data) +#define OBJ_length(o) ((o)->length) + +/* Some new DH functions that aren't in OpenSSL 1.0.x */ +#define DH_bits(dh) BN_num_bits((dh)->p); + +#define DH_set0_pqg(dh, p, q, g) __DH_set0_pqg(dh, p, q, g) +static int +__DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL)) + return 0; + + if (p != NULL) { + BN_free(dh->p); + dh->p = p; + } + if (q != NULL) { + BN_free(dh->q); + dh->q = q; + } + if (g != NULL) { + BN_free(dh->g); + dh->g = g; + } + + if (q != NULL) { + dh->length = BN_num_bits(q); + } + + return 1; +} + +#define DH_get0_pqg(dh, p, q, g) __DH_get0_pqg(dh, p, q, g) +static void +__DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, + const BIGNUM **g) +{ + if (p != NULL) + *p = dh->p; + if (q != NULL) + *q = dh->q; + if (g != NULL) + *g = dh->g; +} + +#define DH_set0_key(dh, pub, priv) __DH_set0_key(dh, pub, priv) +static int +__DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) +{ + if (pub_key != NULL) { + BN_free(dh->pub_key); + dh->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(dh->priv_key); + dh->priv_key = priv_key; + } + + return 1; +} + +#define DH_get0_key(dh, pub, priv) __DH_get0_key(dh, pub, priv) +static void +__DH_get0_key(const DH *dh, const BIGNUM **pub, const BIGNUM **priv) +{ + if (pub != NULL) + *pub = dh->pub_key; + if (priv != NULL) + *priv = dh->priv_key; +} + +#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ + /* Solaris Kerberos */ static k5_mutex_t oids_mutex = K5_MUTEX_PARTIAL_INITIALIZER; static int pkinit_oids_refs = 0; @@ -524,7 +620,7 @@ pkinit_init_pkinit_oids(pkinit_plg_crypto_context ctx) } \ } \ ctx->vn = OBJ_nid2obj(nid); - + /* Solaris Kerberos */ retval = k5_mutex_lock(&oids_mutex); if (retval != 0) @@ -567,7 +663,7 @@ pkinit_init_pkinit_oids(pkinit_plg_crypto_context ctx) /* Success */ retval = 0; - + pkinit_oids_refs++; /* Solaris Kerberos */ k5_mutex_unlock(&oids_mutex); @@ -656,48 +752,69 @@ pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx) /* Only call OBJ_cleanup once! */ /* Solaris Kerberos: locking */ k5_mutex_lock(&oids_mutex); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + /* + * In OpenSSL versions prior to 1.1.0, OBJ_cleanup() cleaned up OpenSSL's + * internal object table. This function is deprecated in version 1.1.0. + * No explicit de-initialisation is now required. + */ if (--pkinit_oids_refs == 0) OBJ_cleanup(); +#else + pkinit_oids_refs--; +#endif k5_mutex_unlock(&oids_mutex); } +static DH * +make_dhprime(uint8_t *prime, size_t len) +{ + DH *dh = NULL; + BIGNUM *p = NULL, *q = NULL, *g = NULL; + + if ((p = BN_bin2bn(prime, len, NULL)) == NULL) + goto cleanup; + if ((q = BN_new()) == NULL) + goto cleanup; + if (!BN_rshift1(q, p)) + goto cleanup; + if ((g = BN_new()) == NULL) + goto cleanup; + if (!BN_set_word(g, DH_GENERATOR_2)) + goto cleanup; + + dh = DH_new(); + if (dh == NULL) + goto cleanup; + DH_set0_pqg(dh, p, q, g); + p = g = q = NULL; + +cleanup: + BN_free(p); + BN_free(q); + BN_free(g); + return dh; +} + static krb5_error_code pkinit_init_dh_params(pkinit_plg_crypto_context plgctx) { krb5_error_code retval = ENOMEM; - plgctx->dh_1024 = DH_new(); + plgctx->dh_1024 = make_dhprime(pkinit_1024_dhprime, + sizeof(pkinit_1024_dhprime)); if (plgctx->dh_1024 == NULL) goto cleanup; - plgctx->dh_1024->p = BN_bin2bn(pkinit_1024_dhprime, - sizeof(pkinit_1024_dhprime), NULL); - if ((plgctx->dh_1024->g = BN_new()) == NULL || - (plgctx->dh_1024->q = BN_new()) == NULL) - goto cleanup; - BN_set_word(plgctx->dh_1024->g, DH_GENERATOR_2); - BN_rshift1(plgctx->dh_1024->q, plgctx->dh_1024->p); - plgctx->dh_2048 = DH_new(); + plgctx->dh_2048 = make_dhprime(pkinit_2048_dhprime, + sizeof(pkinit_2048_dhprime)); if (plgctx->dh_2048 == NULL) goto cleanup; - plgctx->dh_2048->p = BN_bin2bn(pkinit_2048_dhprime, - sizeof(pkinit_2048_dhprime), NULL); - if ((plgctx->dh_2048->g = BN_new()) == NULL || - (plgctx->dh_2048->q = BN_new()) == NULL) - goto cleanup; - BN_set_word(plgctx->dh_2048->g, DH_GENERATOR_2); - BN_rshift1(plgctx->dh_2048->q, plgctx->dh_2048->p); - plgctx->dh_4096 = DH_new(); + plgctx->dh_4096 = make_dhprime(pkinit_4096_dhprime, + sizeof(pkinit_4096_dhprime)); if (plgctx->dh_4096 == NULL) goto cleanup; - plgctx->dh_4096->p = BN_bin2bn(pkinit_4096_dhprime, - sizeof(pkinit_4096_dhprime), NULL); - if ((plgctx->dh_4096->g = BN_new()) == NULL || - (plgctx->dh_4096->q = BN_new()) == NULL) - goto cleanup; - BN_set_word(plgctx->dh_4096->g, DH_GENERATOR_2); - BN_rshift1(plgctx->dh_4096->q, plgctx->dh_4096->p); retval = 0; @@ -858,7 +975,7 @@ cms_signeddata_create(krb5_context context, ASN1_TYPE *pkinit_data = NULL; STACK_OF(X509) * cert_stack = NULL; ASN1_OCTET_STRING *digest_attr = NULL; - EVP_MD_CTX ctx, ctx2; + EVP_MD_CTX *ctx = NULL, *ctx2 = NULL; const EVP_MD *md_tmp = NULL; unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE]; unsigned char *digestInfo_buf = NULL, *abuf = NULL; @@ -902,27 +1019,29 @@ cms_signeddata_create(krb5_context context, } else { /* create a cert chain */ X509_STORE *certstore = NULL; - X509_STORE_CTX certctx; + X509_STORE_CTX *certctx; STACK_OF(X509) *certstack = NULL; char buf[DN_BUF_LEN]; int i = 0, size = 0; if ((certstore = X509_STORE_new()) == NULL) goto cleanup; + if ((certctx = X509_STORE_CTX_new()) == NULL) + goto cleanup; pkiDebug("building certificate chain\n"); - X509_STORE_set_verify_cb_func(certstore, openssl_callback); - X509_STORE_CTX_init(&certctx, certstore, cert, + X509_STORE_set_verify_cb(certstore, openssl_callback); + X509_STORE_CTX_init(certctx, certstore, cert, id_cryptoctx->intermediateCAs); - X509_STORE_CTX_trusted_stack(&certctx, id_cryptoctx->trustedCAs); + X509_STORE_CTX_set0_trusted_stack(certctx, id_cryptoctx->trustedCAs); /* Solaris Kerberos */ - if (X509_verify_cert(&certctx) <= 0) { - pkiDebug("failed to create a certificate chain: %s\n", - X509_verify_cert_error_string(X509_STORE_CTX_get_error(&certctx))); - if (!sk_X509_num(id_cryptoctx->trustedCAs)) + if (X509_verify_cert(certctx) <= 0) { + pkiDebug("failed to create a certificate chain: %s\n", + X509_verify_cert_error_string(X509_STORE_CTX_get_error(certctx))); + if (!sk_X509_num(id_cryptoctx->trustedCAs)) pkiDebug("No trusted CAs found. Check your X509_anchors\n"); goto cleanup; } - certstack = X509_STORE_CTX_get1_chain(&certctx); + certstack = X509_STORE_CTX_get1_chain(certctx); size = sk_X509_num(certstack); pkiDebug("size of certificate chain = %d\n", size); for(i = 0; i < size - 1; i++) { @@ -931,7 +1050,7 @@ cms_signeddata_create(krb5_context context, pkiDebug("cert #%d: %s\n", i, buf); sk_X509_push(cert_stack, X509_dup(x)); } - X509_STORE_CTX_cleanup(&certctx); + X509_STORE_CTX_free(certctx); X509_STORE_free(certstore); sk_X509_pop_free(certstack, X509_free); } @@ -947,9 +1066,9 @@ cms_signeddata_create(krb5_context context, goto cleanup; /* because ASN1_INTEGER_set is used to set a 'long' we will do * things the ugly way. */ - M_ASN1_INTEGER_free(p7si->issuer_and_serial->serial); + ASN1_INTEGER_free(p7si->issuer_and_serial->serial); if (!(p7si->issuer_and_serial->serial = - M_ASN1_INTEGER_dup(X509_get_serialNumber(cert)))) + ASN1_INTEGER_dup(X509_get_serialNumber(cert)))) goto cleanup; /* will not fill-out EVP_PKEY because it's on the smartcard */ @@ -983,11 +1102,16 @@ cms_signeddata_create(krb5_context context, } else { /* add signed attributes */ /* compute sha1 digest over the EncapsulatedContentInfo */ - EVP_MD_CTX_init(&ctx); - EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL); - EVP_DigestUpdate(&ctx, data, data_len); - md_tmp = EVP_MD_CTX_md(&ctx); - EVP_DigestFinal_ex(&ctx, md_data, &md_len); + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + goto cleanup2; + EVP_MD_CTX_init(ctx); + EVP_DigestInit_ex(ctx, EVP_sha1(), NULL); + EVP_DigestUpdate(ctx, data, data_len); + md_tmp = EVP_MD_CTX_md(ctx); + EVP_DigestFinal_ex(ctx, md_data, &md_len); + EVP_MD_CTX_free(ctx); + ctx = NULL; /* create a message digest attr */ digest_attr = ASN1_OCTET_STRING_new(); @@ -996,7 +1120,7 @@ cms_signeddata_create(krb5_context context, V_ASN1_OCTET_STRING, (char *) digest_attr); /* create a content-type attr */ - PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, + PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, V_ASN1_OBJECT, oid); /* create the signature over signed attributes. get DER encoded value */ @@ -1016,17 +1140,22 @@ cms_signeddata_create(krb5_context context, * digestAlgorithm AlgorithmIdentifier, * digest OCTET STRING } */ - if (id_cryptoctx->pkcs11_method == 1 && + if (id_cryptoctx->pkcs11_method == 1 && id_cryptoctx->mech == CKM_RSA_PKCS) { pkiDebug("mech = CKM_RSA_PKCS\n"); - EVP_MD_CTX_init(&ctx2); + ctx2 = EVP_MD_CTX_new(); + if (ctx2 == NULL) + goto cleanup2; + EVP_MD_CTX_init(ctx2); /* if this is not draft9 request, include digest signed attribute */ - if (cms_msg_type != CMS_SIGN_DRAFT9) - EVP_DigestInit_ex(&ctx2, md_tmp, NULL); + if (cms_msg_type != CMS_SIGN_DRAFT9) + EVP_DigestInit_ex(ctx2, md_tmp, NULL); else - EVP_DigestInit_ex(&ctx2, EVP_sha1(), NULL); - EVP_DigestUpdate(&ctx2, abuf, alen); - EVP_DigestFinal_ex(&ctx2, md_data2, &md_len2); + EVP_DigestInit_ex(ctx2, EVP_sha1(), NULL); + EVP_DigestUpdate(ctx2, abuf, alen); + EVP_DigestFinal_ex(ctx2, md_data2, &md_len2); + EVP_MD_CTX_free(ctx2); + ctx2 = NULL; alg = X509_ALGOR_new(); if (alg == NULL) @@ -1074,7 +1203,7 @@ cms_signeddata_create(krb5_context context, #ifdef DEBUG_SIG print_buffer(sig, sig_len); #endif - if (cms_msg_type != CMS_SIGN_DRAFT9) + if (cms_msg_type != CMS_SIGN_DRAFT9) free(abuf); if (retval) goto cleanup2; @@ -1159,12 +1288,14 @@ cms_signeddata_create(krb5_context context, #endif cleanup2: - if (cms_msg_type != CMS_SIGN_DRAFT9) - EVP_MD_CTX_cleanup(&ctx); + if (cms_msg_type != CMS_SIGN_DRAFT9) + if (ctx != NULL) + EVP_MD_CTX_free(ctx); #ifndef WITHOUT_PKCS11 - if (id_cryptoctx->pkcs11_method == 1 && + if (id_cryptoctx->pkcs11_method == 1 && id_cryptoctx->mech == CKM_RSA_PKCS) { - EVP_MD_CTX_cleanup(&ctx2); + if (ctx2 != NULL) + EVP_MD_CTX_free(ctx2); if (digest_buf != NULL) free(digest_buf); if (digestInfo_buf != NULL) @@ -1178,7 +1309,7 @@ cms_signeddata_create(krb5_context context, if (alg != NULL) X509_ALGOR_free(alg); cleanup: - if (p7 != NULL) + if (p7 != NULL) PKCS7_free(p7); if (sig != NULL) free(sig); @@ -1210,7 +1341,7 @@ cms_signeddata_verify(krb5_context context, PKCS7_SIGNER_INFO *si = NULL; X509 *x = NULL; X509_STORE *store = NULL; - X509_STORE_CTX cert_ctx; + X509_STORE_CTX *cert_ctx; STACK_OF(X509) *intermediateCAs = NULL; STACK_OF(X509_CRL) *revoked = NULL; STACK_OF(X509) *verified_chain = NULL; @@ -1254,9 +1385,9 @@ cms_signeddata_verify(krb5_context context, /* check if we are inforcing CRL checking */ vflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; if (require_crl_checking) - X509_STORE_set_verify_cb_func(store, openssl_callback); + X509_STORE_set_verify_cb(store, openssl_callback); else - X509_STORE_set_verify_cb_func(store, openssl_callback_ignore_crls); + X509_STORE_set_verify_cb(store, openssl_callback_ignore_crls); X509_STORE_set_flags(store, vflags); /* get the signer's information from the PKCS7 message */ @@ -1307,14 +1438,16 @@ cms_signeddata_verify(krb5_context context, /* initialize x509 context with the received certificate and * trusted and intermediate CA chains and CRLs */ - if (!X509_STORE_CTX_init(&cert_ctx, store, x, intermediateCAs)) + if ((cert_ctx = X509_STORE_CTX_new()) == NULL) + goto cleanup; + if (!X509_STORE_CTX_init(cert_ctx, store, x, intermediateCAs)) goto cleanup; - X509_STORE_CTX_set0_crls(&cert_ctx, revoked); + X509_STORE_CTX_set0_crls(cert_ctx, revoked); /* add trusted CAs certificates for cert verification */ if (idctx->trustedCAs != NULL) - X509_STORE_CTX_trusted_stack(&cert_ctx, idctx->trustedCAs); + X509_STORE_CTX_set0_trusted_stack(cert_ctx, idctx->trustedCAs); else { pkiDebug("unable to find any trusted CAs\n"); goto cleanup; @@ -1349,11 +1482,12 @@ cms_signeddata_verify(krb5_context context, } #endif - i = X509_verify_cert(&cert_ctx); + i = X509_verify_cert(cert_ctx); if (i <= 0) { - int j = X509_STORE_CTX_get_error(&cert_ctx); + int j = X509_STORE_CTX_get_error(cert_ctx); - reqctx->received_cert = X509_dup(cert_ctx.current_cert); + reqctx->received_cert = X509_dup( + X509_STORE_CTX_get_current_cert(cert_ctx)); switch(j) { case X509_V_ERR_CERT_REVOKED: retval = KRB5KDC_ERR_REVOKED_CERTIFICATE; @@ -1385,10 +1519,10 @@ cms_signeddata_verify(krb5_context context, #endif } else { /* retrieve verified certificate chain */ - if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9) - verified_chain = X509_STORE_CTX_get1_chain(&cert_ctx); + if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9) + verified_chain = X509_STORE_CTX_get1_chain(cert_ctx); } - X509_STORE_CTX_cleanup(&cert_ctx); + X509_STORE_CTX_free(cert_ctx); if (i <= 0) goto cleanup; @@ -1398,7 +1532,7 @@ cms_signeddata_verify(krb5_context context, if (PKCS7_verify(p7, NULL, store, NULL, out, flags)) { int valid_oid = 0; - if (!OBJ_cmp(p7->d.sign->contents->type, oid)) + if (!OBJ_cmp(p7->d.sign->contents->type, oid)) valid_oid = 1; else if (cms_msg_type == CMS_SIGN_DRAFT9) { /* @@ -1416,12 +1550,13 @@ cms_signeddata_verify(krb5_context context, valid_oid = 1; } - if (valid_oid) + if (valid_oid) pkiDebug("PKCS7 Verification successful\n"); else { + const ASN1_OBJECT *etype = p7->d.sign->contents->type; pkiDebug("wrong oid in eContentType\n"); - print_buffer((unsigned char *)p7->d.sign->contents->type->data, - (unsigned int)p7->d.sign->contents->type->length); + print_buffer((unsigned char *)OBJ_get0_data(etype), + OBJ_length(etype)); retval = KRB5KDC_ERR_PREAUTH_FAILED; krb5_set_error_message(context, retval, "wrong oid\n"); goto cleanup; @@ -1460,11 +1595,11 @@ cms_signeddata_verify(krb5_context context, /* generate authorization data */ if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9) { - if (authz_data == NULL || authz_data_len == NULL) + if (authz_data == NULL || authz_data_len == NULL) goto out; *authz_data = NULL; - retval = create_identifiers_from_stack(verified_chain, + retval = create_identifiers_from_stack(verified_chain, &krb5_verified_chain); if (retval) { pkiDebug("create_identifiers_from_stack failed\n"); @@ -1602,15 +1737,15 @@ cms_envelopeddata_create(krb5_context context, } switch (pa_type) { case KRB5_PADATA_PK_AS_REQ: - p7->d.enveloped->enc_data->content_type = + p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_signed); break; case KRB5_PADATA_PK_AS_REP_OLD: case KRB5_PADATA_PK_AS_REQ_OLD: - p7->d.enveloped->enc_data->content_type = + p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data); break; - } + } *out_len = i2d_PKCS7(p7, NULL); if (!*out_len || (p = *out = (unsigned char *)malloc(*out_len)) == NULL) { @@ -1924,7 +2059,7 @@ crypto_retrieve_X509_sans(krb5_context context, pkiDebug("%s: found dns name = %s\n", __FUNCTION__, gen->d.dNSName->data); dnss[d] = (unsigned char *) - strdup((char *)gen->d.dNSName->data); + strdup((char *)gen->d.dNSName->data); if (dnss[d] == NULL) { pkiDebug("%s: failed to duplicate dns name\n", __FUNCTION__); @@ -2163,39 +2298,40 @@ client_create_dh(krb5_context context, krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; unsigned char *buf = NULL; int dh_err = 0; - ASN1_INTEGER *pub_key = NULL; + ASN1_INTEGER *asn_pub_key = NULL; + BIGNUM *p, *g, *q; + const BIGNUM *pub_key; if (cryptoctx->dh == NULL) { if ((cryptoctx->dh = DH_new()) == NULL) goto cleanup; - if ((cryptoctx->dh->g = BN_new()) == NULL || - (cryptoctx->dh->q = BN_new()) == NULL) + if ((g = BN_new()) == NULL || (q = BN_new()) == NULL) goto cleanup; switch(dh_size) { case 1024: pkiDebug("client uses 1024 DH keys\n"); - cryptoctx->dh->p = get_rfc2409_prime_1024(NULL); + cryptoctx->dh = make_dhprime(pkinit_1024_dhprime, + sizeof(pkinit_1024_dhprime)); break; case 2048: pkiDebug("client uses 2048 DH keys\n"); - cryptoctx->dh->p = BN_bin2bn(pkinit_2048_dhprime, - sizeof(pkinit_2048_dhprime), NULL); + cryptoctx->dh = make_dhprime(pkinit_2048_dhprime, + sizeof(pkinit_2048_dhprime)); break; case 4096: pkiDebug("client uses 4096 DH keys\n"); - cryptoctx->dh->p = BN_bin2bn(pkinit_4096_dhprime, - sizeof(pkinit_4096_dhprime), NULL); + cryptoctx->dh = make_dhprime(pkinit_4096_dhprime, + sizeof(pkinit_4096_dhprime)); break; - default: - goto cleanup; } - - BN_set_word((cryptoctx->dh->g), DH_GENERATOR_2); - BN_rshift1(cryptoctx->dh->q, cryptoctx->dh->p); + if (cryptoctx->dh == NULL) + goto cleanup; } DH_generate_key(cryptoctx->dh); + DH_get0_key(cryptoctx->dh, &pub_key, NULL); + /* Solaris Kerberos */ #ifdef DEBUG DH_check(cryptoctx->dh, &dh_err); @@ -2213,10 +2349,10 @@ client_create_dh(krb5_context context, #endif #ifdef DEBUG_DH print_dh(cryptoctx->dh, "client's DH params\n"); - print_pubkey(cryptoctx->dh->pub_key, "client's pub_key="); + print_pubkey(pub_key, "client's pub_key="); #endif - DH_check_pub_key(cryptoctx->dh, cryptoctx->dh->pub_key, &dh_err); + DH_check_pub_key(cryptoctx->dh, pub_key, &dh_err); if (dh_err != 0) { pkiDebug("dh_check_pub_key failed with %d\n", dh_err); goto cleanup; @@ -2226,8 +2362,9 @@ client_create_dh(krb5_context context, /* aglo: usually we could just call i2d_DHparams to encode DH params * however, PKINIT requires RFC3279 encoding and openssl does pkcs#3. */ - retval = pkinit_encode_dh_params(cryptoctx->dh->p, cryptoctx->dh->g, - cryptoctx->dh->q, dh_params, dh_params_len); + DH_get0_pqg(cryptoctx->dh, (const BIGNUM **)&p, (const BIGNUM **)&q, + (const BIGNUM **)&g); + retval = pkinit_encode_dh_params(p, g, q, dh_params, dh_params_len); if (retval) goto cleanup; @@ -2237,18 +2374,18 @@ client_create_dh(krb5_context context, * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo * data element */ - if ((pub_key = BN_to_ASN1_INTEGER(cryptoctx->dh->pub_key, NULL)) == NULL) + if ((asn_pub_key = BN_to_ASN1_INTEGER(pub_key, NULL)) == NULL) goto cleanup; - *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL); + *dh_pubkey_len = i2d_ASN1_INTEGER(asn_pub_key, NULL); if ((buf = *dh_pubkey = (unsigned char *) - malloc((size_t) *dh_pubkey_len)) == NULL) { - retval = ENOMEM; - goto cleanup; + malloc((size_t) *dh_pubkey_len)) == NULL) { + retval = ENOMEM; + goto cleanup; } - i2d_ASN1_INTEGER(pub_key, &buf); + i2d_ASN1_INTEGER(asn_pub_key, &buf); - if (pub_key != NULL) - ASN1_INTEGER_free(pub_key); + if (asn_pub_key != NULL) + ASN1_INTEGER_free(asn_pub_key); retval = 0; return retval; @@ -2263,8 +2400,8 @@ client_create_dh(krb5_context context, if (*dh_pubkey != NULL) free(*dh_pubkey); *dh_pubkey = NULL; - if (pub_key != NULL) - ASN1_INTEGER_free(pub_key); + if (asn_pub_key != NULL) + ASN1_INTEGER_free(asn_pub_key); return retval; } @@ -2352,6 +2489,7 @@ server_check_dh(krb5_context context, unsigned char *tmp = NULL; int dh_prime_bits; krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; + const BIGNUM *p, *g, *q, *p2; tmp = dh_params->data; dh = DH_new(); @@ -2361,8 +2499,10 @@ server_check_dh(krb5_context context, goto cleanup; } + DH_get0_pqg(dh, &p, &q, &g); + /* KDC SHOULD check to see if the key parameters satisfy its policy */ - dh_prime_bits = BN_num_bits(dh->p); + dh_prime_bits = BN_num_bits(p); if (minbits && dh_prime_bits < minbits) { pkiDebug("client sent dh params with %d bits, we require %d\n", dh_prime_bits, minbits); @@ -2370,22 +2510,22 @@ server_check_dh(krb5_context context, } /* check dhparams is group 2 */ - if (pkinit_check_dh_params(cryptoctx->dh_1024->p, - dh->p, dh->g, dh->q) == 0) { + DH_get0_pqg(cryptoctx->dh_1024, &p2, NULL, NULL); + if (pkinit_check_dh_params(p2, p, g, q) == 0) { retval = 0; goto cleanup; } /* check dhparams is group 14 */ - if (pkinit_check_dh_params(cryptoctx->dh_2048->p, - dh->p, dh->g, dh->q) == 0) { + DH_get0_pqg(cryptoctx->dh_2048, &p2, NULL, NULL); + if (pkinit_check_dh_params(p2, p, g, q) == 0) { retval = 0; goto cleanup; } /* check dhparams is group 16 */ - if (pkinit_check_dh_params(cryptoctx->dh_4096->p, - dh->p, dh->g, dh->q) == 0) { + DH_get0_pqg(cryptoctx->dh_4096, &p2, NULL, NULL); + if (pkinit_check_dh_params(p2, p, g, q) == 0) { retval = 0; goto cleanup; } @@ -2416,8 +2556,10 @@ server_process_dh(krb5_context context, /* Solaris Kerberos */ krb5_error_code retval = KRB5KRB_ERR_GENERIC; DH *dh = NULL, *dh_server = NULL; - unsigned char *p = NULL; - ASN1_INTEGER *pub_key = NULL; + const BIGNUM *p, *g, *q, *s_pub_key; + BIGNUM *pub_key; + unsigned char *s = NULL; + ASN1_INTEGER *asn_pub_key = NULL; /* get client's received DH parameters that we saved in server_check_dh */ dh = cryptoctx->dh; @@ -2425,33 +2567,36 @@ server_process_dh(krb5_context context, dh_server = DH_new(); if (dh_server == NULL) goto cleanup; - dh_server->p = BN_dup(dh->p); - dh_server->g = BN_dup(dh->g); - dh_server->q = BN_dup(dh->q); + DH_get0_pqg(dh, &p, &g, &q); + DH_set0_pqg(dh_server, BN_dup(p), BN_dup(g), BN_dup(q)); /* decode client's public key */ - p = data; - pub_key = d2i_ASN1_INTEGER(NULL, (const unsigned char **)&p, (int)data_len); - if (pub_key == NULL) + s = data; + asn_pub_key = d2i_ASN1_INTEGER(NULL, + (const unsigned char **)&s, (int)data_len); + if (asn_pub_key == NULL) goto cleanup; - dh->pub_key = ASN1_INTEGER_to_BN(pub_key, NULL); - if (dh->pub_key == NULL) + pub_key = ASN1_INTEGER_to_BN(asn_pub_key, NULL); + if (pub_key == NULL) goto cleanup; - ASN1_INTEGER_free(pub_key); + DH_set0_key(dh, pub_key, NULL); + ASN1_INTEGER_free(asn_pub_key); if (!DH_generate_key(dh_server)) goto cleanup; /* generate DH session key */ *server_key_len = DH_size(dh_server); - if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len)) == NULL) - goto cleanup; - DH_compute_key(*server_key, dh->pub_key, dh_server); + if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len)) + == NULL) + goto cleanup; + DH_compute_key(*server_key, pub_key, dh_server); + DH_get0_key(dh_server, &s_pub_key, NULL); #ifdef DEBUG_DH print_dh(dh_server, "client&server's DH params\n"); - print_pubkey(dh->pub_key, "client's pub_key="); - print_pubkey(dh_server->pub_key, "server's pub_key="); + print_pubkey(pub_key, "client's pub_key="); + print_pubkey(s_pub_key, "server's pub_key="); pkiDebug("server secret key="); print_buffer(*server_key, *server_key_len); #endif @@ -2463,14 +2608,15 @@ server_process_dh(krb5_context context, * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo * data element */ - if ((pub_key = BN_to_ASN1_INTEGER(dh_server->pub_key, NULL)) == NULL) + if ((asn_pub_key = BN_to_ASN1_INTEGER(s_pub_key, NULL)) == NULL) goto cleanup; - *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL); - if ((p = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len)) == NULL) - goto cleanup; - i2d_ASN1_INTEGER(pub_key, &p); - if (pub_key != NULL) - ASN1_INTEGER_free(pub_key); + *dh_pubkey_len = i2d_ASN1_INTEGER(asn_pub_key, NULL); + if ((s = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len)) + == NULL) + goto cleanup; + i2d_ASN1_INTEGER(asn_pub_key, &s); + if (asn_pub_key != NULL) + ASN1_INTEGER_free(asn_pub_key); retval = 0; @@ -2504,9 +2650,15 @@ openssl_init() if (ret == 0) { if (!did_init) { /* initialize openssl routines */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L + /* + * As of version 1.1.0, OpenSSL will automatically allocate + * resources as-needed. + */ CRYPTO_malloc_init(); ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); +#endif did_init++; } k5_mutex_unlock(&init_mutex); @@ -2515,7 +2667,7 @@ openssl_init() } static krb5_error_code -pkinit_encode_dh_params(BIGNUM *p, BIGNUM *g, BIGNUM *q, +pkinit_encode_dh_params(const BIGNUM *p, const BIGNUM *g, const BIGNUM *q, unsigned char **buf, unsigned int *buf_len) { krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; @@ -2560,6 +2712,8 @@ cleanup: return retval; } +#if OPENSSL_VERSION_NUMBER < 0x10100000L + static DH * pkinit_decode_dh_params(DH ** a, unsigned char **pp, unsigned int len) { @@ -2619,6 +2773,63 @@ pkinit_decode_dh_params(DH ** a, unsigned char **pp, unsigned int len) } +#else + +/* + * This is taken from the internal dh_asn1.c file in OpenSSL 1.1, modified to + * make q an optional field. + */ + +typedef struct { + ASN1_BIT_STRING *seed; + BIGNUM *counter; +} int_dhvparams; + +typedef struct { + BIGNUM *p; + BIGNUM *q; + BIGNUM *g; + BIGNUM *j; + int_dhvparams *vparams; +} int_dhx942_dh; + +ASN1_SEQUENCE(DHvparams) = { + ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING), + ASN1_SIMPLE(int_dhvparams, counter, BIGNUM) +} static_ASN1_SEQUENCE_END_name(int_dhvparams, DHvparams) + +ASN1_SEQUENCE(DHxparams) = { + ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM), + ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM), + ASN1_OPT(int_dhx942_dh, q, BIGNUM), + ASN1_OPT(int_dhx942_dh, j, BIGNUM), + ASN1_OPT(int_dhx942_dh, vparams, DHvparams), +} static_ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams) + +static DH * +pkinit_decode_dh_params(DH **a, unsigned char **pp, unsigned int len) +{ + int_dhx942_dh *params; + DH *dh = *a; + + if (dh == NULL) + return NULL; + + params = (int_dhx942_dh *)ASN1_item_d2i(NULL, + (const unsigned char **)pp, len, ASN1_ITEM_rptr(DHxparams)); + if (params == NULL) { + DH_free(dh); + return NULL; + } + + DH_set0_pqg(dh, params->p, params->q, params->g); + params->p = params->q = params->g = NULL; + ASN1_item_free((ASN1_VALUE *)params, ASN1_ITEM_rptr(DHxparams)); + return dh; +} + +#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ + static krb5_error_code pkinit_create_sequence_of_principal_identifiers( krb5_context context, @@ -2763,6 +2974,7 @@ pkinit_create_td_dh_parameters(krb5_context context, krb5_typed_data **typed_data = NULL; krb5_data *data = NULL, *encoded_algId = NULL; krb5_algorithm_identifier **algId = NULL; + const BIGNUM *p, *q, *g; /* Solaris Kerberos */ if (opts->dh_min_bits > 4096) { @@ -2771,22 +2983,19 @@ pkinit_create_td_dh_parameters(krb5_context context, } if (opts->dh_min_bits <= 1024) { - retval = pkinit_encode_dh_params(plg_cryptoctx->dh_1024->p, - plg_cryptoctx->dh_1024->g, plg_cryptoctx->dh_1024->q, - &buf1, &buf1_len); + DH_get0_pqg(plg_cryptoctx->dh_1024, &p, &q, &g); + retval = pkinit_encode_dh_params(p, g, q, &buf1, &buf1_len); if (retval) goto cleanup; } if (opts->dh_min_bits <= 2048) { - retval = pkinit_encode_dh_params(plg_cryptoctx->dh_2048->p, - plg_cryptoctx->dh_2048->g, plg_cryptoctx->dh_2048->q, - &buf2, &buf2_len); + DH_get0_pqg(plg_cryptoctx->dh_2048, &p, &q, &g); + retval = pkinit_encode_dh_params(p, g, q, &buf2, &buf2_len); if (retval) goto cleanup; } - retval = pkinit_encode_dh_params(plg_cryptoctx->dh_4096->p, - plg_cryptoctx->dh_4096->g, plg_cryptoctx->dh_4096->q, - &buf3, &buf3_len); + DH_get0_pqg(plg_cryptoctx->dh_4096, &p, &q, &g); + retval = pkinit_encode_dh_params(p, g, q, &buf3, &buf3_len); if (retval) goto cleanup; @@ -2980,7 +3189,8 @@ cleanup: } static int -pkinit_check_dh_params(BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1) +pkinit_check_dh_params(const BIGNUM *p1, const BIGNUM *p2, const BIGNUM *g1, + const BIGNUM *q1) { BIGNUM *g2 = NULL, *q2 = NULL; /* Solaris Kerberos */ @@ -3024,6 +3234,7 @@ pkinit_process_td_dh_params(krb5_context context, while (algId[i] != NULL) { DH *dh = NULL; unsigned char *tmp = NULL; + const BIGNUM *p, *g, *q, *p2; int dh_prime_bits = 0; if (algId[i]->algorithm.length != dh_oid.length || @@ -3033,27 +3244,28 @@ pkinit_process_td_dh_params(krb5_context context, tmp = algId[i]->parameters.data; dh = DH_new(); dh = pkinit_decode_dh_params(&dh, &tmp, algId[i]->parameters.length); - dh_prime_bits = BN_num_bits(dh->p); + dh_prime_bits = DH_bits(dh); pkiDebug("client sent %d DH bits server prefers %d DH bits\n", *new_dh_size, dh_prime_bits); + DH_get0_pqg(dh, &p, &q, &g); switch(dh_prime_bits) { case 1024: - if (pkinit_check_dh_params(cryptoctx->dh_1024->p, dh->p, - dh->g, dh->q) == 0) { + DH_get0_pqg(cryptoctx->dh_1024, &p2, NULL, NULL); + if (pkinit_check_dh_params(p2, p, g, q) == 0) { *new_dh_size = 1024; ok = 1; } break; case 2048: - if (pkinit_check_dh_params(cryptoctx->dh_2048->p, dh->p, - dh->g, dh->q) == 0) { + DH_get0_pqg(cryptoctx->dh_2048, &p2, NULL, NULL); + if (pkinit_check_dh_params(p2, p, g, q) == 0) { *new_dh_size = 2048; ok = 1; } break; case 4096: - if (pkinit_check_dh_params(cryptoctx->dh_4096->p, dh->p, - dh->g, dh->q) == 0) { + DH_get0_pqg(cryptoctx->dh_4096, &p2, NULL, NULL); + if (pkinit_check_dh_params(p2, p, g, q) == 0) { *new_dh_size = 4096; ok = 1; } @@ -3093,7 +3305,7 @@ cleanup: return retval; } -/* ARGSUSED */ +/* ARGSUSED */ static int openssl_callback(int ok, X509_STORE_CTX * ctx) { @@ -3113,14 +3325,8 @@ openssl_callback(int ok, X509_STORE_CTX * ctx) static int openssl_callback_ignore_crls(int ok, X509_STORE_CTX * ctx) { - if (!ok) { - switch (ctx->error) { - case X509_V_ERR_UNABLE_TO_GET_CRL: - return 1; - default: - return 0; - } - } + if (!ok) + return (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL); return ok; } @@ -3141,7 +3347,7 @@ pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type) * We need this shadow version because our code * depends on the "other" type to be unknown to the * OpenSSL code. - */ + */ if (cryptoctx->id_pkinit_authData9 == NULL) { pkiDebug("%s: Creating shadow instance of pkcs7-data oid\n", __FUNCTION__); @@ -3309,33 +3515,30 @@ prepare_enc_data(unsigned char *indata, unsigned char **outdata, int *outdata_len) { - /* Solaris Kerberos */ - ASN1_const_CTX c; - long length = indata_len; - int Ttag, Tclass; - long Tlen; - - c.pp = (const unsigned char **)&indata; - c.q = *(const unsigned char **)&indata; - c.error = ERR_R_NESTED_ASN1_ERROR; - c.p= *(const unsigned char **)&indata; - c.max = (length == 0)?0:(c.p+length); - - asn1_GetSequence(&c,&length); - - ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); - c.p += Tlen; - ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); - - asn1_const_Finish(&c); - - *outdata = (unsigned char *)malloc((size_t)Tlen); - /* Solaris Kerberos */ - if (outdata == NULL) - return ENOMEM; - - (void) memcpy(*outdata, c.p, (size_t)Tlen); - *outdata_len = Tlen; + int tag, class; + long tlen, slen; + const uint8_t *p = indata, *oldp; + + /* Top-bit set means that the conversion failed. */ + if (ASN1_get_object(&p, &slen, &tag, &class, indata_len) & 0x80) + return EINVAL; + if (tag != V_ASN1_SEQUENCE) + return EINVAL; + + oldp = p; + if (ASN1_get_object(&p, &tlen, &tag, &class, slen) & 0x80) + return EINVAL; + p += tlen; + slen -= (p - oldp); + + if (ASN1_get_object(&p, &tlen, &tag, &class, slen) & 0x80) + return EINVAL; + + *outdata = malloc(tlen); + if (*outdata == NULL) + return ENOMEM; + memcpy(*outdata, p, tlen); + *outdata_len = tlen; return 0; } @@ -3901,7 +4104,7 @@ out: if (cert_id) free(cert_id); - + return (r); } @@ -3965,7 +4168,7 @@ pkinit_open_session(krb5_context context, * If C_Initialize was already called by the process before the pkinit * module was loaded then record that fact. * "finalize_pkcs11" is used by pkinit_fini_pkcs11 to determine whether - * or not C_Finalize() should be called. + * or not C_Finalize() should be called. */ cctx->finalize_pkcs11 = (r == CKR_CRYPTOKI_ALREADY_INITIALIZED ? FALSE : TRUE); @@ -4023,7 +4226,7 @@ pkinit_open_session(krb5_context context, goto out; } } - + tryagain: /* get count of slots that have tokens */ if ((r = cctx->p11->C_GetSlotList(TRUE, NULL, &count)) != CKR_OK) { @@ -4065,7 +4268,7 @@ tryagain: if (slotlist != NULL) free(slotlist); - + slotlist = malloc(count * sizeof (CK_SLOT_ID)); if (slotlist == NULL) { krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, @@ -4368,6 +4571,7 @@ pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx, CK_ATTRIBUTE attrs[4]; CK_ULONG count; CK_KEY_TYPE keytype; + RSA *rsa; unsigned int nattrs = 0; int r; #ifdef PKINIT_USE_KEY_USAGE @@ -4428,6 +4632,7 @@ pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx, EVP_PKEY *priv; X509 *cert; + const BIGNUM *rsan; unsigned int n_len; unsigned char *n_bytes; @@ -4459,20 +4664,28 @@ pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx, attrs[nattrs].ulValueLen = sizeof keytype; nattrs++; - n_len = BN_num_bytes(priv->pkey.rsa->n); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + rsa = priv->pkey.rsa; + rsan = rsa->n; + n_len = BN_num_bytes(rsan); +#else + rsa = EVP_PKEY_get0_RSA(priv); + RSA_get0_key(rsa, &rsan, NULL, NULL); + n_len = RSA_size(rsa); +#endif n_bytes = (unsigned char *) malloc((size_t) n_len); if (n_bytes == NULL) { return (ENOMEM); } - if (BN_bn2bin(priv->pkey.rsa->n, n_bytes) == 0) { + if (BN_bn2bin(rsan, n_bytes) == 0) { free (n_bytes); - pkiDebug("zero-byte key modulus\n"); + pkiDebug("zero-byte key modulus\n"); return KRB5KDC_ERR_PREAUTH_FAILED; } attrs[nattrs].type = CKA_MODULUS; - attrs[nattrs].ulValueLen = n_len; + attrs[nattrs].ulValueLen = n_len; attrs[nattrs].pValue = n_bytes; nattrs++; @@ -4774,11 +4987,7 @@ decode_data(unsigned char **out_data, unsigned int *out_data_len, if (buf == NULL) return ENOMEM; -#if OPENSSL_VERSION_NUMBER < 0x10000000L - len = EVP_PKEY_decrypt(buf, data, (int)data_len, pkey); -#else len = EVP_PKEY_decrypt_old(buf, data, (int)data_len, pkey); -#endif if (len <= 0) { pkiDebug("unable to decrypt received data (len=%d)\n", data_len); /* Solaris Kerberos */ @@ -4796,23 +5005,26 @@ create_signature(unsigned char **sig, unsigned int *sig_len, unsigned char *data, unsigned int data_len, EVP_PKEY *pkey) { krb5_error_code retval = ENOMEM; - EVP_MD_CTX md_ctx; + EVP_MD_CTX *md_ctx; if (pkey == NULL) /* Solaris Kerberos */ return EINVAL; - EVP_VerifyInit(&md_ctx, EVP_sha1()); - EVP_SignUpdate(&md_ctx, data, data_len); + if ((md_ctx = EVP_MD_CTX_new()) == NULL) + return EINVAL; + + EVP_VerifyInit(md_ctx, EVP_sha1()); + EVP_SignUpdate(md_ctx, data, data_len); *sig_len = EVP_PKEY_size(pkey); if ((*sig = (unsigned char *) malloc((size_t) *sig_len)) == NULL) goto cleanup; - EVP_SignFinal(&md_ctx, *sig, sig_len, pkey); + EVP_SignFinal(md_ctx, *sig, sig_len, pkey); retval = 0; cleanup: - EVP_MD_CTX_cleanup(&md_ctx); + EVP_MD_CTX_free(md_ctx); return retval; } @@ -5153,7 +5365,7 @@ pkinit_get_certs_dir(krb5_context context, retval = 0; cleanup: - if (d) + if (d) (void) closedir(d); return retval; @@ -5450,7 +5662,7 @@ crypto_cert_iteration_next(krb5_context context, if (id_cryptoctx->creds[id->index] == NULL) return PKINIT_ITER_NO_MORE; - + cd = calloc(1, sizeof(*cd)); if (cd == NULL) return ENOMEM; @@ -5506,7 +5718,7 @@ crypto_retieve_X509_key_usage(krb5_context context, pkiDebug("%s: EKUs not requested, not checking\n", __FUNCTION__); goto check_kus; } - + /* Start with Extended Key usage */ i = X509_get_ext_by_NID(x, NID_ext_key_usage, -1); if (i >= 0) { @@ -5727,8 +5939,8 @@ crypto_cert_select(krb5_context context, cd = (struct _pkinit_cert_data *)md->ch; if (cd == NULL || cd->magic != CERT_MAGIC) return EINVAL; - - /* copy the selected cert into our id_cryptoctx */ + + /* copy the selected cert into our id_cryptoctx */ if (cd->idctx->my_certs != NULL) { sk_X509_pop_free(cd->idctx->my_certs, X509_free); } @@ -5740,7 +5952,7 @@ crypto_cert_select(krb5_context context, if (cd->idctx->pkcs11_method != 1) { cd->idctx->my_key = cd->cred->key; cd->idctx->creds[cd->index]->key = NULL; /* Don't free it twice */ - } + } #ifndef WITHOUT_PKCS11 else { cd->idctx->cert_id = cd->cred->cert_id; @@ -5782,7 +5994,7 @@ crypto_cert_select_default(krb5_context context, __FUNCTION__, cert_count); goto errout; } - /* copy the selected cert into our id_cryptoctx */ + /* copy the selected cert into our id_cryptoctx */ if (id_cryptoctx->my_certs != NULL) { sk_X509_pop_free(id_cryptoctx->my_certs, X509_free); } @@ -5794,7 +6006,7 @@ crypto_cert_select_default(krb5_context context, if (id_cryptoctx->pkcs11_method != 1) { id_cryptoctx->my_key = id_cryptoctx->creds[0]->key; id_cryptoctx->creds[0]->key = NULL; /* Don't free it twice */ - } + } #ifndef WITHOUT_PKCS11 else { id_cryptoctx->cert_id = id_cryptoctx->creds[0]->cert_id; @@ -5878,7 +6090,7 @@ load_cas_and_crls(krb5_context context, */ for (i = 0; i < sk_X509_INFO_num(sk); i++) { X509_INFO *xi = sk_X509_INFO_value(sk, i); - if (xi != NULL && xi->x509 != NULL && catype != CATYPE_CRLS) { + if (xi != NULL && xi->x509 != NULL && catype != CATYPE_CRLS) { int j = 0, size = sk_X509_num(ca_certs), flag = 0; if (!size) { @@ -5891,7 +6103,7 @@ load_cas_and_crls(krb5_context context, flag = X509_cmp(x, xi->x509); if (flag == 0) break; - else + else continue; } if (flag != 0) { @@ -5925,7 +6137,7 @@ load_cas_and_crls(krb5_context context, case CATYPE_ANCHORS: if (sk_X509_num(ca_certs) == 0) { pkiDebug("no anchors in file, %s\n", filename); - if (id_cryptoctx->trustedCAs == NULL) + if (id_cryptoctx->trustedCAs == NULL) sk_X509_free(ca_certs); } else { if (id_cryptoctx->trustedCAs == NULL) @@ -5935,7 +6147,7 @@ load_cas_and_crls(krb5_context context, case CATYPE_INTERMEDIATES: if (sk_X509_num(ca_certs) == 0) { pkiDebug("no intermediates in file, %s\n", filename); - if (id_cryptoctx->intermediateCAs == NULL) + if (id_cryptoctx->intermediateCAs == NULL) sk_X509_free(ca_certs); } else { if (id_cryptoctx->intermediateCAs == NULL) @@ -5976,7 +6188,7 @@ load_cas_and_crls_dir(krb5_context context, pkinit_req_crypto_context req_cryptoctx, pkinit_identity_crypto_context id_cryptoctx, int catype, - char *dirname) + char *dirname) { krb5_error_code retval = EINVAL; DIR *d = NULL; @@ -5987,7 +6199,7 @@ load_cas_and_crls_dir(krb5_context context, return EINVAL; d = opendir(dirname); - if (d == NULL) + if (d == NULL) return ENOENT; while ((dentry = readdir(d))) { @@ -6014,7 +6226,7 @@ load_cas_and_crls_dir(krb5_context context, retval = 0; cleanup: - if (d != NULL) + if (d != NULL) (void) closedir(d); return retval; @@ -6029,7 +6241,7 @@ crypto_load_cas_and_crls(krb5_context context, pkinit_identity_crypto_context id_cryptoctx, int idtype, int catype, - char *id) + char *id) { pkiDebug("%s: called with idtype %s and catype %s\n", __FUNCTION__, idtype2string(idtype), catype2string(catype)); @@ -6098,8 +6310,8 @@ if (longhorn == 0) { /* XXX Longhorn doesn't like this */ #endif is = PKCS7_ISSUER_AND_SERIAL_new(); X509_NAME_set(&is->issuer, X509_get_issuer_name(x)); - M_ASN1_INTEGER_free(is->serial); - is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x)); + ASN1_INTEGER_free(is->serial); + is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(x)); len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL); if ((p = krb5_cas[i]->issuerAndSerialNumber.data = (unsigned char *)malloc((size_t) len)) == NULL) @@ -6173,7 +6385,7 @@ create_krb5_invalidCertificates(krb5_context context, return KRB5KDC_ERR_PREAUTH_FAILED; sk = sk_X509_new_null(); - if (sk == NULL) + if (sk == NULL) goto cleanup; sk_X509_push(sk, req_cryptoctx->received_cert); @@ -6241,7 +6453,7 @@ create_krb5_trustedCertifiers(krb5_context context, return KRB5KDC_ERR_PREAUTH_FAILED; return create_identifiers_from_stack(sk, ids); - + } /* ARGSUSED */ @@ -6303,8 +6515,8 @@ create_krb5_trustedCas(krb5_context context, krb5_cas[i]->u.issuerAndSerial.length = 0; is = PKCS7_ISSUER_AND_SERIAL_new(); X509_NAME_set(&is->issuer, X509_get_issuer_name(x)); - M_ASN1_INTEGER_free(is->serial); - is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x)); + ASN1_INTEGER_free(is->serial); + is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(x)); len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL); if ((p = krb5_cas[i]->u.issuerAndSerial.data = (unsigned char *)malloc((size_t) len)) == NULL) @@ -6353,8 +6565,8 @@ create_issuerAndSerial(krb5_context context, is = PKCS7_ISSUER_AND_SERIAL_new(); X509_NAME_set(&is->issuer, X509_get_issuer_name(cert)); - M_ASN1_INTEGER_free(is->serial); - is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert)); + ASN1_INTEGER_free(is->serial); + is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert)); len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL); if ((p = *out = (unsigned char *)malloc((size_t) len)) == NULL) goto cleanup; @@ -6404,7 +6616,7 @@ pkcs7_decrypt(krb5_context context, } #pragma error_messages (default, E_END_OF_LOOP_CODE_NOT_REACHED) - return 0; + return 0; } krb5_error_code @@ -6539,9 +6751,9 @@ pkcs7_dataDecode(krb5_context context, int tmp_ret = 0; ri=sk_PKCS7_RECIP_INFO_value(rsk,i); tmp_ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, - cert->cert_info->issuer); + X509_get_issuer_name(cert)); if (!tmp_ret) { - tmp_ret = M_ASN1_INTEGER_cmp(cert->cert_info->serialNumber, + tmp_ret = ASN1_INTEGER_cmp(X509_get_serialNumber(cert), ri->issuer_and_serial->serial); if (!tmp_ret) break; @@ -6562,8 +6774,8 @@ pkcs7_dataDecode(krb5_context context, for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); jj = pkinit_decode_data(context, id_cryptoctx, - M_ASN1_STRING_data(ri->enc_key), - (unsigned int) M_ASN1_STRING_length(ri->enc_key), + (unsigned char *)ASN1_STRING_get0_data(ri->enc_key), + ASN1_STRING_length(ri->enc_key), &tmp, &tmp_len); if (jj) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB); @@ -6580,14 +6792,14 @@ pkcs7_dataDecode(krb5_context context, } if (ri == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_KEY); + PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); goto cleanup; } } else { jj = pkinit_decode_data(context, id_cryptoctx, - M_ASN1_STRING_data(ri->enc_key), - (unsigned int) M_ASN1_STRING_length(ri->enc_key), + (unsigned char *)ASN1_STRING_get0_data(ri->enc_key), + ASN1_STRING_length(ri->enc_key), &tmp, &tmp_len); /* Solaris Kerberos: tmp_len is unsigned. Cannot be < 0 */ if (jj || tmp_len == 0) { @@ -6611,7 +6823,7 @@ pkcs7_dataDecode(krb5_context context, */ if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, (int)jj)) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); + PKCS7_R_DECRYPT_ERROR); goto cleanup; } } diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h index 680cd76deb..2f3e0ccae4 100644 --- a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h +++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h @@ -30,6 +30,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. */ #ifndef _PKINIT_CRYPTO_OPENSSL_H @@ -44,10 +45,16 @@ #include <openssl/x509v3.h> #include <openssl/err.h> #include <openssl/evp.h> -#include <openssl/asn1_mac.h> #include <openssl/sha.h> #include <openssl/asn1.h> #include <openssl/pem.h> +#include <openssl/rsa.h> + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#include <openssl/asn1_mac.h> +#else +#include <openssl/asn1t.h> +#endif #include "pkinit.h" @@ -162,11 +169,13 @@ static krb5_error_code pkinit_init_pkcs11(pkinit_identity_crypto_context ctx); static void pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx); static krb5_error_code pkinit_encode_dh_params - (BIGNUM *, BIGNUM *, BIGNUM *, unsigned char **, unsigned int *); + (const BIGNUM *, const BIGNUM *, const BIGNUM *, + unsigned char **, unsigned int *); static DH *pkinit_decode_dh_params (DH **, unsigned char **, unsigned int ); static int pkinit_check_dh_params - (BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1); + (const BIGNUM *p1, const BIGNUM *p2, const BIGNUM *g1, + const BIGNUM *q1); static krb5_error_code pkinit_sign_data (krb5_context context, pkinit_identity_crypto_context cryptoctx, @@ -275,8 +284,15 @@ wrap_signeddata(unsigned char *data, unsigned int data_len, #endif /* This handy macro borrowed from crypto/x509v3/v3_purp.c */ + +#if OPENSSL_VERSION_NUMBER < 0x10100000L #define ku_reject(x, usage) \ (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) +#else +#define ku_reject(x, usage) \ + ((X509_get_extension_flags(x) & EXFLAG_KUSAGE) && \ + !(X509_get_key_usage(x) & (usage))) +#endif static char * pkinit_pkcs11_code_to_text(int err); diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/Makefile.com b/usr/src/lib/libkmf/plugins/kmf_openssl/Makefile.com index 9557d11286..b5b08f175c 100644 --- a/usr/src/lib/libkmf/plugins/kmf_openssl/Makefile.com +++ b/usr/src/lib/libkmf/plugins/kmf_openssl/Makefile.com @@ -27,7 +27,7 @@ LIBRARY= kmf_openssl.a VERS= .1 -OBJECTS= openssl_spi.o +OBJECTS= openssl_spi.o compat.o include $(SRC)/lib/Makefile.lib diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/common/compat.c b/usr/src/lib/libkmf/plugins/kmf_openssl/common/compat.c new file mode 100644 index 0000000000..b64064cb7b --- /dev/null +++ b/usr/src/lib/libkmf/plugins/kmf_openssl/common/compat.c @@ -0,0 +1,446 @@ +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <string.h> +#include <openssl/bio.h> +#include <openssl/engine.h> +#include "compat.h" + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + +static void * +OPENSSL_zalloc(size_t num) +{ + void *ret = OPENSSL_malloc(num); + + if (ret != NULL) + (void) memset(ret, 0, num); + return (ret); +} + +int +RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) +{ + /* + * If the fields n and e in r are NULL, the corresponding input + * parameters MUST be non-NULL for n and e. d may be + * left NULL (in case only the public key is used). + */ + if ((r->n == NULL && n == NULL) || (r->e == NULL && e == NULL)) + return (0); + + if (n != NULL) { + BN_free(r->n); + r->n = n; + } + if (e != NULL) { + BN_free(r->e); + r->e = e; + } + if (d != NULL) { + BN_free(r->d); + r->d = d; + } + + return (1); +} + +int +RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) +{ + /* + * If the fields p and q in r are NULL, the corresponding input + * parameters MUST be non-NULL. + */ + if ((r->p == NULL && p == NULL) || (r->q == NULL && q == NULL)) + return (0); + + if (p != NULL) { + BN_free(r->p); + r->p = p; + } + if (q != NULL) { + BN_free(r->q); + r->q = q; + } + + return (1); +} + +int +RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) +{ + /* + * If the fields dmp1, dmq1 and iqmp in r are NULL, the + * corresponding input parameters MUST be non-NULL. + */ + if ((r->dmp1 == NULL && dmp1 == NULL) || + (r->dmq1 == NULL && dmq1 == NULL) || + (r->iqmp == NULL && iqmp == NULL)) + return (0); + + if (dmp1 != NULL) { + BN_free(r->dmp1); + r->dmp1 = dmp1; + } + if (dmq1 != NULL) { + BN_free(r->dmq1); + r->dmq1 = dmq1; + } + if (iqmp != NULL) { + BN_free(r->iqmp); + r->iqmp = iqmp; + } + + return (1); +} + +void +RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) +{ + if (n != NULL) + *n = r->n; + if (e != NULL) + *e = r->e; + if (d != NULL) + *d = r->d; +} + +void +RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) +{ + if (p != NULL) + *p = r->p; + if (q != NULL) + *q = r->q; +} + +void +RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, + const BIGNUM **iqmp) +{ + if (dmp1 != NULL) + *dmp1 = r->dmp1; + if (dmq1 != NULL) + *dmq1 = r->dmq1; + if (iqmp != NULL) + *iqmp = r->iqmp; +} + +void +DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, + const BIGNUM **g) +{ + if (p != NULL) + *p = d->p; + if (q != NULL) + *q = d->q; + if (g != NULL) + *g = d->g; +} + +int +DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + /* + * If the fields p, q and g in d are NULL, the corresponding input + * parameters MUST be non-NULL. + */ + if ((d->p == NULL && p == NULL) || (d->q == NULL && q == NULL) || + (d->g == NULL && g == NULL)) + return (0); + + if (p != NULL) { + BN_free(d->p); + d->p = p; + } + if (q != NULL) { + BN_free(d->q); + d->q = q; + } + if (g != NULL) { + BN_free(d->g); + d->g = g; + } + + return (1); +} + +void +DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key) +{ + if (pub_key != NULL) + *pub_key = d->pub_key; + if (priv_key != NULL) + *priv_key = d->priv_key; +} + +int +DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) +{ + /* + * If the field pub_key in d is NULL, the corresponding input + * parameters MUST be non-NULL. The priv_key field may + * be left NULL. + */ + if (d->pub_key == NULL && pub_key == NULL) + return (0); + + if (pub_key != NULL) { + BN_free(d->pub_key); + d->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(d->priv_key); + d->priv_key = priv_key; + } + + return (1); +} + +void +DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) +{ + if (pr != NULL) + *pr = sig->r; + if (ps != NULL) + *ps = sig->s; +} + +int +DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) +{ + if (r == NULL || s == NULL) + return (0); + BN_clear_free(sig->r); + BN_clear_free(sig->s); + sig->r = r; + sig->s = s; + return (1); +} + +DSA * +EVP_PKEY_get0_DSA(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_DSA) + return (NULL); + return (pkey->pkey.dsa); +} + +void +ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) +{ + if (pr != NULL) + *pr = sig->r; + if (ps != NULL) + *ps = sig->s; +} + +int +ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) +{ + if (r == NULL || s == NULL) + return (0); + BN_clear_free(sig->r); + BN_clear_free(sig->s); + sig->r = r; + sig->s = s; + return (1); +} + +void +DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) +{ + if (p != NULL) + *p = dh->p; + if (q != NULL) + *q = dh->q; + if (g != NULL) + *g = dh->g; +} + +int +DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + /* + * If the fields p and g in d are NULL, the corresponding input + * parameters MUST be non-NULL. q may remain NULL. + */ + if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL)) + return (0); + + if (p != NULL) { + BN_free(dh->p); + dh->p = p; + } + if (q != NULL) { + BN_free(dh->q); + dh->q = q; + } + if (g != NULL) { + BN_free(dh->g); + dh->g = g; + } + + if (q != NULL) { + dh->length = BN_num_bits(q); + } + + return (1); +} + +void +DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) +{ + if (pub_key != NULL) + *pub_key = dh->pub_key; + if (priv_key != NULL) + *priv_key = dh->priv_key; +} + +int +DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) +{ + /* + * If the field pub_key in dh is NULL, the corresponding input + * parameters MUST be non-NULL. The priv_key field may + * be left NULL. + */ + if (dh->pub_key == NULL && pub_key == NULL) + return (0); + + if (pub_key != NULL) { + BN_free(dh->pub_key); + dh->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(dh->priv_key); + dh->priv_key = priv_key; + } + + return (1); +} + +int +DH_set_length(DH *dh, long length) +{ + dh->length = length; + return (1); +} + +const unsigned char * +EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx) +{ + return (ctx->iv); +} + +unsigned char * +EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx) +{ + return (ctx->iv); +} + +EVP_MD_CTX * +EVP_MD_CTX_new(void) +{ + return (OPENSSL_zalloc(sizeof (EVP_MD_CTX))); +} + +void +EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + (void) EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +RSA_METHOD * +RSA_meth_dup(const RSA_METHOD *meth) +{ + RSA_METHOD *ret; + + ret = OPENSSL_malloc(sizeof (RSA_METHOD)); + + if (ret != NULL) { + (void) memcpy(ret, meth, sizeof (*meth)); + ret->name = OPENSSL_strdup(meth->name); + if (ret->name == NULL) { + OPENSSL_free(ret); + return (NULL); + } + } + + return (ret); +} + +int +RSA_meth_set1_name(RSA_METHOD *meth, const char *name) +{ + char *tmpname; + + tmpname = OPENSSL_strdup(name); + if (tmpname == NULL) { + return (0); + } + + OPENSSL_free((char *)meth->name); + meth->name = tmpname; + + return (1); +} + +int +RSA_meth_set_priv_enc(RSA_METHOD *meth, + int (*priv_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding)) +{ + meth->rsa_priv_enc = priv_enc; + return (1); +} + +int +RSA_meth_set_priv_dec(RSA_METHOD *meth, + int (*priv_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding)) +{ + meth->rsa_priv_dec = priv_dec; + return (1); +} + +int +RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa)) +{ + meth->finish = finish; + return (1); +} + +void +RSA_meth_free(RSA_METHOD *meth) +{ + if (meth != NULL) { + OPENSSL_free((char *)meth->name); + OPENSSL_free(meth); + } +} + +int +RSA_bits(const RSA *r) +{ + return (BN_num_bits(r->n)); +} + +RSA * +EVP_PKEY_get0_RSA(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_RSA) { + return (NULL); + } + return (pkey->pkey.rsa); +} + +#endif /* OPENSSL_VERSION_NUMBER */ diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/common/compat.h b/usr/src/lib/libkmf/plugins/kmf_openssl/common/compat.h new file mode 100644 index 0000000000..6613eb8d6d --- /dev/null +++ b/usr/src/lib/libkmf/plugins/kmf_openssl/common/compat.h @@ -0,0 +1,91 @@ +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef LIBCRYPTO_COMPAT_H +#define LIBCRYPTO_COMPAT_H + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + +#include <openssl/rsa.h> +#include <openssl/dsa.h> +#include <openssl/ecdsa.h> +#include <openssl/dh.h> +#include <openssl/evp.h> + +int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); +int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); +int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); +void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, + const BIGNUM **d); +void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q); +void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, + const BIGNUM **dmq1, const BIGNUM **iqmp); + +void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, + const BIGNUM **g); +int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g); +void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, + const BIGNUM **priv_key); +int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key); + +void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); +int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s); +DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey); + +void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); +int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, + const BIGNUM **g); +int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); +void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key); +int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); +int DH_set_length(DH *dh, long length); + +const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx); +unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx); +EVP_MD_CTX *EVP_MD_CTX_new(void); +void EVP_MD_CTX_free(EVP_MD_CTX *ctx); +#define EVP_CIPHER_impl_ctx_size(e) e->ctx_size +#define EVP_CIPHER_CTX_get_cipher_data(ctx) ctx->cipher_data + +RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth); +int RSA_meth_set1_name(RSA_METHOD *meth, const char *name); +#define RSA_meth_get_finish(meth) meth->finish +int RSA_meth_set_priv_enc(RSA_METHOD *meth, + int (*priv_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding)); +int RSA_meth_set_priv_dec(RSA_METHOD *meth, + int (*priv_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding)); +int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa)); +void RSA_meth_free(RSA_METHOD *meth); + +int RSA_bits(const RSA *r); + +RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); + +#define OCSP_resp_get0_certs(bs) ((bs)->certs) +#define PKCS12_SAFEBAG_get0_attr(bag, attr) PKCS12_get_attr(bag, attr) +#define PKCS12_SAFEBAG_get_nid(bag) M_PKCS12_bag_type(bag) +#define PKCS12_SAFEBAG_get0_p8inf(bag) ((bag)->value.keybag) +#define PKCS12_SAFEBAG_get0_safes(bag) ((bag)->value.safes) +#define PKCS12_SAFEBAG_create_cert PKCS12_x5092certbag +#define PKCS12_SAFEBAG_create_pkcs8_encrypt PKCS12_MAKE_SHKEYBAG +#define PKCS12_SAFEBAG_get_bag_nid M_PKCS12_cert_bag_type +#define PKCS12_SAFEBAG_get1_cert PKCS12_certbag2x509 +#define X509_REVOKED_get0_serialNumber(revoke) ((revoke)->serialNumber) +#define X509_CRL_get0_lastUpdate(xcrl) X509_CRL_get_lastUpdate(xcrl) +#define X509_CRL_get0_nextUpdate(xcrl) X509_CRL_get_nextUpdate(xcrl) +#define X509_getm_notBefore X509_get_notBefore +#define X509_getm_notAfter X509_get_notAfter + +#endif /* OPENSSL_VERSION_NUMBER */ + +#endif /* LIBCRYPTO_COMPAT_H */ diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c index 46aea6a2aa..3ca328ff05 100644 --- a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c +++ b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c @@ -5,6 +5,7 @@ */ /* * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved. + * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. */ /* * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL @@ -80,7 +81,6 @@ #include <openssl/bn.h> #include <openssl/asn1.h> #include <openssl/err.h> -#include <openssl/bn.h> #include <openssl/x509.h> #include <openssl/rsa.h> #include <openssl/dsa.h> @@ -91,6 +91,7 @@ #include <openssl/ocsp.h> #include <openssl/des.h> #include <openssl/rand.h> +#include "compat.h" #define PRINT_ANY_EXTENSION (\ KMF_X509_EXT_KEY_USAGE |\ @@ -137,6 +138,7 @@ static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, /* * Declare some new macros for managing stacks of EVP_PKEYS. */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L DECLARE_STACK_OF(EVP_PKEY) #define sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY) @@ -147,6 +149,11 @@ DECLARE_STACK_OF(EVP_PKEY) #define sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \ (free_func)) +#else +/* LINTED E_STATIC_UNUSED */ +DEFINE_STACK_OF(EVP_PKEY) +#endif + mutex_t init_lock = DEFAULTMUTEX; static int ssl_initialized = 0; static BIO *bio_err = NULL; @@ -293,6 +300,7 @@ KMF_PLUGIN_FUNCLIST openssl_plugin_table = NULL /* Finalize */ }; +#if OPENSSL_VERSION_NUMBER < 0x10100000L static mutex_t *lock_cs; static long *lock_count; @@ -313,11 +321,14 @@ thread_id() { return ((unsigned long)thr_self()); } +#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ KMF_PLUGIN_FUNCLIST * KMF_Plugin_Initialize() { +#if OPENSSL_VERSION_NUMBER < 0x10100000L int i; +#endif (void) mutex_lock(&init_lock); if (!ssl_initialized) { @@ -335,8 +346,11 @@ KMF_Plugin_Initialize() "X509v3 Freshest CRL"); (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy", "X509v3 Inhibit Any-Policy"); + +#if OPENSSL_VERSION_NUMBER < 0x10100000L /* * Set up for thread-safe operation. + * This is not required for OpenSSL 1.1 */ lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t)); if (lock_cs == NULL) { @@ -360,10 +374,11 @@ KMF_Plugin_Initialize() if (CRYPTO_get_locking_callback() == NULL) CRYPTO_set_locking_callback((void (*)())locking_cb); - OpenSSL_add_all_algorithms(); + (void) OpenSSL_add_all_algorithms(); /* Enable error strings for reporting */ - ERR_load_crypto_strings(); + (void) ERR_load_crypto_strings(); +#endif ssl_initialized = 1; } @@ -371,6 +386,7 @@ KMF_Plugin_Initialize() return (&openssl_plugin_table); } + /* * Convert an SSL DN to a KMF DN. */ @@ -485,7 +501,7 @@ check_cert(X509 *xcert, char *issuer, char *subject, KMF_BIGINT *serial, if (rv != KMF_OK) return (KMF_ERR_BAD_PARAMETER); - rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN); + rv = get_x509_dn(X509_get_issuer_name(xcert), &certIssuerDN); if (rv != KMF_OK) { kmf_free_dn(&issuerDN); return (KMF_ERR_BAD_PARAMETER); @@ -500,7 +516,7 @@ check_cert(X509 *xcert, char *issuer, char *subject, KMF_BIGINT *serial, goto cleanup; } - rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN); + rv = get_x509_dn(X509_get_subject_name(xcert), &certSubjectDN); if (rv != KMF_OK) { rv = KMF_ERR_BAD_PARAMETER; goto cleanup; @@ -514,7 +530,7 @@ check_cert(X509 *xcert, char *issuer, char *subject, KMF_BIGINT *serial, BIGNUM *bn; /* Comparing BIGNUMs is a pain! */ - bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL); + bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(xcert), NULL); if (bn != NULL) { int bnlen = BN_num_bytes(bn); @@ -1420,17 +1436,13 @@ ssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, case KMF_FORMAT_RAWKEY: /* same as ASN.1 */ case KMF_FORMAT_ASN1: - if (pkey->type == EVP_PKEY_RSA) { - rsa = EVP_PKEY_get1_RSA(pkey); + if ((rsa = EVP_PKEY_get0_RSA(pkey)) != NULL) { if (private) rv = i2d_RSAPrivateKey_bio(out, rsa); else rv = i2d_RSAPublicKey_bio(out, rsa); - RSA_free(rsa); - } else if (pkey->type == EVP_PKEY_DSA) { - dsa = EVP_PKEY_get1_DSA(pkey); + } else if ((dsa = EVP_PKEY_get0_DSA(pkey)) != NULL) { rv = i2d_DSAPrivateKey_bio(out, dsa); - DSA_free(dsa); } if (rv == 1) { rv = KMF_OK; @@ -1439,8 +1451,7 @@ ssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, } break; case KMF_FORMAT_PEM: - if (pkey->type == EVP_PKEY_RSA) { - rsa = EVP_PKEY_get1_RSA(pkey); + if ((rsa = EVP_PKEY_get0_RSA(pkey)) != NULL) { if (private) rv = PEM_write_bio_RSAPrivateKey(out, rsa, NULL, NULL, 0, NULL, @@ -1448,13 +1459,10 @@ ssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, else rv = PEM_write_bio_RSAPublicKey(out, rsa); - RSA_free(rsa); - } else if (pkey->type == EVP_PKEY_DSA) { - dsa = EVP_PKEY_get1_DSA(pkey); + } else if ((dsa = EVP_PKEY_get0_DSA(pkey)) != NULL) { rv = PEM_write_bio_DSAPrivateKey(out, dsa, NULL, NULL, 0, NULL, (cred != NULL ? cred->cred : NULL)); - DSA_free(dsa); } if (rv == 1) { @@ -1477,7 +1485,8 @@ OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - uint32_t eValue = 0x010001; + uint32_t eValue = RSA_F4; + BIGNUM *eValue_bn = NULL; RSA *sslPrivKey = NULL; DSA *sslDSAKey = NULL; EVP_PKEY *eprikey = NULL; @@ -1489,6 +1498,14 @@ OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, boolean_t storekey = TRUE; KMF_KEY_ALG keytype = KMF_RSA; + eValue_bn = BN_new(); + if (eValue_bn == NULL) + return (KMF_ERR_MEMORY); + if (BN_set_word(eValue_bn, eValue) == 0) { + rv = KMF_ERR_KEYGEN_FAILED; + goto cleanup; + } + rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr, &storekey, NULL); if (rv != KMF_OK) { @@ -1503,12 +1520,16 @@ OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, rv = KMF_OK; pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); - if (pubkey == NULL) - return (KMF_ERR_BAD_PARAMETER); + if (pubkey == NULL) { + rv = KMF_ERR_BAD_PARAMETER; + goto cleanup; + } privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); - if (privkey == NULL) - return (KMF_ERR_BAD_PARAMETER); + if (privkey == NULL) { + rv = KMF_ERR_BAD_PARAMETER; + goto cleanup; + } (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE)); (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE)); @@ -1535,6 +1556,10 @@ OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, rsaexp->val != NULL) { /* LINTED E_BAD_PTR_CAST_ALIGN */ eValue = *(uint32_t *)rsaexp->val; + if (BN_set_word(eValue_bn, eValue) == 0) { + rv = KMF_ERR_BAD_PARAMETER; + goto cleanup; + } } else { rv = KMF_ERR_BAD_PARAMETER; goto cleanup; @@ -1554,8 +1579,10 @@ OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, goto cleanup; } - sslPrivKey = RSA_generate_key(keylen, eValue, NULL, NULL); - if (sslPrivKey == NULL) { + sslPrivKey = RSA_new(); + if (sslPrivKey == NULL || + RSA_generate_key_ex(sslPrivKey, keylen, eValue_bn, NULL) + == 0) { SET_ERROR(kmfh, ERR_get_error()); rv = KMF_ERR_KEYGEN_FAILED; } else { @@ -1575,27 +1602,27 @@ OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, pubkey->keyp = (void *)epubkey; } } else if (keytype == KMF_DSA) { - DSA *dp; + BIGNUM *p, *q, *g; + sslDSAKey = DSA_new(); if (sslDSAKey == NULL) { SET_ERROR(kmfh, ERR_get_error()); return (KMF_ERR_MEMORY); } - if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) == - NULL) { + p = BN_bin2bn(P, sizeof (P), NULL); + q = BN_bin2bn(Q, sizeof (Q), NULL); + g = BN_bin2bn(G, sizeof (G), NULL); + if (p == NULL || q == NULL || g == NULL) { + BN_free(p); + BN_free(q); + BN_free(g); SET_ERROR(kmfh, ERR_get_error()); rv = KMF_ERR_KEYGEN_FAILED; goto cleanup; } - if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) == - NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_KEYGEN_FAILED; - goto cleanup; - } - if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) == - NULL) { + + if (DSA_set0_pqg(sslDSAKey, p, q, g) == 0) { SET_ERROR(kmfh, ERR_get_error()); rv = KMF_ERR_KEYGEN_FAILED; goto cleanup; @@ -1618,56 +1645,18 @@ OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, rv = KMF_ERR_KEYGEN_FAILED; goto cleanup; } - dp = DSA_new(); - /* Make a copy for the public key */ - if (dp != NULL) { - if ((dp->p = BN_new()) == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_MEMORY; - DSA_free(dp); - goto cleanup; - } - if ((dp->q = BN_new()) == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_MEMORY; - BN_free(dp->p); - DSA_free(dp); - goto cleanup; - } - if ((dp->g = BN_new()) == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_MEMORY; - BN_free(dp->q); - BN_free(dp->p); - DSA_free(dp); - goto cleanup; - } - if ((dp->pub_key = BN_new()) == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_MEMORY; - BN_free(dp->q); - BN_free(dp->p); - BN_free(dp->g); - DSA_free(dp); - goto cleanup; - } - (void) BN_copy(dp->p, sslDSAKey->p); - (void) BN_copy(dp->q, sslDSAKey->q); - (void) BN_copy(dp->g, sslDSAKey->g); - (void) BN_copy(dp->pub_key, sslDSAKey->pub_key); - pubkey->kstype = KMF_KEYSTORE_OPENSSL; - pubkey->keyalg = KMF_DSA; - pubkey->keyclass = KMF_ASYM_PUB; - pubkey->israw = FALSE; + pubkey->kstype = KMF_KEYSTORE_OPENSSL; + pubkey->keyalg = KMF_DSA; + pubkey->keyclass = KMF_ASYM_PUB; + pubkey->israw = FALSE; - if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { - pubkey->keyp = (void *)epubkey; - } else { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_KEYGEN_FAILED; - goto cleanup; - } + if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { + pubkey->keyp = (void *)epubkey; + } else { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_KEYGEN_FAILED; + goto cleanup; } } @@ -1719,6 +1708,9 @@ OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, } cleanup: + if (eValue_bn != NULL) + BN_free(eValue_bn); + if (rv != KMF_OK) { if (eprikey != NULL) EVP_PKEY_free(eprikey); @@ -1759,7 +1751,7 @@ cleanup: * all of the bits. */ static int -fixbnlen(BIGNUM *bn, unsigned char *buf, int len) { +fixbnlen(const BIGNUM *bn, unsigned char *buf, int len) { int bytes = len - BN_num_bytes(bn); /* prepend with leading 0x00 if necessary */ @@ -1781,7 +1773,7 @@ OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, KMF_RETURN ret = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; KMF_ALGORITHM_INDEX AlgId; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; const EVP_MD *md; if (key == NULL || AlgOID == NULL || @@ -1826,19 +1818,20 @@ OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, } output->Length = len; } else { - (void) EVP_MD_CTX_init(&ctx); - (void) EVP_SignInit_ex(&ctx, md, NULL); - (void) EVP_SignUpdate(&ctx, tobesigned->Data, + if ((ctx = EVP_MD_CTX_new()) == NULL) + return (KMF_ERR_MEMORY); + (void) EVP_SignInit_ex(ctx, md, NULL); + (void) EVP_SignUpdate(ctx, tobesigned->Data, (uint32_t)tobesigned->Length); len = (uint32_t)output->Length; p = output->Data; - if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) { + if (!EVP_SignFinal(ctx, p, (uint32_t *)&len, pkey)) { SET_ERROR(kmfh, ERR_get_error()); len = 0; ret = KMF_ERR_INTERNAL; } output->Length = len; - (void) EVP_MD_CTX_cleanup(&ctx); + EVP_MD_CTX_free(ctx); } } else if (key->keyalg == KMF_DSA) { DSA *dsa = EVP_PKEY_get1_DSA(key->keyp); @@ -1863,11 +1856,12 @@ OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, * not all mechanisms return ASN.1 encodings (PKCS#11 * and NSS return raw signature data). */ - EVP_MD_CTX_init(&ctx); - (void) EVP_DigestInit_ex(&ctx, md, NULL); - (void) EVP_DigestUpdate(&ctx, tobesigned->Data, + if ((ctx = EVP_MD_CTX_new()) == NULL) + return (KMF_ERR_MEMORY); + (void) EVP_DigestInit_ex(ctx, md, NULL); + (void) EVP_DigestUpdate(ctx, tobesigned->Data, tobesigned->Length); - (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen); + (void) EVP_DigestFinal_ex(ctx, hash, &hashlen); /* Only sign first 20 bytes for SHA2 */ if (AlgId == KMF_ALGID_SHA256WithDSA) @@ -1875,17 +1869,20 @@ OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, dsasig = DSA_do_sign(hash, hashlen, dsa); if (dsasig != NULL) { int i; - output->Length = i = fixbnlen(dsasig->r, output->Data, + const BIGNUM *r, *s; + + DSA_SIG_get0(dsasig, &r, &s); + output->Length = i = fixbnlen(r, output->Data, hashlen); - output->Length += fixbnlen(dsasig->s, &output->Data[i], + output->Length += fixbnlen(s, &output->Data[i], hashlen); DSA_SIG_free(dsasig); } else { SET_ERROR(kmfh, ERR_get_error()); } - (void) EVP_MD_CTX_cleanup(&ctx); + EVP_MD_CTX_free(ctx); } else { return (KMF_ERR_BAD_PARAMETER); } @@ -2023,17 +2020,11 @@ OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, X509 *xcert = NULL; unsigned char *outbuf = NULL; unsigned char *outbuf_p; - char *tmpstr = NULL; int j; int ext_index, nid, len; BIO *mem = NULL; -#if OPENSSL_VERSION_NUMBER < 0x10000000L - STACK *emlst = NULL; -#else STACK_OF(OPENSSL_STRING) *emlst = NULL; -#endif X509_EXTENSION *ex; - X509_CINF *ci; if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) { return (KMF_ERR_BAD_PARAMETER); @@ -2075,9 +2066,8 @@ OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, break; case KMF_CERT_VERSION: - tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version); - (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN); - OPENSSL_free(tmpstr); + (void) snprintf(resultStr, KMF_CERT_PRINTABLE_LEN, + "%ld", X509_get_version(xcert)); len = strlen(resultStr); break; @@ -2090,17 +2080,20 @@ OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, break; case KMF_CERT_NOTBEFORE: - (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert)); + (void) ASN1_TIME_print(mem, X509_getm_notBefore(xcert)); len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); break; case KMF_CERT_NOTAFTER: - (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert)); + (void) ASN1_TIME_print(mem, X509_getm_notAfter(xcert)); len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); break; case KMF_CERT_PUBKEY_DATA: { + RSA *rsa; + DSA *dsa; + EVP_PKEY *pkey = X509_get_pubkey(xcert); if (pkey == NULL) { SET_ERROR(kmfh, ERR_get_error()); @@ -2108,15 +2101,16 @@ OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, goto out; } - if (pkey->type == EVP_PKEY_RSA) { + if ((rsa = EVP_PKEY_get0_RSA(pkey)) != NULL) { (void) BIO_printf(mem, "RSA Public Key: (%d bit)\n", - BN_num_bits(pkey->pkey.rsa->n)); - (void) RSA_print(mem, pkey->pkey.rsa, 0); - } else if (pkey->type == EVP_PKEY_DSA) { + RSA_bits(rsa)); + (void) RSA_print(mem, rsa, 0); + + } else if ((dsa = EVP_PKEY_get0_DSA(pkey)) != NULL) { (void) BIO_printf(mem, "%12sDSA Public Key:\n", ""); - (void) DSA_print(mem, pkey->pkey.dsa, 0); + (void) DSA_print(mem, dsa, 0); } else { (void) BIO_printf(mem, "%12sUnknown Public Key:\n", ""); @@ -2128,30 +2122,50 @@ OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, break; case KMF_CERT_SIGNATURE_ALG: case KMF_CERT_PUBKEY_ALG: - if (flag == KMF_CERT_SIGNATURE_ALG) { - len = i2a_ASN1_OBJECT(mem, - xcert->sig_alg->algorithm); - } else { - len = i2a_ASN1_OBJECT(mem, - xcert->cert_info->key->algor->algorithm); - } + { +#if OPENSSL_VERSION_NUMBER < 0x10100000L + ASN1_OBJECT *alg = NULL; +#else + const ASN1_OBJECT *alg = NULL; +#endif + + if (flag == KMF_CERT_SIGNATURE_ALG) { +#if OPENSSL_VERSION_NUMBER < 0x10100000L + alg = xcert->sig_alg->algorithm; +#else + const X509_ALGOR *sig_alg = NULL; + + X509_get0_signature(NULL, &sig_alg, xcert); + if (sig_alg != NULL) + X509_ALGOR_get0(&alg, NULL, NULL, + sig_alg); +#endif + } else { +#if OPENSSL_VERSION_NUMBER < 0x10100000L + alg = xcert->cert_info->key->algor->algorithm; +#else + X509_PUBKEY *key = X509_get_X509_PUBKEY(xcert); + + if (key != NULL) + (void) X509_PUBKEY_get0_param( + (ASN1_OBJECT **)&alg, NULL, 0, + NULL, key); +#endif + } - if (len > 0) { - len = BIO_read(mem, resultStr, - KMF_CERT_PRINTABLE_LEN); + if (alg == NULL) + len = -1; + else if ((len = i2a_ASN1_OBJECT(mem, alg)) > 0) + len = BIO_read(mem, resultStr, + KMF_CERT_PRINTABLE_LEN); } break; case KMF_CERT_EMAIL: emlst = X509_get1_email(xcert); -#if OPENSSL_VERSION_NUMBER < 0x10000000L - for (j = 0; j < sk_num(emlst); j++) - (void) BIO_printf(mem, "%s\n", sk_value(emlst, j)); -#else for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) (void) BIO_printf(mem, "%s\n", sk_OPENSSL_STRING_value(emlst, j)); -#endif len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); X509_email_free(emlst); @@ -2176,16 +2190,15 @@ OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, ret = KMF_ERR_EXTENSION_NOT_FOUND; goto out; } - ci = xcert->cert_info; - ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1); + ext_index = X509_get_ext_by_NID(xcert, nid, -1); if (ext_index == -1) { SET_ERROR(kmfh, ERR_get_error()); ret = KMF_ERR_EXTENSION_NOT_FOUND; goto out; } - ex = X509v3_get_ext(ci->extensions, ext_index); + ex = X509_get_ext(xcert, ext_index); (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex)); @@ -2197,7 +2210,8 @@ OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, } if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) { (void) BIO_printf(mem, "%*s", 4, ""); - (void) M_ASN1_OCTET_STRING_print(mem, ex->value); + (void) ASN1_STRING_print(mem, + X509_EXTENSION_get_data(ex)); } if (BIO_write(mem, "\n", 1) <= 0) { SET_ERROR(kmfh, ERR_get_error()); @@ -2478,22 +2492,36 @@ end: } /* ocsp_find_signer_sk() is copied from openssl source */ -static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) +static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_BASICRESP *bs) { int i; unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; + const ASN1_OCTET_STRING *pid; + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + OCSP_RESPID *id = bs->tbsResponseData->responderId; - /* Easy if lookup by name */ if (id->type == V_OCSP_RESPID_NAME) return (X509_find_by_subject(certs, id->value.byName)); + pid = id->value.byKey; +#else + const X509_NAME *pname; + + if (OCSP_resp_get0_id(bs, &pid, &pname) == 0) + return (NULL); + + if (pname != NULL) + return (X509_find_by_subject(certs, (X509_NAME *)pname)); +#endif + /* Lookup by key hash */ /* If key hash isn't SHA1 length then forget it */ - if (id->value.byKey->length != SHA_DIGEST_LENGTH) + if (pid->length != SHA_DIGEST_LENGTH) return (NULL); - keyhash = id->value.byKey->data; + keyhash = pid->data; /* Calculate hash of each key and compare */ for (i = 0; i < sk_X509_num(certs); i++) { /* LINTED E_BAD_PTR_CAST_ALIGN */ @@ -2513,13 +2541,14 @@ ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags) { X509 *signer; - OCSP_RESPID *rid = bs->tbsResponseData->responderId; - if ((signer = ocsp_find_signer_sk(certs, rid))) { + if ((signer = ocsp_find_signer_sk(certs, bs))) { *psigner = signer; return (2); } + if (!(flags & OCSP_NOINTERN) && - (signer = ocsp_find_signer_sk(bs->certs, rid))) { + (signer = ocsp_find_signer_sk( + (STACK_OF(X509) *)OCSP_resp_get0_certs(bs), bs))) { *psigner = signer; return (1); } @@ -2542,10 +2571,13 @@ check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs, STACK_OF(X509) *cert_stack = NULL; X509 *signer = NULL; X509 *issuer = NULL; +#if OPENSSL_VERSION_NUMBER < 0x10100000L EVP_PKEY *skey = NULL; +#else + STACK_OF(X509) *cert_stack2 = NULL; +#endif unsigned char *ptmp; - if (bs == NULL || issuer_cert == NULL) return (KMF_ERR_BAD_PARAMETER); @@ -2599,6 +2631,7 @@ check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs, } /* Verify the signature of the response */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L skey = X509_get_pubkey(signer); if (skey == NULL) { ret = KMF_ERR_OCSP_BAD_SIGNER; @@ -2606,6 +2639,25 @@ check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs, } ret = OCSP_BASICRESP_verify(bs, skey, 0); +#else + /* + * Technique based on + * https://mta.openssl.org/pipermail/openssl-users/ + * 2017-October/006814.html + */ + if ((cert_stack2 = sk_X509_new_null()) == NULL) { + ret = KMF_ERR_INTERNAL; + goto end; + } + + if (sk_X509_push(cert_stack2, signer) == NULL) { + ret = KMF_ERR_INTERNAL; + goto end; + } + + ret = OCSP_basic_verify(bs, cert_stack2, NULL, OCSP_NOVERIFY); +#endif + if (ret == 0) { ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE; goto end; @@ -2620,9 +2672,15 @@ end: X509_free(signer); } +#if OPENSSL_VERSION_NUMBER < 0x10100000L if (skey != NULL) { EVP_PKEY_free(skey); } +#else + if (cert_stack2 != NULL) { + sk_X509_free(cert_stack2); + } +#endif if (cert_stack != NULL) { sk_X509_free(cert_stack); @@ -2631,8 +2689,6 @@ end: return (ret); } - - KMF_RETURN OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) @@ -2821,9 +2877,9 @@ fetch_key(KMF_HANDLE_T handle, char *path, return (KMF_ERR_KEY_NOT_FOUND); } if (key != NULL) { - if (pkey->type == EVP_PKEY_RSA) + if (EVP_PKEY_get0_RSA(pkey) != NULL) key->keyalg = KMF_RSA; - else if (pkey->type == EVP_PKEY_DSA) + else if (EVP_PKEY_get0_DSA(pkey) != NULL) key->keyalg = KMF_DSA; key->kstype = KMF_KEYSTORE_OPENSSL; @@ -3020,11 +3076,12 @@ OpenSSL_FindKey(KMF_HANDLE_T handle, static int add_alias_to_bag(PKCS12_SAFEBAG *bag, X509 *xcert) { - if (xcert != NULL && xcert->aux != NULL && - xcert->aux->alias != NULL) { + unsigned char *alias; + int len; + + if (xcert != NULL && (alias = X509_alias_get0(xcert, &len)) != NULL) { if (PKCS12_add_friendlyname_asc(bag, - (const char *)xcert->aux->alias->data, - xcert->aux->alias->length) == 0) + (const char *)alias, len) == 0) return (0); } return (1); @@ -3043,7 +3100,7 @@ add_cert_to_safe(X509 *sslcert, KMF_CREDENTIAL *cred, return (NULL); /* Convert cert from X509 struct to PKCS#12 bag */ - bag = PKCS12_x5092certbag(sslcert); + bag = PKCS12_SAFEBAG_create_cert(sslcert); if (bag == NULL) { goto out; } @@ -3088,7 +3145,7 @@ add_key_to_safe(EVP_PKEY *pkey, KMF_CREDENTIAL *cred, return (NULL); } /* Put the shrouded key into a PKCS#12 bag. */ - bag = PKCS12_MAKE_SHKEYBAG( + bag = PKCS12_SAFEBAG_create_pkcs8_encrypt( NID_pbe_WithSHA1And3_Key_TripleDES_CBC, cred->cred, cred->credlen, NULL, 0, PKCS12_DEFAULT_ITER, p8); @@ -3127,55 +3184,71 @@ static EVP_PKEY * ImportRawRSAKey(KMF_RAW_RSA_KEY *key) { RSA *rsa = NULL; - EVP_PKEY *newkey = NULL; + EVP_PKEY *newkey = NULL; + BIGNUM *n = NULL, *e = NULL, *d = NULL, + *p = NULL, *q = NULL, + *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; if ((rsa = RSA_new()) == NULL) - return (NULL); + goto cleanup; - if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL) - return (NULL); + if ((n = BN_bin2bn(key->mod.val, key->mod.len, NULL)) == NULL) + goto cleanup; - if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) == - NULL) - return (NULL); + if ((e = BN_bin2bn(key->pubexp.val, key->pubexp.len, NULL)) == NULL) + goto cleanup; - if (key->priexp.val != NULL) - if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len, - rsa->d)) == NULL) - return (NULL); + if (key->priexp.val != NULL && + (d = BN_bin2bn(key->priexp.val, key->priexp.len, NULL)) == NULL) + goto cleanup; - if (key->prime1.val != NULL) - if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len, - rsa->p)) == NULL) - return (NULL); + if (key->prime1.val != NULL && + (p = BN_bin2bn(key->prime1.val, key->prime1.len, NULL)) == NULL) + goto cleanup; - if (key->prime2.val != NULL) - if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len, - rsa->q)) == NULL) - return (NULL); + if (key->prime2.val != NULL && + (q = BN_bin2bn(key->prime2.val, key->prime2.len, NULL)) == NULL) + goto cleanup; - if (key->exp1.val != NULL) - if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len, - rsa->dmp1)) == NULL) - return (NULL); + if (key->exp1.val != NULL && + (dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len, NULL)) == NULL) + goto cleanup; - if (key->exp2.val != NULL) - if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len, - rsa->dmq1)) == NULL) - return (NULL); + if (key->exp2.val != NULL && + (dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len, NULL)) == NULL) + goto cleanup; - if (key->coef.val != NULL) - if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len, - rsa->iqmp)) == NULL) - return (NULL); + if (key->coef.val != NULL && + (iqmp = BN_bin2bn(key->coef.val, key->coef.len, NULL)) == NULL) + goto cleanup; + + if (RSA_set0_key(rsa, n, e, d) == 0) + goto cleanup; + n = e = d = NULL; + if (RSA_set0_factors(rsa, p, q) == 0) + goto cleanup; + p = q = NULL; + if (RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) == 0) + goto cleanup; + dmp1 = dmq1 = iqmp = NULL; if ((newkey = EVP_PKEY_new()) == NULL) - return (NULL); + goto cleanup; (void) EVP_PKEY_set1_RSA(newkey, rsa); +cleanup: /* The original key must be freed once here or it leaks memory */ - RSA_free(rsa); + if (rsa) + RSA_free(rsa); + BN_free(n); + BN_free(e); + BN_free(d); + BN_free(p); + BN_free(q); + BN_free(dmp1); + BN_free(dmq1); + BN_free(iqmp); return (newkey); } @@ -3184,40 +3257,52 @@ static EVP_PKEY * ImportRawDSAKey(KMF_RAW_DSA_KEY *key) { DSA *dsa = NULL; - EVP_PKEY *newkey = NULL; + EVP_PKEY *newkey = NULL; + BIGNUM *p = NULL, *q = NULL, *g = NULL, + *priv_key = NULL, *pub_key = NULL; if ((dsa = DSA_new()) == NULL) - return (NULL); + goto cleanup; - if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len, - dsa->p)) == NULL) - return (NULL); + if ((p = BN_bin2bn(key->prime.val, key->prime.len, NULL)) == NULL) + goto cleanup; - if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len, - dsa->q)) == NULL) - return (NULL); + if ((q = BN_bin2bn(key->subprime.val, key->subprime.len, NULL)) == NULL) + goto cleanup; - if ((dsa->g = BN_bin2bn(key->base.val, key->base.len, - dsa->g)) == NULL) - return (NULL); + if ((g = BN_bin2bn(key->base.val, key->base.len, NULL)) == NULL) + goto cleanup; - if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len, - dsa->priv_key)) == NULL) - return (NULL); + if ((priv_key = BN_bin2bn(key->value.val, key->value.len, + NULL)) == NULL) + goto cleanup; - if (key->pubvalue.val != NULL) { - if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val, - key->pubvalue.len, dsa->pub_key)) == NULL) - return (NULL); - } + if (key->pubvalue.val != NULL && (pub_key = + BN_bin2bn(key->pubvalue.val, key->pubvalue.len, NULL)) == NULL) + goto cleanup; + + if (DSA_set0_pqg(dsa, p, q, g) == 0) + goto cleanup; + p = q = g = NULL; + if (DSA_set0_key(dsa, pub_key, priv_key) == 0) + goto cleanup; + pub_key = priv_key = 0; if ((newkey = EVP_PKEY_new()) == NULL) - return (NULL); + goto cleanup; (void) EVP_PKEY_set1_DSA(newkey, dsa); +cleanup: /* The original key must be freed once here or it leaks memory */ - DSA_free(dsa); + if (dsa) + DSA_free(dsa); + BN_free(p); + BN_free(q); + BN_free(g); + BN_free(priv_key); + BN_free(pub_key); + return (newkey); } @@ -3732,7 +3817,7 @@ err: } static KMF_RETURN -openssl_parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *pin, +openssl_parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, char *pin, STACK_OF(EVP_PKEY) *keys, STACK_OF(X509) *certs) { KMF_RETURN ret; @@ -3759,28 +3844,13 @@ set_pkey_attrib(EVP_PKEY *pkey, ASN1_TYPE *attrib, int nid) if (pkey == NULL || attrib == NULL) return (KMF_ERR_BAD_PARAMETER); - if (pkey->attributes == NULL) { - pkey->attributes = sk_X509_ATTRIBUTE_new_null(); - if (pkey->attributes == NULL) - return (KMF_ERR_MEMORY); - } attr = X509_ATTRIBUTE_create(nid, attrib->type, attrib->value.ptr); if (attr != NULL) { int i; - X509_ATTRIBUTE *a; - for (i = 0; - i < sk_X509_ATTRIBUTE_num(pkey->attributes); i++) { - /* LINTED E_BAD_PTR_CASE_ALIGN */ - a = sk_X509_ATTRIBUTE_value(pkey->attributes, i); - if (OBJ_obj2nid(a->object) == nid) { - X509_ATTRIBUTE_free(a); - /* LINTED E_BAD_PTR_CAST_ALIGN */ - (void) sk_X509_ATTRIBUTE_set(pkey->attributes, - i, attr); - return (KMF_OK); - } - } - if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == NULL) { + + if ((i = EVP_PKEY_get_attr_by_NID(pkey, nid, -1)) != -1) + (void) EVP_PKEY_delete_attr(pkey, i); + if (EVP_PKEY_add1_attr(pkey, attr) == 0) { X509_ATTRIBUTE_free(attr); return (KMF_ERR_MEMORY); } @@ -3799,18 +3869,19 @@ openssl_parse_bag(PKCS12_SAFEBAG *bag, char *pass, int passlen, PKCS8_PRIV_KEY_INFO *p8 = NULL; EVP_PKEY *pkey = NULL; X509 *xcert = NULL; - ASN1_TYPE *keyid = NULL; - ASN1_TYPE *fname = NULL; + const ASN1_TYPE *keyid = NULL; + const ASN1_TYPE *fname = NULL; uchar_t *data = NULL; - keyid = PKCS12_get_attr(bag, NID_localKeyID); - fname = PKCS12_get_attr(bag, NID_friendlyName); + keyid = PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID); + fname = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName); - switch (M_PKCS12_bag_type(bag)) { + switch (PKCS12_SAFEBAG_get_nid(bag)) { case NID_keyBag: if (keylist == NULL) goto end; - pkey = EVP_PKCS82PKEY(bag->value.keybag); + pkey = EVP_PKCS82PKEY( + PKCS12_SAFEBAG_get0_p8inf(bag)); if (pkey == NULL) ret = KMF_ERR_PKCS12_FORMAT; @@ -3818,7 +3889,7 @@ openssl_parse_bag(PKCS12_SAFEBAG *bag, char *pass, int passlen, case NID_pkcs8ShroudedKeyBag: if (keylist == NULL) goto end; - p8 = M_PKCS12_decrypt_skey(bag, pass, passlen); + p8 = PKCS12_decrypt_skey(bag, pass, passlen); if (p8 == NULL) return (KMF_ERR_AUTH_FAILED); pkey = EVP_PKCS82PKEY(p8); @@ -3829,9 +3900,10 @@ openssl_parse_bag(PKCS12_SAFEBAG *bag, char *pass, int passlen, case NID_certBag: if (certlist == NULL) goto end; - if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) + if (PKCS12_SAFEBAG_get_bag_nid(bag) != + NID_x509Certificate) return (KMF_ERR_PKCS12_FORMAT); - xcert = M_PKCS12_certbag2x509(bag); + xcert = PKCS12_SAFEBAG_get1_cert(bag); if (xcert == NULL) { ret = KMF_ERR_PKCS12_FORMAT; goto end; @@ -3865,8 +3937,9 @@ openssl_parse_bag(PKCS12_SAFEBAG *bag, char *pass, int passlen, xcert = NULL; break; case NID_safeContentsBag: - return (openssl_parse_bags(bag->value.safes, pass, - keylist, certlist)); + return (openssl_parse_bags( + PKCS12_SAFEBAG_get0_safes(bag), + pass, keylist, certlist)); default: ret = KMF_ERR_PKCS12_FORMAT; break; @@ -4076,35 +4149,41 @@ exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key) KMF_RETURN rv; KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa; + const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmpq, *iqmp; + + RSA_get0_key(rsa, &n, &e, &d); + RSA_get0_factors(rsa, &p, &q); + RSA_get0_crt_params(rsa, &dmp1, &dmpq, &iqmp); + (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY)); - if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK) + if ((rv = sslBN2KMFBN((BIGNUM *)n, &kmfkey->mod)) != KMF_OK) goto cleanup; - if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK) + if ((rv = sslBN2KMFBN((BIGNUM *)e, &kmfkey->pubexp)) != KMF_OK) goto cleanup; - if (rsa->d != NULL) - if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK) + if (d != NULL) + if ((rv = sslBN2KMFBN((BIGNUM *)d, &kmfkey->priexp)) != KMF_OK) goto cleanup; - if (rsa->p != NULL) - if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK) + if (p != NULL) + if ((rv = sslBN2KMFBN((BIGNUM *)p, &kmfkey->prime1)) != KMF_OK) goto cleanup; - if (rsa->q != NULL) - if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK) + if (q != NULL) + if ((rv = sslBN2KMFBN((BIGNUM *)q, &kmfkey->prime2)) != KMF_OK) goto cleanup; - if (rsa->dmp1 != NULL) - if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK) + if (dmp1 != NULL) + if ((rv = sslBN2KMFBN((BIGNUM *)dmp1, &kmfkey->exp1)) != KMF_OK) goto cleanup; - if (rsa->dmq1 != NULL) - if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK) + if (dmpq != NULL) + if ((rv = sslBN2KMFBN((BIGNUM *)dmpq, &kmfkey->exp2)) != KMF_OK) goto cleanup; - if (rsa->iqmp != NULL) - if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK) + if (iqmp != NULL) + if ((rv = sslBN2KMFBN((BIGNUM *)iqmp, &kmfkey->coef)) != KMF_OK) goto cleanup; cleanup: if (rv != KMF_OK) @@ -4126,18 +4205,22 @@ exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key) { KMF_RETURN rv; KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa; + const BIGNUM *p, *q, *g, *priv_key; + + DSA_get0_pqg(dsa, &p, &q, &g); + DSA_get0_key(dsa, NULL, &priv_key); (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY)); - if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK) + if ((rv = sslBN2KMFBN((BIGNUM *)p, &kmfkey->prime)) != KMF_OK) goto cleanup; - if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK) + if ((rv = sslBN2KMFBN((BIGNUM *)q, &kmfkey->subprime)) != KMF_OK) goto cleanup; - if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK) + if ((rv = sslBN2KMFBN((BIGNUM *)g, &kmfkey->base)) != KMF_OK) goto cleanup; - if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK) + if ((rv = sslBN2KMFBN((BIGNUM *)priv_key, &kmfkey->value)) != KMF_OK) goto cleanup; cleanup: @@ -4220,68 +4303,44 @@ add_key_to_list(KMF_RAW_KEY_DATA **keylist, return (KMF_OK); } -static X509_ATTRIBUTE * -find_attr(STACK_OF(X509_ATTRIBUTE) *attrs, int nid) -{ - X509_ATTRIBUTE *a; - int i; - - if (attrs == NULL) - return (NULL); - - for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) { - /* LINTED E_BAD_PTR_CAST_ALIGN */ - a = sk_X509_ATTRIBUTE_value(attrs, i); - if (OBJ_obj2nid(a->object) == nid) - return (a); - } - return (NULL); -} - static KMF_RETURN convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key) { KMF_RETURN rv = KMF_OK; X509_ATTRIBUTE *attr; + RSA *rsa; + DSA *dsa; + int loc; if (pkey == NULL || key == NULL) return (KMF_ERR_BAD_PARAMETER); /* Convert SSL key to raw key */ - switch (pkey->type) { - case EVP_PKEY_RSA: - rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey), - key); - if (rv != KMF_OK) - return (rv); - break; - case EVP_PKEY_DSA: - rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey), - key); - if (rv != KMF_OK) - return (rv); - break; - default: - return (KMF_ERR_BAD_PARAMETER); - } + if ((rsa = EVP_PKEY_get1_RSA(pkey)) != NULL) { + rv = exportRawRSAKey(rsa, key); + if (rv != KMF_OK) + return (rv); + } else if ((dsa = EVP_PKEY_get1_DSA(pkey)) != NULL) { + rv = exportRawDSAKey(dsa, key); + if (rv != KMF_OK) + return (rv); + } else + return (KMF_ERR_BAD_PARAMETER); + /* * If friendlyName, add it to record. */ - attr = find_attr(pkey->attributes, NID_friendlyName); - if (attr != NULL) { + + if ((loc = EVP_PKEY_get_attr_by_NID(pkey, + NID_friendlyName, -1)) != -1 && + (attr = EVP_PKEY_get_attr(pkey, loc))) { ASN1_TYPE *ty = NULL; - int numattr = sk_ASN1_TYPE_num(attr->value.set); - if (attr->single == 0 && numattr > 0) { - /* LINTED E_BAD_PTR_CAST_ALIGN */ - ty = sk_ASN1_TYPE_value(attr->value.set, 0); + int numattr = X509_ATTRIBUTE_count(attr); + if (numattr > 0) { + ty = X509_ATTRIBUTE_get0_type(attr, 0); } if (ty != NULL) { -#if OPENSSL_VERSION_NUMBER < 0x10000000L - key->label = uni2asc(ty->value.bmpstring->data, - ty->value.bmpstring->length); -#else key->label = OPENSSL_uni2asc(ty->value.bmpstring->data, ty->value.bmpstring->length); -#endif } } else { key->label = NULL; @@ -4290,14 +4349,13 @@ convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key) /* * If KeyID, add it to record as a KMF_DATA object. */ - attr = find_attr(pkey->attributes, NID_localKeyID); - if (attr != NULL) { + if ((loc = EVP_PKEY_get_attr_by_NID(pkey, + NID_localKeyID, -1)) != -1 && + (attr = EVP_PKEY_get_attr(pkey, loc)) != NULL) { ASN1_TYPE *ty = NULL; - int numattr = sk_ASN1_TYPE_num(attr->value.set); - if (attr->single == 0 && numattr > 0) { - /* LINTED E_BAD_PTR_CAST_ALIGN */ - ty = sk_ASN1_TYPE_value(attr->value.set, 0); - } + int numattr = X509_ATTRIBUTE_count(attr); + if (numattr > 0) + ty = X509_ATTRIBUTE_get0_type(attr, 0); key->id.Data = (uchar_t *)malloc( ty->value.octet_string->length); if (key->id.Data == NULL) @@ -5406,7 +5464,8 @@ OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) } /* Check if the certificate and the CRL have same issuer */ - if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) { + if (X509_NAME_cmp(X509_get_issuer_name(xcert), + X509_CRL_get_issuer(xcrl)) != 0) { ret = KMF_ERR_ISSUER; goto end; } @@ -5423,8 +5482,8 @@ OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) { /* LINTED E_BAD_PTR_CAST_ALIGN */ revoke = sk_X509_REVOKED_value(revoke_stack, i); - if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber, - revoke->serialNumber) == 0) { + if (ASN1_INTEGER_cmp(X509_get_serialNumber(xcert), + X509_REVOKED_get0_serialNumber(revoke)) == 0) { break; } } @@ -5567,13 +5626,13 @@ OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname) ret = KMF_ERR_BAD_CRLFILE; goto cleanup; } - i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL); + i = X509_cmp_time(X509_CRL_get0_lastUpdate(xcrl), NULL); if (i >= 0) { ret = KMF_ERR_VALIDITY_PERIOD; goto cleanup; } - if (X509_CRL_get_nextUpdate(xcrl)) { - i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL); + if (X509_CRL_get0_nextUpdate(xcrl)) { + i = X509_cmp_time(X509_CRL_get0_nextUpdate(xcrl), NULL); if (i <= 0) { ret = KMF_ERR_VALIDITY_PERIOD; diff --git a/usr/src/tools/scripts/nightly.sh b/usr/src/tools/scripts/nightly.sh index 3d14cb72d1..cec1849ff0 100644 --- a/usr/src/tools/scripts/nightly.sh +++ b/usr/src/tools/scripts/nightly.sh @@ -27,6 +27,7 @@ # Copyright 2012 Joshua M. Clulow <josh@sysmgr.org> # Copyright (c) 2017 by Delphix. All rights reserved. # Copyright 2018 Joyent, Inc. +# Copyright 2018 OmniOS Community Edition (OmniOSce) Association. # # Based on the nightly script from the integration folks, # Mostly modified and owned by mike_s. @@ -1662,7 +1663,7 @@ if [[ ! -f $SRC/Makefile ]]; then fi ( cd $SRC - for target in cc-version cc64-version java-version; do + for target in cc-version cc64-version java-version openssl-version; do echo # # Put statefile somewhere we know we can write to rather than trip |