key.c revision 137019
1178479Sjb/*
2178479Sjb * read_bignum():
3178479Sjb * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4178479Sjb *
5178479Sjb * As far as I am concerned, the code I have written for this software
6178479Sjb * can be used freely for any purpose.  Any derived versions of this
7178479Sjb * software must be clearly marked as such, and if the derived work is
8178479Sjb * incompatible with the protocol description in the RFC file, it must be
9178479Sjb * called by a name other than "ssh" or "Secure Shell".
10178479Sjb *
11178479Sjb *
12178479Sjb * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
13178479Sjb *
14178479Sjb * Redistribution and use in source and binary forms, with or without
15178479Sjb * modification, are permitted provided that the following conditions
16178479Sjb * are met:
17178479Sjb * 1. Redistributions of source code must retain the above copyright
18178479Sjb *    notice, this list of conditions and the following disclaimer.
19178479Sjb * 2. Redistributions in binary form must reproduce the above copyright
20178479Sjb *    notice, this list of conditions and the following disclaimer in the
21178479Sjb *    documentation and/or other materials provided with the distribution.
22178479Sjb *
23178479Sjb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24178479Sjb * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25178479Sjb * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26178479Sjb * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27250574Smarkj * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28268578Srpaulo * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29250574Smarkj * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30250574Smarkj * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31250574Smarkj * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32178479Sjb * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33178479Sjb */
34178479Sjb#include "includes.h"
35178479SjbRCSID("$OpenBSD: key.c,v 1.56 2004/07/28 09:40:29 markus Exp $");
36178479Sjb
37178479Sjb#include <openssl/evp.h>
38178479Sjb
39178479Sjb#include "xmalloc.h"
40178479Sjb#include "key.h"
41297077Smav#include "rsa.h"
42178479Sjb#include "uuencode.h"
43178569Sjb#include "buffer.h"
44178479Sjb#include "bufaux.h"
45178479Sjb#include "log.h"
46178479Sjb
47178479SjbKey *
48178479Sjbkey_new(int type)
49178479Sjb{
50178479Sjb	Key *k;
51178479Sjb	RSA *rsa;
52178479Sjb	DSA *dsa;
53178479Sjb	k = xmalloc(sizeof(*k));
54178479Sjb	k->type = type;
55178479Sjb	k->flags = 0;
56178479Sjb	k->dsa = NULL;
57178479Sjb	k->rsa = NULL;
58178479Sjb	switch (k->type) {
59178479Sjb	case KEY_RSA1:
60178479Sjb	case KEY_RSA:
61178479Sjb		if ((rsa = RSA_new()) == NULL)
62178479Sjb			fatal("key_new: RSA_new failed");
63178479Sjb		if ((rsa->n = BN_new()) == NULL)
64178479Sjb			fatal("key_new: BN_new failed");
65178479Sjb		if ((rsa->e = BN_new()) == NULL)
66178479Sjb			fatal("key_new: BN_new failed");
67178479Sjb		k->rsa = rsa;
68178479Sjb		break;
69178479Sjb	case KEY_DSA:
70178479Sjb		if ((dsa = DSA_new()) == NULL)
71178479Sjb			fatal("key_new: DSA_new failed");
72178479Sjb		if ((dsa->p = BN_new()) == NULL)
73178479Sjb			fatal("key_new: BN_new failed");
74178479Sjb		if ((dsa->q = BN_new()) == NULL)
75178479Sjb			fatal("key_new: BN_new failed");
76178479Sjb		if ((dsa->g = BN_new()) == NULL)
77178479Sjb			fatal("key_new: BN_new failed");
78178479Sjb		if ((dsa->pub_key = BN_new()) == NULL)
79178479Sjb			fatal("key_new: BN_new failed");
80178479Sjb		k->dsa = dsa;
81178479Sjb		break;
82178479Sjb	case KEY_UNSPEC:
83178479Sjb		break;
84178479Sjb	default:
85178479Sjb		fatal("key_new: bad key type %d", k->type);
86178479Sjb		break;
87178479Sjb	}
88178479Sjb	return k;
89178479Sjb}
90178479Sjb
91178479SjbKey *
92178479Sjbkey_new_private(int type)
93178479Sjb{
94178479Sjb	Key *k = key_new(type);
95178479Sjb	switch (k->type) {
96178479Sjb	case KEY_RSA1:
97178479Sjb	case KEY_RSA:
98178479Sjb		if ((k->rsa->d = BN_new()) == NULL)
99178479Sjb			fatal("key_new_private: BN_new failed");
100178479Sjb		if ((k->rsa->iqmp = BN_new()) == NULL)
101178479Sjb			fatal("key_new_private: BN_new failed");
102178479Sjb		if ((k->rsa->q = BN_new()) == NULL)
103178479Sjb			fatal("key_new_private: BN_new failed");
104178479Sjb		if ((k->rsa->p = BN_new()) == NULL)
105178479Sjb			fatal("key_new_private: BN_new failed");
106178479Sjb		if ((k->rsa->dmq1 = BN_new()) == NULL)
107178479Sjb			fatal("key_new_private: BN_new failed");
108178479Sjb		if ((k->rsa->dmp1 = BN_new()) == NULL)
109178479Sjb			fatal("key_new_private: BN_new failed");
110178479Sjb		break;
111178479Sjb	case KEY_DSA:
112178479Sjb		if ((k->dsa->priv_key = BN_new()) == NULL)
113178479Sjb			fatal("key_new_private: BN_new failed");
114178479Sjb		break;
115178479Sjb	case KEY_UNSPEC:
116178479Sjb		break;
117178479Sjb	default:
118178479Sjb		break;
119178479Sjb	}
120178479Sjb	return k;
121178479Sjb}
122178479Sjb
123178479Sjbvoid
124178479Sjbkey_free(Key *k)
125178479Sjb{
126178479Sjb	switch (k->type) {
127178479Sjb	case KEY_RSA1:
128178479Sjb	case KEY_RSA:
129178479Sjb		if (k->rsa != NULL)
130178479Sjb			RSA_free(k->rsa);
131178479Sjb		k->rsa = NULL;
132178479Sjb		break;
133178479Sjb	case KEY_DSA:
134178479Sjb		if (k->dsa != NULL)
135178479Sjb			DSA_free(k->dsa);
136178479Sjb		k->dsa = NULL;
137178479Sjb		break;
138178479Sjb	case KEY_UNSPEC:
139178479Sjb		break;
140178479Sjb	default:
141178479Sjb		fatal("key_free: bad key type %d", k->type);
142178479Sjb		break;
143178479Sjb	}
144178479Sjb	xfree(k);
145178479Sjb}
146178479Sjb
147178479Sjbint
148178479Sjbkey_equal(const Key *a, const Key *b)
149178479Sjb{
150178479Sjb	if (a == NULL || b == NULL || a->type != b->type)
151178479Sjb		return 0;
152178479Sjb	switch (a->type) {
153178479Sjb	case KEY_RSA1:
154178479Sjb	case KEY_RSA:
155178479Sjb		return a->rsa != NULL && b->rsa != NULL &&
156178479Sjb		    BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
157178479Sjb		    BN_cmp(a->rsa->n, b->rsa->n) == 0;
158178479Sjb		break;
159178479Sjb	case KEY_DSA:
160178479Sjb		return a->dsa != NULL && b->dsa != NULL &&
161178479Sjb		    BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
162178479Sjb		    BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
163178479Sjb		    BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
164178479Sjb		    BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
165178479Sjb		break;
166178479Sjb	default:
167178479Sjb		fatal("key_equal: bad key type %d", a->type);
168178479Sjb		break;
169178479Sjb	}
170178479Sjb	return 0;
171178479Sjb}
172178479Sjb
173178479Sjbu_char*
174178479Sjbkey_fingerprint_raw(const Key *k, enum fp_type dgst_type,
175178479Sjb    u_int *dgst_raw_length)
176178479Sjb{
177178479Sjb	const EVP_MD *md = NULL;
178178479Sjb	EVP_MD_CTX ctx;
179178479Sjb	u_char *blob = NULL;
180178479Sjb	u_char *retval = NULL;
181178479Sjb	u_int len = 0;
182178479Sjb	int nlen, elen;
183178479Sjb
184178479Sjb	*dgst_raw_length = 0;
185178479Sjb
186178479Sjb	switch (dgst_type) {
187178479Sjb	case SSH_FP_MD5:
188178479Sjb		md = EVP_md5();
189178479Sjb		break;
190178479Sjb	case SSH_FP_SHA1:
191178479Sjb		md = EVP_sha1();
192178479Sjb		break;
193178479Sjb	default:
194178479Sjb		fatal("key_fingerprint_raw: bad digest type %d",
195178479Sjb		    dgst_type);
196178479Sjb	}
197178479Sjb	switch (k->type) {
198178479Sjb	case KEY_RSA1:
199178479Sjb		nlen = BN_num_bytes(k->rsa->n);
200178479Sjb		elen = BN_num_bytes(k->rsa->e);
201178479Sjb		len = nlen + elen;
202178479Sjb		blob = xmalloc(len);
203178479Sjb		BN_bn2bin(k->rsa->n, blob);
204178479Sjb		BN_bn2bin(k->rsa->e, blob + nlen);
205178479Sjb		break;
206178479Sjb	case KEY_DSA:
207178479Sjb	case KEY_RSA:
208178479Sjb		key_to_blob(k, &blob, &len);
209178479Sjb		break;
210178479Sjb	case KEY_UNSPEC:
211178479Sjb		return retval;
212178479Sjb		break;
213178479Sjb	default:
214178479Sjb		fatal("key_fingerprint_raw: bad key type %d", k->type);
215178479Sjb		break;
216178479Sjb	}
217178479Sjb	if (blob != NULL) {
218178479Sjb		retval = xmalloc(EVP_MAX_MD_SIZE);
219178479Sjb		EVP_DigestInit(&ctx, md);
220178479Sjb		EVP_DigestUpdate(&ctx, blob, len);
221178479Sjb		EVP_DigestFinal(&ctx, retval, dgst_raw_length);
222178479Sjb		memset(blob, 0, len);
223178479Sjb		xfree(blob);
224178479Sjb	} else {
225178479Sjb		fatal("key_fingerprint_raw: blob is null");
226178479Sjb	}
227178479Sjb	return retval;
228178479Sjb}
229178479Sjb
230178479Sjbstatic char *
231178479Sjbkey_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len)
232178479Sjb{
233178479Sjb	char *retval;
234178479Sjb	int i;
235178479Sjb
236178479Sjb	retval = xmalloc(dgst_raw_len * 3 + 1);
237178479Sjb	retval[0] = '\0';
238178479Sjb	for (i = 0; i < dgst_raw_len; i++) {
239178479Sjb		char hex[4];
240178479Sjb		snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
241178479Sjb		strlcat(retval, hex, dgst_raw_len * 3 + 1);
242178479Sjb	}
243178479Sjb
244178479Sjb	/* Remove the trailing ':' character */
245178479Sjb	retval[(dgst_raw_len * 3) - 1] = '\0';
246178479Sjb	return retval;
247178479Sjb}
248178479Sjb
249178479Sjbstatic char *
250178479Sjbkey_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len)
251178479Sjb{
252178479Sjb	char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
253178479Sjb	char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
254178479Sjb	    'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
255178479Sjb	u_int i, j = 0, rounds, seed = 1;
256178479Sjb	char *retval;
257178479Sjb
258178479Sjb	rounds = (dgst_raw_len / 2) + 1;
259178479Sjb	retval = xmalloc(sizeof(char) * (rounds*6));
260178479Sjb	retval[j++] = 'x';
261178479Sjb	for (i = 0; i < rounds; i++) {
262178479Sjb		u_int idx0, idx1, idx2, idx3, idx4;
263178479Sjb		if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
264178479Sjb			idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) +
265178479Sjb			    seed) % 6;
266178479Sjb			idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15;
267178479Sjb			idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) +
268178479Sjb			    (seed / 6)) % 6;
269178479Sjb			retval[j++] = vowels[idx0];
270178479Sjb			retval[j++] = consonants[idx1];
271178479Sjb			retval[j++] = vowels[idx2];
272178479Sjb			if ((i + 1) < rounds) {
273178479Sjb				idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;
274178479Sjb				idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15;
275178479Sjb				retval[j++] = consonants[idx3];
276178479Sjb				retval[j++] = '-';
277178479Sjb				retval[j++] = consonants[idx4];
278178479Sjb				seed = ((seed * 5) +
279178479Sjb				    ((((u_int)(dgst_raw[2 * i])) * 7) +
280178479Sjb				    ((u_int)(dgst_raw[(2 * i) + 1])))) % 36;
281178479Sjb			}
282178479Sjb		} else {
283178479Sjb			idx0 = seed % 6;
284178479Sjb			idx1 = 16;
285178479Sjb			idx2 = seed / 6;
286178479Sjb			retval[j++] = vowels[idx0];
287178479Sjb			retval[j++] = consonants[idx1];
288178479Sjb			retval[j++] = vowels[idx2];
289178479Sjb		}
290178479Sjb	}
291178479Sjb	retval[j++] = 'x';
292178479Sjb	retval[j++] = '\0';
293178479Sjb	return retval;
294178479Sjb}
295178479Sjb
296178479Sjbchar *
297178479Sjbkey_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
298178479Sjb{
299178479Sjb	char *retval = NULL;
300178479Sjb	u_char *dgst_raw;
301178479Sjb	u_int dgst_raw_len;
302178479Sjb
303178479Sjb	dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len);
304178479Sjb	if (!dgst_raw)
305178479Sjb		fatal("key_fingerprint: null from key_fingerprint_raw()");
306178479Sjb	switch (dgst_rep) {
307178479Sjb	case SSH_FP_HEX:
308178479Sjb		retval = key_fingerprint_hex(dgst_raw, dgst_raw_len);
309178479Sjb		break;
310178479Sjb	case SSH_FP_BUBBLEBABBLE:
311178479Sjb		retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
312178479Sjb		break;
313178479Sjb	default:
314178479Sjb		fatal("key_fingerprint_ex: bad digest representation %d",
315178479Sjb		    dgst_rep);
316178479Sjb		break;
317178479Sjb	}
318178479Sjb	memset(dgst_raw, 0, dgst_raw_len);
319178479Sjb	xfree(dgst_raw);
320178479Sjb	return retval;
321178479Sjb}
322178479Sjb
323178479Sjb/*
324178479Sjb * Reads a multiple-precision integer in decimal from the buffer, and advances
325178479Sjb * the pointer.  The integer must already be initialized.  This function is
326178479Sjb * permitted to modify the buffer.  This leaves *cpp to point just beyond the
327178479Sjb * last processed (and maybe modified) character.  Note that this may modify
328178479Sjb * the buffer containing the number.
329178479Sjb */
330178479Sjbstatic int
331178479Sjbread_bignum(char **cpp, BIGNUM * value)
332178479Sjb{
333178479Sjb	char *cp = *cpp;
334178479Sjb	int old;
335178479Sjb
336178479Sjb	/* Skip any leading whitespace. */
337178479Sjb	for (; *cp == ' ' || *cp == '\t'; cp++)
338178479Sjb		;
339178479Sjb
340178479Sjb	/* Check that it begins with a decimal digit. */
341178479Sjb	if (*cp < '0' || *cp > '9')
342268578Srpaulo		return 0;
343268578Srpaulo
344268578Srpaulo	/* Save starting position. */
345268578Srpaulo	*cpp = cp;
346268578Srpaulo
347268578Srpaulo	/* Move forward until all decimal digits skipped. */
348268578Srpaulo	for (; *cp >= '0' && *cp <= '9'; cp++)
349268578Srpaulo		;
350268578Srpaulo
351268578Srpaulo	/* Save the old terminating character, and replace it by \0. */
352268578Srpaulo	old = *cp;
353268578Srpaulo	*cp = 0;
354268578Srpaulo
355268578Srpaulo	/* Parse the number. */
356268578Srpaulo	if (BN_dec2bn(&value, *cpp) == 0)
357268578Srpaulo		return 0;
358268578Srpaulo
359178479Sjb	/* Restore old terminating character. */
360178479Sjb	*cp = old;
361178479Sjb
362178479Sjb	/* Move beyond the number and return success. */
363178479Sjb	*cpp = cp;
364178479Sjb	return 1;
365178479Sjb}
366178479Sjb
367178479Sjbstatic int
368178479Sjbwrite_bignum(FILE *f, BIGNUM *num)
369178479Sjb{
370178479Sjb	char *buf = BN_bn2dec(num);
371178479Sjb	if (buf == NULL) {
372178479Sjb		error("write_bignum: BN_bn2dec() failed");
373178479Sjb		return 0;
374178479Sjb	}
375178479Sjb	fprintf(f, " %s", buf);
376178479Sjb	OPENSSL_free(buf);
377178479Sjb	return 1;
378178479Sjb}
379178479Sjb
380178479Sjb/* returns 1 ok, -1 error */
381178479Sjbint
382178479Sjbkey_read(Key *ret, char **cpp)
383178479Sjb{
384178479Sjb	Key *k;
385178479Sjb	int success = -1;
386178479Sjb	char *cp, *space;
387178479Sjb	int len, n, type;
388178479Sjb	u_int bits;
389178479Sjb	u_char *blob;
390178479Sjb
391250574Smarkj	cp = *cpp;
392250574Smarkj
393250574Smarkj	switch (ret->type) {
394250574Smarkj	case KEY_RSA1:
395250574Smarkj		/* Get number of bits. */
396250574Smarkj		if (*cp < '0' || *cp > '9')
397250574Smarkj			return -1;	/* Bad bit count... */
398250574Smarkj		for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
399250574Smarkj			bits = 10 * bits + *cp - '0';
400250574Smarkj		if (bits == 0)
401250574Smarkj			return -1;
402250574Smarkj		*cpp = cp;
403250574Smarkj		/* Get public exponent, public modulus. */
404250574Smarkj		if (!read_bignum(cpp, ret->rsa->e))
405250574Smarkj			return -1;
406250574Smarkj		if (!read_bignum(cpp, ret->rsa->n))
407250574Smarkj			return -1;
408250574Smarkj		success = 1;
409250574Smarkj		break;
410250574Smarkj	case KEY_UNSPEC:
411250574Smarkj	case KEY_RSA:
412250574Smarkj	case KEY_DSA:
413250574Smarkj		space = strchr(cp, ' ');
414250574Smarkj		if (space == NULL) {
415250574Smarkj			debug3("key_read: missing whitespace");
416250574Smarkj			return -1;
417250574Smarkj		}
418250574Smarkj		*space = '\0';
419250574Smarkj		type = key_type_from_name(cp);
420250574Smarkj		*space = ' ';
421250574Smarkj		if (type == KEY_UNSPEC) {
422250574Smarkj			debug3("key_read: missing keytype");
423250574Smarkj			return -1;
424250574Smarkj		}
425250574Smarkj		cp = space+1;
426250574Smarkj		if (*cp == '\0') {
427250574Smarkj			debug3("key_read: short string");
428250574Smarkj			return -1;
429250574Smarkj		}
430250574Smarkj		if (ret->type == KEY_UNSPEC) {
431250574Smarkj			ret->type = type;
432250574Smarkj		} else if (ret->type != type) {
433250574Smarkj			/* is a key, but different type */
434250574Smarkj			debug3("key_read: type mismatch");
435250574Smarkj			return -1;
436250574Smarkj		}
437250574Smarkj		len = 2*strlen(cp);
438250574Smarkj		blob = xmalloc(len);
439250574Smarkj		n = uudecode(cp, blob, len);
440250574Smarkj		if (n < 0) {
441250574Smarkj			error("key_read: uudecode %s failed", cp);
442250574Smarkj			xfree(blob);
443250574Smarkj			return -1;
444250574Smarkj		}
445250574Smarkj		k = key_from_blob(blob, (u_int)n);
446178479Sjb		xfree(blob);
447178479Sjb		if (k == NULL) {
448178479Sjb			error("key_read: key_from_blob %s failed", cp);
449178479Sjb			return -1;
450178479Sjb		}
451178479Sjb		if (k->type != type) {
452178479Sjb			error("key_read: type mismatch: encoding error");
453178479Sjb			key_free(k);
454178479Sjb			return -1;
455178479Sjb		}
456178479Sjb/*XXXX*/
457178479Sjb		if (ret->type == KEY_RSA) {
458178479Sjb			if (ret->rsa != NULL)
459178479Sjb				RSA_free(ret->rsa);
460178479Sjb			ret->rsa = k->rsa;
461178479Sjb			k->rsa = NULL;
462178479Sjb			success = 1;
463178479Sjb#ifdef DEBUG_PK
464178479Sjb			RSA_print_fp(stderr, ret->rsa, 8);
465178479Sjb#endif
466178479Sjb		} else {
467178479Sjb			if (ret->dsa != NULL)
468178479Sjb				DSA_free(ret->dsa);
469178479Sjb			ret->dsa = k->dsa;
470178479Sjb			k->dsa = NULL;
471178479Sjb			success = 1;
472178479Sjb#ifdef DEBUG_PK
473178479Sjb			DSA_print_fp(stderr, ret->dsa, 8);
474178479Sjb#endif
475178479Sjb		}
476178479Sjb/*XXXX*/
477178479Sjb		key_free(k);
478178479Sjb		if (success != 1)
479178479Sjb			break;
480178479Sjb		/* advance cp: skip whitespace and data */
481178479Sjb		while (*cp == ' ' || *cp == '\t')
482178479Sjb			cp++;
483178479Sjb		while (*cp != '\0' && *cp != ' ' && *cp != '\t')
484178479Sjb			cp++;
485178479Sjb		*cpp = cp;
486178479Sjb		break;
487178479Sjb	default:
488178479Sjb		fatal("key_read: bad key type: %d", ret->type);
489178479Sjb		break;
490178479Sjb	}
491178479Sjb	return success;
492178479Sjb}
493178479Sjb
494178479Sjbint
495178479Sjbkey_write(const Key *key, FILE *f)
496178479Sjb{
497178479Sjb	int n, success = 0;
498178479Sjb	u_int len, bits = 0;
499178479Sjb	u_char *blob;
500178479Sjb	char *uu;
501178479Sjb
502178479Sjb	if (key->type == KEY_RSA1 && key->rsa != NULL) {
503178479Sjb		/* size of modulus 'n' */
504178479Sjb		bits = BN_num_bits(key->rsa->n);
505178479Sjb		fprintf(f, "%u", bits);
506178479Sjb		if (write_bignum(f, key->rsa->e) &&
507178479Sjb		    write_bignum(f, key->rsa->n)) {
508178479Sjb			success = 1;
509178479Sjb		} else {
510178479Sjb			error("key_write: failed for RSA key");
511178479Sjb		}
512178479Sjb	} else if ((key->type == KEY_DSA && key->dsa != NULL) ||
513178479Sjb	    (key->type == KEY_RSA && key->rsa != NULL)) {
514178479Sjb		key_to_blob(key, &blob, &len);
515178479Sjb		uu = xmalloc(2*len);
516178479Sjb		n = uuencode(blob, len, uu, 2*len);
517178479Sjb		if (n > 0) {
518178479Sjb			fprintf(f, "%s %s", key_ssh_name(key), uu);
519178479Sjb			success = 1;
520178479Sjb		}
521178479Sjb		xfree(blob);
522178479Sjb		xfree(uu);
523178479Sjb	}
524178479Sjb	return success;
525178479Sjb}
526178479Sjb
527178479Sjbconst char *
528178479Sjbkey_type(const Key *k)
529178479Sjb{
530178479Sjb	switch (k->type) {
531178479Sjb	case KEY_RSA1:
532178479Sjb		return "RSA1";
533178479Sjb		break;
534178479Sjb	case KEY_RSA:
535178479Sjb		return "RSA";
536178479Sjb		break;
537178479Sjb	case KEY_DSA:
538178479Sjb		return "DSA";
539178479Sjb		break;
540178479Sjb	}
541178479Sjb	return "unknown";
542178479Sjb}
543178479Sjb
544178479Sjbconst char *
545178479Sjbkey_ssh_name(const Key *k)
546178479Sjb{
547178479Sjb	switch (k->type) {
548178479Sjb	case KEY_RSA:
549178479Sjb		return "ssh-rsa";
550178479Sjb		break;
551178479Sjb	case KEY_DSA:
552178479Sjb		return "ssh-dss";
553178479Sjb		break;
554178479Sjb	}
555178479Sjb	return "ssh-unknown";
556178479Sjb}
557178479Sjb
558178479Sjbu_int
559178479Sjbkey_size(const Key *k)
560178479Sjb{
561178479Sjb	switch (k->type) {
562178479Sjb	case KEY_RSA1:
563178479Sjb	case KEY_RSA:
564178479Sjb		return BN_num_bits(k->rsa->n);
565178479Sjb		break;
566178479Sjb	case KEY_DSA:
567178479Sjb		return BN_num_bits(k->dsa->p);
568178479Sjb		break;
569178479Sjb	}
570178479Sjb	return 0;
571178479Sjb}
572178479Sjb
573178479Sjbstatic RSA *
574178479Sjbrsa_generate_private_key(u_int bits)
575178479Sjb{
576178479Sjb	RSA *private;
577178479Sjb	private = RSA_generate_key(bits, 35, NULL, NULL);
578178479Sjb	if (private == NULL)
579178479Sjb		fatal("rsa_generate_private_key: key generation failed.");
580178479Sjb	return private;
581178479Sjb}
582178479Sjb
583178479Sjbstatic DSA*
584178479Sjbdsa_generate_private_key(u_int bits)
585178479Sjb{
586178479Sjb	DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
587178479Sjb	if (private == NULL)
588178479Sjb		fatal("dsa_generate_private_key: DSA_generate_parameters failed");
589178479Sjb	if (!DSA_generate_key(private))
590178479Sjb		fatal("dsa_generate_private_key: DSA_generate_key failed.");
591178479Sjb	if (private == NULL)
592178479Sjb		fatal("dsa_generate_private_key: NULL.");
593178479Sjb	return private;
594178479Sjb}
595178479Sjb
596178479SjbKey *
597178479Sjbkey_generate(int type, u_int bits)
598178479Sjb{
599178479Sjb	Key *k = key_new(KEY_UNSPEC);
600178479Sjb	switch (type) {
601178479Sjb	case KEY_DSA:
602178479Sjb		k->dsa = dsa_generate_private_key(bits);
603178479Sjb		break;
604178479Sjb	case KEY_RSA:
605178479Sjb	case KEY_RSA1:
606178479Sjb		k->rsa = rsa_generate_private_key(bits);
607178479Sjb		break;
608178479Sjb	default:
609178479Sjb		fatal("key_generate: unknown type %d", type);
610178479Sjb	}
611178479Sjb	k->type = type;
612178479Sjb	return k;
613178479Sjb}
614178479Sjb
615178479SjbKey *
616178479Sjbkey_from_private(const Key *k)
617178479Sjb{
618178479Sjb	Key *n = NULL;
619178479Sjb	switch (k->type) {
620178479Sjb	case KEY_DSA:
621178479Sjb		n = key_new(k->type);
622178479Sjb		BN_copy(n->dsa->p, k->dsa->p);
623178479Sjb		BN_copy(n->dsa->q, k->dsa->q);
624178479Sjb		BN_copy(n->dsa->g, k->dsa->g);
625178479Sjb		BN_copy(n->dsa->pub_key, k->dsa->pub_key);
626178479Sjb		break;
627178479Sjb	case KEY_RSA:
628178479Sjb	case KEY_RSA1:
629178479Sjb		n = key_new(k->type);
630178479Sjb		BN_copy(n->rsa->n, k->rsa->n);
631178479Sjb		BN_copy(n->rsa->e, k->rsa->e);
632178479Sjb		break;
633178479Sjb	default:
634178479Sjb		fatal("key_from_private: unknown type %d", k->type);
635178479Sjb		break;
636178479Sjb	}
637178479Sjb	return n;
638178479Sjb}
639178479Sjb
640178479Sjbint
641178479Sjbkey_type_from_name(char *name)
642178479Sjb{
643178479Sjb	if (strcmp(name, "rsa1") == 0) {
644178479Sjb		return KEY_RSA1;
645178479Sjb	} else if (strcmp(name, "rsa") == 0) {
646178479Sjb		return KEY_RSA;
647178479Sjb	} else if (strcmp(name, "dsa") == 0) {
648178479Sjb		return KEY_DSA;
649178479Sjb	} else if (strcmp(name, "ssh-rsa") == 0) {
650178479Sjb		return KEY_RSA;
651178479Sjb	} else if (strcmp(name, "ssh-dss") == 0) {
652178479Sjb		return KEY_DSA;
653178479Sjb	}
654178479Sjb	debug2("key_type_from_name: unknown key type '%s'", name);
655178479Sjb	return KEY_UNSPEC;
656178479Sjb}
657178479Sjb
658178479Sjbint
659178479Sjbkey_names_valid2(const char *names)
660178479Sjb{
661178479Sjb	char *s, *cp, *p;
662178479Sjb
663178479Sjb	if (names == NULL || strcmp(names, "") == 0)
664178479Sjb		return 0;
665178479Sjb	s = cp = xstrdup(names);
666178479Sjb	for ((p = strsep(&cp, ",")); p && *p != '\0';
667178479Sjb	    (p = strsep(&cp, ","))) {
668178479Sjb		switch (key_type_from_name(p)) {
669178479Sjb		case KEY_RSA1:
670178479Sjb		case KEY_UNSPEC:
671178479Sjb			xfree(s);
672178479Sjb			return 0;
673178479Sjb		}
674178479Sjb	}
675178479Sjb	debug3("key names ok: [%s]", names);
676178479Sjb	xfree(s);
677178479Sjb	return 1;
678178479Sjb}
679178479Sjb
680178479SjbKey *
681178479Sjbkey_from_blob(const u_char *blob, u_int blen)
682178479Sjb{
683178479Sjb	Buffer b;
684178479Sjb	char *ktype;
685178479Sjb	int rlen, type;
686178479Sjb	Key *key = NULL;
687178479Sjb
688178479Sjb#ifdef DEBUG_PK
689178479Sjb	dump_base64(stderr, blob, blen);
690178479Sjb#endif
691178479Sjb	buffer_init(&b);
692178479Sjb	buffer_append(&b, blob, blen);
693178479Sjb	ktype = buffer_get_string(&b, NULL);
694178479Sjb	type = key_type_from_name(ktype);
695178479Sjb
696178479Sjb	switch (type) {
697178479Sjb	case KEY_RSA:
698178479Sjb		key = key_new(type);
699178479Sjb		buffer_get_bignum2(&b, key->rsa->e);
700178479Sjb		buffer_get_bignum2(&b, key->rsa->n);
701178479Sjb#ifdef DEBUG_PK
702178479Sjb		RSA_print_fp(stderr, key->rsa, 8);
703178479Sjb#endif
704178479Sjb		break;
705178479Sjb	case KEY_DSA:
706178479Sjb		key = key_new(type);
707178479Sjb		buffer_get_bignum2(&b, key->dsa->p);
708178479Sjb		buffer_get_bignum2(&b, key->dsa->q);
709178479Sjb		buffer_get_bignum2(&b, key->dsa->g);
710178479Sjb		buffer_get_bignum2(&b, key->dsa->pub_key);
711178479Sjb#ifdef DEBUG_PK
712178479Sjb		DSA_print_fp(stderr, key->dsa, 8);
713178479Sjb#endif
714178479Sjb		break;
715178479Sjb	case KEY_UNSPEC:
716178479Sjb		key = key_new(type);
717178479Sjb		break;
718178479Sjb	default:
719178479Sjb		error("key_from_blob: cannot handle type %s", ktype);
720178479Sjb		break;
721178479Sjb	}
722178479Sjb	rlen = buffer_len(&b);
723178479Sjb	if (key != NULL && rlen != 0)
724178479Sjb		error("key_from_blob: remaining bytes in key blob %d", rlen);
725178479Sjb	xfree(ktype);
726178479Sjb	buffer_free(&b);
727178479Sjb	return key;
728178479Sjb}
729178479Sjb
730178479Sjbint
731178479Sjbkey_to_blob(const Key *key, u_char **blobp, u_int *lenp)
732178479Sjb{
733178479Sjb	Buffer b;
734178479Sjb	int len;
735178479Sjb
736178479Sjb	if (key == NULL) {
737178479Sjb		error("key_to_blob: key == NULL");
738178479Sjb		return 0;
739178479Sjb	}
740178479Sjb	buffer_init(&b);
741178479Sjb	switch (key->type) {
742178479Sjb	case KEY_DSA:
743178479Sjb		buffer_put_cstring(&b, key_ssh_name(key));
744178479Sjb		buffer_put_bignum2(&b, key->dsa->p);
745178479Sjb		buffer_put_bignum2(&b, key->dsa->q);
746178479Sjb		buffer_put_bignum2(&b, key->dsa->g);
747178479Sjb		buffer_put_bignum2(&b, key->dsa->pub_key);
748178479Sjb		break;
749178479Sjb	case KEY_RSA:
750178479Sjb		buffer_put_cstring(&b, key_ssh_name(key));
751178479Sjb		buffer_put_bignum2(&b, key->rsa->e);
752178479Sjb		buffer_put_bignum2(&b, key->rsa->n);
753178479Sjb		break;
754178479Sjb	default:
755178479Sjb		error("key_to_blob: unsupported key type %d", key->type);
756178479Sjb		buffer_free(&b);
757178479Sjb		return 0;
758178479Sjb	}
759178479Sjb	len = buffer_len(&b);
760178479Sjb	if (lenp != NULL)
761178479Sjb		*lenp = len;
762178479Sjb	if (blobp != NULL) {
763178479Sjb		*blobp = xmalloc(len);
764178479Sjb		memcpy(*blobp, buffer_ptr(&b), len);
765178479Sjb	}
766178479Sjb	memset(buffer_ptr(&b), 0, len);
767178479Sjb	buffer_free(&b);
768178479Sjb	return len;
769178479Sjb}
770178479Sjb
771178479Sjbint
772178479Sjbkey_sign(
773178479Sjb    const Key *key,
774178479Sjb    u_char **sigp, u_int *lenp,
775178479Sjb    const u_char *data, u_int datalen)
776178479Sjb{
777178479Sjb	switch (key->type) {
778178479Sjb	case KEY_DSA:
779178479Sjb		return ssh_dss_sign(key, sigp, lenp, data, datalen);
780178479Sjb		break;
781178479Sjb	case KEY_RSA:
782178479Sjb		return ssh_rsa_sign(key, sigp, lenp, data, datalen);
783178479Sjb		break;
784178479Sjb	default:
785178479Sjb		error("key_sign: invalid key type %d", key->type);
786178479Sjb		return -1;
787178479Sjb		break;
788178479Sjb	}
789178479Sjb}
790178479Sjb
791178479Sjb/*
792178479Sjb * key_verify returns 1 for a correct signature, 0 for an incorrect signature
793178479Sjb * and -1 on error.
794178479Sjb */
795178479Sjbint
796178479Sjbkey_verify(
797178479Sjb    const Key *key,
798178479Sjb    const u_char *signature, u_int signaturelen,
799178479Sjb    const u_char *data, u_int datalen)
800178479Sjb{
801178479Sjb	if (signaturelen == 0)
802178479Sjb		return -1;
803178479Sjb
804178479Sjb	switch (key->type) {
805178479Sjb	case KEY_DSA:
806178479Sjb		return ssh_dss_verify(key, signature, signaturelen, data, datalen);
807178479Sjb		break;
808178479Sjb	case KEY_RSA:
809178479Sjb		return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
810178479Sjb		break;
811178479Sjb	default:
812178479Sjb		error("key_verify: invalid key type %d", key->type);
813178479Sjb		return -1;
814178479Sjb		break;
815178479Sjb	}
816178479Sjb}
817178479Sjb
818178479Sjb/* Converts a private to a public key */
819178479SjbKey *
820178479Sjbkey_demote(const Key *k)
821178479Sjb{
822178479Sjb	Key *pk;
823178479Sjb
824178479Sjb	pk = xmalloc(sizeof(*pk));
825178479Sjb	pk->type = k->type;
826178479Sjb	pk->flags = k->flags;
827178479Sjb	pk->dsa = NULL;
828178479Sjb	pk->rsa = NULL;
829178479Sjb
830178479Sjb	switch (k->type) {
831178479Sjb	case KEY_RSA1:
832178479Sjb	case KEY_RSA:
833178479Sjb		if ((pk->rsa = RSA_new()) == NULL)
834178479Sjb			fatal("key_demote: RSA_new failed");
835178479Sjb		if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL)
836178479Sjb			fatal("key_demote: BN_dup failed");
837178479Sjb		if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL)
838178479Sjb			fatal("key_demote: BN_dup failed");
839178479Sjb		break;
840178479Sjb	case KEY_DSA:
841178479Sjb		if ((pk->dsa = DSA_new()) == NULL)
842178479Sjb			fatal("key_demote: DSA_new failed");
843178479Sjb		if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL)
844178479Sjb			fatal("key_demote: BN_dup failed");
845178479Sjb		if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL)
846178479Sjb			fatal("key_demote: BN_dup failed");
847178479Sjb		if ((pk->dsa->g = BN_dup(k->dsa->g)) == NULL)
848178479Sjb			fatal("key_demote: BN_dup failed");
849178479Sjb		if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL)
850178479Sjb			fatal("key_demote: BN_dup failed");
851178479Sjb		break;
852178479Sjb	default:
853178479Sjb		fatal("key_free: bad key type %d", k->type);
854178479Sjb		break;
855178479Sjb	}
856178479Sjb
857178479Sjb	return (pk);
858178479Sjb}
859178479Sjb