Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <mp.h>
4
#include <libsec.h>
5
#include <fcall.h>
6
#include <thread.h>
7
#include <9p.h>
8
#include <auth.h>
9
#include <ip.h>
10
#include <pool.h>
11
#include "netssh.h"
12
 
13
#undef VERIFYKEYS		/* TODO until it's fixed */
14
 
15
enum {
16
	Errnokey = -2,	/* no key on keyring */
17
	Errnoverify,	/* factotum found a key, but verification failed */
18
	Errfactotum,	/* factotum failure (e.g., no key) */
19
	Errnone,	/* key verified */
20
};
21
 
22
static int dh_server(Conn *, Packet *, mpint *, int);
23
static void genkeys(Conn *, uchar [], mpint *);
24
 
25
/*
26
 * Second Oakley Group from RFC 2409
27
 */
28
static char *group1p =
29
         "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
30
         "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
31
         "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
32
         "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
33
         "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
34
         "FFFFFFFFFFFFFFFF";
35
 
36
/*
37
 * 2048-bit MODP group (id 14) from RFC 3526
38
*/
39
static char *group14p =
40
      "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
41
      "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
42
      "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
43
      "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
44
      "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
45
      "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
46
      "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
47
      "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
48
      "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
49
      "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
50
      "15728E5A8AACAA68FFFFFFFFFFFFFFFF";
51
 
52
mpint *two, *p1, *p14;
53
int nokeyverify;
54
 
55
static DSApriv mydsskey;
56
static RSApriv myrsakey;
57
 
58
void
59
dh_init(PKA *pkas[])
60
{
61
	char *buf, *p, *st, *end;
62
	int fd, n, k;
63
 
64
	if(debug > 1)
65
		sshdebug(nil, "dh_init");
66
	k = 0;
67
	pkas[k] = nil;
68
	fmtinstall('M', mpfmt);
69
	two = strtomp("2", nil, 10, nil);
70
	p1 = strtomp(group1p, nil, 16, nil);
71
	p14 = strtomp(group14p, nil, 16, nil);
72
 
73
	/*
74
	 * this really should be done through factotum
75
	 */
76
	p = getenv("rsakey");
77
	if (p != nil) {
78
		remove("/env/rsakey");
79
		st = buf = p;
80
		end = buf + strlen(p);
81
	} else {
82
		/*
83
		 * it would be better to use bio and rdline here instead of
84
		 * reading all of factotum's contents into memory at once.
85
		 */
86
		buf = emalloc9p(Maxfactotum);
87
		fd = open("rsakey", OREAD);
88
		if (fd < 0 && (fd = open("/mnt/factotum/ctl", OREAD)) < 0)
89
			goto norsa;
90
		n = readn(fd, buf, Maxfactotum - 1);
91
		buf[n >= 0? n: 0] = 0;
92
		close(fd);
93
		assert(n < Maxfactotum - 1);
94
 
95
		st = strstr(buf, "proto=rsa");
96
		if (st == nil) {
97
			sshlog(nil, "no proto=rsa key in factotum");
98
			goto norsa;
99
		}
100
		end = st;
101
		for (; st > buf && *st != '\n'; --st)
102
			;
103
		for (; end < buf + Maxfactotum && *end != '\n'; ++end)
104
			;
105
	}
106
	p = strstr(st, " n=");
107
	if (p == nil || p > end) {
108
		sshlog(nil, "no key (n) found");
109
		free(buf);
110
		return;
111
	}
112
	myrsakey.pub.n = strtomp(p+3, nil, 16, nil);
113
	if (debug > 1)
114
		sshdebug(nil, "n=%M", myrsakey.pub.n);
115
	p = strstr(st, " ek=");
116
	if (p == nil || p > end) {
117
		sshlog(nil, "no key (ek) found");
118
		free(buf);
119
		return;
120
	}
121
	pkas[k++] = &rsa_pka;
122
	pkas[k] = nil;
123
	myrsakey.pub.ek = strtomp(p+4, nil, 16, nil);
124
	if (debug > 1)
125
		sshdebug(nil, "ek=%M", myrsakey.pub.ek);
126
	p = strstr(st, " !dk=");
127
	if (p == nil) {
128
		p = strstr(st, "!dk?");
129
		if (p == nil || p > end) {
130
			// sshlog(nil, "no key (dk) found");
131
			free(buf);
132
			return;
133
		}
134
		goto norsa;
135
	}
136
	myrsakey.dk = strtomp(p+5, nil, 16, nil);
137
	if (debug > 1)
138
		sshdebug(nil, "dk=%M", myrsakey.dk);
139
norsa:
140
	free(buf);
141
 
142
	p = getenv("dsskey");
143
	if (p != nil) {
144
		remove("/env/dsskey");
145
		buf = p;
146
		end = buf + strlen(p);
147
	} else {
148
		/*
149
		 * it would be better to use bio and rdline here instead of
150
		 * reading all of factotum's contents into memory at once.
151
		 */
152
		buf = emalloc9p(Maxfactotum);
153
		fd = open("dsskey", OREAD);
154
		if (fd < 0 && (fd = open("/mnt/factotum/ctl", OREAD)) < 0)
155
			return;
156
		n = readn(fd, buf, Maxfactotum - 1);
157
		buf[n >= 0? n: 0] = 0;
158
		close(fd);
159
		assert(n < Maxfactotum - 1);
160
 
161
		st = strstr(buf, "proto=dsa");
162
		if (st == nil) {
163
			sshlog(nil, "no proto=dsa key in factotum");
164
			free(buf);
165
			return;
166
		}
167
		end = st;
168
		for (; st > buf && *st != '\n'; --st)
169
			;
170
		for (; end < buf + Maxfactotum && *end != '\n'; ++end)
171
			;
172
	}
173
	p = strstr(buf, " p=");
174
	if (p == nil || p > end) {
175
		sshlog(nil, "no key (p) found");
176
		free(buf);
177
		return;
178
	}
179
	mydsskey.pub.p = strtomp(p+3, nil, 16, nil);
180
	p = strstr(buf, " q=");
181
	if (p == nil || p > end) {
182
		sshlog(nil, "no key (q) found");
183
		free(buf);
184
		return;
185
	}
186
	mydsskey.pub.q = strtomp(p+3, nil, 16, nil);
187
	p = strstr(buf, " alpha=");
188
	if (p == nil || p > end) {
189
		sshlog(nil, "no key (g) found");
190
		free(buf);
191
		return;
192
	}
193
	mydsskey.pub.alpha = strtomp(p+7, nil, 16, nil);
194
	p = strstr(buf, " key=");
195
	if (p == nil || p > end) {
196
		sshlog(nil, "no key (y) found");
197
		free(buf);
198
		return;
199
	}
200
	mydsskey.pub.key = strtomp(p+5, nil, 16, nil);
201
	pkas[k++] = &dss_pka;
202
	pkas[k] = nil;
203
	p = strstr(buf, " !secret=");
204
	if (p == nil) {
205
		p = strstr(buf, "!secret?");
206
		if (p == nil || p > end)
207
			sshlog(nil, "no key (x) found");
208
		free(buf);
209
		return;
210
	}
211
	mydsskey.secret = strtomp(p+9, nil, 16, nil);
212
	free(buf);
213
}
214
 
215
static Packet *
216
rsa_ks(Conn *c)
217
{
218
	Packet *ks;
219
 
220
	if (myrsakey.pub.ek == nil || myrsakey.pub.n == nil) {
221
		sshlog(c, "no public RSA key info");
222
		return nil;
223
	}
224
	ks = new_packet(c);
225
	add_string(ks, "ssh-rsa");
226
	add_mp(ks, myrsakey.pub.ek);
227
	add_mp(ks, myrsakey.pub.n);
228
	return ks;
229
}
230
 
231
static void
232
esma_encode(uchar *h, uchar *em, int nb)
233
{
234
	int n, i;
235
	uchar hh[SHA1dlen];
236
	static uchar sha1der[] = {
237
		0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
238
		0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14,
239
	};
240
 
241
	sha1(h, SHA1dlen, hh, nil);
242
	n = nb - (nelem(sha1der) + SHA1dlen) - 3;
243
	i = 0;
244
	em[i++] = 0;
245
	em[i++] = 1;
246
	memset(em + i, 0xff, n);
247
	i += n;
248
	em[i++] = 0;
249
	memmove(em + i, sha1der, sizeof sha1der);
250
	i += sizeof sha1der;
251
	memmove(em + i, hh, SHA1dlen);
252
}
253
 
254
static Packet *
255
rsa_sign(Conn *c, uchar *m, int nm)
256
{
257
	AuthRpc *ar;
258
	Packet *sig;
259
	mpint *s, *mm;
260
	int fd, n, nbit;
261
	uchar hh[SHA1dlen];
262
	uchar *sstr, *em;
263
 
264
	if (myrsakey.dk) {
265
		nbit = mpsignif (myrsakey.pub.n);
266
		n = (nbit + 7) / 8;
267
		sstr = emalloc9p(n);
268
		em = emalloc9p(n);
269
		/* Compute s: RFC 3447 */
270
		esma_encode(m, em, n);
271
		mm = betomp(em, n, nil);
272
		s = mpnew(nbit);
273
		mpexp(mm, myrsakey.dk, myrsakey.pub.n, s);
274
		mptobe(s, sstr, n, nil);
275
		mpfree(mm);
276
		mpfree(s);
277
		free(em);
278
	} else {
279
		fd = open("/mnt/factotum/rpc", ORDWR);
280
		if (fd < 0)
281
			return nil;
282
		sha1(m, nm, hh, nil);
283
		ar = auth_allocrpc(fd);
284
		if (ar == nil ||
285
		    auth_rpc(ar, "start", "role=sign proto=rsa", 19) != ARok ||
286
		    auth_rpc(ar, "write", hh, SHA1dlen) != ARok ||
287
		    auth_rpc(ar, "read", nil, 0) != ARok ||
288
		    ar->arg == nil) {
289
			sshdebug(c, "got error in factotum: %r");
290
			auth_freerpc(ar);
291
			close(fd);
292
			return nil;
293
		}
294
		sstr = emalloc9p(ar->narg);
295
		memmove(sstr, ar->arg, ar->narg);
296
		n = ar->narg;
297
 
298
		auth_freerpc(ar);
299
		close(fd);
300
	}
301
	sig = new_packet(c);
302
	add_string(sig, pkas[c->pkalg]->name);
303
	add_block(sig, sstr, n);
304
	free(sstr);
305
	return sig;
306
}
307
 
308
/*
309
 * 0 - If factotum failed, e.g. no key
310
 * 1 - If key is verified
311
 * -1 - If factotum found a key, but the verification fails
312
 */
313
static int
314
rsa_verify(Conn *c, uchar *m, int nm, char *user, char *sig, int)
315
{
316
	int fd, n, retval, nbit;
317
	char *buf, *p, *sigblob;
318
	uchar *sstr, *em;
319
	uchar hh[SHA1dlen];
320
	mpint *s, *mm, *rsa_exponent, *host_modulus;
321
	AuthRpc *ar;
322
 
323
	sshdebug(c, "in rsa_verify for connection: %d", c->id);
324
	SET(rsa_exponent, host_modulus);
325
	USED(rsa_exponent, host_modulus);
326
	if (0 && rsa_exponent) {
327
		nbit = mpsignif(host_modulus);
328
		n = (nbit + 7) / 8;
329
		em = emalloc9p(n);
330
		/* Compute s: RFC 3447 */
331
		esma_encode(m, em, n);
332
		mm = betomp(em, n, nil);
333
		s = mpnew(1024);
334
		mpexp(mm, rsa_exponent, host_modulus, s);
335
		sstr = emalloc9p(n);
336
		mptobe(s, sstr, n, nil);
337
		free(em);
338
		mpfree(mm);
339
		mpfree(s);
340
		retval = memcmp(sig, sstr, n);
341
		free(sstr);
342
		retval = (retval == 0);
343
	} else {
344
		retval = 1;
345
		fd = open("/mnt/factotum/rpc", ORDWR);
346
		if (fd < 0) {
347
			sshdebug(c, "could not open factotum RPC: %r");
348
			return 0;
349
		}
350
		buf = emalloc9p(Blobsz / 2);
351
		sigblob = emalloc9p(Blobsz);
352
		p = (char *)get_string(nil, (uchar *)sig, buf, Blobsz / 2, nil);
353
		get_string(nil, (uchar *)p, sigblob, Blobsz, &n);
354
		sha1(m, nm, hh, nil);
355
		if (user != nil)
356
			p = smprint("role=verify proto=rsa user=%s", user);
357
		else
358
			p = smprint("role=verify proto=rsa sys=%s", c->remote);
359
 
360
		ar = auth_allocrpc(fd);
361
		if (ar == nil || auth_rpc(ar, "start", p, strlen(p)) != ARok ||
362
		    auth_rpc(ar, "write", hh, SHA1dlen) != ARok ||
363
		    auth_rpc(ar, "write", sigblob, n) != ARok ||
364
		    auth_rpc(ar, "read", nil, 0) != ARok) {
365
			sshdebug(c, "got error in factotum: %r");
366
			retval = 0;
367
		} else {
368
			sshdebug(c, "factotum returned %s", ar->ibuf);
369
			if (strstr(ar->ibuf, "does not verify") != nil)
370
				retval = -1;
371
		}
372
		if (ar != nil)
373
			auth_freerpc(ar);
374
		free(p);
375
		close(fd);
376
		free(sigblob);
377
		free(buf);
378
	}
379
	return retval;
380
}
381
 
382
static Packet *
383
dss_ks(Conn *c)
384
{
385
	Packet *ks;
386
 
387
	if (mydsskey.pub.p == nil)
388
		return nil;
389
	ks = new_packet(c);
390
	add_string(ks, "ssh-dss");
391
	add_mp(ks, mydsskey.pub.p);
392
	add_mp(ks, mydsskey.pub.q);
393
	add_mp(ks, mydsskey.pub.alpha);
394
	add_mp(ks, mydsskey.pub.key);
395
	return ks;
396
}
397
 
398
static Packet *
399
dss_sign(Conn *c, uchar *m, int nm)
400
{
401
	AuthRpc *ar;
402
	DSAsig *s;
403
	Packet *sig;
404
	mpint *mm;
405
	int fd;
406
	uchar sstr[2*SHA1dlen];
407
 
408
	sha1(m, nm, sstr, nil);
409
	sig = new_packet(c);
410
	add_string(sig, pkas[c->pkalg]->name);
411
	if (mydsskey.secret) {
412
		mm = betomp(sstr, SHA1dlen, nil);
413
		s = dsasign(&mydsskey, mm);
414
		mptobe(s->r, sstr, SHA1dlen, nil);
415
		mptobe(s->s, sstr+SHA1dlen, SHA1dlen, nil);
416
		dsasigfree(s);
417
		mpfree(mm);
418
	} else {
419
		fd = open("/mnt/factotum/rpc", ORDWR);
420
		if (fd < 0)
421
			return nil;
422
		ar = auth_allocrpc(fd);
423
		if (ar == nil ||
424
		    auth_rpc(ar, "start", "role=sign proto=dsa", 19) != ARok ||
425
		    auth_rpc(ar, "write", sstr, SHA1dlen) != ARok ||
426
		    auth_rpc(ar, "read", nil, 0) != ARok) {
427
			sshdebug(c, "got error in factotum: %r");
428
			auth_freerpc(ar);
429
			close(fd);
430
			return nil;
431
		}
432
		memmove(sstr, ar->arg, ar->narg);
433
		auth_freerpc(ar);
434
		close(fd);
435
	}
436
	add_block(sig, sstr, 2*SHA1dlen);
437
	return sig;
438
}
439
 
440
static int
441
dss_verify(Conn *c, uchar *m, int nm, char *user, char *sig, int nsig)
442
{
443
	sshdebug(c, "in dss_verify for connection: %d", c->id);
444
	USED(m, nm, user, sig, nsig);
445
	return 0;
446
}
447
 
448
static int
449
dh_server1(Conn *c, Packet *pack1)
450
{
451
	return dh_server(c, pack1, p1, 1024);
452
}
453
 
454
static int
455
dh_server14(Conn *c, Packet *pack1)
456
{
457
	return dh_server(c, pack1, p14, 2048);
458
}
459
 
460
static int
461
dh_server(Conn *c, Packet *pack1, mpint *grp, int nbit)
462
{
463
	Packet *pack2, *ks, *sig;
464
	mpint *y, *e, *f, *k;
465
	int n, ret;
466
	uchar h[SHA1dlen];
467
 
468
	ret = -1;
469
	qlock(&c->l);
470
	f = mpnew(nbit);
471
	k = mpnew(nbit);
472
 
473
	/* Compute f: RFC4253 */
474
	y = mprand(nbit / 8, genrandom, nil);
475
	if (debug > 1)
476
		sshdebug(c, "y=%M", y);
477
	mpexp(two, y, grp, f);
478
	if (debug > 1)
479
		sshdebug(c, "f=%M", f);
480
 
481
	/* Compute k: RFC4253 */
482
	if (debug > 1)
483
		dump_packet(pack1);
484
	e = get_mp(pack1->payload+1);
485
	if (debug > 1)
486
		sshdebug(c, "e=%M", e);
487
	mpexp(e, y, grp, k);
488
	if (debug > 1)
489
		sshdebug(c, "k=%M", k);
490
 
491
	/* Compute H: RFC 4253 */
492
	pack2 = new_packet(c);
493
	sshdebug(c, "ID strings: %s---%s", c->otherid, MYID);
494
	add_string(pack2, c->otherid);
495
	add_string(pack2, MYID);
496
	if (debug > 1) {
497
		fprint(2, "received kexinit:");
498
		dump_packet(c->rkexinit);
499
		fprint(2, "\nsent kexinit:");
500
		dump_packet(c->skexinit);
501
	}
502
	add_block(pack2, c->rkexinit->payload, c->rkexinit->rlength - 1);
503
	add_block(pack2, c->skexinit->payload,
504
		c->skexinit->rlength - c->skexinit->pad_len - 1);
505
	sig = nil;
506
	ks = pkas[c->pkalg]->ks(c);
507
	if (ks == nil)
508
		goto err;
509
	add_block(pack2, ks->payload, ks->rlength - 1);
510
	add_mp(pack2, e);
511
	add_mp(pack2, f);
512
	add_mp(pack2, k);
513
	sha1(pack2->payload, pack2->rlength - 1, h, nil);
514
 
515
	if (c->got_sessid == 0) {
516
		memmove(c->sessid, h, SHA1dlen);
517
		c->got_sessid = 1;
518
	}
519
	sig = pkas[c->pkalg]->sign(c, h, SHA1dlen);
520
	if (sig == nil) {
521
		sshlog(c, "failed to generate signature: %r");
522
		goto err;
523
	}
524
 
525
	/* Send (K_s || f || s) to client: RFC4253 */
526
	init_packet(pack2);
527
	pack2->c = c;
528
	add_byte(pack2, SSH_MSG_KEXDH_REPLY);
529
	add_block(pack2, ks->payload, ks->rlength - 1);
530
	add_mp(pack2, f);
531
	add_block(pack2, sig->payload, sig->rlength - 1);
532
	if (debug > 1)
533
		dump_packet(pack2);
534
	n = finish_packet(pack2);
535
	if (debug > 1) {
536
		sshdebug(c, "writing %d bytes: len %d", n, nhgetl(pack2->nlength));
537
		dump_packet(pack2);
538
	}
539
	iowrite(c->dio, c->datafd, pack2->nlength, n);
540
 
541
	genkeys(c, h, k);
542
 
543
	/* Send SSH_MSG_NEWKEYS */
544
	init_packet(pack2);
545
	pack2->c = c;
546
	add_byte(pack2, SSH_MSG_NEWKEYS);
547
	n = finish_packet(pack2);
548
	iowrite(c->dio, c->datafd, pack2->nlength, n);
549
	ret = 0;
550
err:
551
	mpfree(f);
552
	mpfree(e);
553
	mpfree(k);
554
	mpfree(y);
555
	free(sig);
556
	free(ks);
557
	free(pack2);
558
	qunlock(&c->l);
559
	return ret;
560
}
561
 
562
static int
563
dh_client11(Conn *c, Packet *)
564
{
565
	Packet *p;
566
	int n;
567
 
568
	if (c->e)
569
		mpfree(c->e);
570
	c->e = mpnew(1024);
571
 
572
	/* Compute e: RFC4253 */
573
	if (c->x)
574
		mpfree(c->x);
575
	c->x = mprand(128, genrandom, nil);
576
	mpexp(two, c->x, p1, c->e);
577
 
578
	p = new_packet(c);
579
	add_byte(p, SSH_MSG_KEXDH_INIT);
580
	add_mp(p, c->e);
581
	n = finish_packet(p);
582
	iowrite(c->dio, c->datafd, p->nlength, n);
583
	free(p);
584
	return 0;
585
}
586
 
587
static int
588
findkeyinuserring(Conn *c, RSApub *srvkey)
589
{
590
	int n;
591
	char *home, *newkey, *r;
592
 
593
	home = getenv("home");
594
	if (home == nil) {
595
		newkey = "No home directory for key file";
596
		free(keymbox.msg);
597
		keymbox.msg = smprint("b%04ld%s", strlen(newkey), newkey);
598
		return -1;
599
	}
600
 
601
	r = smprint("%s/lib/keyring", home);
602
	free(home);
603
	if ((n = findkey(r, c->remote, srvkey)) != KeyOk) {
604
		newkey = smprint("ek=%M n=%M", srvkey->ek, srvkey->n);
605
		free(keymbox.msg);
606
		keymbox.msg = smprint("%c%04ld%s", n == NoKeyFile || n == NoKey?
607
			'c': 'b', strlen(newkey), newkey);
608
		free(newkey);
609
 
610
		nbsendul(keymbox.mchan, 1);
611
		recvul(keymbox.mchan);
612
		if (keymbox.msg == nil || keymbox.msg[0] == 'n') {
613
			free(keymbox.msg);
614
			keymbox.msg = nil;
615
			newkey = "Server key reject";
616
			keymbox.msg = smprint("f%04ld%s", strlen(newkey), newkey);
617
			return -1;
618
		}
619
		sshdebug(c, "adding key");
620
		if (keymbox.msg[0] == 'y')
621
			appendkey(r, c->remote, srvkey);
622
		else if (keymbox.msg[0] == 'r')
623
			replacekey(r, c->remote, srvkey);
624
	}
625
	free(r);
626
	return 0;
627
}
628
 
629
static int
630
verifyhostkey(Conn *c, RSApub *srvkey, Packet *sig)
631
{
632
	int fd, n;
633
	char *newkey;
634
	uchar h[SHA1dlen];
635
 
636
	sshdebug(c, "verifying server signature");
637
	if (findkey("/sys/lib/ssh/keyring", c->remote, srvkey) != KeyOk &&
638
	    findkeyinuserring(c, srvkey) < 0) {
639
		nbsendul(keymbox.mchan, 1);
640
		mpfree(srvkey->ek);
641
		mpfree(srvkey->n);
642
		return Errnokey;
643
	}
644
 
645
	newkey = smprint("key proto=rsa role=verify sys=%s size=%d ek=%M n=%M",
646
		c->remote, mpsignif(srvkey->n), srvkey->ek, srvkey->n);
647
	if (newkey == nil) {
648
		sshlog(c, "out of memory");
649
		threadexits("out of memory");
650
	}
651
 
652
	fd = open("/mnt/factotum/ctl", OWRITE);
653
	if (fd >= 0)
654
		write(fd, newkey, strlen(newkey));
655
		/* leave fd open */
656
	else
657
		sshdebug(c, "factotum open failed: %r");
658
 
659
	free(newkey);
660
	mpfree(srvkey->ek);
661
	mpfree(srvkey->n);
662
	free(keymbox.msg);
663
	keymbox.msg = nil;
664
 
665
	n = pkas[c->pkalg]->verify(c, h, SHA1dlen, nil, (char *)sig->payload,
666
		sig->rlength);
667
 
668
	/* fd is perhaps still open */
669
	if (fd >= 0) {
670
		/* sys here is a dotted-quad ip address */
671
		newkey = smprint("delkey proto=rsa role=verify sys=%s",
672
			c->remote);
673
		if (newkey) {
674
			seek(fd, 0, 0);
675
			write(fd, newkey, strlen(newkey));
676
			free(newkey);
677
		}
678
		close(fd);
679
	}
680
	return n;
681
}
682
 
683
static int
684
dh_client12(Conn *c, Packet *p)
685
{
686
	int n, retval;
687
#ifdef VERIFYKEYS
688
	char *newkey;
689
#endif
690
	char buf[10];
691
	uchar *q;
692
	uchar h[SHA1dlen];
693
	mpint *f, *k;
694
	Packet *ks, *sig, *pack2;
695
	RSApub *srvkey;
696
 
697
	ks = new_packet(c);
698
	sig = new_packet(c);
699
	pack2 = new_packet(c);
700
 
701
	q = get_string(p, p->payload+1, (char *)ks->payload, Maxpktpay, &n);
702
	ks->rlength = n + 1;
703
	f = get_mp(q);
704
	q += nhgetl(q) + 4;
705
	get_string(p, q, (char *)sig->payload, Maxpktpay, &n);
706
	sig->rlength = n;
707
	k = mpnew(1024);
708
	mpexp(f, c->x, p1, k);
709
 
710
	/* Compute H: RFC 4253 */
711
	init_packet(pack2);
712
	pack2->c = c;
713
	if (debug > 1)
714
		sshdebug(c, "ID strings: %s---%s", c->otherid, MYID);
715
	add_string(pack2, MYID);
716
	add_string(pack2, c->otherid);
717
	if (debug > 1) {
718
		fprint(2, "received kexinit:");
719
		dump_packet(c->rkexinit);
720
		fprint(2, "\nsent kexinit:");
721
		dump_packet(c->skexinit);
722
	}
723
	add_block(pack2, c->skexinit->payload,
724
		c->skexinit->rlength - c->skexinit->pad_len - 1);
725
	add_block(pack2, c->rkexinit->payload, c->rkexinit->rlength - 1);
726
	add_block(pack2, ks->payload, ks->rlength - 1);
727
	add_mp(pack2, c->e);
728
	add_mp(pack2, f);
729
	add_mp(pack2, k);
730
	sha1(pack2->payload, pack2->rlength - 1, h, nil);
731
	mpfree(f);
732
 
733
	if (c->got_sessid == 0) {
734
		memmove(c->sessid, h, SHA1dlen);
735
		c->got_sessid = 1;
736
	}
737
 
738
	q = get_string(ks, ks->payload, buf, sizeof buf, nil);
739
	srvkey = emalloc9p(sizeof (RSApub));
740
	srvkey->ek = get_mp(q);
741
	q += nhgetl(q) + 4;
742
	srvkey->n = get_mp(q);
743
 
744
	/*
745
	 * key verification is really pretty pedantic and
746
	 * not doing it lets us talk to ssh v1 implementations.
747
	 */
748
	if (nokeyverify)
749
		n = Errnone;
750
	else
751
		n = verifyhostkey(c, srvkey, sig);
752
	retval = -1;
753
	USED(retval);
754
	switch (n) {
755
#ifdef VERIFYKEYS
756
	case Errnokey:
757
		goto out;
758
	case Errnoverify:
759
		newkey = "signature verification failed; try netssh -v";
760
		keymbox.msg = smprint("f%04ld%s", strlen(newkey), newkey);
761
		break;
762
	case Errfactotum:
763
		newkey = "factotum dialogue failed; try netssh -v";
764
		keymbox.msg = smprint("f%04ld%s", strlen(newkey), newkey);
765
		break;
766
	case Errnone:
767
#else
768
	default:
769
#endif
770
		keymbox.msg = smprint("o0000");
771
		retval = 0;
772
		break;
773
	}
774
	nbsendul(keymbox.mchan, 1);
775
	if (retval == 0)
776
		genkeys(c, h, k);
777
#ifdef VERIFYKEYS
778
out:
779
#endif
780
	mpfree(k);
781
	free(ks);
782
	free(sig);
783
	free(pack2);
784
	free(srvkey);
785
	return retval;
786
}
787
 
788
static int
789
dh_client141(Conn *c, Packet *)
790
{
791
	Packet *p;
792
	mpint *e, *x;
793
	int n;
794
 
795
	/* Compute e: RFC4253 */
796
	e = mpnew(2048);
797
	x = mprand(256, genrandom, nil);
798
	mpexp(two, x, p14, e);
799
	p = new_packet(c);
800
	add_byte(p, SSH_MSG_KEXDH_INIT);
801
	add_mp(p, e);
802
	n = finish_packet(p);
803
	iowrite(c->dio, c->datafd, p->nlength, n);
804
	free(p);
805
	mpfree(e);
806
	mpfree(x);
807
	return 0;
808
}
809
 
810
static int
811
dh_client142(Conn *, Packet *)
812
{
813
	return 0;
814
}
815
 
816
static void
817
initsha1pkt(Packet *pack2, mpint *k, uchar *h)
818
{
819
	init_packet(pack2);
820
	add_mp(pack2, k);
821
	add_packet(pack2, h, SHA1dlen);
822
}
823
 
824
static void
825
genkeys(Conn *c, uchar h[], mpint *k)
826
{
827
	Packet *pack2;
828
	char buf[82], *bp, *be;			/* magic 82 */
829
	int n;
830
 
831
	pack2 = new_packet(c);
832
	/* Compute 40 bytes (320 bits) of keys: each alg can use what it needs */
833
 
834
	/* Client to server IV */
835
	if (debug > 1) {
836
		fprint(2, "k=%M\nh=", k);
837
		for (n = 0; n < SHA1dlen; ++n)
838
			fprint(2, "%02ux", h[n]);
839
		fprint(2, "\nsessid=");
840
		for (n = 0; n < SHA1dlen; ++n)
841
			fprint(2, "%02ux", c->sessid[n]);
842
		fprint(2, "\n");
843
	}
844
	initsha1pkt(pack2, k, h);
845
	add_byte(pack2, 'A');
846
	add_packet(pack2, c->sessid, SHA1dlen);
847
	sha1(pack2->payload, pack2->rlength - 1, c->nc2siv, nil);
848
	initsha1pkt(pack2, k, h);
849
	add_packet(pack2, c->nc2siv, SHA1dlen);
850
	sha1(pack2->payload, pack2->rlength - 1, c->nc2siv + SHA1dlen, nil);
851
 
852
	/* Server to client IV */
853
	initsha1pkt(pack2, k, h);
854
	add_byte(pack2, 'B');
855
	add_packet(pack2, c->sessid, SHA1dlen);
856
	sha1(pack2->payload, pack2->rlength - 1, c->ns2civ, nil);
857
	initsha1pkt(pack2, k, h);
858
	add_packet(pack2, c->ns2civ, SHA1dlen);
859
	sha1(pack2->payload, pack2->rlength - 1, c->ns2civ + SHA1dlen, nil);
860
 
861
	/* Client to server encryption key */
862
	initsha1pkt(pack2, k, h);
863
	add_byte(pack2, 'C');
864
	add_packet(pack2, c->sessid, SHA1dlen);
865
	sha1(pack2->payload, pack2->rlength - 1, c->nc2sek, nil);
866
	initsha1pkt(pack2, k, h);
867
	add_packet(pack2, c->nc2sek, SHA1dlen);
868
	sha1(pack2->payload, pack2->rlength - 1, c->nc2sek + SHA1dlen, nil);
869
 
870
	/* Server to client encryption key */
871
	initsha1pkt(pack2, k, h);
872
	add_byte(pack2, 'D');
873
	add_packet(pack2, c->sessid, SHA1dlen);
874
	sha1(pack2->payload, pack2->rlength - 1, c->ns2cek, nil);
875
	initsha1pkt(pack2, k, h);
876
	add_packet(pack2, c->ns2cek, SHA1dlen);
877
	sha1(pack2->payload, pack2->rlength - 1, c->ns2cek + SHA1dlen, nil);
878
 
879
	/* Client to server integrity key */
880
	initsha1pkt(pack2, k, h);
881
	add_byte(pack2, 'E');
882
	add_packet(pack2, c->sessid, SHA1dlen);
883
	sha1(pack2->payload, pack2->rlength - 1, c->nc2sik, nil);
884
	initsha1pkt(pack2, k, h);
885
	add_packet(pack2, c->nc2sik, SHA1dlen);
886
	sha1(pack2->payload, pack2->rlength - 1, c->nc2sik + SHA1dlen, nil);
887
 
888
	/* Server to client integrity key */
889
	initsha1pkt(pack2, k, h);
890
	add_byte(pack2, 'F');
891
	add_packet(pack2, c->sessid, SHA1dlen);
892
	sha1(pack2->payload, pack2->rlength - 1, c->ns2cik, nil);
893
	initsha1pkt(pack2, k, h);
894
	add_packet(pack2, c->ns2cik, SHA1dlen);
895
	sha1(pack2->payload, pack2->rlength - 1, c->ns2cik + SHA1dlen, nil);
896
 
897
	if (debug > 1) {
898
		be = buf + sizeof buf;
899
		fprint(2, "Client to server IV:\n");
900
		for (n = 0, bp = buf; n < SHA1dlen*2; ++n)
901
			bp = seprint(bp, be, "%02x", c->nc2siv[n]);
902
		fprint(2, "%s\n", buf);
903
 
904
		fprint(2, "Server to client IV:\n");
905
		for (n = 0, bp = buf; n < SHA1dlen*2; ++n)
906
			bp = seprint(bp, be, "%02x", c->ns2civ[n]);
907
		fprint(2, "%s\n", buf);
908
 
909
		fprint(2, "Client to server EK:\n");
910
		for (n = 0, bp = buf; n < SHA1dlen*2; ++n)
911
			bp = seprint(bp, be, "%02x", c->nc2sek[n]);
912
		fprint(2, "%s\n", buf);
913
 
914
		fprint(2, "Server to client EK:\n");
915
		for (n = 0, bp = buf; n < SHA1dlen*2; ++n)
916
			bp = seprint(bp, be, "%02x", c->ns2cek[n]);
917
		fprint(2, "%s\n", buf);
918
	}
919
	free(pack2);
920
}
921
 
922
Kex dh1sha1 = {
923
	"diffie-hellman-group1-sha1",
924
	dh_server1,
925
	dh_client11,
926
	dh_client12
927
};
928
 
929
Kex dh14sha1 = {
930
	"diffie-hellman-group14-sha1",
931
	dh_server14,
932
	dh_client141,
933
	dh_client142
934
};
935
 
936
PKA rsa_pka = {
937
	"ssh-rsa",
938
	rsa_ks,
939
	rsa_sign,
940
	rsa_verify
941
};
942
 
943
PKA dss_pka = {
944
	"ssh-dss",
945
	dss_ks,
946
	dss_sign,
947
	dss_verify
948
};