]> andersk Git - openssh.git/blame - key.c
- jakob@cvs.openbsd.org 2001/03/11 15:04:16
[openssh.git] / key.c
CommitLineData
4fe2af09 1/*
bcbf86ec 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 *
4fe2af09 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.
4fe2af09 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 */
4fe2af09 34#include "includes.h"
301e8e5b 35RCSID("$OpenBSD: key.c,v 1.19 2001/03/11 15:03:15 jakob Exp $");
42f11eb2 36
4fe2af09 37#include <openssl/evp.h>
42f11eb2 38
4fe2af09 39#include "xmalloc.h"
40#include "key.h"
fa08c86b 41#include "rsa.h"
42#include "ssh-dss.h"
43#include "ssh-rsa.h"
a306f2dd 44#include "uuencode.h"
fa08c86b 45#include "buffer.h"
46#include "bufaux.h"
42f11eb2 47#include "log.h"
4fe2af09 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;
a306f2dd 57 k->dsa = NULL;
58 k->rsa = NULL;
4fe2af09 59 switch (k->type) {
fa08c86b 60 case KEY_RSA1:
4fe2af09 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;
fa08c86b 75 case KEY_UNSPEC:
4fe2af09 76 break;
77 default:
78 fatal("key_new: bad key type %d", k->type);
79 break;
80 }
81 return k;
82}
fa08c86b 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}
4fe2af09 107void
108key_free(Key *k)
109{
110 switch (k->type) {
fa08c86b 111 case KEY_RSA1:
4fe2af09 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;
fa08c86b 122 case KEY_UNSPEC:
123 break;
4fe2af09 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) {
fa08c86b 136 case KEY_RSA1:
4fe2af09 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:
a306f2dd 150 fatal("key_equal: bad key type %d", a->type);
4fe2af09 151 break;
152 }
153 return 0;
154}
155
301e8e5b 156u_char*
157key_fingerprint_raw(Key *k, enum fp_type dgst_type, size_t *dgst_raw_length)
4fe2af09 158{
1e3b8b07 159 u_char *blob = NULL;
301e8e5b 160 u_char *retval = NULL;
4fe2af09 161 int len = 0;
a306f2dd 162 int nlen, elen;
4fe2af09 163
301e8e5b 164 *dgst_raw_length = 0;
165
4fe2af09 166 switch (k->type) {
fa08c86b 167 case KEY_RSA1:
4fe2af09 168 nlen = BN_num_bytes(k->rsa->n);
169 elen = BN_num_bytes(k->rsa->e);
170 len = nlen + elen;
a306f2dd 171 blob = xmalloc(len);
172 BN_bn2bin(k->rsa->n, blob);
173 BN_bn2bin(k->rsa->e, blob + nlen);
4fe2af09 174 break;
175 case KEY_DSA:
fa08c86b 176 case KEY_RSA:
177 key_to_blob(k, &blob, &len);
178 break;
179 case KEY_UNSPEC:
180 return retval;
4fe2af09 181 break;
182 default:
301e8e5b 183 fatal("key_fingerprint_raw: bad key type %d", k->type);
4fe2af09 184 break;
185 }
a306f2dd 186 if (blob != NULL) {
301e8e5b 187 EVP_MD *md = NULL;
74fc9186 188 EVP_MD_CTX ctx;
301e8e5b 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
74fc9186 204 EVP_DigestInit(&ctx, md);
205 EVP_DigestUpdate(&ctx, blob, len);
301e8e5b 206 EVP_DigestFinal(&ctx, retval, NULL);
207 *dgst_raw_length = md->md_size;
a306f2dd 208 memset(blob, 0, len);
209 xfree(blob);
301e8e5b 210 } else {
211 fatal("key_fingerprint_raw: blob is null");
4fe2af09 212 }
213 return retval;
214}
215
301e8e5b 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
4fe2af09 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);
53a24016 373 xfree(buf);
4fe2af09 374 return 1;
375}
fa08c86b 376
377/* returns 1 ok, -1 error, 0 type mismatch */
378int
a306f2dd 379key_read(Key *ret, char **cpp)
4fe2af09 380{
a306f2dd 381 Key *k;
fa08c86b 382 int success = -1;
383 char *cp, *space;
384 int len, n, type;
385 u_int bits;
1e3b8b07 386 u_char *blob;
a306f2dd 387
388 cp = *cpp;
389
4fe2af09 390 switch(ret->type) {
fa08c86b 391 case KEY_RSA1:
a306f2dd 392 /* Get number of bits. */
393 if (*cp < '0' || *cp > '9')
fa08c86b 394 return -1; /* Bad bit count... */
a306f2dd 395 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
396 bits = 10 * bits + *cp - '0';
4fe2af09 397 if (bits == 0)
fa08c86b 398 return -1;
a306f2dd 399 *cpp = cp;
4fe2af09 400 /* Get public exponent, public modulus. */
401 if (!read_bignum(cpp, ret->rsa->e))
fa08c86b 402 return -1;
4fe2af09 403 if (!read_bignum(cpp, ret->rsa->n))
fa08c86b 404 return -1;
405 success = 1;
4fe2af09 406 break;
fa08c86b 407 case KEY_UNSPEC:
408 case KEY_RSA:
4fe2af09 409 case KEY_DSA:
fa08c86b 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");
4fe2af09 432 return 0;
fa08c86b 433 }
a306f2dd 434 len = 2*strlen(cp);
435 blob = xmalloc(len);
436 n = uudecode(cp, blob, len);
1d1ffb87 437 if (n < 0) {
71276795 438 error("key_read: uudecode %s failed", cp);
fa08c86b 439 return -1;
1d1ffb87 440 }
fa08c86b 441 k = key_from_blob(blob, n);
71276795 442 if (k == NULL) {
fa08c86b 443 error("key_read: key_from_blob %s failed", cp);
444 return -1;
71276795 445 }
a306f2dd 446 xfree(blob);
fa08c86b 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;
a306f2dd 475 key_free(k);
71276795 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;
4fe2af09 482 break;
483 default:
a306f2dd 484 fatal("key_read: bad key type: %d", ret->type);
4fe2af09 485 break;
486 }
fa08c86b 487 return success;
4fe2af09 488}
489int
490key_write(Key *key, FILE *f)
491{
492 int success = 0;
1e3b8b07 493 u_int bits = 0;
4fe2af09 494
fa08c86b 495 if (key->type == KEY_RSA1 && key->rsa != NULL) {
4fe2af09 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 }
fa08c86b 505 } else if ((key->type == KEY_DSA && key->dsa != NULL) ||
506 (key->type == KEY_RSA && key->rsa != NULL)) {
a306f2dd 507 int len, n;
1e3b8b07 508 u_char *blob, *uu;
fa08c86b 509 key_to_blob(key, &blob, &len);
a306f2dd 510 uu = xmalloc(2*len);
1d1ffb87 511 n = uuencode(blob, len, uu, 2*len);
512 if (n > 0) {
fa08c86b 513 fprintf(f, "%s %s", key_ssh_name(key), uu);
1d1ffb87 514 success = 1;
515 }
a306f2dd 516 xfree(blob);
517 xfree(uu);
4fe2af09 518 }
519 return success;
520}
1d1ffb87 521char *
522key_type(Key *k)
523{
524 switch (k->type) {
fa08c86b 525 case KEY_RSA1:
526 return "RSA1";
527 break;
1d1ffb87 528 case KEY_RSA:
529 return "RSA";
530 break;
531 case KEY_DSA:
532 return "DSA";
533 break;
534 }
535 return "unknown";
536}
fa08c86b 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
2e73a022 551key_size(Key *k){
552 switch (k->type) {
fa08c86b 553 case KEY_RSA1:
2e73a022 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}
fa08c86b 563
564RSA *
1e3b8b07 565rsa_generate_private_key(u_int bits)
fa08c86b 566{
2b87da3b 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;
fa08c86b 572}
573
574DSA*
1e3b8b07 575dsa_generate_private_key(u_int bits)
fa08c86b 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))
2b87da3b 581 fatal("dsa_generate_private_key: DSA_generate_key failed.");
582 if (private == NULL)
583 fatal("dsa_generate_private_key: NULL.");
fa08c86b 584 return private;
585}
586
587Key *
1e3b8b07 588key_generate(int type, u_int bits)
fa08c86b 589{
590 Key *k = key_new(KEY_UNSPEC);
591 switch (type) {
2b87da3b 592 case KEY_DSA:
fa08c86b 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:
2b87da3b 600 fatal("key_generate: unknown type %d", type);
fa08c86b 601 }
2b87da3b 602 k->type = type;
fa08c86b 603 return k;
604}
605
606Key *
607key_from_private(Key *k)
608{
609 Key *n = NULL;
610 switch (k->type) {
2b87da3b 611 case KEY_DSA:
fa08c86b 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:
2b87da3b 625 fatal("key_from_private: unknown type %d", k->type);
fa08c86b 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 }
539af7f5 645 debug2("key_type_from_name: unknown key type '%s'", name);
fa08c86b 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);
fa08c86b 668 buffer_get_bignum2(&b, key->rsa->e);
b5c334cc 669 buffer_get_bignum2(&b, key->rsa->n);
fa08c86b 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
1e3b8b07 700key_to_blob(Key *key, u_char **blobp, u_int *lenp)
fa08c86b 701{
702 Buffer b;
703 int len;
1e3b8b07 704 u_char *buf;
fa08c86b 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));
fa08c86b 721 buffer_put_bignum2(&b, key->rsa->e);
b5c334cc 722 buffer_put_bignum2(&b, key->rsa->n);
fa08c86b 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,
1e3b8b07 743 u_char **sigp, int *lenp,
744 u_char *data, int datalen)
fa08c86b 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,
1e3b8b07 763 u_char *signature, int signaturelen,
764 u_char *data, int datalen)
fa08c86b 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.195686 seconds and 5 git commands to generate.