]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 3095] Compatibility with openssl 1.1
authorJuergen Perlinger <perlinger@ntp.org>
Sun, 4 Sep 2016 06:48:03 +0000 (08:48 +0200)
committerJuergen Perlinger <perlinger@ntp.org>
Sun, 4 Sep 2016 06:48:03 +0000 (08:48 +0200)
  - applied patches by Kurt Roeckx <kurt@roeckx.be> to source
  - added shim layer for SSL API calls with issues (both directions)

bk: 57cbc3a31sDs0X_urNJIrgOcHd15Hw

ChangeLog
include/libssl_compat.h [new file with mode: 0644]
libntp/Makefile.am
libntp/a_md5encrypt.c
libntp/libssl_compat.c [new file with mode: 0644]
libntp/ssl_init.c
ntpd/ntp_control.c
ntpd/ntp_crypto.c
ntpq/ntpq.c
sntp/crypto.c
util/ntp-keygen.c

index 0805467dc6b9b1ce7768a039f6a2d87af37546b9..cadee06f7ff94bb67fbf337396ae9f1c3bf04437 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+---
+* [Bug 3095] Compatibility with openssl 1.1 <perlinger@ntp.org>
+  - applied patches by Kurt Roeckx <kurt@roeckx.be> to source
+  - added shim layer for SSL API calls with issues (both directions)
+
 ---
 (4.2.8p8) 2016/06/02 Released by Harlan Stenn <stenn@ntp.org>
 
diff --git a/include/libssl_compat.h b/include/libssl_compat.h
new file mode 100644 (file)
index 0000000..b739773
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * libssl_compat.h -- OpenSSL v1.1 compatibility shims
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Written by Juergen Perlinger <perlinger@ntp.org> for the NTP project
+ *
+ * Based on an idea by Kurt Roeckx <kurt@roeckx.be>
+ *
+ * ---------------------------------------------------------------------
+ * 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.
+ *
+ * The other way round, functions that need random number generator
+ * callbacks have also changed in OpenSSL v1.1, but in this case it is
+ * easier to wrap the new behaviour into a shim simulating the old API.
+ *
+ * At the time of this writing the old-style API is still available; it
+ * just creates annoying depreciation warnings. OTOH, this means the
+ * implementation in OpenSSL can vanish at any time, so it's better to
+ * provide the necessary wrappers.
+ * ---------------------------------------------------------------------
+ */
+
+#ifndef NTP_LIBSSL_COMPAT_H
+#define NTP_LIBSSL_COMPAT_H
+
+#include "openssl/evp.h"
+#include "openssl/dsa.h"
+#include "openssl/rsa.h"
+
+extern BIGNUM * ntpMP_new_from_ulong(unsigned long);
+extern BIGNUM * ntpMP_new_from_long(long);
+
+/* ----------------------------------------------------------------- */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+/* ----------------------------------------------------------------- */
+
+/* shim the new-style API on an old-style OpenSSL */
+
+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_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 EVP_MD_CTX_new         sslshim_EVP_MD_CTX_new
+#define EVP_MD_CTX_free                sslshim_EVP_MD_CTX_free
+
+#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
+
+/* ----------------------------------------------------------------- */
+#else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
+/* ----------------------------------------------------------------- */
+
+/* shim the new API to provide old functions */
+
+extern BIGNUM * sslshim_BN_generate_prime(
+       BIGNUM *ret, int num, int safe, BIGNUM *add, BIGNUM *rem,
+       void (*callback)(int, int, void *), void *cb_arg);
+
+extern int sslshim_BN_is_prime(
+       const BIGNUM *a, int checks, void (*callback)(int, int, void *),
+       BN_CTX *ctx, void *cb_arg);
+
+extern RSA * sslshim_RSA_generate_key(
+       int num, unsigned long e, void (*callback)(int, int, void *),
+       void *cb_arg);
+
+extern DSA * sslshim_DSA_generate_parameters(
+       int bits, unsigned char *seed, int seed_len, int *counter_ret,
+       unsigned long *h_ret, void (*callback)(int, int, void *),
+       void *cb_arg);
+
+
+#define BN_generate_prime      sslshim_BN_generate_prime
+#define BN_is_prime            sslshim_BN_is_prime
+
+#define RSA_generate_key       sslshim_RSA_generate_key
+#define DSA_generate_parameters        sslshim_DSA_generate_parameters
+
+/* ----------------------------------------------------------------- */
+#endif /* OPENSSL_VERSION_NUMBER checks */
+/* ----------------------------------------------------------------- */
+
+#endif /* NTP_LIBSSL_COMPAT_H */
index 26a4709e8b54c3ca5184a825a5577d6833935370..874739a188460241c0b51c9d80e11ebaad0ad224 100644 (file)
@@ -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                                       \
index 618ccd9de10288fc0da51a696989fa7a419dfa94..0ff036f0ed47d0eba0bd2224862182512ffb0c82 100644 (file)
@@ -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 (file)
index 0000000..ac4a633
--- /dev/null
@@ -0,0 +1,452 @@
+/*
+ * libssl_compat.c -- OpenSSL v1.1 compatibility functions
+ *
+ * ---------------------------------------------------------------------
+ * Written by Juergen Perlinger <perlinger@ntp.org> for the NTP project
+ *
+ * Based on an idea by Kurt Roeckx <kurt@roeckx.be>
+ *
+ * ---------------------------------------------------------------------
+ * 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.
+ *
+ * The other way round, functions that need random number generator
+ * callbacks have also changed in OpenSSL v1.1, but in this case it is
+ * easier to wrap new behaviour into a shim simulating the old API.
+ *
+ * ---------------------------------------------------------------------
+ */
+#include "config.h"
+
+#include <string.h>
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+
+#include "ntp_types.h"
+#include "libssl_compat.h"
+
+/* --------------------------------------------------------------------
+ * allocate & set a new BIGNUM object. Some examples and hints made me
+ * wary of using BN_set_word here, so I went through a big-endian byte
+ * buffer, which should be pretty portable, too.
+ */
+BIGNUM*
+ntpMP_new_from_ulong(
+       unsigned long   v
+       )
+{
+       unsigned char   buf[sizeof(v)];
+       int             idx;
+       
+       for (idx = sizeof(v); idx; v >>= 8)
+               buf[--idx] = (unsigned char)(v & 0x0FF);
+       return BN_bin2bn(buf, sizeof(v), NULL);
+}
+
+BIGNUM*
+ntpMP_new_from_long(
+       long    v
+       )
+{
+       unsigned long   um = 0UL - (v < 0);
+       unsigned long   uv = (unsigned long)v;
+       BIGNUM *        bn = ntpMP_new_from_ulong((uv + um) ^ um);
+       if (bn)
+               BN_set_negative(bn, (um & 1));
+       return bn;
+}
+
+/* ----------------------------------------------------------------- */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+/* ----------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------
+ * 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) {
+               BN_clear_free(*ps);
+               *ps = n;
+       }
+}
+
+/* --------------------------------------------------------------------
+ * 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_base_id(
+       const EVP_PKEY *pkey
+       )
+{
+       return (pkey) ? 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
+       )
+{
+       const BIGNUM *n = NULL;
+       const BIGNUM *e = NULL;
+       const BIGNUM *d = NULL;
+       if (prsa) {
+               n = prsa->n;
+               e = prsa->e;
+               d = prsa->d;
+       }
+       if (pn)
+               *pn = n;
+       if (pe)
+               *pe = e;
+       if (pd)
+               *pd = d;
+}
+
+int
+sslshim_RSA_set0_key(
+       RSA *           prsa,
+       BIGNUM *        n,
+       BIGNUM *        e,
+       BIGNUM *        d
+       )
+{
+       if (!(prsa && (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
+       )
+{
+       const BIGNUM *p = NULL;
+       const BIGNUM *q = NULL;
+       if (prsa) {
+               p = prsa->p;
+               q = prsa->q;
+       }
+       if (pp)
+               *pp = p;
+       if (pq)
+               *pq = q;
+}
+
+int
+sslshim_RSA_set0_factors(
+       RSA    *        prsa,
+       BIGNUM *        p,
+       BIGNUM *        q
+       )
+{
+       if (!(prsa && (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
+       )
+{
+       if (!(prsa && (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
+       )
+{
+       BIGNUM * r = NULL;
+       BIGNUM * s = NULL;
+       if (psig) {
+               r = psig->r;
+               s = psig->s;
+       }
+       if (pr != NULL)
+               *pr = r;
+       if (ps != NULL)
+               *ps = s;
+}
+
+int
+sslshim_DSA_SIG_set0(
+       DSA_SIG *       psig,
+       BIGNUM *        r,
+       BIGNUM *        s
+       )
+{
+       if (!(psig && r && s))
+               return 0;
+       
+       BN_clear_free(psig->r);
+       psig->r = r;
+       BN_clear_free(psig->s);
+       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
+       )
+{
+       BIGNUM * p = NULL;
+       BIGNUM * q = NULL;
+       BIGNUM * g = NULL;
+       if (pdsa) {
+               p = pdsa->p;
+               q = pdsa->q;
+               g = pdsa->g;
+       }
+       if (pp != NULL)
+               *pp = p;
+       if (pq != NULL)
+               *pq = q;
+       if (pg != NULL)
+               *pg = g;
+}
+
+int
+sslshim_DSA_set0_pqg(
+       DSA *           pdsa,
+       BIGNUM *        p,
+       BIGNUM *        q,
+       BIGNUM *        g
+       )
+{
+       if (!(pdsa && (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
+       )
+{
+       const BIGNUM * ppub  = NULL;
+       const BIGNUM * ppriv = NULL;
+       if (pdsa) {
+               ppub  = pdsa->pub_key;
+               ppriv = pdsa->priv_key;
+       }
+       if (ppub_key != NULL)
+               *ppub_key = ppub;
+       if (ppriv_key != NULL)
+               *ppriv_key = ppriv;
+}
+
+int
+sslshim_DSA_set0_key(
+       DSA *           pdsa,
+       BIGNUM *        pub_key,
+       BIGNUM *        priv_key
+       )
+{
+       if (!(pdsa && (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
+/* ----------------------------------------------------------------- */
+
+/* backward compat shims -- it's easier this way because of the
+ * callbacks. Once the new API is used exclusively, these shims can go.
+ */
+static BN_GENCB *
+new_gencb(
+       void    (*callback)(int, int, void *),
+       void *  cb_arg
+       )
+{
+       BN_GENCB * gcb = BN_GENCB_new();
+       if (gcb)
+               BN_GENCB_set_old(gcb, callback, cb_arg);
+       return gcb;
+}
+
+BIGNUM*
+sslshim_BN_generate_prime(
+       BIGNUM *        ret,
+       int             bits,
+       int             safe,
+       BIGNUM *        add,
+       BIGNUM *        rem,
+       void            (*callback)(int, int, void *),
+       void *          cb_arg
+       )
+{
+       BN_GENCB *      gcb = new_gencb(callback, cb_arg);
+       int             ok  = 0;
+
+       if (gcb) {
+               ok = BN_generate_prime_ex(
+                       ret, bits, safe, add, rem, gcb);
+               BN_GENCB_free(gcb);
+       }
+       return ok ? ret : NULL; 
+}
+
+int
+sslshim_BN_is_prime(
+       const BIGNUM *  a,
+       int             checks,
+       void            (*callback)(int, int, void *),
+       BN_CTX *        ctx,
+       void *          cb_arg
+       )
+{
+       BN_GENCB *      gcb = new_gencb(callback, cb_arg);
+       int             ok  = 0;
+
+       if (gcb) {
+               ok = BN_is_prime_ex(a, checks, ctx, gcb);
+               BN_GENCB_free(gcb);
+       }
+       return ok;
+}
+
+RSA*
+sslshim_RSA_generate_key(
+       int             bits,
+       unsigned long   e,
+       void            (*callback)(int, int, void *),
+       void *          cb_arg
+       )
+{
+       RSA *           rsa = RSA_new();
+       BIGNUM *        be  = ntpMP_new_from_ulong(e);
+       BN_GENCB *      gcb = new_gencb(callback, cb_arg);
+
+       if (!(rsa && gcb && be && RSA_generate_key_ex(rsa, bits, be, gcb))) {
+               RSA_free(rsa);
+               rsa = NULL;
+       }
+       BN_GENCB_free(gcb);
+       BN_free(be);
+       return rsa;
+}
+
+DSA*
+sslshim_DSA_generate_parameters(
+       int             bits,
+       unsigned char * seed,
+       int             slen,
+       int *           cntret,
+       unsigned long * hret,
+       void            (*callback)(int, int, void *),
+       void *          cb_arg
+       )
+{
+       DSA *           dsa = DSA_new();
+       BN_GENCB *      gcb = new_gencb(callback, cb_arg);
+       if (!(dsa && gcb && DSA_generate_parameters_ex(
+                     dsa, bits, seed, slen, cntret, hret, gcb)))
+       {
+               DSA_free(dsa);
+               dsa = NULL;
+       }
+       BN_GENCB_free(gcb);
+       return dsa;
+}
+/* ----------------------------------------------------------------- */
+#endif
+/* ----------------------------------------------------------------- */
index a9d1d546dfb89ba2b8217e48320e1bc582b58070..755a5ff354cd7a26917988f7079f8ce2781ee430 100644 (file)
@@ -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",
index 07b5697f1536605efed3f4ee726d21ee94a59a70..73beaba1d812b7dce3680a5932689016d05ad1cd 100644 (file)
@@ -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;
 }
index 86541bdc16c4abc42e73fff8e460b7762f37819c..2b9cb52e4b349cf97cd9bb821572469b92b39815 100644 (file)
 #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);
index ed5c65fca1949edb6027bd39dacef8b88a289fa5..91364de4ba8bd799308bbca83c6c57025076f34d 100644 (file)
@@ -34,6 +34,7 @@
 #include "openssl/evp.h"
 #include "openssl/objects.h"
 #include "openssl/err.h"
+#include "libssl_compat.h"
 #endif
 #include <ssl_applink.c>
 
@@ -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;
 
index a534239a31f865a97e4a792082057f8643e035b3..7b4e63833ac154959c1ab1259599bfb5e2280416 100644 (file)
@@ -2,6 +2,7 @@
 #include "crypto.h"
 #include <ctype.h>
 #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;
index ab34927cd8bd9e677fbb8f609e441d956dff8dee..628ea3bb0cd9eeab55301db6709b4f762fad8353 100644 (file)
 #include "openssl/pem.h"
 #include "openssl/x509v3.h"
 #include <openssl/objects.h>
+#include "libssl_compat.h"
 #endif /* OPENSSL */
 #include <ssl_applink.c>
 
@@ -294,7 +295,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 +511,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 +523,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 +621,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 +644,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 +669,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 +710,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 +735,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 +780,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 +798,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 +947,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);
                }
        }
@@ -1124,6 +1137,8 @@ gen_iffkey(
        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.
@@ -1139,6 +1154,7 @@ gen_iffkey(
                    ERR_error_string(ERR_get_error(), NULL));
                return (NULL);;
        }
+       DSA_get0_pqg(dsa, &p, &q, &g);
 
        /*
         * Generate the private and public keys. The DSA parameters and
@@ -1147,12 +1163,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 +1178,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 +1208,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,6 +1318,8 @@ 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.
@@ -1315,8 +1334,10 @@ gen_gqkey(
                    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 +1345,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 +1376,26 @@ gen_gqkey(
                RSA_free(rsa);
                return (NULL);
        }
-       BN_copy(rsa->p, u);                     /* private key */
-       BN_copy(rsa->q, v);                     /* public key */
+       RSA_set0_factors(rsa, u, 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 +1404,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 +1430,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 +1528,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 +1539,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,8 +1564,8 @@ 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();
@@ -1577,13 +1597,13 @@ 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,
+                       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(p, BN_prime_checks, NULL, ctx,
                    NULL))
                        break;
 
@@ -1608,20 +1628,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 +1652,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 +1677,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 +1705,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 +1730,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 +1742,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 +1762,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 +1770,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 +1786,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 +1798,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 +1837,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 +1861,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 +1883,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 +1895,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 +1916,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 +1961,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);