Use generic APIs for (HMAC-)MD5/SHA1 and RNG, and implement them via OpenSSL/libgcrypt.

This commit is contained in:
Simon Josefsson
2007-01-15 21:12:00 +00:00
parent 362d3466cf
commit 79761a6455
10 changed files with 231 additions and 79 deletions

View File

@@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS = foreign nostdinc
libssh2_la_SOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c \ libssh2_la_SOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c \
misc.c packet.c publickey.c scp.c session.c sftp.c userauth.c \ misc.c packet.c publickey.c scp.c session.c sftp.c userauth.c \
libssh2_priv.h libssh2_priv.h openssl.h libgcrypt.h
EXTRA_DIST = libssh2_config.h.in EXTRA_DIST = libssh2_config.h.in

View File

@@ -36,7 +36,6 @@
*/ */
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include <openssl/rand.h>
#ifndef WIN32 #ifndef WIN32
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -637,7 +636,7 @@ LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_
int i; int i;
unsigned char buffer[LIBSSH2_X11_RANDOM_COOKIE_LEN / 2]; unsigned char buffer[LIBSSH2_X11_RANDOM_COOKIE_LEN / 2];
RAND_bytes(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); libssh2_random(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2);
for (i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) { for (i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) {
snprintf((char *)s + (i * 2), 2, "%02X", buffer[i]); snprintf((char *)s + (i * 2), 2, "%02X", buffer[i]);
} }

View File

@@ -37,29 +37,27 @@
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/sha.h>
#include <openssl/rand.h>
/* TODO: Switch this to an inline and handle alloc() failures */ /* TODO: Switch this to an inline and handle alloc() failures */
/* Helper macro called from libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange */ /* Helper macro called from libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange */
#define LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(value, reqlen, version) \ #define LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(value, reqlen, version) \
{ \ { \
SHA_CTX hash; \ libssh2_sha1_ctx hash; \
unsigned long len = 0; \ unsigned long len = 0; \
if (!(value)) { \ if (!(value)) { \
value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH); \ value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH); \
} \ } \
while (len < reqlen) { \ while (len < reqlen) { \
SHA1_Init(&hash); \ libssh2_sha1_init(&hash); \
SHA1_Update(&hash, k_value, k_value_len); \ libssh2_sha1_update(hash, k_value, k_value_len); \
SHA1_Update(&hash, h_sig_comp, SHA_DIGEST_LENGTH); \ libssh2_sha1_update(hash, h_sig_comp, SHA_DIGEST_LENGTH); \
if (len > 0) { \ if (len > 0) { \
SHA1_Update(&hash, value, len); \ libssh2_sha1_update(hash, value, len); \
} else { \ } else { \
SHA1_Update(&hash, (version), 1); \ libssh2_sha1_update(hash, (version), 1); \
SHA1_Update(&hash, session->session_id, session->session_id_len); \ libssh2_sha1_update(hash, session->session_id, session->session_id_len); \
} \ } \
SHA1_Final((value) + len, &hash); \ libssh2_sha1_final(hash, (value) + len); \
len += SHA_DIGEST_LENGTH; \ len += SHA_DIGEST_LENGTH; \
} \ } \
} }
@@ -81,7 +79,7 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
BIGNUM *k = BN_new(); /* The shared secret: f^x mod p */ BIGNUM *k = BN_new(); /* The shared secret: f^x mod p */
unsigned char *s, *f_value, *k_value = NULL, *h_sig; unsigned char *s, *f_value, *k_value = NULL, *h_sig;
unsigned long f_value_len, k_value_len, h_sig_len; unsigned long f_value_len, k_value_len, h_sig_len;
SHA_CTX exchange_hash; libssh2_sha1_ctx exchange_hash;
/* Generate x and e */ /* Generate x and e */
BN_rand(x, group_order, 0, -1); BN_rand(x, group_order, 0, -1);
@@ -159,11 +157,11 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
#ifndef OPENSSL_NO_MD5 #ifndef OPENSSL_NO_MD5
{ {
MD5_CTX fingerprint_ctx; libssh2_md5_ctx fingerprint_ctx;
MD5_Init(&fingerprint_ctx); libssh2_md5_init(&fingerprint_ctx);
MD5_Update(&fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); libssh2_md5_update(fingerprint_ctx, session->server_hostkey, session->server_hostkey_len);
MD5_Final(session->server_hostkey_md5, &fingerprint_ctx); libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5);
} }
#ifdef LIBSSH2_DEBUG_KEX #ifdef LIBSSH2_DEBUG_KEX
{ {
@@ -179,11 +177,11 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
#endif /* ! OPENSSL_NO_MD5 */ #endif /* ! OPENSSL_NO_MD5 */
{ {
SHA_CTX fingerprint_ctx; libssh2_sha1_ctx fingerprint_ctx;
SHA1_Init(&fingerprint_ctx); libssh2_sha1_init(&fingerprint_ctx);
SHA1_Update(&fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); libssh2_sha1_update (fingerprint_ctx, session->server_hostkey, session->server_hostkey_len);
SHA1_Final(session->server_hostkey_sha1, &fingerprint_ctx); libssh2_sha1_final(fingerprint_ctx, session->server_hostkey_sha1);
} }
#ifdef LIBSSH2_DEBUG_KEX #ifdef LIBSSH2_DEBUG_KEX
{ {
@@ -231,36 +229,36 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
BN_bn2bin(k, k_value + 5); BN_bn2bin(k, k_value + 5);
} }
SHA1_Init(&exchange_hash); libssh2_sha1_init(&exchange_hash);
if (session->local.banner) { if (session->local.banner) {
libssh2_htonu32(h_sig_comp, libssh2_htonu32(h_sig_comp,
strlen((char *)session->local.banner) - 2); strlen((char *)session->local.banner) - 2);
SHA1_Update(&exchange_hash, h_sig_comp, 4); libssh2_sha1_update(exchange_hash, h_sig_comp, 4);
SHA1_Update(&exchange_hash, (char *)session->local.banner, libssh2_sha1_update(exchange_hash, (char *)session->local.banner,
strlen((char *)session->local.banner) - 2); strlen((char *)session->local.banner) - 2);
} else { } else {
libssh2_htonu32(h_sig_comp, sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); libssh2_htonu32(h_sig_comp, sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1);
SHA1_Update(&exchange_hash, h_sig_comp, 4); libssh2_sha1_update(exchange_hash, h_sig_comp, 4);
SHA1_Update(&exchange_hash, LIBSSH2_SSH_DEFAULT_BANNER, libssh2_sha1_update(exchange_hash, LIBSSH2_SSH_DEFAULT_BANNER,
sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1);
} }
libssh2_htonu32(h_sig_comp, strlen((char *)session->remote.banner)); libssh2_htonu32(h_sig_comp, strlen((char *)session->remote.banner));
SHA1_Update(&exchange_hash, h_sig_comp, 4); libssh2_sha1_update(exchange_hash, h_sig_comp, 4);
SHA1_Update(&exchange_hash, session->remote.banner, libssh2_sha1_update(exchange_hash, session->remote.banner,
strlen((char *)session->remote.banner)); strlen((char *)session->remote.banner));
libssh2_htonu32(h_sig_comp, session->local.kexinit_len); libssh2_htonu32(h_sig_comp, session->local.kexinit_len);
SHA1_Update(&exchange_hash, h_sig_comp, 4); libssh2_sha1_update(exchange_hash, h_sig_comp, 4);
SHA1_Update(&exchange_hash, session->local.kexinit, session->local.kexinit_len); libssh2_sha1_update(exchange_hash, session->local.kexinit, session->local.kexinit_len);
libssh2_htonu32(h_sig_comp, session->remote.kexinit_len); libssh2_htonu32(h_sig_comp, session->remote.kexinit_len);
SHA1_Update(&exchange_hash, h_sig_comp, 4); libssh2_sha1_update(exchange_hash, h_sig_comp, 4);
SHA1_Update(&exchange_hash, session->remote.kexinit, session->remote.kexinit_len); libssh2_sha1_update(exchange_hash, session->remote.kexinit, session->remote.kexinit_len);
libssh2_htonu32(h_sig_comp, session->server_hostkey_len); libssh2_htonu32(h_sig_comp, session->server_hostkey_len);
SHA1_Update(&exchange_hash, h_sig_comp, 4); libssh2_sha1_update(exchange_hash, h_sig_comp, 4);
SHA1_Update(&exchange_hash, session->server_hostkey, session->server_hostkey_len); libssh2_sha1_update(exchange_hash, session->server_hostkey, session->server_hostkey_len);
if (packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) { if (packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) {
/* diffie-hellman-group-exchange hashes additional fields */ /* diffie-hellman-group-exchange hashes additional fields */
@@ -268,26 +266,26 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
libssh2_htonu32(h_sig_comp, LIBSSH2_DH_GEX_MINGROUP); libssh2_htonu32(h_sig_comp, LIBSSH2_DH_GEX_MINGROUP);
libssh2_htonu32(h_sig_comp + 4, LIBSSH2_DH_GEX_OPTGROUP); libssh2_htonu32(h_sig_comp + 4, LIBSSH2_DH_GEX_OPTGROUP);
libssh2_htonu32(h_sig_comp + 8, LIBSSH2_DH_GEX_MAXGROUP); libssh2_htonu32(h_sig_comp + 8, LIBSSH2_DH_GEX_MAXGROUP);
SHA1_Update(&exchange_hash, h_sig_comp, 12); libssh2_sha1_update(exchange_hash, h_sig_comp, 12);
#else #else
libssh2_htonu32(h_sig_comp, LIBSSH2_DH_GEX_OPTGROUP); libssh2_htonu32(h_sig_comp, LIBSSH2_DH_GEX_OPTGROUP);
SHA1_Update(&exchange_hash, h_sig_comp, 4); libssh2_sha1_update(exchange_hash, h_sig_comp, 4);
#endif #endif
} }
if (midhash) { if (midhash) {
SHA1_Update(&exchange_hash, midhash, midhash_len); libssh2_sha1_update(exchange_hash, midhash, midhash_len);
} }
SHA1_Update(&exchange_hash, e_packet + 1, e_packet_len - 1); libssh2_sha1_update(exchange_hash, e_packet + 1, e_packet_len - 1);
libssh2_htonu32(h_sig_comp, f_value_len); libssh2_htonu32(h_sig_comp, f_value_len);
SHA1_Update(&exchange_hash, h_sig_comp, 4); libssh2_sha1_update(exchange_hash, h_sig_comp, 4);
SHA1_Update(&exchange_hash, f_value, f_value_len); libssh2_sha1_update(exchange_hash, f_value, f_value_len);
SHA1_Update(&exchange_hash, k_value, k_value_len); libssh2_sha1_update(exchange_hash, k_value, k_value_len);
SHA1_Final(h_sig_comp, &exchange_hash); libssh2_sha1_final(exchange_hash, h_sig_comp);
if (session->hostkey->sig_verify(session, h_sig, h_sig_len, h_sig_comp, 20, &session->server_hostkey_abstract)) { if (session->hostkey->sig_verify(session, h_sig, h_sig_len, h_sig_comp, 20, &session->server_hostkey_abstract)) {
libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, "Unable to verify hostkey signature", 0); libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, "Unable to verify hostkey signature", 0);
@@ -756,7 +754,7 @@ static int libssh2_kexinit(LIBSSH2_SESSION *session)
*(s++) = SSH_MSG_KEXINIT; *(s++) = SSH_MSG_KEXINIT;
RAND_bytes(s, 16); libssh2_random(s, 16);
s += 16; s += 16;
/* Ennumerating through these lists twice is probably (certainly?) inefficient from a CPU standpoint, but it saves multiple malloc/realloc calls */ /* Ennumerating through these lists twice is probably (certainly?) inefficient from a CPU standpoint, but it saves multiple malloc/realloc calls */

79
src/libgcrypt.h Normal file
View File

@@ -0,0 +1,79 @@
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
* Author: Simon Josefsson
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include <gcrypt.h>
#define MD5_DIGEST_LENGTH 16
#define SHA_DIGEST_LENGTH 20
#define libssh2_random(buf, len) \
(gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 1)
#define libssh2_sha1_ctx gcry_md_hd_t
#define libssh2_sha1_init(ctx) gcry_md_open (ctx, GCRY_MD_SHA1, 0);
#define libssh2_sha1_update(ctx, data, len) gcry_md_write (ctx, data, len)
#define libssh2_sha1_final(ctx, out) \
memcpy (out, gcry_md_read (ctx, 0), 20), gcry_md_close (ctx)
#define libssh2_sha1(message, len, out) \
gcry_md_hash_buffer (GCRY_MD_SHA1, out, message, len)
#define libssh2_md5_ctx gcry_md_hd_t
#define libssh2_md5_init(ctx) gcry_md_open (ctx, GCRY_MD_MD5, 0);
#define libssh2_md5_update(ctx, data, len) gcry_md_write (ctx, data, len)
#define libssh2_md5_final(ctx, out) \
memcpy (out, gcry_md_read (ctx, 0), 20), gcry_md_close (ctx)
#define libssh2_md5(message, len, out) \
gcry_md_hash_buffer (GCRY_MD_MD5, out, message, len)
#define libssh2_hmac_ctx gcry_md_hd_t
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
gcry_md_open (ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey (*ctx, key, keylen)
#define libssh2_hmac_md5_init(ctx, key, keylen) \
gcry_md_open (ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey (*ctx, key, keylen)
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
gcry_md_open (ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey (*ctx, key, keylen)
#define libssh2_hmac_update(ctx, data, datalen) \
gcry_md_write (ctx, data, datalen)
#define libssh2_hmac_final(ctx, data) \
memcpy (data, gcry_md_read (ctx, 0), \
gcry_md_get_algo_dlen (gcry_md_get_algo (ctx)))
#define libssh2_hmac_cleanup(ctx) gcry_md_close (*ctx);
#define libssh2_crypto_init() gcry_control (GCRYCTL_DISABLE_SECMEM)

View File

@@ -45,10 +45,11 @@
#ifndef WIN32 #ifndef WIN32
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
#include <openssl/evp.h>
#include <openssl/sha.h> #if LIBSSH2_LIBGCRYPT
#ifndef OPENSSL_NO_MD5 #include "libgcrypt.h"
#include <openssl/md5.h> #else
#include "openssl.h"
#endif #endif
#define LIBSSH2_ALLOC(session, count) session->alloc((count), &(session)->abstract) #define LIBSSH2_ALLOC(session, count) session->alloc((count), &(session)->abstract)

View File

@@ -36,7 +36,6 @@
*/ */
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include <openssl/hmac.h>
#ifdef LIBSSH2_MAC_NONE #ifdef LIBSSH2_MAC_NONE
/* {{{ libssh2_mac_none_MAC /* {{{ libssh2_mac_none_MAC
@@ -95,20 +94,20 @@ static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned
const unsigned char *packet, unsigned long packet_len, const unsigned char *packet, unsigned long packet_len,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) const unsigned char *addtl, unsigned long addtl_len, void **abstract)
{ {
HMAC_CTX ctx; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
(void)session; (void)session;
libssh2_htonu32(seqno_buf, seqno); libssh2_htonu32(seqno_buf, seqno);
HMAC_Init(&ctx, *abstract, 20, EVP_sha1()); libssh2_hmac_sha1_init(&ctx, *abstract, 20);
HMAC_Update(&ctx, seqno_buf, 4); libssh2_hmac_update(ctx, seqno_buf, 4);
HMAC_Update(&ctx, packet, packet_len); libssh2_hmac_update(ctx, packet, packet_len);
if (addtl && addtl_len) { if (addtl && addtl_len) {
HMAC_Update(&ctx, addtl, addtl_len); libssh2_hmac_update(ctx, addtl, addtl_len);
} }
HMAC_Final(&ctx, buf, NULL); libssh2_hmac_final(ctx, buf);
HMAC_cleanup(&ctx); libssh2_hmac_cleanup(&ctx);
return 0; return 0;
} }
@@ -155,19 +154,19 @@ static int libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION *session, unsigned c
const unsigned char *packet, unsigned long packet_len, const unsigned char *packet, unsigned long packet_len,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) const unsigned char *addtl, unsigned long addtl_len, void **abstract)
{ {
HMAC_CTX ctx; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
libssh2_htonu32(seqno_buf, seqno); libssh2_htonu32(seqno_buf, seqno);
HMAC_Init(&ctx, *abstract, 16, EVP_md5()); libssh2_hmac_md5_init(&ctx, *abstract, 16);
HMAC_Update(&ctx, seqno_buf, 4); libssh2_hmac_update(ctx, seqno_buf, 4);
HMAC_Update(&ctx, packet, packet_len); libssh2_hmac_update(ctx, packet, packet_len);
if (addtl && addtl_len) { if (addtl && addtl_len) {
HMAC_Update(&ctx, addtl, addtl_len); libssh2_hmac_update(ctx, addtl, addtl_len);
} }
HMAC_Final(&ctx, buf, NULL); libssh2_hmac_final(ctx, buf);
HMAC_cleanup(&ctx); libssh2_hmac_cleanup(&ctx);
return 0; return 0;
} }
@@ -215,19 +214,19 @@ static int libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION *session, unsi
const unsigned char *packet, unsigned long packet_len, const unsigned char *packet, unsigned long packet_len,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) const unsigned char *addtl, unsigned long addtl_len, void **abstract)
{ {
HMAC_CTX ctx; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
libssh2_htonu32(seqno_buf, seqno); libssh2_htonu32(seqno_buf, seqno);
HMAC_Init(&ctx, *abstract, 20, EVP_ripemd160()); libssh2_hmac_ripemd160_init(&ctx, *abstract, 20);
HMAC_Update(&ctx, seqno_buf, 4); libssh2_hmac_update(ctx, seqno_buf, 4);
HMAC_Update(&ctx, packet, packet_len); libssh2_hmac_update(ctx, packet, packet_len);
if (addtl && addtl_len) { if (addtl && addtl_len) {
HMAC_Update(&ctx, addtl, addtl_len); libssh2_hmac_update(ctx, addtl, addtl_len);
} }
HMAC_Final(&ctx, buf, NULL); libssh2_hmac_final(ctx, buf);
HMAC_cleanup(&ctx); libssh2_hmac_cleanup(&ctx);
return 0; return 0;
} }

74
src/openssl.h Normal file
View File

@@ -0,0 +1,74 @@
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
* Author: Simon Josefsson
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#ifndef OPENSSL_NO_SHA
#include <openssl/sha.h>
#endif
#ifndef OPENSSL_NO_MD5
#include <openssl/md5.h>
#endif
#include <openssl/evp.h>
#include <openssl/hmac.h>
#define libssh2_random(buf, len) \
RAND_bytes ((buf), (len))
#define libssh2_sha1_ctx SHA_CTX
#define libssh2_sha1_init(ctx) SHA1_Init(ctx)
#define libssh2_sha1_update(ctx, data, len) SHA1_Update(&(ctx), data, len)
#define libssh2_sha1_final(ctx, out) SHA1_Final(out, &(ctx))
#define libssh2_sha1(message, len, out) SHA1(message, len, out)
#define libssh2_md5_ctx MD5_CTX
#define libssh2_md5_init(ctx) MD5_Init(ctx)
#define libssh2_md5_update(ctx, data, len) MD5_Update(&(ctx), data, len)
#define libssh2_md5_final(ctx, out) MD5_Final(out, &(ctx))
#define libssh2_md5(message, len, out) MD5(message, len, out)
#define libssh2_hmac_ctx HMAC_CTX
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
HMAC_Init(ctx, key, keylen, EVP_sha1())
#define libssh2_hmac_md5_init(ctx, key, keylen) \
HMAC_Init(ctx, key, keylen, EVP_md5())
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
HMAC_Init(ctx, key, keylen, EVP_ripemd160())
#define libssh2_hmac_update(ctx, data, datalen) \
HMAC_Update(&(ctx), data, datalen)
#define libssh2_hmac_final(ctx, data) HMAC_Final(&(ctx), data, NULL)
#define libssh2_hmac_cleanup(ctx) HMAC_cleanup(ctx)
#define libssh2_crypto_init() 1

View File

@@ -41,7 +41,6 @@
#ifndef WIN32 #ifndef WIN32
#include <unistd.h> #include <unistd.h>
#endif #endif
#include <openssl/rand.h>
/* Needed for struct iovec on some platforms */ /* Needed for struct iovec on some platforms */
#ifdef HAVE_SYS_UIO_H #ifdef HAVE_SYS_UIO_H
@@ -1224,7 +1223,7 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
/* Copy packet to encoding buffer */ /* Copy packet to encoding buffer */
memcpy(encbuf, buf, 5); memcpy(encbuf, buf, 5);
memcpy(encbuf + 5, data, data_len); memcpy(encbuf + 5, data, data_len);
RAND_bytes(encbuf + 5 + data_len, padding_length); libssh2_random(encbuf + 5 + data_len, padding_length);
if (free_data) { if (free_data) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }

View File

@@ -254,6 +254,8 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "New session resource allocated"); _libssh2_debug(session, LIBSSH2_DBG_TRANS, "New session resource allocated");
#endif #endif
libssh2_crypto_init ();
return session; return session;
} }
/* }}} */ /* }}} */

View File

@@ -38,6 +38,7 @@
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include <ctype.h> #include <ctype.h>
#include <stdio.h>
/* Needed for struct iovec on some platforms */ /* Needed for struct iovec on some platforms */
#ifdef HAVE_SYS_UIO_H #ifdef HAVE_SYS_UIO_H