summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Fiddaman <omnios@citrus-it.co.uk>2018-01-16 21:39:56 +0000
committerDan McDonald <danmcd@joyent.com>2018-05-02 22:06:02 -0400
commit300fdee27f8b59b381c1a0316bdee52fdfdb9213 (patch)
treeb1968149c7837343badd37f984681a0d007b598e
parentbb1f424574ac8e08069d0ba993c2a41ffe796794 (diff)
downloadillumos-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/Makefile11
-rw-r--r--usr/src/Makefile.master2
-rw-r--r--usr/src/cmd/sendmail/src/tls.c255
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c696
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h22
-rw-r--r--usr/src/lib/libkmf/plugins/kmf_openssl/Makefile.com2
-rw-r--r--usr/src/lib/libkmf/plugins/kmf_openssl/common/compat.c446
-rw-r--r--usr/src/lib/libkmf/plugins/kmf_openssl/common/compat.h91
-rw-r--r--usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c683
-rw-r--r--usr/src/tools/scripts/nightly.sh3
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