From 72096874d0b1aa03142424d71413b547f4fbd76e Mon Sep 17 00:00:00 2001 From: Kevin Darbyshire-Bryant Date: Wed, 17 Oct 2018 08:12:48 +0100 Subject: [PATCH] libssh: bump to 0.7.6 CVE-2018-10933 fix Bump from 0.7.5 to 0.7.6. Upstream changelog: Fixed CVE-2018-10933 Added support for OpenSSL 1.1 Added SHA256 support for ssh_get_publickey_hash() Fixed config parsing Fixed random memory corruption when importing pubkeys Backported upstream patches since 0.7.6 to fix interactive authentication issues amongst other things: 9d5cf209 libcrypto: Fix memory leak in evp_final() 10397321 gssapi: Set correct state after sending GSSAPI_RESPONSE (select mechanism OID) 7ad80ba1 server: Fix compile error acb0e4f4 examples: Explicitly track auth state in samplesshd-kbdint 3fe7510b messages: Check that the requested service is 'ssh-connection' 734e3ce6 server: Set correct state after sending INFO_REQUEST (Kbd Interactive) e4c6d591 packet: Add missing break in ssh_packet_incoming_filter() f81ca616 misc: Add strndup implementation if not provides by the OS Refresh patches. Remove local backport for OpenSSL 1.1 support as is now in release Remove PKG_INSTALL & CMAKE vars that are defaulted anyway Add PKG_CPE_ID:=cpe:/a:libssh:libssh for CVE tracking Remove BROKEN tag as is no longer broken Signed-off-by: Kevin Darbyshire-Bryant --- libs/libssh/Makefile | 15 +- ...-implementation-if-not-provides-by-t.patch | 83 ++ ...ng-break-in-ssh_packet_incoming_filt.patch | 24 + ...ct-state-after-sending-INFO_REQUEST-.patch | 24 + ...hat-the-requested-service-is-ssh-con.patch | 37 + ...tly-track-auth-state-in-samplesshd-k.patch | 72 + .../0006-server-Fix-compile-error.patch | 22 + ...ct-state-after-sending-GSSAPI_RESPON.patch | 24 + ...bcrypto-Fix-memory-leak-in-evp_final.patch | 24 + libs/libssh/patches/001-compile.patch | 2 +- libs/libssh/patches/005-openssl-1.1.patch | 1159 ----------------- 11 files changed, 318 insertions(+), 1168 deletions(-) create mode 100644 libs/libssh/patches/0001-misc-Add-strndup-implementation-if-not-provides-by-t.patch create mode 100644 libs/libssh/patches/0002-packet-Add-missing-break-in-ssh_packet_incoming_filt.patch create mode 100644 libs/libssh/patches/0003-server-Set-correct-state-after-sending-INFO_REQUEST-.patch create mode 100644 libs/libssh/patches/0004-messages-Check-that-the-requested-service-is-ssh-con.patch create mode 100644 libs/libssh/patches/0005-examples-Explicitly-track-auth-state-in-samplesshd-k.patch create mode 100644 libs/libssh/patches/0006-server-Fix-compile-error.patch create mode 100644 libs/libssh/patches/0007-gssapi-Set-correct-state-after-sending-GSSAPI_RESPON.patch create mode 100644 libs/libssh/patches/0008-libcrypto-Fix-memory-leak-in-evp_final.patch delete mode 100644 libs/libssh/patches/005-openssl-1.1.patch diff --git a/libs/libssh/Makefile b/libs/libssh/Makefile index e6a372ee4..6ffb70045 100644 --- a/libs/libssh/Makefile +++ b/libs/libssh/Makefile @@ -11,17 +11,18 @@ PKG_LICENSE:=LGPL-2.1+ BSD-2-Clause PKG_MAINTAINER:=Mislav Novakovic PKG_NAME:=libssh -PKG_VERSION:=0.7.5 -PKG_RELEASE:=2 +PKG_VERSION:=0.7.6 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz -PKG_SOURCE_URL:=https://red.libssh.org/attachments/download/218/ -PKG_HASH:=54e86dd5dc20e5367e58f3caab337ce37675f863f80df85b6b1614966a337095 +PKG_SOURCE_URL:=https://www.libssh.org/files/0.7/ +PKG_HASH:=1d607d3859274f755942324afb0f887ee22edd157f9596a2e69e3a28ec6d1092 + +PKG_CPE_ID:=cpe:/a:libssh:libssh CMAKE_INSTALL:=1 PKG_BUILD_PARALLEL:=1 -PKG_INSTALL:=1 PKG_USE_MIPS16:=0 include $(INCLUDE_DIR)/package.mk @@ -32,7 +33,7 @@ define Package/libssh CATEGORY:=Libraries URL:=$(PKG_SOURCE_URL) TITLE:=SSH library - DEPENDS:=+libpthread +librt +zlib +libopenssl @BROKEN + DEPENDS:=+libpthread +librt +zlib +libopenssl endef define Package/libssh/description @@ -41,8 +42,6 @@ define Package/libssh/description endef CMAKE_OPTIONS = \ - -DCMAKE_INSTALL_PREFIX:PATH=/usr \ - -DCMAKE_BUILD_TYPE:STRING=Release \ -DHAVE_STRTOULL=1 \ -DHAVE_GETADDRINFO=1 \ -DHAVE_TERMIOS_H=1 \ diff --git a/libs/libssh/patches/0001-misc-Add-strndup-implementation-if-not-provides-by-t.patch b/libs/libssh/patches/0001-misc-Add-strndup-implementation-if-not-provides-by-t.patch new file mode 100644 index 000000000..5813704e7 --- /dev/null +++ b/libs/libssh/patches/0001-misc-Add-strndup-implementation-if-not-provides-by-t.patch @@ -0,0 +1,83 @@ +From f81ca6161223e3566ce78a427571235fb6848fe9 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 29 Aug 2018 18:41:15 +0200 +Subject: [PATCH 1/8] misc: Add strndup implementation if not provides by the + OS + +Fixes T112 + +Signed-off-by: Andreas Schneider +(cherry picked from commit 247983e9820fd264cb5a59c14cc12846c028bd08) +Signed-off-by: Kevin Darbyshire-Bryant +--- + ConfigureChecks.cmake | 1 + + config.h.cmake | 3 +++ + include/libssh/priv.h | 4 ++++ + src/misc.c | 21 +++++++++++++++++++++ + 4 files changed, 29 insertions(+) + +--- a/ConfigureChecks.cmake ++++ b/ConfigureChecks.cmake +@@ -115,6 +115,7 @@ endif (NOT WITH_GCRYPT) + + check_function_exists(isblank HAVE_ISBLANK) + check_function_exists(strncpy HAVE_STRNCPY) ++check_function_exists(strndup HAVE_STRNDUP) + check_function_exists(strtoull HAVE_STRTOULL) + + if (NOT WIN32) +--- a/config.h.cmake ++++ b/config.h.cmake +@@ -103,6 +103,9 @@ + /* Define to 1 if you have the `strncpy' function. */ + #cmakedefine HAVE_STRNCPY 1 + ++/* Define to 1 if you have the `strndup' function. */ ++#cmakedefine HAVE_STRNDUP 1 ++ + /* Define to 1 if you have the `cfmakeraw' function. */ + #cmakedefine HAVE_CFMAKERAW 1 + +--- a/include/libssh/priv.h ++++ b/include/libssh/priv.h +@@ -43,6 +43,10 @@ + # endif + #endif /* !defined(HAVE_STRTOULL) */ + ++#if !defined(HAVE_STRNDUP) ++char *strndup(const char *s, size_t n); ++#endif /* ! HAVE_STRNDUP */ ++ + #ifdef HAVE_BYTESWAP_H + #include + #endif +--- a/src/misc.c ++++ b/src/misc.c +@@ -1028,6 +1028,27 @@ int ssh_match_group(const char *group, c + return 0; + } + ++#if !defined(HAVE_STRNDUP) ++char *strndup(const char *s, size_t n) ++{ ++ char *x = NULL; ++ ++ if (n + 1 < n) { ++ return NULL; ++ } ++ ++ x = malloc(n + 1); ++ if (x == NULL) { ++ return NULL; ++ } ++ ++ memcpy(x, s, n); ++ x[n] = '\0'; ++ ++ return x; ++} ++#endif /* ! HAVE_STRNDUP */ ++ + /** @} */ + + /* vim: set ts=4 sw=4 et cindent: */ diff --git a/libs/libssh/patches/0002-packet-Add-missing-break-in-ssh_packet_incoming_filt.patch b/libs/libssh/patches/0002-packet-Add-missing-break-in-ssh_packet_incoming_filt.patch new file mode 100644 index 000000000..1db276cc7 --- /dev/null +++ b/libs/libssh/patches/0002-packet-Add-missing-break-in-ssh_packet_incoming_filt.patch @@ -0,0 +1,24 @@ +From e4c6d591df6a9c34c1ff3ec9f367c7257122bef3 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 17 Oct 2018 07:23:10 +0200 +Subject: [PATCH 2/8] packet: Add missing break in ssh_packet_incoming_filter() + +CID 1396239 + +Signed-off-by: Andreas Schneider +(cherry picked from commit fe618a35dc4be3e73ddf29d0c4a96b98d3b9c48f) +Signed-off-by: Kevin Darbyshire-Bryant +--- + src/packet.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/src/packet.c ++++ b/src/packet.c +@@ -285,6 +285,7 @@ static enum ssh_packet_filter_result_e s + (session->dh_handshake_state != DH_STATE_FINISHED)) + { + rc = SSH_PACKET_DENIED; ++ break; + } + + rc = SSH_PACKET_ALLOWED; diff --git a/libs/libssh/patches/0003-server-Set-correct-state-after-sending-INFO_REQUEST-.patch b/libs/libssh/patches/0003-server-Set-correct-state-after-sending-INFO_REQUEST-.patch new file mode 100644 index 000000000..b5d011399 --- /dev/null +++ b/libs/libssh/patches/0003-server-Set-correct-state-after-sending-INFO_REQUEST-.patch @@ -0,0 +1,24 @@ +From 734e3ce6747a5ed120b93a1ff253b3fde5f20024 Mon Sep 17 00:00:00 2001 +From: Meng Tan +Date: Wed, 17 Oct 2018 14:50:08 +0200 +Subject: [PATCH 3/8] server: Set correct state after sending INFO_REQUEST (Kbd + Interactive) + +Signed-off-by: Meng Tan +Reviewed-by: Andreas Schneider +(cherry picked from commit 4ea46eecce9f4e676150fe27fec34e1570b70ace) +Signed-off-by: Kevin Darbyshire-Bryant +--- + src/server.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/src/server.c ++++ b/src/server.c +@@ -976,6 +976,7 @@ int ssh_message_auth_interactive_request + msg->session->kbdint->prompts = NULL; + msg->session->kbdint->echo = NULL; + } ++ msg->session->auth.state = SSH_AUTH_STATE_INFO; + + return rc; + } diff --git a/libs/libssh/patches/0004-messages-Check-that-the-requested-service-is-ssh-con.patch b/libs/libssh/patches/0004-messages-Check-that-the-requested-service-is-ssh-con.patch new file mode 100644 index 000000000..059a69ca2 --- /dev/null +++ b/libs/libssh/patches/0004-messages-Check-that-the-requested-service-is-ssh-con.patch @@ -0,0 +1,37 @@ +From 3fe7510b261098e3937ab5417935916a46e6727b Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Fri, 19 Oct 2018 11:40:44 +0200 +Subject: [PATCH 4/8] messages: Check that the requested service is + 'ssh-connection' + +Signed-off-by: Andreas Schneider +(cherry picked from commit 9c200d3ef4f62d724d3bae2563b81c38cc31e215) +Signed-off-by: Kevin Darbyshire-Bryant +--- + src/messages.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/src/messages.c ++++ b/src/messages.c +@@ -649,6 +649,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_ + ssh_message msg = NULL; + char *service = NULL; + char *method = NULL; ++ int cmp; + int rc; + + (void)user; +@@ -675,6 +676,13 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_ + service, method, + msg->auth_request.username); + ++ cmp = strcmp(service, "ssh-connection"); ++ if (cmp != 0) { ++ SSH_LOG(SSH_LOG_WARNING, ++ "Invalid service request: %s", ++ service); ++ goto end; ++ } + + if (strcmp(method, "none") == 0) { + msg->auth_request.method = SSH_AUTH_METHOD_NONE; diff --git a/libs/libssh/patches/0005-examples-Explicitly-track-auth-state-in-samplesshd-k.patch b/libs/libssh/patches/0005-examples-Explicitly-track-auth-state-in-samplesshd-k.patch new file mode 100644 index 000000000..10bff4359 --- /dev/null +++ b/libs/libssh/patches/0005-examples-Explicitly-track-auth-state-in-samplesshd-k.patch @@ -0,0 +1,72 @@ +From acb0e4f401440ca325e441064d2cb4b896fb9a3d Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 17 Oct 2018 17:32:54 +0200 +Subject: [PATCH 5/8] examples: Explicitly track auth state in + samplesshd-kbdint + +Signed-off-by: Andreas Schneider +(cherry picked from commit 0ff566b6dde5cd27653aa35280feceefad5d5224) +Signed-off-by: Kevin Darbyshire-Bryant +--- + examples/samplesshd-kbdint.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +--- a/examples/samplesshd-kbdint.c ++++ b/examples/samplesshd-kbdint.c +@@ -23,6 +23,7 @@ clients must be made or how a client sho + #include + #include + #include ++#include + + #define SSHD_USER "libssh" + #define SSHD_PASSWORD "libssh" +@@ -36,6 +37,7 @@ clients must be made or how a client sho + #endif + + static int port = 22; ++static bool authenticated = false; + + #ifdef WITH_PCAP + static const char *pcap_file = "debug.server.pcap"; +@@ -61,11 +63,20 @@ static void cleanup_pcap(void) { + #endif + + +-static int auth_password(const char *user, const char *password){ +- if(strcmp(user, SSHD_USER)) ++static int auth_password(const char *user, const char *password) ++{ ++ int cmp; ++ ++ cmp = strcmp(user, SSHD_USER); ++ if (cmp != 0) { + return 0; +- if(strcmp(password, SSHD_PASSWORD)) ++ } ++ cmp = strcmp(password, SSHD_PASSWORD); ++ if (cmp != 0) { + return 0; ++ } ++ ++ authenticated = true; + return 1; // authenticated + } + #ifdef HAVE_ARGP_H +@@ -200,6 +211,7 @@ static int kbdint_check_response(ssh_ses + return 0; + } + ++ authenticated = true; + return 1; + } + +@@ -328,7 +340,7 @@ int main(int argc, char **argv){ + + /* proceed to authentication */ + auth = authenticate(session); +- if(!auth){ ++ if (!auth || !authenticated) { + printf("Authentication error: %s\n", ssh_get_error(session)); + ssh_disconnect(session); + return 1; diff --git a/libs/libssh/patches/0006-server-Fix-compile-error.patch b/libs/libssh/patches/0006-server-Fix-compile-error.patch new file mode 100644 index 000000000..a60688cd0 --- /dev/null +++ b/libs/libssh/patches/0006-server-Fix-compile-error.patch @@ -0,0 +1,22 @@ +From 7ad80ba1cc48f7af1f192692d100a6255d97b843 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Wed, 24 Oct 2018 19:57:17 +0200 +Subject: [PATCH 6/8] server: Fix compile error + +Signed-off-by: Andreas Schneider +Signed-off-by: Kevin Darbyshire-Bryant +--- + src/server.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/src/server.c ++++ b/src/server.c +@@ -976,7 +976,7 @@ int ssh_message_auth_interactive_request + msg->session->kbdint->prompts = NULL; + msg->session->kbdint->echo = NULL; + } +- msg->session->auth.state = SSH_AUTH_STATE_INFO; ++ msg->session->auth_state = SSH_AUTH_STATE_INFO; + + return rc; + } diff --git a/libs/libssh/patches/0007-gssapi-Set-correct-state-after-sending-GSSAPI_RESPON.patch b/libs/libssh/patches/0007-gssapi-Set-correct-state-after-sending-GSSAPI_RESPON.patch new file mode 100644 index 000000000..b3a98046d --- /dev/null +++ b/libs/libssh/patches/0007-gssapi-Set-correct-state-after-sending-GSSAPI_RESPON.patch @@ -0,0 +1,24 @@ +From 103973215443f6e02e010114a3f7ac19eb6f3c8c Mon Sep 17 00:00:00 2001 +From: Meng Tan +Date: Thu, 25 Oct 2018 17:06:06 +0200 +Subject: [PATCH 7/8] gssapi: Set correct state after sending GSSAPI_RESPONSE + (select mechanism OID) + +Signed-off-by: Meng Tan +Reviewed-by: Andreas Schneider +(cherry picked from commit bce8d567053232debd6ec490af5a7d27e1160f39) +Signed-off-by: Kevin Darbyshire-Bryant +--- + src/gssapi.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/src/gssapi.c ++++ b/src/gssapi.c +@@ -120,6 +120,7 @@ static int ssh_gssapi_send_response(ssh_ + ssh_set_error_oom(session); + return SSH_ERROR; + } ++ session->auth_state = SSH_AUTH_STATE_GSSAPI_TOKEN; + + packet_send(session); + SSH_LOG(SSH_LOG_PACKET, diff --git a/libs/libssh/patches/0008-libcrypto-Fix-memory-leak-in-evp_final.patch b/libs/libssh/patches/0008-libcrypto-Fix-memory-leak-in-evp_final.patch new file mode 100644 index 000000000..64f6e3fb5 --- /dev/null +++ b/libs/libssh/patches/0008-libcrypto-Fix-memory-leak-in-evp_final.patch @@ -0,0 +1,24 @@ +From 9d5cf209df4c260546e1468cc15fbbbfba3097c6 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Sat, 27 Oct 2018 22:15:56 +0200 +Subject: [PATCH 8/8] libcrypto: Fix memory leak in evp_final() + +Fixes T116 + +Signed-off-by: Andreas Schneider +(cherry picked from commit a2807474621e51b386ea26ce2a01d2b1aa295c7b) +Signed-off-by: Kevin Darbyshire-Bryant +--- + src/libcrypto.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/src/libcrypto.c ++++ b/src/libcrypto.c +@@ -165,6 +165,7 @@ void evp_update(EVPCTX ctx, const void * + void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen) + { + EVP_DigestFinal(ctx, md, mdlen); ++ EVP_MD_CTX_free(ctx); + } + #endif + diff --git a/libs/libssh/patches/001-compile.patch b/libs/libssh/patches/001-compile.patch index bbc994ba6..c89179247 100644 --- a/libs/libssh/patches/001-compile.patch +++ b/libs/libssh/patches/001-compile.patch @@ -21,7 +21,7 @@ set(PACKAGE ${APPLICATION_NAME}) set(VERSION ${APPLICATION_VERSION}) -@@ -270,6 +269,8 @@ if (WITH_GSSAPI AND NOT GSSAPI_FOUND) +@@ -272,6 +271,8 @@ if (WITH_GSSAPI AND NOT GSSAPI_FOUND) endif (WITH_GSSAPI AND NOT GSSAPI_FOUND) # ENDIAN diff --git a/libs/libssh/patches/005-openssl-1.1.patch b/libs/libssh/patches/005-openssl-1.1.patch deleted file mode 100644 index a5916a575..000000000 --- a/libs/libssh/patches/005-openssl-1.1.patch +++ /dev/null @@ -1,1159 +0,0 @@ ---- a/src/libcrypto.c -+++ b/src/libcrypto.c -@@ -43,10 +43,12 @@ - #include - #include - #include -+#include "libcrypto-compat.h" - - #ifdef HAVE_OPENSSL_AES_H - #define HAS_AES - #include -+#include - #endif - #ifdef HAVE_OPENSSL_BLOWFISH_H - #define HAS_BLOWFISH -@@ -133,18 +135,20 @@ static const EVP_MD *nid_to_evpmd(int ni - 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_DigestInit(&md, evp_md); -- EVP_DigestUpdate(&md, digest, len); -- EVP_DigestFinal(&md, hash, hlen); -+ md = EVP_MD_CTX_new(); -+ 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; - } -@@ -322,32 +326,33 @@ void ssh_mac_final(unsigned char *md, ss - 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; - } -@@ -363,7 +368,8 @@ void hmac_final(HMACCTX ctx, unsigned ch - HMAC_Final(ctx,hashmacbuf,len); - - #ifndef OLD_CRYPTO -- HMAC_CTX_cleanup(ctx); -+ HMAC_CTX_free(ctx); -+ ctx = NULL; - #else - HMAC_cleanup(ctx); - #endif -@@ -455,7 +461,11 @@ static void aes_ctr128_encrypt(struct ss - * Same for num, which is being used to store the current offset in blocksize in CTR - * function. - */ -+#if OPENSSL_VERSION_NUMBER < 0x10100000L - AES_ctr128_encrypt(in, out, len, cipher->key, cipher->IV, tmp_buffer, &num); -+#else -+ CRYPTO_ctr128_encrypt(in, out, len, cipher->key, cipher->IV, tmp_buffer, &num, (block128_f)AES_encrypt); -+#endif - } - #endif /* BROKEN_AES_CTR */ - #endif /* HAS_AES */ ---- a/src/pki_crypto.c -+++ b/src/pki_crypto.c -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include "libcrypto-compat.h" - - #ifdef HAVE_OPENSSL_EC_H - #include -@@ -230,7 +231,10 @@ ssh_key pki_key_dup(const ssh_key key, i - } - - 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, i - * 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, i - * 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; -@@ -409,11 +451,30 @@ int pki_key_generate_rsa(ssh_key key, in - - int pki_key_generate_dss(ssh_key key, int parameter){ - int rc; -+#if OPENSSL_VERSION_NUMBER > 0x10100000L -+ key->dsa = DSA_new(); -+ if (key->dsa == NULL) { -+ return SSH_ERROR; -+ } -+ rc = DSA_generate_parameters_ex(key->dsa, -+ parameter, -+ NULL, /* seed */ -+ 0, /* seed_len */ -+ NULL, /* counter_ret */ -+ NULL, /* h_ret */ -+ NULL); /* cb */ -+ if (rc != 1) { -+ DSA_free(key->dsa); -+ key->dsa = NULL; -+ return SSH_ERROR; -+ } -+#else - key->dsa = DSA_generate_parameters(parameter, NULL, 0, NULL, NULL, - NULL, NULL); - if(key->dsa == NULL){ - return SSH_ERROR; - } -+#endif - rc = DSA_generate_key(key->dsa); - if (rc != 1){ - DSA_free(key->dsa); -@@ -466,51 +527,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 - { -@@ -586,7 +660,7 @@ ssh_string pki_private_key_to_pem(const - } else { - rc = PEM_write_bio_DSAPrivateKey(mem, - key->dsa, -- NULL, /* cipher */ -+ EVP_aes_128_cbc(), - NULL, /* kstr */ - 0, /* klen */ - NULL, /* auth_fn */ -@@ -611,7 +685,7 @@ ssh_string pki_private_key_to_pem(const - } else { - rc = PEM_write_bio_RSAPrivateKey(mem, - key->rsa, -- NULL, /* cipher */ -+ EVP_aes_128_cbc(), - NULL, /* kstr */ - 0, /* klen */ - NULL, /* auth_fn */ -@@ -621,8 +695,8 @@ ssh_string pki_private_key_to_pem(const - goto err; - } - break; -- case SSH_KEYTYPE_ECDSA: - #ifdef HAVE_ECC -+ case SSH_KEYTYPE_ECDSA: - if (passphrase == NULL) { - struct pem_get_password_struct pgp = { auth_fn, auth_data }; - -@@ -636,7 +710,7 @@ ssh_string pki_private_key_to_pem(const - } else { - rc = PEM_write_bio_ECPrivateKey(mem, - key->ecdsa, -- NULL, /* cipher */ -+ EVP_aes_128_cbc(), - NULL, /* kstr */ - 0, /* klen */ - NULL, /* auth_fn */ -@@ -819,43 +893,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 = make_string_bn(p); -- key->dsa->q = make_string_bn(q); -- key->dsa->g = make_string_bn(g); -- key->dsa->pub_key = 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 = make_string_bn(p); -+ bq = make_string_bn(q); -+ bg = make_string_bn(g); -+ bpub_key = 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 = make_string_bn(e); -- key->rsa->n = make_string_bn(n); -- if (key->rsa->e == NULL || -- key->rsa->n == NULL) { -- RSA_free(key->rsa); -- return SSH_ERROR; -+ be = make_string_bn(e); -+ bn = 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) -@@ -889,23 +985,26 @@ ssh_string pki_publickey_to_blob(const s - } - - switch (key->type) { -- case SSH_KEYTYPE_DSS: -- p = 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 = make_bignum_string((BIGNUM *)bp); - if (p == NULL) { - goto fail; - } - -- q = make_bignum_string(key->dsa->q); -+ q = make_bignum_string((BIGNUM *)bq); - if (q == NULL) { - goto fail; - } - -- g = make_bignum_string(key->dsa->g); -+ g = make_bignum_string((BIGNUM *)bg); - if (g == NULL) { - goto fail; - } - -- n = make_bignum_string(key->dsa->pub_key); -+ DSA_get0_key(key->dsa, &bpub_key, NULL); -+ n = make_bignum_string((BIGNUM *)bpub_key); - if (n == NULL) { - goto fail; - } -@@ -937,14 +1036,17 @@ ssh_string pki_publickey_to_blob(const s - n = NULL; - - break; -+ } - case SSH_KEYTYPE_RSA: -- case SSH_KEYTYPE_RSA1: -- e = make_bignum_string(key->rsa->e); -+ case SSH_KEYTYPE_RSA1: { -+ const BIGNUM *be, *bn; -+ RSA_get0_key(key->rsa, &bn, &be, NULL); -+ e = make_bignum_string((BIGNUM *)be); - if (e == NULL) { - goto fail; - } - -- n = make_bignum_string(key->rsa->n); -+ n = make_bignum_string((BIGNUM *)bn); - if (n == NULL) { - goto fail; - } -@@ -964,6 +1066,7 @@ ssh_string pki_publickey_to_blob(const s - n = NULL; - - break; -+ } - case SSH_KEYTYPE_ECDSA: - #ifdef HAVE_OPENSSL_ECC - rc = ssh_buffer_reinit(buffer); -@@ -1065,13 +1168,15 @@ int pki_export_pubkey_rsa1(const ssh_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; -@@ -1136,6 +1241,7 @@ static ssh_string pki_dsa_signature_to_b - { - 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; -@@ -1143,12 +1249,13 @@ static ssh_string pki_dsa_signature_to_b - ssh_string s; - int s_len, s_offset_in, s_offset_out; - -- r = make_bignum_string(sig->dsa_sig->r); -+ DSA_SIG_get0(sig->dsa_sig, &pr, &ps); -+ r = make_bignum_string((BIGNUM *)pr); - if (r == NULL) { - return NULL; - } - -- s = make_bignum_string(sig->dsa_sig->s); -+ s = make_bignum_string((BIGNUM *)ps); - if (s == NULL) { - ssh_string_free(r); - return NULL; -@@ -1201,13 +1308,15 @@ ssh_string pki_signature_to_blob(const s - ssh_string s; - ssh_buffer b; - int rc; -+ const BIGNUM *pr, *ps; - - b = ssh_buffer_new(); - if (b == NULL) { - return NULL; - } - -- r = make_bignum_string(sig->ecdsa_sig->r); -+ ECDSA_SIG_get0(sig->ecdsa_sig, &pr, &ps); -+ r = make_bignum_string((BIGNUM *)pr); - if (r == NULL) { - ssh_buffer_free(b); - return NULL; -@@ -1219,7 +1328,7 @@ ssh_string pki_signature_to_blob(const s - return NULL; - } - -- s = make_bignum_string(sig->ecdsa_sig->s); -+ s = make_bignum_string((BIGNUM *)ps); - if (s == NULL) { - ssh_buffer_free(b); - return NULL; -@@ -1324,6 +1433,7 @@ ssh_signature pki_signature_from_blob(co - ssh_string s; - size_t len; - int rc; -+ BIGNUM *pr = NULL, *ps = NULL; - - sig = ssh_signature_new(); - if (sig == NULL) { -@@ -1363,9 +1473,9 @@ ssh_signature pki_signature_from_blob(co - } - ssh_string_fill(r, ssh_string_data(sig_blob), 20); - -- sig->dsa_sig->r = make_string_bn(r); -+ pr = make_string_bn(r); - ssh_string_free(r); -- if (sig->dsa_sig->r == NULL) { -+ if (pr == NULL) { - ssh_signature_free(sig); - return NULL; - } -@@ -1377,9 +1487,15 @@ ssh_signature pki_signature_from_blob(co - } - ssh_string_fill(s, (char *)ssh_string_data(sig_blob) + 20, 20); - -- sig->dsa_sig->s = make_string_bn(s); -+ ps = 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; - } -@@ -1427,17 +1543,17 @@ ssh_signature pki_signature_from_blob(co - ssh_print_hexa("r", ssh_string_data(r), ssh_string_len(r)); - #endif - -- make_string_bn_inplace(r, sig->ecdsa_sig->r); -+ pr = 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; - } - - s = buffer_get_ssh_string(b); -- rlen = buffer_get_rest_len(b); -+ rlen = buffer_get_len(b); - ssh_buffer_free(b); - if (s == NULL) { - ssh_signature_free(sig); -@@ -1448,10 +1564,16 @@ ssh_signature pki_signature_from_blob(co - ssh_print_hexa("s", ssh_string_data(s), ssh_string_len(s)); - #endif - -- make_string_bn_inplace(s, sig->ecdsa_sig->s); -+ ps = 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; - } -@@ -1578,8 +1700,12 @@ ssh_signature pki_do_sign(const ssh_key - } - - #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; -@@ -1601,8 +1727,12 @@ ssh_signature pki_do_sign(const ssh_key - } - - # 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->ecdsa_sig, &pr, &ps); -+ ssh_print_bignum("r", (BIGNUM *) pr); -+ ssh_print_bignum("s", (BIGNUM *) ps); -+ } - # endif /* DEBUG_CRYPTO */ - - break; ---- a/src/CMakeLists.txt -+++ b/src/CMakeLists.txt -@@ -164,6 +164,9 @@ else (WITH_GCRYPT) - ${libssh_SRCS} - pki_crypto.c - ) -+ if(OPENSSL_VERSION VERSION_LESS "1.1.0") -+ set(libssh_SRCS ${libssh_SRCS} libcrypto-compat.c) -+ endif() - endif (WITH_GCRYPT) - - if (WITH_SFTP) ---- /dev/null -+++ b/src/libcrypto-compat.c -@@ -0,0 +1,334 @@ -+/* -+ * 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 "config.h" -+ -+#include -+#include -+#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); -+#if OPENSSL_VERSION_NUMBER > 0x10100000L -+ EVP_MD_CTX_free(&ctx->i_ctx); -+ EVP_MD_CTX_free(&ctx->o_ctx); -+ EVP_MD_CTX_free(&ctx->md_ctx); -+#endif -+ OPENSSL_free(ctx); -+ } -+} -+ -+int HMAC_CTX_reset(HMAC_CTX *ctx) -+{ -+ HMAC_CTX_init(ctx); -+ return 1; -+} -+ -+#ifndef HAVE_OPENSSL_EVP_CIPHER_CTX_NEW -+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); -+} -+#endif ---- /dev/null -+++ b/src/libcrypto-compat.h -@@ -0,0 +1,42 @@ -+#ifndef LIBCRYPTO_COMPAT_H -+#define LIBCRYPTO_COMPAT_H -+ -+#include -+#if OPENSSL_VERSION_NUMBER < 0x10100000L -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+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 */