]> andersk Git - openssh.git/blame_incremental - key.c
- jakob@cvs.openbsd.org 2001/03/11 15:04:16
[openssh.git] / key.c
... / ...
CommitLineData
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"
35RCSID("$OpenBSD: key.c,v 1.19 2001/03/11 15:03:15 jakob 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->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}
83Key *
84key_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}
107void
108key_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}
130int
131key_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
156u_char*
157key_fingerprint_raw(Key *k, enum fp_type dgst_type, size_t *dgst_raw_length)
158{
159 u_char *blob = NULL;
160 u_char *retval = NULL;
161 int len = 0;
162 int nlen, elen;
163
164 *dgst_raw_length = 0;
165
166 switch (k->type) {
167 case KEY_RSA1:
168 nlen = BN_num_bytes(k->rsa->n);
169 elen = BN_num_bytes(k->rsa->e);
170 len = nlen + elen;
171 blob = xmalloc(len);
172 BN_bn2bin(k->rsa->n, blob);
173 BN_bn2bin(k->rsa->e, blob + nlen);
174 break;
175 case KEY_DSA:
176 case KEY_RSA:
177 key_to_blob(k, &blob, &len);
178 break;
179 case KEY_UNSPEC:
180 return retval;
181 break;
182 default:
183 fatal("key_fingerprint_raw: bad key type %d", k->type);
184 break;
185 }
186 if (blob != NULL) {
187 EVP_MD *md = NULL;
188 EVP_MD_CTX ctx;
189
190 retval = xmalloc(EVP_MAX_MD_SIZE);
191
192 switch (dgst_type) {
193 case SSH_FP_MD5:
194 md = EVP_md5();
195 break;
196 case SSH_FP_SHA1:
197 md = EVP_sha1();
198 break;
199 default:
200 fatal("key_fingerprint_raw: bad digest type %d",
201 dgst_type);
202 }
203
204 EVP_DigestInit(&ctx, md);
205 EVP_DigestUpdate(&ctx, blob, len);
206 EVP_DigestFinal(&ctx, retval, NULL);
207 *dgst_raw_length = md->md_size;
208 memset(blob, 0, len);
209 xfree(blob);
210 } else {
211 fatal("key_fingerprint_raw: blob is null");
212 }
213 return retval;
214}
215
216char*
217key_fingerprint_hex(u_char* dgst_raw, size_t dgst_raw_len)
218{
219 char *retval;
220 int i;
221
222 retval = xmalloc(dgst_raw_len * 3);
223 retval[0] = '\0';
224 for(i = 0; i < dgst_raw_len; i++) {
225 char hex[4];
226 snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
227 strlcat(retval, hex, dgst_raw_len * 3);
228 }
229 retval[(dgst_raw_len * 3) - 1] = '\0';
230 return retval;
231}
232
233char*
234key_fingerprint_bubblebabble(u_char* dgst_raw, size_t dgst_raw_len)
235{
236 char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
237 char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
238 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
239 u_int rounds, idx, retval_idx, seed;
240 char *retval;
241
242 rounds = (dgst_raw_len / 2) + 1;
243 retval = xmalloc(sizeof(char) * (rounds*6));
244 seed = 1;
245 retval_idx = 0;
246 retval[retval_idx++] = 'x';
247 for (idx=0;idx<rounds;idx++) {
248 u_int idx0, idx1, idx2, idx3, idx4;
249 if ((idx + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
250 idx0 = (((((u_int)(dgst_raw[2 * idx])) >> 6) & 3) +
251 seed) % 6;
252 idx1 = (((u_int)(dgst_raw[2 * idx])) >> 2) & 15;
253 idx2 = ((((u_int)(dgst_raw[2 * idx])) & 3) +
254 (seed / 6)) % 6;
255 retval[retval_idx++] = vowels[idx0];
256 retval[retval_idx++] = consonants[idx1];
257 retval[retval_idx++] = vowels[idx2];
258 if ((idx + 1) < rounds) {
259 idx3 = (((u_int)(dgst_raw[(2 * idx) + 1])) >> 4) & 15;
260 idx4 = (((u_int)(dgst_raw[(2 * idx) + 1]))) & 15;
261 retval[retval_idx++] = consonants[idx3];
262 retval[retval_idx++] = '-';
263 retval[retval_idx++] = consonants[idx4];
264 seed = ((seed * 5) +
265 ((((u_int)(dgst_raw[2 * idx])) * 7) +
266 ((u_int)(dgst_raw[(2 * idx) + 1])))) % 36;
267 }
268 } else {
269 idx0 = seed % 6;
270 idx1 = 16;
271 idx2 = seed / 6;
272 retval[retval_idx++] = vowels[idx0];
273 retval[retval_idx++] = consonants[idx1];
274 retval[retval_idx++] = vowels[idx2];
275 }
276 }
277 retval[retval_idx++] = 'x';
278 retval[retval_idx++] = '\0';
279 return retval;
280}
281
282char*
283key_fingerprint_ex(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
284{
285 char *retval = NULL;
286 u_char *dgst_raw;
287 size_t dgst_raw_len;
288
289 dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len);
290 if (!dgst_raw)
291 fatal("key_fingerprint_ex: null value returned from key_fingerprint_raw()");
292 switch(dgst_rep) {
293 case SSH_FP_HEX:
294 retval = key_fingerprint_hex(dgst_raw, dgst_raw_len);
295 break;
296 case SSH_FP_BUBBLEBABBLE:
297 retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
298 break;
299 default:
300 fatal("key_fingerprint_ex: bad digest representation %d",
301 dgst_rep);
302 break;
303 }
304 memset(dgst_raw, 0, dgst_raw_len);
305 xfree(dgst_raw);
306 return retval;
307}
308
309char *
310key_fingerprint(Key *k)
311{
312 static char retval[(EVP_MAX_MD_SIZE + 1) * 3];
313 char *digest;
314
315 digest = key_fingerprint_ex(k, SSH_FP_MD5, SSH_FP_HEX);
316 strlcpy(retval, digest, sizeof(retval));
317 xfree(digest);
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 */
328int
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}
364int
365write_bignum(FILE *f, BIGNUM *num)
366{
367 char *buf = BN_bn2dec(num);
368 if (buf == NULL) {
369 error("write_bignum: BN_bn2dec() failed");
370 return 0;
371 }
372 fprintf(f, " %s", buf);
373 xfree(buf);
374 return 1;
375}
376
377/* returns 1 ok, -1 error, 0 type mismatch */
378int
379key_read(Key *ret, char **cpp)
380{
381 Key *k;
382 int success = -1;
383 char *cp, *space;
384 int len, n, type;
385 u_int bits;
386 u_char *blob;
387
388 cp = *cpp;
389
390 switch(ret->type) {
391 case KEY_RSA1:
392 /* Get number of bits. */
393 if (*cp < '0' || *cp > '9')
394 return -1; /* Bad bit count... */
395 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
396 bits = 10 * bits + *cp - '0';
397 if (bits == 0)
398 return -1;
399 *cpp = cp;
400 /* Get public exponent, public modulus. */
401 if (!read_bignum(cpp, ret->rsa->e))
402 return -1;
403 if (!read_bignum(cpp, ret->rsa->n))
404 return -1;
405 success = 1;
406 break;
407 case KEY_UNSPEC:
408 case KEY_RSA:
409 case KEY_DSA:
410 space = strchr(cp, ' ');
411 if (space == NULL) {
412 debug3("key_read: no space");
413 return -1;
414 }
415 *space = '\0';
416 type = key_type_from_name(cp);
417 *space = ' ';
418 if (type == KEY_UNSPEC) {
419 debug3("key_read: no key found");
420 return -1;
421 }
422 cp = space+1;
423 if (*cp == '\0') {
424 debug3("key_read: short string");
425 return -1;
426 }
427 if (ret->type == KEY_UNSPEC) {
428 ret->type = type;
429 } else if (ret->type != type) {
430 /* is a key, but different type */
431 debug3("key_read: type mismatch");
432 return 0;
433 }
434 len = 2*strlen(cp);
435 blob = xmalloc(len);
436 n = uudecode(cp, blob, len);
437 if (n < 0) {
438 error("key_read: uudecode %s failed", cp);
439 return -1;
440 }
441 k = key_from_blob(blob, n);
442 if (k == NULL) {
443 error("key_read: key_from_blob %s failed", cp);
444 return -1;
445 }
446 xfree(blob);
447 if (k->type != type) {
448 error("key_read: type mismatch: encoding error");
449 key_free(k);
450 return -1;
451 }
452/*XXXX*/
453 if (ret->type == KEY_RSA) {
454 if (ret->rsa != NULL)
455 RSA_free(ret->rsa);
456 ret->rsa = k->rsa;
457 k->rsa = NULL;
458 success = 1;
459#ifdef DEBUG_PK
460 RSA_print_fp(stderr, ret->rsa, 8);
461#endif
462 } else {
463 if (ret->dsa != NULL)
464 DSA_free(ret->dsa);
465 ret->dsa = k->dsa;
466 k->dsa = NULL;
467 success = 1;
468#ifdef DEBUG_PK
469 DSA_print_fp(stderr, ret->dsa, 8);
470#endif
471 }
472/*XXXX*/
473 if (success != 1)
474 break;
475 key_free(k);
476 /* advance cp: skip whitespace and data */
477 while (*cp == ' ' || *cp == '\t')
478 cp++;
479 while (*cp != '\0' && *cp != ' ' && *cp != '\t')
480 cp++;
481 *cpp = cp;
482 break;
483 default:
484 fatal("key_read: bad key type: %d", ret->type);
485 break;
486 }
487 return success;
488}
489int
490key_write(Key *key, FILE *f)
491{
492 int success = 0;
493 u_int bits = 0;
494
495 if (key->type == KEY_RSA1 && key->rsa != NULL) {
496 /* size of modulus 'n' */
497 bits = BN_num_bits(key->rsa->n);
498 fprintf(f, "%u", bits);
499 if (write_bignum(f, key->rsa->e) &&
500 write_bignum(f, key->rsa->n)) {
501 success = 1;
502 } else {
503 error("key_write: failed for RSA key");
504 }
505 } else if ((key->type == KEY_DSA && key->dsa != NULL) ||
506 (key->type == KEY_RSA && key->rsa != NULL)) {
507 int len, n;
508 u_char *blob, *uu;
509 key_to_blob(key, &blob, &len);
510 uu = xmalloc(2*len);
511 n = uuencode(blob, len, uu, 2*len);
512 if (n > 0) {
513 fprintf(f, "%s %s", key_ssh_name(key), uu);
514 success = 1;
515 }
516 xfree(blob);
517 xfree(uu);
518 }
519 return success;
520}
521char *
522key_type(Key *k)
523{
524 switch (k->type) {
525 case KEY_RSA1:
526 return "RSA1";
527 break;
528 case KEY_RSA:
529 return "RSA";
530 break;
531 case KEY_DSA:
532 return "DSA";
533 break;
534 }
535 return "unknown";
536}
537char *
538key_ssh_name(Key *k)
539{
540 switch (k->type) {
541 case KEY_RSA:
542 return "ssh-rsa";
543 break;
544 case KEY_DSA:
545 return "ssh-dss";
546 break;
547 }
548 return "ssh-unknown";
549}
550u_int
551key_size(Key *k){
552 switch (k->type) {
553 case KEY_RSA1:
554 case KEY_RSA:
555 return BN_num_bits(k->rsa->n);
556 break;
557 case KEY_DSA:
558 return BN_num_bits(k->dsa->p);
559 break;
560 }
561 return 0;
562}
563
564RSA *
565rsa_generate_private_key(u_int bits)
566{
567 RSA *private;
568 private = RSA_generate_key(bits, 35, NULL, NULL);
569 if (private == NULL)
570 fatal("rsa_generate_private_key: key generation failed.");
571 return private;
572}
573
574DSA*
575dsa_generate_private_key(u_int bits)
576{
577 DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
578 if (private == NULL)
579 fatal("dsa_generate_private_key: DSA_generate_parameters failed");
580 if (!DSA_generate_key(private))
581 fatal("dsa_generate_private_key: DSA_generate_key failed.");
582 if (private == NULL)
583 fatal("dsa_generate_private_key: NULL.");
584 return private;
585}
586
587Key *
588key_generate(int type, u_int bits)
589{
590 Key *k = key_new(KEY_UNSPEC);
591 switch (type) {
592 case KEY_DSA:
593 k->dsa = dsa_generate_private_key(bits);
594 break;
595 case KEY_RSA:
596 case KEY_RSA1:
597 k->rsa = rsa_generate_private_key(bits);
598 break;
599 default:
600 fatal("key_generate: unknown type %d", type);
601 }
602 k->type = type;
603 return k;
604}
605
606Key *
607key_from_private(Key *k)
608{
609 Key *n = NULL;
610 switch (k->type) {
611 case KEY_DSA:
612 n = key_new(k->type);
613 BN_copy(n->dsa->p, k->dsa->p);
614 BN_copy(n->dsa->q, k->dsa->q);
615 BN_copy(n->dsa->g, k->dsa->g);
616 BN_copy(n->dsa->pub_key, k->dsa->pub_key);
617 break;
618 case KEY_RSA:
619 case KEY_RSA1:
620 n = key_new(k->type);
621 BN_copy(n->rsa->n, k->rsa->n);
622 BN_copy(n->rsa->e, k->rsa->e);
623 break;
624 default:
625 fatal("key_from_private: unknown type %d", k->type);
626 break;
627 }
628 return n;
629}
630
631int
632key_type_from_name(char *name)
633{
634 if (strcmp(name, "rsa1") == 0){
635 return KEY_RSA1;
636 } else if (strcmp(name, "rsa") == 0){
637 return KEY_RSA;
638 } else if (strcmp(name, "dsa") == 0){
639 return KEY_DSA;
640 } else if (strcmp(name, "ssh-rsa") == 0){
641 return KEY_RSA;
642 } else if (strcmp(name, "ssh-dss") == 0){
643 return KEY_DSA;
644 }
645 debug2("key_type_from_name: unknown key type '%s'", name);
646 return KEY_UNSPEC;
647}
648
649Key *
650key_from_blob(char *blob, int blen)
651{
652 Buffer b;
653 char *ktype;
654 int rlen, type;
655 Key *key = NULL;
656
657#ifdef DEBUG_PK
658 dump_base64(stderr, blob, blen);
659#endif
660 buffer_init(&b);
661 buffer_append(&b, blob, blen);
662 ktype = buffer_get_string(&b, NULL);
663 type = key_type_from_name(ktype);
664
665 switch(type){
666 case KEY_RSA:
667 key = key_new(type);
668 buffer_get_bignum2(&b, key->rsa->e);
669 buffer_get_bignum2(&b, key->rsa->n);
670#ifdef DEBUG_PK
671 RSA_print_fp(stderr, key->rsa, 8);
672#endif
673 break;
674 case KEY_DSA:
675 key = key_new(type);
676 buffer_get_bignum2(&b, key->dsa->p);
677 buffer_get_bignum2(&b, key->dsa->q);
678 buffer_get_bignum2(&b, key->dsa->g);
679 buffer_get_bignum2(&b, key->dsa->pub_key);
680#ifdef DEBUG_PK
681 DSA_print_fp(stderr, key->dsa, 8);
682#endif
683 break;
684 case KEY_UNSPEC:
685 key = key_new(type);
686 break;
687 default:
688 error("key_from_blob: cannot handle type %s", ktype);
689 break;
690 }
691 rlen = buffer_len(&b);
692 if (key != NULL && rlen != 0)
693 error("key_from_blob: remaining bytes in key blob %d", rlen);
694 xfree(ktype);
695 buffer_free(&b);
696 return key;
697}
698
699int
700key_to_blob(Key *key, u_char **blobp, u_int *lenp)
701{
702 Buffer b;
703 int len;
704 u_char *buf;
705
706 if (key == NULL) {
707 error("key_to_blob: key == NULL");
708 return 0;
709 }
710 buffer_init(&b);
711 switch(key->type){
712 case KEY_DSA:
713 buffer_put_cstring(&b, key_ssh_name(key));
714 buffer_put_bignum2(&b, key->dsa->p);
715 buffer_put_bignum2(&b, key->dsa->q);
716 buffer_put_bignum2(&b, key->dsa->g);
717 buffer_put_bignum2(&b, key->dsa->pub_key);
718 break;
719 case KEY_RSA:
720 buffer_put_cstring(&b, key_ssh_name(key));
721 buffer_put_bignum2(&b, key->rsa->e);
722 buffer_put_bignum2(&b, key->rsa->n);
723 break;
724 default:
725 error("key_to_blob: illegal key type %d", key->type);
726 break;
727 }
728 len = buffer_len(&b);
729 buf = xmalloc(len);
730 memcpy(buf, buffer_ptr(&b), len);
731 memset(buffer_ptr(&b), 0, len);
732 buffer_free(&b);
733 if (lenp != NULL)
734 *lenp = len;
735 if (blobp != NULL)
736 *blobp = buf;
737 return len;
738}
739
740int
741key_sign(
742 Key *key,
743 u_char **sigp, int *lenp,
744 u_char *data, int datalen)
745{
746 switch(key->type){
747 case KEY_DSA:
748 return ssh_dss_sign(key, sigp, lenp, data, datalen);
749 break;
750 case KEY_RSA:
751 return ssh_rsa_sign(key, sigp, lenp, data, datalen);
752 break;
753 default:
754 error("key_sign: illegal key type %d", key->type);
755 return -1;
756 break;
757 }
758}
759
760int
761key_verify(
762 Key *key,
763 u_char *signature, int signaturelen,
764 u_char *data, int datalen)
765{
766 switch(key->type){
767 case KEY_DSA:
768 return ssh_dss_verify(key, signature, signaturelen, data, datalen);
769 break;
770 case KEY_RSA:
771 return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
772 break;
773 default:
774 error("key_verify: illegal key type %d", key->type);
775 return -1;
776 break;
777 }
778}
This page took 0.117772 seconds and 5 git commands to generate.