diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | kex.c | 23 | ||||
-rw-r--r-- | kex.h | 23 | ||||
-rw-r--r-- | kexdh.c | 234 | ||||
-rw-r--r-- | kexdhc.c | 137 | ||||
-rw-r--r-- | kexdhs.c | 138 | ||||
-rw-r--r-- | kexgex.c | 328 | ||||
-rw-r--r-- | kexgexc.c | 189 | ||||
-rw-r--r-- | kexgexs.c | 186 | ||||
-rw-r--r-- | ssh-keyscan.c | 4 | ||||
-rw-r--r-- | sshconnect2.c | 4 | ||||
-rw-r--r-- | sshd.c | 8 |
12 files changed, 697 insertions, 583 deletions
@@ -63,6 +63,10 @@ | |||
63 | - markus@cvs.openbsd.org 2003/02/12 21:39:50 | 63 | - markus@cvs.openbsd.org 2003/02/12 21:39:50 |
64 | [crc32.c crc32.h] | 64 | [crc32.c crc32.h] |
65 | replace crc32.c with a BSD licensed version; noted by David Turner | 65 | replace crc32.c with a BSD licensed version; noted by David Turner |
66 | - markus@cvs.openbsd.org 2003/02/16 17:09:57 | ||
67 | [kex.c kexdh.c kexgex.c kex.h sshconnect2.c sshd.c ssh-keyscan.c] | ||
68 | split kex into client and server code, no need to link | ||
69 | server code into the client; ok provos@ | ||
66 | 70 | ||
67 | 20030211 | 71 | 20030211 |
68 | - (djm) Cygwin needs libcrypt too. Patch from vinschen@redhat.com | 72 | - (djm) Cygwin needs libcrypt too. Patch from vinschen@redhat.com |
@@ -1163,4 +1167,4 @@ | |||
1163 | save auth method before monitor_reset_key_state(); bugzilla bug #284; | 1167 | save auth method before monitor_reset_key_state(); bugzilla bug #284; |
1164 | ok provos@ | 1168 | ok provos@ |
1165 | 1169 | ||
1166 | $Id: ChangeLog,v 1.2611 2003/02/24 01:02:12 djm Exp $ | 1170 | $Id: ChangeLog,v 1.2612 2003/02/24 01:03:03 djm Exp $ |
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: kex.c,v 1.53 2003/02/02 10:56:08 markus Exp $"); | 26 | RCSID("$OpenBSD: kex.c,v 1.54 2003/02/16 17:09:57 markus Exp $"); |
27 | 27 | ||
28 | #include <openssl/crypto.h> | 28 | #include <openssl/crypto.h> |
29 | 29 | ||
@@ -44,11 +44,6 @@ RCSID("$OpenBSD: kex.c,v 1.53 2003/02/02 10:56:08 markus Exp $"); | |||
44 | 44 | ||
45 | #define KEX_COOKIE_LEN 16 | 45 | #define KEX_COOKIE_LEN 16 |
46 | 46 | ||
47 | /* Use privilege separation for sshd */ | ||
48 | int use_privsep; | ||
49 | struct monitor *pmonitor; | ||
50 | |||
51 | |||
52 | /* prototype */ | 47 | /* prototype */ |
53 | static void kex_kexinit_finish(Kex *); | 48 | static void kex_kexinit_finish(Kex *); |
54 | static void kex_choose_conf(Kex *); | 49 | static void kex_choose_conf(Kex *); |
@@ -237,14 +232,10 @@ kex_kexinit_finish(Kex *kex) | |||
237 | 232 | ||
238 | kex_choose_conf(kex); | 233 | kex_choose_conf(kex); |
239 | 234 | ||
240 | switch (kex->kex_type) { | 235 | if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX && |
241 | case DH_GRP1_SHA1: | 236 | kex->kex[kex->kex_type] != NULL) { |
242 | kexdh(kex); | 237 | (kex->kex[kex->kex_type])(kex); |
243 | break; | 238 | } else { |
244 | case DH_GEX_SHA1: | ||
245 | kexgex(kex); | ||
246 | break; | ||
247 | default: | ||
248 | fatal("Unsupported key exchange %d", kex->kex_type); | 239 | fatal("Unsupported key exchange %d", kex->kex_type); |
249 | } | 240 | } |
250 | } | 241 | } |
@@ -301,9 +292,9 @@ choose_kex(Kex *k, char *client, char *server) | |||
301 | if (k->name == NULL) | 292 | if (k->name == NULL) |
302 | fatal("no kex alg"); | 293 | fatal("no kex alg"); |
303 | if (strcmp(k->name, KEX_DH1) == 0) { | 294 | if (strcmp(k->name, KEX_DH1) == 0) { |
304 | k->kex_type = DH_GRP1_SHA1; | 295 | k->kex_type = KEX_DH_GRP1_SHA1; |
305 | } else if (strcmp(k->name, KEX_DHGEX) == 0) { | 296 | } else if (strcmp(k->name, KEX_DHGEX) == 0) { |
306 | k->kex_type = DH_GEX_SHA1; | 297 | k->kex_type = KEX_DH_GEX_SHA1; |
307 | } else | 298 | } else |
308 | fatal("bad kex alg %s", k->name); | 299 | fatal("bad kex alg %s", k->name); |
309 | } | 300 | } |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kex.h,v 1.32 2002/09/09 14:54:14 markus Exp $ */ | 1 | /* $OpenBSD: kex.h,v 1.33 2003/02/16 17:09:57 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
@@ -55,8 +55,9 @@ enum kex_modes { | |||
55 | }; | 55 | }; |
56 | 56 | ||
57 | enum kex_exchange { | 57 | enum kex_exchange { |
58 | DH_GRP1_SHA1, | 58 | KEX_DH_GRP1_SHA1, |
59 | DH_GEX_SHA1 | 59 | KEX_DH_GEX_SHA1, |
60 | KEX_MAX | ||
60 | }; | 61 | }; |
61 | 62 | ||
62 | #define KEX_INIT_SENT 0x0001 | 63 | #define KEX_INIT_SENT 0x0001 |
@@ -112,6 +113,7 @@ struct Kex { | |||
112 | int (*verify_host_key)(Key *); | 113 | int (*verify_host_key)(Key *); |
113 | Key *(*load_host_key)(int); | 114 | Key *(*load_host_key)(int); |
114 | int (*host_key_index)(Key *); | 115 | int (*host_key_index)(Key *); |
116 | void (*kex[KEX_MAX])(Kex *); | ||
115 | }; | 117 | }; |
116 | 118 | ||
117 | Kex *kex_setup(char *[PROPOSAL_MAX]); | 119 | Kex *kex_setup(char *[PROPOSAL_MAX]); |
@@ -121,11 +123,20 @@ void kex_send_kexinit(Kex *); | |||
121 | void kex_input_kexinit(int, u_int32_t, void *); | 123 | void kex_input_kexinit(int, u_int32_t, void *); |
122 | void kex_derive_keys(Kex *, u_char *, BIGNUM *); | 124 | void kex_derive_keys(Kex *, u_char *, BIGNUM *); |
123 | 125 | ||
124 | void kexdh(Kex *); | ||
125 | void kexgex(Kex *); | ||
126 | |||
127 | Newkeys *kex_get_newkeys(int); | 126 | Newkeys *kex_get_newkeys(int); |
128 | 127 | ||
128 | void kexdh_client(Kex *); | ||
129 | void kexdh_server(Kex *); | ||
130 | void kexgex_client(Kex *); | ||
131 | void kexgex_server(Kex *); | ||
132 | |||
133 | u_char * | ||
134 | kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, | ||
135 | BIGNUM *, BIGNUM *, BIGNUM *); | ||
136 | u_char * | ||
137 | kexgex_hash(char *, char *, char *, int, char *, int, u_char *, int, | ||
138 | int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *); | ||
139 | |||
129 | #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) | 140 | #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) |
130 | void dump_digest(char *, u_char *, int); | 141 | void dump_digest(char *, u_char *, int); |
131 | #endif | 142 | #endif |
@@ -23,23 +23,16 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: kexdh.c,v 1.18 2002/03/18 17:50:31 provos Exp $"); | 26 | RCSID("$OpenBSD: kexdh.c,v 1.19 2003/02/16 17:09:57 markus Exp $"); |
27 | 27 | ||
28 | #include <openssl/crypto.h> | 28 | #include <openssl/evp.h> |
29 | #include <openssl/bn.h> | ||
30 | 29 | ||
31 | #include "xmalloc.h" | ||
32 | #include "buffer.h" | 30 | #include "buffer.h" |
33 | #include "bufaux.h" | 31 | #include "bufaux.h" |
34 | #include "key.h" | ||
35 | #include "kex.h" | ||
36 | #include "log.h" | ||
37 | #include "packet.h" | ||
38 | #include "dh.h" | ||
39 | #include "ssh2.h" | 32 | #include "ssh2.h" |
40 | #include "monitor_wrap.h" | 33 | #include "kex.h" |
41 | 34 | ||
42 | static u_char * | 35 | u_char * |
43 | kex_dh_hash( | 36 | kex_dh_hash( |
44 | char *client_version_string, | 37 | char *client_version_string, |
45 | char *server_version_string, | 38 | char *server_version_string, |
@@ -86,222 +79,3 @@ kex_dh_hash( | |||
86 | #endif | 79 | #endif |
87 | return digest; | 80 | return digest; |
88 | } | 81 | } |
89 | |||
90 | /* client */ | ||
91 | |||
92 | static void | ||
93 | kexdh_client(Kex *kex) | ||
94 | { | ||
95 | BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; | ||
96 | DH *dh; | ||
97 | Key *server_host_key; | ||
98 | u_char *server_host_key_blob = NULL, *signature = NULL; | ||
99 | u_char *kbuf, *hash; | ||
100 | u_int klen, kout, slen, sbloblen; | ||
101 | |||
102 | /* generate and send 'e', client DH public key */ | ||
103 | dh = dh_new_group1(); | ||
104 | dh_gen_key(dh, kex->we_need * 8); | ||
105 | packet_start(SSH2_MSG_KEXDH_INIT); | ||
106 | packet_put_bignum2(dh->pub_key); | ||
107 | packet_send(); | ||
108 | |||
109 | debug("sending SSH2_MSG_KEXDH_INIT"); | ||
110 | #ifdef DEBUG_KEXDH | ||
111 | DHparams_print_fp(stderr, dh); | ||
112 | fprintf(stderr, "pub= "); | ||
113 | BN_print_fp(stderr, dh->pub_key); | ||
114 | fprintf(stderr, "\n"); | ||
115 | #endif | ||
116 | |||
117 | debug("expecting SSH2_MSG_KEXDH_REPLY"); | ||
118 | packet_read_expect(SSH2_MSG_KEXDH_REPLY); | ||
119 | |||
120 | /* key, cert */ | ||
121 | server_host_key_blob = packet_get_string(&sbloblen); | ||
122 | server_host_key = key_from_blob(server_host_key_blob, sbloblen); | ||
123 | if (server_host_key == NULL) | ||
124 | fatal("cannot decode server_host_key_blob"); | ||
125 | if (server_host_key->type != kex->hostkey_type) | ||
126 | fatal("type mismatch for decoded server_host_key_blob"); | ||
127 | if (kex->verify_host_key == NULL) | ||
128 | fatal("cannot verify server_host_key"); | ||
129 | if (kex->verify_host_key(server_host_key) == -1) | ||
130 | fatal("server_host_key verification failed"); | ||
131 | |||
132 | /* DH paramter f, server public DH key */ | ||
133 | if ((dh_server_pub = BN_new()) == NULL) | ||
134 | fatal("dh_server_pub == NULL"); | ||
135 | packet_get_bignum2(dh_server_pub); | ||
136 | |||
137 | #ifdef DEBUG_KEXDH | ||
138 | fprintf(stderr, "dh_server_pub= "); | ||
139 | BN_print_fp(stderr, dh_server_pub); | ||
140 | fprintf(stderr, "\n"); | ||
141 | debug("bits %d", BN_num_bits(dh_server_pub)); | ||
142 | #endif | ||
143 | |||
144 | /* signed H */ | ||
145 | signature = packet_get_string(&slen); | ||
146 | packet_check_eom(); | ||
147 | |||
148 | if (!dh_pub_is_valid(dh, dh_server_pub)) | ||
149 | packet_disconnect("bad server public DH value"); | ||
150 | |||
151 | klen = DH_size(dh); | ||
152 | kbuf = xmalloc(klen); | ||
153 | kout = DH_compute_key(kbuf, dh_server_pub, dh); | ||
154 | #ifdef DEBUG_KEXDH | ||
155 | dump_digest("shared secret", kbuf, kout); | ||
156 | #endif | ||
157 | if ((shared_secret = BN_new()) == NULL) | ||
158 | fatal("kexdh_client: BN_new failed"); | ||
159 | BN_bin2bn(kbuf, kout, shared_secret); | ||
160 | memset(kbuf, 0, klen); | ||
161 | xfree(kbuf); | ||
162 | |||
163 | /* calc and verify H */ | ||
164 | hash = kex_dh_hash( | ||
165 | kex->client_version_string, | ||
166 | kex->server_version_string, | ||
167 | buffer_ptr(&kex->my), buffer_len(&kex->my), | ||
168 | buffer_ptr(&kex->peer), buffer_len(&kex->peer), | ||
169 | server_host_key_blob, sbloblen, | ||
170 | dh->pub_key, | ||
171 | dh_server_pub, | ||
172 | shared_secret | ||
173 | ); | ||
174 | xfree(server_host_key_blob); | ||
175 | BN_clear_free(dh_server_pub); | ||
176 | DH_free(dh); | ||
177 | |||
178 | if (key_verify(server_host_key, signature, slen, hash, 20) != 1) | ||
179 | fatal("key_verify failed for server_host_key"); | ||
180 | key_free(server_host_key); | ||
181 | xfree(signature); | ||
182 | |||
183 | /* save session id */ | ||
184 | if (kex->session_id == NULL) { | ||
185 | kex->session_id_len = 20; | ||
186 | kex->session_id = xmalloc(kex->session_id_len); | ||
187 | memcpy(kex->session_id, hash, kex->session_id_len); | ||
188 | } | ||
189 | |||
190 | kex_derive_keys(kex, hash, shared_secret); | ||
191 | BN_clear_free(shared_secret); | ||
192 | kex_finish(kex); | ||
193 | } | ||
194 | |||
195 | /* server */ | ||
196 | |||
197 | static void | ||
198 | kexdh_server(Kex *kex) | ||
199 | { | ||
200 | BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; | ||
201 | DH *dh; | ||
202 | Key *server_host_key; | ||
203 | u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; | ||
204 | u_int sbloblen, klen, kout; | ||
205 | u_int slen; | ||
206 | |||
207 | /* generate server DH public key */ | ||
208 | dh = dh_new_group1(); | ||
209 | dh_gen_key(dh, kex->we_need * 8); | ||
210 | |||
211 | debug("expecting SSH2_MSG_KEXDH_INIT"); | ||
212 | packet_read_expect(SSH2_MSG_KEXDH_INIT); | ||
213 | |||
214 | if (kex->load_host_key == NULL) | ||
215 | fatal("Cannot load hostkey"); | ||
216 | server_host_key = kex->load_host_key(kex->hostkey_type); | ||
217 | if (server_host_key == NULL) | ||
218 | fatal("Unsupported hostkey type %d", kex->hostkey_type); | ||
219 | |||
220 | /* key, cert */ | ||
221 | if ((dh_client_pub = BN_new()) == NULL) | ||
222 | fatal("dh_client_pub == NULL"); | ||
223 | packet_get_bignum2(dh_client_pub); | ||
224 | packet_check_eom(); | ||
225 | |||
226 | #ifdef DEBUG_KEXDH | ||
227 | fprintf(stderr, "dh_client_pub= "); | ||
228 | BN_print_fp(stderr, dh_client_pub); | ||
229 | fprintf(stderr, "\n"); | ||
230 | debug("bits %d", BN_num_bits(dh_client_pub)); | ||
231 | #endif | ||
232 | |||
233 | #ifdef DEBUG_KEXDH | ||
234 | DHparams_print_fp(stderr, dh); | ||
235 | fprintf(stderr, "pub= "); | ||
236 | BN_print_fp(stderr, dh->pub_key); | ||
237 | fprintf(stderr, "\n"); | ||
238 | #endif | ||
239 | if (!dh_pub_is_valid(dh, dh_client_pub)) | ||
240 | packet_disconnect("bad client public DH value"); | ||
241 | |||
242 | klen = DH_size(dh); | ||
243 | kbuf = xmalloc(klen); | ||
244 | kout = DH_compute_key(kbuf, dh_client_pub, dh); | ||
245 | #ifdef DEBUG_KEXDH | ||
246 | dump_digest("shared secret", kbuf, kout); | ||
247 | #endif | ||
248 | if ((shared_secret = BN_new()) == NULL) | ||
249 | fatal("kexdh_server: BN_new failed"); | ||
250 | BN_bin2bn(kbuf, kout, shared_secret); | ||
251 | memset(kbuf, 0, klen); | ||
252 | xfree(kbuf); | ||
253 | |||
254 | key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); | ||
255 | |||
256 | /* calc H */ | ||
257 | hash = kex_dh_hash( | ||
258 | kex->client_version_string, | ||
259 | kex->server_version_string, | ||
260 | buffer_ptr(&kex->peer), buffer_len(&kex->peer), | ||
261 | buffer_ptr(&kex->my), buffer_len(&kex->my), | ||
262 | server_host_key_blob, sbloblen, | ||
263 | dh_client_pub, | ||
264 | dh->pub_key, | ||
265 | shared_secret | ||
266 | ); | ||
267 | BN_clear_free(dh_client_pub); | ||
268 | |||
269 | /* save session id := H */ | ||
270 | /* XXX hashlen depends on KEX */ | ||
271 | if (kex->session_id == NULL) { | ||
272 | kex->session_id_len = 20; | ||
273 | kex->session_id = xmalloc(kex->session_id_len); | ||
274 | memcpy(kex->session_id, hash, kex->session_id_len); | ||
275 | } | ||
276 | |||
277 | /* sign H */ | ||
278 | /* XXX hashlen depends on KEX */ | ||
279 | PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20)); | ||
280 | |||
281 | /* destroy_sensitive_data(); */ | ||
282 | |||
283 | /* send server hostkey, DH pubkey 'f' and singed H */ | ||
284 | packet_start(SSH2_MSG_KEXDH_REPLY); | ||
285 | packet_put_string(server_host_key_blob, sbloblen); | ||
286 | packet_put_bignum2(dh->pub_key); /* f */ | ||
287 | packet_put_string(signature, slen); | ||
288 | packet_send(); | ||
289 | |||
290 | xfree(signature); | ||
291 | xfree(server_host_key_blob); | ||
292 | /* have keys, free DH */ | ||
293 | DH_free(dh); | ||
294 | |||
295 | kex_derive_keys(kex, hash, shared_secret); | ||
296 | BN_clear_free(shared_secret); | ||
297 | kex_finish(kex); | ||
298 | } | ||
299 | |||
300 | void | ||
301 | kexdh(Kex *kex) | ||
302 | { | ||
303 | if (kex->server) | ||
304 | kexdh_server(kex); | ||
305 | else | ||
306 | kexdh_client(kex); | ||
307 | } | ||
diff --git a/kexdhc.c b/kexdhc.c new file mode 100644 index 000000000..fe6dc53f8 --- /dev/null +++ b/kexdhc.c | |||
@@ -0,0 +1,137 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * 1. Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * 2. Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
14 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
15 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
16 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
19 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
20 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | */ | ||
24 | |||
25 | #include "includes.h" | ||
26 | RCSID("$OpenBSD: kexdhc.c,v 1.1 2003/02/16 17:09:57 markus Exp $"); | ||
27 | |||
28 | #include "xmalloc.h" | ||
29 | #include "key.h" | ||
30 | #include "kex.h" | ||
31 | #include "log.h" | ||
32 | #include "packet.h" | ||
33 | #include "dh.h" | ||
34 | #include "ssh2.h" | ||
35 | |||
36 | void | ||
37 | kexdh_client(Kex *kex) | ||
38 | { | ||
39 | BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; | ||
40 | DH *dh; | ||
41 | Key *server_host_key; | ||
42 | u_char *server_host_key_blob = NULL, *signature = NULL; | ||
43 | u_char *kbuf, *hash; | ||
44 | u_int klen, kout, slen, sbloblen; | ||
45 | |||
46 | /* generate and send 'e', client DH public key */ | ||
47 | dh = dh_new_group1(); | ||
48 | dh_gen_key(dh, kex->we_need * 8); | ||
49 | packet_start(SSH2_MSG_KEXDH_INIT); | ||
50 | packet_put_bignum2(dh->pub_key); | ||
51 | packet_send(); | ||
52 | |||
53 | debug("sending SSH2_MSG_KEXDH_INIT"); | ||
54 | #ifdef DEBUG_KEXDH | ||
55 | DHparams_print_fp(stderr, dh); | ||
56 | fprintf(stderr, "pub= "); | ||
57 | BN_print_fp(stderr, dh->pub_key); | ||
58 | fprintf(stderr, "\n"); | ||
59 | #endif | ||
60 | |||
61 | debug("expecting SSH2_MSG_KEXDH_REPLY"); | ||
62 | packet_read_expect(SSH2_MSG_KEXDH_REPLY); | ||
63 | |||
64 | /* key, cert */ | ||
65 | server_host_key_blob = packet_get_string(&sbloblen); | ||
66 | server_host_key = key_from_blob(server_host_key_blob, sbloblen); | ||
67 | if (server_host_key == NULL) | ||
68 | fatal("cannot decode server_host_key_blob"); | ||
69 | if (server_host_key->type != kex->hostkey_type) | ||
70 | fatal("type mismatch for decoded server_host_key_blob"); | ||
71 | if (kex->verify_host_key == NULL) | ||
72 | fatal("cannot verify server_host_key"); | ||
73 | if (kex->verify_host_key(server_host_key) == -1) | ||
74 | fatal("server_host_key verification failed"); | ||
75 | |||
76 | /* DH paramter f, server public DH key */ | ||
77 | if ((dh_server_pub = BN_new()) == NULL) | ||
78 | fatal("dh_server_pub == NULL"); | ||
79 | packet_get_bignum2(dh_server_pub); | ||
80 | |||
81 | #ifdef DEBUG_KEXDH | ||
82 | fprintf(stderr, "dh_server_pub= "); | ||
83 | BN_print_fp(stderr, dh_server_pub); | ||
84 | fprintf(stderr, "\n"); | ||
85 | debug("bits %d", BN_num_bits(dh_server_pub)); | ||
86 | #endif | ||
87 | |||
88 | /* signed H */ | ||
89 | signature = packet_get_string(&slen); | ||
90 | packet_check_eom(); | ||
91 | |||
92 | if (!dh_pub_is_valid(dh, dh_server_pub)) | ||
93 | packet_disconnect("bad server public DH value"); | ||
94 | |||
95 | klen = DH_size(dh); | ||
96 | kbuf = xmalloc(klen); | ||
97 | kout = DH_compute_key(kbuf, dh_server_pub, dh); | ||
98 | #ifdef DEBUG_KEXDH | ||
99 | dump_digest("shared secret", kbuf, kout); | ||
100 | #endif | ||
101 | if ((shared_secret = BN_new()) == NULL) | ||
102 | fatal("kexdh_client: BN_new failed"); | ||
103 | BN_bin2bn(kbuf, kout, shared_secret); | ||
104 | memset(kbuf, 0, klen); | ||
105 | xfree(kbuf); | ||
106 | |||
107 | /* calc and verify H */ | ||
108 | hash = kex_dh_hash( | ||
109 | kex->client_version_string, | ||
110 | kex->server_version_string, | ||
111 | buffer_ptr(&kex->my), buffer_len(&kex->my), | ||
112 | buffer_ptr(&kex->peer), buffer_len(&kex->peer), | ||
113 | server_host_key_blob, sbloblen, | ||
114 | dh->pub_key, | ||
115 | dh_server_pub, | ||
116 | shared_secret | ||
117 | ); | ||
118 | xfree(server_host_key_blob); | ||
119 | BN_clear_free(dh_server_pub); | ||
120 | DH_free(dh); | ||
121 | |||
122 | if (key_verify(server_host_key, signature, slen, hash, 20) != 1) | ||
123 | fatal("key_verify failed for server_host_key"); | ||
124 | key_free(server_host_key); | ||
125 | xfree(signature); | ||
126 | |||
127 | /* save session id */ | ||
128 | if (kex->session_id == NULL) { | ||
129 | kex->session_id_len = 20; | ||
130 | kex->session_id = xmalloc(kex->session_id_len); | ||
131 | memcpy(kex->session_id, hash, kex->session_id_len); | ||
132 | } | ||
133 | |||
134 | kex_derive_keys(kex, hash, shared_secret); | ||
135 | BN_clear_free(shared_secret); | ||
136 | kex_finish(kex); | ||
137 | } | ||
diff --git a/kexdhs.c b/kexdhs.c new file mode 100644 index 000000000..f04bce825 --- /dev/null +++ b/kexdhs.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * 1. Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * 2. Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
14 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
15 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
16 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
19 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
20 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | */ | ||
24 | |||
25 | #include "includes.h" | ||
26 | RCSID("$OpenBSD: kexdhs.c,v 1.1 2003/02/16 17:09:57 markus Exp $"); | ||
27 | |||
28 | #include "xmalloc.h" | ||
29 | #include "key.h" | ||
30 | #include "kex.h" | ||
31 | #include "log.h" | ||
32 | #include "packet.h" | ||
33 | #include "dh.h" | ||
34 | #include "ssh2.h" | ||
35 | #include "monitor_wrap.h" | ||
36 | |||
37 | void | ||
38 | kexdh_server(Kex *kex) | ||
39 | { | ||
40 | BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; | ||
41 | DH *dh; | ||
42 | Key *server_host_key; | ||
43 | u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; | ||
44 | u_int sbloblen, klen, kout; | ||
45 | u_int slen; | ||
46 | |||
47 | /* generate server DH public key */ | ||
48 | dh = dh_new_group1(); | ||
49 | dh_gen_key(dh, kex->we_need * 8); | ||
50 | |||
51 | debug("expecting SSH2_MSG_KEXDH_INIT"); | ||
52 | packet_read_expect(SSH2_MSG_KEXDH_INIT); | ||
53 | |||
54 | if (kex->load_host_key == NULL) | ||
55 | fatal("Cannot load hostkey"); | ||
56 | server_host_key = kex->load_host_key(kex->hostkey_type); | ||
57 | if (server_host_key == NULL) | ||
58 | fatal("Unsupported hostkey type %d", kex->hostkey_type); | ||
59 | |||
60 | /* key, cert */ | ||
61 | if ((dh_client_pub = BN_new()) == NULL) | ||
62 | fatal("dh_client_pub == NULL"); | ||
63 | packet_get_bignum2(dh_client_pub); | ||
64 | packet_check_eom(); | ||
65 | |||
66 | #ifdef DEBUG_KEXDH | ||
67 | fprintf(stderr, "dh_client_pub= "); | ||
68 | BN_print_fp(stderr, dh_client_pub); | ||
69 | fprintf(stderr, "\n"); | ||
70 | debug("bits %d", BN_num_bits(dh_client_pub)); | ||
71 | #endif | ||
72 | |||
73 | #ifdef DEBUG_KEXDH | ||
74 | DHparams_print_fp(stderr, dh); | ||
75 | fprintf(stderr, "pub= "); | ||
76 | BN_print_fp(stderr, dh->pub_key); | ||
77 | fprintf(stderr, "\n"); | ||
78 | #endif | ||
79 | if (!dh_pub_is_valid(dh, dh_client_pub)) | ||
80 | packet_disconnect("bad client public DH value"); | ||
81 | |||
82 | klen = DH_size(dh); | ||
83 | kbuf = xmalloc(klen); | ||
84 | kout = DH_compute_key(kbuf, dh_client_pub, dh); | ||
85 | #ifdef DEBUG_KEXDH | ||
86 | dump_digest("shared secret", kbuf, kout); | ||
87 | #endif | ||
88 | if ((shared_secret = BN_new()) == NULL) | ||
89 | fatal("kexdh_server: BN_new failed"); | ||
90 | BN_bin2bn(kbuf, kout, shared_secret); | ||
91 | memset(kbuf, 0, klen); | ||
92 | xfree(kbuf); | ||
93 | |||
94 | key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); | ||
95 | |||
96 | /* calc H */ | ||
97 | hash = kex_dh_hash( | ||
98 | kex->client_version_string, | ||
99 | kex->server_version_string, | ||
100 | buffer_ptr(&kex->peer), buffer_len(&kex->peer), | ||
101 | buffer_ptr(&kex->my), buffer_len(&kex->my), | ||
102 | server_host_key_blob, sbloblen, | ||
103 | dh_client_pub, | ||
104 | dh->pub_key, | ||
105 | shared_secret | ||
106 | ); | ||
107 | BN_clear_free(dh_client_pub); | ||
108 | |||
109 | /* save session id := H */ | ||
110 | /* XXX hashlen depends on KEX */ | ||
111 | if (kex->session_id == NULL) { | ||
112 | kex->session_id_len = 20; | ||
113 | kex->session_id = xmalloc(kex->session_id_len); | ||
114 | memcpy(kex->session_id, hash, kex->session_id_len); | ||
115 | } | ||
116 | |||
117 | /* sign H */ | ||
118 | /* XXX hashlen depends on KEX */ | ||
119 | PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20)); | ||
120 | |||
121 | /* destroy_sensitive_data(); */ | ||
122 | |||
123 | /* send server hostkey, DH pubkey 'f' and singed H */ | ||
124 | packet_start(SSH2_MSG_KEXDH_REPLY); | ||
125 | packet_put_string(server_host_key_blob, sbloblen); | ||
126 | packet_put_bignum2(dh->pub_key); /* f */ | ||
127 | packet_put_string(signature, slen); | ||
128 | packet_send(); | ||
129 | |||
130 | xfree(signature); | ||
131 | xfree(server_host_key_blob); | ||
132 | /* have keys, free DH */ | ||
133 | DH_free(dh); | ||
134 | |||
135 | kex_derive_keys(kex, hash, shared_secret); | ||
136 | BN_clear_free(shared_secret); | ||
137 | kex_finish(kex); | ||
138 | } | ||
@@ -24,23 +24,16 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include "includes.h" | 26 | #include "includes.h" |
27 | RCSID("$OpenBSD: kexgex.c,v 1.22 2002/03/24 17:27:03 stevesk Exp $"); | 27 | RCSID("$OpenBSD: kexgex.c,v 1.23 2003/02/16 17:09:57 markus Exp $"); |
28 | 28 | ||
29 | #include <openssl/bn.h> | 29 | #include <openssl/evp.h> |
30 | 30 | ||
31 | #include "xmalloc.h" | ||
32 | #include "buffer.h" | 31 | #include "buffer.h" |
33 | #include "bufaux.h" | 32 | #include "bufaux.h" |
34 | #include "key.h" | ||
35 | #include "kex.h" | 33 | #include "kex.h" |
36 | #include "log.h" | ||
37 | #include "packet.h" | ||
38 | #include "dh.h" | ||
39 | #include "ssh2.h" | 34 | #include "ssh2.h" |
40 | #include "compat.h" | ||
41 | #include "monitor_wrap.h" | ||
42 | 35 | ||
43 | static u_char * | 36 | u_char * |
44 | kexgex_hash( | 37 | kexgex_hash( |
45 | char *client_version_string, | 38 | char *client_version_string, |
46 | char *server_version_string, | 39 | char *server_version_string, |
@@ -97,318 +90,3 @@ kexgex_hash( | |||
97 | #endif | 90 | #endif |
98 | return digest; | 91 | return digest; |
99 | } | 92 | } |
100 | |||
101 | /* client */ | ||
102 | |||
103 | static void | ||
104 | kexgex_client(Kex *kex) | ||
105 | { | ||
106 | BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; | ||
107 | BIGNUM *p = NULL, *g = NULL; | ||
108 | Key *server_host_key; | ||
109 | u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; | ||
110 | u_int klen, kout, slen, sbloblen; | ||
111 | int min, max, nbits; | ||
112 | DH *dh; | ||
113 | |||
114 | nbits = dh_estimate(kex->we_need * 8); | ||
115 | |||
116 | if (datafellows & SSH_OLD_DHGEX) { | ||
117 | debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD sent"); | ||
118 | |||
119 | /* Old GEX request */ | ||
120 | packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); | ||
121 | packet_put_int(nbits); | ||
122 | min = DH_GRP_MIN; | ||
123 | max = DH_GRP_MAX; | ||
124 | } else { | ||
125 | debug("SSH2_MSG_KEX_DH_GEX_REQUEST sent"); | ||
126 | |||
127 | /* New GEX request */ | ||
128 | min = DH_GRP_MIN; | ||
129 | max = DH_GRP_MAX; | ||
130 | packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); | ||
131 | packet_put_int(min); | ||
132 | packet_put_int(nbits); | ||
133 | packet_put_int(max); | ||
134 | } | ||
135 | #ifdef DEBUG_KEXDH | ||
136 | fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n", | ||
137 | min, nbits, max); | ||
138 | #endif | ||
139 | packet_send(); | ||
140 | |||
141 | debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP"); | ||
142 | packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP); | ||
143 | |||
144 | if ((p = BN_new()) == NULL) | ||
145 | fatal("BN_new"); | ||
146 | packet_get_bignum2(p); | ||
147 | if ((g = BN_new()) == NULL) | ||
148 | fatal("BN_new"); | ||
149 | packet_get_bignum2(g); | ||
150 | packet_check_eom(); | ||
151 | |||
152 | if (BN_num_bits(p) < min || BN_num_bits(p) > max) | ||
153 | fatal("DH_GEX group out of range: %d !< %d !< %d", | ||
154 | min, BN_num_bits(p), max); | ||
155 | |||
156 | dh = dh_new_group(g, p); | ||
157 | dh_gen_key(dh, kex->we_need * 8); | ||
158 | |||
159 | #ifdef DEBUG_KEXDH | ||
160 | DHparams_print_fp(stderr, dh); | ||
161 | fprintf(stderr, "pub= "); | ||
162 | BN_print_fp(stderr, dh->pub_key); | ||
163 | fprintf(stderr, "\n"); | ||
164 | #endif | ||
165 | |||
166 | debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); | ||
167 | /* generate and send 'e', client DH public key */ | ||
168 | packet_start(SSH2_MSG_KEX_DH_GEX_INIT); | ||
169 | packet_put_bignum2(dh->pub_key); | ||
170 | packet_send(); | ||
171 | |||
172 | debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY"); | ||
173 | packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY); | ||
174 | |||
175 | /* key, cert */ | ||
176 | server_host_key_blob = packet_get_string(&sbloblen); | ||
177 | server_host_key = key_from_blob(server_host_key_blob, sbloblen); | ||
178 | if (server_host_key == NULL) | ||
179 | fatal("cannot decode server_host_key_blob"); | ||
180 | if (server_host_key->type != kex->hostkey_type) | ||
181 | fatal("type mismatch for decoded server_host_key_blob"); | ||
182 | if (kex->verify_host_key == NULL) | ||
183 | fatal("cannot verify server_host_key"); | ||
184 | if (kex->verify_host_key(server_host_key) == -1) | ||
185 | fatal("server_host_key verification failed"); | ||
186 | |||
187 | /* DH paramter f, server public DH key */ | ||
188 | if ((dh_server_pub = BN_new()) == NULL) | ||
189 | fatal("dh_server_pub == NULL"); | ||
190 | packet_get_bignum2(dh_server_pub); | ||
191 | |||
192 | #ifdef DEBUG_KEXDH | ||
193 | fprintf(stderr, "dh_server_pub= "); | ||
194 | BN_print_fp(stderr, dh_server_pub); | ||
195 | fprintf(stderr, "\n"); | ||
196 | debug("bits %d", BN_num_bits(dh_server_pub)); | ||
197 | #endif | ||
198 | |||
199 | /* signed H */ | ||
200 | signature = packet_get_string(&slen); | ||
201 | packet_check_eom(); | ||
202 | |||
203 | if (!dh_pub_is_valid(dh, dh_server_pub)) | ||
204 | packet_disconnect("bad server public DH value"); | ||
205 | |||
206 | klen = DH_size(dh); | ||
207 | kbuf = xmalloc(klen); | ||
208 | kout = DH_compute_key(kbuf, dh_server_pub, dh); | ||
209 | #ifdef DEBUG_KEXDH | ||
210 | dump_digest("shared secret", kbuf, kout); | ||
211 | #endif | ||
212 | if ((shared_secret = BN_new()) == NULL) | ||
213 | fatal("kexgex_client: BN_new failed"); | ||
214 | BN_bin2bn(kbuf, kout, shared_secret); | ||
215 | memset(kbuf, 0, klen); | ||
216 | xfree(kbuf); | ||
217 | |||
218 | if (datafellows & SSH_OLD_DHGEX) | ||
219 | min = max = -1; | ||
220 | |||
221 | /* calc and verify H */ | ||
222 | hash = kexgex_hash( | ||
223 | kex->client_version_string, | ||
224 | kex->server_version_string, | ||
225 | buffer_ptr(&kex->my), buffer_len(&kex->my), | ||
226 | buffer_ptr(&kex->peer), buffer_len(&kex->peer), | ||
227 | server_host_key_blob, sbloblen, | ||
228 | min, nbits, max, | ||
229 | dh->p, dh->g, | ||
230 | dh->pub_key, | ||
231 | dh_server_pub, | ||
232 | shared_secret | ||
233 | ); | ||
234 | /* have keys, free DH */ | ||
235 | DH_free(dh); | ||
236 | xfree(server_host_key_blob); | ||
237 | BN_clear_free(dh_server_pub); | ||
238 | |||
239 | if (key_verify(server_host_key, signature, slen, hash, 20) != 1) | ||
240 | fatal("key_verify failed for server_host_key"); | ||
241 | key_free(server_host_key); | ||
242 | xfree(signature); | ||
243 | |||
244 | /* save session id */ | ||
245 | if (kex->session_id == NULL) { | ||
246 | kex->session_id_len = 20; | ||
247 | kex->session_id = xmalloc(kex->session_id_len); | ||
248 | memcpy(kex->session_id, hash, kex->session_id_len); | ||
249 | } | ||
250 | kex_derive_keys(kex, hash, shared_secret); | ||
251 | BN_clear_free(shared_secret); | ||
252 | |||
253 | kex_finish(kex); | ||
254 | } | ||
255 | |||
256 | /* server */ | ||
257 | |||
258 | static void | ||
259 | kexgex_server(Kex *kex) | ||
260 | { | ||
261 | BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; | ||
262 | Key *server_host_key; | ||
263 | DH *dh; | ||
264 | u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; | ||
265 | u_int sbloblen, klen, kout, slen; | ||
266 | int min = -1, max = -1, nbits = -1, type; | ||
267 | |||
268 | if (kex->load_host_key == NULL) | ||
269 | fatal("Cannot load hostkey"); | ||
270 | server_host_key = kex->load_host_key(kex->hostkey_type); | ||
271 | if (server_host_key == NULL) | ||
272 | fatal("Unsupported hostkey type %d", kex->hostkey_type); | ||
273 | |||
274 | type = packet_read(); | ||
275 | switch (type) { | ||
276 | case SSH2_MSG_KEX_DH_GEX_REQUEST: | ||
277 | debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); | ||
278 | min = packet_get_int(); | ||
279 | nbits = packet_get_int(); | ||
280 | max = packet_get_int(); | ||
281 | min = MAX(DH_GRP_MIN, min); | ||
282 | max = MIN(DH_GRP_MAX, max); | ||
283 | break; | ||
284 | case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: | ||
285 | debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); | ||
286 | nbits = packet_get_int(); | ||
287 | min = DH_GRP_MIN; | ||
288 | max = DH_GRP_MAX; | ||
289 | /* unused for old GEX */ | ||
290 | break; | ||
291 | default: | ||
292 | fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type); | ||
293 | } | ||
294 | packet_check_eom(); | ||
295 | |||
296 | if (max < min || nbits < min || max < nbits) | ||
297 | fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d", | ||
298 | min, nbits, max); | ||
299 | |||
300 | /* Contact privileged parent */ | ||
301 | dh = PRIVSEP(choose_dh(min, nbits, max)); | ||
302 | if (dh == NULL) | ||
303 | packet_disconnect("Protocol error: no matching DH grp found"); | ||
304 | |||
305 | debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); | ||
306 | packet_start(SSH2_MSG_KEX_DH_GEX_GROUP); | ||
307 | packet_put_bignum2(dh->p); | ||
308 | packet_put_bignum2(dh->g); | ||
309 | packet_send(); | ||
310 | |||
311 | /* flush */ | ||
312 | packet_write_wait(); | ||
313 | |||
314 | /* Compute our exchange value in parallel with the client */ | ||
315 | dh_gen_key(dh, kex->we_need * 8); | ||
316 | |||
317 | debug("expecting SSH2_MSG_KEX_DH_GEX_INIT"); | ||
318 | packet_read_expect(SSH2_MSG_KEX_DH_GEX_INIT); | ||
319 | |||
320 | /* key, cert */ | ||
321 | if ((dh_client_pub = BN_new()) == NULL) | ||
322 | fatal("dh_client_pub == NULL"); | ||
323 | packet_get_bignum2(dh_client_pub); | ||
324 | packet_check_eom(); | ||
325 | |||
326 | #ifdef DEBUG_KEXDH | ||
327 | fprintf(stderr, "dh_client_pub= "); | ||
328 | BN_print_fp(stderr, dh_client_pub); | ||
329 | fprintf(stderr, "\n"); | ||
330 | debug("bits %d", BN_num_bits(dh_client_pub)); | ||
331 | #endif | ||
332 | |||
333 | #ifdef DEBUG_KEXDH | ||
334 | DHparams_print_fp(stderr, dh); | ||
335 | fprintf(stderr, "pub= "); | ||
336 | BN_print_fp(stderr, dh->pub_key); | ||
337 | fprintf(stderr, "\n"); | ||
338 | #endif | ||
339 | if (!dh_pub_is_valid(dh, dh_client_pub)) | ||
340 | packet_disconnect("bad client public DH value"); | ||
341 | |||
342 | klen = DH_size(dh); | ||
343 | kbuf = xmalloc(klen); | ||
344 | kout = DH_compute_key(kbuf, dh_client_pub, dh); | ||
345 | #ifdef DEBUG_KEXDH | ||
346 | dump_digest("shared secret", kbuf, kout); | ||
347 | #endif | ||
348 | if ((shared_secret = BN_new()) == NULL) | ||
349 | fatal("kexgex_server: BN_new failed"); | ||
350 | BN_bin2bn(kbuf, kout, shared_secret); | ||
351 | memset(kbuf, 0, klen); | ||
352 | xfree(kbuf); | ||
353 | |||
354 | key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); | ||
355 | |||
356 | if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) | ||
357 | min = max = -1; | ||
358 | |||
359 | /* calc H */ /* XXX depends on 'kex' */ | ||
360 | hash = kexgex_hash( | ||
361 | kex->client_version_string, | ||
362 | kex->server_version_string, | ||
363 | buffer_ptr(&kex->peer), buffer_len(&kex->peer), | ||
364 | buffer_ptr(&kex->my), buffer_len(&kex->my), | ||
365 | server_host_key_blob, sbloblen, | ||
366 | min, nbits, max, | ||
367 | dh->p, dh->g, | ||
368 | dh_client_pub, | ||
369 | dh->pub_key, | ||
370 | shared_secret | ||
371 | ); | ||
372 | BN_clear_free(dh_client_pub); | ||
373 | |||
374 | /* save session id := H */ | ||
375 | /* XXX hashlen depends on KEX */ | ||
376 | if (kex->session_id == NULL) { | ||
377 | kex->session_id_len = 20; | ||
378 | kex->session_id = xmalloc(kex->session_id_len); | ||
379 | memcpy(kex->session_id, hash, kex->session_id_len); | ||
380 | } | ||
381 | |||
382 | /* sign H */ | ||
383 | /* XXX hashlen depends on KEX */ | ||
384 | PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20)); | ||
385 | |||
386 | /* destroy_sensitive_data(); */ | ||
387 | |||
388 | /* send server hostkey, DH pubkey 'f' and singed H */ | ||
389 | debug("SSH2_MSG_KEX_DH_GEX_REPLY sent"); | ||
390 | packet_start(SSH2_MSG_KEX_DH_GEX_REPLY); | ||
391 | packet_put_string(server_host_key_blob, sbloblen); | ||
392 | packet_put_bignum2(dh->pub_key); /* f */ | ||
393 | packet_put_string(signature, slen); | ||
394 | packet_send(); | ||
395 | |||
396 | xfree(signature); | ||
397 | xfree(server_host_key_blob); | ||
398 | /* have keys, free DH */ | ||
399 | DH_free(dh); | ||
400 | |||
401 | kex_derive_keys(kex, hash, shared_secret); | ||
402 | BN_clear_free(shared_secret); | ||
403 | |||
404 | kex_finish(kex); | ||
405 | } | ||
406 | |||
407 | void | ||
408 | kexgex(Kex *kex) | ||
409 | { | ||
410 | if (kex->server) | ||
411 | kexgex_server(kex); | ||
412 | else | ||
413 | kexgex_client(kex); | ||
414 | } | ||
diff --git a/kexgexc.c b/kexgexc.c new file mode 100644 index 000000000..f14ac44ca --- /dev/null +++ b/kexgexc.c | |||
@@ -0,0 +1,189 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000 Niels Provos. All rights reserved. | ||
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * 2. Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * | ||
14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
17 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
24 | */ | ||
25 | |||
26 | #include "includes.h" | ||
27 | RCSID("$OpenBSD: kexgexc.c,v 1.1 2003/02/16 17:09:57 markus Exp $"); | ||
28 | |||
29 | #include "xmalloc.h" | ||
30 | #include "key.h" | ||
31 | #include "kex.h" | ||
32 | #include "log.h" | ||
33 | #include "packet.h" | ||
34 | #include "dh.h" | ||
35 | #include "ssh2.h" | ||
36 | #include "compat.h" | ||
37 | |||
38 | void | ||
39 | kexgex_client(Kex *kex) | ||
40 | { | ||
41 | BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; | ||
42 | BIGNUM *p = NULL, *g = NULL; | ||
43 | Key *server_host_key; | ||
44 | u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; | ||
45 | u_int klen, kout, slen, sbloblen; | ||
46 | int min, max, nbits; | ||
47 | DH *dh; | ||
48 | |||
49 | nbits = dh_estimate(kex->we_need * 8); | ||
50 | |||
51 | if (datafellows & SSH_OLD_DHGEX) { | ||
52 | debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD sent"); | ||
53 | |||
54 | /* Old GEX request */ | ||
55 | packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); | ||
56 | packet_put_int(nbits); | ||
57 | min = DH_GRP_MIN; | ||
58 | max = DH_GRP_MAX; | ||
59 | } else { | ||
60 | debug("SSH2_MSG_KEX_DH_GEX_REQUEST sent"); | ||
61 | |||
62 | /* New GEX request */ | ||
63 | min = DH_GRP_MIN; | ||
64 | max = DH_GRP_MAX; | ||
65 | packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); | ||
66 | packet_put_int(min); | ||
67 | packet_put_int(nbits); | ||
68 | packet_put_int(max); | ||
69 | } | ||
70 | #ifdef DEBUG_KEXDH | ||
71 | fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n", | ||
72 | min, nbits, max); | ||
73 | #endif | ||
74 | packet_send(); | ||
75 | |||
76 | debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP"); | ||
77 | packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP); | ||
78 | |||
79 | if ((p = BN_new()) == NULL) | ||
80 | fatal("BN_new"); | ||
81 | packet_get_bignum2(p); | ||
82 | if ((g = BN_new()) == NULL) | ||
83 | fatal("BN_new"); | ||
84 | packet_get_bignum2(g); | ||
85 | packet_check_eom(); | ||
86 | |||
87 | if (BN_num_bits(p) < min || BN_num_bits(p) > max) | ||
88 | fatal("DH_GEX group out of range: %d !< %d !< %d", | ||
89 | min, BN_num_bits(p), max); | ||
90 | |||
91 | dh = dh_new_group(g, p); | ||
92 | dh_gen_key(dh, kex->we_need * 8); | ||
93 | |||
94 | #ifdef DEBUG_KEXDH | ||
95 | DHparams_print_fp(stderr, dh); | ||
96 | fprintf(stderr, "pub= "); | ||
97 | BN_print_fp(stderr, dh->pub_key); | ||
98 | fprintf(stderr, "\n"); | ||
99 | #endif | ||
100 | |||
101 | debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); | ||
102 | /* generate and send 'e', client DH public key */ | ||
103 | packet_start(SSH2_MSG_KEX_DH_GEX_INIT); | ||
104 | packet_put_bignum2(dh->pub_key); | ||
105 | packet_send(); | ||
106 | |||
107 | debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY"); | ||
108 | packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY); | ||
109 | |||
110 | /* key, cert */ | ||
111 | server_host_key_blob = packet_get_string(&sbloblen); | ||
112 | server_host_key = key_from_blob(server_host_key_blob, sbloblen); | ||
113 | if (server_host_key == NULL) | ||
114 | fatal("cannot decode server_host_key_blob"); | ||
115 | if (server_host_key->type != kex->hostkey_type) | ||
116 | fatal("type mismatch for decoded server_host_key_blob"); | ||
117 | if (kex->verify_host_key == NULL) | ||
118 | fatal("cannot verify server_host_key"); | ||
119 | if (kex->verify_host_key(server_host_key) == -1) | ||
120 | fatal("server_host_key verification failed"); | ||
121 | |||
122 | /* DH paramter f, server public DH key */ | ||
123 | if ((dh_server_pub = BN_new()) == NULL) | ||
124 | fatal("dh_server_pub == NULL"); | ||
125 | packet_get_bignum2(dh_server_pub); | ||
126 | |||
127 | #ifdef DEBUG_KEXDH | ||
128 | fprintf(stderr, "dh_server_pub= "); | ||
129 | BN_print_fp(stderr, dh_server_pub); | ||
130 | fprintf(stderr, "\n"); | ||
131 | debug("bits %d", BN_num_bits(dh_server_pub)); | ||
132 | #endif | ||
133 | |||
134 | /* signed H */ | ||
135 | signature = packet_get_string(&slen); | ||
136 | packet_check_eom(); | ||
137 | |||
138 | if (!dh_pub_is_valid(dh, dh_server_pub)) | ||
139 | packet_disconnect("bad server public DH value"); | ||
140 | |||
141 | klen = DH_size(dh); | ||
142 | kbuf = xmalloc(klen); | ||
143 | kout = DH_compute_key(kbuf, dh_server_pub, dh); | ||
144 | #ifdef DEBUG_KEXDH | ||
145 | dump_digest("shared secret", kbuf, kout); | ||
146 | #endif | ||
147 | if ((shared_secret = BN_new()) == NULL) | ||
148 | fatal("kexgex_client: BN_new failed"); | ||
149 | BN_bin2bn(kbuf, kout, shared_secret); | ||
150 | memset(kbuf, 0, klen); | ||
151 | xfree(kbuf); | ||
152 | |||
153 | if (datafellows & SSH_OLD_DHGEX) | ||
154 | min = max = -1; | ||
155 | |||
156 | /* calc and verify H */ | ||
157 | hash = kexgex_hash( | ||
158 | kex->client_version_string, | ||
159 | kex->server_version_string, | ||
160 | buffer_ptr(&kex->my), buffer_len(&kex->my), | ||
161 | buffer_ptr(&kex->peer), buffer_len(&kex->peer), | ||
162 | server_host_key_blob, sbloblen, | ||
163 | min, nbits, max, | ||
164 | dh->p, dh->g, | ||
165 | dh->pub_key, | ||
166 | dh_server_pub, | ||
167 | shared_secret | ||
168 | ); | ||
169 | /* have keys, free DH */ | ||
170 | DH_free(dh); | ||
171 | xfree(server_host_key_blob); | ||
172 | BN_clear_free(dh_server_pub); | ||
173 | |||
174 | if (key_verify(server_host_key, signature, slen, hash, 20) != 1) | ||
175 | fatal("key_verify failed for server_host_key"); | ||
176 | key_free(server_host_key); | ||
177 | xfree(signature); | ||
178 | |||
179 | /* save session id */ | ||
180 | if (kex->session_id == NULL) { | ||
181 | kex->session_id_len = 20; | ||
182 | kex->session_id = xmalloc(kex->session_id_len); | ||
183 | memcpy(kex->session_id, hash, kex->session_id_len); | ||
184 | } | ||
185 | kex_derive_keys(kex, hash, shared_secret); | ||
186 | BN_clear_free(shared_secret); | ||
187 | |||
188 | kex_finish(kex); | ||
189 | } | ||
diff --git a/kexgexs.c b/kexgexs.c new file mode 100644 index 000000000..baebfcfb0 --- /dev/null +++ b/kexgexs.c | |||
@@ -0,0 +1,186 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000 Niels Provos. All rights reserved. | ||
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * 2. Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * | ||
14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
17 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
24 | */ | ||
25 | |||
26 | #include "includes.h" | ||
27 | RCSID("$OpenBSD: kexgexs.c,v 1.1 2003/02/16 17:09:57 markus Exp $"); | ||
28 | |||
29 | #include "xmalloc.h" | ||
30 | #include "key.h" | ||
31 | #include "kex.h" | ||
32 | #include "log.h" | ||
33 | #include "packet.h" | ||
34 | #include "dh.h" | ||
35 | #include "ssh2.h" | ||
36 | #include "compat.h" | ||
37 | #include "monitor_wrap.h" | ||
38 | |||
39 | void | ||
40 | kexgex_server(Kex *kex) | ||
41 | { | ||
42 | BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; | ||
43 | Key *server_host_key; | ||
44 | DH *dh; | ||
45 | u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; | ||
46 | u_int sbloblen, klen, kout, slen; | ||
47 | int min = -1, max = -1, nbits = -1, type; | ||
48 | |||
49 | if (kex->load_host_key == NULL) | ||
50 | fatal("Cannot load hostkey"); | ||
51 | server_host_key = kex->load_host_key(kex->hostkey_type); | ||
52 | if (server_host_key == NULL) | ||
53 | fatal("Unsupported hostkey type %d", kex->hostkey_type); | ||
54 | |||
55 | type = packet_read(); | ||
56 | switch (type) { | ||
57 | case SSH2_MSG_KEX_DH_GEX_REQUEST: | ||
58 | debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); | ||
59 | min = packet_get_int(); | ||
60 | nbits = packet_get_int(); | ||
61 | max = packet_get_int(); | ||
62 | min = MAX(DH_GRP_MIN, min); | ||
63 | max = MIN(DH_GRP_MAX, max); | ||
64 | break; | ||
65 | case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: | ||
66 | debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); | ||
67 | nbits = packet_get_int(); | ||
68 | min = DH_GRP_MIN; | ||
69 | max = DH_GRP_MAX; | ||
70 | /* unused for old GEX */ | ||
71 | break; | ||
72 | default: | ||
73 | fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type); | ||
74 | } | ||
75 | packet_check_eom(); | ||
76 | |||
77 | if (max < min || nbits < min || max < nbits) | ||
78 | fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d", | ||
79 | min, nbits, max); | ||
80 | |||
81 | /* Contact privileged parent */ | ||
82 | dh = PRIVSEP(choose_dh(min, nbits, max)); | ||
83 | if (dh == NULL) | ||
84 | packet_disconnect("Protocol error: no matching DH grp found"); | ||
85 | |||
86 | debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); | ||
87 | packet_start(SSH2_MSG_KEX_DH_GEX_GROUP); | ||
88 | packet_put_bignum2(dh->p); | ||
89 | packet_put_bignum2(dh->g); | ||
90 | packet_send(); | ||
91 | |||
92 | /* flush */ | ||
93 | packet_write_wait(); | ||
94 | |||
95 | /* Compute our exchange value in parallel with the client */ | ||
96 | dh_gen_key(dh, kex->we_need * 8); | ||
97 | |||
98 | debug("expecting SSH2_MSG_KEX_DH_GEX_INIT"); | ||
99 | packet_read_expect(SSH2_MSG_KEX_DH_GEX_INIT); | ||
100 | |||
101 | /* key, cert */ | ||
102 | if ((dh_client_pub = BN_new()) == NULL) | ||
103 | fatal("dh_client_pub == NULL"); | ||
104 | packet_get_bignum2(dh_client_pub); | ||
105 | packet_check_eom(); | ||
106 | |||
107 | #ifdef DEBUG_KEXDH | ||
108 | fprintf(stderr, "dh_client_pub= "); | ||
109 | BN_print_fp(stderr, dh_client_pub); | ||
110 | fprintf(stderr, "\n"); | ||
111 | debug("bits %d", BN_num_bits(dh_client_pub)); | ||
112 | #endif | ||
113 | |||
114 | #ifdef DEBUG_KEXDH | ||
115 | DHparams_print_fp(stderr, dh); | ||
116 | fprintf(stderr, "pub= "); | ||
117 | BN_print_fp(stderr, dh->pub_key); | ||
118 | fprintf(stderr, "\n"); | ||
119 | #endif | ||
120 | if (!dh_pub_is_valid(dh, dh_client_pub)) | ||
121 | packet_disconnect("bad client public DH value"); | ||
122 | |||
123 | klen = DH_size(dh); | ||
124 | kbuf = xmalloc(klen); | ||
125 | kout = DH_compute_key(kbuf, dh_client_pub, dh); | ||
126 | #ifdef DEBUG_KEXDH | ||
127 | dump_digest("shared secret", kbuf, kout); | ||
128 | #endif | ||
129 | if ((shared_secret = BN_new()) == NULL) | ||
130 | fatal("kexgex_server: BN_new failed"); | ||
131 | BN_bin2bn(kbuf, kout, shared_secret); | ||
132 | memset(kbuf, 0, klen); | ||
133 | xfree(kbuf); | ||
134 | |||
135 | key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); | ||
136 | |||
137 | if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) | ||
138 | min = max = -1; | ||
139 | |||
140 | /* calc H */ /* XXX depends on 'kex' */ | ||
141 | hash = kexgex_hash( | ||
142 | kex->client_version_string, | ||
143 | kex->server_version_string, | ||
144 | buffer_ptr(&kex->peer), buffer_len(&kex->peer), | ||
145 | buffer_ptr(&kex->my), buffer_len(&kex->my), | ||
146 | server_host_key_blob, sbloblen, | ||
147 | min, nbits, max, | ||
148 | dh->p, dh->g, | ||
149 | dh_client_pub, | ||
150 | dh->pub_key, | ||
151 | shared_secret | ||
152 | ); | ||
153 | BN_clear_free(dh_client_pub); | ||
154 | |||
155 | /* save session id := H */ | ||
156 | /* XXX hashlen depends on KEX */ | ||
157 | if (kex->session_id == NULL) { | ||
158 | kex->session_id_len = 20; | ||
159 | kex->session_id = xmalloc(kex->session_id_len); | ||
160 | memcpy(kex->session_id, hash, kex->session_id_len); | ||
161 | } | ||
162 | |||
163 | /* sign H */ | ||
164 | /* XXX hashlen depends on KEX */ | ||
165 | PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20)); | ||
166 | |||
167 | /* destroy_sensitive_data(); */ | ||
168 | |||
169 | /* send server hostkey, DH pubkey 'f' and singed H */ | ||
170 | debug("SSH2_MSG_KEX_DH_GEX_REPLY sent"); | ||
171 | packet_start(SSH2_MSG_KEX_DH_GEX_REPLY); | ||
172 | packet_put_string(server_host_key_blob, sbloblen); | ||
173 | packet_put_bignum2(dh->pub_key); /* f */ | ||
174 | packet_put_string(signature, slen); | ||
175 | packet_send(); | ||
176 | |||
177 | xfree(signature); | ||
178 | xfree(server_host_key_blob); | ||
179 | /* have keys, free DH */ | ||
180 | DH_free(dh); | ||
181 | |||
182 | kex_derive_keys(kex, hash, shared_secret); | ||
183 | BN_clear_free(shared_secret); | ||
184 | |||
185 | kex_finish(kex); | ||
186 | } | ||
diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 8c14d6d26..5b4eb82d1 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c | |||
@@ -7,7 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include "includes.h" | 9 | #include "includes.h" |
10 | RCSID("$OpenBSD: ssh-keyscan.c,v 1.40 2002/07/06 17:47:58 stevesk Exp $"); | 10 | RCSID("$OpenBSD: ssh-keyscan.c,v 1.41 2003/02/16 17:09:57 markus Exp $"); |
11 | 11 | ||
12 | #include "openbsd-compat/sys-queue.h" | 12 | #include "openbsd-compat/sys-queue.h" |
13 | 13 | ||
@@ -354,6 +354,8 @@ keygrab_ssh2(con *c) | |||
354 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA? | 354 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA? |
355 | "ssh-dss": "ssh-rsa"; | 355 | "ssh-dss": "ssh-rsa"; |
356 | c->c_kex = kex_setup(myproposal); | 356 | c->c_kex = kex_setup(myproposal); |
357 | c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; | ||
358 | c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; | ||
357 | c->c_kex->verify_host_key = hostjump; | 359 | c->c_kex->verify_host_key = hostjump; |
358 | 360 | ||
359 | if (!(j = setjmp(kexjmp))) { | 361 | if (!(j = setjmp(kexjmp))) { |
diff --git a/sshconnect2.c b/sshconnect2.c index de33e142b..81d1b91c7 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: sshconnect2.c,v 1.110 2002/12/19 00:07:02 djm Exp $"); | 26 | RCSID("$OpenBSD: sshconnect2.c,v 1.111 2003/02/16 17:09:57 markus Exp $"); |
27 | 27 | ||
28 | #include "ssh.h" | 28 | #include "ssh.h" |
29 | #include "ssh2.h" | 29 | #include "ssh2.h" |
@@ -110,6 +110,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
110 | 110 | ||
111 | /* start key exchange */ | 111 | /* start key exchange */ |
112 | kex = kex_setup(myproposal); | 112 | kex = kex_setup(myproposal); |
113 | kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; | ||
114 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; | ||
113 | kex->client_version_string=client_version_string; | 115 | kex->client_version_string=client_version_string; |
114 | kex->server_version_string=server_version_string; | 116 | kex->server_version_string=server_version_string; |
115 | kex->verify_host_key=&verify_host_key_callback; | 117 | kex->verify_host_key=&verify_host_key_callback; |
@@ -42,7 +42,7 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include "includes.h" | 44 | #include "includes.h" |
45 | RCSID("$OpenBSD: sshd.c,v 1.262 2003/01/27 17:06:31 markus Exp $"); | 45 | RCSID("$OpenBSD: sshd.c,v 1.263 2003/02/16 17:09:57 markus Exp $"); |
46 | 46 | ||
47 | #include <openssl/dh.h> | 47 | #include <openssl/dh.h> |
48 | #include <openssl/bn.h> | 48 | #include <openssl/bn.h> |
@@ -202,8 +202,8 @@ int *startup_pipes = NULL; | |||
202 | int startup_pipe; /* in child */ | 202 | int startup_pipe; /* in child */ |
203 | 203 | ||
204 | /* variables used for privilege separation */ | 204 | /* variables used for privilege separation */ |
205 | extern struct monitor *pmonitor; | 205 | int use_privsep; |
206 | extern int use_privsep; | 206 | struct monitor *pmonitor; |
207 | 207 | ||
208 | /* Prototypes for various functions defined later in this file. */ | 208 | /* Prototypes for various functions defined later in this file. */ |
209 | void destroy_sensitive_data(void); | 209 | void destroy_sensitive_data(void); |
@@ -1814,6 +1814,8 @@ do_ssh2_kex(void) | |||
1814 | 1814 | ||
1815 | /* start key exchange */ | 1815 | /* start key exchange */ |
1816 | kex = kex_setup(myproposal); | 1816 | kex = kex_setup(myproposal); |
1817 | kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; | ||
1818 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; | ||
1817 | kex->server = 1; | 1819 | kex->server = 1; |
1818 | kex->client_version_string=client_version_string; | 1820 | kex->client_version_string=client_version_string; |
1819 | kex->server_version_string=server_version_string; | 1821 | kex->server_version_string=server_version_string; |