Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4539 - (show annotations) (download) (as text)
Wed Jul 27 08:50:14 2011 UTC (12 years, 8 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 27450 byte(s)
SSHFP 検証を ECDSA 鍵、および SHA256 ダイジェストに対応させた
http://tools.ietf.org/html/draft-os-ietf-sshfp-ecdsa-sha2-00

1 /*
2 Copyright (c) 2011, TeraTerm Project
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8 Redistributions of source code must retain the above copyright notice, this list of
9 conditions and the following disclaimer.
10
11 Redistributions in binary form must reproduce the above copyright notice, this list
12 of conditions and the following disclaimer in the documentation and/or other materials
13 provided with the distribution.
14
15 The name of Robert O'Callahan may not be used to endorse or promote products derived from
16 this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "key.h"
30 #include "kex.h"
31
32 #include <openssl/rsa.h>
33 #include <openssl/dsa.h>
34 #include <openssl/ecdsa.h>
35
36 #define INTBLOB_LEN 20
37 #define SIGBLOB_LEN (2*INTBLOB_LEN)
38
39 //////////////////////////////////////////////////////////////////////////////
40 //
41 // Key verify function
42 //
43 //////////////////////////////////////////////////////////////////////////////
44
45 //
46 // DSS
47 //
48
49 int ssh_dss_verify(DSA *key,
50 u_char *signature, u_int signaturelen,
51 u_char *data, u_int datalen)
52 {
53 DSA_SIG *sig;
54 const EVP_MD *evp_md = EVP_sha1();
55 EVP_MD_CTX md;
56 unsigned char digest[EVP_MAX_MD_SIZE], *sigblob;
57 unsigned int len, dlen;
58 int ret;
59 char *ptr;
60
61 OpenSSL_add_all_digests();
62
63 if (key == NULL) {
64 return -2;
65 }
66
67 ptr = signature;
68
69 // step1
70 if (signaturelen == 0x28) {
71 // workaround for SSH-2.0-2.0* and SSH-2.0-2.1* (2006.11.18 maya)
72 ptr -= 4;
73 }
74 else {
75 len = get_uint32_MSBfirst(ptr);
76 ptr += 4;
77 if (strncmp("ssh-dss", ptr, len) != 0) {
78 return -3;
79 }
80 ptr += len;
81 }
82
83 // step2
84 len = get_uint32_MSBfirst(ptr);
85 ptr += 4;
86 sigblob = ptr;
87 ptr += len;
88
89 if (len != SIGBLOB_LEN) {
90 return -4;
91 }
92
93 /* parse signature */
94 if ((sig = DSA_SIG_new()) == NULL)
95 return -5;
96 if ((sig->r = BN_new()) == NULL)
97 return -6;
98 if ((sig->s = BN_new()) == NULL)
99 return -7;
100 BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
101 BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
102
103 /* sha1 the data */
104 EVP_DigestInit(&md, evp_md);
105 EVP_DigestUpdate(&md, data, datalen);
106 EVP_DigestFinal(&md, digest, &dlen);
107
108 ret = DSA_do_verify(digest, dlen, sig, key);
109 memset(digest, 'd', sizeof(digest));
110
111 DSA_SIG_free(sig);
112
113 return ret;
114 }
115
116
117 //
118 // RSA
119 //
120
121 /*
122 * See:
123 * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
124 * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
125 */
126 /*
127 * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
128 * oiw(14) secsig(3) algorithms(2) 26 }
129 */
130 static const u_char id_sha1[] = {
131 0x30, 0x21, /* type Sequence, length 0x21 (33) */
132 0x30, 0x09, /* type Sequence, length 0x09 */
133 0x06, 0x05, /* type OID, length 0x05 */
134 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
135 0x05, 0x00, /* NULL */
136 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
137 };
138 /*
139 * id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
140 * rsadsi(113549) digestAlgorithm(2) 5 }
141 */
142 static const u_char id_md5[] = {
143 0x30, 0x20, /* type Sequence, length 0x20 (32) */
144 0x30, 0x0c, /* type Sequence, length 0x09 */
145 0x06, 0x08, /* type OID, length 0x05 */
146 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */
147 0x05, 0x00, /* NULL */
148 0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */
149 };
150
151 static int openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
152 u_char *sigbuf, u_int siglen, RSA *rsa)
153 {
154 u_int ret, rsasize, oidlen = 0, hlen = 0;
155 int len;
156 const u_char *oid = NULL;
157 u_char *decrypted = NULL;
158
159 ret = 0;
160 switch (type) {
161 case NID_sha1:
162 oid = id_sha1;
163 oidlen = sizeof(id_sha1);
164 hlen = 20;
165 break;
166 case NID_md5:
167 oid = id_md5;
168 oidlen = sizeof(id_md5);
169 hlen = 16;
170 break;
171 default:
172 goto done;
173 break;
174 }
175 if (hashlen != hlen) {
176 //error("bad hashlen");
177 goto done;
178 }
179 rsasize = RSA_size(rsa);
180 if (siglen == 0 || siglen > rsasize) {
181 //error("bad siglen");
182 goto done;
183 }
184 decrypted = malloc(rsasize);
185 if (decrypted == NULL)
186 return 1; // error
187
188 if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
189 RSA_PKCS1_PADDING)) < 0) {
190 //error("RSA_public_decrypt failed: %s",
191 // ERR_error_string(ERR_get_error(), NULL));
192 goto done;
193 }
194 if (len != hlen + oidlen) {
195 //error("bad decrypted len: %d != %d + %d", len, hlen, oidlen);
196 goto done;
197 }
198 if (memcmp(decrypted, oid, oidlen) != 0) {
199 //error("oid mismatch");
200 goto done;
201 }
202 if (memcmp(decrypted + oidlen, hash, hlen) != 0) {
203 //error("hash mismatch");
204 goto done;
205 }
206 ret = 1;
207 done:
208 if (decrypted)
209 free(decrypted);
210 return ret;
211 }
212
213 int ssh_rsa_verify(RSA *key,
214 u_char *signature, u_int signaturelen,
215 u_char *data, u_int datalen)
216 {
217 const EVP_MD *evp_md;
218 EVP_MD_CTX md;
219 // char *ktype;
220 u_char digest[EVP_MAX_MD_SIZE], *sigblob;
221 u_int len, dlen, modlen;
222 // int rlen, ret, nid;
223 int ret, nid;
224 char *ptr;
225
226 OpenSSL_add_all_digests();
227
228 if (key == NULL) {
229 return -2;
230 }
231 if (BN_num_bits(key->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
232 return -3;
233 }
234 //debug_print(41, signature, signaturelen);
235 ptr = signature;
236
237 // step1
238 len = get_uint32_MSBfirst(ptr);
239 ptr += 4;
240 if (strncmp("ssh-rsa", ptr, len) != 0) {
241 return -4;
242 }
243 ptr += len;
244
245 // step2
246 len = get_uint32_MSBfirst(ptr);
247 ptr += 4;
248 sigblob = ptr;
249 ptr += len;
250 #if 0
251 rlen = get_uint32_MSBfirst(ptr);
252 if (rlen != 0) {
253 return -1;
254 }
255 #endif
256
257 /* RSA_verify expects a signature of RSA_size */
258 modlen = RSA_size(key);
259 if (len > modlen) {
260 return -5;
261
262 } else if (len < modlen) {
263 u_int diff = modlen - len;
264 sigblob = realloc(sigblob, modlen);
265 memmove(sigblob + diff, sigblob, len);
266 memset(sigblob, 0, diff);
267 len = modlen;
268 }
269
270 /* sha1 the data */
271 // nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
272 nid = NID_sha1;
273 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
274 //error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid);
275 return -6;
276 }
277 EVP_DigestInit(&md, evp_md);
278 EVP_DigestUpdate(&md, data, datalen);
279 EVP_DigestFinal(&md, digest, &dlen);
280
281 ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key);
282
283 memset(digest, 'd', sizeof(digest));
284 memset(sigblob, 's', len);
285 //free(sigblob);
286 //debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
287
288 return ret;
289 }
290
291 int ssh_ecdsa_verify(EC_KEY *key, ssh_keytype keytype,
292 u_char *signature, u_int signaturelen,
293 u_char *data, u_int datalen)
294 {
295 ECDSA_SIG *sig;
296 const EVP_MD *evp_md;
297 EVP_MD_CTX md;
298 unsigned char digest[EVP_MAX_MD_SIZE], *sigblob;
299 unsigned int len, dlen;
300 int ret, nid = NID_undef;
301 char *ptr;
302
303 OpenSSL_add_all_digests();
304
305 if (key == NULL) {
306 return -2;
307 }
308
309 ptr = signature;
310
311 len = get_uint32_MSBfirst(ptr);
312 ptr += 4;
313 if (strncmp(get_ssh_keytype_name(keytype), ptr, len) != 0) {
314 return -3;
315 }
316 ptr += len;
317
318 len = get_uint32_MSBfirst(ptr);
319 ptr += 4;
320 sigblob = ptr;
321 ptr += len;
322
323 /* parse signature */
324 if ((sig = ECDSA_SIG_new()) == NULL)
325 return -4;
326 if ((sig->r = BN_new()) == NULL)
327 return -5;
328 if ((sig->s = BN_new()) == NULL)
329 return -6;
330
331 buffer_get_bignum2(&sigblob, sig->r);
332 buffer_get_bignum2(&sigblob, sig->s);
333 if (sigblob != ptr) {
334 return -7;
335 }
336
337 /* hash the data */
338 nid = keytype_to_hash_nid(keytype);
339 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
340 return -8;
341 }
342 EVP_DigestInit(&md, evp_md);
343 EVP_DigestUpdate(&md, data, datalen);
344 EVP_DigestFinal(&md, digest, &dlen);
345
346 ret = ECDSA_do_verify(digest, dlen, sig, key);
347 memset(digest, 'd', sizeof(digest));
348
349 ECDSA_SIG_free(sig);
350
351 return ret;
352 }
353
354 int key_verify(Key *key,
355 unsigned char *signature, unsigned int signaturelen,
356 unsigned char *data, unsigned int datalen)
357 {
358 int ret = 0;
359
360 switch (key->type) {
361 case KEY_RSA:
362 ret = ssh_rsa_verify(key->rsa, signature, signaturelen, data, datalen);
363 break;
364 case KEY_DSA:
365 ret = ssh_dss_verify(key->dsa, signature, signaturelen, data, datalen);
366 break;
367 case KEY_ECDSA256:
368 case KEY_ECDSA384:
369 case KEY_ECDSA521:
370 ret = ssh_ecdsa_verify(key->ecdsa, key->type, signature, signaturelen, data, datalen);
371 break;
372 default:
373 return -1;
374 }
375
376 return (ret); // success
377 }
378
379 //
380 // RSA�\����������
381 //
382 RSA *duplicate_RSA(RSA *src)
383 {
384 RSA *rsa = NULL;
385
386 rsa = RSA_new();
387 if (rsa == NULL)
388 goto error;
389 rsa->n = BN_new();
390 rsa->e = BN_new();
391 if (rsa->n == NULL || rsa->e == NULL) {
392 RSA_free(rsa);
393 goto error;
394 }
395
396 // �[���R�s�[(deep copy)���s���B�����R�s�[(shallow copy)��NG�B
397 BN_copy(rsa->n, src->n);
398 BN_copy(rsa->e, src->e);
399
400 error:
401 return (rsa);
402 }
403
404
405 //
406 // DSA�\����������
407 //
408 DSA *duplicate_DSA(DSA *src)
409 {
410 DSA *dsa = NULL;
411
412 dsa = DSA_new();
413 if (dsa == NULL)
414 goto error;
415 dsa->p = BN_new();
416 dsa->q = BN_new();
417 dsa->g = BN_new();
418 dsa->pub_key = BN_new();
419 if (dsa->p == NULL ||
420 dsa->q == NULL ||
421 dsa->g == NULL ||
422 dsa->pub_key == NULL) {
423 DSA_free(dsa);
424 goto error;
425 }
426
427 // �[���R�s�[(deep copy)���s���B�����R�s�[(shallow copy)��NG�B
428 BN_copy(dsa->p, src->p);
429 BN_copy(dsa->q, src->q);
430 BN_copy(dsa->g, src->g);
431 BN_copy(dsa->pub_key, src->pub_key);
432
433 error:
434 return (dsa);
435 }
436
437
438 char* key_fingerprint_raw(Key *k, enum fp_type dgst_type, int *dgst_raw_length)
439 {
440 const EVP_MD *md = NULL;
441 EVP_MD_CTX ctx;
442 char *blob = NULL;
443 char *retval = NULL;
444 int len = 0;
445 int nlen, elen;
446 RSA *rsa;
447
448 *dgst_raw_length = 0;
449
450 switch (dgst_type) {
451 case SSH_FP_MD5:
452 md = EVP_md5();
453 break;
454 case SSH_FP_SHA1:
455 md = EVP_sha1();
456 break;
457 case SSH_FP_SHA256:
458 md = EVP_sha256();
459 break;
460 default:
461 md = EVP_md5();
462 }
463
464 switch (k->type) {
465 case KEY_RSA1:
466 rsa = make_key(NULL, k->bits, k->exp, k->mod);
467 nlen = BN_num_bytes(rsa->n);
468 elen = BN_num_bytes(rsa->e);
469 len = nlen + elen;
470 blob = malloc(len);
471 if (blob == NULL) {
472 // TODO:
473 }
474 BN_bn2bin(rsa->n, blob);
475 BN_bn2bin(rsa->e, blob + nlen);
476 RSA_free(rsa);
477 break;
478
479 case KEY_DSA:
480 case KEY_RSA:
481 case KEY_ECDSA256:
482 case KEY_ECDSA384:
483 case KEY_ECDSA521:
484 key_to_blob(k, &blob, &len);
485 break;
486
487 case KEY_UNSPEC:
488 return retval;
489 break;
490
491 default:
492 //fatal("key_fingerprint_raw: bad key type %d", k->type);
493 break;
494 }
495
496 if (blob != NULL) {
497 retval = malloc(EVP_MAX_MD_SIZE);
498 if (retval == NULL) {
499 // TODO:
500 }
501 EVP_DigestInit(&ctx, md);
502 EVP_DigestUpdate(&ctx, blob, len);
503 EVP_DigestFinal(&ctx, retval, dgst_raw_length);
504 memset(blob, 0, len);
505 free(blob);
506 } else {
507 //fatal("key_fingerprint_raw: blob is null");
508 }
509 return retval;
510 }
511
512
513 const char *
514 key_type(const Key *k)
515 {
516 switch (k->type) {
517 case KEY_RSA1:
518 return "RSA1";
519 case KEY_RSA:
520 return "RSA";
521 case KEY_DSA:
522 return "DSA";
523 case KEY_ECDSA256:
524 case KEY_ECDSA384:
525 case KEY_ECDSA521:
526 return "ECDSA";
527 }
528 return "unknown";
529 }
530
531 unsigned int
532 key_size(const Key *k)
533 {
534 switch (k->type) {
535 case KEY_RSA1:
536 // SSH1�������� key->rsa �� key->dsa �� NULL �����������A�g�������B
537 return k->bits;
538 case KEY_RSA:
539 return BN_num_bits(k->rsa->n);
540 case KEY_DSA:
541 return BN_num_bits(k->dsa->p);
542 case KEY_ECDSA256:
543 return 256;
544 case KEY_ECDSA384:
545 return 384;
546 case KEY_ECDSA521:
547 return 521;
548 }
549 return 0;
550 }
551
552 // based on OpenSSH 5.1
553 #define FLDBASE 8
554 #define FLDSIZE_Y (FLDBASE + 1)
555 #define FLDSIZE_X (FLDBASE * 2 + 1)
556 static char *
557 key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
558 {
559 /*
560 * Chars to be used after each other every time the worm
561 * intersects with itself. Matter of taste.
562 */
563 char *augmentation_string = " .o+=*BOX@%&#/^SE";
564 char *retval, *p;
565 unsigned char field[FLDSIZE_X][FLDSIZE_Y];
566 unsigned int i, b;
567 int x, y;
568 size_t len = strlen(augmentation_string) - 1;
569
570 retval = calloc(1, (FLDSIZE_X + 3 + 1) * (FLDSIZE_Y + 2));
571
572 /* initialize field */
573 memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
574 x = FLDSIZE_X / 2;
575 y = FLDSIZE_Y / 2;
576
577 /* process raw key */
578 for (i = 0; i < dgst_raw_len; i++) {
579 int input;
580 /* each byte conveys four 2-bit move commands */
581 input = dgst_raw[i];
582 for (b = 0; b < 4; b++) {
583 /* evaluate 2 bit, rest is shifted later */
584 x += (input & 0x1) ? 1 : -1;
585 y += (input & 0x2) ? 1 : -1;
586
587 /* assure we are still in bounds */
588 x = max(x, 0);
589 y = max(y, 0);
590 x = min(x, FLDSIZE_X - 1);
591 y = min(y, FLDSIZE_Y - 1);
592
593 /* augment the field */
594 field[x][y]++;
595 input = input >> 2;
596 }
597 }
598
599 /* mark starting point and end point*/
600 field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
601 field[x][y] = len;
602
603 /* fill in retval */
604 _snprintf_s(retval, FLDSIZE_X, _TRUNCATE, "+--[%4s %4u]", key_type(k), key_size(k));
605 p = strchr(retval, '\0');
606
607 /* output upper border */
608 for (i = p - retval - 1; i < FLDSIZE_X; i++)
609 *p++ = '-';
610 *p++ = '+';
611 *p++ = '\r';
612 *p++ = '\n';
613
614 /* output content */
615 for (y = 0; y < FLDSIZE_Y; y++) {
616 *p++ = '|';
617 for (x = 0; x < FLDSIZE_X; x++)
618 *p++ = augmentation_string[min(field[x][y], len)];
619 *p++ = '|';
620 *p++ = '\r';
621 *p++ = '\n';
622 }
623
624 /* output lower border */
625 *p++ = '+';
626 for (i = 0; i < FLDSIZE_X; i++)
627 *p++ = '-';
628 *p++ = '+';
629
630 return retval;
631 }
632 #undef FLDBASE
633 #undef FLDSIZE_Y
634 #undef FLDSIZE_X
635
636 //
637 // fingerprint�i�w���F�z�X�g���J�����n�b�V���j����������
638 //
639 char *key_fingerprint(Key *key, enum fp_rep dgst_rep)
640 {
641 char *retval = NULL;
642 unsigned char *dgst_raw;
643 int dgst_raw_len;
644 int i, retval_len;
645
646 // fingerprint���n�b�V���l�i�o�C�i���j��������
647 dgst_raw = key_fingerprint_raw(key, SSH_FP_MD5, &dgst_raw_len);
648
649 if (dgst_rep == SSH_FP_HEX) {
650 // 16�i�\�L����������
651 retval_len = dgst_raw_len * 3 + 1;
652 retval = malloc(retval_len);
653 retval[0] = '\0';
654 for (i = 0; i < dgst_raw_len; i++) {
655 char hex[4];
656 _snprintf_s(hex, sizeof(hex), _TRUNCATE, "%02x:", dgst_raw[i]);
657 strncat_s(retval, retval_len, hex, _TRUNCATE);
658 }
659
660 /* Remove the trailing ':' character */
661 retval[(dgst_raw_len * 3) - 1] = '\0';
662
663 } else if (dgst_rep == SSH_FP_RANDOMART) {
664 retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, key);
665
666 } else {
667
668 }
669
670 memset(dgst_raw, 0, dgst_raw_len);
671 free(dgst_raw);
672
673 return (retval);
674 }
675
676
677 //
678 // �L�[����������������
679 //
680 void key_free(Key *key)
681 {
682 if (key == NULL) {
683 return;
684 }
685
686 switch (key->type) {
687 case KEY_RSA1:
688 case KEY_RSA:
689 if (key->rsa != NULL)
690 RSA_free(key->rsa);
691 key->rsa = NULL;
692 break;
693
694 case KEY_DSA:
695 if (key->dsa != NULL)
696 DSA_free(key->dsa);
697 key->dsa = NULL;
698 break;
699
700 case KEY_ECDSA256:
701 case KEY_ECDSA384:
702 case KEY_ECDSA521:
703 if (key->ecdsa != NULL)
704 EC_KEY_free(key->ecdsa);
705 key->ecdsa = NULL;
706 break;
707 }
708 free(key);
709 }
710
711 //
712 // �L�[���������������p����
713 //
714 char *get_sshname_from_key(Key *key)
715 {
716 return get_ssh_keytype_name(key->type);
717 }
718
719 //
720 // �L�[������������������������
721 //
722 ssh_keytype get_keytype_from_name(char *name)
723 {
724 if (strcmp(name, "rsa1") == 0) {
725 return KEY_RSA1;
726 } else if (strcmp(name, "rsa") == 0) {
727 return KEY_RSA;
728 } else if (strcmp(name, "dsa") == 0) {
729 return KEY_DSA;
730 } else if (strcmp(name, "ssh-rsa") == 0) {
731 return KEY_RSA;
732 } else if (strcmp(name, "ssh-dss") == 0) {
733 return KEY_DSA;
734 } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
735 return KEY_ECDSA256;
736 } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
737 return KEY_ECDSA384;
738 } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
739 return KEY_ECDSA521;
740 }
741 return KEY_UNSPEC;
742 }
743
744
745 ssh_keytype key_curve_name_to_keytype(char *name)
746 {
747 if (strcmp(name, "nistp256") == 0) {
748 return KEY_ECDSA256;
749 } else if (strcmp(name, "nistp384") == 0) {
750 return KEY_ECDSA384;
751 } else if (strcmp(name, "nistp521") == 0) {
752 return KEY_ECDSA521;
753 }
754 return KEY_UNSPEC;
755 }
756
757 char *curve_keytype_to_name(ssh_keytype type)
758 {
759 switch (type) {
760 case KEY_ECDSA256:
761 return "nistp256";
762 break;
763 case KEY_ECDSA384:
764 return "nistp384";
765 break;
766 case KEY_ECDSA521:
767 return "nistp521";
768 break;
769 }
770 return NULL;
771 }
772
773 //
774 // �L�[���������o�b�t�@���������� (for SSH2)
775 // NOTE:
776 //
777 int key_to_blob(Key *key, char **blobp, int *lenp)
778 {
779 buffer_t *b;
780 char *sshname, *tmp;
781 int len;
782 int ret = 1; // success
783
784 b = buffer_init();
785 sshname = get_sshname_from_key(key);
786
787 switch (key->type) {
788 case KEY_RSA:
789 buffer_put_string(b, sshname, strlen(sshname));
790 buffer_put_bignum2(b, key->rsa->e);
791 buffer_put_bignum2(b, key->rsa->n);
792 break;
793 case KEY_DSA:
794 buffer_put_string(b, sshname, strlen(sshname));
795 buffer_put_bignum2(b, key->dsa->p);
796 buffer_put_bignum2(b, key->dsa->q);
797 buffer_put_bignum2(b, key->dsa->g);
798 buffer_put_bignum2(b, key->dsa->pub_key);
799 break;
800 case KEY_ECDSA256:
801 case KEY_ECDSA384:
802 case KEY_ECDSA521:
803 buffer_put_string(b, sshname, strlen(sshname));
804 tmp = curve_keytype_to_name(key->type);
805 buffer_put_string(b, tmp, strlen(tmp));
806 buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
807 EC_KEY_get0_public_key(key->ecdsa));
808 break;
809
810 default:
811 ret = 0;
812 goto error;
813 }
814
815 len = buffer_len(b);
816 if (lenp != NULL)
817 *lenp = len;
818 if (blobp != NULL) {
819 *blobp = malloc(len);
820 if (*blobp == NULL) {
821 ret = 0;
822 goto error;
823 }
824 memcpy(*blobp, buffer_ptr(b), len);
825 }
826
827 error:
828 buffer_free(b);
829
830 return (ret);
831 }
832
833
834 //
835 // �o�b�t�@�����L�[�����������o��(for SSH2)
836 // NOTE: ���l���A���P�[�g���������������A�����o�������������������B
837 //
838 Key *key_from_blob(char *data, int blen)
839 {
840 int keynamelen;
841 char key[128];
842 RSA *rsa = NULL;
843 DSA *dsa = NULL;
844 EC_KEY *ecdsa = NULL;
845 EC_POINT *q = NULL;
846 char *curve = NULL;
847 Key *hostkey; // hostkey
848 ssh_keytype type;
849
850 hostkey = malloc(sizeof(Key));
851 if (hostkey == NULL)
852 goto error;
853
854 memset(hostkey, 0, sizeof(Key));
855
856 keynamelen = get_uint32_MSBfirst(data);
857 if (keynamelen >= sizeof(key)) {
858 goto error;
859 }
860 data += 4;
861 memcpy(key, data, keynamelen);
862 key[keynamelen] = 0;
863 data += keynamelen;
864
865 type = get_keytype_from_name(key);
866
867 switch (type) {
868 case KEY_RSA: // RSA key
869 rsa = RSA_new();
870 if (rsa == NULL) {
871 goto error;
872 }
873 rsa->n = BN_new();
874 rsa->e = BN_new();
875 if (rsa->n == NULL || rsa->e == NULL) {
876 goto error;
877 }
878
879 buffer_get_bignum2(&data, rsa->e);
880 buffer_get_bignum2(&data, rsa->n);
881
882 hostkey->type = type;
883 hostkey->rsa = rsa;
884 break;
885
886 case KEY_DSA: // DSA key
887 dsa = DSA_new();
888 if (dsa == NULL) {
889 goto error;
890 }
891 dsa->p = BN_new();
892 dsa->q = BN_new();
893 dsa->g = BN_new();
894 dsa->pub_key = BN_new();
895 if (dsa->p == NULL ||
896 dsa->q == NULL ||
897 dsa->g == NULL ||
898 dsa->pub_key == NULL) {
899 goto error;
900 }
901
902 buffer_get_bignum2(&data, dsa->p);
903 buffer_get_bignum2(&data, dsa->q);
904 buffer_get_bignum2(&data, dsa->g);
905 buffer_get_bignum2(&data, dsa->pub_key);
906
907 hostkey->type = type;
908 hostkey->dsa = dsa;
909 break;
910
911 case KEY_ECDSA256: // ECDSA
912 case KEY_ECDSA384:
913 case KEY_ECDSA521:
914 curve = buffer_get_string(&data, NULL);
915 if (type != key_curve_name_to_keytype(curve)) {
916 goto error;
917 }
918
919 ecdsa = EC_KEY_new_by_curve_name(keytype_to_cipher_nid(type));
920 if (ecdsa == NULL) {
921 goto error;
922 }
923
924 q = EC_POINT_new(EC_KEY_get0_group(ecdsa));
925 if (q == NULL) {
926 goto error;
927 }
928
929 buffer_get_ecpoint(&data, EC_KEY_get0_group(ecdsa), q);
930 if (key_ec_validate_public(EC_KEY_get0_group(ecdsa), q) == -1) {
931 goto error;
932 }
933
934 if (EC_KEY_set_public_key(ecdsa, q) != 1) {
935 goto error;
936 }
937
938 hostkey->type = type;
939 hostkey->ecdsa = ecdsa;
940 break;
941
942 default: // unknown key
943 goto error;
944 }
945
946 return (hostkey);
947
948 error:
949 if (rsa != NULL)
950 RSA_free(rsa);
951 if (dsa != NULL)
952 DSA_free(dsa);
953 if (ecdsa != NULL)
954 EC_KEY_free(ecdsa);
955
956 return NULL;
957 }
958
959
960 BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen)
961 {
962 buffer_t *msg = NULL;
963 char *s;
964
965 msg = buffer_init();
966 if (msg == NULL) {
967 // TODO: error check
968 return FALSE;
969 }
970
971 switch (keypair->type) {
972 case KEY_RSA: // RSA
973 {
974 const EVP_MD *evp_md = EVP_sha1();
975 EVP_MD_CTX md;
976 u_char digest[EVP_MAX_MD_SIZE], *sig;
977 u_int slen, dlen, len;
978 int ok, nid = NID_sha1;
979
980 // �_�C�W�F�X�g�l���v�Z
981 EVP_DigestInit(&md, evp_md);
982 EVP_DigestUpdate(&md, data, datalen);
983 EVP_DigestFinal(&md, digest, &dlen);
984
985 slen = RSA_size(keypair->rsa);
986 sig = malloc(slen);
987 if (sig == NULL)
988 goto error;
989
990 // �d�q�������v�Z
991 ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa);
992 memset(digest, 'd', sizeof(digest));
993 if (ok != 1) { // error
994 free(sig);
995 goto error;
996 }
997 // �������T�C�Y���o�b�t�@���������������A�������������B�������[�����������B
998 if (len < slen) {
999 u_int diff = slen - len;
1000 memmove(sig + diff, sig, len);
1001 memset(sig, 0, diff);
1002
1003 } else if (len > slen) {
1004 free(sig);
1005 goto error;
1006
1007 } else {
1008 // do nothing
1009
1010 }
1011
1012 s = get_sshname_from_key(keypair);
1013 buffer_put_string(msg, s, strlen(s));
1014 buffer_append_length(msg, sig, slen);
1015 len = buffer_len(msg);
1016
1017 // setting
1018 *siglen = len;
1019 *sigptr = malloc(len);
1020 if (*sigptr == NULL) {
1021 free(sig);
1022 goto error;
1023 }
1024 memcpy(*sigptr, buffer_ptr(msg), len);
1025 free(sig);
1026
1027 break;
1028 }
1029 case KEY_DSA: // DSA
1030 {
1031 DSA_SIG *sig;
1032 const EVP_MD *evp_md = EVP_sha1();
1033 EVP_MD_CTX md;
1034 u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
1035 u_int rlen, slen, len, dlen;
1036
1037 // �_�C�W�F�X�g���v�Z
1038 EVP_DigestInit(&md, evp_md);
1039 EVP_DigestUpdate(&md, data, datalen);
1040 EVP_DigestFinal(&md, digest, &dlen);
1041
1042 // DSA�d�q�������v�Z
1043 sig = DSA_do_sign(digest, dlen, keypair->dsa);
1044 memset(digest, 'd', sizeof(digest));
1045 if (sig == NULL) {
1046 goto error;
1047 }
1048
1049 // BIGNUM�����o�C�i���l��������
1050 rlen = BN_num_bytes(sig->r);
1051 slen = BN_num_bytes(sig->s);
1052 if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
1053 DSA_SIG_free(sig);
1054 goto error;
1055 }
1056 memset(sigblob, 0, SIGBLOB_LEN);
1057 BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
1058 BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
1059 DSA_SIG_free(sig);
1060
1061 // setting
1062 s = get_sshname_from_key(keypair);
1063 buffer_put_string(msg, s, strlen(s));
1064 buffer_append_length(msg, sigblob, sizeof(sigblob));
1065 len = buffer_len(msg);
1066
1067 // setting
1068 *siglen = len;
1069 *sigptr = malloc(len);
1070 if (*sigptr == NULL) {
1071 goto error;
1072 }
1073 memcpy(*sigptr, buffer_ptr(msg), len);
1074
1075 break;
1076 }
1077 case KEY_ECDSA256: // ECDSA
1078 case KEY_ECDSA384:
1079 case KEY_ECDSA521:
1080 {
1081 ECDSA_SIG *sig;
1082 const EVP_MD *evp_md;
1083 EVP_MD_CTX md;
1084 u_char digest[EVP_MAX_MD_SIZE];
1085 u_int len, dlen, nid;
1086 buffer_t *buf2 = NULL;
1087
1088 nid = keytype_to_hash_nid(keypair->type);
1089 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
1090 goto error;
1091 }
1092 EVP_DigestInit(&md, evp_md);
1093 EVP_DigestUpdate(&md, data, datalen);
1094 EVP_DigestFinal(&md, digest, &dlen);
1095
1096 sig = ECDSA_do_sign(digest, dlen, keypair->ecdsa);
1097 memset(digest, 'd', sizeof(digest));
1098
1099 if (sig == NULL) {
1100 goto error;
1101 }
1102
1103 buf2 = buffer_init();
1104 if (buf2 == NULL) {
1105 // TODO: error check
1106 goto error;
1107 }
1108 buffer_put_bignum2(buf2, sig->r);
1109 buffer_put_bignum2(buf2, sig->s);
1110 ECDSA_SIG_free(sig);
1111
1112 s = get_sshname_from_key(keypair);
1113 buffer_put_string(msg, s, strlen(s));
1114 buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2));
1115 buffer_free(buf2);
1116 len = buffer_len(msg);
1117
1118 *siglen = len;
1119 *sigptr = malloc(len);
1120 if (*sigptr == NULL) {
1121 goto error;
1122 }
1123 memcpy(*sigptr, buffer_ptr(msg), len);
1124
1125 break;
1126 }
1127 default:
1128 buffer_free(msg);
1129 return FALSE;
1130 break;
1131 }
1132
1133 buffer_free(msg);
1134 return TRUE;
1135
1136 error:
1137 buffer_free(msg);
1138
1139 return FALSE;
1140 }
1141
1142
1143 BOOL get_SSH2_publickey_blob(PTInstVar pvar, buffer_t **blobptr, int *bloblen)
1144 {
1145 buffer_t *msg = NULL;
1146 Key *keypair;
1147 char *s, *tmp;
1148
1149 msg = buffer_init();
1150 if (msg == NULL) {
1151 // TODO: error check
1152 return FALSE;
1153 }
1154
1155 keypair = pvar->auth_state.cur_cred.key_pair;
1156
1157 switch (keypair->type) {
1158 case KEY_RSA: // RSA
1159 s = get_sshname_from_key(keypair);
1160 buffer_put_string(msg, s, strlen(s));
1161 buffer_put_bignum2(msg, keypair->rsa->e); // ���J�w��
1162 buffer_put_bignum2(msg, keypair->rsa->n); // p�~q
1163 break;
1164 case KEY_DSA: // DSA
1165 s = get_sshname_from_key(keypair);
1166 buffer_put_string(msg, s, strlen(s));
1167 buffer_put_bignum2(msg, keypair->dsa->p); // �f��
1168 buffer_put_bignum2(msg, keypair->dsa->q); // (p-1)���f����
1169 buffer_put_bignum2(msg, keypair->dsa->g); // ����
1170 buffer_put_bignum2(msg, keypair->dsa->pub_key); // ���J��
1171 break;
1172 case KEY_ECDSA256: // ECDSA
1173 case KEY_ECDSA384:
1174 case KEY_ECDSA521:
1175 s = get_sshname_from_key(keypair);
1176 buffer_put_string(msg, s, strlen(s));
1177 tmp = curve_keytype_to_name(keypair->type);
1178 buffer_put_string(msg, tmp, strlen(tmp));
1179 buffer_put_ecpoint(msg, EC_KEY_get0_group(keypair->ecdsa),
1180 EC_KEY_get0_public_key(keypair->ecdsa));
1181 break;
1182 default:
1183 return FALSE;
1184 }
1185
1186 *blobptr = msg;
1187 *bloblen = buffer_len(msg);
1188
1189 return TRUE;
1190 }
1191
1192 int kextype_to_cipher_nid(kex_algorithm type)
1193 {
1194 switch (type) {
1195 case KEX_ECDH_SHA2_256:
1196 return NID_X9_62_prime256v1;
1197 case KEX_ECDH_SHA2_384:
1198 return NID_secp384r1;
1199 case KEX_ECDH_SHA2_521:
1200 return NID_secp521r1;
1201 }
1202 return NID_undef;
1203 }
1204
1205 int keytype_to_hash_nid(ssh_keytype type)
1206 {
1207 switch (type) {
1208 case KEY_ECDSA256:
1209 return NID_sha256;
1210 case KEY_ECDSA384:
1211 return NID_sha384;
1212 case KEY_ECDSA521:
1213 return NID_sha512;
1214 }
1215 return NID_undef;
1216 }
1217
1218 int keytype_to_cipher_nid(ssh_keytype type)
1219 {
1220 switch (type) {
1221 case KEY_ECDSA256:
1222 return NID_X9_62_prime256v1;
1223 case KEY_ECDSA384:
1224 return NID_secp384r1;
1225 case KEY_ECDSA521:
1226 return NID_secp521r1;
1227 }
1228 return NID_undef;
1229 }
1230
1231 ssh_keytype nid_to_keytype(int nid)
1232 {
1233 switch (nid) {
1234 case NID_X9_62_prime256v1:
1235 return KEY_ECDSA256;
1236 case NID_secp384r1:
1237 return KEY_ECDSA384;
1238 case NID_secp521r1:
1239 return KEY_ECDSA521;
1240 }
1241 return KEY_UNSPEC;
1242 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26