source: trunk/third/openssh/key.c @ 18763

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