Import OpenSSH 4.5p1.
[dragonfly.git] / crypto / openssh-4 / key.c
1 /* $OpenBSD: key.c,v 1.68 2006/11/06 21:25:28 markus Exp $ */
2 /*
3  * read_bignum():
4  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5  *
6  * As far as I am concerned, the code I have written for this software
7  * can be used freely for any purpose.  Any derived versions of this
8  * software must be clearly marked as such, and if the derived work is
9  * incompatible with the protocol description in the RFC file, it must be
10  * called by a name other than "ssh" or "Secure Shell".
11  *
12  *
13  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 #include "includes.h"
37
38 #include <sys/types.h>
39
40 #include <openssl/evp.h>
41
42 #include <stdarg.h>
43 #include <stdio.h>
44 #include <string.h>
45
46 #include "xmalloc.h"
47 #include "key.h"
48 #include "rsa.h"
49 #include "uuencode.h"
50 #include "buffer.h"
51 #include "log.h"
52
53 Key *
54 key_new(int type)
55 {
56         Key *k;
57         RSA *rsa;
58         DSA *dsa;
59         k = xcalloc(1, sizeof(*k));
60         k->type = type;
61         k->dsa = NULL;
62         k->rsa = NULL;
63         switch (k->type) {
64         case KEY_RSA1:
65         case KEY_RSA:
66                 if ((rsa = RSA_new()) == NULL)
67                         fatal("key_new: RSA_new failed");
68                 if ((rsa->n = BN_new()) == NULL)
69                         fatal("key_new: BN_new failed");
70                 if ((rsa->e = BN_new()) == NULL)
71                         fatal("key_new: BN_new failed");
72                 k->rsa = rsa;
73                 break;
74         case KEY_DSA:
75                 if ((dsa = DSA_new()) == NULL)
76                         fatal("key_new: DSA_new failed");
77                 if ((dsa->p = BN_new()) == NULL)
78                         fatal("key_new: BN_new failed");
79                 if ((dsa->q = BN_new()) == NULL)
80                         fatal("key_new: BN_new failed");
81                 if ((dsa->g = BN_new()) == NULL)
82                         fatal("key_new: BN_new failed");
83                 if ((dsa->pub_key = BN_new()) == NULL)
84                         fatal("key_new: BN_new failed");
85                 k->dsa = dsa;
86                 break;
87         case KEY_UNSPEC:
88                 break;
89         default:
90                 fatal("key_new: bad key type %d", k->type);
91                 break;
92         }
93         return k;
94 }
95
96 Key *
97 key_new_private(int type)
98 {
99         Key *k = key_new(type);
100         switch (k->type) {
101         case KEY_RSA1:
102         case KEY_RSA:
103                 if ((k->rsa->d = BN_new()) == NULL)
104                         fatal("key_new_private: BN_new failed");
105                 if ((k->rsa->iqmp = BN_new()) == NULL)
106                         fatal("key_new_private: BN_new failed");
107                 if ((k->rsa->q = BN_new()) == NULL)
108                         fatal("key_new_private: BN_new failed");
109                 if ((k->rsa->p = BN_new()) == NULL)
110                         fatal("key_new_private: BN_new failed");
111                 if ((k->rsa->dmq1 = BN_new()) == NULL)
112                         fatal("key_new_private: BN_new failed");
113                 if ((k->rsa->dmp1 = BN_new()) == NULL)
114                         fatal("key_new_private: BN_new failed");
115                 break;
116         case KEY_DSA:
117                 if ((k->dsa->priv_key = BN_new()) == NULL)
118                         fatal("key_new_private: BN_new failed");
119                 break;
120         case KEY_UNSPEC:
121                 break;
122         default:
123                 break;
124         }
125         return k;
126 }
127
128 void
129 key_free(Key *k)
130 {
131         if (k == NULL)
132                 fatal("key_free: key is NULL");
133         switch (k->type) {
134         case KEY_RSA1:
135         case KEY_RSA:
136                 if (k->rsa != NULL)
137                         RSA_free(k->rsa);
138                 k->rsa = NULL;
139                 break;
140         case KEY_DSA:
141                 if (k->dsa != NULL)
142                         DSA_free(k->dsa);
143                 k->dsa = NULL;
144                 break;
145         case KEY_UNSPEC:
146                 break;
147         default:
148                 fatal("key_free: bad key type %d", k->type);
149                 break;
150         }
151         xfree(k);
152 }
153
154 int
155 key_equal(const Key *a, const Key *b)
156 {
157         if (a == NULL || b == NULL || a->type != b->type)
158                 return 0;
159         switch (a->type) {
160         case KEY_RSA1:
161         case KEY_RSA:
162                 return a->rsa != NULL && b->rsa != NULL &&
163                     BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
164                     BN_cmp(a->rsa->n, b->rsa->n) == 0;
165         case KEY_DSA:
166                 return a->dsa != NULL && b->dsa != NULL &&
167                     BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
168                     BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
169                     BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
170                     BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
171         default:
172                 fatal("key_equal: bad key type %d", a->type);
173                 break;
174         }
175         return 0;
176 }
177
178 u_char*
179 key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
180     u_int *dgst_raw_length)
181 {
182         const EVP_MD *md = NULL;
183         EVP_MD_CTX ctx;
184         u_char *blob = NULL;
185         u_char *retval = NULL;
186         u_int len = 0;
187         int nlen, elen;
188
189         *dgst_raw_length = 0;
190
191         switch (dgst_type) {
192         case SSH_FP_MD5:
193                 md = EVP_md5();
194                 break;
195         case SSH_FP_SHA1:
196                 md = EVP_sha1();
197                 break;
198         default:
199                 fatal("key_fingerprint_raw: bad digest type %d",
200                     dgst_type);
201         }
202         switch (k->type) {
203         case KEY_RSA1:
204                 nlen = BN_num_bytes(k->rsa->n);
205                 elen = BN_num_bytes(k->rsa->e);
206                 len = nlen + elen;
207                 blob = xmalloc(len);
208                 BN_bn2bin(k->rsa->n, blob);
209                 BN_bn2bin(k->rsa->e, blob + nlen);
210                 break;
211         case KEY_DSA:
212         case KEY_RSA:
213                 key_to_blob(k, &blob, &len);
214                 break;
215         case KEY_UNSPEC:
216                 return retval;
217         default:
218                 fatal("key_fingerprint_raw: bad key type %d", k->type);
219                 break;
220         }
221         if (blob != NULL) {
222                 retval = xmalloc(EVP_MAX_MD_SIZE);
223                 EVP_DigestInit(&ctx, md);
224                 EVP_DigestUpdate(&ctx, blob, len);
225                 EVP_DigestFinal(&ctx, retval, dgst_raw_length);
226                 memset(blob, 0, len);
227                 xfree(blob);
228         } else {
229                 fatal("key_fingerprint_raw: blob is null");
230         }
231         return retval;
232 }
233
234 static char *
235 key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len)
236 {
237         char *retval;
238         u_int i;
239
240         retval = xcalloc(1, dgst_raw_len * 3 + 1);
241         for (i = 0; i < dgst_raw_len; i++) {
242                 char hex[4];
243                 snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
244                 strlcat(retval, hex, dgst_raw_len * 3 + 1);
245         }
246
247         /* Remove the trailing ':' character */
248         retval[(dgst_raw_len * 3) - 1] = '\0';
249         return retval;
250 }
251
252 static char *
253 key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len)
254 {
255         char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
256         char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
257             'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
258         u_int i, j = 0, rounds, seed = 1;
259         char *retval;
260
261         rounds = (dgst_raw_len / 2) + 1;
262         retval = xcalloc((rounds * 6), sizeof(char));
263         retval[j++] = 'x';
264         for (i = 0; i < rounds; i++) {
265                 u_int idx0, idx1, idx2, idx3, idx4;
266                 if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
267                         idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) +
268                             seed) % 6;
269                         idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15;
270                         idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) +
271                             (seed / 6)) % 6;
272                         retval[j++] = vowels[idx0];
273                         retval[j++] = consonants[idx1];
274                         retval[j++] = vowels[idx2];
275                         if ((i + 1) < rounds) {
276                                 idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;
277                                 idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15;
278                                 retval[j++] = consonants[idx3];
279                                 retval[j++] = '-';
280                                 retval[j++] = consonants[idx4];
281                                 seed = ((seed * 5) +
282                                     ((((u_int)(dgst_raw[2 * i])) * 7) +
283                                     ((u_int)(dgst_raw[(2 * i) + 1])))) % 36;
284                         }
285                 } else {
286                         idx0 = seed % 6;
287                         idx1 = 16;
288                         idx2 = seed / 6;
289                         retval[j++] = vowels[idx0];
290                         retval[j++] = consonants[idx1];
291                         retval[j++] = vowels[idx2];
292                 }
293         }
294         retval[j++] = 'x';
295         retval[j++] = '\0';
296         return retval;
297 }
298
299 char *
300 key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
301 {
302         char *retval = NULL;
303         u_char *dgst_raw;
304         u_int dgst_raw_len;
305
306         dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len);
307         if (!dgst_raw)
308                 fatal("key_fingerprint: null from key_fingerprint_raw()");
309         switch (dgst_rep) {
310         case SSH_FP_HEX:
311                 retval = key_fingerprint_hex(dgst_raw, dgst_raw_len);
312                 break;
313         case SSH_FP_BUBBLEBABBLE:
314                 retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
315                 break;
316         default:
317                 fatal("key_fingerprint_ex: bad digest representation %d",
318                     dgst_rep);
319                 break;
320         }
321         memset(dgst_raw, 0, dgst_raw_len);
322         xfree(dgst_raw);
323         return retval;
324 }
325
326 /*
327  * Reads a multiple-precision integer in decimal from the buffer, and advances
328  * the pointer.  The integer must already be initialized.  This function is
329  * permitted to modify the buffer.  This leaves *cpp to point just beyond the
330  * last processed (and maybe modified) character.  Note that this may modify
331  * the buffer containing the number.
332  */
333 static int
334 read_bignum(char **cpp, BIGNUM * value)
335 {
336         char *cp = *cpp;
337         int old;
338
339         /* Skip any leading whitespace. */
340         for (; *cp == ' ' || *cp == '\t'; cp++)
341                 ;
342
343         /* Check that it begins with a decimal digit. */
344         if (*cp < '0' || *cp > '9')
345                 return 0;
346
347         /* Save starting position. */
348         *cpp = cp;
349
350         /* Move forward until all decimal digits skipped. */
351         for (; *cp >= '0' && *cp <= '9'; cp++)
352                 ;
353
354         /* Save the old terminating character, and replace it by \0. */
355         old = *cp;
356         *cp = 0;
357
358         /* Parse the number. */
359         if (BN_dec2bn(&value, *cpp) == 0)
360                 return 0;
361
362         /* Restore old terminating character. */
363         *cp = old;
364
365         /* Move beyond the number and return success. */
366         *cpp = cp;
367         return 1;
368 }
369
370 static int
371 write_bignum(FILE *f, BIGNUM *num)
372 {
373         char *buf = BN_bn2dec(num);
374         if (buf == NULL) {
375                 error("write_bignum: BN_bn2dec() failed");
376                 return 0;
377         }
378         fprintf(f, " %s", buf);
379         OPENSSL_free(buf);
380         return 1;
381 }
382
383 /* returns 1 ok, -1 error */
384 int
385 key_read(Key *ret, char **cpp)
386 {
387         Key *k;
388         int success = -1;
389         char *cp, *space;
390         int len, n, type;
391         u_int bits;
392         u_char *blob;
393
394         cp = *cpp;
395
396         switch (ret->type) {
397         case KEY_RSA1:
398                 /* Get number of bits. */
399                 if (*cp < '0' || *cp > '9')
400                         return -1;      /* Bad bit count... */
401                 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
402                         bits = 10 * bits + *cp - '0';
403                 if (bits == 0)
404                         return -1;
405                 *cpp = cp;
406                 /* Get public exponent, public modulus. */
407                 if (!read_bignum(cpp, ret->rsa->e))
408                         return -1;
409                 if (!read_bignum(cpp, ret->rsa->n))
410                         return -1;
411                 success = 1;
412                 break;
413         case KEY_UNSPEC:
414         case KEY_RSA:
415         case KEY_DSA:
416                 space = strchr(cp, ' ');
417                 if (space == NULL) {
418                         debug3("key_read: missing whitespace");
419                         return -1;
420                 }
421                 *space = '\0';
422                 type = key_type_from_name(cp);
423                 *space = ' ';
424                 if (type == KEY_UNSPEC) {
425                         debug3("key_read: missing keytype");
426                         return -1;
427                 }
428                 cp = space+1;
429                 if (*cp == '\0') {
430                         debug3("key_read: short string");
431                         return -1;
432                 }
433                 if (ret->type == KEY_UNSPEC) {
434                         ret->type = type;
435                 } else if (ret->type != type) {
436                         /* is a key, but different type */
437                         debug3("key_read: type mismatch");
438                         return -1;
439                 }
440                 len = 2*strlen(cp);
441                 blob = xmalloc(len);
442                 n = uudecode(cp, blob, len);
443                 if (n < 0) {
444                         error("key_read: uudecode %s failed", cp);
445                         xfree(blob);
446                         return -1;
447                 }
448                 k = key_from_blob(blob, (u_int)n);
449                 xfree(blob);
450                 if (k == NULL) {
451                         error("key_read: key_from_blob %s failed", cp);
452                         return -1;
453                 }
454                 if (k->type != type) {
455                         error("key_read: type mismatch: encoding error");
456                         key_free(k);
457                         return -1;
458                 }
459 /*XXXX*/
460                 if (ret->type == KEY_RSA) {
461                         if (ret->rsa != NULL)
462                                 RSA_free(ret->rsa);
463                         ret->rsa = k->rsa;
464                         k->rsa = NULL;
465                         success = 1;
466 #ifdef DEBUG_PK
467                         RSA_print_fp(stderr, ret->rsa, 8);
468 #endif
469                 } else {
470                         if (ret->dsa != NULL)
471                                 DSA_free(ret->dsa);
472                         ret->dsa = k->dsa;
473                         k->dsa = NULL;
474                         success = 1;
475 #ifdef DEBUG_PK
476                         DSA_print_fp(stderr, ret->dsa, 8);
477 #endif
478                 }
479 /*XXXX*/
480                 key_free(k);
481                 if (success != 1)
482                         break;
483                 /* advance cp: skip whitespace and data */
484                 while (*cp == ' ' || *cp == '\t')
485                         cp++;
486                 while (*cp != '\0' && *cp != ' ' && *cp != '\t')
487                         cp++;
488                 *cpp = cp;
489                 break;
490         default:
491                 fatal("key_read: bad key type: %d", ret->type);
492                 break;
493         }
494         return success;
495 }
496
497 int
498 key_write(const Key *key, FILE *f)
499 {
500         int n, success = 0;
501         u_int len, bits = 0;
502         u_char *blob;
503         char *uu;
504
505         if (key->type == KEY_RSA1 && key->rsa != NULL) {
506                 /* size of modulus 'n' */
507                 bits = BN_num_bits(key->rsa->n);
508                 fprintf(f, "%u", bits);
509                 if (write_bignum(f, key->rsa->e) &&
510                     write_bignum(f, key->rsa->n)) {
511                         success = 1;
512                 } else {
513                         error("key_write: failed for RSA key");
514                 }
515         } else if ((key->type == KEY_DSA && key->dsa != NULL) ||
516             (key->type == KEY_RSA && key->rsa != NULL)) {
517                 key_to_blob(key, &blob, &len);
518                 uu = xmalloc(2*len);
519                 n = uuencode(blob, len, uu, 2*len);
520                 if (n > 0) {
521                         fprintf(f, "%s %s", key_ssh_name(key), uu);
522                         success = 1;
523                 }
524                 xfree(blob);
525                 xfree(uu);
526         }
527         return success;
528 }
529
530 const char *
531 key_type(const Key *k)
532 {
533         switch (k->type) {
534         case KEY_RSA1:
535                 return "RSA1";
536         case KEY_RSA:
537                 return "RSA";
538         case KEY_DSA:
539                 return "DSA";
540         }
541         return "unknown";
542 }
543
544 const char *
545 key_ssh_name(const Key *k)
546 {
547         switch (k->type) {
548         case KEY_RSA:
549                 return "ssh-rsa";
550         case KEY_DSA:
551                 return "ssh-dss";
552         }
553         return "ssh-unknown";
554 }
555
556 u_int
557 key_size(const Key *k)
558 {
559         switch (k->type) {
560         case KEY_RSA1:
561         case KEY_RSA:
562                 return BN_num_bits(k->rsa->n);
563         case KEY_DSA:
564                 return BN_num_bits(k->dsa->p);
565         }
566         return 0;
567 }
568
569 static RSA *
570 rsa_generate_private_key(u_int bits)
571 {
572         RSA *private;
573
574         private = RSA_generate_key(bits, 35, NULL, NULL);
575         if (private == NULL)
576                 fatal("rsa_generate_private_key: key generation failed.");
577         return private;
578 }
579
580 static DSA*
581 dsa_generate_private_key(u_int bits)
582 {
583         DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
584
585         if (private == NULL)
586                 fatal("dsa_generate_private_key: DSA_generate_parameters failed");
587         if (!DSA_generate_key(private))
588                 fatal("dsa_generate_private_key: DSA_generate_key failed.");
589         if (private == NULL)
590                 fatal("dsa_generate_private_key: NULL.");
591         return private;
592 }
593
594 Key *
595 key_generate(int type, u_int bits)
596 {
597         Key *k = key_new(KEY_UNSPEC);
598         switch (type) {
599         case KEY_DSA:
600                 k->dsa = dsa_generate_private_key(bits);
601                 break;
602         case KEY_RSA:
603         case KEY_RSA1:
604                 k->rsa = rsa_generate_private_key(bits);
605                 break;
606         default:
607                 fatal("key_generate: unknown type %d", type);
608         }
609         k->type = type;
610         return k;
611 }
612
613 Key *
614 key_from_private(const Key *k)
615 {
616         Key *n = NULL;
617         switch (k->type) {
618         case KEY_DSA:
619                 n = key_new(k->type);
620                 if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
621                     (BN_copy(n->dsa->q, k->dsa->q) == NULL) ||
622                     (BN_copy(n->dsa->g, k->dsa->g) == NULL) ||
623                     (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL))
624                         fatal("key_from_private: BN_copy failed");
625                 break;
626         case KEY_RSA:
627         case KEY_RSA1:
628                 n = key_new(k->type);
629                 if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
630                     (BN_copy(n->rsa->e, k->rsa->e) == NULL))
631                         fatal("key_from_private: BN_copy failed");
632                 break;
633         default:
634                 fatal("key_from_private: unknown type %d", k->type);
635                 break;
636         }
637         return n;
638 }
639
640 int
641 key_type_from_name(char *name)
642 {
643         if (strcmp(name, "rsa1") == 0) {
644                 return KEY_RSA1;
645         } else if (strcmp(name, "rsa") == 0) {
646                 return KEY_RSA;
647         } else if (strcmp(name, "dsa") == 0) {
648                 return KEY_DSA;
649         } else if (strcmp(name, "ssh-rsa") == 0) {
650                 return KEY_RSA;
651         } else if (strcmp(name, "ssh-dss") == 0) {
652                 return KEY_DSA;
653         }
654         debug2("key_type_from_name: unknown key type '%s'", name);
655         return KEY_UNSPEC;
656 }
657
658 int
659 key_names_valid2(const char *names)
660 {
661         char *s, *cp, *p;
662
663         if (names == NULL || strcmp(names, "") == 0)
664                 return 0;
665         s = cp = xstrdup(names);
666         for ((p = strsep(&cp, ",")); p && *p != '\0';
667             (p = strsep(&cp, ","))) {
668                 switch (key_type_from_name(p)) {
669                 case KEY_RSA1:
670                 case KEY_UNSPEC:
671                         xfree(s);
672                         return 0;
673                 }
674         }
675         debug3("key names ok: [%s]", names);
676         xfree(s);
677         return 1;
678 }
679
680 Key *
681 key_from_blob(const u_char *blob, u_int blen)
682 {
683         Buffer b;
684         int rlen, type;
685         char *ktype = NULL;
686         Key *key = NULL;
687
688 #ifdef DEBUG_PK
689         dump_base64(stderr, blob, blen);
690 #endif
691         buffer_init(&b);
692         buffer_append(&b, blob, blen);
693         if ((ktype = buffer_get_string_ret(&b, NULL)) == NULL) {
694                 error("key_from_blob: can't read key type");
695                 goto out;
696         }
697
698         type = key_type_from_name(ktype);
699
700         switch (type) {
701         case KEY_RSA:
702                 key = key_new(type);
703                 if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 ||
704                     buffer_get_bignum2_ret(&b, key->rsa->n) == -1) {
705                         error("key_from_blob: can't read rsa key");
706                         key_free(key);
707                         key = NULL;
708                         goto out;
709                 }
710 #ifdef DEBUG_PK
711                 RSA_print_fp(stderr, key->rsa, 8);
712 #endif
713                 break;
714         case KEY_DSA:
715                 key = key_new(type);
716                 if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 ||
717                     buffer_get_bignum2_ret(&b, key->dsa->q) == -1 ||
718                     buffer_get_bignum2_ret(&b, key->dsa->g) == -1 ||
719                     buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) {
720                         error("key_from_blob: can't read dsa key");
721                         key_free(key);
722                         key = NULL;
723                         goto out;
724                 }
725 #ifdef DEBUG_PK
726                 DSA_print_fp(stderr, key->dsa, 8);
727 #endif
728                 break;
729         case KEY_UNSPEC:
730                 key = key_new(type);
731                 break;
732         default:
733                 error("key_from_blob: cannot handle type %s", ktype);
734                 goto out;
735         }
736         rlen = buffer_len(&b);
737         if (key != NULL && rlen != 0)
738                 error("key_from_blob: remaining bytes in key blob %d", rlen);
739  out:
740         if (ktype != NULL)
741                 xfree(ktype);
742         buffer_free(&b);
743         return key;
744 }
745
746 int
747 key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
748 {
749         Buffer b;
750         int len;
751
752         if (key == NULL) {
753                 error("key_to_blob: key == NULL");
754                 return 0;
755         }
756         buffer_init(&b);
757         switch (key->type) {
758         case KEY_DSA:
759                 buffer_put_cstring(&b, key_ssh_name(key));
760                 buffer_put_bignum2(&b, key->dsa->p);
761                 buffer_put_bignum2(&b, key->dsa->q);
762                 buffer_put_bignum2(&b, key->dsa->g);
763                 buffer_put_bignum2(&b, key->dsa->pub_key);
764                 break;
765         case KEY_RSA:
766                 buffer_put_cstring(&b, key_ssh_name(key));
767                 buffer_put_bignum2(&b, key->rsa->e);
768                 buffer_put_bignum2(&b, key->rsa->n);
769                 break;
770         default:
771                 error("key_to_blob: unsupported key type %d", key->type);
772                 buffer_free(&b);
773                 return 0;
774         }
775         len = buffer_len(&b);
776         if (lenp != NULL)
777                 *lenp = len;
778         if (blobp != NULL) {
779                 *blobp = xmalloc(len);
780                 memcpy(*blobp, buffer_ptr(&b), len);
781         }
782         memset(buffer_ptr(&b), 0, len);
783         buffer_free(&b);
784         return len;
785 }
786
787 int
788 key_sign(
789     const Key *key,
790     u_char **sigp, u_int *lenp,
791     const u_char *data, u_int datalen)
792 {
793         switch (key->type) {
794         case KEY_DSA:
795                 return ssh_dss_sign(key, sigp, lenp, data, datalen);
796         case KEY_RSA:
797                 return ssh_rsa_sign(key, sigp, lenp, data, datalen);
798         default:
799                 error("key_sign: invalid key type %d", key->type);
800                 return -1;
801         }
802 }
803
804 /*
805  * key_verify returns 1 for a correct signature, 0 for an incorrect signature
806  * and -1 on error.
807  */
808 int
809 key_verify(
810     const Key *key,
811     const u_char *signature, u_int signaturelen,
812     const u_char *data, u_int datalen)
813 {
814         if (signaturelen == 0)
815                 return -1;
816
817         switch (key->type) {
818         case KEY_DSA:
819                 return ssh_dss_verify(key, signature, signaturelen, data, datalen);
820         case KEY_RSA:
821                 return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
822         default:
823                 error("key_verify: invalid key type %d", key->type);
824                 return -1;
825         }
826 }
827
828 /* Converts a private to a public key */
829 Key *
830 key_demote(const Key *k)
831 {
832         Key *pk;
833
834         pk = xcalloc(1, sizeof(*pk));
835         pk->type = k->type;
836         pk->flags = k->flags;
837         pk->dsa = NULL;
838         pk->rsa = NULL;
839
840         switch (k->type) {
841         case KEY_RSA1:
842         case KEY_RSA:
843                 if ((pk->rsa = RSA_new()) == NULL)
844                         fatal("key_demote: RSA_new failed");
845                 if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL)
846                         fatal("key_demote: BN_dup failed");
847                 if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL)
848                         fatal("key_demote: BN_dup failed");
849                 break;
850         case KEY_DSA:
851                 if ((pk->dsa = DSA_new()) == NULL)
852                         fatal("key_demote: DSA_new failed");
853                 if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL)
854                         fatal("key_demote: BN_dup failed");
855                 if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL)
856                         fatal("key_demote: BN_dup failed");
857                 if ((pk->dsa->g = BN_dup(k->dsa->g)) == NULL)
858                         fatal("key_demote: BN_dup failed");
859                 if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL)
860                         fatal("key_demote: BN_dup failed");
861                 break;
862         default:
863                 fatal("key_free: bad key type %d", k->type);
864                 break;
865         }
866
867         return (pk);
868 }