Commit 0a5cc6b2 authored by Ed Maste's avatar Ed Maste
Browse files

openssh: cherry-pick OpenSSL 1.1.1 compatibility

Upstream commits:
482d23bcac upstream: hold our collective noses and use the openssl-1.1.x
48f54b9d12 adapt -portable to OpenSSL 1.1x API
86e0a9f3d2 upstream: use only openssl-1.1.x API here too
a3fd8074e2 upstream: missed a bit of openssl-1.0.x API in this unittest
cce8cbe0ed Fix openssl-1.1 fallout for --without-openssl.

Trivial conflicts in sshkey.c and test_sshkey.c were resolved.

Discussed with:	des
parent d46065df
......@@ -128,6 +128,10 @@ extern u_int utmp_len;
typedef pthread_t sp_pthread_t;
#else
typedef pid_t sp_pthread_t;
#define pthread_exit fake_pthread_exit
#define pthread_create fake_pthread_create
#define pthread_cancel fake_pthread_cancel
#define pthread_join fake_pthread_join
#endif
struct pam_ctxt {
......
......@@ -706,7 +706,7 @@ auth2_record_key(Authctxt *authctxt, int authenticated,
struct sshkey **tmp, *dup;
int r;
if ((r = sshkey_demote(key, &dup)) != 0)
if ((r = sshkey_from_private(key, &dup)) != 0)
fatal("%s: copy key: %s", __func__, ssh_err(r));
sshkey_free(authctxt->auth_method_key);
authctxt->auth_method_key = dup;
......@@ -715,7 +715,7 @@ auth2_record_key(Authctxt *authctxt, int authenticated,
return;
/* If authenticated, make sure we don't accept this key again */
if ((r = sshkey_demote(key, &dup)) != 0)
if ((r = sshkey_from_private(key, &dup)) != 0)
fatal("%s: copy key: %s", __func__, ssh_err(r));
if (authctxt->nprev_keys >= INT_MAX ||
(tmp = recallocarray(authctxt->prev_keys, authctxt->nprev_keys,
......
......@@ -446,7 +446,7 @@ cipher_get_keyiv_len(const struct sshcipher_ctx *cc)
}
int
cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, size_t len)
{
#ifdef WITH_OPENSSL
const struct sshcipher *c = cc->cipher;
......@@ -473,7 +473,7 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
return 0;
else if (evplen < 0)
return SSH_ERR_LIBCRYPTO_ERROR;
if ((u_int)evplen != len)
if ((size_t)evplen != len)
return SSH_ERR_INVALID_ARGUMENT;
#ifndef OPENSSL_HAVE_EVPCTR
if (c->evptype == evp_aes_128_ctr)
......@@ -484,14 +484,14 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
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);
} else if (!EVP_CIPHER_CTX_get_iv(cc->evp, iv, len))
return SSH_ERR_LIBCRYPTO_ERROR;
#endif
return 0;
}
int
cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv, size_t len)
{
#ifdef WITH_OPENSSL
const struct sshcipher *c = cc->cipher;
......@@ -507,6 +507,8 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
if (evplen <= 0)
return SSH_ERR_LIBCRYPTO_ERROR;
if ((size_t)evplen != len)
return SSH_ERR_INVALID_ARGUMENT;
#ifndef OPENSSL_HAVE_EVPCTR
/* XXX iv arg is const, but ssh_aes_ctr_iv isn't */
if (c->evptype == evp_aes_128_ctr)
......@@ -518,46 +520,8 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
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 if (!EVP_CIPHER_CTX_set_iv(cc->evp, iv, evplen))
return SSH_ERR_LIBCRYPTO_ERROR;
#endif
return 0;
}
#ifdef WITH_OPENSSL
#define EVP_X_STATE(evp) (evp)->cipher_data
#define EVP_X_STATE_LEN(evp) (evp)->cipher->ctx_size
#endif
int
cipher_get_keycontext(const struct sshcipher_ctx *cc, u_char *dat)
{
#if defined(WITH_OPENSSL) && !defined(OPENSSL_NO_RC4)
const struct sshcipher *c = cc->cipher;
int plen = 0;
if (c->evptype == EVP_rc4) {
plen = EVP_X_STATE_LEN(cc->evp);
if (dat == NULL)
return (plen);
memcpy(dat, EVP_X_STATE(cc->evp), plen);
}
return (plen);
#else
return 0;
#endif
}
void
cipher_set_keycontext(struct sshcipher_ctx *cc, const u_char *dat)
{
#if defined(WITH_OPENSSL) && !defined(OPENSSL_NO_RC4)
const struct sshcipher *c = cc->cipher;
int plen;
if (c->evptype == EVP_rc4) {
plen = EVP_X_STATE_LEN(cc->evp);
memcpy(EVP_X_STATE(cc->evp), dat, plen);
}
#endif
}
......@@ -68,8 +68,8 @@ u_int cipher_is_cbc(const struct sshcipher *);
u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *);
int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, u_int);
int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *);
int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, size_t);
int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *, size_t);
int cipher_get_keyiv_len(const struct sshcipher_ctx *);
#endif /* CIPHER_H */
......@@ -2602,9 +2602,10 @@ if test "x$openssl" = "xyes" ; then
AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")])
;;
100*) ;; # 1.0.x
101*) ;; # 1.1.x
200*) ;; # LibreSSL
*)
AC_MSG_ERROR([OpenSSL >= 1.1.0 is not yet supported (have "$ssl_library_ver")])
AC_MSG_ERROR([OpenSSL > 1.1.x is not yet supported (have "$ssl_library_ver")])
;;
esac
AC_MSG_RESULT([$ssl_library_ver])
......@@ -2777,6 +2778,115 @@ if test "x$openssl" = "xyes" ; then
[AC_DEFINE([HAVE_EVP_CIPHER_CTX_CTRL], [1],
[Define if libcrypto has EVP_CIPHER_CTX_ctrl])])
# LibreSSL/OpenSSL 1.1x API
AC_SEARCH_LIBS([DH_get0_key], [crypto],
[AC_DEFINE([HAVE_DH_GET0_KEY], [1],
[Define if libcrypto has DH_get0_key])])
AC_SEARCH_LIBS([DH_get0_pqg], [crypto],
[AC_DEFINE([HAVE_DH_GET0_PQG], [1],
[Define if libcrypto has DH_get0_pqg])])
AC_SEARCH_LIBS([DH_set0_key], [crypto],
[AC_DEFINE([HAVE_DH_SET0_KEY], [1],
[Define if libcrypto has DH_set0_key])])
AC_SEARCH_LIBS([DH_set_length], [crypto],
[AC_DEFINE([HAVE_DH_SET_LENGTH], [1],
[Define if libcrypto has DH_set_length])])
AC_SEARCH_LIBS([DH_set0_pqg], [crypto],
[AC_DEFINE([HAVE_DH_SET0_PQG], [1],
[Define if libcrypto has DH_set0_pqg])])
AC_SEARCH_LIBS([DSA_get0_key], [crypto],
[AC_DEFINE([HAVE_DSA_GET0_KEY], [1],
[Define if libcrypto has DSA_get0_key])])
AC_SEARCH_LIBS([DSA_get0_pqg], [crypto],
[AC_DEFINE([HAVE_DSA_GET0_PQG], [1],
[Define if libcrypto has DSA_get0_pqg])])
AC_SEARCH_LIBS([DSA_set0_key], [crypto],
[AC_DEFINE([HAVE_DSA_SET0_KEY], [1],
[Define if libcrypto has DSA_set0_key])])
AC_SEARCH_LIBS([DSA_set0_pqg], [crypto],
[AC_DEFINE([HAVE_DSA_SET0_PQG], [1],
[Define if libcrypto has DSA_set0_pqg])])
AC_SEARCH_LIBS([DSA_SIG_get0], [crypto],
[AC_DEFINE([HAVE_DSA_SIG_GET0], [1],
[Define if libcrypto has DSA_SIG_get0])])
AC_SEARCH_LIBS([DSA_SIG_set0], [crypto],
[AC_DEFINE([HAVE_DSA_SIG_SET0], [1],
[Define if libcrypto has DSA_SIG_set0])])
AC_SEARCH_LIBS([ECDSA_SIG_get0], [crypto],
[AC_DEFINE([HAVE_ECDSA_SIG_GET0], [1],
[Define if libcrypto has ECDSA_SIG_get0])])
AC_SEARCH_LIBS([ECDSA_SIG_set0], [crypto],
[AC_DEFINE([HAVE_ECDSA_SIG_SET0], [1],
[Define if libcrypto has ECDSA_SIG_set0])])
AC_SEARCH_LIBS([EVP_CIPHER_CTX_iv], [crypto],
[AC_DEFINE([HAVE_EVP_CIPHER_CTX_IV], [1],
[Define if libcrypto has EVP_CIPHER_CTX_iv])])
AC_SEARCH_LIBS([EVP_CIPHER_CTX_iv_noconst], [crypto],
[AC_DEFINE([HAVE_EVP_CIPHER_CTX_IV_NOCONST], [1],
[Define if libcrypto has EVP_CIPHER_CTX_iv_noconst])])
AC_SEARCH_LIBS([EVP_CIPHER_CTX_get_iv], [crypto],
[AC_DEFINE([HAVE_EVP_CIPHER_CTX_GET_IV], [1],
[Define if libcrypto has EVP_CIPHER_CTX_get_iv])])
AC_SEARCH_LIBS([EVP_CIPHER_CTX_set_iv], [crypto],
[AC_DEFINE([HAVE_EVP_CIPHER_CTX_GET_IV], [1],
[Define if libcrypto has EVP_CIPHER_CTX_set_iv])])
AC_SEARCH_LIBS([RSA_get0_crt_params], [crypto],
[AC_DEFINE([HAVE_RSA_GET0_CRT_PARAMS], [1],
[Define if libcrypto has RSA_get0_crt_params])])
AC_SEARCH_LIBS([RSA_get0_factors], [crypto],
[AC_DEFINE([HAVE_RSA_GET0_FACTORS], [1],
[Define if libcrypto has RSA_get0_factors])])
AC_SEARCH_LIBS([RSA_get0_key], [crypto],
[AC_DEFINE([HAVE_RSA_GET0_KEY], [1],
[Define if libcrypto has RSA_get0_key])])
AC_SEARCH_LIBS([RSA_set0_crt_params], [crypto],
[AC_DEFINE([HAVE_RSA_SET0_CRT_PARAMS], [1],
[Define if libcrypto has RSA_get0_srt_params])])
AC_SEARCH_LIBS([RSA_set0_factors], [crypto],
[AC_DEFINE([HAVE_RSA_SET0_FACTORS], [1],
[Define if libcrypto has RSA_set0_factors])])
AC_SEARCH_LIBS([RSA_set0_key], [crypto],
[AC_DEFINE([HAVE_RSA_SET0_KEY], [1],
[Define if libcrypto has RSA_set0_key])])
AC_SEARCH_LIBS([RSA_meth_free], [crypto],
[AC_DEFINE([HAVE_RSA_METH_FREE], [1],
[Define if libcrypto has RSA_meth_free])])
AC_SEARCH_LIBS([RSA_meth_dup], [crypto],
[AC_DEFINE([HAVE_RSA_METH_DUP], [1],
[Define if libcrypto has RSA_meth_dup])])
AC_SEARCH_LIBS([RSA_meth_set1_name], [crypto],
[AC_DEFINE([HAVE_RSA_METH_SET1_NAME], [1],
[Define if libcrypto has RSA_meth_set1_name])])
AC_SEARCH_LIBS([RSA_meth_get_finish], [crypto],
[AC_DEFINE([HAVE_RSA_METH_GET_FINISH], [1],
[Define if libcrypto has RSA_meth_get_finish])])
AC_SEARCH_LIBS([RSA_meth_set_priv_enc], [crypto],
[AC_DEFINE([HAVE_RSA_METH_SET_PRIV_ENC], [1],
[Define if libcrypto has RSA_meth_set_priv_enc])])
AC_SEARCH_LIBS([RSA_meth_set_priv_dec], [crypto],
[AC_DEFINE([HAVE_RSA_METH_SET_PRIV_DEC], [1],
[Define if libcrypto has RSA_meth_set_priv_dec])])
AC_SEARCH_LIBS([RSA_meth_set_finish], [crypto],
[AC_DEFINE([HAVE_RSA_METH_SET_FINISH], [1],
[Define if libcrypto has RSA_meth_set_finish])])
AC_SEARCH_LIBS([EVP_PKEY_get0_RSA], [crypto],
[AC_DEFINE([HAVE_EVP_PKEY_GET0_RSA], [1],
[Define if libcrypto has EVP_PKEY_get0_RSA])])
AC_SEARCH_LIBS([EVP_MD_CTX_new], [crypto],
[AC_DEFINE([HAVE_EVP_MD_CTX_NEW], [1],
[Define if libcrypto has EVP_MD_CTX_new])])
AC_SEARCH_LIBS([EVP_MD_CTX_free], [crypto],
[AC_DEFINE([HAVE_EVP_MD_CTX_FREE], [1],
[Define if libcrypto has EVP_MD_CTX_free])])
AC_MSG_CHECKING([if EVP_DigestUpdate returns an int])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[
......
......@@ -43,6 +43,8 @@
#include "misc.h"
#include "ssherr.h"
#include "openbsd-compat/openssl-compat.h"
static int
parse_prime(int linenum, char *line, struct dhgroup *dhg)
{
......@@ -216,14 +218,17 @@ 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(const 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;
DH_get0_pqg(dh, &dh_p, NULL, NULL);
if (dh_pub->neg) {
if (BN_is_negative(dh_pub)) {
logit("invalid public DH value: negative");
return 0;
}
......@@ -236,7 +241,7 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
error("%s: BN_new failed", __func__);
return 0;
}
if (!BN_sub(tmp, dh->p, BN_value_one()) ||
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");
......@@ -247,14 +252,14 @@ 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 < 4) {
logit("invalid public DH value (%d/%d)",
bits_set, BN_num_bits(dh->p));
bits_set, BN_num_bits(dh_p));
return 0;
}
return 1;
......@@ -264,9 +269,12 @@ int
dh_gen_key(DH *dh, int need)
{
int pbits;
const BIGNUM *dh_p, *pub_key;
if (need < 0 || dh->p == NULL ||
(pbits = BN_num_bits(dh->p)) <= 0 ||
DH_get0_pqg(dh, &dh_p, NULL, NULL);
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;
if (need < 256)
......@@ -275,13 +283,14 @@ dh_gen_key(DH *dh, int need)
* Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
* so double requested need here.
*/
dh->length = MINIMUM(need * 2, pbits - 1);
if (DH_generate_key(dh) == 0 ||
!dh_pub_is_valid(dh, dh->pub_key)) {
BN_clear_free(dh->priv_key);
dh->priv_key = NULL;
if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
return SSH_ERR_LIBCRYPTO_ERROR;
}
if (DH_generate_key(dh) == 0)
return SSH_ERR_LIBCRYPTO_ERROR;
DH_get0_key(dh, &pub_key, NULL);
if (!dh_pub_is_valid(dh, pub_key))
return SSH_ERR_INVALID_FORMAT;
return 0;
}
......@@ -289,22 +298,27 @@ DH *
dh_new_group_asc(const char *gen, const char *modulus)
{
DH *dh;
BIGNUM *dh_p = NULL, *dh_g = NULL;
if ((dh = DH_new()) == NULL)
return NULL;
if (BN_hex2bn(&dh->p, modulus) == 0 ||
BN_hex2bn(&dh->g, gen) == 0) {
DH_free(dh);
return NULL;
}
return (dh);
if (BN_hex2bn(&dh_p, modulus) == 0 ||
BN_hex2bn(&dh_g, gen) == 0)
goto fail;
if (!DH_set0_pqg(dh, dh_p, NULL, dh_g))
goto fail;
return dh;
fail:
DH_free(dh);
BN_clear_free(dh_p);
BN_clear_free(dh_g);
return NULL;
}
/*
* This just returns the group, we still need to generate the exchange
* value.
*/
DH *
dh_new_group(BIGNUM *gen, BIGNUM *modulus)
{
......@@ -312,10 +326,12 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulus)
if ((dh = DH_new()) == NULL)
return NULL;
dh->p = modulus;
dh->g = gen;
if (!DH_set0_pqg(dh, modulus, NULL, gen)) {
DH_free(dh);
return NULL;
}
return (dh);
return dh;
}
/* rfc2409 "Second Oakley Group" (1024 bits) */
......
......@@ -42,7 +42,7 @@ DH *dh_new_group18(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(const DH *, const BIGNUM *);
u_int dh_estimate(int);
......
......@@ -43,7 +43,7 @@
struct ssh_digest_ctx {
int alg;
EVP_MD_CTX mdctx;
EVP_MD_CTX *mdctx;
};
struct ssh_digest {
......@@ -106,7 +106,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 *
......@@ -118,11 +118,14 @@ 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) {
if ((ret->mdctx = EVP_MD_CTX_new()) == NULL) {
free(ret);
return NULL;
}
if (EVP_DigestInit_ex(ret->mdctx, digest->mdfunc(), NULL) != 1) {
ssh_digest_free(ret);
return NULL;
}
return ret;
}
......@@ -132,7 +135,7 @@ ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
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;
}
......@@ -140,7 +143,7 @@ ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
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;
}
......@@ -161,7 +164,7 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
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;
......@@ -171,11 +174,10 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
void
ssh_digest_free(struct ssh_digest_ctx *ctx)
{
if (ctx != NULL) {
EVP_MD_CTX_cleanup(&ctx->mdctx);
explicit_bzero(ctx, sizeof(*ctx));
free(ctx);
}
if (ctx == NULL)
return;
EVP_MD_CTX_free(ctx->mdctx);
freezero(ctx, sizeof(*ctx));
}
int
......
......@@ -33,6 +33,8 @@
#include <openssl/evp.h>
#include "openbsd-compat/openssl-compat.h"
#include "ssh2.h"
#include "sshkey.h"
#include "cipher.h"
......
......@@ -36,6 +36,8 @@
#include <string.h>
#include <signal.h>
#include "openbsd-compat/openssl-compat.h"
#include "sshkey.h"
#include "cipher.h"
#include "digest.h"
......@@ -56,6 +58,7 @@ kexdh_client(struct ssh *ssh)
{
struct kex *kex = ssh->kex;
int r;
const BIGNUM *pub_key;
/* generate and send 'e', client DH public key */
switch (kex->kex_type) {
......@@ -81,15 +84,17 @@ kexdh_client(struct ssh *ssh)
goto out;
}
debug("sending SSH2_MSG_KEXDH_INIT");
if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 ||
(r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 ||
(r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||
if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
goto out;
DH_get0_key(kex->dh, &pub_key, NULL);
if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 ||
(r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||
(r = sshpkt_send(ssh)) != 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, pub_key);
fprintf(stderr, "\n");
#endif
debug("expecting SSH2_MSG_KEXDH_REPLY");
......@@ -104,6 +109,7 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh)
{
struct kex *kex = ssh->kex;
BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
const BIGNUM *pub_key;
struct sshkey *server_host_key = NULL;
u_char *kbuf = NULL, *server_host_key_blob = NULL, *signature = NULL;
u_char hash[SSH_DIGEST_MAX_LENGTH];
......@@ -168,6 +174,7 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh)
#endif
/* calc and verify H */
DH_get0_key(kex->dh, &pub_key, NULL);
hashlen = sizeof(hash);
if ((r = kex_dh_hash(
kex->hash_alg,
......@@ -176,7 +183,7 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh)
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,
pub_key,
dh_server_pub,
shared_secret,
hash, &hashlen)) != 0)
......
......@@ -35,6 +35,8 @@
#include <openssl/dh.h>
#include "openbsd-compat/openssl-compat.h"
#include "sshkey.h"
#include "cipher.h"
#include "digest.h"
......@@ -95,6 +97,7 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
{
struct kex *kex = ssh->kex;
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
const BIGNUM *pub_key;
struct sshkey *server_host_public, *server_host_private;
u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL;
u_char hash[SSH_DIGEST_MAX_LENGTH];
......@@ -121,6 +124,7 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
DH_get0_key(kex->dh, &pub_key, NULL);
if ((r = sshpkt_get_bignum2(ssh, dh_client_pub)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
goto out;
......@@ -130,12 +134,9 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
BN_print_fp(stderr, dh_client_pub);
fprintf(stderr, "\n");
debug("bits %d", BN_num_bits(dh_client_pub));
#endif
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, kex->dh);
fprintf(stderr, "pub= ");
BN_print_fp(stderr, kex->dh->pub_key);
BN_print_fp(stderr, pub_key);
fprintf(stderr, "\n");
#endif
if (!dh_pub_is_valid(kex->dh, dh_client_pub)) {
......@@ -171,7 +172,7 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
sshbuf_ptr(kex->my), sshbuf_len(kex->my),
server_host_key_blob, sbloblen,
dh_client_pub,
kex->dh->pub_key,
pub_key,
shared_secret,
hash, &hashlen)) != 0)
goto out;
......@@ -197,7 +198,7 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
/* send server hostkey, DH pubkey 'f' and signed H */
if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 ||
(r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
(r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */
(r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */
(r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
goto out;
......
......@@ -33,6 +33,8 @@
#include <openssl/evp.h>
#include <signal.h>
#include "openbsd-compat/openssl-compat.h"
#include "sshkey.h"
#include "cipher.h"
#include "kex.h"
......
......@@ -37,6 +37,8 @@
#include <string.h>
#include <signal.h>
#include "openbsd-compat/openssl-compat.h"