From: Juergen Perlinger Date: Sat, 10 Sep 2016 15:22:27 +0000 (+0200) Subject: [Bug 3095] Compatibility with openssl 1.1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=130b8cea1821849e6b926dfb992c3da2ed4fe4f3;p=thirdparty%2Fntp.git [Bug 3095] Compatibility with openssl 1.1 - applied patches by Kurt Roeckx to source - added shim layer for new SSL API calls bk: 57d42533jAufWUyyoiWfaGKj_W-WNQ --- diff --git a/ChangeLog b/ChangeLog index 0805467dc..cadee06f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +--- +* [Bug 3095] Compatibility with openssl 1.1 + - applied patches by Kurt Roeckx to source + - added shim layer for SSL API calls with issues (both directions) + --- (4.2.8p8) 2016/06/02 Released by Harlan Stenn diff --git a/include/libssl_compat.h b/include/libssl_compat.h new file mode 100644 index 000000000..65d7501f8 --- /dev/null +++ b/include/libssl_compat.h @@ -0,0 +1,93 @@ +/* + * libssl_compat.h -- OpenSSL v1.1 compatibility shims + * + * --------------------------------------------------------------------- + * + * Written by Juergen Perlinger for the NTP project + * + * Based on an idea by Kurt Roeckx + * + * --------------------------------------------------------------------- + * This is a clean room implementation of shim functions that have + * counterparts in the OpenSSL v1.1 API but not in earlier versions. + * + * If the OpenSSL version used for compilation needs the shims (that is, + * does not provide the new functions) the names of these functions are + * redirected to our shims. + * --------------------------------------------------------------------- + */ + +#ifndef NTP_LIBSSL_COMPAT_H +#define NTP_LIBSSL_COMPAT_H + +#include "openssl/evp.h" +#include "openssl/dsa.h" +#include "openssl/rsa.h" + +/* ----------------------------------------------------------------- */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L +/* ----------------------------------------------------------------- */ + +/* shim the new-style API on an old-style OpenSSL */ + +extern BN_GENCB* sslshimBN_GENCB_new(void); +extern void sslshimBN_GENCB_free(BN_GENCB*); + +extern EVP_MD_CTX* sslshim_EVP_MD_CTX_new(void); +extern void sslshim_EVP_MD_CTX_free(EVP_MD_CTX *ctx); + +extern int sslshim_EVP_PKEY_id(const EVP_PKEY * pkey); +extern int sslshim_EVP_PKEY_base_id(const EVP_PKEY * pkey); +extern RSA* sslshim_EVP_PKEY_get0_RSA(EVP_PKEY * pkey); +extern DSA* sslshim_EVP_PKEY_get0_DSA(EVP_PKEY * pkey); + +extern void sslshim_RSA_get0_key(const RSA *prsa, const BIGNUM **pn, + const BIGNUM **pe, const BIGNUM **pd); +extern int sslshim_RSA_set0_key(RSA *prsa, BIGNUM *n, + BIGNUM *e, BIGNUM *d); +extern void sslshim_RSA_get0_factors(const RSA *prsa, const BIGNUM **pp, + const BIGNUM **pq); +extern int sslshim_RSA_set0_factors(RSA *prsar, BIGNUM *p, BIGNUM *q); +extern int sslshim_RSA_set0_crt_params(RSA *prsa, BIGNUM *dmp1, + BIGNUM *dmq1, BIGNUM *iqmp); + +extern void sslshim_DSA_SIG_get0(const DSA_SIG *psig, const BIGNUM **pr, + const BIGNUM **ps); +extern int sslshim_DSA_SIG_set0(DSA_SIG *psig, BIGNUM *r, BIGNUM *s); +extern void sslshim_DSA_get0_pqg(const DSA *pdsa, const BIGNUM **pp, + const BIGNUM **pq, const BIGNUM **pg); +extern int sslshim_DSA_set0_pqg(DSA *pdsa, BIGNUM *p, BIGNUM *q, BIGNUM *g); +extern void sslshim_DSA_get0_key(const DSA *pdsa, const BIGNUM **ppub_key, + const BIGNUM **ppriv_key); +extern int sslshim_DSA_set0_key(DSA *pdsa, BIGNUM *pub_key, + BIGNUM *priv_key); + +#define BN_GENCB_new sslshimBN_GENCB_new +#define BN_GENCB_free sslshimBN_GENCB_free + +#define EVP_MD_CTX_new sslshim_EVP_MD_CTX_new +#define EVP_MD_CTX_free sslshim_EVP_MD_CTX_free + +#define EVP_PKEY_id sslshim_EVP_PKEY_id +#define EVP_PKEY_base_id sslshim_EVP_PKEY_base_id +#define EVP_PKEY_get0_RSA sslshim_EVP_PKEY_get0_RSA +#define EVP_PKEY_get0_DSA sslshim_EVP_PKEY_get0_DSA + +#define RSA_get0_key sslshim_RSA_get0_key +#define RSA_set0_key sslshim_RSA_set0_key +#define RSA_get0_factors sslshim_RSA_get0_factors +#define RSA_set0_factors sslshim_RSA_set0_factors +#define RSA_set0_crt_params sslshim_RSA_set0_crt_params + +#define DSA_SIG_get0 sslshim_DSA_SIG_get0 +#define DSA_SIG_set0 sslshim_DSA_SIG_set0 +#define DSA_get0_pqg sslshim_DSA_get0_pqg +#define DSA_set0_pqg sslshim_DSA_set0_pqg +#define DSA_get0_key sslshim_DSA_get0_key +#define DSA_set0_key sslshim_DSA_set0_key + +/* ----------------------------------------------------------------- */ +#endif /* OPENSSL_VERSION_NUMBER checks */ +/* ----------------------------------------------------------------- */ + +#endif /* NTP_LIBSSL_COMPAT_H */ diff --git a/libntp/Makefile.am b/libntp/Makefile.am index 26a4709e8..874739a18 100644 --- a/libntp/Makefile.am +++ b/libntp/Makefile.am @@ -73,6 +73,7 @@ libntp_a_SRCS = \ iosignal.c \ is_ip_address.c \ lib_strbuf.c \ + libssl_compat.c \ machines.c \ mktime.c \ modetoa.c \ diff --git a/libntp/a_md5encrypt.c b/libntp/a_md5encrypt.c index 618ccd9de..0ff036f0e 100644 --- a/libntp/a_md5encrypt.c +++ b/libntp/a_md5encrypt.c @@ -11,6 +11,7 @@ #include "ntp.h" #include "ntp_md5.h" /* provides OpenSSL digest API */ #include "isc/string.h" +#include "libssl_compat.h" /* * MD5authencrypt - generate message digest * @@ -26,7 +27,7 @@ MD5authencrypt( { u_char digest[EVP_MAX_MD_SIZE]; u_int len; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; /* * Compute digest of key concatenated with packet. Note: the @@ -34,18 +35,17 @@ MD5authencrypt( * was creaded. */ INIT_SSL(); -#if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x0090700fL - if (!EVP_DigestInit(&ctx, EVP_get_digestbynid(type))) { + ctx = EVP_MD_CTX_new(); + if (!(ctx && EVP_DigestInit(ctx, EVP_get_digestbynid(type)))) { msyslog(LOG_ERR, "MAC encrypt: digest init failed"); + EVP_MD_CTX_free(ctx); return (0); } -#else - EVP_DigestInit(&ctx, EVP_get_digestbynid(type)); -#endif - EVP_DigestUpdate(&ctx, key, cache_secretsize); - EVP_DigestUpdate(&ctx, (u_char *)pkt, length); - EVP_DigestFinal(&ctx, digest, &len); + EVP_DigestUpdate(ctx, key, cache_secretsize); + EVP_DigestUpdate(ctx, (u_char *)pkt, length); + EVP_DigestFinal(ctx, digest, &len); + EVP_MD_CTX_free(ctx); memmove((u_char *)pkt + length + 4, digest, len); return (len + 4); } @@ -67,7 +67,7 @@ MD5authdecrypt( { u_char digest[EVP_MAX_MD_SIZE]; u_int len; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; /* * Compute digest of key concatenated with packet. Note: the @@ -75,18 +75,17 @@ MD5authdecrypt( * was created. */ INIT_SSL(); -#if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x0090700fL - if (!EVP_DigestInit(&ctx, EVP_get_digestbynid(type))) { + ctx = EVP_MD_CTX_new(); + if (!(ctx && EVP_DigestInit(ctx, EVP_get_digestbynid(type)))) { msyslog(LOG_ERR, "MAC decrypt: digest init failed"); + EVP_MD_CTX_free(ctx); return (0); } -#else - EVP_DigestInit(&ctx, EVP_get_digestbynid(type)); -#endif - EVP_DigestUpdate(&ctx, key, cache_secretsize); - EVP_DigestUpdate(&ctx, (u_char *)pkt, length); - EVP_DigestFinal(&ctx, digest, &len); + EVP_DigestUpdate(ctx, key, cache_secretsize); + EVP_DigestUpdate(ctx, (u_char *)pkt, length); + EVP_DigestFinal(ctx, digest, &len); + EVP_MD_CTX_free(ctx); if (size != (size_t)len + 4) { msyslog(LOG_ERR, "MAC decrypt: MAC length error"); @@ -106,7 +105,7 @@ addr2refid(sockaddr_u *addr) { u_char digest[20]; u_int32 addr_refid; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; u_int len; if (IS_IPV4(addr)) @@ -114,24 +113,23 @@ addr2refid(sockaddr_u *addr) INIT_SSL(); -#if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x0090700fL - EVP_MD_CTX_init(&ctx); + ctx = EVP_MD_CTX_new(); + EVP_MD_CTX_init(ctx); #ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW /* MD5 is not used as a crypto hash here. */ - EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); #endif - if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL)) { + if (!EVP_DigestInit_ex(ctx, EVP_md5(), NULL)) { msyslog(LOG_ERR, "MD5 init failed"); + EVP_MD_CTX_free(ctx); /* pedantic... but safe */ exit(1); } -#else - EVP_DigestInit(&ctx, EVP_md5()); -#endif - EVP_DigestUpdate(&ctx, (u_char *)PSOCK_ADDR6(addr), + EVP_DigestUpdate(ctx, (u_char *)PSOCK_ADDR6(addr), sizeof(struct in6_addr)); - EVP_DigestFinal(&ctx, digest, &len); + EVP_DigestFinal(ctx, digest, &len); + EVP_MD_CTX_free(ctx); memcpy(&addr_refid, digest, sizeof(addr_refid)); return (addr_refid); } diff --git a/libntp/libssl_compat.c b/libntp/libssl_compat.c new file mode 100644 index 000000000..513d3d8ee --- /dev/null +++ b/libntp/libssl_compat.c @@ -0,0 +1,327 @@ +/* + * libssl_compat.c -- OpenSSL v1.1 compatibility functions + * + * --------------------------------------------------------------------- + * Written by Juergen Perlinger for the NTP project + * + * Based on an idea by Kurt Roeckx + * + * --------------------------------------------------------------------- + * This is a clean room implementation of shim functions that have + * counterparts in the OpenSSL v1.1 API but not in earlier versions. So + * while OpenSSL broke binary compatibility with v1.1, this shim module + * should provide the necessary source code compatibility with older + * versions of OpenSSL. + * --------------------------------------------------------------------- + */ +#include "config.h" + +#include +#include +#include + +#include "ntp_types.h" + +/* ----------------------------------------------------------------- */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L +/* ----------------------------------------------------------------- */ + +#include "libssl_compat.h" +#include "ntp_assert.h" + +/* -------------------------------------------------------------------- + * replace a BIGNUM owned by the caller with another one if it's not + * NULL, taking over the ownership of the new value. This clears & frees + * the old value -- the clear might be overkill, but it's better to err + * on the side of paranoia here. + */ +static void +replace_bn_nn( + BIGNUM ** ps, + BIGNUM * n + ) +{ + if (n) { + REQUIRE(*ps != n); + BN_clear_free(*ps); + *ps = n; + } +} + +/* -------------------------------------------------------------------- + * allocation and deallocation of prime number callbacks + */ +BN_GENCB* +sslshimBN_GENCB_new(void) +{ + return calloc(1,sizeof(BN_GENCB)); +} + +void +sslshimBN_GENCB_free( + BN_GENCB *cb + ) +{ + free(cb); +} + +/* -------------------------------------------------------------------- + * allocation and deallocation of message digests + */ +EVP_MD_CTX* +sslshim_EVP_MD_CTX_new(void) +{ + return calloc(1, sizeof(EVP_MD_CTX)); +} + +void +sslshim_EVP_MD_CTX_free( + EVP_MD_CTX * pctx + ) +{ + free(pctx); +} + +/* -------------------------------------------------------------------- + * get EVP keys and key type + */ +int +sslshim_EVP_PKEY_id( + const EVP_PKEY *pkey + ) +{ + return (pkey) ? pkey->type : EVP_PKEY_NONE; +} + +int +sslshim_EVP_PKEY_base_id( + const EVP_PKEY *pkey + ) +{ + return (pkey) ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE; +} + +RSA* +sslshim_EVP_PKEY_get0_RSA( + EVP_PKEY * pkey + ) +{ + return (pkey) ? pkey->pkey.rsa : NULL; +} + +DSA* +sslshim_EVP_PKEY_get0_DSA( + EVP_PKEY * pkey + ) +{ + return (pkey) ? pkey->pkey.dsa : NULL; +} + +/* -------------------------------------------------------------------- + * set/get RSA params + */ +void +sslshim_RSA_get0_key( + const RSA * prsa, + const BIGNUM ** pn, + const BIGNUM ** pe, + const BIGNUM ** pd + ) +{ + REQUIRE(prsa != NULL); + + if (pn) + *pn = prsa->n; + if (pe) + *pe = prsa->e; + if (pd) + *pd = prsa->d; +} + +int +sslshim_RSA_set0_key( + RSA * prsa, + BIGNUM * n, + BIGNUM * e, + BIGNUM * d + ) +{ + REQUIRE(prsa != NULL); + if (!((prsa->n || n) && (prsa->e || e))) + return 0; + + replace_bn_nn(&prsa->n, n); + replace_bn_nn(&prsa->e, e); + replace_bn_nn(&prsa->d, d); + + return 1; +} + +void +sslshim_RSA_get0_factors( + const RSA * prsa, + const BIGNUM ** pp, + const BIGNUM ** pq + ) +{ + REQUIRE(prsa != NULL); + + if (pp) + *pp = prsa->p; + if (pq) + *pq = prsa->q; +} + +int +sslshim_RSA_set0_factors( + RSA * prsa, + BIGNUM * p, + BIGNUM * q + ) +{ + REQUIRE(prsa != NULL); + if (!((prsa->p || p) && (prsa->q || q))) + return 0; + + replace_bn_nn(&prsa->p, p); + replace_bn_nn(&prsa->q, q); + + return 1; +} + +int +sslshim_RSA_set0_crt_params( + RSA * prsa, + BIGNUM * dmp1, + BIGNUM * dmq1, + BIGNUM * iqmp + ) +{ + REQUIRE(prsa != NULL); + if (!((prsa->dmp1 || dmp1) && + (prsa->dmq1 || dmq1) && + (prsa->iqmp || iqmp) )) + return 0; + + replace_bn_nn(&prsa->dmp1, dmp1); + replace_bn_nn(&prsa->dmq1, dmq1); + replace_bn_nn(&prsa->iqmp, iqmp); + + return 1; +} + +/* -------------------------------------------------------------------- + * set/get DSA signature parameters + */ +void +sslshim_DSA_SIG_get0( + const DSA_SIG * psig, + const BIGNUM ** pr, + const BIGNUM ** ps + ) +{ + REQUIRE(psig != NULL); + + if (pr != NULL) + *pr = psig->r; + if (ps != NULL) + *ps = psig->s; +} + +int +sslshim_DSA_SIG_set0( + DSA_SIG * psig, + BIGNUM * r, + BIGNUM * s + ) +{ + REQUIRE(psig != NULL); + if (!(r && s)) + return 0; + + replace_bn_nn(&psig->r, r); + replace_bn_nn(&psig->s, s); + + return 1; +} + +/* -------------------------------------------------------------------- + * get/set DSA parameters + */ +void +sslshim_DSA_get0_pqg( + const DSA * pdsa, + const BIGNUM ** pp, + const BIGNUM ** pq, + const BIGNUM ** pg + ) +{ + REQUIRE(pdsa != NULL); + + if (pp != NULL) + *pp = pdsa->p; + if (pq != NULL) + *pq = pdsa->q; + if (pg != NULL) + *pg = pdsa->g; +} + +int +sslshim_DSA_set0_pqg( + DSA * pdsa, + BIGNUM * p, + BIGNUM * q, + BIGNUM * g + ) +{ + if (!((pdsa->p || p) && (pdsa->q || q) && (pdsa->g || g))) + return 0; + + replace_bn_nn(&pdsa->p, p); + replace_bn_nn(&pdsa->q, q); + replace_bn_nn(&pdsa->g, g); + + return 1; +} + +void +sslshim_DSA_get0_key( + const DSA * pdsa, + const BIGNUM ** ppub_key, + const BIGNUM ** ppriv_key + ) +{ + REQUIRE(pdsa != NULL); + + if (ppub_key != NULL) + *ppub_key = pdsa->pub_key; + if (ppriv_key != NULL) + *ppriv_key = pdsa->priv_key; +} + +int +sslshim_DSA_set0_key( + DSA * pdsa, + BIGNUM * pub_key, + BIGNUM * priv_key + ) +{ + REQUIRE(pdsa != NULL); + if (!(pdsa->pub_key || pub_key)) + return 0; + + replace_bn_nn(&pdsa->pub_key, pub_key); + replace_bn_nn(&pdsa->priv_key, priv_key); + + return 1; +} + +/* ----------------------------------------------------------------- */ +#else +/* ----------------------------------------------------------------- */ + +NONEMPTY_TRANSLATION_UNIT + +/* ----------------------------------------------------------------- */ +#endif +/* ----------------------------------------------------------------- */ diff --git a/libntp/ssl_init.c b/libntp/ssl_init.c index a9d1d546d..755a5ff35 100644 --- a/libntp/ssl_init.c +++ b/libntp/ssl_init.c @@ -15,6 +15,7 @@ #ifdef OPENSSL #include "openssl/err.h" #include "openssl/evp.h" +#include "libssl_compat.h" void atexit_ssl_cleanup(void); @@ -84,7 +85,6 @@ keytype_from_text( u_char digest[EVP_MAX_MD_SIZE]; char * upcased; char * pch; - EVP_MD_CTX ctx; /* * OpenSSL digest short names are capitalized, so uppercase the @@ -110,8 +110,12 @@ keytype_from_text( if (NULL != pdigest_len) { #ifdef OPENSSL - EVP_DigestInit(&ctx, EVP_get_digestbynid(key_type)); - EVP_DigestFinal(&ctx, digest, &digest_len); + EVP_MD_CTX *ctx; + + ctx = EVP_MD_CTX_new(); + EVP_DigestInit(ctx, EVP_get_digestbynid(key_type)); + EVP_DigestFinal(ctx, digest, &digest_len); + EVP_MD_CTX_free(ctx); if (digest_len > max_digest_len) { fprintf(stderr, "key type %s %u octet digests are too big, max %lu\n", diff --git a/ntpd/ntp_control.c b/ntpd/ntp_control.c index 07b5697f1..73beaba1d 100644 --- a/ntpd/ntp_control.c +++ b/ntpd/ntp_control.c @@ -33,6 +33,7 @@ # include "ntp_syscall.h" #endif +#include "libssl_compat.h" /* * Structure to hold request procedure information @@ -3649,7 +3650,7 @@ static u_int32 derive_nonce( u_char digest[EVP_MAX_MD_SIZE]; u_int32 extract; } d; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; u_int len; while (!salt[0] || current_time - last_salt_update >= 3600) { @@ -3660,19 +3661,21 @@ static u_int32 derive_nonce( last_salt_update = current_time; } - EVP_DigestInit(&ctx, EVP_get_digestbynid(NID_md5)); - EVP_DigestUpdate(&ctx, salt, sizeof(salt)); - EVP_DigestUpdate(&ctx, &ts_i, sizeof(ts_i)); - EVP_DigestUpdate(&ctx, &ts_f, sizeof(ts_f)); + ctx = EVP_MD_CTX_new(); + EVP_DigestInit(ctx, EVP_get_digestbynid(NID_md5)); + EVP_DigestUpdate(ctx, salt, sizeof(salt)); + EVP_DigestUpdate(ctx, &ts_i, sizeof(ts_i)); + EVP_DigestUpdate(ctx, &ts_f, sizeof(ts_f)); if (IS_IPV4(addr)) - EVP_DigestUpdate(&ctx, &SOCK_ADDR4(addr), + EVP_DigestUpdate(ctx, &SOCK_ADDR4(addr), sizeof(SOCK_ADDR4(addr))); else - EVP_DigestUpdate(&ctx, &SOCK_ADDR6(addr), + EVP_DigestUpdate(ctx, &SOCK_ADDR6(addr), sizeof(SOCK_ADDR6(addr))); - EVP_DigestUpdate(&ctx, &NSRCPORT(addr), sizeof(NSRCPORT(addr))); - EVP_DigestUpdate(&ctx, salt, sizeof(salt)); - EVP_DigestFinal(&ctx, d.digest, &len); + EVP_DigestUpdate(ctx, &NSRCPORT(addr), sizeof(NSRCPORT(addr))); + EVP_DigestUpdate(ctx, salt, sizeof(salt)); + EVP_DigestFinal(ctx, d.digest, &len); + EVP_MD_CTX_free(ctx); return d.extract; } diff --git a/ntpd/ntp_crypto.c b/ntpd/ntp_crypto.c index 86541bdc1..2b9cb52e4 100644 --- a/ntpd/ntp_crypto.c +++ b/ntpd/ntp_crypto.c @@ -22,13 +22,13 @@ #include "ntp_calendar.h" #include "ntp_leapsec.h" -#include "openssl/asn1_mac.h" #include "openssl/bn.h" #include "openssl/err.h" #include "openssl/evp.h" #include "openssl/pem.h" #include "openssl/rand.h" #include "openssl/x509v3.h" +#include "libssl_compat.h" #ifdef KERNEL_PLL #include "ntp_syscall.h" @@ -230,7 +230,7 @@ session_key( u_long lifetime /* key lifetime */ ) { - EVP_MD_CTX ctx; /* message digest context */ + EVP_MD_CTX *ctx; /* message digest context */ u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */ keyid_t keyid; /* key identifer */ u_int32 header[10]; /* data in network byte order */ @@ -263,9 +263,11 @@ session_key( hdlen = 10 * sizeof(u_int32); break; } - EVP_DigestInit(&ctx, EVP_get_digestbynid(crypto_nid)); - EVP_DigestUpdate(&ctx, (u_char *)header, hdlen); - EVP_DigestFinal(&ctx, dgst, &len); + ctx = EVP_MD_CTX_new(); + EVP_DigestInit(ctx, EVP_get_digestbynid(crypto_nid)); + EVP_DigestUpdate(ctx, (u_char *)header, hdlen); + EVP_DigestFinal(ctx, dgst, &len); + EVP_MD_CTX_free(ctx); memcpy(&keyid, dgst, 4); keyid = ntohl(keyid); if (lifetime != 0) { @@ -299,7 +301,7 @@ make_keylist( struct interface *dstadr /* interface */ ) { - EVP_MD_CTX ctx; /* signature context */ + EVP_MD_CTX *ctx; /* signature context */ tstamp_t tstamp; /* NTP timestamp */ struct autokey *ap; /* autokey pointer */ struct value *vp; /* value pointer */ @@ -377,14 +379,16 @@ make_keylist( if (tstamp != 0) { if (vp->sig == NULL) vp->sig = emalloc(sign_siglen); - EVP_SignInit(&ctx, sign_digest); - EVP_SignUpdate(&ctx, (u_char *)vp, 12); - EVP_SignUpdate(&ctx, vp->ptr, sizeof(struct autokey)); - if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) { + ctx = EVP_MD_CTX_new(); + EVP_SignInit(ctx, sign_digest); + EVP_SignUpdate(ctx, (u_char *)vp, 12); + EVP_SignUpdate(ctx, vp->ptr, sizeof(struct autokey)); + if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { INSIST(len <= sign_siglen); vp->siglen = htonl(len); peer->flags |= FLAG_ASSOC; } + EVP_MD_CTX_free(ctx); } DPRINTF(1, ("make_keys: %d %08x %08x ts %u fs %u poll %d\n", peer->keynumber, keyid, cookie, ntohl(vp->tstamp), @@ -820,8 +824,8 @@ crypto_recv( * errors. */ if (vallen == (u_int)EVP_PKEY_size(host_pkey)) { - u_int32 *cookiebuf = malloc( - RSA_size(host_pkey->pkey.rsa)); + RSA *rsa = EVP_PKEY_get0_RSA(host_pkey); + u_int32 *cookiebuf = malloc(RSA_size(rsa)); if (!cookiebuf) { rval = XEVNT_CKY; break; @@ -830,7 +834,7 @@ crypto_recv( if (RSA_private_decrypt(vallen, (u_char *)ep->pkt, (u_char *)cookiebuf, - host_pkey->pkey.rsa, + rsa, RSA_PKCS1_OAEP_PADDING) != 4) { rval = XEVNT_CKY; free(cookiebuf); @@ -1421,7 +1425,7 @@ crypto_verify( ) { EVP_PKEY *pkey; /* server public key */ - EVP_MD_CTX ctx; /* signature context */ + EVP_MD_CTX *ctx; /* signature context */ tstamp_t tstamp, tstamp1 = 0; /* timestamp */ tstamp_t fstamp, fstamp1 = 0; /* filestamp */ u_int vallen; /* value length */ @@ -1533,12 +1537,16 @@ crypto_verify( * signature. If the identity exchange is verified, light the * proventic bit. What a relief. */ - EVP_VerifyInit(&ctx, peer->digest); + ctx = EVP_MD_CTX_new(); + EVP_VerifyInit(ctx, peer->digest); /* XXX: the "+ 12" needs to be at least documented... */ - EVP_VerifyUpdate(&ctx, (u_char *)&ep->tstamp, vallen + 12); - if (EVP_VerifyFinal(&ctx, (u_char *)&ep->pkt[i], siglen, - pkey) <= 0) + EVP_VerifyUpdate(ctx, (u_char *)&ep->tstamp, vallen + 12); + if (EVP_VerifyFinal(ctx, (u_char *)&ep->pkt[i], siglen, + pkey) <= 0) { + EVP_MD_CTX_free(ctx); return (XEVNT_SIG); + } + EVP_MD_CTX_free(ctx); if (peer->crypto & CRYPTO_FLAG_VRFY) peer->crypto |= CRYPTO_FLAG_PROV; @@ -1564,7 +1572,7 @@ crypto_encrypt( ) { EVP_PKEY *pkey; /* public key */ - EVP_MD_CTX ctx; /* signature context */ + EVP_MD_CTX *ctx; /* signature context */ tstamp_t tstamp; /* NTP timestamp */ u_int32 temp32; u_char *puch; @@ -1592,7 +1600,7 @@ crypto_encrypt( puch = vp->ptr; temp32 = htonl(*cookie); if (RSA_public_encrypt(4, (u_char *)&temp32, puch, - pkey->pkey.rsa, RSA_PKCS1_OAEP_PADDING) <= 0) { + EVP_PKEY_get0_RSA(pkey), RSA_PKCS1_OAEP_PADDING) <= 0) { msyslog(LOG_ERR, "crypto_encrypt: %s", ERR_error_string(ERR_get_error(), NULL)); free(vp->ptr); @@ -1604,13 +1612,15 @@ crypto_encrypt( return (XEVNT_OK); vp->sig = emalloc(sign_siglen); - EVP_SignInit(&ctx, sign_digest); - EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); - EVP_SignUpdate(&ctx, vp->ptr, vallen); - if (EVP_SignFinal(&ctx, vp->sig, &vallen, sign_pkey)) { + ctx = EVP_MD_CTX_new(); + EVP_SignInit(ctx, sign_digest); + EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12); + EVP_SignUpdate(ctx, vp->ptr, vallen); + if (EVP_SignFinal(ctx, vp->sig, &vallen, sign_pkey)) { INSIST(vallen <= sign_siglen); vp->siglen = htonl(vallen); } + EVP_MD_CTX_free(ctx); return (XEVNT_OK); } @@ -1817,7 +1827,7 @@ crypto_send( void crypto_update(void) { - EVP_MD_CTX ctx; /* message digest context */ + EVP_MD_CTX *ctx; /* message digest context */ struct cert_info *cp; /* certificate info/value */ char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ u_int32 *ptr; @@ -1828,6 +1838,8 @@ crypto_update(void) if (hostval.tstamp == 0) return; + ctx = EVP_MD_CTX_new(); + /* * Sign public key and timestamps. The filestamp is derived from * the host key file extension from wherever the file was @@ -1838,10 +1850,10 @@ crypto_update(void) pubkey.siglen = 0; if (pubkey.sig == NULL) pubkey.sig = emalloc(sign_siglen); - EVP_SignInit(&ctx, sign_digest); - EVP_SignUpdate(&ctx, (u_char *)&pubkey, 12); - EVP_SignUpdate(&ctx, pubkey.ptr, ntohl(pubkey.vallen)); - if (EVP_SignFinal(&ctx, pubkey.sig, &len, sign_pkey)) { + EVP_SignInit(ctx, sign_digest); + EVP_SignUpdate(ctx, (u_char *)&pubkey, 12); + EVP_SignUpdate(ctx, pubkey.ptr, ntohl(pubkey.vallen)); + if (EVP_SignFinal(ctx, pubkey.sig, &len, sign_pkey)) { INSIST(len <= sign_siglen); pubkey.siglen = htonl(len); } @@ -1858,11 +1870,11 @@ crypto_update(void) cp->cert.siglen = 0; if (cp->cert.sig == NULL) cp->cert.sig = emalloc(sign_siglen); - EVP_SignInit(&ctx, sign_digest); - EVP_SignUpdate(&ctx, (u_char *)&cp->cert, 12); - EVP_SignUpdate(&ctx, cp->cert.ptr, + EVP_SignInit(ctx, sign_digest); + EVP_SignUpdate(ctx, (u_char *)&cp->cert, 12); + EVP_SignUpdate(ctx, cp->cert.ptr, ntohl(cp->cert.vallen)); - if (EVP_SignFinal(&ctx, cp->cert.sig, &len, sign_pkey)) { + if (EVP_SignFinal(ctx, cp->cert.sig, &len, sign_pkey)) { INSIST(len <= sign_siglen); cp->cert.siglen = htonl(len); } @@ -1909,10 +1921,10 @@ crypto_update(void) } if (tai_leap.sig == NULL) tai_leap.sig = emalloc(sign_siglen); - EVP_SignInit(&ctx, sign_digest); - EVP_SignUpdate(&ctx, (u_char *)&tai_leap, 12); - EVP_SignUpdate(&ctx, tai_leap.ptr, len); - if (EVP_SignFinal(&ctx, tai_leap.sig, &len, sign_pkey)) { + EVP_SignInit(ctx, sign_digest); + EVP_SignUpdate(ctx, (u_char *)&tai_leap, 12); + EVP_SignUpdate(ctx, tai_leap.ptr, len); + if (EVP_SignFinal(ctx, tai_leap.sig, &len, sign_pkey)) { INSIST(len <= sign_siglen); tai_leap.siglen = htonl(len); } @@ -1922,6 +1934,7 @@ crypto_update(void) ntohl(hostval.tstamp)); record_crypto_stats(NULL, statstr); DPRINTF(1, ("crypto_update: %s\n", statstr)); + EVP_MD_CTX_free(ctx); } /* @@ -2061,7 +2074,7 @@ bighash( BIGNUM *bk /* BIGNUM * to */ ) { - EVP_MD_CTX ctx; /* message digest context */ + EVP_MD_CTX *ctx; /* message digest context */ u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */ u_char *ptr; /* a BIGNUM as binary string */ u_int len; @@ -2069,9 +2082,11 @@ bighash( len = BN_num_bytes(bn); ptr = emalloc(len); BN_bn2bin(bn, ptr); - EVP_DigestInit(&ctx, EVP_md5()); - EVP_DigestUpdate(&ctx, ptr, len); - EVP_DigestFinal(&ctx, dgst, &len); + ctx = EVP_MD_CTX_new(); + EVP_DigestInit(ctx, EVP_md5()); + EVP_DigestUpdate(ctx, ptr, len); + EVP_DigestFinal(ctx, dgst, &len); + EVP_MD_CTX_free(ctx); BN_bin2bn(dgst, len, bk); free(ptr); } @@ -2139,9 +2154,10 @@ crypto_alice( { DSA *dsa; /* IFF parameters */ BN_CTX *bctx; /* BIGNUM context */ - EVP_MD_CTX ctx; /* signature context */ + EVP_MD_CTX *ctx; /* signature context */ tstamp_t tstamp; u_int len; + const BIGNUM *q; /* * The identity parameters must have correct format and content. @@ -2151,7 +2167,7 @@ crypto_alice( return (XEVNT_ID); } - if ((dsa = peer->ident_pkey->pkey->pkey.dsa) == NULL) { + if ((dsa = EVP_PKEY_get0_DSA(peer->ident_pkey->pkey)) == NULL) { msyslog(LOG_NOTICE, "crypto_alice: defective key"); return (XEVNT_PUB); } @@ -2162,10 +2178,11 @@ crypto_alice( if (peer->iffval != NULL) BN_free(peer->iffval); peer->iffval = BN_new(); - len = BN_num_bytes(dsa->q); + DSA_get0_pqg(dsa, NULL, &q, NULL); + len = BN_num_bytes(q); BN_rand(peer->iffval, len * 8, -1, 1); /* r mod q*/ bctx = BN_CTX_new(); - BN_mod(peer->iffval, peer->iffval, dsa->q, bctx); + BN_mod(peer->iffval, peer->iffval, q, bctx); BN_CTX_free(bctx); /* @@ -2182,13 +2199,15 @@ crypto_alice( return (XEVNT_OK); vp->sig = emalloc(sign_siglen); - EVP_SignInit(&ctx, sign_digest); - EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); - EVP_SignUpdate(&ctx, vp->ptr, len); - if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) { + ctx = EVP_MD_CTX_new(); + EVP_SignInit(ctx, sign_digest); + EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12); + EVP_SignUpdate(ctx, vp->ptr, len); + if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { INSIST(len <= sign_siglen); vp->siglen = htonl(len); } + EVP_MD_CTX_free(ctx); return (XEVNT_OK); } @@ -2210,11 +2229,13 @@ crypto_bob( DSA *dsa; /* IFF parameters */ DSA_SIG *sdsa; /* DSA signature context fake */ BN_CTX *bctx; /* BIGNUM context */ - EVP_MD_CTX ctx; /* signature context */ + EVP_MD_CTX *ctx; /* signature context */ tstamp_t tstamp; /* NTP timestamp */ BIGNUM *bn, *bk, *r; u_char *ptr; u_int len; /* extension field value length */ + const BIGNUM *p, *q, *g; + const BIGNUM *priv_key; /* * If the IFF parameters are not valid, something awful @@ -2224,7 +2245,9 @@ crypto_bob( msyslog(LOG_NOTICE, "crypto_bob: scheme unavailable"); return (XEVNT_ID); } - dsa = iffkey_info->pkey->pkey.dsa; + dsa = EVP_PKEY_get0_DSA(iffkey_info->pkey); + DSA_get0_pqg(dsa, &p, &q, &g); + DSA_get0_key(dsa, NULL, &priv_key); /* * Extract r from the challenge. @@ -2245,15 +2268,14 @@ crypto_bob( bctx = BN_CTX_new(); bk = BN_new(); bn = BN_new(); sdsa = DSA_SIG_new(); BN_rand(bk, len * 8, -1, 1); /* k */ - BN_mod_mul(bn, dsa->priv_key, r, dsa->q, bctx); /* b r mod q */ + BN_mod_mul(bn, priv_key, r, q, bctx); /* b r mod q */ BN_add(bn, bn, bk); - BN_mod(bn, bn, dsa->q, bctx); /* k + b r mod q */ - sdsa->r = BN_dup(bn); - BN_mod_exp(bk, dsa->g, bk, dsa->p, bctx); /* g^k mod p */ + BN_mod(bn, bn, q, bctx); /* k + b r mod q */ + BN_mod_exp(bk, g, bk, p, bctx); /* g^k mod p */ bighash(bk, bk); - sdsa->s = BN_dup(bk); + DSA_SIG_set0(sdsa, bn, bk); BN_CTX_free(bctx); - BN_free(r); BN_free(bn); BN_free(bk); + BN_free(r); #ifdef DEBUG if (debug > 1) DSA_print_fp(stdout, dsa, 0); @@ -2290,13 +2312,15 @@ crypto_bob( /* XXX: more validation to make sure the sign fits... */ vp->sig = emalloc(sign_siglen); - EVP_SignInit(&ctx, sign_digest); - EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); - EVP_SignUpdate(&ctx, vp->ptr, len); - if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) { + ctx = EVP_MD_CTX_new(); + EVP_SignInit(ctx, sign_digest); + EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12); + EVP_SignUpdate(ctx, vp->ptr, len); + if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { INSIST(len <= sign_siglen); vp->siglen = htonl(len); } + EVP_MD_CTX_free(ctx); return (XEVNT_OK); } @@ -2323,6 +2347,9 @@ crypto_iff( u_int len; const u_char *ptr; int temp; + const BIGNUM *p, *g; + const BIGNUM *r, *s; + const BIGNUM *pub_key; /* * If the IFF parameters are not valid or no challenge was sent, @@ -2337,7 +2364,7 @@ crypto_iff( ntohl(ep->fstamp)); return (XEVNT_FSP); } - if ((dsa = peer->ident_pkey->pkey->pkey.dsa) == NULL) { + if ((dsa = EVP_PKEY_get0_DSA(peer->ident_pkey->pkey)) == NULL) { msyslog(LOG_NOTICE, "crypto_iff: defective key"); return (XEVNT_PUB); } @@ -2362,15 +2389,18 @@ crypto_iff( /* * Compute g^(k + b r) g^(q - b)r mod p. */ - BN_mod_exp(bn, dsa->pub_key, peer->iffval, dsa->p, bctx); - BN_mod_exp(bk, dsa->g, sdsa->r, dsa->p, bctx); - BN_mod_mul(bn, bn, bk, dsa->p, bctx); + DSA_get0_key(dsa, &pub_key, NULL); + DSA_get0_pqg(dsa, &p, NULL, &g); + DSA_SIG_get0(sdsa, &r, &s); + BN_mod_exp(bn, pub_key, peer->iffval, p, bctx); + BN_mod_exp(bk, g, r, p, bctx); + BN_mod_mul(bn, bn, bk, p, bctx); /* * Verify the hash of the result matches hash(x). */ bighash(bn, bn); - temp = BN_cmp(bn, sdsa->s); + temp = BN_cmp(bn, s); BN_free(bn); BN_free(bk); BN_CTX_free(bctx); BN_free(peer->iffval); peer->iffval = NULL; @@ -2456,9 +2486,10 @@ crypto_alice2( { RSA *rsa; /* GQ parameters */ BN_CTX *bctx; /* BIGNUM context */ - EVP_MD_CTX ctx; /* signature context */ + EVP_MD_CTX *ctx; /* signature context */ tstamp_t tstamp; u_int len; + const BIGNUM *n; /* * The identity parameters must have correct format and content. @@ -2466,7 +2497,7 @@ crypto_alice2( if (peer->ident_pkey == NULL) return (XEVNT_ID); - if ((rsa = peer->ident_pkey->pkey->pkey.rsa) == NULL) { + if ((rsa = EVP_PKEY_get0_RSA(peer->ident_pkey->pkey)) == NULL) { msyslog(LOG_NOTICE, "crypto_alice2: defective key"); return (XEVNT_PUB); } @@ -2477,10 +2508,11 @@ crypto_alice2( if (peer->iffval != NULL) BN_free(peer->iffval); peer->iffval = BN_new(); - len = BN_num_bytes(rsa->n); + RSA_get0_key(rsa, &n, NULL, NULL); + len = BN_num_bytes(n); BN_rand(peer->iffval, len * 8, -1, 1); /* r mod n */ bctx = BN_CTX_new(); - BN_mod(peer->iffval, peer->iffval, rsa->n, bctx); + BN_mod(peer->iffval, peer->iffval, n, bctx); BN_CTX_free(bctx); /* @@ -2497,13 +2529,15 @@ crypto_alice2( return (XEVNT_OK); vp->sig = emalloc(sign_siglen); - EVP_SignInit(&ctx, sign_digest); - EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); - EVP_SignUpdate(&ctx, vp->ptr, len); - if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) { + ctx = EVP_MD_CTX_new(); + EVP_SignInit(ctx, sign_digest); + EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12); + EVP_SignUpdate(ctx, vp->ptr, len); + if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { INSIST(len <= sign_siglen); vp->siglen = htonl(len); } + EVP_MD_CTX_free(ctx); return (XEVNT_OK); } @@ -2525,12 +2559,13 @@ crypto_bob2( RSA *rsa; /* GQ parameters */ DSA_SIG *sdsa; /* DSA parameters */ BN_CTX *bctx; /* BIGNUM context */ - EVP_MD_CTX ctx; /* signature context */ + EVP_MD_CTX *ctx; /* signature context */ tstamp_t tstamp; /* NTP timestamp */ BIGNUM *r, *k, *g, *y; u_char *ptr; u_int len; int s_len; + const BIGNUM *n, *p, *e; /* * If the GQ parameters are not valid, something awful @@ -2540,7 +2575,8 @@ crypto_bob2( msyslog(LOG_NOTICE, "crypto_bob2: scheme unavailable"); return (XEVNT_ID); } - rsa = gqkey_info->pkey->pkey.rsa; + rsa = EVP_PKEY_get0_RSA(gqkey_info->pkey); + RSA_get0_key(rsa, &n, &p, &e); /* * Extract r from the challenge. @@ -2561,15 +2597,14 @@ crypto_bob2( bctx = BN_CTX_new(); k = BN_new(); g = BN_new(); y = BN_new(); sdsa = DSA_SIG_new(); BN_rand(k, len * 8, -1, 1); /* k */ - BN_mod(k, k, rsa->n, bctx); - BN_mod_exp(y, rsa->p, r, rsa->n, bctx); /* u^r mod n */ - BN_mod_mul(y, k, y, rsa->n, bctx); /* k u^r mod n */ - sdsa->r = BN_dup(y); - BN_mod_exp(g, k, rsa->e, rsa->n, bctx); /* k^b mod n */ + BN_mod(k, k, n, bctx); + BN_mod_exp(y, p, r, n, bctx); /* u^r mod n */ + BN_mod_mul(y, k, y, n, bctx); /* k u^r mod n */ + BN_mod_exp(g, k, e, n, bctx); /* k^b mod n */ bighash(g, g); - sdsa->s = BN_dup(g); + DSA_SIG_set0(sdsa, y, g); BN_CTX_free(bctx); - BN_free(r); BN_free(k); BN_free(g); BN_free(y); + BN_free(r); BN_free(k); #ifdef DEBUG if (debug > 1) RSA_print_fp(stdout, rsa, 0); @@ -2599,13 +2634,15 @@ crypto_bob2( return (XEVNT_OK); vp->sig = emalloc(sign_siglen); - EVP_SignInit(&ctx, sign_digest); - EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); - EVP_SignUpdate(&ctx, vp->ptr, len); - if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) { + ctx = EVP_MD_CTX_new(); + EVP_SignInit(ctx, sign_digest); + EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12); + EVP_SignUpdate(ctx, vp->ptr, len); + if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { INSIST(len <= sign_siglen); vp->siglen = htonl(len); } + EVP_MD_CTX_free(ctx); return (XEVNT_OK); } @@ -2633,6 +2670,8 @@ crypto_gq( const u_char *ptr; long len; u_int temp; + const BIGNUM *n, *e; + const BIGNUM *r, *s; /* * If the GQ parameters are not valid or no challenge was sent, @@ -2649,10 +2688,11 @@ crypto_gq( ntohl(ep->fstamp)); return (XEVNT_FSP); } - if ((rsa = peer->ident_pkey->pkey->pkey.rsa) == NULL) { + if ((rsa = EVP_PKEY_get0_RSA(peer->ident_pkey->pkey)) == NULL) { msyslog(LOG_NOTICE, "crypto_gq: defective key"); return (XEVNT_PUB); } + RSA_get0_key(rsa, &n, NULL, &e); if (peer->iffval == NULL) { msyslog(LOG_NOTICE, "crypto_gq: missing challenge"); return (XEVNT_ID); @@ -2671,6 +2711,7 @@ crypto_gq( ERR_error_string(ERR_get_error(), NULL)); return (XEVNT_ERR); } + DSA_SIG_get0(sdsa, &r, &s); /* * Compute v^r y^b mod n. @@ -2679,16 +2720,16 @@ crypto_gq( msyslog(LOG_NOTICE, "crypto_gq: missing group key"); return (XEVNT_ID); } - BN_mod_exp(v, peer->grpkey, peer->iffval, rsa->n, bctx); + BN_mod_exp(v, peer->grpkey, peer->iffval, n, bctx); /* v^r mod n */ - BN_mod_exp(y, sdsa->r, rsa->e, rsa->n, bctx); /* y^b mod n */ - BN_mod_mul(y, v, y, rsa->n, bctx); /* v^r y^b mod n */ + BN_mod_exp(y, r, e, n, bctx); /* y^b mod n */ + BN_mod_mul(y, v, y, n, bctx); /* v^r y^b mod n */ /* * Verify the hash of the result matches hash(x). */ bighash(y, y); - temp = BN_cmp(y, sdsa->s); + temp = BN_cmp(y, s); BN_CTX_free(bctx); BN_free(y); BN_free(v); BN_free(peer->iffval); peer->iffval = NULL; @@ -2789,9 +2830,10 @@ crypto_alice3( { DSA *dsa; /* MV parameters */ BN_CTX *bctx; /* BIGNUM context */ - EVP_MD_CTX ctx; /* signature context */ + EVP_MD_CTX *ctx; /* signature context */ tstamp_t tstamp; u_int len; + const BIGNUM *p; /* * The identity parameters must have correct format and content. @@ -2799,10 +2841,11 @@ crypto_alice3( if (peer->ident_pkey == NULL) return (XEVNT_ID); - if ((dsa = peer->ident_pkey->pkey->pkey.dsa) == NULL) { + if ((dsa = EVP_PKEY_get0_DSA(peer->ident_pkey->pkey)) == NULL) { msyslog(LOG_NOTICE, "crypto_alice3: defective key"); return (XEVNT_PUB); } + DSA_get0_pqg(dsa, &p, NULL, NULL); /* * Roll new random r (0 < r < q). @@ -2810,10 +2853,10 @@ crypto_alice3( if (peer->iffval != NULL) BN_free(peer->iffval); peer->iffval = BN_new(); - len = BN_num_bytes(dsa->p); + len = BN_num_bytes(p); BN_rand(peer->iffval, len * 8, -1, 1); /* r mod p */ bctx = BN_CTX_new(); - BN_mod(peer->iffval, peer->iffval, dsa->p, bctx); + BN_mod(peer->iffval, peer->iffval, p, bctx); BN_CTX_free(bctx); /* @@ -2830,13 +2873,15 @@ crypto_alice3( return (XEVNT_OK); vp->sig = emalloc(sign_siglen); - EVP_SignInit(&ctx, sign_digest); - EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); - EVP_SignUpdate(&ctx, vp->ptr, len); - if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) { + ctx = EVP_MD_CTX_new(); + EVP_SignInit(ctx, sign_digest); + EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12); + EVP_SignUpdate(ctx, vp->ptr, len); + if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { INSIST(len <= sign_siglen); vp->siglen = htonl(len); } + EVP_MD_CTX_free(ctx); return (XEVNT_OK); } @@ -2857,11 +2902,14 @@ crypto_bob3( DSA *dsa; /* MV parameters */ DSA *sdsa; /* DSA signature context fake */ BN_CTX *bctx; /* BIGNUM context */ - EVP_MD_CTX ctx; /* signature context */ + EVP_MD_CTX *ctx; /* signature context */ tstamp_t tstamp; /* NTP timestamp */ BIGNUM *r, *k, *u; u_char *ptr; u_int len; + const BIGNUM *p, *q, *g; + const BIGNUM *pub_key, *priv_key; + BIGNUM *sp, *sq, *sg; /* * If the MV parameters are not valid, something awful @@ -2871,7 +2919,9 @@ crypto_bob3( msyslog(LOG_NOTICE, "crypto_bob3: scheme unavailable"); return (XEVNT_ID); } - dsa = mvkey_info->pkey->pkey.dsa; + dsa = EVP_PKEY_get0_DSA(mvkey_info->pkey); + DSA_get0_pqg(dsa, &p, &q, &g); + DSA_get0_key(dsa, &pub_key, &priv_key); /* * Extract r from the challenge. @@ -2892,18 +2942,20 @@ crypto_bob3( */ bctx = BN_CTX_new(); k = BN_new(); u = BN_new(); sdsa = DSA_new(); - sdsa->p = BN_new(); sdsa->q = BN_new(); sdsa->g = BN_new(); + sp = BN_new(); sq = BN_new(); sg = BN_new(); while (1) { - BN_rand(k, BN_num_bits(dsa->q), 0, 0); - BN_mod(k, k, dsa->q, bctx); - BN_gcd(u, k, dsa->q, bctx); + BN_rand(k, BN_num_bits(q), 0, 0); + BN_mod(k, k, q, bctx); + BN_gcd(u, k, q, bctx); if (BN_is_one(u)) break; } - BN_mod_exp(u, dsa->g, k, dsa->p, bctx); /* A^k r */ - BN_mod_mul(sdsa->p, u, r, dsa->p, bctx); - BN_mod_exp(sdsa->q, dsa->priv_key, k, dsa->p, bctx); /* gbar */ - BN_mod_exp(sdsa->g, dsa->pub_key, k, dsa->p, bctx); /* ghat */ + BN_mod_exp(u, g, k, p, bctx); /* A^k r */ + BN_mod_mul(sp, u, r, p, bctx); + BN_mod_exp(sq, priv_key, k, p, bctx); /* gbar */ + BN_mod_exp(sg, pub_key, k, p, bctx); /* ghat */ + DSA_set0_key(sdsa, BN_dup(pub_key), NULL); + DSA_set0_pqg(sdsa, sp, sq, sg); BN_CTX_free(bctx); BN_free(k); BN_free(r); BN_free(u); #ifdef DEBUG if (debug > 1) @@ -2934,13 +2986,15 @@ crypto_bob3( return (XEVNT_OK); vp->sig = emalloc(sign_siglen); - EVP_SignInit(&ctx, sign_digest); - EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); - EVP_SignUpdate(&ctx, vp->ptr, len); - if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) { + ctx = EVP_MD_CTX_new(); + EVP_SignInit(ctx, sign_digest); + EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12); + EVP_SignUpdate(ctx, vp->ptr, len); + if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { INSIST(len <= sign_siglen); vp->siglen = htonl(len); } + EVP_MD_CTX_free(ctx); return (XEVNT_OK); } @@ -2968,6 +3022,9 @@ crypto_mv( u_int len; const u_char *ptr; int temp; + const BIGNUM *p; + const BIGNUM *pub_key, *priv_key; + const BIGNUM *sp, *sq, *sg; /* * If the MV parameters are not valid or no challenge was sent, @@ -2982,10 +3039,12 @@ crypto_mv( ntohl(ep->fstamp)); return (XEVNT_FSP); } - if ((dsa = peer->ident_pkey->pkey->pkey.dsa) == NULL) { + if ((dsa = EVP_PKEY_get0_DSA(peer->ident_pkey->pkey)) == NULL) { msyslog(LOG_NOTICE, "crypto_mv: defective key"); return (XEVNT_PUB); } + DSA_get0_pqg(dsa, &p, NULL, NULL); + DSA_get0_key(dsa, &pub_key, &priv_key); if (peer->iffval == NULL) { msyslog(LOG_NOTICE, "crypto_mv: missing challenge"); return (XEVNT_ID); @@ -3002,14 +3061,15 @@ crypto_mv( ERR_error_string(ERR_get_error(), NULL)); return (XEVNT_ERR); } + DSA_get0_pqg(sdsa, &sp, &sq, &sg); /* * Compute (gbar^xhat ghat^xbar) mod p. */ - BN_mod_exp(u, sdsa->q, dsa->pub_key, dsa->p, bctx); - BN_mod_exp(v, sdsa->g, dsa->priv_key, dsa->p, bctx); - BN_mod_mul(u, u, v, dsa->p, bctx); - BN_mod_mul(u, u, sdsa->p, dsa->p, bctx); + BN_mod_exp(u, sq, pub_key, p, bctx); + BN_mod_exp(v, sg, priv_key, p, bctx); + BN_mod_mul(u, u, v, p, bctx); + BN_mod_mul(u, u, sp, p, bctx); /* * The result should match r. @@ -3080,7 +3140,7 @@ cert_sign( ASN1_INTEGER *serial; /* serial number */ X509_NAME *subj; /* distinguished (common) name */ EVP_PKEY *pkey; /* public key */ - EVP_MD_CTX ctx; /* message digest context */ + EVP_MD_CTX *ctx; /* message digest context */ tstamp_t tstamp; /* NTP timestamp */ struct calendar tscal; u_int len; @@ -3176,13 +3236,15 @@ cert_sign( vp->siglen = 0; if (tstamp != 0) { vp->sig = emalloc(sign_siglen); - EVP_SignInit(&ctx, sign_digest); - EVP_SignUpdate(&ctx, (u_char *)vp, 12); - EVP_SignUpdate(&ctx, vp->ptr, len); - if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) { + ctx = EVP_MD_CTX_new(); + EVP_SignInit(ctx, sign_digest); + EVP_SignUpdate(ctx, (u_char *)vp, 12); + EVP_SignUpdate(ctx, vp->ptr, len); + if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { INSIST(len <= sign_siglen); vp->siglen = htonl(len); } + EVP_MD_CTX_free(ctx); } #ifdef DEBUG if (debug > 1) @@ -3368,13 +3430,12 @@ cert_parse( ) { X509 *cert; /* X509 certificate */ - X509_EXTENSION *ext; /* X509v3 extension */ struct cert_info *ret; /* certificate info/value */ BIO *bp; char pathbuf[MAXFILENAME]; const u_char *ptr; char *pch; - int temp, cnt, i; + int cnt, i; struct calendar fscal; /* @@ -3422,7 +3483,7 @@ cert_parse( * objects at this time, since the real crunch can happen only * when the time is valid but not yet certificated. */ - ret->nid = OBJ_obj2nid(cert->cert_info->signature->algorithm); + ret->nid = X509_get_signature_nid(cert); ret->digest = (const EVP_MD *)EVP_get_digestbynid(ret->nid); ret->serial = (u_long)ASN1_INTEGER_get(X509_get_serialNumber(cert)); @@ -3446,9 +3507,16 @@ cert_parse( */ cnt = X509_get_ext_count(cert); for (i = 0; i < cnt; i++) { + X509_EXTENSION *ext; + ASN1_OBJECT *obj; + int nid; + ASN1_OCTET_STRING *data; + ext = X509_get_ext(cert, i); - temp = OBJ_obj2nid(ext->object); - switch (temp) { + obj = X509_EXTENSION_get_object(ext); + nid = OBJ_obj2nid(obj); + + switch (nid) { /* * If a key_usage field is present, we decode whether @@ -3466,7 +3534,7 @@ cert_parse( else if (strcmp(pathbuf, "Private") == 0) ret->flags |= CERT_PRIV; DPRINTF(1, ("cert_parse: %s: %s\n", - OBJ_nid2ln(temp), pathbuf)); + OBJ_nid2ln(nid), pathbuf)); break; /* @@ -3474,12 +3542,13 @@ cert_parse( * contains the GQ public key. */ case NID_subject_key_identifier: - ret->grpkey = BN_bin2bn(&ext->value->data[2], - ext->value->length - 2, NULL); + data = X509_EXTENSION_get_data(ext); + ret->grpkey = BN_bin2bn(&data->data[2], + data->length - 2, NULL); /* fall through */ default: DPRINTF(1, ("cert_parse: %s\n", - OBJ_nid2ln(temp))); + OBJ_nid2ln(nid))); break; } } @@ -3669,10 +3738,10 @@ crypto_key( DPRINTF(1, ("crypto_key: %s\n", statstr)); #ifdef DEBUG if (debug > 1) { - if (pkey->type == EVP_PKEY_DSA) - DSA_print_fp(stdout, pkey->pkey.dsa, 0); - else if (pkey->type == EVP_PKEY_RSA) - RSA_print_fp(stdout, pkey->pkey.rsa, 0); + if (EVP_PKEY_base_id(pkey) == EVP_PKEY_DSA) + DSA_print_fp(stdout, EVP_PKEY_get0_DSA(pkey), 0); + else if (EVP_PKEY_base_id(pkey) == EVP_PKEY_RSA) + RSA_print_fp(stdout, EVP_PKEY_get0_RSA(pkey), 0); } #endif return (pkp); @@ -3882,7 +3951,7 @@ crypto_setup(void) filename); exit (-1); } - if (pinfo->pkey->type != EVP_PKEY_RSA) { + if (EVP_PKEY_base_id(pinfo->pkey) != EVP_PKEY_RSA) { msyslog(LOG_ERR, "crypto_setup: host key is not RSA key type"); exit (-1); diff --git a/ntpq/ntpq.c b/ntpq/ntpq.c index ed5c65fca..91364de4b 100644 --- a/ntpq/ntpq.c +++ b/ntpq/ntpq.c @@ -34,6 +34,7 @@ #include "openssl/evp.h" #include "openssl/objects.h" #include "openssl/err.h" +#include "libssl_compat.h" #endif #include @@ -3582,7 +3583,7 @@ static void list_md_fn(const EVP_MD *m, const char *from, const char *to, void * size_t len, n; const char *name, *cp, **seen; struct hstate *hstate = arg; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; u_int digest_len; u_char digest[EVP_MAX_MD_SIZE]; @@ -3613,8 +3614,10 @@ static void list_md_fn(const EVP_MD *m, const char *from, const char *to, void * * Keep this consistent with keytype_from_text() in ssl_init.c. */ - EVP_DigestInit(&ctx, EVP_get_digestbyname(name)); - EVP_DigestFinal(&ctx, digest, &digest_len); + ctx = EVP_MD_CTX_new(); + EVP_DigestInit(ctx, EVP_get_digestbyname(name)); + EVP_DigestFinal(ctx, digest, &digest_len); + EVP_MD_CTX_free(ctx); if (digest_len > (MAX_MAC_LEN - sizeof(keyid_t))) return; diff --git a/sntp/crypto.c b/sntp/crypto.c index a534239a3..7b4e63833 100644 --- a/sntp/crypto.c +++ b/sntp/crypto.c @@ -2,6 +2,7 @@ #include "crypto.h" #include #include "isc/string.h" +#include "libssl_compat.h" struct key *key_ptr; size_t key_cnt = 0; @@ -17,7 +18,7 @@ make_mac( { u_int len = mac_size; int key_type; - EVP_MD_CTX ctx; + EVP_MD_CTX * ctx; if (cmp_key->key_len > 64) return 0; @@ -26,11 +27,14 @@ make_mac( INIT_SSL(); key_type = keytype_from_text(cmp_key->type, NULL); - EVP_DigestInit(&ctx, EVP_get_digestbynid(key_type)); - EVP_DigestUpdate(&ctx, (const u_char *)cmp_key->key_seq, (u_int)cmp_key->key_len); - EVP_DigestUpdate(&ctx, pkt_data, (u_int)pkt_size); - EVP_DigestFinal(&ctx, digest, &len); - + + ctx = EVP_MD_CTX_new(); + EVP_DigestInit(ctx, EVP_get_digestbynid(key_type)); + EVP_DigestUpdate(ctx, (const u_char *)cmp_key->key_seq, (u_int)cmp_key->key_len); + EVP_DigestUpdate(ctx, pkt_data, (u_int)pkt_size); + EVP_DigestFinal(ctx, digest, &len); + EVP_MD_CTX_free(ctx); + return (int)len; } @@ -64,7 +68,7 @@ auth_md5( * with. sntp is a 1-shot program, so snooping for * timing attacks is Harder. */ - authentic = !memcmp(digest, pkt_data + pkt_size + 4, + authentic = !memcmp(digest, (const char*)pkt_data + pkt_size + 4, hash_len); } return authentic; diff --git a/util/ntp-keygen.c b/util/ntp-keygen.c index ab34927cd..66a4755df 100644 --- a/util/ntp-keygen.c +++ b/util/ntp-keygen.c @@ -105,6 +105,7 @@ #include "openssl/pem.h" #include "openssl/x509v3.h" #include +#include "libssl_compat.h" #endif /* OPENSSL */ #include @@ -148,6 +149,10 @@ EVP_PKEY *genkey (const char *, const char *); EVP_PKEY *readkey (char *, char *, u_int *, EVP_PKEY **); void writekey (char *, char *, u_int *, EVP_PKEY **); u_long asn2ntp (ASN1_TIME *); + +static DSA* genDsaParams(int, char*); +static RSA* genRsaKeyPair(int, char*); + #endif /* AUTOKEY */ /* @@ -294,7 +299,6 @@ main( int optct; /* option count */ #ifdef AUTOKEY X509 *cert = NULL; /* X509 certificate */ - X509_EXTENSION *ext; /* X509v3 extension */ EVP_PKEY *pkey_host = NULL; /* host key */ EVP_PKEY *pkey_sign = NULL; /* sign key */ EVP_PKEY *pkey_iffkey = NULL; /* IFF sever keys */ @@ -511,8 +515,7 @@ main( * Extract digest/signature scheme. */ if (scheme == NULL) { - nid = OBJ_obj2nid(cert->cert_info-> - signature->algorithm); + nid = X509_get_signature_nid(cert); scheme = OBJ_nid2sn(nid); } @@ -524,8 +527,13 @@ main( ptr = strstr(groupbuf, "CN="); cnt = X509_get_ext_count(cert); for (i = 0; i < cnt; i++) { + X509_EXTENSION *ext; + ASN1_OBJECT *obj; + ext = X509_get_ext(cert, i); - if (OBJ_obj2nid(ext->object) == + obj = X509_EXTENSION_get_object(ext); + + if (OBJ_obj2nid(obj) == NID_ext_key_usage) { bp = BIO_new(BIO_s_mem()); X509V3_EXT_print(bp, ext, 0, 0); @@ -617,8 +625,14 @@ main( filename); } } - if (pkey_gqkey != NULL) - grpkey = BN_bn2hex(pkey_gqkey->pkey.rsa->q); + if (pkey_gqkey != NULL) { + RSA *rsa; + const BIGNUM *q; + + rsa = EVP_PKEY_get0_RSA(pkey_gqkey); + RSA_get0_factors(rsa, NULL, &q); + grpkey = BN_bn2hex(q); + } /* * Write the nonencrypted GQ client parameters to the stdout @@ -634,9 +648,10 @@ main( filename); fprintf(stdout, "# %s\n# %s\n", filename, ctime(&epoch)); - rsa = pkey_gqkey->pkey.rsa; - BN_copy(rsa->p, BN_value_one()); - BN_copy(rsa->q, BN_value_one()); + /* XXX: This modifies the private key and should probably use a + * copy of it instead. */ + rsa = EVP_PKEY_get0_RSA(pkey_gqkey); + RSA_set0_factors(rsa, BN_dup(BN_value_one()), BN_dup(BN_value_one())); pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, rsa); PEM_write_PKCS8PrivateKey(stdout, pkey, NULL, NULL, 0, @@ -658,7 +673,7 @@ main( filename); fprintf(stdout, "# %s\n# %s\n", filename, ctime(&epoch)); - rsa = pkey_gqkey->pkey.rsa; + rsa = EVP_PKEY_get0_RSA(pkey_gqkey); pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, rsa); PEM_write_PKCS8PrivateKey(stdout, pkey, cipher, NULL, 0, @@ -699,8 +714,10 @@ main( filename); fprintf(stdout, "# %s\n# %s\n", filename, ctime(&epoch)); - dsa = pkey_iffkey->pkey.dsa; - BN_copy(dsa->priv_key, BN_value_one()); + /* XXX: This modifies the private key and should probably use a + * copy of it instead. */ + dsa = EVP_PKEY_get0_DSA(pkey_iffkey); + DSA_set0_key(dsa, NULL, BN_dup(BN_value_one())); pkey = EVP_PKEY_new(); EVP_PKEY_assign_DSA(pkey, dsa); PEM_write_PKCS8PrivateKey(stdout, pkey, NULL, NULL, 0, @@ -722,7 +739,7 @@ main( filename); fprintf(stdout, "# %s\n# %s\n", filename, ctime(&epoch)); - dsa = pkey_iffkey->pkey.dsa; + dsa = EVP_PKEY_get0_DSA(pkey_iffkey); pkey = EVP_PKEY_new(); EVP_PKEY_assign_DSA(pkey, dsa); PEM_write_PKCS8PrivateKey(stdout, pkey, cipher, NULL, 0, @@ -767,7 +784,7 @@ main( NULL, NULL); fflush(stdout); if (debug) - DSA_print_fp(stderr, pkey->pkey.dsa, 0); + DSA_print_fp(stderr, EVP_PKEY_get0_DSA(pkey), 0); } /* @@ -785,7 +802,7 @@ main( NULL, passwd2); fflush(stdout); if (debug) - DSA_print_fp(stderr, pkey->pkey.dsa, 0); + DSA_print_fp(stderr, EVP_PKEY_get0_DSA(pkey), 0); } /* @@ -934,11 +951,11 @@ readkey( if (pkey == NULL) pkey = parkey; if (debug) { - if (parkey->type == EVP_PKEY_DSA) - DSA_print_fp(stderr, parkey->pkey.dsa, + if (EVP_PKEY_base_id(parkey) == EVP_PKEY_DSA) + DSA_print_fp(stderr, EVP_PKEY_get0_DSA(parkey), 0); - else if (parkey->type == EVP_PKEY_RSA) - RSA_print_fp(stderr, parkey->pkey.rsa, + else if (EVP_PKEY_base_id(parkey) == EVP_PKEY_RSA) + RSA_print_fp(stderr, EVP_PKEY_get0_RSA(parkey), 0); } } @@ -967,7 +984,7 @@ gen_rsa( FILE *str; fprintf(stderr, "Generating RSA keys (%d bits)...\n", modulus); - rsa = RSA_generate_key(modulus, 65537, cb, _UC("RSA")); + rsa = genRsaKeyPair(modulus, _UC("RSA")); fprintf(stderr, "\n"); if (rsa == NULL) { fprintf(stderr, "RSA generate keys fails\n%s\n", @@ -1006,7 +1023,7 @@ gen_rsa( return (pkey); } - + /* * Generate DSA public/private key pair */ @@ -1017,7 +1034,6 @@ gen_dsa( { EVP_PKEY *pkey; /* private key */ DSA *dsa; /* DSA parameters */ - u_char seed[20]; /* seed for parameters */ FILE *str; /* @@ -1025,9 +1041,7 @@ gen_dsa( */ fprintf(stderr, "Generating DSA parameters (%d bits)...\n", modulus); - RAND_bytes(seed, sizeof(seed)); - dsa = DSA_generate_parameters(modulus, seed, sizeof(seed), NULL, - NULL, cb, _UC("DSA")); + dsa = genDsaParams(modulus, _UC("DSA")); fprintf(stderr, "\n"); if (dsa == NULL) { fprintf(stderr, "DSA generate parameters fails\n%s\n", @@ -1119,26 +1133,26 @@ gen_iffkey( { EVP_PKEY *pkey; /* private key */ DSA *dsa; /* DSA parameters */ - u_char seed[20]; /* seed for parameters */ BN_CTX *ctx; /* BN working space */ BIGNUM *b, *r, *k, *u, *v, *w; /* BN temp */ FILE *str; u_int temp; - + const BIGNUM *p, *q, *g; + BIGNUM *pub_key, *priv_key; + /* * Generate DSA parameters for use as IFF parameters. */ fprintf(stderr, "Generating IFF keys (%d bits)...\n", modulus2); - RAND_bytes(seed, sizeof(seed)); - dsa = DSA_generate_parameters(modulus2, seed, sizeof(seed), NULL, - NULL, cb, _UC("IFF")); + dsa = genDsaParams(modulus2, _UC("IFF")); fprintf(stderr, "\n"); if (dsa == NULL) { fprintf(stderr, "DSA generate parameters fails\n%s\n", ERR_error_string(ERR_get_error(), NULL)); - return (NULL);; + return (NULL); } + DSA_get0_pqg(dsa, &p, &q, &g); /* * Generate the private and public keys. The DSA parameters and @@ -1147,12 +1161,12 @@ gen_iffkey( */ b = BN_new(); r = BN_new(); k = BN_new(); u = BN_new(); v = BN_new(); w = BN_new(); ctx = BN_CTX_new(); - BN_rand(b, BN_num_bits(dsa->q), -1, 0); /* a */ - BN_mod(b, b, dsa->q, ctx); - BN_sub(v, dsa->q, b); - BN_mod_exp(v, dsa->g, v, dsa->p, ctx); /* g^(q - b) mod p */ - BN_mod_exp(u, dsa->g, b, dsa->p, ctx); /* g^b mod p */ - BN_mod_mul(u, u, v, dsa->p, ctx); + BN_rand(b, BN_num_bits(q), -1, 0); /* a */ + BN_mod(b, b, q, ctx); + BN_sub(v, q, b); + BN_mod_exp(v, g, v, p, ctx); /* g^(q - b) mod p */ + BN_mod_exp(u, g, b, p, ctx); /* g^b mod p */ + BN_mod_mul(u, u, v, p, ctx); temp = BN_is_one(u); fprintf(stderr, "Confirm g^(q - b) g^b = 1 mod p: %s\n", temp == 1 ? @@ -1162,28 +1176,29 @@ gen_iffkey( BN_free(u); BN_free(v); BN_free(w); BN_CTX_free(ctx); return (NULL); } - dsa->priv_key = BN_dup(b); /* private key */ - dsa->pub_key = BN_dup(v); /* public key */ + pub_key = BN_dup(v); + priv_key = BN_dup(b); + DSA_set0_key(dsa, pub_key, priv_key); /* * Here is a trial round of the protocol. First, Alice rolls * random nonce r mod q and sends it to Bob. She needs only * q from parameters. */ - BN_rand(r, BN_num_bits(dsa->q), -1, 0); /* r */ - BN_mod(r, r, dsa->q, ctx); + BN_rand(r, BN_num_bits(q), -1, 0); /* r */ + BN_mod(r, r, q, ctx); /* * Bob rolls random nonce k mod q, computes y = k + b r mod q * and x = g^k mod p, then sends (y, x) to Alice. He needs * p, q and b from parameters and r from Alice. */ - BN_rand(k, BN_num_bits(dsa->q), -1, 0); /* k, 0 < k < q */ - BN_mod(k, k, dsa->q, ctx); - BN_mod_mul(v, dsa->priv_key, r, dsa->q, ctx); /* b r mod q */ + BN_rand(k, BN_num_bits(q), -1, 0); /* k, 0 < k < q */ + BN_mod(k, k, q, ctx); + BN_mod_mul(v, priv_key, r, q, ctx); /* b r mod q */ BN_add(v, v, k); - BN_mod(v, v, dsa->q, ctx); /* y = k + b r mod q */ - BN_mod_exp(u, dsa->g, k, dsa->p, ctx); /* x = g^k mod p */ + BN_mod(v, v, q, ctx); /* y = k + b r mod q */ + BN_mod_exp(u, g, k, p, ctx); /* x = g^k mod p */ /* * Alice verifies x = g^y v^r to confirm that Bob has group key @@ -1191,9 +1206,9 @@ gen_iffkey( * original r. We omit the detail here thatt only the hash of y * is sent. */ - BN_mod_exp(v, dsa->g, v, dsa->p, ctx); /* g^y mod p */ - BN_mod_exp(w, dsa->pub_key, r, dsa->p, ctx); /* v^r */ - BN_mod_mul(v, w, v, dsa->p, ctx); /* product mod p */ + BN_mod_exp(v, g, v, p, ctx); /* g^y mod p */ + BN_mod_exp(w, pub_key, r, p, ctx); /* v^r */ + BN_mod_mul(v, w, v, p, ctx); /* product mod p */ temp = BN_cmp(u, v); fprintf(stderr, "Confirm g^k = g^(k + b r) g^(q - b) r: %s\n", temp == @@ -1301,22 +1316,26 @@ gen_gqkey( BIGNUM *u, *v, *g, *k, *r, *y; /* BN temps */ FILE *str; u_int temp; - + BIGNUM *b; + const BIGNUM *n; + /* * Generate RSA parameters for use as GQ parameters. */ fprintf(stderr, "Generating GQ parameters (%d bits)...\n", modulus2); - rsa = RSA_generate_key(modulus2, 65537, cb, _UC("GQ")); + rsa = genRsaKeyPair(modulus2, _UC("GQ")); fprintf(stderr, "\n"); if (rsa == NULL) { fprintf(stderr, "RSA generate keys fails\n%s\n", ERR_error_string(ERR_get_error(), NULL)); return (NULL); } + RSA_get0_key(rsa, &n, NULL, NULL); u = BN_new(); v = BN_new(); g = BN_new(); k = BN_new(); r = BN_new(); y = BN_new(); + b = BN_new(); /* * Generate the group key b, which is saved in the e member of @@ -1324,26 +1343,26 @@ gen_gqkey( * member encrypted by the member private key. */ ctx = BN_CTX_new(); - BN_rand(rsa->e, BN_num_bits(rsa->n), -1, 0); /* b */ - BN_mod(rsa->e, rsa->e, rsa->n, ctx); + BN_rand(b, BN_num_bits(n), -1, 0); /* b */ + BN_mod(b, b, n, ctx); /* * When generating his certificate, Bob rolls random private key * u, then computes inverse v = u^-1. */ - BN_rand(u, BN_num_bits(rsa->n), -1, 0); /* u */ - BN_mod(u, u, rsa->n, ctx); - BN_mod_inverse(v, u, rsa->n, ctx); /* u^-1 mod n */ - BN_mod_mul(k, v, u, rsa->n, ctx); + BN_rand(u, BN_num_bits(n), -1, 0); /* u */ + BN_mod(u, u, n, ctx); + BN_mod_inverse(v, u, n, ctx); /* u^-1 mod n */ + BN_mod_mul(k, v, u, n, ctx); /* * Bob computes public key v = (u^-1)^b, which is saved in an * extension field on his certificate. We check that u^b v = * 1 mod n. */ - BN_mod_exp(v, v, rsa->e, rsa->n, ctx); - BN_mod_exp(g, u, rsa->e, rsa->n, ctx); /* u^b */ - BN_mod_mul(g, g, v, rsa->n, ctx); /* u^b (u^-1)^b */ + BN_mod_exp(v, v, b, n, ctx); + BN_mod_exp(g, u, b, n, ctx); /* u^b */ + BN_mod_mul(g, g, v, n, ctx); /* u^b (u^-1)^b */ temp = BN_is_one(g); fprintf(stderr, "Confirm u^b (u^-1)^b = 1 mod n: %s\n", temp ? "yes" : @@ -1355,27 +1374,30 @@ gen_gqkey( RSA_free(rsa); return (NULL); } - BN_copy(rsa->p, u); /* private key */ - BN_copy(rsa->q, v); /* public key */ + /* setting 'u' and 'v' into a RSA object takes over ownership. + * Since we use these values again, we have to pass in dupes, + * or we'll corrupt the program! + */ + RSA_set0_factors(rsa, BN_dup(u), BN_dup(v)); /* * Here is a trial run of the protocol. First, Alice rolls * random nonce r mod n and sends it to Bob. She needs only n * from parameters. */ - BN_rand(r, BN_num_bits(rsa->n), -1, 0); /* r */ - BN_mod(r, r, rsa->n, ctx); + BN_rand(r, BN_num_bits(n), -1, 0); /* r */ + BN_mod(r, r, n, ctx); /* * Bob rolls random nonce k mod n, computes y = k u^r mod n and * g = k^b mod n, then sends (y, g) to Alice. He needs n, u, b * from parameters and r from Alice. */ - BN_rand(k, BN_num_bits(rsa->n), -1, 0); /* k */ - BN_mod(k, k, rsa->n, ctx); - BN_mod_exp(y, rsa->p, r, rsa->n, ctx); /* u^r mod n */ - BN_mod_mul(y, k, y, rsa->n, ctx); /* y = k u^r mod n */ - BN_mod_exp(g, k, rsa->e, rsa->n, ctx); /* g = k^b mod n */ + BN_rand(k, BN_num_bits(n), -1, 0); /* k */ + BN_mod(k, k, n, ctx); + BN_mod_exp(y, u, r, n, ctx); /* u^r mod n */ + BN_mod_mul(y, k, y, n, ctx); /* y = k u^r mod n */ + BN_mod_exp(g, k, b, n, ctx); /* g = k^b mod n */ /* * Alice verifies g = v^r y^b mod n to confirm that Bob has @@ -1384,9 +1406,9 @@ gen_gqkey( * original r. We omit the detaul here that only the hash of g * is sent. */ - BN_mod_exp(v, rsa->q, r, rsa->n, ctx); /* v^r mod n */ - BN_mod_exp(y, y, rsa->e, rsa->n, ctx); /* y^b mod n */ - BN_mod_mul(y, v, y, rsa->n, ctx); /* v^r y^b mod n */ + BN_mod_exp(v, v, r, n, ctx); /* v^r mod n */ + BN_mod_exp(y, y, b, n, ctx); /* y^b mod n */ + BN_mod_mul(y, v, y, n, ctx); /* v^r y^b mod n */ temp = BN_cmp(y, g); fprintf(stderr, "Confirm g^k = v^r y^b mod n: %s\n", temp == 0 ? "yes" : "no"); @@ -1410,10 +1432,9 @@ gen_gqkey( * dmq1 not used * iqmp not used */ - BN_copy(rsa->d, BN_value_one()); - BN_copy(rsa->dmp1, BN_value_one()); - BN_copy(rsa->dmq1, BN_value_one()); - BN_copy(rsa->iqmp, BN_value_one()); + RSA_set0_key(rsa, NULL, b, BN_dup(BN_value_one())); + RSA_set0_crt_params(rsa, BN_dup(BN_value_one()), BN_dup(BN_value_one()), + BN_dup(BN_value_one())); str = fheader("GQkey", id, groupname); pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, rsa); @@ -1509,7 +1530,7 @@ gen_mvkey( DSA *dsa, *dsa2, *sdsa; /* DSA parameters */ BN_CTX *ctx; /* BN working space */ BIGNUM *a[MVMAX]; /* polynomial coefficient vector */ - BIGNUM *g[MVMAX]; /* public key vector */ + BIGNUM *gs[MVMAX]; /* public key vector */ BIGNUM *s1[MVMAX]; /* private enabling keys */ BIGNUM *x[MVMAX]; /* polynomial zeros vector */ BIGNUM *xbar[MVMAX], *xhat[MVMAX]; /* private keys vector */ @@ -1520,6 +1541,7 @@ gen_mvkey( BIGNUM *bige; /* session encryption key */ BIGNUM *gbar, *ghat; /* public key */ BIGNUM *u, *v, *w; /* BN scratch */ + BIGNUM *p, *q, *g, *priv_key, *pub_key; int i, j, n; FILE *str; u_int temp; @@ -1544,14 +1566,14 @@ gen_mvkey( ctx = BN_CTX_new(); u = BN_new(); v = BN_new(); w = BN_new(); b = BN_new(); b1 = BN_new(); dsa = DSA_new(); - dsa->p = BN_new(); dsa->q = BN_new(); dsa->g = BN_new(); - dsa->priv_key = BN_new(); dsa->pub_key = BN_new(); + p = BN_new(); q = BN_new(); g = BN_new(); + priv_key = BN_new(); pub_key = BN_new(); temp = 0; for (j = 1; j <= n; j++) { s1[j] = BN_new(); while (1) { - BN_generate_prime(s1[j], modulus2 / n, 0, NULL, - NULL, NULL, NULL); + BN_generate_prime_ex(s1[j], modulus2 / n, 0, + NULL, NULL, NULL); for (i = 1; i < j; i++) { if (BN_cmp(s1[i], s1[j]) == 0) break; @@ -1577,21 +1599,20 @@ gen_mvkey( */ temp = 0; while (1) { - BN_one(dsa->q); + BN_one(q); for (j = 1; j <= n; j++) - BN_mul(dsa->q, dsa->q, s1[j], ctx); - BN_copy(dsa->p, dsa->q); - BN_add(dsa->p, dsa->p, dsa->p); - BN_add_word(dsa->p, 1); - if (BN_is_prime(dsa->p, BN_prime_checks, NULL, ctx, - NULL)) + BN_mul(q, q, s1[j], ctx); + BN_copy(p, q); + BN_add(p, p, p); + BN_add_word(p, 1); + if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) break; temp++; j = temp % n + 1; while (1) { - BN_generate_prime(u, modulus2 / n, 0, 0, NULL, - NULL, NULL); + BN_generate_prime_ex(u, modulus2 / n, 0, + NULL, NULL, NULL); for (i = 1; i <= n; i++) { if (BN_cmp(u, s1[i]) == 0) break; @@ -1608,20 +1629,22 @@ gen_mvkey( * gcd(g, p - 1) = 1 and g^q = 1. This is a generator of p, not * q. This may take several iterations. */ - BN_copy(v, dsa->p); + BN_copy(v, p); BN_sub_word(v, 1); while (1) { - BN_rand(dsa->g, BN_num_bits(dsa->p) - 1, 0, 0); - BN_mod(dsa->g, dsa->g, dsa->p, ctx); - BN_gcd(u, dsa->g, v, ctx); + BN_rand(g, BN_num_bits(p) - 1, 0, 0); + BN_mod(g, g, p, ctx); + BN_gcd(u, g, v, ctx); if (!BN_is_one(u)) continue; - BN_mod_exp(u, dsa->g, dsa->q, dsa->p, ctx); + BN_mod_exp(u, g, q, p, ctx); if (BN_is_one(u)) break; } + DSA_set0_pqg(dsa, p, q, g); + /* * Setup is now complete. Roll random polynomial roots x[j] * (j = 1...n) for all j. While it may not be strictly @@ -1630,14 +1653,14 @@ gen_mvkey( */ fprintf(stderr, "Generating polynomial coefficients for %d roots (%d bits)\n", - n, BN_num_bits(dsa->q)); + n, BN_num_bits(q)); for (j = 1; j <= n; j++) { x[j] = BN_new(); while (1) { - BN_rand(x[j], BN_num_bits(dsa->q), 0, 0); - BN_mod(x[j], x[j], dsa->q, ctx); - BN_gcd(u, x[j], dsa->q, ctx); + BN_rand(x[j], BN_num_bits(q), 0, 0); + BN_mod(x[j], x[j], q, ctx); + BN_gcd(u, x[j], q, ctx); if (BN_is_one(u)) break; } @@ -1655,26 +1678,26 @@ gen_mvkey( for (j = 1; j <= n; j++) { BN_zero(w); for (i = 0; i < j; i++) { - BN_copy(u, dsa->q); - BN_mod_mul(v, a[i], x[j], dsa->q, ctx); + BN_copy(u, q); + BN_mod_mul(v, a[i], x[j], q, ctx); BN_sub(u, u, v); BN_add(u, u, w); BN_copy(w, a[i]); - BN_mod(a[i], u, dsa->q, ctx); + BN_mod(a[i], u, q, ctx); } } /* - * Generate g[i] = g^a[i] mod p for all i and the generator g. + * Generate gs[i] = g^a[i] mod p for all i and the generator g. */ for (i = 0; i <= n; i++) { - g[i] = BN_new(); - BN_mod_exp(g[i], dsa->g, a[i], dsa->p, ctx); + gs[i] = BN_new(); + BN_mod_exp(gs[i], g, a[i], p, ctx); } /* - * Verify prod(g[i]^(a[i] x[j]^i)) = 1 for all i, j. Note the - * a[i] x[j]^i exponent is computed mod q, but the g[i] is + * Verify prod(gs[i]^(a[i] x[j]^i)) = 1 for all i, j. Note the + * a[i] x[j]^i exponent is computed mod q, but the gs[i] is * computed mod p. also note the expression given in the paper * is incorrect. */ @@ -1683,16 +1706,16 @@ gen_mvkey( BN_one(u); for (i = 0; i <= n; i++) { BN_set_word(v, i); - BN_mod_exp(v, x[j], v, dsa->q, ctx); - BN_mod_mul(v, v, a[i], dsa->q, ctx); - BN_mod_exp(v, dsa->g, v, dsa->p, ctx); - BN_mod_mul(u, u, v, dsa->p, ctx); + BN_mod_exp(v, x[j], v, q, ctx); + BN_mod_mul(v, v, a[i], q, ctx); + BN_mod_exp(v, g, v, p, ctx); + BN_mod_mul(u, u, v, p, ctx); } if (!BN_is_one(u)) temp = 0; } fprintf(stderr, - "Confirm prod(g[i]^(x[j]^i)) = 1 for all i, j: %s\n", temp ? + "Confirm prod(gs[i]^(x[j]^i)) = 1 for all i, j: %s\n", temp ? "yes" : "no"); if (!temp) { return (NULL); @@ -1708,9 +1731,9 @@ gen_mvkey( for (j = 1; j <= n; j++) { for (i = 0; i < n; i++) { BN_set_word(v, i); - BN_mod_exp(v, x[j], v, dsa->q, ctx); - BN_mod_exp(v, g[i], v, dsa->p, ctx); - BN_mod_mul(biga, biga, v, dsa->p, ctx); + BN_mod_exp(v, x[j], v, q, ctx); + BN_mod_exp(v, gs[i], v, p, ctx); + BN_mod_mul(biga, biga, v, p, ctx); } } @@ -1720,13 +1743,13 @@ gen_mvkey( * mod q. If b is changed, the client keys must be recomputed. */ while (1) { - BN_rand(b, BN_num_bits(dsa->q), 0, 0); - BN_mod(b, b, dsa->q, ctx); - BN_gcd(u, b, dsa->q, ctx); + BN_rand(b, BN_num_bits(q), 0, 0); + BN_mod(b, b, q, ctx); + BN_gcd(u, b, q, ctx); if (BN_is_one(u)) break; } - BN_mod_inverse(b1, b, dsa->q, ctx); + BN_mod_inverse(b1, b, q, ctx); /* * Make private client keys (xbar[j], xhat[j]) for all j. Note @@ -1740,7 +1763,7 @@ gen_mvkey( for (j = 1; j <= n; j++) { xbar[j] = BN_new(); xhat[j] = BN_new(); - BN_add(w, dsa->q, s1[j]); + BN_add(w, q, s1[j]); BN_div(w, u, w, s1[j], ctx); BN_zero(xbar[j]); BN_set_word(v, n); @@ -1748,12 +1771,12 @@ gen_mvkey( if (i == j) continue; - BN_mod_exp(u, x[i], v, dsa->q, ctx); + BN_mod_exp(u, x[i], v, q, ctx); BN_add(xbar[j], xbar[j], u); } - BN_mod_mul(xbar[j], xbar[j], b1, dsa->q, ctx); - BN_mod_exp(xhat[j], x[j], v, dsa->q, ctx); - BN_mod_mul(xhat[j], xhat[j], w, dsa->q, ctx); + BN_mod_mul(xbar[j], xbar[j], b1, q, ctx); + BN_mod_exp(xhat[j], x[j], v, q, ctx); + BN_mod_mul(xhat[j], xhat[j], w, q, ctx); } /* @@ -1764,7 +1787,7 @@ gen_mvkey( * additional keys, so we sail on with only token revocations. */ s = BN_new(); - BN_copy(s, dsa->q); + BN_copy(s, q); BN_div(s, u, s, s1[n], ctx); /* @@ -1776,10 +1799,10 @@ gen_mvkey( * changed. */ bige = BN_new(); gbar = BN_new(); ghat = BN_new(); - BN_mod_exp(bige, biga, s, dsa->p, ctx); - BN_mod_exp(gbar, dsa->g, s, dsa->p, ctx); - BN_mod_mul(v, s, b, dsa->q, ctx); - BN_mod_exp(ghat, dsa->g, v, dsa->p, ctx); + BN_mod_exp(bige, biga, s, p, ctx); + BN_mod_exp(gbar, g, s, p, ctx); + BN_mod_mul(v, s, b, q, ctx); + BN_mod_exp(ghat, g, v, p, ctx); /* * Notes: We produce the key media in three steps. The first @@ -1815,8 +1838,9 @@ gen_mvkey( i = 0; str = fheader("MVta", "mvta", groupname); fprintf(stderr, "Generating MV trusted-authority keys\n"); - BN_copy(dsa->priv_key, biga); - BN_copy(dsa->pub_key, b); + BN_copy(priv_key, biga); + BN_copy(pub_key, b); + DSA_set0_key(dsa, pub_key, priv_key); pkey = EVP_PKEY_new(); EVP_PKEY_assign_DSA(pkey, dsa); PEM_write_PKCS8PrivateKey(str, pkey, cipher, NULL, 0, NULL, @@ -1838,11 +1862,8 @@ gen_mvkey( */ fprintf(stderr, "Generating MV server keys\n"); dsa2 = DSA_new(); - dsa2->p = BN_dup(dsa->p); - dsa2->q = BN_dup(dsa->q); - dsa2->g = BN_dup(bige); - dsa2->priv_key = BN_dup(gbar); - dsa2->pub_key = BN_dup(ghat); + DSA_set0_pqg(dsa2, BN_dup(p), BN_dup(q), BN_dup(bige)); + DSA_set0_key(dsa2, BN_dup(ghat), BN_dup(gbar)); pkey1 = EVP_PKEY_new(); EVP_PKEY_assign_DSA(pkey1, dsa2); PEM_write_PKCS8PrivateKey(str, pkey1, cipher, NULL, 0, NULL, @@ -1863,11 +1884,9 @@ gen_mvkey( fprintf(stderr, "Generating %d MV client keys\n", n); for (j = 1; j <= n; j++) { sdsa = DSA_new(); - sdsa->p = BN_dup(dsa->p); - sdsa->q = BN_dup(BN_value_one()); - sdsa->g = BN_dup(BN_value_one()); - sdsa->priv_key = BN_dup(xbar[j]); - sdsa->pub_key = BN_dup(xhat[j]); + DSA_set0_pqg(sdsa, BN_dup(p), BN_dup(BN_value_one()), + BN_dup(BN_value_one())); + DSA_set0_key(sdsa, BN_dup(xhat[j]), BN_dup(xbar[j])); pkey1 = EVP_PKEY_new(); EVP_PKEY_set1_DSA(pkey1, sdsa); PEM_write_PKCS8PrivateKey(str, pkey1, cipher, NULL, 0, @@ -1877,17 +1896,15 @@ gen_mvkey( DSA_print_fp(stderr, sdsa, 0); /* - * The product gbar^k)^xbar[j] (ghat^k)^xhat[j] and E + * The product (gbar^k)^xbar[j] (ghat^k)^xhat[j] and E * are inverses of each other. We check that the product * is one for each client except the ones that have been * revoked. */ - BN_mod_exp(v, dsa2->priv_key, sdsa->pub_key, dsa->p, - ctx); - BN_mod_exp(u, dsa2->pub_key, sdsa->priv_key, dsa->p, - ctx); - BN_mod_mul(u, u, v, dsa->p, ctx); - BN_mod_mul(u, u, bige, dsa->p, ctx); + BN_mod_exp(v, gbar, xhat[j], p, ctx); + BN_mod_exp(u, ghat, xbar[j], p, ctx); + BN_mod_mul(u, u, v, p, ctx); + BN_mod_mul(u, u, bige, p, ctx); if (!BN_is_one(u)) { fprintf(stderr, "Revoke key %d\n", j); continue; @@ -1900,7 +1917,7 @@ gen_mvkey( * Free the countries. */ for (i = 0; i <= n; i++) { - BN_free(a[i]); BN_free(g[i]); + BN_free(a[i]); BN_free(gs[i]); } for (j = 1; j <= n; j++) { BN_free(x[j]); BN_free(xbar[j]); BN_free(xhat[j]); @@ -1945,7 +1962,7 @@ x509 ( * the version to 3. Set the initial validity to the current * time and the finalvalidity one year hence. */ - id = OBJ_nid2sn(md->pkey_type); + id = OBJ_nid2sn(EVP_MD_pkey_type(md)); fprintf(stderr, "Generating new certificate %s %s\n", name, id); cert = X509_new(); X509_set_version(cert, 2L); @@ -2154,6 +2171,56 @@ genkey( fprintf(stderr, "Invalid %s key type %s\n", id, type); return (NULL); } + +static RSA* +genRsaKeyPair( + int bits, + char * what + ) +{ + RSA * rsa = RSA_new(); + BN_GENCB * gcb = BN_GENCB_new(); + BIGNUM * bne = BN_new(); + + if (gcb) + BN_GENCB_set_old(gcb, cb, what); + if (bne) + BN_set_word(bne, 65537); + if (!(rsa && gcb && bne && RSA_generate_key_ex( + rsa, bits, bne, gcb))) + { + RSA_free(rsa); + rsa = NULL; + } + BN_GENCB_free(gcb); + BN_free(bne); + return rsa; +} + +static DSA* +genDsaParams( + int bits, + char * what + ) +{ + + DSA * dsa = DSA_new(); + BN_GENCB * gcb = BN_GENCB_new(); + u_char seed[20]; + + if (gcb) + BN_GENCB_set_old(gcb, cb, what); + RAND_bytes(seed, sizeof(seed)); + if (!(dsa && gcb && DSA_generate_parameters_ex( + dsa, bits, seed, sizeof(seed), NULL, NULL, gcb))) + { + DSA_free(dsa); + dsa = NULL; + } + BN_GENCB_free(gcb); + return dsa; +} + #endif /* AUTOKEY */