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

Revision 16801, 16.9 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r16800, which included commits to RCS files with non-trunk default branches.
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.32 2001/09/19 13:23:29 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                rsa = RSA_new();
64                rsa->n = BN_new();
65                rsa->e = BN_new();
66                k->rsa = rsa;
67                break;
68        case KEY_DSA:
69                dsa = DSA_new();
70                dsa->p = BN_new();
71                dsa->q = BN_new();
72                dsa->g = BN_new();
73                dsa->pub_key = BN_new();
74                k->dsa = dsa;
75                break;
76        case KEY_UNSPEC:
77                break;
78        default:
79                fatal("key_new: bad key type %d", k->type);
80                break;
81        }
82        return k;
83}
84Key *
85key_new_private(int type)
86{
87        Key *k = key_new(type);
88        switch (k->type) {
89        case KEY_RSA1:
90        case KEY_RSA:
91                k->rsa->d = BN_new();
92                k->rsa->iqmp = BN_new();
93                k->rsa->q = BN_new();
94                k->rsa->p = BN_new();
95                k->rsa->dmq1 = BN_new();
96                k->rsa->dmp1 = BN_new();
97                break;
98        case KEY_DSA:
99                k->dsa->priv_key = BN_new();
100                break;
101        case KEY_UNSPEC:
102                break;
103        default:
104                break;
105        }
106        return k;
107}
108void
109key_free(Key *k)
110{
111        switch (k->type) {
112        case KEY_RSA1:
113        case KEY_RSA:
114                if (k->rsa != NULL)
115                        RSA_free(k->rsa);
116                k->rsa = NULL;
117                break;
118        case KEY_DSA:
119                if (k->dsa != NULL)
120                        DSA_free(k->dsa);
121                k->dsa = NULL;
122                break;
123        case KEY_UNSPEC:
124                break;
125        default:
126                fatal("key_free: bad key type %d", k->type);
127                break;
128        }
129        xfree(k);
130}
131int
132key_equal(Key *a, Key *b)
133{
134        if (a == NULL || b == NULL || a->type != b->type)
135                return 0;
136        switch (a->type) {
137        case KEY_RSA1:
138        case KEY_RSA:
139                return a->rsa != NULL && b->rsa != NULL &&
140                    BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
141                    BN_cmp(a->rsa->n, b->rsa->n) == 0;
142                break;
143        case KEY_DSA:
144                return a->dsa != NULL && b->dsa != NULL &&
145                    BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
146                    BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
147                    BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
148                    BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
149                break;
150        default:
151                fatal("key_equal: bad key type %d", a->type);
152                break;
153        }
154        return 0;
155}
156
157static u_char*
158key_fingerprint_raw(Key *k, enum fp_type dgst_type, size_t *dgst_raw_length)
159{
160        EVP_MD *md = NULL;
161        EVP_MD_CTX ctx;
162        u_char *blob = NULL;
163        u_char *retval = NULL;
164        int len = 0;
165        int nlen, elen;
166
167        *dgst_raw_length = 0;
168
169        switch (dgst_type) {
170        case SSH_FP_MD5:
171                md = EVP_md5();
172                break;
173        case SSH_FP_SHA1:
174                md = EVP_sha1();
175                break;
176        default:
177                fatal("key_fingerprint_raw: bad digest type %d",
178                    dgst_type);
179        }
180        switch (k->type) {
181        case KEY_RSA1:
182                nlen = BN_num_bytes(k->rsa->n);
183                elen = BN_num_bytes(k->rsa->e);
184                len = nlen + elen;
185                blob = xmalloc(len);
186                BN_bn2bin(k->rsa->n, blob);
187                BN_bn2bin(k->rsa->e, blob + nlen);
188                break;
189        case KEY_DSA:
190        case KEY_RSA:
191                key_to_blob(k, &blob, &len);
192                break;
193        case KEY_UNSPEC:
194                return retval;
195                break;
196        default:
197                fatal("key_fingerprint_raw: bad key type %d", k->type);
198                break;
199        }
200        if (blob != NULL) {
201                retval = xmalloc(EVP_MAX_MD_SIZE);
202                EVP_DigestInit(&ctx, md);
203                EVP_DigestUpdate(&ctx, blob, len);
204                EVP_DigestFinal(&ctx, retval, NULL);
205                *dgst_raw_length = md->md_size;
206                memset(blob, 0, len);
207                xfree(blob);
208        } else {
209                fatal("key_fingerprint_raw: blob is null");
210        }
211        return retval;
212}
213
214static char*
215key_fingerprint_hex(u_char* dgst_raw, size_t dgst_raw_len)
216{
217        char *retval;
218        int i;
219
220        retval = xmalloc(dgst_raw_len * 3 + 1);
221        retval[0] = '\0';
222        for(i = 0; i < dgst_raw_len; i++) {
223                char hex[4];
224                snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
225                strlcat(retval, hex, dgst_raw_len * 3);
226        }
227        retval[(dgst_raw_len * 3) - 1] = '\0';
228        return retval;
229}
230
231static char*
232key_fingerprint_bubblebabble(u_char* dgst_raw, size_t dgst_raw_len)
233{
234        char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
235        char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
236            'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
237        u_int i, j = 0, rounds, seed = 1;
238        char *retval;
239
240        rounds = (dgst_raw_len / 2) + 1;
241        retval = xmalloc(sizeof(char) * (rounds*6));
242        retval[j++] = 'x';
243        for (i = 0; i < rounds; i++) {
244                u_int idx0, idx1, idx2, idx3, idx4;
245                if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
246                        idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) +
247                            seed) % 6;
248                        idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15;
249                        idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) +
250                            (seed / 6)) % 6;
251                        retval[j++] = vowels[idx0];
252                        retval[j++] = consonants[idx1];
253                        retval[j++] = vowels[idx2];
254                        if ((i + 1) < rounds) {
255                                idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;
256                                idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15;
257                                retval[j++] = consonants[idx3];
258                                retval[j++] = '-';
259                                retval[j++] = consonants[idx4];
260                                seed = ((seed * 5) +
261                                    ((((u_int)(dgst_raw[2 * i])) * 7) +
262                                    ((u_int)(dgst_raw[(2 * i) + 1])))) % 36;
263                        }
264                } else {
265                        idx0 = seed % 6;
266                        idx1 = 16;
267                        idx2 = seed / 6;
268                        retval[j++] = vowels[idx0];
269                        retval[j++] = consonants[idx1];
270                        retval[j++] = vowels[idx2];
271                }
272        }
273        retval[j++] = 'x';
274        retval[j++] = '\0';
275        return retval;
276}
277
278char*
279key_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
280{
281        char *retval = NULL;
282        u_char *dgst_raw;
283        size_t dgst_raw_len;
284       
285        dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len);
286        if (!dgst_raw)
287                fatal("key_fingerprint: null from key_fingerprint_raw()");
288        switch(dgst_rep) {
289        case SSH_FP_HEX:
290                retval = key_fingerprint_hex(dgst_raw, dgst_raw_len);
291                break;
292        case SSH_FP_BUBBLEBABBLE:
293                retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
294                break;
295        default:
296                fatal("key_fingerprint_ex: bad digest representation %d",
297                    dgst_rep);
298                break;
299        }
300        memset(dgst_raw, 0, dgst_raw_len);
301        xfree(dgst_raw);
302        return retval;
303}
304
305/*
306 * Reads a multiple-precision integer in decimal from the buffer, and advances
307 * the pointer.  The integer must already be initialized.  This function is
308 * permitted to modify the buffer.  This leaves *cpp to point just beyond the
309 * last processed (and maybe modified) character.  Note that this may modify
310 * the buffer containing the number.
311 */
312static int
313read_bignum(char **cpp, BIGNUM * value)
314{
315        char *cp = *cpp;
316        int old;
317
318        /* Skip any leading whitespace. */
319        for (; *cp == ' ' || *cp == '\t'; cp++)
320                ;
321
322        /* Check that it begins with a decimal digit. */
323        if (*cp < '0' || *cp > '9')
324                return 0;
325
326        /* Save starting position. */
327        *cpp = cp;
328
329        /* Move forward until all decimal digits skipped. */
330        for (; *cp >= '0' && *cp <= '9'; cp++)
331                ;
332
333        /* Save the old terminating character, and replace it by \0. */
334        old = *cp;
335        *cp = 0;
336
337        /* Parse the number. */
338        if (BN_dec2bn(&value, *cpp) == 0)
339                return 0;
340
341        /* Restore old terminating character. */
342        *cp = old;
343
344        /* Move beyond the number and return success. */
345        *cpp = cp;
346        return 1;
347}
348static int
349write_bignum(FILE *f, BIGNUM *num)
350{
351        char *buf = BN_bn2dec(num);
352        if (buf == NULL) {
353                error("write_bignum: BN_bn2dec() failed");
354                return 0;
355        }
356        fprintf(f, " %s", buf);
357        xfree(buf);
358        return 1;
359}
360
361/* returns 1 ok, -1 error */
362int
363key_read(Key *ret, char **cpp)
364{
365        Key *k;
366        int success = -1;
367        char *cp, *space;
368        int len, n, type;
369        u_int bits;
370        u_char *blob;
371
372        cp = *cpp;
373
374        switch(ret->type) {
375        case KEY_RSA1:
376                /* Get number of bits. */
377                if (*cp < '0' || *cp > '9')
378                        return -1;      /* Bad bit count... */
379                for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
380                        bits = 10 * bits + *cp - '0';
381                if (bits == 0)
382                        return -1;
383                *cpp = cp;
384                /* Get public exponent, public modulus. */
385                if (!read_bignum(cpp, ret->rsa->e))
386                        return -1;
387                if (!read_bignum(cpp, ret->rsa->n))
388                        return -1;
389                success = 1;
390                break;
391        case KEY_UNSPEC:
392        case KEY_RSA:
393        case KEY_DSA:
394                space = strchr(cp, ' ');
395                if (space == NULL) {
396                        debug3("key_read: no space");
397                        return -1;
398                }
399                *space = '\0';
400                type = key_type_from_name(cp);
401                *space = ' ';
402                if (type == KEY_UNSPEC) {
403                        debug3("key_read: no key found");
404                        return -1;
405                }
406                cp = space+1;
407                if (*cp == '\0') {
408                        debug3("key_read: short string");
409                        return -1;
410                }
411                if (ret->type == KEY_UNSPEC) {
412                        ret->type = type;
413                } else if (ret->type != type) {
414                        /* is a key, but different type */
415                        debug3("key_read: type mismatch");
416                        return -1;
417                }
418                len = 2*strlen(cp);
419                blob = xmalloc(len);
420                n = uudecode(cp, blob, len);
421                if (n < 0) {
422                        error("key_read: uudecode %s failed", cp);
423                        return -1;
424                }
425                k = key_from_blob(blob, n);
426                if (k == NULL) {
427                        error("key_read: key_from_blob %s failed", cp);
428                        return -1;
429                }
430                xfree(blob);
431                if (k->type != type) {
432                        error("key_read: type mismatch: encoding error");
433                        key_free(k);
434                        return -1;
435                }
436/*XXXX*/
437                if (ret->type == KEY_RSA) {
438                        if (ret->rsa != NULL)
439                                RSA_free(ret->rsa);
440                        ret->rsa = k->rsa;
441                        k->rsa = NULL;
442                        success = 1;
443#ifdef DEBUG_PK
444                        RSA_print_fp(stderr, ret->rsa, 8);
445#endif
446                } else {
447                        if (ret->dsa != NULL)
448                                DSA_free(ret->dsa);
449                        ret->dsa = k->dsa;
450                        k->dsa = NULL;
451                        success = 1;
452#ifdef DEBUG_PK
453                        DSA_print_fp(stderr, ret->dsa, 8);
454#endif
455                }
456/*XXXX*/
457                if (success != 1)
458                        break;
459                key_free(k);
460                /* advance cp: skip whitespace and data */
461                while (*cp == ' ' || *cp == '\t')
462                        cp++;
463                while (*cp != '\0' && *cp != ' ' && *cp != '\t')
464                        cp++;
465                *cpp = cp;
466                break;
467        default:
468                fatal("key_read: bad key type: %d", ret->type);
469                break;
470        }
471        return success;
472}
473int
474key_write(Key *key, FILE *f)
475{
476        int success = 0;
477        u_int bits = 0;
478
479        if (key->type == KEY_RSA1 && key->rsa != NULL) {
480                /* size of modulus 'n' */
481                bits = BN_num_bits(key->rsa->n);
482                fprintf(f, "%u", bits);
483                if (write_bignum(f, key->rsa->e) &&
484                    write_bignum(f, key->rsa->n)) {
485                        success = 1;
486                } else {
487                        error("key_write: failed for RSA key");
488                }
489        } else if ((key->type == KEY_DSA && key->dsa != NULL) ||
490            (key->type == KEY_RSA && key->rsa != NULL)) {
491                int len, n;
492                u_char *blob, *uu;
493                key_to_blob(key, &blob, &len);
494                uu = xmalloc(2*len);
495                n = uuencode(blob, len, uu, 2*len);
496                if (n > 0) {
497                        fprintf(f, "%s %s", key_ssh_name(key), uu);
498                        success = 1;
499                }
500                xfree(blob);
501                xfree(uu);
502        }
503        return success;
504}
505char *
506key_type(Key *k)
507{
508        switch (k->type) {
509        case KEY_RSA1:
510                return "RSA1";
511                break;
512        case KEY_RSA:
513                return "RSA";
514                break;
515        case KEY_DSA:
516                return "DSA";
517                break;
518        }
519        return "unknown";
520}
521char *
522key_ssh_name(Key *k)
523{
524        switch (k->type) {
525        case KEY_RSA:
526                return "ssh-rsa";
527                break;
528        case KEY_DSA:
529                return "ssh-dss";
530                break;
531        }
532        return "ssh-unknown";
533}
534u_int
535key_size(Key *k){
536        switch (k->type) {
537        case KEY_RSA1:
538        case KEY_RSA:
539                return BN_num_bits(k->rsa->n);
540                break;
541        case KEY_DSA:
542                return BN_num_bits(k->dsa->p);
543                break;
544        }
545        return 0;
546}
547
548static RSA *
549rsa_generate_private_key(u_int bits)
550{
551        RSA *private;
552        private = RSA_generate_key(bits, 35, NULL, NULL);
553        if (private == NULL)
554                fatal("rsa_generate_private_key: key generation failed.");
555        return private;
556}
557
558static DSA*
559dsa_generate_private_key(u_int bits)
560{
561        DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
562        if (private == NULL)
563                fatal("dsa_generate_private_key: DSA_generate_parameters failed");
564        if (!DSA_generate_key(private))
565                fatal("dsa_generate_private_key: DSA_generate_key failed.");
566        if (private == NULL)
567                fatal("dsa_generate_private_key: NULL.");
568        return private;
569}
570
571Key *
572key_generate(int type, u_int bits)
573{
574        Key *k = key_new(KEY_UNSPEC);
575        switch (type) {
576        case KEY_DSA:
577                k->dsa = dsa_generate_private_key(bits);
578                break;
579        case KEY_RSA:
580        case KEY_RSA1:
581                k->rsa = rsa_generate_private_key(bits);
582                break;
583        default:
584                fatal("key_generate: unknown type %d", type);
585        }
586        k->type = type;
587        return k;
588}
589
590Key *
591key_from_private(Key *k)
592{
593        Key *n = NULL;
594        switch (k->type) {
595        case KEY_DSA:
596                n = key_new(k->type);
597                BN_copy(n->dsa->p, k->dsa->p);
598                BN_copy(n->dsa->q, k->dsa->q);
599                BN_copy(n->dsa->g, k->dsa->g);
600                BN_copy(n->dsa->pub_key, k->dsa->pub_key);
601                break;
602        case KEY_RSA:
603        case KEY_RSA1:
604                n = key_new(k->type);
605                BN_copy(n->rsa->n, k->rsa->n);
606                BN_copy(n->rsa->e, k->rsa->e);
607                break;
608        default:
609                fatal("key_from_private: unknown type %d", k->type);
610                break;
611        }
612        return n;
613}
614
615int
616key_type_from_name(char *name)
617{
618        if (strcmp(name, "rsa1") == 0){
619                return KEY_RSA1;
620        } else if (strcmp(name, "rsa") == 0){
621                return KEY_RSA;
622        } else if (strcmp(name, "dsa") == 0){
623                return KEY_DSA;
624        } else if (strcmp(name, "ssh-rsa") == 0){
625                return KEY_RSA;
626        } else if (strcmp(name, "ssh-dss") == 0){
627                return KEY_DSA;
628        }
629        debug2("key_type_from_name: unknown key type '%s'", name);
630        return KEY_UNSPEC;
631}
632
633int
634key_names_valid2(const char *names)
635{
636        char *s, *cp, *p;
637
638        if (names == NULL || strcmp(names, "") == 0)
639                return 0;
640        s = cp = xstrdup(names);
641        for ((p = strsep(&cp, ",")); p && *p != '\0';
642             (p = strsep(&cp, ","))) {
643                switch (key_type_from_name(p)) {
644                case KEY_RSA1:
645                case KEY_UNSPEC:
646                        xfree(s);
647                        return 0;
648                }
649        }
650        debug3("key names ok: [%s]", names);
651        xfree(s);
652        return 1;
653}
654
655Key *
656key_from_blob(u_char *blob, int blen)
657{
658        Buffer b;
659        char *ktype;
660        int rlen, type;
661        Key *key = NULL;
662
663#ifdef DEBUG_PK
664        dump_base64(stderr, blob, blen);
665#endif
666        buffer_init(&b);
667        buffer_append(&b, blob, blen);
668        ktype = buffer_get_string(&b, NULL);
669        type = key_type_from_name(ktype);
670
671        switch(type){
672        case KEY_RSA:
673                key = key_new(type);
674                buffer_get_bignum2(&b, key->rsa->e);
675                buffer_get_bignum2(&b, key->rsa->n);
676#ifdef DEBUG_PK
677                RSA_print_fp(stderr, key->rsa, 8);
678#endif
679                break;
680        case KEY_DSA:
681                key = key_new(type);
682                buffer_get_bignum2(&b, key->dsa->p);
683                buffer_get_bignum2(&b, key->dsa->q);
684                buffer_get_bignum2(&b, key->dsa->g);
685                buffer_get_bignum2(&b, key->dsa->pub_key);
686#ifdef DEBUG_PK
687                DSA_print_fp(stderr, key->dsa, 8);
688#endif
689                break;
690        case KEY_UNSPEC:
691                key = key_new(type);
692                break;
693        default:
694                error("key_from_blob: cannot handle type %s", ktype);
695                break;
696        }
697        rlen = buffer_len(&b);
698        if (key != NULL && rlen != 0)
699                error("key_from_blob: remaining bytes in key blob %d", rlen);
700        xfree(ktype);
701        buffer_free(&b);
702        return key;
703}
704
705int
706key_to_blob(Key *key, u_char **blobp, u_int *lenp)
707{
708        Buffer b;
709        int len;
710        u_char *buf;
711
712        if (key == NULL) {
713                error("key_to_blob: key == NULL");
714                return 0;
715        }
716        buffer_init(&b);
717        switch(key->type){
718        case KEY_DSA:
719                buffer_put_cstring(&b, key_ssh_name(key));
720                buffer_put_bignum2(&b, key->dsa->p);
721                buffer_put_bignum2(&b, key->dsa->q);
722                buffer_put_bignum2(&b, key->dsa->g);
723                buffer_put_bignum2(&b, key->dsa->pub_key);
724                break;
725        case KEY_RSA:
726                buffer_put_cstring(&b, key_ssh_name(key));
727                buffer_put_bignum2(&b, key->rsa->e);
728                buffer_put_bignum2(&b, key->rsa->n);
729                break;
730        default:
731                error("key_to_blob: unsupported key type %d", key->type);
732                buffer_free(&b);
733                return 0;
734        }
735        len = buffer_len(&b);
736        buf = xmalloc(len);
737        memcpy(buf, buffer_ptr(&b), len);
738        memset(buffer_ptr(&b), 0, len);
739        buffer_free(&b);
740        if (lenp != NULL)
741                *lenp = len;
742        if (blobp != NULL)
743                *blobp = buf;
744        return len;
745}
746
747int
748key_sign(
749    Key *key,
750    u_char **sigp, int *lenp,
751    u_char *data, int datalen)
752{
753        switch(key->type){
754        case KEY_DSA:
755                return ssh_dss_sign(key, sigp, lenp, data, datalen);
756                break;
757        case KEY_RSA:
758                return ssh_rsa_sign(key, sigp, lenp, data, datalen);
759                break;
760        default:
761                error("key_sign: illegal key type %d", key->type);
762                return -1;
763                break;
764        }
765}
766
767int
768key_verify(
769    Key *key,
770    u_char *signature, int signaturelen,
771    u_char *data, int datalen)
772{
773        if (signaturelen == 0)
774                return -1;
775
776        switch(key->type){
777        case KEY_DSA:
778                return ssh_dss_verify(key, signature, signaturelen, data, datalen);
779                break;
780        case KEY_RSA:
781                return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
782                break;
783        default:
784                error("key_verify: illegal key type %d", key->type);
785                return -1;
786                break;
787        }
788}
Note: See TracBrowser for help on using the repository browser.