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