- (djm) [authfd.c authfile.c bufec.c buffer.h configure.ac kex.h kexecdh.c]

[kexecdhc.c kexecdhs.c key.c key.h myproposal.h packet.c readconf.c]
   [ssh-agent.c ssh-ecdsa.c ssh-keygen.c ssh.c] Disable ECDH and ECDSA on
   platforms that don't have the requisite OpenSSL support. ok dtucker@
This commit is contained in:
Damien Miller 2010-09-10 11:39:26 +10:00
parent 041ab7c1e7
commit 6af914a15c
19 changed files with 201 additions and 37 deletions

View File

@ -62,6 +62,10 @@
client.
ok naddy@
- (djm) [authfd.c authfile.c bufec.c buffer.h configure.ac kex.h kexecdh.c]
[kexecdhc.c kexecdhs.c key.c key.h myproposal.h packet.c readconf.c]
[ssh-agent.c ssh-ecdsa.c ssh-keygen.c ssh.c] Disable ECDH and ECDSA on
platforms that don't have the requisite OpenSSL support. ok dtucker@
20100831
- OpenBSD CVS Sync

View File

@ -509,6 +509,7 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
buffer_len(&key->cert->certblob));
buffer_put_bignum2(b, key->dsa->priv_key);
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid));
buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
@ -522,6 +523,7 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
buffer_len(&key->cert->certblob));
buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
break;
#endif
}
buffer_put_cstring(b, comment);
}

View File

@ -213,10 +213,12 @@ key_save_private_pem(Key *key, const char *filename, const char *_passphrase,
success = PEM_write_DSAPrivateKey(fp, key->dsa,
cipher, passphrase, len, NULL, NULL);
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
success = PEM_write_ECPrivateKey(fp, key->ecdsa,
cipher, passphrase, len, NULL, NULL);
break;
#endif
case KEY_RSA:
success = PEM_write_RSAPrivateKey(fp, key->rsa,
cipher, passphrase, len, NULL, NULL);
@ -515,6 +517,7 @@ key_load_private_pem(int fd, int type, const char *passphrase,
#ifdef DEBUG_PK
DSA_print_fp(stderr, prv->dsa, 8);
#endif
#ifdef OPENSSL_HAS_ECC
} else if (pk->type == EVP_PKEY_EC &&
(type == KEY_UNSPEC||type==KEY_ECDSA)) {
prv = key_new(KEY_UNSPEC);
@ -538,6 +541,7 @@ key_load_private_pem(int fd, int type, const char *passphrase,
if (prv->ecdsa != NULL)
key_dump_ec_key(prv->ecdsa);
#endif
#endif /* OPENSSL_HAS_ECC */
} else {
error("PEM_read_PrivateKey: mismatch or "
"unknown EVP_PKEY save_type %d", pk->save_type);

View File

@ -17,6 +17,8 @@
#include "includes.h"
#ifdef OPENSSL_HAS_ECC
#include <sys/types.h>
#include <openssl/bn.h>
@ -141,3 +143,4 @@ buffer_get_ecpoint(Buffer *buffer, const EC_GROUP *curve,
fatal("%s: buffer error", __func__);
}
#endif /* OPENSSL_HAS_ECC */

View File

@ -86,11 +86,13 @@ char *buffer_get_cstring_ret(Buffer *, u_int *);
void *buffer_get_string_ptr_ret(Buffer *, u_int *);
int buffer_get_char_ret(char *, Buffer *);
#ifdef OPENSSL_HAS_ECC
#include <openssl/ec.h>
int buffer_put_ecpoint_ret(Buffer *, const EC_GROUP *, const EC_POINT *);
void buffer_put_ecpoint(Buffer *, const EC_GROUP *, const EC_POINT *);
int buffer_get_ecpoint_ret(Buffer *, const EC_GROUP *, EC_POINT *);
void buffer_get_ecpoint(Buffer *, const EC_GROUP *, EC_POINT *);
#endif
#endif /* BUFFER_H */

View File

@ -1,4 +1,4 @@
# $Id: configure.ac,v 1.451 2010/08/16 03:15:23 dtucker Exp $
# $Id: configure.ac,v 1.452 2010/09/10 01:39:27 djm Exp $
#
# Copyright (c) 1999-2004 Damien Miller
#
@ -15,7 +15,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org)
AC_REVISION($Revision: 1.451 $)
AC_REVISION($Revision: 1.452 $)
AC_CONFIG_SRCDIR([ssh.c])
AC_CONFIG_HEADER(config.h)
@ -2158,6 +2158,28 @@ fi
# Search for SHA256 support in libc and/or OpenSSL
AC_CHECK_FUNCS(SHA256_Update EVP_sha256)
# Check complete ECC support in OpenSSL
AC_MSG_CHECKING([whether OpenSSL has complete ECC support])
AC_LINK_IFELSE(
[AC_LANG_SOURCE([[
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
int main(void) {
EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1);
const EVP_MD *m = EVP_sha512(); /* We need this too */
}
]])],
[
AC_MSG_RESULT(yes)
AC_DEFINE(OPENSSL_HAS_ECC, 1,
[libcrypto includes complete ECC support])
],
[
AC_MSG_RESULT(no)
]
)
saved_LIBS="$LIBS"
AC_CHECK_LIB(iaf, ia_openinfo, [
LIBS="$LIBS -liaf"

5
kex.h
View File

@ -159,13 +159,16 @@ void
kexgex_hash(const EVP_MD *, 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,
char *, int, u_char *, int, const EC_POINT *, const EC_POINT *,
const BIGNUM *, u_char **, u_int *);
int kex_ecdh_name_to_nid(const char *);
const EVP_MD *kex_ecdh_name_to_evpmd(const char *);
#else
# define kex_ecdh_name_to_evpmd(x) NULL
#endif
void
derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]);

View File

@ -26,6 +26,8 @@
#include "includes.h"
#ifdef OPENSSL_HAS_ECC
#include <sys/types.h>
#include <signal.h>
@ -116,3 +118,4 @@ kex_ecdh_hash(
*hashlen = EVP_MD_size(evp_md);
}
#endif /* OPENSSL_HAS_ECC */

View File

@ -32,8 +32,6 @@
#include <string.h>
#include <signal.h>
#include <openssl/ecdh.h>
#include "xmalloc.h"
#include "buffer.h"
#include "key.h"
@ -44,6 +42,10 @@
#include "dh.h"
#include "ssh2.h"
#ifdef OPENSSL_HAS_ECC
#include <openssl/ecdh.h>
void
kexecdh_client(Kex *kex)
{
@ -156,3 +158,10 @@ kexecdh_client(Kex *kex)
BN_clear_free(shared_secret);
kex_finish(kex);
}
#else /* OPENSSL_HAS_ECC */
void
kexecdh_client(Kex *kex)
{
fatal("ECC support is not enabled");
}
#endif /* OPENSSL_HAS_ECC */

View File

@ -30,8 +30,6 @@
#include <string.h>
#include <signal.h>
#include <openssl/ecdh.h>
#include "xmalloc.h"
#include "buffer.h"
#include "key.h"
@ -46,6 +44,10 @@
#endif
#include "monitor_wrap.h"
#ifdef OPENSSL_HAS_ECC
#include <openssl/ecdh.h>
void
kexecdh_server(Kex *kex)
{
@ -161,3 +163,10 @@ kexecdh_server(Kex *kex)
BN_clear_free(shared_secret);
kex_finish(kex);
}
#else /* OPENSSL_HAS_ECC */
void
kexecdh_server(Kex *kex)
{
fatal("ECC support is not enabled");
}
#endif /* OPENSSL_HAS_ECC */

67
key.c
View File

@ -111,10 +111,12 @@ key_new(int type)
fatal("key_new: BN_new failed");
k->dsa = dsa;
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
case KEY_ECDSA_CERT:
/* Cannot do anything until we know the group */
break;
#endif
case KEY_UNSPEC:
break;
default:
@ -214,12 +216,14 @@ key_free(Key *k)
DSA_free(k->dsa);
k->dsa = NULL;
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
case KEY_ECDSA_CERT:
if (k->ecdsa != NULL)
EC_KEY_free(k->ecdsa);
k->ecdsa = NULL;
break;
#endif
case KEY_UNSPEC:
break;
default:
@ -279,6 +283,7 @@ key_equal_public(const Key *a, const Key *b)
BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA_CERT:
case KEY_ECDSA:
if (a->ecdsa == NULL || b->ecdsa == NULL ||
@ -297,6 +302,7 @@ key_equal_public(const Key *a, const Key *b)
}
BN_CTX_free(bnctx);
return 1;
#endif /* OPENSSL_HAS_ECC */
default:
fatal("key_equal: bad key type %d", a->type);
}
@ -695,11 +701,13 @@ key_read(Key *ret, char **cpp)
}
*space = '\0';
type = key_type_from_name(cp);
#ifdef OPENSSL_HAS_ECC
if (key_type_plain(type) == KEY_ECDSA &&
(curve_nid = key_ecdsa_nid_from_name(cp)) == -1) {
debug("key_read: invalid curve");
return -1;
}
#endif
*space = ' ';
if (type == KEY_UNSPEC) {
debug3("key_read: missing keytype");
@ -736,12 +744,14 @@ key_read(Key *ret, char **cpp)
key_free(k);
return -1;
}
#ifdef OPENSSL_HAS_ECC
if (key_type_plain(type) == KEY_ECDSA &&
curve_nid != k->ecdsa_nid) {
error("key_read: type mismatch: EC curve mismatch");
key_free(k);
return -1;
}
#endif
/*XXXX*/
if (key_is_cert(ret)) {
if (!key_is_cert(k)) {
@ -772,6 +782,7 @@ key_read(Key *ret, char **cpp)
DSA_print_fp(stderr, ret->dsa, 8);
#endif
}
#ifdef OPENSSL_HAS_ECC
if (key_type_plain(ret->type) == KEY_ECDSA) {
if (ret->ecdsa != NULL)
EC_KEY_free(ret->ecdsa);
@ -783,6 +794,7 @@ key_read(Key *ret, char **cpp)
key_dump_ec_key(ret->ecdsa);
#endif
}
#endif
success = 1;
/*XXXX*/
key_free(k);
@ -839,11 +851,13 @@ key_write(const Key *key, FILE *f)
if (key->dsa == NULL)
return 0;
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
case KEY_ECDSA_CERT:
if (key->ecdsa == NULL)
return 0;
break;
#endif
case KEY_RSA:
case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
@ -877,8 +891,10 @@ key_type(const Key *k)
return "RSA";
case KEY_DSA:
return "DSA";
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
return "ECDSA";
#endif
case KEY_RSA_CERT_V00:
return "RSA-CERT-V00";
case KEY_DSA_CERT_V00:
@ -887,8 +903,10 @@ key_type(const Key *k)
return "RSA-CERT";
case KEY_DSA_CERT:
return "DSA-CERT";
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA_CERT:
return "ECDSA-CERT";
#endif
}
return "unknown";
}
@ -922,6 +940,7 @@ key_ssh_name_from_type_nid(int type, int nid)
return "ssh-rsa-cert-v01@openssh.com";
case KEY_DSA_CERT:
return "ssh-dss-cert-v01@openssh.com";
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
switch (nid) {
case NID_X9_62_prime256v1:
@ -946,6 +965,7 @@ key_ssh_name_from_type_nid(int type, int nid)
break;
}
break;
#endif /* OPENSSL_HAS_ECC */
}
return "ssh-unknown";
}
@ -976,9 +996,11 @@ key_size(const Key *k)
case KEY_DSA_CERT_V00:
case KEY_DSA_CERT:
return BN_num_bits(k->dsa->p);
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
case KEY_ECDSA_CERT:
return key_curve_nid_to_bits(k->ecdsa_nid);
#endif
}
return 0;
}
@ -1012,17 +1034,20 @@ int
key_ecdsa_bits_to_nid(int bits)
{
switch (bits) {
#ifdef OPENSSL_HAS_ECC
case 256:
return NID_X9_62_prime256v1;
case 384:
return NID_secp384r1;
case 521:
return NID_secp521r1;
#endif
default:
return -1;
}
}
#ifdef OPENSSL_HAS_ECC
/*
* This is horrid, but OpenSSL's PEM_read_PrivateKey seems not to restore
* the EC_GROUP nid when loading a key...
@ -1070,6 +1095,7 @@ ecdsa_generate_private_key(u_int bits, int *nid)
fatal("%s: EC_KEY_generate_key failed", __func__);
return private;
}
#endif /* OPENSSL_HAS_ECC */
Key *
key_generate(int type, u_int bits)
@ -1079,9 +1105,11 @@ key_generate(int type, u_int bits)
case KEY_DSA:
k->dsa = dsa_generate_private_key(bits);
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
k->ecdsa = ecdsa_generate_private_key(bits, &k->ecdsa_nid);
break;
#endif
case KEY_RSA:
case KEY_RSA1:
k->rsa = rsa_generate_private_key(bits);
@ -1158,6 +1186,7 @@ key_from_private(const Key *k)
(BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL))
fatal("key_from_private: BN_copy failed");
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
case KEY_ECDSA_CERT:
n = key_new(k->type);
@ -1168,6 +1197,7 @@ key_from_private(const Key *k)
EC_KEY_get0_public_key(k->ecdsa)) != 1)
fatal("%s: EC_KEY_set_public_key failed", __func__);
break;
#endif
case KEY_RSA:
case KEY_RSA1:
case KEY_RSA_CERT_V00:
@ -1199,11 +1229,13 @@ key_type_from_name(char *name)
return KEY_RSA;
} else if (strcmp(name, "ssh-dss") == 0) {
return KEY_DSA;
#ifdef OPENSSL_HAS_ECC
} else if (strcmp(name, "ecdsa") == 0 ||
strcmp(name, "ecdsa-sha2-nistp256") == 0 ||
strcmp(name, "ecdsa-sha2-nistp384") == 0 ||
strcmp(name, "ecdsa-sha2-nistp521") == 0) {
return KEY_ECDSA;
#endif
} else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) {
return KEY_RSA_CERT_V00;
} else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) {
@ -1212,10 +1244,13 @@ key_type_from_name(char *name)
return KEY_RSA_CERT;
} else if (strcmp(name, "ssh-dss-cert-v01@openssh.com") == 0) {
return KEY_DSA_CERT;
#ifdef OPENSSL_HAS_ECC
} else if (strcmp(name, "ecdsa-sha2-nistp256-cert-v01@openssh.com") == 0 ||
strcmp(name, "ecdsa-sha2-nistp384-cert-v01@openssh.com") == 0 ||
strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0)
strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0) {
return KEY_ECDSA_CERT;
#endif
}
debug2("key_type_from_name: unknown key type '%s'", name);
return KEY_UNSPEC;
@ -1224,6 +1259,7 @@ key_type_from_name(char *name)
int
key_ecdsa_nid_from_name(const char *name)
{
#ifdef OPENSSL_HAS_ECC
if (strcmp(name, "ecdsa-sha2-nistp256") == 0 ||
strcmp(name, "ecdsa-sha2-nistp256-cert-v01@openssh.com") == 0)
return NID_X9_62_prime256v1;
@ -1233,6 +1269,7 @@ key_ecdsa_nid_from_name(const char *name)
if (strcmp(name, "ecdsa-sha2-nistp521") == 0 ||
strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0)
return NID_secp521r1;
#endif /* OPENSSL_HAS_ECC */
debug2("%s: unknown/non-ECDSA key type '%s'", __func__, name);
return -1;
@ -1403,7 +1440,9 @@ key_from_blob(const u_char *blob, u_int blen)
int rlen, type, nid = -1;
char *ktype = NULL, *curve = NULL;
Key *key = NULL;
#ifdef OPENSSL_HAS_ECC
EC_POINT *q = NULL;
#endif
#ifdef DEBUG_PK
dump_base64(stderr, blob, blen);
@ -1416,8 +1455,10 @@ key_from_blob(const u_char *blob, u_int blen)
}
type = key_type_from_name(ktype);
#ifdef OPENSSL_HAS_ECC
if (key_type_plain(type) == KEY_ECDSA)
nid = key_ecdsa_nid_from_name(ktype);
#endif
switch (type) {
case KEY_RSA_CERT:
@ -1455,6 +1496,7 @@ key_from_blob(const u_char *blob, u_int blen)
DSA_print_fp(stderr, key->dsa, 8);
#endif
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA_CERT:
(void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
/* FALLTHROUGH */
@ -1490,6 +1532,7 @@ key_from_blob(const u_char *blob, u_int blen)
key_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q);
#endif
break;
#endif /* OPENSSL_HAS_ECC */
case KEY_UNSPEC:
key = key_new(type);
break;
@ -1509,8 +1552,10 @@ key_from_blob(const u_char *blob, u_int blen)
xfree(ktype);
if (curve != NULL)
xfree(curve);
#ifdef OPENSSL_HAS_ECC
if (q != NULL)
EC_POINT_free(q);
#endif
buffer_free(&b);
return key;
}
@ -1543,12 +1588,14 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
buffer_put_bignum2(&b, key->dsa->g);
buffer_put_bignum2(&b, key->dsa->pub_key);
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
buffer_put_cstring(&b, key_ssh_name(key));
buffer_put_cstring(&b, key_curve_nid_to_name(key->ecdsa_nid));
buffer_put_ecpoint(&b, EC_KEY_get0_group(key->ecdsa),
EC_KEY_get0_public_key(key->ecdsa));
break;
#endif
case KEY_RSA:
buffer_put_cstring(&b, key_ssh_name(key));
buffer_put_bignum2(&b, key->rsa->e);
@ -1582,9 +1629,11 @@ key_sign(
case KEY_DSA_CERT:
case KEY_DSA:
return ssh_dss_sign(key, sigp, lenp, data, datalen);
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA_CERT:
case KEY_ECDSA:
return ssh_ecdsa_sign(key, sigp, lenp, data, datalen);
#endif
case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
case KEY_RSA:
@ -1613,9 +1662,11 @@ key_verify(
case KEY_DSA_CERT:
case KEY_DSA:
return ssh_dss_verify(key, signature, signaturelen, data, datalen);
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA_CERT:
case KEY_ECDSA:
return ssh_ecdsa_verify(key, signature, signaturelen, data, datalen);
#endif
case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
case KEY_RSA:
@ -1670,6 +1721,7 @@ key_demote(const Key *k)
if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL)
fatal("key_demote: BN_dup failed");
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA_CERT:
key_cert_copy(k, pk);
/* FALLTHROUGH */
@ -1680,6 +1732,7 @@ key_demote(const Key *k)
EC_KEY_get0_public_key(k->ecdsa)) != 1)
fatal("key_demote: EC_KEY_set_public_key failed");
break;
#endif
default:
fatal("key_free: bad key type %d", k->type);
break;
@ -1819,6 +1872,7 @@ key_certify(Key *k, Key *ca)
buffer_put_bignum2(&k->cert->certblob, k->dsa->g);
buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key);
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA_CERT:
buffer_put_cstring(&k->cert->certblob,
key_curve_nid_to_name(k->ecdsa_nid));
@ -1826,6 +1880,7 @@ key_certify(Key *k, Key *ca)
EC_KEY_get0_group(k->ecdsa),
EC_KEY_get0_public_key(k->ecdsa));
break;
#endif
case KEY_RSA_CERT_V00:
case KEY_RSA_CERT:
buffer_put_bignum2(&k->cert->certblob, k->rsa->e);
@ -1955,12 +2010,14 @@ key_cert_is_legacy(Key *k)
int
key_curve_name_to_nid(const char *name)
{
#ifdef OPENSSL_HAS_ECC
if (strcmp(name, "nistp256") == 0)
return NID_X9_62_prime256v1;
else if (strcmp(name, "nistp384") == 0)
return NID_secp384r1;
else if (strcmp(name, "nistp521") == 0)
return NID_secp521r1;
#endif
debug("%s: unsupported EC curve name \"%.100s\"", __func__, name);
return -1;
@ -1970,12 +2027,14 @@ u_int
key_curve_nid_to_bits(int nid)
{
switch (nid) {
#ifdef OPENSSL_HAS_ECC
case NID_X9_62_prime256v1:
return 256;
case NID_secp384r1:
return 384;
case NID_secp521r1:
return 521;
#endif
default:
error("%s: unsupported EC curve nid %d", __func__, nid);
return 0;
@ -1985,17 +2044,19 @@ key_curve_nid_to_bits(int nid)
const char *
key_curve_nid_to_name(int nid)
{
#ifdef OPENSSL_HAS_ECC
if (nid == NID_X9_62_prime256v1)
return "nistp256";
else if (nid == NID_secp384r1)
return "nistp384";
else if (nid == NID_secp521r1)
return "nistp521";
#endif
error("%s: unsupported EC curve nid %d", __func__, nid);
return NULL;
}
#ifdef OPENSSL_HAS_ECC
const EVP_MD *
key_ec_nid_to_evpmd(int nid)
{
@ -2180,4 +2241,4 @@ key_dump_ec_key(const EC_KEY *key)
fputs("\n", stderr);
}
#endif /* defined(DEBUG_KEXECDH) || defined(DEBUG_PK) */
#endif /* OPENSSL_HAS_ECC */

10
key.h
View File

@ -29,7 +29,9 @@
#include "buffer.h"
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#ifdef OPENSSL_HAS_ECC
#include <openssl/ec.h>
#endif
typedef struct Key Key;
enum types {
@ -77,7 +79,11 @@ struct Key {
RSA *rsa;
DSA *dsa;
int ecdsa_nid; /* NID of curve */
#ifdef OPENSSL_HAS_ECC
EC_KEY *ecdsa;
#else
void *ecdsa;
#endif
struct KeyCert *cert;
};
@ -114,10 +120,12 @@ int key_curve_name_to_nid(const char *);
const char * key_curve_nid_to_name(int);
u_int key_curve_nid_to_bits(int);
int key_ecdsa_bits_to_nid(int);
#ifdef OPENSSL_HAS_ECC
int key_ecdsa_group_to_nid(const EC_GROUP *);
const EVP_MD * key_ec_nid_to_evpmd(int nid);
int key_ec_validate_public(const EC_GROUP *, const EC_POINT *);
int key_ec_validate_private(const EC_KEY *);
#endif
Key *key_from_blob(const u_char *, u_int);
int key_to_blob(const Key *, u_char **, u_int *);
@ -135,7 +143,7 @@ int ssh_ecdsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int)
int ssh_rsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
int ssh_rsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
#if defined(DEBUG_KEXECDH) || defined(DEBUG_PK)
#if defined(OPENSSL_HAS_ECC) && (defined(DEBUG_KEXECDH) || defined(DEBUG_PK))
void key_dump_ec_point(const EC_GROUP *, const EC_POINT *);
void key_dump_ec_key(const EC_KEY *);
#endif

View File

@ -26,44 +26,49 @@
#include <openssl/opensslv.h>
/* Old OpenSSL doesn't support what we need for DHGEX-sha256 */
#if OPENSSL_VERSION_NUMBER < 0x00907000L
# define KEX_DEFAULT_KEX \
"diffie-hellman-group-exchange-sha1," \
"diffie-hellman-group14-sha1," \
"diffie-hellman-group1-sha1"
#define KEX_DEFAULT_PK_ALG \
"ssh-rsa-cert-v01@openssh.com," \
"ssh-dss-cert-v01@openssh.com," \
"ssh-rsa-cert-v00@openssh.com," \
"ssh-dss-cert-v00@openssh.com," \
"ssh-rsa," \
"ssh-dss"
#else
# define KEX_DEFAULT_KEX \
#ifdef OPENSSL_HAS_ECC
# define KEX_ECDH_METHODS \
"ecdh-sha2-nistp256," \
"ecdh-sha2-nistp384," \
"ecdh-sha2-nistp521," \
"diffie-hellman-group-exchange-sha256," \
"ecdh-sha2-nistp521,"
# define HOSTKEY_ECDSA_CERT_METHODS \
"ecdsa-sha2-nistp256-cert-v01@openssh.com," \
"ecdsa-sha2-nistp384-cert-v01@openssh.com," \
"ecdsa-sha2-nistp521-cert-v01@openssh.com,"
# define HOSTKEY_ECDSA_METHODS \
"ecdsa-sha2-nistp256," \
"ecdsa-sha2-nistp384," \
"ecdsa-sha2-nistp521,"
#else
# define KEX_ECDH_METHODS
# define HOSTKEY_ECDSA_CERT_METHODS
# define HOSTKEY_ECDSA_METHODS
#endif
/* Old OpenSSL doesn't support what we need for DHGEX-sha256 */
#if OPENSSL_VERSION_NUMBER < 0x00907000L
# define KEX_SHA256_METHODS \
"diffie-hellman-group-exchange-sha1,"
#else
# define KEX_SHA256_METHODS
#endif
# define KEX_DEFAULT_KEX \
KEX_ECDH_METHODS \
KEX_SHA256_METHODS \
"diffie-hellman-group-exchange-sha1," \
"diffie-hellman-group14-sha1," \
"diffie-hellman-group1-sha1"
#define KEX_DEFAULT_PK_ALG \
"ecdsa-sha2-nistp256-cert-v01@openssh.com," \
"ecdsa-sha2-nistp384-cert-v01@openssh.com," \
"ecdsa-sha2-nistp521-cert-v01@openssh.com," \
HOSTKEY_ECDSA_CERT_METHODS \
"ssh-rsa-cert-v01@openssh.com," \
"ssh-dss-cert-v01@openssh.com," \
"ssh-rsa-cert-v00@openssh.com," \
"ssh-dss-cert-v00@openssh.com," \
"ecdsa-sha2-nistp256," \
"ecdsa-sha2-nistp384," \
"ecdsa-sha2-nistp521," \
HOSTKEY_ECDSA_METHODS \
"ssh-rsa," \
"ssh-dss"
#endif
#define KEX_DEFAULT_ENCRYPT \
"aes128-ctr,aes192-ctr,aes256-ctr," \

View File

@ -641,11 +641,13 @@ packet_put_bignum2(BIGNUM * value)
buffer_put_bignum2(&active_state->outgoing_packet, value);
}
#ifdef OPENSSL_HAS_ECC
void
packet_put_ecpoint(const EC_GROUP *curve, const EC_POINT *point)
{
buffer_put_ecpoint(&active_state->outgoing_packet, curve, point);
}
#endif
/*
* Finalizes and sends the packet. If the encryption key has been set,
@ -1517,11 +1519,13 @@ packet_get_bignum2(BIGNUM * value)
buffer_get_bignum2(&active_state->incoming_packet, value);
}
#ifdef OPENSSL_HAS_ECC
void
packet_get_ecpoint(const EC_GROUP *curve, EC_POINT *point)
{
buffer_get_ecpoint(&active_state->incoming_packet, curve, point);
}
#endif
void *
packet_get_raw(u_int *length_ptr)

View File

@ -1214,12 +1214,13 @@ fill_default_options(Options * options)
xmalloc(len);
snprintf(options->identity_files[options->num_identity_files++],
len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
#ifdef OPENSSL_HAS_ECC
len = 2 + strlen(_PATH_SSH_CLIENT_ID_ECDSA) + 1;
options->identity_files[options->num_identity_files] =
xmalloc(len);
snprintf(options->identity_files[options->num_identity_files++],
len, "~/%.100s", _PATH_SSH_CLIENT_ID_ECDSA);
#endif
}
}
if (options->escape_char == -1)

View File

@ -468,8 +468,10 @@ process_add_identity(SocketEntry *e, int version)
int type, success = 0, death = 0, confirm = 0;
char *type_name, *comment, *curve;
Key *k = NULL;
#ifdef OPENSSL_HAS_ECC
BIGNUM *exponent;
EC_POINT *q;
#endif
u_char *cert;
u_int len;
@ -510,6 +512,7 @@ process_add_identity(SocketEntry *e, int version)
key_add_private(k);
buffer_get_bignum2(&e->request, k->dsa->priv_key);
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
k = key_new_private(type);
k->ecdsa_nid = key_ecdsa_nid_from_name(type_name);
@ -561,6 +564,7 @@ process_add_identity(SocketEntry *e, int version)
fatal("%s: bad ECDSA key", __func__);
BN_clear_free(exponent);
break;
#endif /* OPENSSL_HAS_ECC */
case KEY_RSA:
k = key_new_private(type);
buffer_get_bignum2(&e->request, k->rsa->n);

View File

@ -26,6 +26,8 @@
#include "includes.h"
#ifdef OPENSSL_HAS_ECC
#include <sys/types.h>
#include <openssl/bn.h>
@ -162,3 +164,5 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error");
return ret;
}
#endif /* OPENSSL_HAS_ECC */

View File

@ -265,10 +265,12 @@ do_convert_to_pkcs8(Key *k)
if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
fatal("PEM_write_DSA_PUBKEY failed");
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))
fatal("PEM_write_EC_PUBKEY failed");
break;
#endif
default:
fatal("%s: unsupported key type %s", __func__, key_type(k));
}
@ -549,6 +551,7 @@ do_convert_from_pkcs8(Key **k, int *private)
(*k)->type = KEY_DSA;
(*k)->dsa = EVP_PKEY_get1_DSA(pubkey);
break;
#ifdef OPENSSL_HAS_ECC
case EVP_PKEY_EC:
*k = key_new(KEY_UNSPEC);
(*k)->type = KEY_ECDSA;
@ -556,6 +559,7 @@ do_convert_from_pkcs8(Key **k, int *private)
(*k)->ecdsa_nid = key_ecdsa_group_to_nid(
EC_KEY_get0_group((*k)->ecdsa));
break;
#endif
default:
fatal("%s: unsupported pubkey type %d", __func__,
EVP_PKEY_type(pubkey->type));
@ -632,10 +636,12 @@ do_convert_from(struct passwd *pw)
ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL,
NULL, 0, NULL, NULL);
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL,
NULL, 0, NULL, NULL);
break;
#endif
case KEY_RSA:
ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL,
NULL, 0, NULL, NULL);

10
ssh.c
View File

@ -783,20 +783,26 @@ main(int ac, char **av)
sensitive_data.nkeys = 7;
sensitive_data.keys = xcalloc(sensitive_data.nkeys,
sizeof(Key));
for (i = 0; i < sensitive_data.nkeys; i++)
sensitive_data.keys[i] = NULL;
PRIV_START;
sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
_PATH_HOST_KEY_FILE, "", NULL, NULL);
sensitive_data.keys[1] = key_load_private_cert(KEY_DSA,
_PATH_HOST_DSA_KEY_FILE, "", NULL);
#ifdef OPENSSL_HAS_ECC
sensitive_data.keys[2] = key_load_private_cert(KEY_ECDSA,
_PATH_HOST_ECDSA_KEY_FILE, "", NULL);
#endif
sensitive_data.keys[3] = key_load_private_cert(KEY_RSA,
_PATH_HOST_RSA_KEY_FILE, "", NULL);
sensitive_data.keys[4] = key_load_private_type(KEY_DSA,
_PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
#ifdef OPENSSL_HAS_ECC
sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA,
_PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL);
#endif
sensitive_data.keys[6] = key_load_private_type(KEY_RSA,
_PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
PRIV_END;
@ -808,14 +814,18 @@ main(int ac, char **av)
sensitive_data.keys[6] == NULL) {
sensitive_data.keys[1] = key_load_cert(
_PATH_HOST_DSA_KEY_FILE);
#ifdef OPENSSL_HAS_ECC
sensitive_data.keys[2] = key_load_cert(
_PATH_HOST_ECDSA_KEY_FILE);
#endif
sensitive_data.keys[3] = key_load_cert(
_PATH_HOST_RSA_KEY_FILE);
sensitive_data.keys[4] = key_load_public(
_PATH_HOST_DSA_KEY_FILE, NULL);
#ifdef OPENSSL_HAS_ECC
sensitive_data.keys[5] = key_load_public(
_PATH_HOST_ECDSA_KEY_FILE, NULL);
#endif
sensitive_data.keys[6] = key_load_public(
_PATH_HOST_RSA_KEY_FILE, NULL);
sensitive_data.external_keysign = 1;