- djm@cvs.openbsd.org 2014/01/09 23:20:00
[digest.c digest.h hostfile.c kex.c kex.h kexc25519.c kexc25519c.c] [kexc25519s.c kexdh.c kexecdh.c kexecdhc.c kexecdhs.c kexgex.c kexgexc.c] [kexgexs.c key.c key.h roaming_client.c roaming_common.c schnorr.c] [schnorr.h ssh-dss.c ssh-ecdsa.c ssh-rsa.c sshconnect2.c] Introduce digest API and use it to perform all hashing operations rather than calling OpenSSL EVP_Digest* directly. Will make it easier to build a reduced-feature OpenSSH without OpenSSL in future; feedback, ok markus@
This commit is contained in:
parent
e00e413dd1
commit
b3051d01e5
|
@ -9,6 +9,15 @@
|
|||
with the year, and rearrange a comparison to avoid a potentional signed
|
||||
arithmetic overflow that would give the wrong result.
|
||||
ok djm@
|
||||
- djm@cvs.openbsd.org 2014/01/09 23:20:00
|
||||
[digest.c digest.h hostfile.c kex.c kex.h kexc25519.c kexc25519c.c]
|
||||
[kexc25519s.c kexdh.c kexecdh.c kexecdhc.c kexecdhs.c kexgex.c kexgexc.c]
|
||||
[kexgexs.c key.c key.h roaming_client.c roaming_common.c schnorr.c]
|
||||
[schnorr.h ssh-dss.c ssh-ecdsa.c ssh-rsa.c sshconnect2.c]
|
||||
Introduce digest API and use it to perform all hashing operations
|
||||
rather than calling OpenSSL EVP_Digest* directly. Will make it easier
|
||||
to build a reduced-feature OpenSSH without OpenSSL in future;
|
||||
feedback, ok markus@
|
||||
|
||||
20140108
|
||||
- (djm) [regress/.cvsignore] Ignore regress test droppings; ok dtucker@
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile.in,v 1.348 2013/12/08 04:53:28 djm Exp $
|
||||
# $Id: Makefile.in,v 1.349 2014/01/09 23:58:53 djm Exp $
|
||||
|
||||
# uncomment if you run a non bourne compatable shell. Ie. csh
|
||||
#SHELL = @SH@
|
||||
|
@ -75,7 +75,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \
|
|||
msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
|
||||
jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \
|
||||
kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \
|
||||
ssh-ed25519.o \
|
||||
ssh-ed25519.o digest.o \
|
||||
sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \
|
||||
|
||||
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
/* $OpenBSD: digest.c,v 1.1 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bn.h> /* for buffer.h */
|
||||
#include <openssl/ec.h> /* for buffer.h */
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "digest.h"
|
||||
|
||||
struct ssh_digest_ctx {
|
||||
int alg;
|
||||
EVP_MD_CTX mdctx;
|
||||
};
|
||||
|
||||
struct ssh_digest {
|
||||
int id;
|
||||
const char *name;
|
||||
size_t digest_len;
|
||||
const EVP_MD *(*mdfunc)(void);
|
||||
};
|
||||
|
||||
/* NB. Indexed directly by algorithm number */
|
||||
const struct ssh_digest digests[] = {
|
||||
{ SSH_DIGEST_MD5, "MD5", 16, EVP_md5 },
|
||||
{ SSH_DIGEST_RIPEMD160, "RIPEMD160", 20, EVP_ripemd160 },
|
||||
{ SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 },
|
||||
#ifdef HAVE_EVP_SHA256 /* XXX replace with local if missing */
|
||||
{ SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 },
|
||||
{ SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 },
|
||||
{ SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 },
|
||||
#endif
|
||||
{ -1, NULL, 0, NULL },
|
||||
};
|
||||
|
||||
static const struct ssh_digest *
|
||||
ssh_digest_by_alg(int alg)
|
||||
{
|
||||
if (alg < 0 || alg >= SSH_DIGEST_MAX)
|
||||
return NULL;
|
||||
if (digests[alg].id != alg) /* sanity */
|
||||
return NULL;
|
||||
return &(digests[alg]);
|
||||
}
|
||||
|
||||
size_t
|
||||
ssh_digest_bytes(int alg)
|
||||
{
|
||||
const struct ssh_digest *digest = ssh_digest_by_alg(alg);
|
||||
|
||||
return digest == NULL ? 0 : digest->digest_len;
|
||||
}
|
||||
|
||||
struct ssh_digest_ctx *
|
||||
ssh_digest_start(int alg)
|
||||
{
|
||||
const struct ssh_digest *digest = ssh_digest_by_alg(alg);
|
||||
struct ssh_digest_ctx *ret;
|
||||
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
|
||||
{
|
||||
if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b)
|
||||
{
|
||||
return ssh_digest_update(ctx, buffer_ptr(b), buffer_len(b));
|
||||
}
|
||||
|
||||
int
|
||||
ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
|
||||
{
|
||||
const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);
|
||||
u_int l = dlen;
|
||||
|
||||
if (dlen > UINT_MAX)
|
||||
return -1;
|
||||
if (dlen < digest->digest_len) /* No truncation allowed */
|
||||
return -1;
|
||||
if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1)
|
||||
return -1;
|
||||
if (l != digest->digest_len) /* sanity */
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ssh_digest_free(struct ssh_digest_ctx *ctx)
|
||||
{
|
||||
EVP_MD_CTX_cleanup(&ctx->mdctx);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
int
|
||||
ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen)
|
||||
{
|
||||
struct ssh_digest_ctx *ctx = ssh_digest_start(alg);
|
||||
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
if (ssh_digest_update(ctx, m, mlen) != 0 ||
|
||||
ssh_digest_final(ctx, d, dlen) != 0)
|
||||
return -1;
|
||||
ssh_digest_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen)
|
||||
{
|
||||
return ssh_digest_memory(alg, buffer_ptr(b), buffer_len(b), d, dlen);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/* $OpenBSD: digest.h,v 1.1 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _DIGEST_H
|
||||
#define _DIGEST_H
|
||||
|
||||
/* Maximum digest output length */
|
||||
#define SSH_DIGEST_MAX_LENGTH 64
|
||||
|
||||
/* Digest algorithms */
|
||||
#define SSH_DIGEST_MD5 0
|
||||
#define SSH_DIGEST_RIPEMD160 1
|
||||
#define SSH_DIGEST_SHA1 2
|
||||
#define SSH_DIGEST_SHA256 3
|
||||
#define SSH_DIGEST_SHA384 4
|
||||
#define SSH_DIGEST_SHA512 5
|
||||
#define SSH_DIGEST_MAX 6
|
||||
|
||||
/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */
|
||||
size_t ssh_digest_bytes(int alg);
|
||||
|
||||
/* One-shot API */
|
||||
int ssh_digest_memory(int alg, const void *m, size_t mlen,
|
||||
u_char *d, size_t dlen)
|
||||
__attribute__((__bounded__(__buffer__, 2, 3)))
|
||||
__attribute__((__bounded__(__buffer__, 4, 5)));
|
||||
int ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen)
|
||||
__attribute__((__bounded__(__buffer__, 3, 4)));
|
||||
|
||||
/* Update API */
|
||||
struct ssh_digest_ctx;
|
||||
struct ssh_digest_ctx *ssh_digest_start(int alg);
|
||||
int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
|
||||
__attribute__((__bounded__(__buffer__, 2, 3)));
|
||||
int ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b);
|
||||
int ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
|
||||
__attribute__((__bounded__(__buffer__, 2, 3)));
|
||||
void ssh_digest_free(struct ssh_digest_ctx *ctx);
|
||||
|
||||
#endif /* _DIGEST_H */
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: hostfile.c,v 1.52 2013/07/12 00:19:58 djm Exp $ */
|
||||
/* $OpenBSD: hostfile.c,v 1.53 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -57,6 +57,7 @@
|
|||
#include "hostfile.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "digest.h"
|
||||
|
||||
struct hostkeys {
|
||||
struct hostkey_entry *entries;
|
||||
|
|
94
kex.c
94
kex.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kex.c,v 1.93 2013/11/07 11:58:27 dtucker Exp $ */
|
||||
/* $OpenBSD: kex.c,v 1.94 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -49,6 +49,7 @@
|
|||
#include "dispatch.h"
|
||||
#include "monitor.h"
|
||||
#include "roaming.h"
|
||||
#include "digest.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
|
||||
# if defined(HAVE_EVP_SHA256)
|
||||
|
@ -66,26 +67,30 @@ struct kexalg {
|
|||
char *name;
|
||||
int type;
|
||||
int ec_nid;
|
||||
const EVP_MD *(*mdfunc)(void);
|
||||
int hash_alg;
|
||||
};
|
||||
static const struct kexalg kexalgs[] = {
|
||||
{ KEX_DH1, KEX_DH_GRP1_SHA1, 0, EVP_sha1 },
|
||||
{ KEX_DH14, KEX_DH_GRP14_SHA1, 0, EVP_sha1 },
|
||||
{ KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, EVP_sha1 },
|
||||
{ KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
|
||||
{ KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
|
||||
{ KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
|
||||
#ifdef HAVE_EVP_SHA256
|
||||
{ KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, EVP_sha256 },
|
||||
{ KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
|
||||
#endif
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
{ KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, NID_X9_62_prime256v1, EVP_sha256 },
|
||||
{ KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, EVP_sha384 },
|
||||
{ KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
|
||||
NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
|
||||
{ KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
|
||||
SSH_DIGEST_SHA384 },
|
||||
# ifdef OPENSSL_HAS_NISTP521
|
||||
{ KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, EVP_sha512 },
|
||||
{ KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
|
||||
SSH_DIGEST_SHA512 },
|
||||
# endif
|
||||
#endif
|
||||
{ KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
|
||||
#ifdef HAVE_EVP_SHA256
|
||||
{ KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, EVP_sha256 },
|
||||
{ KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
|
||||
#endif
|
||||
{ NULL, -1, -1, NULL},
|
||||
{ NULL, -1, -1, -1},
|
||||
};
|
||||
|
||||
char *
|
||||
|
@ -406,7 +411,7 @@ choose_kex(Kex *k, char *client, char *server)
|
|||
if ((kexalg = kex_alg_by_name(k->name)) == NULL)
|
||||
fatal("unsupported kex alg %s", k->name);
|
||||
k->kex_type = kexalg->type;
|
||||
k->evp_md = kexalg->mdfunc();
|
||||
k->hash_alg = kexalg->hash_alg;
|
||||
k->ec_nid = kexalg->ec_nid;
|
||||
}
|
||||
|
||||
|
@ -532,27 +537,31 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
|
|||
BIGNUM *shared_secret)
|
||||
{
|
||||
Buffer b;
|
||||
EVP_MD_CTX md;
|
||||
struct ssh_digest_ctx *hashctx;
|
||||
char c = id;
|
||||
u_int have;
|
||||
int mdsz;
|
||||
size_t mdsz;
|
||||
u_char *digest;
|
||||
|
||||
if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0)
|
||||
fatal("bad kex md size %d", mdsz);
|
||||
if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
|
||||
fatal("bad kex md size %zu", mdsz);
|
||||
digest = xmalloc(roundup(need, mdsz));
|
||||
|
||||
buffer_init(&b);
|
||||
buffer_put_bignum2(&b, shared_secret);
|
||||
|
||||
/* K1 = HASH(K || H || "A" || session_id) */
|
||||
EVP_DigestInit(&md, kex->evp_md);
|
||||
if (!(datafellows & SSH_BUG_DERIVEKEY))
|
||||
EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
|
||||
EVP_DigestUpdate(&md, hash, hashlen);
|
||||
EVP_DigestUpdate(&md, &c, 1);
|
||||
EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len);
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL)
|
||||
fatal("%s: ssh_digest_start failed", __func__);
|
||||
if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
|
||||
ssh_digest_update(hashctx, hash, hashlen) != 0 ||
|
||||
ssh_digest_update(hashctx, &c, 1) != 0 ||
|
||||
ssh_digest_update(hashctx, kex->session_id,
|
||||
kex->session_id_len) != 0)
|
||||
fatal("%s: ssh_digest_update failed", __func__);
|
||||
if (ssh_digest_final(hashctx, digest, mdsz) != 0)
|
||||
fatal("%s: ssh_digest_final failed", __func__);
|
||||
ssh_digest_free(hashctx);
|
||||
|
||||
/*
|
||||
* expand key:
|
||||
|
@ -560,12 +569,15 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
|
|||
* Key = K1 || K2 || ... || Kn
|
||||
*/
|
||||
for (have = mdsz; need > have; have += mdsz) {
|
||||
EVP_DigestInit(&md, kex->evp_md);
|
||||
if (!(datafellows & SSH_BUG_DERIVEKEY))
|
||||
EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
|
||||
EVP_DigestUpdate(&md, hash, hashlen);
|
||||
EVP_DigestUpdate(&md, digest, have);
|
||||
EVP_DigestFinal(&md, digest + have, NULL);
|
||||
if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL)
|
||||
fatal("%s: ssh_digest_start failed", __func__);
|
||||
if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
|
||||
ssh_digest_update(hashctx, hash, hashlen) != 0 ||
|
||||
ssh_digest_update(hashctx, digest, have) != 0)
|
||||
fatal("%s: ssh_digest_update failed", __func__);
|
||||
if (ssh_digest_final(hashctx, digest + have, mdsz) != 0)
|
||||
fatal("%s: ssh_digest_final failed", __func__);
|
||||
ssh_digest_free(hashctx);
|
||||
}
|
||||
buffer_free(&b);
|
||||
#ifdef DEBUG_KEX
|
||||
|
@ -615,33 +627,33 @@ void
|
|||
derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
|
||||
u_int8_t cookie[8], u_int8_t id[16])
|
||||
{
|
||||
const EVP_MD *evp_md = EVP_md5();
|
||||
EVP_MD_CTX md;
|
||||
u_int8_t nbuf[2048], obuf[EVP_MAX_MD_SIZE];
|
||||
u_int8_t nbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
|
||||
int len;
|
||||
struct ssh_digest_ctx *hashctx;
|
||||
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL)
|
||||
fatal("%s: ssh_digest_start", __func__);
|
||||
|
||||
len = BN_num_bytes(host_modulus);
|
||||
if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
|
||||
fatal("%s: bad host modulus (len %d)", __func__, len);
|
||||
BN_bn2bin(host_modulus, nbuf);
|
||||
EVP_DigestUpdate(&md, nbuf, len);
|
||||
if (ssh_digest_update(hashctx, nbuf, len) != 0)
|
||||
fatal("%s: ssh_digest_update failed", __func__);
|
||||
|
||||
len = BN_num_bytes(server_modulus);
|
||||
if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
|
||||
fatal("%s: bad server modulus (len %d)", __func__, len);
|
||||
BN_bn2bin(server_modulus, nbuf);
|
||||
EVP_DigestUpdate(&md, nbuf, len);
|
||||
|
||||
EVP_DigestUpdate(&md, cookie, 8);
|
||||
|
||||
EVP_DigestFinal(&md, obuf, NULL);
|
||||
memcpy(id, obuf, 16);
|
||||
if (ssh_digest_update(hashctx, nbuf, len) != 0 ||
|
||||
ssh_digest_update(hashctx, cookie, 8) != 0)
|
||||
fatal("%s: ssh_digest_update failed", __func__);
|
||||
if (ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0)
|
||||
fatal("%s: ssh_digest_final failed", __func__);
|
||||
memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
|
||||
|
||||
memset(nbuf, 0, sizeof(nbuf));
|
||||
memset(obuf, 0, sizeof(obuf));
|
||||
memset(&md, 0, sizeof(md));
|
||||
}
|
||||
|
||||
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
|
||||
|
|
10
kex.h
10
kex.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kex.h,v 1.58 2013/11/07 11:58:27 dtucker Exp $ */
|
||||
/* $OpenBSD: kex.h,v 1.59 2014/01/09 23:20:00 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
|
@ -133,7 +133,7 @@ struct Kex {
|
|||
Buffer peer;
|
||||
sig_atomic_t done;
|
||||
int flags;
|
||||
const EVP_MD *evp_md;
|
||||
int hash_alg;
|
||||
int ec_nid;
|
||||
char *client_version_string;
|
||||
char *server_version_string;
|
||||
|
@ -170,17 +170,17 @@ void
|
|||
kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
|
||||
BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *);
|
||||
void
|
||||
kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *,
|
||||
kexgex_hash(int, char *, char *, char *, int, char *,
|
||||
int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *,
|
||||
BIGNUM *, BIGNUM *, u_char **, u_int *);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
void
|
||||
kex_ecdh_hash(const EVP_MD *, const EC_GROUP *, char *, char *, char *, int,
|
||||
kex_ecdh_hash(int, const EC_GROUP *, char *, char *, char *, int,
|
||||
char *, int, u_char *, int, const EC_POINT *, const EC_POINT *,
|
||||
const BIGNUM *, u_char **, u_int *);
|
||||
#endif
|
||||
void
|
||||
kex_c25519_hash(const EVP_MD *, char *, char *, char *, int,
|
||||
kex_c25519_hash(int, char *, char *, char *, int,
|
||||
char *, int, u_char *, int, const u_char *, const u_char *,
|
||||
const BIGNUM *, u_char **, u_int *);
|
||||
|
||||
|
|
17
kexc25519.c
17
kexc25519.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kexc25519.c,v 1.2 2013/11/02 22:02:14 markus Exp $ */
|
||||
/* $OpenBSD: kexc25519.c,v 1.3 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001, 2013 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
|
@ -41,6 +41,7 @@
|
|||
#include "cipher.h"
|
||||
#include "kex.h"
|
||||
#include "log.h"
|
||||
#include "digest.h"
|
||||
|
||||
extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE],
|
||||
const u_char b[CURVE25519_SIZE], const u_char c[CURVE25519_SIZE])
|
||||
|
@ -78,7 +79,7 @@ kexc25519_shared_key(const u_char key[CURVE25519_SIZE],
|
|||
|
||||
void
|
||||
kex_c25519_hash(
|
||||
const EVP_MD *evp_md,
|
||||
int hash_alg,
|
||||
char *client_version_string,
|
||||
char *server_version_string,
|
||||
char *ckexinit, int ckexinitlen,
|
||||
|
@ -90,8 +91,7 @@ kex_c25519_hash(
|
|||
u_char **hash, u_int *hashlen)
|
||||
{
|
||||
Buffer b;
|
||||
EVP_MD_CTX md;
|
||||
static u_char digest[EVP_MAX_MD_SIZE];
|
||||
static u_char digest[SSH_DIGEST_MAX_LENGTH];
|
||||
|
||||
buffer_init(&b);
|
||||
buffer_put_cstring(&b, client_version_string);
|
||||
|
@ -113,15 +113,14 @@ kex_c25519_hash(
|
|||
#ifdef DEBUG_KEX
|
||||
buffer_dump(&b);
|
||||
#endif
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0)
|
||||
fatal("%s: digest_buffer failed", __func__);
|
||||
|
||||
buffer_free(&b);
|
||||
|
||||
#ifdef DEBUG_KEX
|
||||
dump_digest("hash", digest, EVP_MD_size(evp_md));
|
||||
dump_digest("hash", digest, ssh_digest_bytes(hash_alg));
|
||||
#endif
|
||||
*hash = digest;
|
||||
*hashlen = EVP_MD_size(evp_md);
|
||||
*hashlen = ssh_digest_bytes(hash_alg);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kexc25519c.c,v 1.2 2013/11/02 22:02:14 markus Exp $ */
|
||||
/* $OpenBSD: kexc25519c.c,v 1.3 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
|
@ -97,7 +97,7 @@ kexc25519_client(Kex *kex)
|
|||
|
||||
/* calc and verify H */
|
||||
kex_c25519_hash(
|
||||
kex->evp_md,
|
||||
kex->hash_alg,
|
||||
kex->client_version_string,
|
||||
kex->server_version_string,
|
||||
buffer_ptr(&kex->my), buffer_len(&kex->my),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kexc25519s.c,v 1.2 2013/11/02 22:02:14 markus Exp $ */
|
||||
/* $OpenBSD: kexc25519s.c,v 1.3 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
|
@ -81,7 +81,7 @@ kexc25519_server(Kex *kex)
|
|||
/* calc H */
|
||||
key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
|
||||
kex_c25519_hash(
|
||||
kex->evp_md,
|
||||
kex->hash_alg,
|
||||
kex->client_version_string,
|
||||
kex->server_version_string,
|
||||
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
|
||||
|
|
17
kexdh.c
17
kexdh.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kexdh.c,v 1.23 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/* $OpenBSD: kexdh.c,v 1.24 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -36,6 +36,8 @@
|
|||
#include "key.h"
|
||||
#include "cipher.h"
|
||||
#include "kex.h"
|
||||
#include "digest.h"
|
||||
#include "log.h"
|
||||
|
||||
void
|
||||
kex_dh_hash(
|
||||
|
@ -50,9 +52,7 @@ kex_dh_hash(
|
|||
u_char **hash, u_int *hashlen)
|
||||
{
|
||||
Buffer b;
|
||||
static u_char digest[EVP_MAX_MD_SIZE];
|
||||
const EVP_MD *evp_md = EVP_sha1();
|
||||
EVP_MD_CTX md;
|
||||
static u_char digest[SSH_DIGEST_MAX_LENGTH];
|
||||
|
||||
buffer_init(&b);
|
||||
buffer_put_cstring(&b, client_version_string);
|
||||
|
@ -74,15 +74,14 @@ kex_dh_hash(
|
|||
#ifdef DEBUG_KEX
|
||||
buffer_dump(&b);
|
||||
#endif
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, digest, sizeof(digest)) != 0)
|
||||
fatal("%s: ssh_digest_buffer failed", __func__);
|
||||
|
||||
buffer_free(&b);
|
||||
|
||||
#ifdef DEBUG_KEX
|
||||
dump_digest("hash", digest, EVP_MD_size(evp_md));
|
||||
dump_digest("hash", digest, ssh_digest_bytes(SSH_DIGEST_SHA1));
|
||||
#endif
|
||||
*hash = digest;
|
||||
*hashlen = EVP_MD_size(evp_md);
|
||||
*hashlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
|
||||
}
|
||||
|
|
18
kexecdh.c
18
kexecdh.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kexecdh.c,v 1.4 2013/04/19 01:06:50 djm Exp $ */
|
||||
/* $OpenBSD: kexecdh.c,v 1.5 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
|
@ -44,10 +44,11 @@
|
|||
#include "cipher.h"
|
||||
#include "kex.h"
|
||||
#include "log.h"
|
||||
#include "digest.h"
|
||||
|
||||
void
|
||||
kex_ecdh_hash(
|
||||
const EVP_MD *evp_md,
|
||||
int hash_alg,
|
||||
const EC_GROUP *ec_group,
|
||||
char *client_version_string,
|
||||
char *server_version_string,
|
||||
|
@ -60,8 +61,7 @@ kex_ecdh_hash(
|
|||
u_char **hash, u_int *hashlen)
|
||||
{
|
||||
Buffer b;
|
||||
EVP_MD_CTX md;
|
||||
static u_char digest[EVP_MAX_MD_SIZE];
|
||||
static u_char digest[SSH_DIGEST_MAX_LENGTH];
|
||||
|
||||
buffer_init(&b);
|
||||
buffer_put_cstring(&b, client_version_string);
|
||||
|
@ -83,17 +83,15 @@ kex_ecdh_hash(
|
|||
#ifdef DEBUG_KEX
|
||||
buffer_dump(&b);
|
||||
#endif
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0)
|
||||
fatal("%s: ssh_digest_buffer failed", __func__);
|
||||
|
||||
buffer_free(&b);
|
||||
|
||||
#ifdef DEBUG_KEX
|
||||
dump_digest("hash", digest, EVP_MD_size(evp_md));
|
||||
dump_digest("hash", digest, ssh_digest_bytes(hash_alg));
|
||||
#endif
|
||||
*hash = digest;
|
||||
*hashlen = EVP_MD_size(evp_md);
|
||||
*hashlen = ssh_digest_bytes(hash_alg);
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_HAS_ECC */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kexecdhc.c,v 1.4 2013/05/17 00:13:13 djm Exp $ */
|
||||
/* $OpenBSD: kexecdhc.c,v 1.5 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
|
@ -124,7 +124,7 @@ kexecdh_client(Kex *kex)
|
|||
|
||||
/* calc and verify H */
|
||||
kex_ecdh_hash(
|
||||
kex->evp_md,
|
||||
kex->hash_alg,
|
||||
group,
|
||||
kex->client_version_string,
|
||||
kex->server_version_string,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kexecdhs.c,v 1.7 2013/11/02 22:24:24 markus Exp $ */
|
||||
/* $OpenBSD: kexecdhs.c,v 1.8 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
|
@ -109,7 +109,7 @@ kexecdh_server(Kex *kex)
|
|||
/* calc H */
|
||||
key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
|
||||
kex_ecdh_hash(
|
||||
kex->evp_md,
|
||||
kex->hash_alg,
|
||||
group,
|
||||
kex->client_version_string,
|
||||
kex->server_version_string,
|
||||
|
|
24
kexgex.c
24
kexgex.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kexgex.c,v 1.27 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/* $OpenBSD: kexgex.c,v 1.28 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
|
@ -36,10 +36,12 @@
|
|||
#include "cipher.h"
|
||||
#include "kex.h"
|
||||
#include "ssh2.h"
|
||||
#include "digest.h"
|
||||
#include "log.h"
|
||||
|
||||
void
|
||||
kexgex_hash(
|
||||
const EVP_MD *evp_md,
|
||||
int hash_alg,
|
||||
char *client_version_string,
|
||||
char *server_version_string,
|
||||
char *ckexinit, int ckexinitlen,
|
||||
|
@ -52,8 +54,7 @@ kexgex_hash(
|
|||
u_char **hash, u_int *hashlen)
|
||||
{
|
||||
Buffer b;
|
||||
static u_char digest[EVP_MAX_MD_SIZE];
|
||||
EVP_MD_CTX md;
|
||||
static u_char digest[SSH_DIGEST_MAX_LENGTH];
|
||||
|
||||
buffer_init(&b);
|
||||
buffer_put_cstring(&b, client_version_string);
|
||||
|
@ -84,15 +85,14 @@ kexgex_hash(
|
|||
#ifdef DEBUG_KEXDH
|
||||
buffer_dump(&b);
|
||||
#endif
|
||||
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0)
|
||||
fatal("%s: ssh_digest_buffer failed", __func__);
|
||||
|
||||
buffer_free(&b);
|
||||
*hash = digest;
|
||||
*hashlen = EVP_MD_size(evp_md);
|
||||
#ifdef DEBUG_KEXDH
|
||||
dump_digest("hash", digest, *hashlen);
|
||||
|
||||
#ifdef DEBUG_KEX
|
||||
dump_digest("hash", digest, ssh_digest_bytes(hash_alg));
|
||||
#endif
|
||||
*hash = digest;
|
||||
*hashlen = ssh_digest_bytes(hash_alg);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kexgexc.c,v 1.13 2013/05/17 00:13:13 djm Exp $ */
|
||||
/* $OpenBSD: kexgexc.c,v 1.14 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
|
@ -170,7 +170,7 @@ kexgex_client(Kex *kex)
|
|||
|
||||
/* calc and verify H */
|
||||
kexgex_hash(
|
||||
kex->evp_md,
|
||||
kex->hash_alg,
|
||||
kex->client_version_string,
|
||||
kex->server_version_string,
|
||||
buffer_ptr(&kex->my), buffer_len(&kex->my),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kexgexs.c,v 1.16 2013/07/19 07:37:48 markus Exp $ */
|
||||
/* $OpenBSD: kexgexs.c,v 1.17 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
|
@ -160,7 +160,7 @@ kexgex_server(Kex *kex)
|
|||
|
||||
/* calc H */
|
||||
kexgex_hash(
|
||||
kex->evp_md,
|
||||
kex->hash_alg,
|
||||
kex->client_version_string,
|
||||
kex->server_version_string,
|
||||
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
|
||||
|
|
42
key.c
42
key.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: key.c,v 1.114 2013/12/29 04:20:04 djm Exp $ */
|
||||
/* $OpenBSD: key.c,v 1.115 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* read_bignum():
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -56,6 +56,7 @@
|
|||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "ssh2.h"
|
||||
#include "digest.h"
|
||||
|
||||
static int to_blob(const Key *, u_char **, u_int *, int);
|
||||
static Key *key_from_blob2(const u_char *, u_int, int);
|
||||
|
@ -358,30 +359,26 @@ u_char*
|
|||
key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
|
||||
u_int *dgst_raw_length)
|
||||
{
|
||||
const EVP_MD *md = NULL;
|
||||
EVP_MD_CTX ctx;
|
||||
u_char *blob = NULL;
|
||||
u_char *retval = NULL;
|
||||
u_int len = 0;
|
||||
int nlen, elen;
|
||||
int nlen, elen, hash_alg = -1;
|
||||
|
||||
*dgst_raw_length = 0;
|
||||
|
||||
/* XXX switch to DIGEST_* directly? */
|
||||
switch (dgst_type) {
|
||||
case SSH_FP_MD5:
|
||||
md = EVP_md5();
|
||||
hash_alg = SSH_DIGEST_MD5;
|
||||
break;
|
||||
case SSH_FP_SHA1:
|
||||
md = EVP_sha1();
|
||||
hash_alg = SSH_DIGEST_SHA1;
|
||||
break;
|
||||
#ifdef HAVE_EVP_SHA256
|
||||
case SSH_FP_SHA256:
|
||||
md = EVP_sha256();
|
||||
hash_alg = SSH_DIGEST_SHA256;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
fatal("key_fingerprint_raw: bad digest type %d",
|
||||
dgst_type);
|
||||
fatal("%s: bad digest type %d", __func__, dgst_type);
|
||||
}
|
||||
switch (k->type) {
|
||||
case KEY_RSA1:
|
||||
|
@ -410,18 +407,19 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
|
|||
case KEY_UNSPEC:
|
||||
return retval;
|
||||
default:
|
||||
fatal("key_fingerprint_raw: bad key type %d", k->type);
|
||||
fatal("%s: bad key type %d", __func__, k->type);
|
||||
break;
|
||||
}
|
||||
if (blob != NULL) {
|
||||
retval = xmalloc(EVP_MAX_MD_SIZE);
|
||||
EVP_DigestInit(&ctx, md);
|
||||
EVP_DigestUpdate(&ctx, blob, len);
|
||||
EVP_DigestFinal(&ctx, retval, dgst_raw_length);
|
||||
retval = xmalloc(SSH_DIGEST_MAX_LENGTH);
|
||||
if ((ssh_digest_memory(hash_alg, blob, len,
|
||||
retval, SSH_DIGEST_MAX_LENGTH)) != 0)
|
||||
fatal("%s: digest_memory failed", __func__);
|
||||
memset(blob, 0, len);
|
||||
free(blob);
|
||||
*dgst_raw_length = ssh_digest_bytes(hash_alg);
|
||||
} else {
|
||||
fatal("key_fingerprint_raw: blob is null");
|
||||
fatal("%s: blob is null", __func__);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
@ -2211,8 +2209,8 @@ key_curve_nid_to_name(int nid)
|
|||
}
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
const EVP_MD *
|
||||
key_ec_nid_to_evpmd(int nid)
|
||||
int
|
||||
key_ec_nid_to_hash_alg(int nid)
|
||||
{
|
||||
int kbits = key_curve_nid_to_bits(nid);
|
||||
|
||||
|
@ -2220,11 +2218,11 @@ key_ec_nid_to_evpmd(int nid)
|
|||
fatal("%s: invalid nid %d", __func__, nid);
|
||||
/* RFC5656 section 6.2.1 */
|
||||
if (kbits <= 256)
|
||||
return EVP_sha256();
|
||||
return SSH_DIGEST_SHA256;
|
||||
else if (kbits <= 384)
|
||||
return EVP_sha384();
|
||||
return SSH_DIGEST_SHA384;
|
||||
else
|
||||
return EVP_sha512();
|
||||
return SSH_DIGEST_SHA512;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
4
key.h
4
key.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: key.h,v 1.40 2013/12/06 13:39:49 markus Exp $ */
|
||||
/* $OpenBSD: key.h,v 1.41 2014/01/09 23:20:00 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
|
@ -131,7 +131,7 @@ u_int key_curve_nid_to_bits(int);
|
|||
int key_ecdsa_bits_to_nid(int);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
int key_ecdsa_key_to_nid(EC_KEY *);
|
||||
const EVP_MD *key_ec_nid_to_evpmd(int nid);
|
||||
int key_ec_nid_to_hash_alg(int nid);
|
||||
int key_ec_validate_public(const EC_GROUP *, const EC_POINT *);
|
||||
int key_ec_validate_private(const EC_KEY *);
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: roaming_client.c,v 1.6 2013/10/16 02:31:46 djm Exp $ */
|
||||
/* $OpenBSD: roaming_client.c,v 1.7 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2004-2009 AppGate Network Security AB
|
||||
*
|
||||
|
@ -48,6 +48,7 @@
|
|||
#include "roaming.h"
|
||||
#include "ssh2.h"
|
||||
#include "sshconnect.h"
|
||||
#include "digest.h"
|
||||
|
||||
/* import */
|
||||
extern Options options;
|
||||
|
@ -90,10 +91,8 @@ request_roaming(void)
|
|||
static void
|
||||
roaming_auth_required(void)
|
||||
{
|
||||
u_char digest[SHA_DIGEST_LENGTH];
|
||||
EVP_MD_CTX md;
|
||||
u_char digest[SSH_DIGEST_MAX_LENGTH];
|
||||
Buffer b;
|
||||
const EVP_MD *evp_md = EVP_sha1();
|
||||
u_int64_t chall, oldchall;
|
||||
|
||||
chall = packet_get_int64();
|
||||
|
@ -107,14 +106,13 @@ roaming_auth_required(void)
|
|||
buffer_init(&b);
|
||||
buffer_put_int64(&b, cookie);
|
||||
buffer_put_int64(&b, chall);
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, digest, sizeof(digest)) != 0)
|
||||
fatal("%s: ssh_digest_buffer failed", __func__);
|
||||
buffer_free(&b);
|
||||
|
||||
packet_start(SSH2_MSG_KEX_ROAMING_AUTH);
|
||||
packet_put_int64(key1 ^ get_recv_bytes());
|
||||
packet_put_raw(digest, sizeof(digest));
|
||||
packet_put_raw(digest, ssh_digest_bytes(SSH_DIGEST_SHA1));
|
||||
packet_send();
|
||||
|
||||
oldkey1 = key1;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: roaming_common.c,v 1.11 2013/11/03 10:37:19 djm Exp $ */
|
||||
/* $OpenBSD: roaming_common.c,v 1.12 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2004-2009 AppGate Network Security AB
|
||||
*
|
||||
|
@ -36,6 +36,7 @@
|
|||
#include "cipher.h"
|
||||
#include "buffer.h"
|
||||
#include "roaming.h"
|
||||
#include "digest.h"
|
||||
|
||||
static size_t out_buf_size = 0;
|
||||
static char *out_buf = NULL;
|
||||
|
@ -225,9 +226,7 @@ resend_bytes(int fd, u_int64_t *offset)
|
|||
void
|
||||
calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge)
|
||||
{
|
||||
const EVP_MD *md = EVP_sha1();
|
||||
EVP_MD_CTX ctx;
|
||||
u_char hash[EVP_MAX_MD_SIZE];
|
||||
u_char hash[SSH_DIGEST_MAX_LENGTH];
|
||||
Buffer b;
|
||||
|
||||
buffer_init(&b);
|
||||
|
@ -235,12 +234,11 @@ calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge)
|
|||
buffer_put_int64(&b, cookie);
|
||||
buffer_put_int64(&b, challenge);
|
||||
|
||||
EVP_DigestInit(&ctx, md);
|
||||
EVP_DigestUpdate(&ctx, buffer_ptr(&b), buffer_len(&b));
|
||||
EVP_DigestFinal(&ctx, hash, NULL);
|
||||
if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, hash, sizeof(hash)) != 0)
|
||||
fatal("%s: digest_buffer failed", __func__);
|
||||
|
||||
buffer_clear(&b);
|
||||
buffer_append(&b, hash, EVP_MD_size(md));
|
||||
buffer_append(&b, hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
|
||||
*key = buffer_get_int64(&b);
|
||||
buffer_free(&b);
|
||||
}
|
||||
|
|
57
schnorr.c
57
schnorr.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: schnorr.c,v 1.8 2013/11/08 00:39:15 djm Exp $ */
|
||||
/* $OpenBSD: schnorr.c,v 1.9 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
||||
*
|
||||
|
@ -41,6 +41,7 @@
|
|||
#include "log.h"
|
||||
|
||||
#include "schnorr.h"
|
||||
#include "digest.h"
|
||||
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
|
@ -57,12 +58,12 @@
|
|||
|
||||
/*
|
||||
* Calculate hash component of Schnorr signature H(g || g^v || g^x || id)
|
||||
* using the hash function defined by "evp_md". Returns signature as
|
||||
* using the hash function defined by "hash_alg". Returns signature as
|
||||
* bignum or NULL on error.
|
||||
*/
|
||||
static BIGNUM *
|
||||
schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
|
||||
const EVP_MD *evp_md, const BIGNUM *g_v, const BIGNUM *g_x,
|
||||
int hash_alg, const BIGNUM *g_v, const BIGNUM *g_x,
|
||||
const u_char *id, u_int idlen)
|
||||
{
|
||||
u_char *digest;
|
||||
|
@ -88,7 +89,7 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
|
|||
|
||||
SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
|
||||
"%s: hashblob", __func__));
|
||||
if (hash_buffer(buffer_ptr(&b), buffer_len(&b), evp_md,
|
||||
if (hash_buffer(buffer_ptr(&b), buffer_len(&b), hash_alg,
|
||||
&digest, &digest_len) != 0) {
|
||||
error("%s: hash_buffer", __func__);
|
||||
goto out;
|
||||
|
@ -113,7 +114,7 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
|
|||
/*
|
||||
* Generate Schnorr signature to prove knowledge of private value 'x' used
|
||||
* in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
|
||||
* using the hash function "evp_md".
|
||||
* using the hash function "hash_alg".
|
||||
* 'idlen' bytes from 'id' will be included in the signature hash as an anti-
|
||||
* replay salt.
|
||||
*
|
||||
|
@ -123,7 +124,7 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
|
|||
*/
|
||||
int
|
||||
schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
const EVP_MD *evp_md, const BIGNUM *x, const BIGNUM *g_x,
|
||||
int hash_alg, const BIGNUM *x, const BIGNUM *g_x,
|
||||
const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p)
|
||||
{
|
||||
int success = -1;
|
||||
|
@ -173,7 +174,7 @@ schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
|||
SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
|
||||
|
||||
/* h = H(g || g^v || g^x || id) */
|
||||
if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, g_v, g_x,
|
||||
if ((h = schnorr_hash(grp_p, grp_q, grp_g, hash_alg, g_v, g_x,
|
||||
id, idlen)) == NULL) {
|
||||
error("%s: schnorr_hash failed", __func__);
|
||||
goto out;
|
||||
|
@ -223,7 +224,7 @@ schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
|||
Buffer b;
|
||||
BIGNUM *r, *e;
|
||||
|
||||
if (schnorr_sign(grp_p, grp_q, grp_g, EVP_sha256(),
|
||||
if (schnorr_sign(grp_p, grp_q, grp_g, SSH_DIGEST_SHA256,
|
||||
x, g_x, id, idlen, &r, &e) != 0)
|
||||
return -1;
|
||||
|
||||
|
@ -248,13 +249,13 @@ schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
|||
/*
|
||||
* Verify Schnorr signature { r (v - xh mod q), e (g^v mod p) } against
|
||||
* public exponent g_x (g^x) under group defined by 'grp_p', 'grp_q' and
|
||||
* 'grp_g' using hash "evp_md".
|
||||
* 'grp_g' using hash "hash_alg".
|
||||
* Signature hash will be salted with 'idlen' bytes from 'id'.
|
||||
* Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
|
||||
*/
|
||||
int
|
||||
schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
const EVP_MD *evp_md, const BIGNUM *g_x, const u_char *id, u_int idlen,
|
||||
int hash_alg, const BIGNUM *g_x, const u_char *id, u_int idlen,
|
||||
const BIGNUM *r, const BIGNUM *e)
|
||||
{
|
||||
int success = -1;
|
||||
|
@ -302,7 +303,7 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
|||
|
||||
SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__));
|
||||
/* h = H(g || g^v || g^x || id) */
|
||||
if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x,
|
||||
if ((h = schnorr_hash(grp_p, grp_q, grp_g, hash_alg, e, g_x,
|
||||
id, idlen)) == NULL) {
|
||||
error("%s: schnorr_hash failed", __func__);
|
||||
goto out;
|
||||
|
@ -385,7 +386,7 @@ schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = schnorr_verify(grp_p, grp_q, grp_g, EVP_sha256(),
|
||||
ret = schnorr_verify(grp_p, grp_q, grp_g, SSH_DIGEST_SHA256,
|
||||
g_x, id, idlen, r, e);
|
||||
out:
|
||||
BN_clear_free(e);
|
||||
|
@ -443,43 +444,33 @@ bn_rand_range_gt_one(const BIGNUM *high)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* XXX convert all callers of this to use ssh_digest_memory() directly */
|
||||
/*
|
||||
* Hash contents of buffer 'b' with hash 'md'. Returns 0 on success,
|
||||
* with digest via 'digestp' (caller to free) and length via 'lenp'.
|
||||
* Returns -1 on failure.
|
||||
*/
|
||||
int
|
||||
hash_buffer(const u_char *buf, u_int len, const EVP_MD *md,
|
||||
hash_buffer(const u_char *buf, u_int len, int hash_alg,
|
||||
u_char **digestp, u_int *lenp)
|
||||
{
|
||||
u_char digest[EVP_MAX_MD_SIZE];
|
||||
u_int digest_len;
|
||||
EVP_MD_CTX evp_md_ctx;
|
||||
int success = -1;
|
||||
u_char digest[SSH_DIGEST_MAX_LENGTH];
|
||||
u_int digest_len = ssh_digest_bytes(hash_alg);
|
||||
|
||||
EVP_MD_CTX_init(&evp_md_ctx);
|
||||
|
||||
if (EVP_DigestInit_ex(&evp_md_ctx, md, NULL) != 1) {
|
||||
error("%s: EVP_DigestInit_ex", __func__);
|
||||
goto out;
|
||||
if (digest_len == 0) {
|
||||
error("%s: invalid hash", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (EVP_DigestUpdate(&evp_md_ctx, buf, len) != 1) {
|
||||
error("%s: EVP_DigestUpdate", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (EVP_DigestFinal_ex(&evp_md_ctx, digest, &digest_len) != 1) {
|
||||
error("%s: EVP_DigestFinal_ex", __func__);
|
||||
goto out;
|
||||
if (ssh_digest_memory(hash_alg, buf, len, digest, digest_len) != 0) {
|
||||
error("%s: digest_memory failed", __func__);
|
||||
return -1;
|
||||
}
|
||||
*digestp = xmalloc(digest_len);
|
||||
*lenp = digest_len;
|
||||
memcpy(*digestp, digest, *lenp);
|
||||
success = 0;
|
||||
out:
|
||||
EVP_MD_CTX_cleanup(&evp_md_ctx);
|
||||
bzero(digest, sizeof(digest));
|
||||
digest_len = 0;
|
||||
return success;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* print formatted string followed by bignum */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: schnorr.h,v 1.1 2009/03/05 07:18:19 djm Exp $ */
|
||||
/* $OpenBSD: schnorr.h,v 1.2 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Damien Miller. All rights reserved.
|
||||
*
|
||||
|
@ -27,7 +27,7 @@ struct modp_group {
|
|||
};
|
||||
|
||||
BIGNUM *bn_rand_range_gt_one(const BIGNUM *high);
|
||||
int hash_buffer(const u_char *, u_int, const EVP_MD *, u_char **, u_int *);
|
||||
int hash_buffer(const u_char *, u_int, int, u_char **, u_int *);
|
||||
void debug3_bn(const BIGNUM *, const char *, ...)
|
||||
__attribute__((__nonnull__ (2)))
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
|
@ -40,7 +40,7 @@ void modp_group_free(struct modp_group *);
|
|||
/* Signature and verification functions */
|
||||
int
|
||||
schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
const EVP_MD *evp_md, const BIGNUM *x, const BIGNUM *g_x,
|
||||
int hash_alg, const BIGNUM *x, const BIGNUM *g_x,
|
||||
const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p);
|
||||
int
|
||||
schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
|
@ -48,7 +48,7 @@ schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
|||
u_char **sig, u_int *siglen);
|
||||
int
|
||||
schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
const EVP_MD *evp_md, const BIGNUM *g_x, const u_char *id, u_int idlen,
|
||||
int hash_alg, const BIGNUM *g_x, const u_char *id, u_int idlen,
|
||||
const BIGNUM *r, const BIGNUM *e);
|
||||
int
|
||||
schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
|
||||
|
|
31
ssh-dss.c
31
ssh-dss.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-dss.c,v 1.29 2013/12/27 22:30:17 djm Exp $ */
|
||||
/* $OpenBSD: ssh-dss.c,v 1.30 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -38,6 +38,7 @@
|
|||
#include "compat.h"
|
||||
#include "log.h"
|
||||
#include "key.h"
|
||||
#include "digest.h"
|
||||
|
||||
#define INTBLOB_LEN 20
|
||||
#define SIGBLOB_LEN (2*INTBLOB_LEN)
|
||||
|
@ -47,10 +48,8 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
|
|||
const u_char *data, u_int datalen)
|
||||
{
|
||||
DSA_SIG *sig;
|
||||
const EVP_MD *evp_md = EVP_sha1();
|
||||
EVP_MD_CTX md;
|
||||
u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
|
||||
u_int rlen, slen, len, dlen;
|
||||
u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
|
||||
u_int rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
|
||||
Buffer b;
|
||||
|
||||
if (key == NULL || key_type_plain(key->type) != KEY_DSA ||
|
||||
|
@ -59,9 +58,11 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
|
|||
return -1;
|
||||
}
|
||||
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, data, datalen);
|
||||
EVP_DigestFinal(&md, digest, &dlen);
|
||||
if (ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
|
||||
digest, sizeof(digest)) != 0) {
|
||||
error("%s: ssh_digest_memory failed", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sig = DSA_do_sign(digest, dlen, key->dsa);
|
||||
memset(digest, 'd', sizeof(digest));
|
||||
|
@ -111,10 +112,8 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
|||
const u_char *data, u_int datalen)
|
||||
{
|
||||
DSA_SIG *sig;
|
||||
const EVP_MD *evp_md = EVP_sha1();
|
||||
EVP_MD_CTX md;
|
||||
u_char digest[EVP_MAX_MD_SIZE], *sigblob;
|
||||
u_int len, dlen;
|
||||
u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob;
|
||||
u_int len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
|
||||
int rlen, ret;
|
||||
Buffer b;
|
||||
|
||||
|
@ -173,9 +172,11 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
|||
free(sigblob);
|
||||
|
||||
/* sha1 the data */
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, data, datalen);
|
||||
EVP_DigestFinal(&md, digest, &dlen);
|
||||
if (ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
|
||||
digest, sizeof(digest)) != 0) {
|
||||
error("%s: digest_memory failed", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = DSA_do_verify(digest, dlen, sig, key->dsa);
|
||||
memset(digest, 'd', sizeof(digest));
|
||||
|
|
42
ssh-ecdsa.c
42
ssh-ecdsa.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-ecdsa.c,v 1.7 2013/12/27 22:30:17 djm Exp $ */
|
||||
/* $OpenBSD: ssh-ecdsa.c,v 1.8 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
|
@ -42,15 +42,15 @@
|
|||
#include "compat.h"
|
||||
#include "log.h"
|
||||
#include "key.h"
|
||||
#include "digest.h"
|
||||
|
||||
int
|
||||
ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp,
|
||||
const u_char *data, u_int datalen)
|
||||
{
|
||||
ECDSA_SIG *sig;
|
||||
const EVP_MD *evp_md;
|
||||
EVP_MD_CTX md;
|
||||
u_char digest[EVP_MAX_MD_SIZE];
|
||||
int hash_alg;
|
||||
u_char digest[SSH_DIGEST_MAX_LENGTH];
|
||||
u_int len, dlen;
|
||||
Buffer b, bb;
|
||||
|
||||
|
@ -60,10 +60,16 @@ ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp,
|
|||
return -1;
|
||||
}
|
||||
|
||||
evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid);
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, data, datalen);
|
||||
EVP_DigestFinal(&md, digest, &dlen);
|
||||
hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid);
|
||||
if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
|
||||
error("%s: bad hash algorithm %d", __func__, hash_alg);
|
||||
return -1;
|
||||
}
|
||||
if (ssh_digest_memory(hash_alg, data, datalen,
|
||||
digest, sizeof(digest)) != 0) {
|
||||
error("%s: digest_memory failed", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sig = ECDSA_do_sign(digest, dlen, key->ecdsa);
|
||||
memset(digest, 'd', sizeof(digest));
|
||||
|
@ -98,9 +104,8 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
|||
const u_char *data, u_int datalen)
|
||||
{
|
||||
ECDSA_SIG *sig;
|
||||
const EVP_MD *evp_md;
|
||||
EVP_MD_CTX md;
|
||||
u_char digest[EVP_MAX_MD_SIZE], *sigblob;
|
||||
int hash_alg;
|
||||
u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob;
|
||||
u_int len, dlen;
|
||||
int rlen, ret;
|
||||
Buffer b, bb;
|
||||
|
@ -112,8 +117,6 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
|||
return -1;
|
||||
}
|
||||
|
||||
evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid);
|
||||
|
||||
/* fetch signature */
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, signature, signaturelen);
|
||||
|
@ -154,9 +157,16 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
|||
free(sigblob);
|
||||
|
||||
/* hash the data */
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, data, datalen);
|
||||
EVP_DigestFinal(&md, digest, &dlen);
|
||||
hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid);
|
||||
if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
|
||||
error("%s: bad hash algorithm %d", __func__, hash_alg);
|
||||
return -1;
|
||||
}
|
||||
if (ssh_digest_memory(hash_alg, data, datalen,
|
||||
digest, sizeof(digest)) != 0) {
|
||||
error("%s: digest_memory failed", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa);
|
||||
memset(digest, 'd', sizeof(digest));
|
||||
|
|
54
ssh-rsa.c
54
ssh-rsa.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-rsa.c,v 1.49 2013/12/30 23:52:27 djm Exp $ */
|
||||
/* $OpenBSD: ssh-rsa.c,v 1.50 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
|
||||
*
|
||||
|
@ -32,6 +32,7 @@
|
|||
#include "compat.h"
|
||||
#include "misc.h"
|
||||
#include "ssh.h"
|
||||
#include "digest.h"
|
||||
|
||||
static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *);
|
||||
|
||||
|
@ -40,9 +41,8 @@ int
|
|||
ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
|
||||
const u_char *data, u_int datalen)
|
||||
{
|
||||
const EVP_MD *evp_md;
|
||||
EVP_MD_CTX md;
|
||||
u_char digest[EVP_MAX_MD_SIZE], *sig;
|
||||
int hash_alg;
|
||||
u_char digest[SSH_DIGEST_MAX_LENGTH], *sig;
|
||||
u_int slen, dlen, len;
|
||||
int ok, nid;
|
||||
Buffer b;
|
||||
|
@ -53,14 +53,18 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* hash the data */
|
||||
hash_alg = SSH_DIGEST_SHA1;
|
||||
nid = NID_sha1;
|
||||
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
|
||||
error("%s: EVP_get_digestbynid %d failed", __func__, nid);
|
||||
if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
|
||||
error("%s: bad hash algorithm %d", __func__, hash_alg);
|
||||
return -1;
|
||||
}
|
||||
if (ssh_digest_memory(hash_alg, data, datalen,
|
||||
digest, sizeof(digest)) != 0) {
|
||||
error("%s: ssh_digest_memory failed", __func__);
|
||||
return -1;
|
||||
}
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, data, datalen);
|
||||
EVP_DigestFinal(&md, digest, &dlen);
|
||||
|
||||
slen = RSA_size(key->rsa);
|
||||
sig = xmalloc(slen);
|
||||
|
@ -109,12 +113,11 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
|||
const u_char *data, u_int datalen)
|
||||
{
|
||||
Buffer b;
|
||||
const EVP_MD *evp_md;
|
||||
EVP_MD_CTX md;
|
||||
int hash_alg;
|
||||
char *ktype;
|
||||
u_char digest[EVP_MAX_MD_SIZE], *sigblob;
|
||||
u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob;
|
||||
u_int len, dlen, modlen;
|
||||
int rlen, ret, nid;
|
||||
int rlen, ret;
|
||||
|
||||
if (key == NULL || key_type_plain(key->type) != KEY_RSA ||
|
||||
key->rsa == NULL) {
|
||||
|
@ -161,17 +164,20 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
|||
memset(sigblob, 0, diff);
|
||||
len = modlen;
|
||||
}
|
||||
nid = NID_sha1;
|
||||
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
|
||||
error("%s: EVP_get_digestbynid %d failed", __func__, nid);
|
||||
free(sigblob);
|
||||
/* hash the data */
|
||||
hash_alg = SSH_DIGEST_SHA1;
|
||||
if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
|
||||
error("%s: bad hash algorithm %d", __func__, hash_alg);
|
||||
return -1;
|
||||
}
|
||||
if (ssh_digest_memory(hash_alg, data, datalen,
|
||||
digest, sizeof(digest)) != 0) {
|
||||
error("%s: ssh_digest_memory failed", __func__);
|
||||
return -1;
|
||||
}
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, data, datalen);
|
||||
EVP_DigestFinal(&md, digest, &dlen);
|
||||
|
||||
ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key->rsa);
|
||||
ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,
|
||||
key->rsa);
|
||||
memset(digest, 'd', sizeof(digest));
|
||||
memset(sigblob, 's', len);
|
||||
free(sigblob);
|
||||
|
@ -198,7 +204,7 @@ static const u_char id_sha1[] = {
|
|||
};
|
||||
|
||||
static int
|
||||
openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
|
||||
openssh_RSA_verify(int hash_alg, u_char *hash, u_int hashlen,
|
||||
u_char *sigbuf, u_int siglen, RSA *rsa)
|
||||
{
|
||||
u_int ret, rsasize, oidlen = 0, hlen = 0;
|
||||
|
@ -207,8 +213,8 @@ openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
|
|||
u_char *decrypted = NULL;
|
||||
|
||||
ret = 0;
|
||||
switch (type) {
|
||||
case NID_sha1:
|
||||
switch (hash_alg) {
|
||||
case SSH_DIGEST_SHA1:
|
||||
oid = id_sha1;
|
||||
oidlen = sizeof(id_sha1);
|
||||
hlen = 20;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshconnect2.c,v 1.200 2013/12/30 23:52:28 djm Exp $ */
|
||||
/* $OpenBSD: sshconnect2.c,v 1.201 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
||||
|
@ -1006,7 +1006,7 @@ jpake_password_to_secret(Authctxt *authctxt, const char *crypt_scheme,
|
|||
debug3("%s: crypted = %s", __func__, crypted);
|
||||
#endif
|
||||
|
||||
if (hash_buffer(crypted, strlen(crypted), EVP_sha256(),
|
||||
if (hash_buffer(crypted, strlen(crypted), SSH_DIGEST_SHA1,
|
||||
&secret, &secret_len) != 0)
|
||||
fatal("%s: hash_buffer", __func__);
|
||||
|
||||
|
|
Loading…
Reference in New Issue