summaryrefslogtreecommitdiff
path: root/kex.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2013-04-23 19:24:32 +1000
committerDamien Miller <djm@mindrot.org>2013-04-23 19:24:32 +1000
commitea11119eee3c5e2429b1f5f8688b25b028fa991a (patch)
tree5916295fcefb8665088f59a5431cb0c792fbf327 /kex.c
parenta56086b9903b62c1c4fdedf01b68338fe4dc90e4 (diff)
- djm@cvs.openbsd.org 2013/04/19 01:06:50
[authfile.c cipher.c cipher.h kex.c kex.h kexecdh.c kexecdhc.c kexecdhs.c] [key.c key.h mac.c mac.h packet.c ssh.1 ssh.c] add the ability to query supported ciphers, MACs, key type and KEX algorithms to ssh. Includes some refactoring of KEX and key type handling to be table-driven; ok markus@
Diffstat (limited to 'kex.c')
-rw-r--r--kex.c86
1 files changed, 58 insertions, 28 deletions
diff --git a/kex.c b/kex.c
index 57a79dd9e..65a227bc1 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.c,v 1.88 2013/01/08 18:49:04 markus Exp $ */ 1/* $OpenBSD: kex.c,v 1.89 2013/04/19 01:06:50 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -62,6 +62,55 @@ extern const EVP_MD *evp_ssh_sha256(void);
62static void kex_kexinit_finish(Kex *); 62static void kex_kexinit_finish(Kex *);
63static void kex_choose_conf(Kex *); 63static void kex_choose_conf(Kex *);
64 64
65struct kexalg {
66 char *name;
67 int type;
68 int ec_nid;
69 const EVP_MD *(*mdfunc)(void);
70};
71static const struct kexalg kexalgs[] = {
72 { KEX_DH1, KEX_DH_GRP1_SHA1, 0, EVP_sha1 },
73 { KEX_DH14, KEX_DH_GRP14_SHA1, 0, EVP_sha1 },
74 { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, EVP_sha1 },
75#if OPENSSL_VERSION_NUMBER >= 0x00907000L
76 { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, EVP_sha256 },
77 { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, NID_X9_62_prime256v1, EVP_sha256 },
78 { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, EVP_sha384 },
79 { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, EVP_sha512 },
80#endif
81 { NULL, -1, -1, NULL},
82};
83
84char *
85kex_alg_list(void)
86{
87 char *ret = NULL;
88 size_t nlen, rlen = 0;
89 const struct kexalg *k;
90
91 for (k = kexalgs; k->name != NULL; k++) {
92 if (ret != NULL)
93 ret[rlen++] = '\n';
94 nlen = strlen(k->name);
95 ret = xrealloc(ret, 1, rlen + nlen + 2);
96 memcpy(ret + rlen, k->name, nlen + 1);
97 rlen += nlen;
98 }
99 return ret;
100}
101
102static const struct kexalg *
103kex_alg_by_name(const char *name)
104{
105 const struct kexalg *k;
106
107 for (k = kexalgs; k->name != NULL; k++) {
108 if (strcmp(k->name, name) == 0)
109 return k;
110 }
111 return NULL;
112}
113
65/* Validate KEX method name list */ 114/* Validate KEX method name list */
66int 115int
67kex_names_valid(const char *names) 116kex_names_valid(const char *names)
@@ -73,13 +122,7 @@ kex_names_valid(const char *names)
73 s = cp = xstrdup(names); 122 s = cp = xstrdup(names);
74 for ((p = strsep(&cp, ",")); p && *p != '\0'; 123 for ((p = strsep(&cp, ",")); p && *p != '\0';
75 (p = strsep(&cp, ","))) { 124 (p = strsep(&cp, ","))) {
76 if (strcmp(p, KEX_DHGEX_SHA256) != 0 && 125 if (kex_alg_by_name(p) == NULL) {
77 strcmp(p, KEX_DHGEX_SHA1) != 0 &&
78 strcmp(p, KEX_DH14) != 0 &&
79 strcmp(p, KEX_DH1) != 0 &&
80 (strncmp(p, KEX_ECDH_SHA2_STEM,
81 sizeof(KEX_ECDH_SHA2_STEM) - 1) != 0 ||
82 kex_ecdh_name_to_nid(p) == -1)) {
83 error("Unsupported KEX algorithm \"%.100s\"", p); 126 error("Unsupported KEX algorithm \"%.100s\"", p);
84 xfree(s); 127 xfree(s);
85 return 0; 128 return 0;
@@ -348,29 +391,16 @@ choose_comp(Comp *comp, char *client, char *server)
348static void 391static void
349choose_kex(Kex *k, char *client, char *server) 392choose_kex(Kex *k, char *client, char *server)
350{ 393{
394 const struct kexalg *kexalg;
395
351 k->name = match_list(client, server, NULL); 396 k->name = match_list(client, server, NULL);
352 if (k->name == NULL) 397 if (k->name == NULL)
353 fatal("Unable to negotiate a key exchange method"); 398 fatal("Unable to negotiate a key exchange method");
354 if (strcmp(k->name, KEX_DH1) == 0) { 399 if ((kexalg = kex_alg_by_name(k->name)) == NULL)
355 k->kex_type = KEX_DH_GRP1_SHA1; 400 fatal("unsupported kex alg %s", k->name);
356 k->evp_md = EVP_sha1(); 401 k->kex_type = kexalg->type;
357 } else if (strcmp(k->name, KEX_DH14) == 0) { 402 k->evp_md = kexalg->mdfunc();
358 k->kex_type = KEX_DH_GRP14_SHA1; 403 k->ec_nid = kexalg->ec_nid;
359 k->evp_md = EVP_sha1();
360 } else if (strcmp(k->name, KEX_DHGEX_SHA1) == 0) {
361 k->kex_type = KEX_DH_GEX_SHA1;
362 k->evp_md = EVP_sha1();
363#if OPENSSL_VERSION_NUMBER >= 0x00907000L
364 } else if (strcmp(k->name, KEX_DHGEX_SHA256) == 0) {
365 k->kex_type = KEX_DH_GEX_SHA256;
366 k->evp_md = evp_ssh_sha256();
367 } else if (strncmp(k->name, KEX_ECDH_SHA2_STEM,
368 sizeof(KEX_ECDH_SHA2_STEM) - 1) == 0) {
369 k->kex_type = KEX_ECDH_SHA2;
370 k->evp_md = kex_ecdh_name_to_evpmd(k->name);
371#endif
372 } else
373 fatal("bad kex alg %s", k->name);
374} 404}
375 405
376static void 406static void