summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2001-04-04 01:56:17 +0000
committerBen Lindstrom <mouring@eviladmin.org>2001-04-04 01:56:17 +0000
commit20d7c7b02c92c28007dba8b08e617a415146d1df (patch)
tree8b5258b1065f6ad079d7410c3a29562903f128bb /sshconnect2.c
parent86ebcb6cf55ea296a7921d157afdc03c07102933 (diff)
- markus@cvs.openbsd.org 2001/04/03 19:53:29
[dh.c dh.h kex.c kex.h sshconnect2.c sshd.c] move kex to kex*.c, used dispatch_set() callbacks for kex. should make rekeying easier.
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c409
1 files changed, 28 insertions, 381 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index 460d614f0..4ed39a23e 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: sshconnect2.c,v 1.60 2001/03/29 21:06:21 stevesk Exp $"); 26RCSID("$OpenBSD: sshconnect2.c,v 1.61 2001/04/03 19:53:29 markus Exp $");
27 27
28#include <openssl/bn.h> 28#include <openssl/bn.h>
29#include <openssl/md5.h> 29#include <openssl/md5.h>
@@ -47,15 +47,12 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.60 2001/03/29 21:06:21 stevesk Exp $");
47#include "authfile.h" 47#include "authfile.h"
48#include "cli.h" 48#include "cli.h"
49#include "dh.h" 49#include "dh.h"
50#include "dispatch.h"
51#include "authfd.h" 50#include "authfd.h"
52#include "log.h" 51#include "log.h"
53#include "readconf.h" 52#include "readconf.h"
54#include "readpass.h" 53#include "readpass.h"
55#include "match.h" 54#include "match.h"
56 55#include "dispatch.h"
57void ssh_dh1_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
58void ssh_dhgex_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
59 56
60/* import */ 57/* import */
61extern char *client_version_string; 58extern char *client_version_string;
@@ -69,13 +66,24 @@ extern Options options;
69u_char *session_id2 = NULL; 66u_char *session_id2 = NULL;
70int session_id2_len = 0; 67int session_id2_len = 0;
71 68
69char *xxx_host;
70struct sockaddr *xxx_hostaddr;
71
72int
73check_host_key_callback(Key *hostkey)
74{
75 check_host_key(xxx_host, xxx_hostaddr, hostkey,
76 options.user_hostfile2, options.system_hostfile2);
77 return 0;
78}
79
72void 80void
73ssh_kex2(char *host, struct sockaddr *hostaddr) 81ssh_kex2(char *host, struct sockaddr *hostaddr)
74{ 82{
75 int i, plen;
76 Kex *kex; 83 Kex *kex;
77 Buffer *client_kexinit, *server_kexinit; 84
78 char *sprop[PROPOSAL_MAX]; 85 xxx_host = host;
86 xxx_hostaddr = hostaddr;
79 87
80 if (options.ciphers == (char *)-1) { 88 if (options.ciphers == (char *)-1) {
81 log("No valid ciphers for protocol version 2 given, using defaults."); 89 log("No valid ciphers for protocol version 2 given, using defaults.");
@@ -101,46 +109,13 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
101 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; 109 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
102 } 110 }
103 111
104 /* buffers with raw kexinit messages */ 112 kex = kex_start(myproposal);
105 server_kexinit = xmalloc(sizeof(*server_kexinit)); 113 kex->client_version_string=client_version_string;
106 buffer_init(server_kexinit); 114 kex->server_version_string=server_version_string;
107 client_kexinit = kex_init(myproposal); 115 kex->check_host_key=&check_host_key_callback;
108
109 /* algorithm negotiation */
110 kex_exchange_kexinit(client_kexinit, server_kexinit, sprop);
111 kex = kex_choose_conf(myproposal, sprop, 0);
112 for (i = 0; i < PROPOSAL_MAX; i++)
113 xfree(sprop[i]);
114
115 /* server authentication and session key agreement */
116 switch(kex->kex_type) {
117 case DH_GRP1_SHA1:
118 ssh_dh1_client(kex, host, hostaddr,
119 client_kexinit, server_kexinit);
120 break;
121 case DH_GEX_SHA1:
122 ssh_dhgex_client(kex, host, hostaddr, client_kexinit,
123 server_kexinit);
124 break;
125 default:
126 fatal("Unsupported key exchange %d", kex->kex_type);
127 }
128
129 buffer_free(client_kexinit);
130 buffer_free(server_kexinit);
131 xfree(client_kexinit);
132 xfree(server_kexinit);
133 116
134 debug("Wait SSH2_MSG_NEWKEYS."); 117 /* start key exchange */
135 packet_read_expect(&plen, SSH2_MSG_NEWKEYS); 118 dispatch_run(DISPATCH_BLOCK, &kex->newkeys, kex);
136 packet_done();
137 debug("GOT SSH2_MSG_NEWKEYS.");
138
139 debug("send SSH2_MSG_NEWKEYS.");
140 packet_start(SSH2_MSG_NEWKEYS);
141 packet_send();
142 packet_write_wait();
143 debug("done: send SSH2_MSG_NEWKEYS.");
144 119
145#ifdef DEBUG_KEXDH 120#ifdef DEBUG_KEXDH
146 /* send 1st encrypted/maced/compressed message */ 121 /* send 1st encrypted/maced/compressed message */
@@ -149,339 +124,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
149 packet_send(); 124 packet_send();
150 packet_write_wait(); 125 packet_write_wait();
151#endif 126#endif
152 debug("done: KEX2."); 127 debug("done: ssh_kex2.");
153}
154
155/* diffie-hellman-group1-sha1 */
156
157void
158ssh_dh1_client(Kex *kex, char *host, struct sockaddr *hostaddr,
159 Buffer *client_kexinit, Buffer *server_kexinit)
160{
161#ifdef DEBUG_KEXDH
162 int i;
163#endif
164 int plen, dlen;
165 u_int klen, kout;
166 char *signature = NULL;
167 u_int slen;
168 char *server_host_key_blob = NULL;
169 Key *server_host_key;
170 u_int sbloblen;
171 DH *dh;
172 BIGNUM *dh_server_pub = 0;
173 BIGNUM *shared_secret = 0;
174 u_char *kbuf;
175 u_char *hash;
176
177 debug("Sending SSH2_MSG_KEXDH_INIT.");
178 /* generate and send 'e', client DH public key */
179 dh = dh_new_group1();
180 dh_gen_key(dh, kex->we_need * 8);
181 packet_start(SSH2_MSG_KEXDH_INIT);
182 packet_put_bignum2(dh->pub_key);
183 packet_send();
184 packet_write_wait();
185
186#ifdef DEBUG_KEXDH
187 fprintf(stderr, "\np= ");
188 BN_print_fp(stderr, dh->p);
189 fprintf(stderr, "\ng= ");
190 BN_print_fp(stderr, dh->g);
191 fprintf(stderr, "\npub= ");
192 BN_print_fp(stderr, dh->pub_key);
193 fprintf(stderr, "\n");
194 DHparams_print_fp(stderr, dh);
195#endif
196
197 debug("Wait SSH2_MSG_KEXDH_REPLY.");
198
199 packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY);
200
201 debug("Got SSH2_MSG_KEXDH_REPLY.");
202
203 /* key, cert */
204 server_host_key_blob = packet_get_string(&sbloblen);
205 server_host_key = key_from_blob(server_host_key_blob, sbloblen);
206 if (server_host_key == NULL)
207 fatal("cannot decode server_host_key_blob");
208
209 check_host_key(host, hostaddr, server_host_key,
210 options.user_hostfile2, options.system_hostfile2);
211
212 /* DH paramter f, server public DH key */
213 dh_server_pub = BN_new();
214 if (dh_server_pub == NULL)
215 fatal("dh_server_pub == NULL");
216 packet_get_bignum2(dh_server_pub, &dlen);
217
218#ifdef DEBUG_KEXDH
219 fprintf(stderr, "\ndh_server_pub= ");
220 BN_print_fp(stderr, dh_server_pub);
221 fprintf(stderr, "\n");
222 debug("bits %d", BN_num_bits(dh_server_pub));
223#endif
224
225 /* signed H */
226 signature = packet_get_string(&slen);
227 packet_done();
228
229 if (!dh_pub_is_valid(dh, dh_server_pub))
230 packet_disconnect("bad server public DH value");
231
232 klen = DH_size(dh);
233 kbuf = xmalloc(klen);
234 kout = DH_compute_key(kbuf, dh_server_pub, dh);
235#ifdef DEBUG_KEXDH
236 debug("shared secret: len %d/%d", klen, kout);
237 fprintf(stderr, "shared secret == ");
238 for (i = 0; i< kout; i++)
239 fprintf(stderr, "%02x", (kbuf[i])&0xff);
240 fprintf(stderr, "\n");
241#endif
242 shared_secret = BN_new();
243
244 BN_bin2bn(kbuf, kout, shared_secret);
245 memset(kbuf, 0, klen);
246 xfree(kbuf);
247
248 /* calc and verify H */
249 hash = kex_hash(
250 client_version_string,
251 server_version_string,
252 buffer_ptr(client_kexinit), buffer_len(client_kexinit),
253 buffer_ptr(server_kexinit), buffer_len(server_kexinit),
254 server_host_key_blob, sbloblen,
255 dh->pub_key,
256 dh_server_pub,
257 shared_secret
258 );
259 xfree(server_host_key_blob);
260 DH_free(dh);
261 BN_free(dh_server_pub);
262#ifdef DEBUG_KEXDH
263 fprintf(stderr, "hash == ");
264 for (i = 0; i< 20; i++)
265 fprintf(stderr, "%02x", (hash[i])&0xff);
266 fprintf(stderr, "\n");
267#endif
268 if (key_verify(server_host_key, (u_char *)signature, slen, hash, 20) != 1)
269 fatal("key_verify failed for server_host_key");
270 key_free(server_host_key);
271 xfree(signature);
272
273 kex_derive_keys(kex, hash, shared_secret);
274 BN_clear_free(shared_secret);
275 packet_set_kex(kex);
276
277 /* save session id */
278 session_id2_len = 20;
279 session_id2 = xmalloc(session_id2_len);
280 memcpy(session_id2, hash, session_id2_len);
281}
282
283/* diffie-hellman-group-exchange-sha1 */
284
285/*
286 * Estimates the group order for a Diffie-Hellman group that has an
287 * attack complexity approximately the same as O(2**bits). Estimate
288 * with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3)))
289 */
290
291int
292dh_estimate(int bits)
293{
294
295 if (bits < 64)
296 return (512); /* O(2**63) */
297 if (bits < 128)
298 return (1024); /* O(2**86) */
299 if (bits < 192)
300 return (2048); /* O(2**116) */
301 return (4096); /* O(2**156) */
302}
303
304void
305ssh_dhgex_client(Kex *kex, char *host, struct sockaddr *hostaddr,
306 Buffer *client_kexinit, Buffer *server_kexinit)
307{
308#ifdef DEBUG_KEXDH
309 int i;
310#endif
311 int plen, dlen;
312 u_int klen, kout;
313 char *signature = NULL;
314 u_int slen, nbits, min, max;
315 char *server_host_key_blob = NULL;
316 Key *server_host_key;
317 u_int sbloblen;
318 DH *dh;
319 BIGNUM *dh_server_pub = 0;
320 BIGNUM *shared_secret = 0;
321 BIGNUM *p = 0, *g = 0;
322 u_char *kbuf;
323 u_char *hash;
324
325 nbits = dh_estimate(kex->we_need * 8);
326
327 if (datafellows & SSH_OLD_DHGEX) {
328 debug("Sending SSH2_MSG_KEX_DH_GEX_REQUEST_OLD.");
329
330 /* Old GEX request */
331 packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD);
332 packet_put_int(nbits);
333 min = DH_GRP_MIN;
334 max = DH_GRP_MAX;
335 } else {
336 debug("Sending SSH2_MSG_KEX_DH_GEX_REQUEST.");
337
338 /* New GEX request */
339 min = DH_GRP_MIN;
340 max = DH_GRP_MAX;
341
342 packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST);
343 packet_put_int(min);
344 packet_put_int(nbits);
345 packet_put_int(max);
346 }
347 packet_send();
348 packet_write_wait();
349
350#ifdef DEBUG_KEXDH
351 fprintf(stderr, "\nmin = %d, nbits = %d, max = %d", min, nbits, max);
352#endif
353
354 debug("Wait SSH2_MSG_KEX_DH_GEX_GROUP.");
355
356 packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_GROUP);
357
358 debug("Got SSH2_MSG_KEX_DH_GEX_GROUP.");
359
360 if ((p = BN_new()) == NULL)
361 fatal("BN_new");
362 packet_get_bignum2(p, &dlen);
363 if ((g = BN_new()) == NULL)
364 fatal("BN_new");
365 packet_get_bignum2(g, &dlen);
366
367 if (BN_num_bits(p) < min || BN_num_bits(p) > max)
368 fatal("DH_GEX group out of range: %d !< %d !< %d",
369 min, BN_num_bits(p), max);
370
371 dh = dh_new_group(g, p);
372
373 dh_gen_key(dh, kex->we_need * 8);
374
375#ifdef DEBUG_KEXDH
376 fprintf(stderr, "\np= ");
377 BN_print_fp(stderr, dh->p);
378 fprintf(stderr, "\ng= ");
379 BN_print_fp(stderr, dh->g);
380 fprintf(stderr, "\npub= ");
381 BN_print_fp(stderr, dh->pub_key);
382 fprintf(stderr, "\n");
383 DHparams_print_fp(stderr, dh);
384#endif
385
386 debug("Sending SSH2_MSG_KEX_DH_GEX_INIT.");
387 /* generate and send 'e', client DH public key */
388 packet_start(SSH2_MSG_KEX_DH_GEX_INIT);
389 packet_put_bignum2(dh->pub_key);
390 packet_send();
391 packet_write_wait();
392
393 debug("Wait SSH2_MSG_KEX_DH_GEX_REPLY.");
394
395 packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_REPLY);
396
397 debug("Got SSH2_MSG_KEXDH_REPLY.");
398
399 /* key, cert */
400 server_host_key_blob = packet_get_string(&sbloblen);
401 server_host_key = key_from_blob(server_host_key_blob, sbloblen);
402 if (server_host_key == NULL)
403 fatal("cannot decode server_host_key_blob");
404
405 check_host_key(host, hostaddr, server_host_key,
406 options.user_hostfile2, options.system_hostfile2);
407
408 /* DH paramter f, server public DH key */
409 dh_server_pub = BN_new();
410 if (dh_server_pub == NULL)
411 fatal("dh_server_pub == NULL");
412 packet_get_bignum2(dh_server_pub, &dlen);
413
414#ifdef DEBUG_KEXDH
415 fprintf(stderr, "\ndh_server_pub= ");
416 BN_print_fp(stderr, dh_server_pub);
417 fprintf(stderr, "\n");
418 debug("bits %d", BN_num_bits(dh_server_pub));
419#endif
420
421 /* signed H */
422 signature = packet_get_string(&slen);
423 packet_done();
424
425 if (!dh_pub_is_valid(dh, dh_server_pub))
426 packet_disconnect("bad server public DH value");
427
428 klen = DH_size(dh);
429 kbuf = xmalloc(klen);
430 kout = DH_compute_key(kbuf, dh_server_pub, dh);
431#ifdef DEBUG_KEXDH
432 debug("shared secret: len %d/%d", klen, kout);
433 fprintf(stderr, "shared secret == ");
434 for (i = 0; i< kout; i++)
435 fprintf(stderr, "%02x", (kbuf[i])&0xff);
436 fprintf(stderr, "\n");
437#endif
438 shared_secret = BN_new();
439
440 BN_bin2bn(kbuf, kout, shared_secret);
441 memset(kbuf, 0, klen);
442 xfree(kbuf);
443
444 if (datafellows & SSH_OLD_DHGEX) {
445 /* These values are not included in the hash */
446 min = -1;
447 max = -1;
448 }
449
450 /* calc and verify H */
451 hash = kex_hash_gex(
452 client_version_string,
453 server_version_string,
454 buffer_ptr(client_kexinit), buffer_len(client_kexinit),
455 buffer_ptr(server_kexinit), buffer_len(server_kexinit),
456 server_host_key_blob, sbloblen,
457 min, nbits, max,
458 dh->p, dh->g,
459 dh->pub_key,
460 dh_server_pub,
461 shared_secret
462 );
463 xfree(server_host_key_blob);
464 DH_free(dh);
465 BN_free(dh_server_pub);
466#ifdef DEBUG_KEXDH
467 fprintf(stderr, "hash == ");
468 for (i = 0; i< 20; i++)
469 fprintf(stderr, "%02x", (hash[i])&0xff);
470 fprintf(stderr, "\n");
471#endif
472 if (key_verify(server_host_key, (u_char *)signature, slen, hash, 20) != 1)
473 fatal("key_verify failed for server_host_key");
474 key_free(server_host_key);
475 xfree(signature);
476
477 kex_derive_keys(kex, hash, shared_secret);
478 BN_clear_free(shared_secret);
479 packet_set_kex(kex);
480
481 /* save session id */
482 session_id2_len = 20;
483 session_id2 = xmalloc(session_id2_len);
484 memcpy(session_id2, hash, session_id2_len);
485} 128}
486 129
487/* 130/*
@@ -563,6 +206,7 @@ ssh_userauth2(const char *server_user, char *host)
563 Authctxt authctxt; 206 Authctxt authctxt;
564 int type; 207 int type;
565 int plen; 208 int plen;
209 int i;
566 210
567 if (options.challenge_reponse_authentication) 211 if (options.challenge_reponse_authentication)
568 options.kbd_interactive_authentication = 1; 212 options.kbd_interactive_authentication = 1;
@@ -603,7 +247,10 @@ ssh_userauth2(const char *server_user, char *host)
603 /* initial userauth request */ 247 /* initial userauth request */
604 userauth_none(&authctxt); 248 userauth_none(&authctxt);
605 249
606 dispatch_init(&input_userauth_error); 250 //dispatch_init(&input_userauth_error);
251 for (i = 50; i <= 254; i++) {
252 dispatch_set(i, &input_userauth_error);
253 }
607 dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); 254 dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
608 dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure); 255 dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
609 dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner); 256 dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);