Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it build using OpenSSL 1.1.0 #48

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -92,7 +92,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \
kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \
platform-pledge.o platform-tracing.o platform-misc.o
platform-pledge.o platform-tracing.o platform-misc.o libcrypto-compat.o

SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
sshconnect.o sshconnect2.o mux.o
@@ -279,7 +279,7 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv,
if (EVP_CipherInit_ex(cc->evp, type, NULL, NULL, (u_char *)iv,
(do_encrypt == CIPHER_ENCRYPT)) == 0) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
@@ -297,7 +297,7 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
goto out;
}
}
if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
if (EVP_CipherInit_ex(cc->evp, NULL, NULL, (u_char *)key, NULL, -1) == 0) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
@@ -486,7 +486,7 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
len, iv))
return SSH_ERR_LIBCRYPTO_ERROR;
} else
memcpy(iv, cc->evp->iv, len);
memcpy(iv, EVP_CIPHER_CTX_iv(cc->evp), len);
#endif
return 0;
}
@@ -520,14 +520,14 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
return SSH_ERR_LIBCRYPTO_ERROR;
} else
memcpy(cc->evp->iv, iv, evplen);
memcpy(EVP_CIPHER_CTX_iv_noconst(cc->evp), iv, evplen);
#endif
return 0;
}

#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
38 dh.c
@@ -212,14 +212,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(const DH *dh, const BIGNUM *dh_pub)
{
int i;
int n = BN_num_bits(dh_pub);
int bits_set = 0;
BIGNUM *tmp;
const BIGNUM *p;

if (dh_pub->neg) {
if (BN_is_negative(dh_pub)) {
logit("invalid public DH value: negative");
return 0;
}
@@ -232,7 +233,8 @@ 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()) ||
DH_get0_pqg(dh, &p, NULL, NULL);
if (!BN_sub(tmp, 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");
@@ -243,14 +245,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(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(p));
return 0;
}
return 1;
@@ -260,9 +262,11 @@ int
dh_gen_key(DH *dh, int need)
{
int pbits;
const BIGNUM *p, *pub_key;

if (need < 0 || dh->p == NULL ||
(pbits = BN_num_bits(dh->p)) <= 0 ||
DH_get0_pqg(dh, &p, NULL, NULL);
if (need < 0 || p == NULL ||
(pbits = BN_num_bits(p)) <= 0 ||
need > INT_MAX / 2 || 2 * need > pbits)
return SSH_ERR_INVALID_ARGUMENT;
if (need < 256)
@@ -271,10 +275,11 @@ 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_set_length(dh, MINIMUM(need * 2, pbits - 1));
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_LIBCRYPTO_ERROR;
}
return 0;
@@ -284,12 +289,16 @@ DH *
dh_new_group_asc(const char *gen, const char *modulus)
{
DH *dh;
BIGNUM *p = NULL, *g = NULL;

if ((dh = DH_new()) == NULL)
return NULL;
if (BN_hex2bn(&dh->p, modulus) == 0 ||
BN_hex2bn(&dh->g, gen) == 0) {
if (BN_hex2bn(&p, modulus) == 0 ||
BN_hex2bn(&g, gen) == 0 ||
DH_set0_pqg(dh, p, NULL, g) == 0) {
DH_free(dh);
BN_free(p);
BN_free(g);
return NULL;
}
return (dh);
@@ -307,8 +316,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulus)

if ((dh = DH_new()) == NULL)
return NULL;
dh->p = modulus;
dh->g = gen;
DH_set0_pqg(dh, modulus, NULL, gen);

return (dh);
}
2 dh.h
@@ -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,9 +118,10 @@ 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) {
free(ret);
ret->mdctx = EVP_MD_CTX_new();
if (ret->mdctx == NULL ||
EVP_DigestInit_ex(ret->mdctx, digest->mdfunc(), NULL) != 1) {
ssh_digest_free(ret);
return NULL;
}
return ret;
@@ -132,15 +133,15 @@ 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;
}

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 +162,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;
@@ -172,7 +173,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);
}
@@ -166,6 +166,7 @@

#ifdef WITH_OPENSSL
#include <openssl/opensslv.h> /* For OPENSSL_VERSION_NUMBER */
#include "libcrypto-compat.h"
#endif

#include "defines.h"
@@ -56,6 +56,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,21 +82,27 @@ 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");
ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_REPLY, &input_kex_dh);
r = 0;
out:
if (r != 0) {
DH_free(kex->dh);
kex->dh = NULL;
}
return r;
}

@@ -109,6 +116,7 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh)
u_char hash[SSH_DIGEST_MAX_LENGTH];
size_t klen = 0, slen, sbloblen, hashlen;
int kout, r;
const BIGNUM *pub_key;

if (kex->verify_host_key == NULL) {
r = SSH_ERR_INVALID_ARGUMENT;
@@ -168,6 +176,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 +185,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)
@@ -87,6 +87,10 @@ kexdh_server(struct ssh *ssh)
ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init);
r = 0;
out:
if (r != 0) {
DH_free(kex->dh);
kex->dh = NULL;
}
return r;
}

@@ -101,6 +105,7 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
size_t sbloblen, slen;
size_t klen = 0, hashlen;
int kout, r;
const BIGNUM *pub_key;

if (kex->load_host_public_key == NULL ||
kex->load_host_private_key == NULL) {
@@ -163,6 +168,7 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
goto out;
/* calc H */
hashlen = sizeof(hash);
DH_get0_key(kex->dh, &pub_key, NULL);
if ((r = kex_dh_hash(
kex->hash_alg,
kex->client_version_string,
@@ -171,7 +177,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 +203,7 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
/* send server hostkey, DH pubkey 'f' and singed 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;