Skip to content

Commit

Permalink
upstream: hold our collective noses and use the openssl-1.1.x API in
Browse files Browse the repository at this point in the history
OpenSSH; feedback and ok tb@ jsing@ markus@

OpenBSD-Commit-ID: cacbcac87ce5da0d3ca7ef1b38a6f7fb349e4417
  • Loading branch information
djmdjm committed Sep 13, 2018
1 parent d70d061 commit 482d23b
Show file tree
Hide file tree
Showing 20 changed files with 619 additions and 438 deletions.
4 changes: 2 additions & 2 deletions auth2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand Down
16 changes: 9 additions & 7 deletions cipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand All @@ -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;
Expand All @@ -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)
Expand All @@ -518,8 +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;
}
Expand Down
4 changes: 2 additions & 2 deletions cipher.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
60 changes: 37 additions & 23 deletions dh.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,14 +216,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;

if (dh_pub->neg) {
DH_get0_pqg(dh, &dh_p, NULL, NULL);

if (BN_is_negative(dh_pub)) {
logit("invalid public DH value: negative");
return 0;
}
Expand All @@ -236,7 +239,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");
Expand All @@ -247,14 +250,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;
Expand All @@ -264,9 +267,12 @@ int
dh_gen_key(DH *dh, int need)
{
int pbits;
const BIGNUM *dh_p, *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;
if (need < 256)
Expand All @@ -275,47 +281,55 @@ 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;
}

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)
{
DH *dh;

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) */
Expand Down
2 changes: 1 addition & 1 deletion dh.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
26 changes: 14 additions & 12 deletions digest-openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@

struct ssh_digest_ctx {
int alg;
EVP_MD_CTX mdctx;
EVP_MD_CTX *mdctx;
};

struct ssh_digest {
Expand Down Expand Up @@ -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 *
Expand All @@ -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;
}

Expand All @@ -132,15 +135,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;
}
Expand All @@ -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;
Expand All @@ -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
Expand Down
15 changes: 10 additions & 5 deletions kexdhc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -81,15 +82,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");
Expand All @@ -104,6 +107,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];
Expand Down Expand Up @@ -168,6 +172,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,
Expand All @@ -176,7 +181,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)
Expand Down
Loading

0 comments on commit 482d23b

Please sign in to comment.