[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Build libssh against openssl 1.1.0


Andreas,
thank you for the comments. I reworked the patch (attached) to smaller parts that finally build and passes the testsuite in master for both OpenSSL versions (sorry for the first bad version). It also improves the readability of some constructions according to your hints.

The related problem was with EVP_CIPHER_CTX that can't be used statically in new OpenSSL and it needs to be allocated using EVP_CIPHER_CTX_new(). There is no single initialization function for ssh_cipher_struct (evp_cipher_init can be called more times?) so therefore the check for NULL. Also the NULL should probably come to the ssh_ciphertab[] as a default value to make sure there is really zero. Also some of the constructions in the [PATCH 3/4] might need some consideration from you, more versed on the code execution paths that are expected.

Regards,
Jakub

On 11/02/2016 01:06 PM, Andreas Schneider wrote:
On Wednesday, 2 November 2016 12:34:59 CET Andreas Schneider wrote:
On Wednesday, 2 November 2016 11:27:18 CET Aris Adamantiadis wrote:
Hi Jakub,

That's great work you did here. Please let us some time to review your
patch and give feedback. We should test on some older systems, such as
centos/RHEL 4.x that some people still use.
Yes, this is indeed nice work. However I've already found some small issues.
In DEBUG_CRYPTO there were some const issue and dsa instead of ecdsa was
used. I've fixed that in the branch here:

https://git.libssh.org/users/asn/libssh.git/log/?h=fix

Oh,

the test 'torture_crypto' fails for me with openssl 1.0.2j:


#0  0x00007ffff75f37fd in EVP_CIPHER_CTX_init () from /lib64/libcrypto.so.
1.0.0
#1  0x0000000000420693 in evp_cipher_set_encrypt_key (cipher=0x7fffffffd6c0,
key=0x68d800 <key>, IV=0x7fffffffd720) at /home/asn/workspace/projects/libssh/
src/libcrypto.c:484
#2  0x0000000000410d95 in torture_crypto_aes256_cbc (state=0x6921a0) at /home/
asn/workspace/projects/libssh/tests/unittests/torture_crypto.c:64


void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);


You make ctx in struct ssh_cipher_struct a pointer which gets initialized with
NULL.


So we call: EVP_CIPHER_CTX_init(NULL);

and segfault.

If I remove the change to make ctx a pointer in ssh_cipher_struct it works
just fine.


	Andreas



--
Jakub Jelen
Software Engineer
Security Technologies
Red Hat

From c824d59e44eae826f3ee21d27127fbd2649c6899 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@xxxxxxxxxx>
Date: Wed, 2 Nov 2016 16:20:46 +0100
Subject: [PATCH 1/4] OpenSSL 1.1.0: Removed AES_ctr128_encrypt()

Signed-off-by: Jakub Jelen <jjelen@xxxxxxxxxx>
---
 src/libcrypto.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/libcrypto.c b/src/libcrypto.c
index ac95010..19065bd 100644
--- a/src/libcrypto.c
+++ b/src/libcrypto.c
@@ -587,7 +587,11 @@ static void aes_ctr_encrypt(struct ssh_cipher_struct *cipher, void *in, void *ou
    * Same for num, which is being used to store the current offset in blocksize in CTR
    * function.
    */
+# if OPENSSL_VERSION_NUMBER >= 0x10100000L
+  CRYPTO_ctr128_encrypt(in, out, len, &cipher->aes_key->key, cipher->aes_key->IV, tmp_buffer, &num, (block128_f)AES_encrypt);
+# else
   AES_ctr128_encrypt(in, out, len, &cipher->aes_key->key, cipher->aes_key->IV, tmp_buffer, &num);
+# endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
 }
 
 static void aes_ctr_cleanup(struct ssh_cipher_struct *cipher){
-- 
2.7.4


From e50acee0b67bf471597fd93989bbdb01067220cb Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@xxxxxxxxxx>
Date: Wed, 2 Nov 2016 16:38:09 +0100
Subject: [PATCH 2/4] OpenSSL 1.1.0: Introduce compat file

Signed-off-by: Jakub Jelen <jjelen@xxxxxxxxxx>
---
 src/CMakeLists.txt     |   1 +
 src/libcrypto-compat.c | 335 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/libcrypto-compat.h |  43 +++++++
 3 files changed, 379 insertions(+)
 create mode 100644 src/libcrypto-compat.c
 create mode 100644 src/libcrypto-compat.h

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a3e08a6..2517267 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -126,6 +126,7 @@ set(libssh_SRCS
   known_hosts.c
   legacy.c
   libcrypto.c
+  libcrypto-compat.c
   log.c
   match.c
   messages.c
diff --git a/src/libcrypto-compat.c b/src/libcrypto-compat.c
new file mode 100644
index 0000000..1f27dd5
--- /dev/null
+++ b/src/libcrypto-compat.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/opensslv.h>
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+#include <string.h>
+#include <openssl/engine.h>
+#include "libcrypto-compat.h"
+
+static void *OPENSSL_zalloc(size_t num)
+{
+    void *ret = OPENSSL_malloc(num);
+
+    if (ret != NULL)
+        memset(ret, 0, num);
+    return ret;
+}
+
+int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
+{
+    /* If the fields n and e in r are NULL, the corresponding input
+     * parameters MUST be non-NULL for n and e.  d may be
+     * left NULL (in case only the public key is used).
+     */
+    if ((r->n == NULL && n == NULL)
+        || (r->e == NULL && e == NULL))
+        return 0;
+
+    if (n != NULL) {
+        BN_free(r->n);
+        r->n = n;
+    }
+    if (e != NULL) {
+        BN_free(r->e);
+        r->e = e;
+    }
+    if (d != NULL) {
+        BN_free(r->d);
+        r->d = d;
+    }
+
+    return 1;
+}
+
+int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
+{
+    /* If the fields p and q in r are NULL, the corresponding input
+     * parameters MUST be non-NULL.
+     */
+    if ((r->p == NULL && p == NULL)
+        || (r->q == NULL && q == NULL))
+        return 0;
+
+    if (p != NULL) {
+        BN_free(r->p);
+        r->p = p;
+    }
+    if (q != NULL) {
+        BN_free(r->q);
+        r->q = q;
+    }
+
+    return 1;
+}
+
+int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
+{
+    /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input
+     * parameters MUST be non-NULL.
+     */
+    if ((r->dmp1 == NULL && dmp1 == NULL)
+        || (r->dmq1 == NULL && dmq1 == NULL)
+        || (r->iqmp == NULL && iqmp == NULL))
+        return 0;
+
+    if (dmp1 != NULL) {
+        BN_free(r->dmp1);
+        r->dmp1 = dmp1;
+    }
+    if (dmq1 != NULL) {
+        BN_free(r->dmq1);
+        r->dmq1 = dmq1;
+    }
+    if (iqmp != NULL) {
+        BN_free(r->iqmp);
+        r->iqmp = iqmp;
+    }
+
+    return 1;
+}
+
+void RSA_get0_key(const RSA *r,
+                  const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
+{
+    if (n != NULL)
+        *n = r->n;
+    if (e != NULL)
+        *e = r->e;
+    if (d != NULL)
+        *d = r->d;
+}
+
+void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
+{
+    if (p != NULL)
+        *p = r->p;
+    if (q != NULL)
+        *q = r->q;
+}
+
+void RSA_get0_crt_params(const RSA *r,
+                         const BIGNUM **dmp1, const BIGNUM **dmq1,
+                         const BIGNUM **iqmp)
+{
+    if (dmp1 != NULL)
+        *dmp1 = r->dmp1;
+    if (dmq1 != NULL)
+        *dmq1 = r->dmq1;
+    if (iqmp != NULL)
+        *iqmp = r->iqmp;
+}
+
+void DSA_get0_pqg(const DSA *d,
+                  const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+    if (p != NULL)
+        *p = d->p;
+    if (q != NULL)
+        *q = d->q;
+    if (g != NULL)
+        *g = d->g;
+}
+
+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+    /* If the fields p, q and g in d are NULL, the corresponding input
+     * parameters MUST be non-NULL.
+     */
+    if ((d->p == NULL && p == NULL)
+        || (d->q == NULL && q == NULL)
+        || (d->g == NULL && g == NULL))
+        return 0;
+
+    if (p != NULL) {
+        BN_free(d->p);
+        d->p = p;
+    }
+    if (q != NULL) {
+        BN_free(d->q);
+        d->q = q;
+    }
+    if (g != NULL) {
+        BN_free(d->g);
+        d->g = g;
+    }
+
+    return 1;
+}
+
+void DSA_get0_key(const DSA *d,
+                  const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+    if (pub_key != NULL)
+        *pub_key = d->pub_key;
+    if (priv_key != NULL)
+        *priv_key = d->priv_key;
+}
+
+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+    /* If the field pub_key in d is NULL, the corresponding input
+     * parameters MUST be non-NULL.  The priv_key field may
+     * be left NULL.
+     */
+    if (d->pub_key == NULL && pub_key == NULL)
+        return 0;
+
+    if (pub_key != NULL) {
+        BN_free(d->pub_key);
+        d->pub_key = pub_key;
+    }
+    if (priv_key != NULL) {
+        BN_free(d->priv_key);
+        d->priv_key = priv_key;
+    }
+
+    return 1;
+}
+
+void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
+{
+    if (pr != NULL)
+        *pr = sig->r;
+    if (ps != NULL)
+        *ps = sig->s;
+}
+
+int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+    if (r == NULL || s == NULL)
+        return 0;
+    BN_clear_free(sig->r);
+    BN_clear_free(sig->s);
+    sig->r = r;
+    sig->s = s;
+    return 1;
+}
+
+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
+{
+    if (pr != NULL)
+        *pr = sig->r;
+    if (ps != NULL)
+        *ps = sig->s;
+}
+
+int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+    if (r == NULL || s == NULL)
+        return 0;
+    BN_clear_free(sig->r);
+    BN_clear_free(sig->s);
+    sig->r = r;
+    sig->s = s;
+    return 1;
+}
+
+EVP_MD_CTX *EVP_MD_CTX_new(void)
+{
+    return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
+}
+
+static void OPENSSL_clear_free(void *str, size_t num)
+{
+    if (str == NULL)
+        return;
+    if (num)
+        OPENSSL_cleanse(str, num);
+    OPENSSL_free(str);
+}
+
+/* This call frees resources associated with the context */
+int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
+{
+    if (ctx == NULL)
+        return 1;
+
+    /*
+     * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
+     * sometimes only copies of the context are ever finalised.
+     */
+    if (ctx->digest && ctx->digest->cleanup
+        && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
+        ctx->digest->cleanup(ctx);
+    if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
+        && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
+        OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
+    }
+    EVP_PKEY_CTX_free(ctx->pctx);
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(ctx->engine);
+#endif
+    OPENSSL_cleanse(ctx, sizeof(*ctx));
+
+    return 1;
+}
+
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
+{
+    EVP_MD_CTX_reset(ctx);
+    OPENSSL_free(ctx);
+}
+
+HMAC_CTX *HMAC_CTX_new(void)
+{
+    HMAC_CTX *ctx = OPENSSL_zalloc(sizeof(HMAC_CTX));
+
+    if (ctx != NULL) {
+        if (!HMAC_CTX_reset(ctx)) {
+            HMAC_CTX_free(ctx);
+            return NULL;
+        }
+    }
+    return ctx;
+}
+
+static void hmac_ctx_cleanup(HMAC_CTX *ctx)
+{
+    EVP_MD_CTX_reset(&ctx->i_ctx);
+    EVP_MD_CTX_reset(&ctx->o_ctx);
+    EVP_MD_CTX_reset(&ctx->md_ctx);
+    ctx->md = NULL;
+    ctx->key_length = 0;
+    OPENSSL_cleanse(ctx->key, sizeof(ctx->key));
+}
+
+void HMAC_CTX_free(HMAC_CTX *ctx)
+{
+    if (ctx != NULL) {
+        hmac_ctx_cleanup(ctx);
+        EVP_MD_CTX_free(&ctx->i_ctx);
+        EVP_MD_CTX_free(&ctx->o_ctx);
+        EVP_MD_CTX_free(&ctx->md_ctx);
+        OPENSSL_free(ctx);
+    }
+}
+
+int HMAC_CTX_reset(HMAC_CTX *ctx)
+{
+    HMAC_CTX_init(ctx);
+    return 1;
+}
+
+EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
+{
+    return OPENSSL_zalloc(sizeof(EVP_CIPHER_CTX));
+}
+
+void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
+{
+    /* EVP_CIPHER_CTX_reset(ctx); alias */
+    EVP_CIPHER_CTX_init(ctx);
+    OPENSSL_free(ctx);
+}
+
+#else
+typedef int iso_c_forbids_an_empty_source_file;
+#endif /* OPENSSL_VERSION_NUMBER */
diff --git a/src/libcrypto-compat.h b/src/libcrypto-compat.h
new file mode 100644
index 0000000..7364d4c
--- /dev/null
+++ b/src/libcrypto-compat.h
@@ -0,0 +1,43 @@
+#ifndef LIBCRYPTO_COMPAT_H
+#define LIBCRYPTO_COMPAT_H
+
+#include <openssl/opensslv.h>
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/ecdsa.h>
+#include <openssl/dh.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+
+int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
+int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q);
+int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp);
+void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d);
+void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q);
+void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp);
+
+void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g);
+void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key);
+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key);
+
+void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
+int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s);
+
+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
+int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);
+
+int EVP_MD_CTX_reset(EVP_MD_CTX *ctx);
+EVP_MD_CTX *EVP_MD_CTX_new(void);
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
+
+HMAC_CTX *HMAC_CTX_new(void);
+int HMAC_CTX_reset(HMAC_CTX *ctx);
+void HMAC_CTX_free(HMAC_CTX *ctx);
+
+#endif /* OPENSSL_VERSION_NUMBER */
+
+#endif /* LIBCRYPTO_COMPAT_H */
+
-- 
2.7.4


From 4896ac1196e82508fb1f94cd377797968a122970 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@xxxxxxxxxx>
Date: Wed, 2 Nov 2016 16:32:32 +0100
Subject: [PATCH 3/4] OpenSSL 1.1.0: CIPHER_CTX was made opaque and therefore
 it can not be used static

---
 include/libssh/crypto.h |  2 +-
 src/libcrypto.c         | 50 +++++++++++++++++++++++++++----------------------
 src/wrapper.c           | 11 +++++++++++
 3 files changed, 40 insertions(+), 23 deletions(-)

diff --git a/include/libssh/crypto.h b/include/libssh/crypto.h
index e370c74..18bc944 100644
--- a/include/libssh/crypto.h
+++ b/include/libssh/crypto.h
@@ -126,7 +126,7 @@ struct ssh_cipher_struct {
     struct ssh_3des_key_schedule *des3_key;
     struct ssh_aes_key_schedule *aes_key;
     const EVP_CIPHER *cipher;
-    EVP_CIPHER_CTX ctx;
+    EVP_CIPHER_CTX *ctx;
 #endif
     unsigned int keysize; /* bytes of key used. != keylen */
     /* sets the new key for immediate use */
diff --git a/src/libcrypto.c b/src/libcrypto.c
index 19065bd..3acb85c 100644
--- a/src/libcrypto.c
+++ b/src/libcrypto.c
@@ -43,6 +43,7 @@
 #include <openssl/hmac.h>
 #include <openssl/opensslv.h>
 #include <openssl/rand.h>
+#include "libcrypto-compat.h"
 
 #ifdef HAVE_OPENSSL_AES_H
 #define HAS_AES
@@ -135,18 +136,19 @@ static const EVP_MD *nid_to_evpmd(int nid)
 void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned int *hlen)
 {
     const EVP_MD *evp_md = nid_to_evpmd(nid);
-    EVP_MD_CTX md;
+    EVP_MD_CTX *md = EVP_MD_CTX_new();
 
-    EVP_DigestInit(&md, evp_md);
-    EVP_DigestUpdate(&md, digest, len);
-    EVP_DigestFinal(&md, hash, hlen);
+    EVP_DigestInit(md, evp_md);
+    EVP_DigestUpdate(md, digest, len);
+    EVP_DigestFinal(md, hash, hlen);
+    EVP_MD_CTX_free(md);
 }
 
 EVPCTX evp_init(int nid)
 {
     const EVP_MD *evp_md = nid_to_evpmd(nid);
 
-    EVPCTX ctx = malloc(sizeof(EVP_MD_CTX));
+    EVPCTX ctx = EVP_MD_CTX_new();
     if (ctx == NULL) {
         return NULL;
     }
@@ -378,32 +380,33 @@ void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) {
 HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
   HMACCTX ctx = NULL;
 
-  ctx = malloc(sizeof(*ctx));
+  ctx = HMAC_CTX_new();
   if (ctx == NULL) {
     return NULL;
   }
 
 #ifndef OLD_CRYPTO
-  HMAC_CTX_init(ctx); // openssl 0.9.7 requires it.
+  HMAC_CTX_reset(ctx); // openssl 0.9.7 requires it.
 #endif
 
   switch(type) {
     case SSH_HMAC_SHA1:
-      HMAC_Init(ctx, key, len, EVP_sha1());
+      HMAC_Init_ex(ctx, key, len, EVP_sha1(), NULL);
       break;
     case SSH_HMAC_SHA256:
-      HMAC_Init(ctx, key, len, EVP_sha256());
+      HMAC_Init_ex(ctx, key, len, EVP_sha256(), NULL);
       break;
     case SSH_HMAC_SHA384:
-      HMAC_Init(ctx, key, len, EVP_sha384());
+      HMAC_Init_ex(ctx, key, len, EVP_sha384(), NULL);
       break;
     case SSH_HMAC_SHA512:
-      HMAC_Init(ctx, key, len, EVP_sha512());
+      HMAC_Init_ex(ctx, key, len, EVP_sha512(), NULL);
       break;
     case SSH_HMAC_MD5:
-      HMAC_Init(ctx, key, len, EVP_md5());
+      HMAC_Init_ex(ctx, key, len, EVP_md5(), NULL);
       break;
     default:
+      HMAC_CTX_free(ctx);
       SAFE_FREE(ctx);
       ctx = NULL;
   }
@@ -419,7 +422,7 @@ void hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, unsigned int *len) {
   HMAC_Final(ctx,hashmacbuf,len);
 
 #ifndef OLD_CRYPTO
-  HMAC_CTX_cleanup(ctx);
+  HMAC_CTX_reset(ctx);
 #else
   HMAC_cleanup(ctx);
 #endif
@@ -428,6 +431,9 @@ void hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, unsigned int *len) {
 }
 
 static void evp_cipher_init(struct ssh_cipher_struct *cipher) {
+    if (cipher->ctx == NULL)
+        cipher->ctx = EVP_CIPHER_CTX_new();
+
     switch(cipher->ciphertype){
     case SSH_AES128_CBC:
         cipher->cipher = EVP_aes_128_cbc();
@@ -478,14 +484,14 @@ static int evp_cipher_set_encrypt_key(struct ssh_cipher_struct *cipher,
     int rc;
 
     evp_cipher_init(cipher);
-    EVP_CIPHER_CTX_init(&cipher->ctx);
+    EVP_CIPHER_CTX_init(cipher->ctx);
 
-    rc = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, key, IV);
+    rc = EVP_EncryptInit_ex(cipher->ctx, cipher->cipher, NULL, key, IV);
     if (rc != 1){
         SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptInit_ex failed");
         return SSH_ERROR;
     }
-    EVP_CIPHER_CTX_set_padding(&cipher->ctx, 0);
+    EVP_CIPHER_CTX_set_padding(cipher->ctx, 0);
 
     return SSH_OK;
 }
@@ -495,14 +501,14 @@ static int evp_cipher_set_decrypt_key(struct ssh_cipher_struct *cipher,
     int rc;
 
     evp_cipher_init(cipher);
-    EVP_CIPHER_CTX_init(&cipher->ctx);
+    EVP_CIPHER_CTX_init(cipher->ctx);
 
-    rc = EVP_DecryptInit_ex(&cipher->ctx, cipher->cipher, NULL, key, IV);
+    rc = EVP_DecryptInit_ex(cipher->ctx, cipher->cipher, NULL, key, IV);
     if (rc != 1){
         SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptInit_ex failed");
         return SSH_ERROR;
     }
-    EVP_CIPHER_CTX_set_padding(&cipher->ctx, 0);
+    EVP_CIPHER_CTX_set_padding(cipher->ctx, 0);
 
     return SSH_OK;
 }
@@ -515,7 +521,7 @@ static void evp_cipher_encrypt(struct ssh_cipher_struct *cipher,
     int outlen = 0;
     int rc = 0;
 
-    rc = EVP_EncryptUpdate(&cipher->ctx, (unsigned char *)out, &outlen, (unsigned char *)in, len);
+    rc = EVP_EncryptUpdate(cipher->ctx, (unsigned char *)out, &outlen, (unsigned char *)in, len);
     if (rc != 1){
         SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptUpdate failed");
         return;
@@ -533,7 +539,7 @@ static void evp_cipher_decrypt(struct ssh_cipher_struct *cipher,
     int outlen = 0;
     int rc = 0;
 
-    rc = EVP_DecryptUpdate(&cipher->ctx, (unsigned char *)out, &outlen, (unsigned char *)in, len);
+    rc = EVP_DecryptUpdate(cipher->ctx, (unsigned char *)out, &outlen, (unsigned char *)in, len);
     if (rc != 1){
         SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptUpdate failed");
         return;
@@ -545,7 +551,7 @@ static void evp_cipher_decrypt(struct ssh_cipher_struct *cipher,
 }
 
 static void evp_cipher_cleanup(struct ssh_cipher_struct *cipher) {
-    EVP_CIPHER_CTX_cleanup(&cipher->ctx);
+    EVP_CIPHER_CTX_cleanup(cipher->ctx);
 }
 
 #ifndef HAVE_OPENSSL_EVP_AES_CTR
diff --git a/src/wrapper.c b/src/wrapper.c
index 705d6c8..2e7710c 100644
--- a/src/wrapper.c
+++ b/src/wrapper.c
@@ -100,6 +100,14 @@ static struct ssh_cipher_struct *cipher_new(int offset) {
   /* note the memcpy will copy the pointers : so, you shouldn't free them */
   memcpy(cipher, &ssh_get_ciphertab()[offset], sizeof(*cipher));
 
+#ifdef HAVE_LIBCRYPTO
+  cipher->ctx = EVP_CIPHER_CTX_new();
+  if (cipher->ctx == NULL) {
+    free(cipher);
+    return NULL;
+  }
+#endif
+
   return cipher;
 }
 
@@ -123,6 +131,9 @@ void ssh_cipher_clear(struct ssh_cipher_struct *cipher){
   if (cipher->cleanup != NULL){
     cipher->cleanup(cipher);
   }
+#ifdef HAVE_LIBCRYPTO
+  EVP_CIPHER_CTX_free(cipher->ctx);
+#endif
 }
 
 static void cipher_free(struct ssh_cipher_struct *cipher) {
-- 
2.7.4


From f125ba2984b5c355f205ca1b7ea7151462ef425c Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@xxxxxxxxxx>
Date: Wed, 2 Nov 2016 17:02:58 +0100
Subject: [PATCH 4/4] OpenSSL 1.1.0: getters and setters for opaque keys and
 signatures manipulation

Signed-off-by: Jakub Jelen <jjelen@xxxxxxxxxx>
---
 src/pki_crypto.c | 295 ++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 203 insertions(+), 92 deletions(-)

diff --git a/src/pki_crypto.c b/src/pki_crypto.c
index dabf54b..a63c825 100644
--- a/src/pki_crypto.c
+++ b/src/pki_crypto.c
@@ -31,6 +31,7 @@
 #include <openssl/dsa.h>
 #include <openssl/err.h>
 #include <openssl/rsa.h>
+#include "libcrypto-compat.h"
 
 #ifdef HAVE_OPENSSL_EC_H
 #include <openssl/ec.h>
@@ -230,7 +231,10 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
     }
 
     switch (key->type) {
-    case SSH_KEYTYPE_DSS:
+    case SSH_KEYTYPE_DSS: {
+        const BIGNUM *p = NULL, *q = NULL, *g = NULL,
+          *pub_key = NULL, *priv_key = NULL;
+        BIGNUM *np, *nq, *ng, *npub_key, *npriv_key;
         new->dsa = DSA_new();
         if (new->dsa == NULL) {
             goto fail;
@@ -243,36 +247,54 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
          * pub_key  = public key y = g^x
          * priv_key = private key x
          */
-        new->dsa->p = BN_dup(key->dsa->p);
-        if (new->dsa->p == NULL) {
+        DSA_get0_pqg(key->dsa, &p, &q, &g);
+        np = BN_dup(p);
+        nq = BN_dup(q);
+        ng = BN_dup(g);
+        if (np == NULL || nq == NULL || ng == NULL) {
+            BN_free(np);
+            BN_free(nq);
+            BN_free(ng);
             goto fail;
         }
 
-        new->dsa->q = BN_dup(key->dsa->q);
-        if (new->dsa->q == NULL) {
+        rc = DSA_set0_pqg(new->dsa, np, nq, ng);
+        if (rc == 0) {
+            BN_free(np);
+            BN_free(nq);
+            BN_free(ng);
             goto fail;
         }
 
-        new->dsa->g = BN_dup(key->dsa->g);
-        if (new->dsa->g == NULL) {
+        DSA_get0_key(key->dsa, &pub_key, &priv_key);
+        npub_key = BN_dup(pub_key);
+        if (npub_key == NULL) {
             goto fail;
         }
 
-        new->dsa->pub_key = BN_dup(key->dsa->pub_key);
-        if (new->dsa->pub_key == NULL) {
+        rc = DSA_set0_key(new->dsa, npub_key, NULL);
+        if (rc == 0) {
             goto fail;
         }
 
         if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) {
-            new->dsa->priv_key = BN_dup(key->dsa->priv_key);
-            if (new->dsa->priv_key == NULL) {
+            npriv_key = BN_dup(priv_key);
+            if (npriv_key == NULL) {
+                goto fail;
+            }
+
+            rc = DSA_set0_key(new->dsa, NULL, npriv_key);
+            if (rc == 0) {
                 goto fail;
             }
         }
 
         break;
+    }
     case SSH_KEYTYPE_RSA:
-    case SSH_KEYTYPE_RSA1:
+    case SSH_KEYTYPE_RSA1: {
+        const BIGNUM *n = NULL, *e = NULL, *d = NULL;
+        BIGNUM *nn, *ne, *nd;
         new->rsa = RSA_new();
         if (new->rsa == NULL) {
             goto fail;
@@ -288,62 +310,82 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
          * dmq1 = d mod (q-1)
          * iqmp = q^-1 mod p
          */
-        new->rsa->n = BN_dup(key->rsa->n);
-        if (new->rsa->n == NULL) {
+        RSA_get0_key(key->rsa, &n, &e, &d);
+        nn = BN_dup(n);
+        ne = BN_dup(e);
+        if (nn == NULL || ne == NULL) {
+            BN_free(nn);
+            BN_free(ne);
             goto fail;
         }
 
-        new->rsa->e = BN_dup(key->rsa->e);
-        if (new->rsa->e == NULL) {
+        rc = RSA_set0_key(new->rsa, nn, ne, NULL);
+        if (rc == 0) {
+            BN_free(nn);
+            BN_free(ne);
             goto fail;
         }
 
         if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) {
-            new->rsa->d = BN_dup(key->rsa->d);
-            if (new->rsa->d == NULL) {
+            const BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL,
+              *dmq1 = NULL, *iqmp = NULL;
+            BIGNUM *np, *nq, *ndmp1, *ndmq1, *niqmp;
+
+            nd = BN_dup(d);
+            if (nd == NULL) {
+                goto fail;
+            }
+
+            rc = RSA_set0_key(new->rsa, NULL, NULL, nd);
+            if (rc == 0) {
                 goto fail;
             }
 
             /* p, q, dmp1, dmq1 and iqmp may be NULL in private keys, but the
              * RSA operations are much faster when these values are available.
              */
-            if (key->rsa->p != NULL) {
-                new->rsa->p = BN_dup(key->rsa->p);
-                if (new->rsa->p == NULL) {
+            RSA_get0_factors(key->rsa, &p, &q);
+            if (p != NULL && q != NULL) { /* need to set both of them */
+                np = BN_dup(p);
+                nq = BN_dup(q);
+                if (np == NULL || nq == NULL) {
+                    BN_free(np);
+                    BN_free(nq);
                     goto fail;
                 }
-            }
 
-            if (key->rsa->q != NULL) {
-                new->rsa->q = BN_dup(key->rsa->q);
-                if (new->rsa->q == NULL) {
+                rc = RSA_set0_factors(new->rsa, np, nq);
+                if (rc == 0) {
+                    BN_free(np);
+                    BN_free(nq);
                     goto fail;
                 }
             }
 
-            if (key->rsa->dmp1 != NULL) {
-                new->rsa->dmp1 = BN_dup(key->rsa->dmp1);
-                if (new->rsa->dmp1 == NULL) {
+            RSA_get0_crt_params(key->rsa, &dmp1, &dmq1, &iqmp);
+            if (dmp1 != NULL || dmq1 != NULL || iqmp != NULL) {
+                ndmp1 = BN_dup(dmp1);
+                ndmq1 = BN_dup(dmq1);
+                niqmp = BN_dup(iqmp);
+                if (ndmp1 == NULL || ndmq1 == NULL || niqmp == NULL) {
+                    BN_free(ndmp1);
+                    BN_free(ndmq1);
+                    BN_free(niqmp);
                     goto fail;
                 }
-            }
 
-            if (key->rsa->dmq1 != NULL) {
-                new->rsa->dmq1 = BN_dup(key->rsa->dmq1);
-                if (new->rsa->dmq1 == NULL) {
-                    goto fail;
-                }
-            }
-
-            if (key->rsa->iqmp != NULL) {
-                new->rsa->iqmp = BN_dup(key->rsa->iqmp);
-                if (new->rsa->iqmp == NULL) {
+                rc =  RSA_set0_crt_params(new->rsa, ndmp1, ndmq1, niqmp);
+                if (rc == 0) {
+                    BN_free(ndmp1);
+                    BN_free(ndmq1);
+                    BN_free(niqmp);
                     goto fail;
                 }
             }
         }
 
         break;
+    }
     case SSH_KEYTYPE_ECDSA:
 #ifdef HAVE_OPENSSL_ECC
         new->ecdsa_nid = key->ecdsa_nid;
@@ -466,51 +508,64 @@ int pki_key_compare(const ssh_key k1,
                     enum ssh_keycmp_e what)
 {
     switch (k1->type) {
-        case SSH_KEYTYPE_DSS:
+        case SSH_KEYTYPE_DSS: {
+            const BIGNUM *p1, *p2, *q1, *q2, *g1, *g2,
+                *pub_key1, *pub_key2, *priv_key1, *priv_key2;
             if (DSA_size(k1->dsa) != DSA_size(k2->dsa)) {
                 return 1;
             }
-            if (bignum_cmp(k1->dsa->p, k2->dsa->p) != 0) {
+            DSA_get0_pqg(k1->dsa, &p1, &q1, &g1);
+            DSA_get0_pqg(k2->dsa, &p2, &q2, &g2);
+            if (bignum_cmp(p1, p2) != 0) {
                 return 1;
             }
-            if (bignum_cmp(k1->dsa->q, k2->dsa->q) != 0) {
+            if (bignum_cmp(q1, q2) != 0) {
                 return 1;
             }
-            if (bignum_cmp(k1->dsa->g, k2->dsa->g) != 0) {
+            if (bignum_cmp(g1, g2) != 0) {
                 return 1;
             }
-            if (bignum_cmp(k1->dsa->pub_key, k2->dsa->pub_key) != 0) {
+            DSA_get0_key(k1->dsa, &pub_key1, &priv_key1);
+            DSA_get0_key(k2->dsa, &pub_key2, &priv_key2);
+            if (bignum_cmp(pub_key1, pub_key2) != 0) {
                 return 1;
             }
 
             if (what == SSH_KEY_CMP_PRIVATE) {
-                if (bignum_cmp(k1->dsa->priv_key, k2->dsa->priv_key) != 0) {
+                if (bignum_cmp(priv_key1, priv_key2) != 0) {
                     return 1;
                 }
             }
             break;
+        }
         case SSH_KEYTYPE_RSA:
-        case SSH_KEYTYPE_RSA1:
+        case SSH_KEYTYPE_RSA1: {
+            const BIGNUM *e1, *e2, *n1, *n2, *p1, *p2, *q1, *q2;
             if (RSA_size(k1->rsa) != RSA_size(k2->rsa)) {
                 return 1;
             }
-            if (bignum_cmp(k1->rsa->e, k2->rsa->e) != 0) {
+            RSA_get0_key(k1->rsa, &n1, &e1, NULL);
+            RSA_get0_key(k2->rsa, &n2, &e2, NULL);
+            if (bignum_cmp(e1, e2) != 0) {
                 return 1;
             }
-            if (bignum_cmp(k1->rsa->n, k2->rsa->n) != 0) {
+            if (bignum_cmp(n1, n2) != 0) {
                 return 1;
             }
 
             if (what == SSH_KEY_CMP_PRIVATE) {
-                if (bignum_cmp(k1->rsa->p, k2->rsa->p) != 0) {
+                RSA_get0_factors(k1->rsa, &p1, &q1);
+                RSA_get0_factors(k2->rsa, &p2, &q2);
+                if (bignum_cmp(p1, p2) != 0) {
                     return 1;
                 }
 
-                if (bignum_cmp(k1->rsa->q, k2->rsa->q) != 0) {
+                if (bignum_cmp(q1, q2) != 0) {
                     return 1;
                 }
             }
             break;
+        }
         case SSH_KEYTYPE_ECDSA:
 #ifdef HAVE_OPENSSL_ECC
             {
@@ -826,43 +881,65 @@ int pki_pubkey_build_dss(ssh_key key,
                          ssh_string q,
                          ssh_string g,
                          ssh_string pubkey) {
+    int rc;
+    BIGNUM *bp, *bq, *bg, *bpub_key;
+
     key->dsa = DSA_new();
     if (key->dsa == NULL) {
         return SSH_ERROR;
     }
 
-    key->dsa->p = ssh_make_string_bn(p);
-    key->dsa->q = ssh_make_string_bn(q);
-    key->dsa->g = ssh_make_string_bn(g);
-    key->dsa->pub_key = ssh_make_string_bn(pubkey);
-    if (key->dsa->p == NULL ||
-        key->dsa->q == NULL ||
-        key->dsa->g == NULL ||
-        key->dsa->pub_key == NULL) {
-        DSA_free(key->dsa);
-        return SSH_ERROR;
+    bp = ssh_make_string_bn(p);
+    bq = ssh_make_string_bn(q);
+    bg = ssh_make_string_bn(g);
+    bpub_key = ssh_make_string_bn(pubkey);
+    if (bp == NULL || bq == NULL ||
+        bg == NULL || bpub_key == NULL) {
+        goto fail;
+    }
+
+    rc = DSA_set0_pqg(key->dsa, bp, bq, bg);
+    if (rc == 0) {
+        goto fail;
+    }
+
+    rc = DSA_set0_key(key->dsa, bpub_key, NULL);
+    if (rc == 0) {
+        goto fail;
     }
 
     return SSH_OK;
+fail:
+    DSA_free(key->dsa);
+    return SSH_ERROR;
 }
 
 int pki_pubkey_build_rsa(ssh_key key,
                          ssh_string e,
                          ssh_string n) {
+    int rc;
+    BIGNUM *be, *bn;
+
     key->rsa = RSA_new();
     if (key->rsa == NULL) {
         return SSH_ERROR;
     }
 
-    key->rsa->e = ssh_make_string_bn(e);
-    key->rsa->n = ssh_make_string_bn(n);
-    if (key->rsa->e == NULL ||
-        key->rsa->n == NULL) {
-        RSA_free(key->rsa);
-        return SSH_ERROR;
+    be = ssh_make_string_bn(e);
+    bn = ssh_make_string_bn(n);
+    if (be == NULL || bn == NULL) {
+        goto fail;
+    }
+
+    rc = RSA_set0_key(key->rsa, bn, be, NULL);
+    if (rc == 0) {
+        goto fail;
     }
 
     return SSH_OK;
+fail:
+    RSA_free(key->rsa);
+    return SSH_ERROR;
 }
 
 ssh_string pki_publickey_to_blob(const ssh_key key)
@@ -905,23 +982,26 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
     }
 
     switch (key->type) {
-        case SSH_KEYTYPE_DSS:
-            p = ssh_make_bignum_string(key->dsa->p);
+        case SSH_KEYTYPE_DSS: {
+            const BIGNUM *bp, *bq, *bg, *bpub_key;
+            DSA_get0_pqg(key->dsa, &bp, &bq, &bg);
+            p = ssh_make_bignum_string((BIGNUM *)bp);
             if (p == NULL) {
                 goto fail;
             }
 
-            q = ssh_make_bignum_string(key->dsa->q);
+            q = ssh_make_bignum_string((BIGNUM *)bq);
             if (q == NULL) {
                 goto fail;
             }
 
-            g = ssh_make_bignum_string(key->dsa->g);
+            g = ssh_make_bignum_string((BIGNUM *)bg);
             if (g == NULL) {
                 goto fail;
             }
 
-            n = ssh_make_bignum_string(key->dsa->pub_key);
+            DSA_get0_key(key->dsa, &bpub_key, NULL);
+            n = ssh_make_bignum_string((BIGNUM *)bpub_key);
             if (n == NULL) {
                 goto fail;
             }
@@ -953,14 +1033,17 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
             n = NULL;
 
             break;
+        }
         case SSH_KEYTYPE_RSA:
-        case SSH_KEYTYPE_RSA1:
-            e = ssh_make_bignum_string(key->rsa->e);
+        case SSH_KEYTYPE_RSA1: {
+            const BIGNUM *be, *bn;
+            RSA_get0_key(key->rsa, &bn, &be, NULL);
+            e = ssh_make_bignum_string((BIGNUM *)be);
             if (e == NULL) {
                 goto fail;
             }
 
-            n = ssh_make_bignum_string(key->rsa->n);
+            n = ssh_make_bignum_string((BIGNUM *)bn);
             if (n == NULL) {
                 goto fail;
             }
@@ -980,6 +1063,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
             n = NULL;
 
             break;
+        }
         case SSH_KEYTYPE_ECDSA:
 #ifdef HAVE_OPENSSL_ECC
             rc = ssh_buffer_reinit(buffer);
@@ -1082,13 +1166,15 @@ int pki_export_pubkey_rsa1(const ssh_key key,
     char *e;
     char *n;
     int rsa_size = RSA_size(key->rsa);
+    const BIGNUM *be, *bn;
 
-    e = bignum_bn2dec(key->rsa->e);
+    RSA_get0_key(key->rsa, &bn, &be, NULL);
+    e = bignum_bn2dec(be);
     if (e == NULL) {
         return SSH_ERROR;
     }
 
-    n = bignum_bn2dec(key->rsa->n);
+    n = bignum_bn2dec(bn);
     if (n == NULL) {
         OPENSSL_free(e);
         return SSH_ERROR;
@@ -1153,6 +1239,7 @@ static ssh_string pki_dsa_signature_to_blob(const ssh_signature sig)
 {
     char buffer[40] = { 0 };
     ssh_string sig_blob = NULL;
+    const BIGNUM *pr, *ps;
 
     ssh_string r;
     int r_len, r_offset_in, r_offset_out;
@@ -1160,12 +1247,13 @@ static ssh_string pki_dsa_signature_to_blob(const ssh_signature sig)
     ssh_string s;
     int s_len, s_offset_in, s_offset_out;
 
-    r = ssh_make_bignum_string(sig->dsa_sig->r);
+    DSA_SIG_get0(sig->dsa_sig, &pr, &ps);
+    r = ssh_make_bignum_string((BIGNUM *)pr);
     if (r == NULL) {
         return NULL;
     }
 
-    s = ssh_make_bignum_string(sig->dsa_sig->s);
+    s = ssh_make_bignum_string((BIGNUM *)ps);
     if (s == NULL) {
         ssh_string_free(r);
         return NULL;
@@ -1218,13 +1306,15 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
             ssh_string s;
             ssh_buffer b;
             int rc;
+            const BIGNUM *pr, *ps;
 
             b = ssh_buffer_new();
             if (b == NULL) {
                 return NULL;
             }
 
-            r = ssh_make_bignum_string(sig->ecdsa_sig->r);
+            ECDSA_SIG_get0(sig->ecdsa_sig, &pr, &ps);
+            r = ssh_make_bignum_string((BIGNUM *)pr);
             if (r == NULL) {
                 ssh_buffer_free(b);
                 return NULL;
@@ -1236,7 +1326,7 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
                 return NULL;
             }
 
-            s = ssh_make_bignum_string(sig->ecdsa_sig->s);
+            s = ssh_make_bignum_string((BIGNUM *)ps);
             if (s == NULL) {
                 ssh_buffer_free(b);
                 return NULL;
@@ -1345,6 +1435,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
     ssh_string s;
     size_t len;
     int rc;
+    BIGNUM *pr = NULL, *ps = NULL;
 
     sig = ssh_signature_new();
     if (sig == NULL) {
@@ -1385,9 +1476,9 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
             }
             ssh_string_fill(r, ssh_string_data(sig_blob), 20);
 
-            sig->dsa_sig->r = ssh_make_string_bn(r);
+            pr = ssh_make_string_bn(r);
             ssh_string_free(r);
-            if (sig->dsa_sig->r == NULL) {
+            if (pr == NULL) {
                 ssh_signature_free(sig);
                 return NULL;
             }
@@ -1399,9 +1490,15 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
             }
             ssh_string_fill(s, (char *)ssh_string_data(sig_blob) + 20, 20);
 
-            sig->dsa_sig->s = ssh_make_string_bn(s);
+            ps = ssh_make_string_bn(s);
             ssh_string_free(s);
-            if (sig->dsa_sig->s == NULL) {
+            if (ps == NULL) {
+                ssh_signature_free(sig);
+                return NULL;
+            }
+
+            rc = DSA_SIG_set0(sig->dsa_sig, pr, ps);
+            if (rc == 0) {
                 ssh_signature_free(sig);
                 return NULL;
             }
@@ -1449,10 +1546,10 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
                 ssh_print_hexa("r", ssh_string_data(r), ssh_string_len(r));
 #endif
 
-                ssh_make_string_bn_inplace(r, sig->ecdsa_sig->r);
+                pr = ssh_make_string_bn(r);
                 ssh_string_burn(r);
                 ssh_string_free(r);
-                if (sig->ecdsa_sig->r == NULL) {
+                if (pr == NULL) {
                     ssh_buffer_free(b);
                     ssh_signature_free(sig);
                     return NULL;
@@ -1470,10 +1567,16 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
                 ssh_print_hexa("s", ssh_string_data(s), ssh_string_len(s));
 #endif
 
-                ssh_make_string_bn_inplace(s, sig->ecdsa_sig->s);
+                ps = ssh_make_string_bn(s);
                 ssh_string_burn(s);
                 ssh_string_free(s);
-                if (sig->ecdsa_sig->s == NULL) {
+                if (ps == NULL) {
+                    ssh_signature_free(sig);
+                    return NULL;
+                }
+
+                rc = ECDSA_SIG_set0(sig->ecdsa_sig, pr, ps);
+                if (rc == 0) {
                     ssh_signature_free(sig);
                     return NULL;
                 }
@@ -1601,8 +1704,12 @@ ssh_signature pki_do_sign(const ssh_key privkey,
             }
 
 #ifdef DEBUG_CRYPTO
-            ssh_print_bignum("r", sig->dsa_sig->r);
-            ssh_print_bignum("s", sig->dsa_sig->s);
+            {
+                const BIGNUM *pr, *ps;
+                DSA_SIG_get0(sig->dsa_sig, &pr, &ps);
+                ssh_print_bignum("r", (BIGNUM *) pr);
+                ssh_print_bignum("s", (BIGNUM *) ps);
+            }
 #endif
 
             break;
@@ -1624,8 +1731,12 @@ ssh_signature pki_do_sign(const ssh_key privkey,
             }
 
 # ifdef DEBUG_CRYPTO
-            ssh_print_bignum("r", sig->ecdsa_sig->r);
-            ssh_print_bignum("s", sig->ecdsa_sig->s);
+            {
+                const BIGNUM *pr, *ps;
+                ECDSA_SIG_get0(sig->dsa_sig, &pr, &ps);
+                ssh_print_bignum("r", (BIGNUM *) pr);
+                ssh_print_bignum("s", (BIGNUM *) ps);
+            }
 # endif /* DEBUG_CRYPTO */
 
             break;
-- 
2.7.4


Follow-Ups:
Re: Build libssh against openssl 1.1.0Andreas Schneider <asn@xxxxxxxxxxxxxx>
References:
Build libssh against openssl 1.1.0Jakub Jelen <jjelen@xxxxxxxxxx>
Re: Build libssh against openssl 1.1.0Aris Adamantiadis <aris@xxxxxxxxxxxx>
Re: Build libssh against openssl 1.1.0Andreas Schneider <asn@xxxxxxxxxxxxxx>
Re: Build libssh against openssl 1.1.0Andreas Schneider <asn@xxxxxxxxxxxxxx>
Archive administrator: postmaster@lists.cynapses.org