Commit e5168177 authored by Hilko Bengen's avatar Hilko Bengen

Add patch to implement OpenSSL 1.1 compatibility

(upstream commit 1c2f805e65e2e1231ecbe2ba1e5d83245c240da3)
parent 95eea548
ncrack (0.6-1) UNRELEASED; urgency=medium
ncrack (0.6-1) unstable; urgency=medium
* Team upload
[ Marcos Fouces ]
* New upstream version 0.6
......@@ -7,8 +9,12 @@ ncrack (0.6-1) UNRELEASED; urgency=medium
[ Hilko Bengen ]
* Patch opensshlib/configure so OpenSSL 1.1 is recognized
(upstream commit 150b06b53a78b6a334f1147504ed6218293f3318)
* Add patch to implement OpenSSL 1.1 compatibility
(upstream commit 1c2f805e65e2e1231ecbe2ba1e5d83245c240da3)
* Closes: #844303
-- Hilko Bengen <bengen@debian.org> Mon, 11 Dec 2017 17:29:27 +0100
-- Hilko Bengen <bengen@debian.org> Sun, 14 Jan 2018 18:03:21 +0100
ncrack (0.5-6) unstable; urgency=high
......
......@@ -3,7 +3,7 @@ Section: net
Priority: optional
Maintainer: Debian Security Tools Packaging Team <pkg-security-team@lists.alioth.debian.org>
Uploaders: Marcos Fouces <marcos.fouces@gmail.com>
Build-Depends: debhelper (>= 10), libssl1.0-dev, zlib1g-dev
Build-Depends: debhelper (>= 10), libssl-dev (>= 1.1), zlib1g-dev
Standards-Version: 4.1.1
Homepage: http://nmap.org/ncrack/
Vcs-Git: https://anonscm.debian.org/git/pkg-security/ncrack.git
......
Index: ncrack/crypto.cc
===================================================================
--- ncrack.orig/crypto.cc
+++ ncrack/crypto.cc
@@ -418,28 +418,27 @@ void rsa_encrypt(uint8_t *input, uint8_t
uint8_t *mod_bin, uint32_t mod_size, uint8_t *exp_bin)
{
uint8_t input_temp[256];
- BIGNUM val1, val2, bn_mod, bn_exp;
- BN_init(&bn_mod); BN_init(&bn_exp); BN_init(&val1); BN_init(&val2);
+ BIGNUM *val1 = BN_new(), *val2 = BN_new(), *bn_mod = BN_new(), *bn_exp = BN_new();
BN_CTX *bn_ctx = BN_CTX_new();
memcpy(input_temp, input, length);
mem_reverse(input_temp, length);
mem_reverse(mod_bin, mod_size);
mem_reverse(exp_bin, 4);
- BN_bin2bn(input_temp, length, &val1);
- BN_bin2bn(exp_bin, 4, &bn_exp);
- BN_bin2bn(mod_bin, mod_size, &bn_mod);
- BN_mod_exp(&val2, &val1, &bn_exp, &bn_mod, bn_ctx);
- int output_length = BN_bn2bin(&val2, output);
+ BN_bin2bn(input_temp, length, val1);
+ BN_bin2bn(exp_bin, 4, bn_exp);
+ BN_bin2bn(mod_bin, mod_size, bn_mod);
+ BN_mod_exp(val2, val1, bn_exp, bn_mod, bn_ctx);
+ int output_length = BN_bn2bin(val2, output);
mem_reverse(output, output_length);
if (output_length < (int) mod_size)
memset(output + output_length, 0, mod_size - output_length);
BN_CTX_free(bn_ctx);
- BN_clear_free(&val1);
- BN_free(&val2);
- BN_free(&bn_mod);
- BN_free(&bn_exp);
+ BN_clear_free(val1);
+ BN_free(val2);
+ BN_free(bn_mod);
+ BN_free(bn_exp);
}
Index: ncrack/modules/ncrack_ssh.cc
===================================================================
--- ncrack.orig/modules/ncrack_ssh.cc
+++ ncrack/modules/ncrack_ssh.cc
@@ -577,8 +577,8 @@ ssh_free(Connection *con)
}
}
- EVP_CIPHER_CTX_cleanup(&p->receive_context.evp);
- EVP_CIPHER_CTX_cleanup(&p->send_context.evp);
+ EVP_CIPHER_CTX_free(p->receive_context.evp);
+ EVP_CIPHER_CTX_free(p->send_context.evp);
buffer_free(p->input);
buffer_free(p->output);
Index: ncrack/opensshlib/cipher-3des1.c
===================================================================
--- ncrack.orig/opensshlib/cipher-3des1.c
+++ ncrack/opensshlib/cipher-3des1.c
@@ -42,7 +42,7 @@
*/
struct ssh1_3des_ctx
{
- EVP_CIPHER_CTX k1, k2, k3;
+ EVP_CIPHER_CTX *k1, *k2, *k3;
};
const EVP_CIPHER * evp_ssh1_3des(void);
@@ -63,7 +63,7 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, cons
if (key == NULL)
return 1;
if (enc == -1)
- enc = ctx->encrypt;
+ enc = EVP_CIPHER_CTX_encrypting(ctx);
k1 = k2 = k3 = (u_char *) key;
k2 += 8;
if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
@@ -72,12 +72,15 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, cons
else
k1 += 16;
}
- EVP_CIPHER_CTX_init(&c->k1);
- EVP_CIPHER_CTX_init(&c->k2);
- EVP_CIPHER_CTX_init(&c->k3);
- if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
- EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
- EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
+ c->k1 = EVP_CIPHER_CTX_new();
+ c->k2 = EVP_CIPHER_CTX_new();
+ c->k3 = EVP_CIPHER_CTX_new();
+ if (EVP_CipherInit(c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
+ EVP_CipherInit(c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
+ EVP_CipherInit(c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
+ EVP_CIPHER_CTX_free(c->k1);
+ EVP_CIPHER_CTX_free(c->k2);
+ EVP_CIPHER_CTX_free(c->k3);
explicit_bzero(c, sizeof(*c));
free(c);
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
@@ -93,9 +96,9 @@ ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_cha
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
return 0;
- if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
- EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
- EVP_Cipher(&c->k3, dest, dest, len) == 0)
+ if (EVP_Cipher(c->k1, dest, (u_char *)src, len) == 0 ||
+ EVP_Cipher(c->k2, dest, dest, len) == 0 ||
+ EVP_Cipher(c->k3, dest, dest, len) == 0)
return 0;
return 1;
}
@@ -106,9 +109,9 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
struct ssh1_3des_ctx *c;
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
- EVP_CIPHER_CTX_cleanup(&c->k1);
- EVP_CIPHER_CTX_cleanup(&c->k2);
- EVP_CIPHER_CTX_cleanup(&c->k3);
+ EVP_CIPHER_CTX_free(c->k1);
+ EVP_CIPHER_CTX_free(c->k2);
+ EVP_CIPHER_CTX_free(c->k3);
explicit_bzero(c, sizeof(*c));
free(c);
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
@@ -126,30 +129,29 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int do
if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
return SSH_ERR_INTERNAL_ERROR;
if (doset) {
- memcpy(c->k1.iv, iv, 8);
- memcpy(c->k2.iv, iv + 8, 8);
- memcpy(c->k3.iv, iv + 16, 8);
+ // FIXME(hb) Is there a saner way to do this?
+ memcpy(EVP_CIPHER_CTX_iv_noconst(c->k1), iv, 8);
+ memcpy(EVP_CIPHER_CTX_iv_noconst(c->k2), iv + 8, 8);
+ memcpy(EVP_CIPHER_CTX_iv_noconst(c->k3), iv + 16, 8);
} else {
- memcpy(iv, c->k1.iv, 8);
- memcpy(iv + 8, c->k2.iv, 8);
- memcpy(iv + 16, c->k3.iv, 8);
+ memcpy(iv, EVP_CIPHER_CTX_iv(c->k1), 8);
+ memcpy(iv + 8, EVP_CIPHER_CTX_iv(c->k2), 8);
+ memcpy(iv + 16, EVP_CIPHER_CTX_iv(c->k3), 8);
}
return 0;
}
+static EVP_CIPHER *ssh1_3des;
+
const EVP_CIPHER *
evp_ssh1_3des(void)
{
- static EVP_CIPHER ssh1_3des;
+ ssh1_3des = EVP_CIPHER_meth_new(NID_undef, 8, 16);
- memset(&ssh1_3des, 0, sizeof(ssh1_3des));
- ssh1_3des.nid = NID_undef;
- ssh1_3des.block_size = 8;
- ssh1_3des.iv_len = 0;
- ssh1_3des.key_len = 16;
- ssh1_3des.init = ssh1_3des_init;
- ssh1_3des.cleanup = ssh1_3des_cleanup;
- ssh1_3des.do_cipher = ssh1_3des_cbc;
- ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
- return &ssh1_3des;
+ EVP_CIPHER_meth_set_iv_length(ssh1_3des, 0);
+ EVP_CIPHER_meth_set_init(ssh1_3des, ssh1_3des_init);
+ EVP_CIPHER_meth_set_cleanup(ssh1_3des, ssh1_3des_cleanup);
+ EVP_CIPHER_meth_set_do_cipher(ssh1_3des, ssh1_3des_cbc);
+ EVP_CIPHER_meth_set_flags(ssh1_3des, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH);
+ return ssh1_3des;
}
Index: ncrack/opensshlib/cipher-bf1.c
===================================================================
--- ncrack.orig/opensshlib/cipher-bf1.c
+++ ncrack/opensshlib/cipher-bf1.c
@@ -70,34 +70,33 @@ static void bf_ssh1_init (EVP_CIPHER_CTX
}
#endif
-static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *,
+static int (*orig_do_cipher)(EVP_CIPHER_CTX *, u_char *,
const u_char *, LIBCRYPTO_EVP_INL_TYPE) = NULL;
static int
-bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in,
+bf_ssh1_do_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in,
LIBCRYPTO_EVP_INL_TYPE len)
{
int ret;
swap_bytes(in, out, len);
- ret = (*orig_bf)(ctx, out, out, len);
+ ret = (*orig_do_cipher)(ctx, out, out, len);
swap_bytes(out, out, len);
return (ret);
}
+static EVP_CIPHER *ssh1_bf;
+
const EVP_CIPHER *
evp_ssh1_bf(void)
{
- static EVP_CIPHER ssh1_bf;
-
- memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER));
- orig_bf = ssh1_bf.do_cipher;
- ssh1_bf.nid = NID_undef;
-#ifdef SSH_OLD_EVP
- ssh1_bf.init = bf_ssh1_init;
-#endif
- ssh1_bf.do_cipher = bf_ssh1_cipher;
- ssh1_bf.key_len = 32;
- return (&ssh1_bf);
+ ssh1_bf = EVP_CIPHER_meth_dup(EVP_bf_cbc());
+ orig_do_cipher = EVP_CIPHER_meth_get_do_cipher(ssh1_bf);
+ /* FIXME(hb): Do we need to set the associated NID?
+ (ssh1_bf.nid = NID_undef)
+ Do we need to set key length? (ssh1_bf.key_len = 32)
+ */
+ EVP_CIPHER_meth_set_do_cipher(ssh1_bf, bf_ssh1_do_cipher);
+ return (ssh1_bf);
}
#endif /* WITH_OPENSSL */
Index: ncrack/opensshlib/cipher.c
===================================================================
--- ncrack.orig/opensshlib/cipher.c
+++ ncrack/opensshlib/cipher.c
@@ -330,26 +330,26 @@ cipher_init(struct sshcipher_ctx *cc, co
return SSH_ERR_INVALID_ARGUMENT;
#else
type = (*cipher->evptype)();
- EVP_CIPHER_CTX_init(&cc->evp);
- if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
+ cc->evp = EVP_CIPHER_CTX_new();
+ if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv,
(do_encrypt == CIPHER_ENCRYPT)) == 0) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto bad;
}
if (cipher_authlen(cipher) &&
- !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED,
+ !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED,
-1, (u_char *)iv)) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto bad;
}
- klen = EVP_CIPHER_CTX_key_length(&cc->evp);
+ klen = EVP_CIPHER_CTX_key_length(cc->evp);
if (klen > 0 && keylen != (u_int)klen) {
- if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) {
+ if (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto bad;
}
}
- if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
+ if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto bad;
}
@@ -362,14 +362,14 @@ cipher_init(struct sshcipher_ctx *cc, co
ret = SSH_ERR_ALLOC_FAIL;
goto bad;
}
- ret = EVP_Cipher(&cc->evp, discard, junk, cipher->discard_len);
+ ret = EVP_Cipher(cc->evp, discard, junk, cipher->discard_len);
explicit_bzero(discard, cipher->discard_len);
free(junk);
free(discard);
if (ret != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
bad:
- EVP_CIPHER_CTX_cleanup(&cc->evp);
+ EVP_CIPHER_CTX_free(cc->evp);
return ret;
}
}
@@ -415,33 +415,33 @@ cipher_crypt(struct sshcipher_ctx *cc, u
if (authlen != cipher_authlen(cc->cipher))
return SSH_ERR_INVALID_ARGUMENT;
/* increment IV */
- if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN,
+ if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
1, lastiv))
return SSH_ERR_LIBCRYPTO_ERROR;
/* set tag on decyption */
if (!cc->encrypt &&
- !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG,
+ !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG,
authlen, (u_char *)src + aadlen + len))
return SSH_ERR_LIBCRYPTO_ERROR;
}
if (aadlen) {
if (authlen &&
- EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0)
+ EVP_Cipher(cc->evp, NULL, (u_char *)src, aadlen) < 0)
return SSH_ERR_LIBCRYPTO_ERROR;
memcpy(dest, src, aadlen);
}
if (len % cc->cipher->block_size)
return SSH_ERR_INVALID_ARGUMENT;
- if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen,
+ if (EVP_Cipher(cc->evp, dest + aadlen, (u_char *)src + aadlen,
len) < 0)
return SSH_ERR_LIBCRYPTO_ERROR;
if (authlen) {
/* compute tag (on encrypt) or verify tag (on decrypt) */
- if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0)
+ if (EVP_Cipher(cc->evp, NULL, NULL, 0) < 0)
return cc->encrypt ?
SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID;
if (cc->encrypt &&
- !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG,
+ !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG,
authlen, dest + aadlen + len))
return SSH_ERR_LIBCRYPTO_ERROR;
}
@@ -473,8 +473,7 @@ cipher_cleanup(struct sshcipher_ctx *cc)
else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx));
#ifdef WITH_OPENSSL
- else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
- return SSH_ERR_LIBCRYPTO_ERROR;
+ EVP_CIPHER_CTX_free(cc->evp);
#endif
return 0;
}
@@ -520,7 +519,7 @@ cipher_get_keyiv_len(const struct sshcip
ivlen = sizeof(cc->ac_ctx.ctr);
#ifdef WITH_OPENSSL
else
- ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
+ ivlen = EVP_CIPHER_CTX_iv_length(cc->evp);
#endif /* WITH_OPENSSL */
return (ivlen);
}
@@ -552,7 +551,7 @@ cipher_get_keyiv(struct sshcipher_ctx *c
case SSH_CIPHER_SSH2:
case SSH_CIPHER_DES:
case SSH_CIPHER_BLOWFISH:
- evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
+ evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
if (evplen == 0)
return 0;
else if (evplen < 0)
@@ -561,20 +560,20 @@ cipher_get_keyiv(struct sshcipher_ctx *c
return SSH_ERR_INVALID_ARGUMENT;
#ifndef OPENSSL_HAVE_EVPCTR
if (c->evptype == evp_aes_128_ctr)
- ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
+ ssh_aes_ctr_iv(cc->evp, 0, iv, len);
else
#endif
if (cipher_authlen(c)) {
- if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN,
+ if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
len, iv))
return SSH_ERR_LIBCRYPTO_ERROR;
} else
- memcpy(iv, cc->evp.iv, len);
+ memcpy(iv, EVP_CIPHER_CTX_iv(cc->evp), len);
break;
#endif
#ifdef WITH_SSH1
case SSH_CIPHER_3DES:
- return ssh1_3des_iv(&cc->evp, 0, iv, 24);
+ return ssh1_3des_iv(cc->evp, 0, iv, 24);
#endif
default:
return SSH_ERR_INVALID_ARGUMENT;
@@ -600,21 +599,25 @@ cipher_set_keyiv(struct sshcipher_ctx *c
case SSH_CIPHER_SSH2:
case SSH_CIPHER_DES:
case SSH_CIPHER_BLOWFISH:
- evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
+ evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
if (evplen <= 0)
return SSH_ERR_LIBCRYPTO_ERROR;
if (cipher_authlen(c)) {
/* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */
- if (!EVP_CIPHER_CTX_ctrl(&cc->evp,
+ if (!EVP_CIPHER_CTX_ctrl(cc->evp,
EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
return SSH_ERR_LIBCRYPTO_ERROR;
- } else
- memcpy(cc->evp.iv, iv, evplen);
+ } else {
+ /* XXX There must be a saner way to do this
+ than using the "getter" function to determine
+ the target of a copy operation */
+ memcpy(EVP_CIPHER_CTX_iv_noconst(cc->evp), iv, evplen);
+ }
break;
#endif
#ifdef WITH_SSH1
case SSH_CIPHER_3DES:
- return ssh1_3des_iv(&cc->evp, 1, (u_char *)iv, 24);
+ return ssh1_3des_iv(cc->evp, 1, (u_char *)iv, 24);
#endif
default:
return SSH_ERR_INVALID_ARGUMENT;
@@ -623,8 +626,8 @@ cipher_set_keyiv(struct sshcipher_ctx *c
}
#ifdef WITH_OPENSSL
-#define EVP_X_STATE(evp) (evp).cipher_data
-#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size
+#define EVP_X_STATE(evp) EVP_CIPHER_CTX_get_cipher_data(evp)
+#define EVP_X_STATE_LEN(evp) EVP_CIPHER_impl_ctx_size(EVP_CIPHER_CTX_cipher(evp))
#endif
int
Index: ncrack/opensshlib/cipher.h
===================================================================
--- ncrack.orig/opensshlib/cipher.h
+++ ncrack/opensshlib/cipher.h
@@ -66,7 +66,7 @@ struct sshcipher;
struct sshcipher_ctx {
int plaintext;
int encrypt;
- EVP_CIPHER_CTX evp;
+ EVP_CIPHER_CTX *evp;
struct chachapoly_ctx cp_ctx; /* XXX union with evp? */
struct aesctr_ctx ac_ctx; /* XXX union with evp? */
const struct sshcipher *cipher;
Index: ncrack/opensshlib/dh.c
===================================================================
--- ncrack.orig/opensshlib/dh.c
+++ ncrack/opensshlib/dh.c
@@ -215,14 +215,15 @@ choose_dh(int min, int wantbits, int max
/* diffie-hellman-groupN-sha1 */
int
-dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
+dh_pub_is_valid(DH *dh, const BIGNUM *dh_pub)
{
int i;
int n = BN_num_bits(dh_pub);
int bits_set = 0;
BIGNUM *tmp;
+ const BIGNUM *dh_p;
- if (dh_pub->neg) {
+ if (BN_is_negative(dh_pub)) {
logit("invalid public DH value: negative");
return 0;
}
@@ -235,7 +236,9 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
ssh_error("%s: BN_new failed", __func__);
return 0;
}
- if (!BN_sub(tmp, dh->p, BN_value_one()) ||
+
+ DH_get0_pqg(dh, &dh_p, NULL, NULL);
+ if (!BN_sub(tmp, dh_p, BN_value_one()) ||
BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
BN_clear_free(tmp);
logit("invalid public DH value: >= p-1");
@@ -246,13 +249,13 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
for (i = 0; i <= n; i++)
if (BN_is_bit_set(dh_pub, i))
bits_set++;
- debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
+ debug2("bits set: %d/%d", bits_set, BN_num_bits(dh_p));
/* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */
if (bits_set > 1)
return 1;
- logit("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p));
+ logit("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh_p));
return 0;
}
@@ -260,15 +263,17 @@ int
dh_gen_key(DH *dh, int need)
{
int pbits;
+ const BIGNUM *dh_p, *dh_pub_key;
+ DH_get0_pqg(dh, &dh_p, NULL, NULL);
- if (need < 0 || dh->p == NULL ||
- (pbits = BN_num_bits(dh->p)) <= 0 ||
+ if (need < 0 || dh_p == NULL ||
+ (pbits = BN_num_bits(dh_p)) <= 0 ||
need > INT_MAX / 2 || 2 * need > pbits)
return SSH_ERR_INVALID_ARGUMENT;
- dh->length = MIN(need * 2, pbits - 1);
+ DH_set_length(dh, MIN(need * 2, pbits - 1));
+ DH_get0_key(dh, &dh_pub_key, NULL);
if (DH_generate_key(dh) == 0 ||
- !dh_pub_is_valid(dh, dh->pub_key)) {
- BN_clear_free(dh->priv_key);
+ !dh_pub_is_valid(dh, dh_pub_key)) {
return SSH_ERR_LIBCRYPTO_ERROR;
}
return 0;
@@ -278,11 +283,13 @@ DH *
dh_new_group_asc(const char *gen, const char *modulus)
{
DH *dh;
+ const BIGNUM *dh_p, *dh_g;
if ((dh = DH_new()) == NULL)
return NULL;
- if (BN_hex2bn(&dh->p, modulus) == 0 ||
- BN_hex2bn(&dh->g, gen) == 0) {
+ DH_get0_pqg(dh, &dh_p, NULL, &dh_g);
+ if (BN_hex2bn((BIGNUM**)&dh_p, modulus) == 0 ||
+ BN_hex2bn((BIGNUM**)&dh_g, gen) == 0) {
DH_free(dh);
return NULL;
}
@@ -301,8 +308,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulu
if ((dh = DH_new()) == NULL)
return NULL;
- dh->p = modulus;
- dh->g = gen;
+ DH_set0_pqg(dh, modulus, NULL, gen);
return (dh);
}
Index: ncrack/opensshlib/dh.h
===================================================================
--- ncrack.orig/opensshlib/dh.h
+++ ncrack/opensshlib/dh.h
@@ -40,7 +40,7 @@ DH *dh_new_group14(void);
DH *dh_new_group_fallback(int);
int dh_gen_key(DH *, int);
-int dh_pub_is_valid(DH *, BIGNUM *);
+int dh_pub_is_valid(DH *, const BIGNUM *);
u_int dh_estimate(int);
Index: ncrack/opensshlib/digest-openssl.c
===================================================================
--- ncrack.orig/opensshlib/digest-openssl.c
+++ ncrack/opensshlib/digest-openssl.c
@@ -43,7 +43,7 @@
struct ssh_digest_ctx {
int alg;
- EVP_MD_CTX mdctx;
+ EVP_MD_CTX *mdctx;
};
struct ssh_digest {
@@ -111,7 +111,7 @@ ssh_digest_bytes(int alg)
size_t
ssh_digest_blocksize(struct ssh_digest_ctx *ctx)
{
- return EVP_MD_CTX_block_size(&ctx->mdctx);
+ return EVP_MD_CTX_block_size(ctx->mdctx);
}
struct ssh_digest_ctx *
@@ -123,8 +123,9 @@ ssh_digest_start(int alg)
if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL))
return NULL;
ret->alg = alg;
- EVP_MD_CTX_init(&ret->mdctx);
- if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) {
+ ret->mdctx = EVP_MD_CTX_new();
+ if (EVP_DigestInit_ex(ret->mdctx, digest->mdfunc(), NULL) != 1) {
+ EVP_MD_CTX_free(ret->mdctx);
free(ret);
return NULL;
}
@@ -137,7 +138,7 @@ ssh_digest_copy_state(struct ssh_digest_
if (from->alg != to->alg)
return SSH_ERR_INVALID_ARGUMENT;
/* we have bcopy-style order while openssl has memcpy-style */
- if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx))
+ if (!EVP_MD_CTX_copy_ex(to->mdctx, from->mdctx))
return SSH_ERR_LIBCRYPTO_ERROR;
return 0;
}
@@ -145,7 +146,7 @@ ssh_digest_copy_state(struct ssh_digest_
int
ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
{
- if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1)
+ if (EVP_DigestUpdate(ctx->mdctx, m, mlen) != 1)
return SSH_ERR_LIBCRYPTO_ERROR;
return 0;
}
@@ -166,7 +167,7 @@ ssh_digest_final(struct ssh_digest_ctx *
return SSH_ERR_INVALID_ARGUMENT;
if (dlen < digest->digest_len) /* No truncation allowed */
return SSH_ERR_INVALID_ARGUMENT;
- if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1)
+ if (EVP_DigestFinal_ex(ctx->mdctx, d, &l) != 1)
return SSH_ERR_LIBCRYPTO_ERROR;
if (l != digest->digest_len) /* sanity */
return SSH_ERR_INTERNAL_ERROR;
@@ -177,7 +178,7 @@ void
ssh_digest_free(struct ssh_digest_ctx *ctx)
{
if (ctx != NULL) {
- EVP_MD_CTX_cleanup(&ctx->mdctx);
+ EVP_MD_CTX_free(ctx->mdctx);
explicit_bzero(ctx, sizeof(*ctx));
free(ctx);
}
Index: ncrack/opensshlib/kexdhc.c
===================================================================
--- ncrack.orig/opensshlib/kexdhc.c
+++ ncrack/opensshlib/kexdhc.c
@@ -56,6 +56,7 @@ kexdh_client(ncrack_ssh_state *nstate)
{
struct kex *kex = nstate->kex;
int r;
+ const BIGNUM *kex_dh_pub_key;
//printf("kexdh client\n");
@@ -76,15 +77,16 @@ kexdh_client(ncrack_ssh_state *nstate)
goto out;
}
debug("sending SSH2_MSG_KEXDH_INIT");
+ DH_get0_key(kex->dh, &kex_dh_pub_key, NULL);
if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 ||
(r = sshpkt_start(nstate, SSH2_MSG_KEXDH_INIT)) != 0 ||
- (r = sshpkt_put_bignum2(nstate, kex->dh->pub_key)) != 0 ||
+ (r = sshpkt_put_bignum2(nstate, kex_dh_pub_key)) != 0 ||
(r = sshpkt_send(nstate)) != 0)
goto out;
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, kex->dh);
fprintf(stderr, "pub= ");
- BN_print_fp(stderr, kex->dh->pub_key);
+ BN_print_fp(stderr, kex_dh_pub_key);
fprintf(stderr, "\n");
#endif
debug("expecting SSH2_MSG_KEXDH_REPLY");
@@ -105,6 +107,7 @@ ncrackssh_input_kex_dh(ncrack_ssh_state
u_char hash[SSH_DIGEST_MAX_LENGTH];
size_t klen = 0, slen, sbloblen, hashlen;
int kout, r;
+ const BIGNUM *kex_dh_pub_key;
if (kex->verify_host_key == NULL) {
r = SSH_ERR_INVALID_ARGUMENT;
@@ -163,6 +166,8 @@ ncrackssh_input_kex_dh(ncrack_ssh_state
dump_digest("shared secret", kbuf, kout);
#endif
+ DH_get0_key(kex->dh, &kex_dh_pub_key, NULL);
+
/* calc and verify H */
hashlen = sizeof(hash);
if ((r = kex_dh_hash(
@@ -171,7 +176,7 @@ ncrackssh_input_kex_dh(ncrack_ssh_state
sshbuf_ptr(kex->my), sshbuf_len(kex->my),
sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
server_host_key_blob, sbloblen,
- kex->dh->pub_key,
+ kex_dh_pub_key,
dh_server_pub,
shared_secret,
hash, &hashlen)) != 0)
Index: ncrack/opensshlib/kexgexc.c
===================================================================
--- ncrack.orig/opensshlib/kexgexc.c
+++ ncrack/opensshlib/kexgexc.c
@@ -100,6 +100,7 @@ ncrackssh_input_kex_dh_gex_group(ncrack_
struct kex *kex = nstate->kex;
BIGNUM *p = NULL, *g = NULL;
int r, bits;
+ const BIGNUM *kex_dh_pub_key;
//printf("DH GEX GROUP\n");
@@ -124,18 +125,19 @@ ncrackssh_input_kex_dh_gex_group(ncrack_
goto out;
}
p = g = NULL; /* belong to kex->dh now */
+ DH_get0_key(kex->dh, &kex_dh_pub_key, NULL);
/* generate and send 'e', client DH public key */
if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 ||
(r = sshpkt_start(nstate, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 ||
- (r = sshpkt_put_bignum2(nstate, kex->dh->pub_key)) != 0 ||
+ (r = sshpkt_put_bignum2(nstate, kex_dh_pub_key)) != 0 ||
(r = sshpkt_send(nstate)) != 0)
goto out;
debug("SSH2_MSG_KEX_DH_GEX_INIT sent");
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, kex->dh);
fprintf(stderr, "pub= ");
- BN_print_fp(stderr, kex->dh->pub_key);
+ BN_print_fp(stderr, kex_dh_pub_key);
fprintf(stderr, "\n");
#endif
@@ -161,6 +163,7 @@ ncrackssh_input_kex_dh_gex_reply(ncrack_
u_char hash[SSH_DIGEST_MAX_LENGTH];
size_t klen = 0, slen, sbloblen, hashlen;
int kout, r;
+ const BIGNUM *kex_dh_pub_key, *kex_dh_p, *kex_dh_g;
debug("got SSH2_MSG_KEX_DH_GEX_REPLY");
if (kex->verify_host_key == NULL) {
@@ -225,6 +228,8 @@ ncrackssh_input_kex_dh_gex_reply(ncrack_
#endif
if (nstate->compat & SSH_OLD_DHGEX)
kex->min = kex->max = -1;
+ DH_get0_key(kex->dh, &kex_dh_pub_key, NULL);
+ DH_get0_pqg(kex->dh, &kex_dh_p, NULL, &kex_dh_g);
/* calc and verify H */
hashlen = sizeof(hash);
@@ -236,8 +241,8 @@ ncrackssh_input_kex_dh_gex_reply(ncrack_
sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
server_host_key_blob, sbloblen,