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 4324 - (show annotations) (download) (as text)
Sat Feb 19 11:07:05 2011 UTC (13 years, 1 month ago) by maya
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 27298 byte(s)
SSH2 の ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521 公開鍵認証をサポートした
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, enum 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_sshname_from_keytype(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 switch (keytype) {
339 case KEY_ECDSA256:
340 nid = NID_sha256;
341 break;
342 case KEY_ECDSA384:
343 nid = NID_sha384;
344 break;
345 case KEY_ECDSA521:
346 nid = NID_sha512;
347 break;
348 }
349 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
350 return -8;
351 }
352 EVP_DigestInit(&md, evp_md);
353 EVP_DigestUpdate(&md, data, datalen);
354 EVP_DigestFinal(&md, digest, &dlen);
355
356 ret = ECDSA_do_verify(digest, dlen, sig, key);
357 memset(digest, 'd', sizeof(digest));
358
359 ECDSA_SIG_free(sig);
360
361 return ret;
362 }
363
364 int key_verify(Key *key,
365 unsigned char *signature, unsigned int signaturelen,
366 unsigned char *data, unsigned int datalen)
367 {
368 int ret = 0;
369
370 switch (key->type) {
371 case KEY_RSA:
372 ret = ssh_rsa_verify(key->rsa, signature, signaturelen, data, datalen);
373 break;
374 case KEY_DSA:
375 ret = ssh_dss_verify(key->dsa, signature, signaturelen, data, datalen);
376 break;
377 case KEY_ECDSA256:
378 case KEY_ECDSA384:
379 case KEY_ECDSA521:
380 ret = ssh_ecdsa_verify(key->ecdsa, key->type, signature, signaturelen, data, datalen);
381 break;
382 default:
383 return -1;
384 }
385
386 return (ret); // success
387 }
388
389 //
390 // RSA�\����������
391 //
392 RSA *duplicate_RSA(RSA *src)
393 {
394 RSA *rsa = NULL;
395
396 rsa = RSA_new();
397 if (rsa == NULL)
398 goto error;
399 rsa->n = BN_new();
400 rsa->e = BN_new();
401 if (rsa->n == NULL || rsa->e == NULL) {
402 RSA_free(rsa);
403 goto error;
404 }
405
406 // �[���R�s�[(deep copy)���s���B�����R�s�[(shallow copy)��NG�B
407 BN_copy(rsa->n, src->n);
408 BN_copy(rsa->e, src->e);
409
410 error:
411 return (rsa);
412 }
413
414
415 //
416 // DSA�\����������
417 //
418 DSA *duplicate_DSA(DSA *src)
419 {
420 DSA *dsa = NULL;
421
422 dsa = DSA_new();
423 if (dsa == NULL)
424 goto error;
425 dsa->p = BN_new();
426 dsa->q = BN_new();
427 dsa->g = BN_new();
428 dsa->pub_key = BN_new();
429 if (dsa->p == NULL ||
430 dsa->q == NULL ||
431 dsa->g == NULL ||
432 dsa->pub_key == NULL) {
433 DSA_free(dsa);
434 goto error;
435 }
436
437 // �[���R�s�[(deep copy)���s���B�����R�s�[(shallow copy)��NG�B
438 BN_copy(dsa->p, src->p);
439 BN_copy(dsa->q, src->q);
440 BN_copy(dsa->g, src->g);
441 BN_copy(dsa->pub_key, src->pub_key);
442
443 error:
444 return (dsa);
445 }
446
447
448 char* key_fingerprint_raw(Key *k, int *dgst_raw_length)
449 {
450 const EVP_MD *md = NULL;
451 EVP_MD_CTX ctx;
452 char *blob = NULL;
453 char *retval = NULL;
454 int len = 0;
455 int nlen, elen;
456 RSA *rsa;
457
458 *dgst_raw_length = 0;
459
460 // MD5�A���S���Y�����g�p����
461 md = EVP_md5();
462
463 switch (k->type) {
464 case KEY_RSA1:
465 rsa = make_key(NULL, k->bits, k->exp, k->mod);
466 nlen = BN_num_bytes(rsa->n);
467 elen = BN_num_bytes(rsa->e);
468 len = nlen + elen;
469 blob = malloc(len);
470 if (blob == NULL) {
471 // TODO:
472 }
473 BN_bn2bin(rsa->n, blob);
474 BN_bn2bin(rsa->e, blob + nlen);
475 RSA_free(rsa);
476 break;
477
478 case KEY_DSA:
479 case KEY_RSA:
480 case KEY_ECDSA256:
481 case KEY_ECDSA384:
482 case KEY_ECDSA521:
483 key_to_blob(k, &blob, &len);
484 break;
485
486 case KEY_UNSPEC:
487 return retval;
488 break;
489
490 default:
491 //fatal("key_fingerprint_raw: bad key type %d", k->type);
492 break;
493 }
494
495 if (blob != NULL) {
496 retval = malloc(EVP_MAX_MD_SIZE);
497 if (retval == NULL) {
498 // TODO:
499 }
500 EVP_DigestInit(&ctx, md);
501 EVP_DigestUpdate(&ctx, blob, len);
502 EVP_DigestFinal(&ctx, retval, dgst_raw_length);
503 memset(blob, 0, len);
504 free(blob);
505 } else {
506 //fatal("key_fingerprint_raw: blob is null");
507 }
508 return retval;
509 }
510
511
512 const char *
513 key_type(const Key *k)
514 {
515 switch (k->type) {
516 case KEY_RSA1:
517 return "RSA1";
518 case KEY_RSA:
519 return "RSA";
520 case KEY_DSA:
521 return "DSA";
522 case KEY_ECDSA256:
523 case KEY_ECDSA384:
524 case KEY_ECDSA521:
525 return "ECDSA";
526 }
527 return "unknown";
528 }
529
530 unsigned int
531 key_size(const Key *k)
532 {
533 switch (k->type) {
534 case KEY_RSA1:
535 // SSH1�������� key->rsa �� key->dsa �� NULL �����������A�g�������B
536 return k->bits;
537 case KEY_RSA:
538 return BN_num_bits(k->rsa->n);
539 case KEY_DSA:
540 return BN_num_bits(k->dsa->p);
541 case KEY_ECDSA256:
542 return 256;
543 case KEY_ECDSA384:
544 return 384;
545 case KEY_ECDSA521:
546 return 521;
547 }
548 return 0;
549 }
550
551 // based on OpenSSH 5.1
552 #define FLDBASE 8
553 #define FLDSIZE_Y (FLDBASE + 1)
554 #define FLDSIZE_X (FLDBASE * 2 + 1)
555 static char *
556 key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
557 {
558 /*
559 * Chars to be used after each other every time the worm
560 * intersects with itself. Matter of taste.
561 */
562 char *augmentation_string = " .o+=*BOX@%&#/^SE";
563 char *retval, *p;
564 unsigned char field[FLDSIZE_X][FLDSIZE_Y];
565 unsigned int i, b;
566 int x, y;
567 size_t len = strlen(augmentation_string) - 1;
568
569 retval = calloc(1, (FLDSIZE_X + 3 + 1) * (FLDSIZE_Y + 2));
570
571 /* initialize field */
572 memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
573 x = FLDSIZE_X / 2;
574 y = FLDSIZE_Y / 2;
575
576 /* process raw key */
577 for (i = 0; i < dgst_raw_len; i++) {
578 int input;
579 /* each byte conveys four 2-bit move commands */
580 input = dgst_raw[i];
581 for (b = 0; b < 4; b++) {
582 /* evaluate 2 bit, rest is shifted later */
583 x += (input & 0x1) ? 1 : -1;
584 y += (input & 0x2) ? 1 : -1;
585
586 /* assure we are still in bounds */
587 x = max(x, 0);
588 y = max(y, 0);
589 x = min(x, FLDSIZE_X - 1);
590 y = min(y, FLDSIZE_Y - 1);
591
592 /* augment the field */
593 field[x][y]++;
594 input = input >> 2;
595 }
596 }
597
598 /* mark starting point and end point*/
599 field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
600 field[x][y] = len;
601
602 /* fill in retval */
603 _snprintf_s(retval, FLDSIZE_X, _TRUNCATE, "+--[%4s %4u]", key_type(k), key_size(k));
604 p = strchr(retval, '\0');
605
606 /* output upper border */
607 for (i = p - retval - 1; i < FLDSIZE_X; i++)
608 *p++ = '-';
609 *p++ = '+';
610 *p++ = '\r';
611 *p++ = '\n';
612
613 /* output content */
614 for (y = 0; y < FLDSIZE_Y; y++) {
615 *p++ = '|';
616 for (x = 0; x < FLDSIZE_X; x++)
617 *p++ = augmentation_string[min(field[x][y], len)];
618 *p++ = '|';
619 *p++ = '\r';
620 *p++ = '\n';
621 }
622
623 /* output lower border */
624 *p++ = '+';
625 for (i = 0; i < FLDSIZE_X; i++)
626 *p++ = '-';
627 *p++ = '+';
628
629 return retval;
630 }
631 #undef FLDBASE
632 #undef FLDSIZE_Y
633 #undef FLDSIZE_X
634
635 //
636 // fingerprint�i�w���F�z�X�g���J�����n�b�V���j����������
637 //
638 char *key_fingerprint(Key *key, enum fp_rep dgst_rep)
639 {
640 char *retval = NULL;
641 unsigned char *dgst_raw;
642 int dgst_raw_len;
643 int i, retval_len;
644
645 // fingerprint���n�b�V���l�i�o�C�i���j��������
646 dgst_raw = key_fingerprint_raw(key, &dgst_raw_len);
647
648 if (dgst_rep == SSH_FP_HEX) {
649 // 16�i�\�L����������
650 retval_len = dgst_raw_len * 3 + 1;
651 retval = malloc(retval_len);
652 retval[0] = '\0';
653 for (i = 0; i < dgst_raw_len; i++) {
654 char hex[4];
655 _snprintf_s(hex, sizeof(hex), _TRUNCATE, "%02x:", dgst_raw[i]);
656 strncat_s(retval, retval_len, hex, _TRUNCATE);
657 }
658
659 /* Remove the trailing ':' character */
660 retval[(dgst_raw_len * 3) - 1] = '\0';
661
662 } else if (dgst_rep == SSH_FP_RANDOMART) {
663 retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, key);
664
665 } else {
666
667 }
668
669 memset(dgst_raw, 0, dgst_raw_len);
670 free(dgst_raw);
671
672 return (retval);
673 }
674
675
676 //
677 // �L�[����������������
678 //
679 void key_free(Key *key)
680 {
681 if (key == NULL) {
682 return;
683 }
684
685 switch (key->type) {
686 case KEY_RSA1:
687 case KEY_RSA:
688 if (key->rsa != NULL)
689 RSA_free(key->rsa);
690 key->rsa = NULL;
691 break;
692
693 case KEY_DSA:
694 if (key->dsa != NULL)
695 DSA_free(key->dsa);
696 key->dsa = NULL;
697 break;
698
699 case KEY_ECDSA256:
700 case KEY_ECDSA384:
701 case KEY_ECDSA521:
702 if (key->ecdsa != NULL)
703 EC_KEY_free(key->ecdsa);
704 key->ecdsa = NULL;
705 break;
706 }
707 free(key);
708 }
709
710 //
711 // �L�[���������������p����
712 //
713 char *get_sshname_from_keytype(enum ssh_keytype type)
714 {
715 if (type == KEY_RSA) {
716 return "ssh-rsa";
717 } else if (type == KEY_DSA) {
718 return "ssh-dss";
719 } else if (type == KEY_ECDSA256) {
720 return "ecdsa-sha2-nistp256";
721 } else if (type == KEY_ECDSA384) {
722 return "ecdsa-sha2-nistp384";
723 } else if (type == KEY_ECDSA521) {
724 return "ecdsa-sha2-nistp521";
725 } else {
726 return "ssh-unknown";
727 }
728 }
729 char *get_sshname_from_key(Key *key)
730 {
731 return get_sshname_from_keytype(key->type);
732 }
733
734 //
735 // �L�[������������������������
736 //
737 enum ssh_keytype get_keytype_from_name(char *name)
738 {
739 if (strcmp(name, "rsa1") == 0) {
740 return KEY_RSA1;
741 } else if (strcmp(name, "rsa") == 0) {
742 return KEY_RSA;
743 } else if (strcmp(name, "dsa") == 0) {
744 return KEY_DSA;
745 } else if (strcmp(name, "ssh-rsa") == 0) {
746 return KEY_RSA;
747 } else if (strcmp(name, "ssh-dss") == 0) {
748 return KEY_DSA;
749 } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
750 return KEY_ECDSA256;
751 } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
752 return KEY_ECDSA384;
753 } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
754 return KEY_ECDSA521;
755 }
756 return KEY_UNSPEC;
757 }
758
759
760 enum ssh_keytype key_curve_name_to_keytype(char *name)
761 {
762 if (strcmp(name, "nistp256") == 0) {
763 return KEY_ECDSA256;
764 } else if (strcmp(name, "nistp384") == 0) {
765 return KEY_ECDSA384;
766 } else if (strcmp(name, "nistp521") == 0) {
767 return KEY_ECDSA521;
768 }
769 return KEY_UNSPEC;
770 }
771
772 char *curve_keytype_to_name(enum ssh_keytype type)
773 {
774 switch (type) {
775 case KEY_ECDSA256:
776 return "nistp256";
777 break;
778 case KEY_ECDSA384:
779 return "nistp384";
780 break;
781 case KEY_ECDSA521:
782 return "nistp521";
783 break;
784 }
785 return NULL;
786 }
787
788 //
789 // �L�[���������o�b�t�@���������� (for SSH2)
790 // NOTE:
791 //
792 int key_to_blob(Key *key, char **blobp, int *lenp)
793 {
794 buffer_t *b;
795 char *sshname, *tmp;
796 int len;
797 int ret = 1; // success
798
799 b = buffer_init();
800 sshname = get_sshname_from_key(key);
801
802 switch (key->type) {
803 case KEY_RSA:
804 buffer_put_string(b, sshname, strlen(sshname));
805 buffer_put_bignum2(b, key->rsa->e);
806 buffer_put_bignum2(b, key->rsa->n);
807 break;
808 case KEY_DSA:
809 buffer_put_string(b, sshname, strlen(sshname));
810 buffer_put_bignum2(b, key->dsa->p);
811 buffer_put_bignum2(b, key->dsa->q);
812 buffer_put_bignum2(b, key->dsa->g);
813 buffer_put_bignum2(b, key->dsa->pub_key);
814 break;
815 case KEY_ECDSA256:
816 case KEY_ECDSA384:
817 case KEY_ECDSA521:
818 buffer_put_string(b, sshname, strlen(sshname));
819 tmp = curve_keytype_to_name(key->type);
820 buffer_put_string(b, tmp, strlen(tmp));
821 buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
822 EC_KEY_get0_public_key(key->ecdsa));
823 break;
824
825 default:
826 ret = 0;
827 goto error;
828 }
829
830 len = buffer_len(b);
831 if (lenp != NULL)
832 *lenp = len;
833 if (blobp != NULL) {
834 *blobp = malloc(len);
835 if (*blobp == NULL) {
836 ret = 0;
837 goto error;
838 }
839 memcpy(*blobp, buffer_ptr(b), len);
840 }
841
842 error:
843 buffer_free(b);
844
845 return (ret);
846 }
847
848
849 //
850 // �o�b�t�@�����L�[�����������o��(for SSH2)
851 // NOTE: ���l���A���P�[�g���������������A�����o�������������������B
852 //
853 Key *key_from_blob(char *data, int blen)
854 {
855 int keynamelen;
856 char key[128];
857 RSA *rsa = NULL;
858 DSA *dsa = NULL;
859 EC_KEY *ecdsa = NULL;
860 EC_POINT *q = NULL;
861 char *curve = NULL;
862 Key *hostkey; // hostkey
863 enum ssh_keytype type;
864
865 hostkey = malloc(sizeof(Key));
866 if (hostkey == NULL)
867 goto error;
868
869 memset(hostkey, 0, sizeof(Key));
870
871 keynamelen = get_uint32_MSBfirst(data);
872 if (keynamelen >= sizeof(key)) {
873 goto error;
874 }
875 data += 4;
876 memcpy(key, data, keynamelen);
877 key[keynamelen] = 0;
878 data += keynamelen;
879
880 type = get_keytype_from_name(key);
881
882 switch (type) {
883 case KEY_RSA: // RSA key
884 rsa = RSA_new();
885 if (rsa == NULL) {
886 goto error;
887 }
888 rsa->n = BN_new();
889 rsa->e = BN_new();
890 if (rsa->n == NULL || rsa->e == NULL) {
891 goto error;
892 }
893
894 buffer_get_bignum2(&data, rsa->e);
895 buffer_get_bignum2(&data, rsa->n);
896
897 hostkey->type = type;
898 hostkey->rsa = rsa;
899 break;
900
901 case KEY_DSA: // DSA key
902 dsa = DSA_new();
903 if (dsa == NULL) {
904 goto error;
905 }
906 dsa->p = BN_new();
907 dsa->q = BN_new();
908 dsa->g = BN_new();
909 dsa->pub_key = BN_new();
910 if (dsa->p == NULL ||
911 dsa->q == NULL ||
912 dsa->g == NULL ||
913 dsa->pub_key == NULL) {
914 goto error;
915 }
916
917 buffer_get_bignum2(&data, dsa->p);
918 buffer_get_bignum2(&data, dsa->q);
919 buffer_get_bignum2(&data, dsa->g);
920 buffer_get_bignum2(&data, dsa->pub_key);
921
922 hostkey->type = type;
923 hostkey->dsa = dsa;
924 break;
925
926 case KEY_ECDSA256: // ECDSA
927 case KEY_ECDSA384:
928 case KEY_ECDSA521:
929 curve = buffer_get_string(&data, NULL);
930 if (type != key_curve_name_to_keytype(curve)) {
931 goto error;
932 }
933
934 switch (type) {
935 case KEY_ECDSA256:
936 ecdsa = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
937 break;
938 case KEY_ECDSA384:
939 ecdsa = EC_KEY_new_by_curve_name(NID_secp384r1);
940 break;
941 case KEY_ECDSA521:
942 ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1);
943 break;
944 default:
945 goto error;
946 }
947 if (ecdsa == NULL) {
948 goto error;
949 }
950
951 q = EC_POINT_new(EC_KEY_get0_group(ecdsa));
952 if (q == NULL) {
953 goto error;
954 }
955
956 buffer_get_ecpoint(&data, EC_KEY_get0_group(ecdsa), q);
957 if (key_ec_validate_public(EC_KEY_get0_group(ecdsa), q) == -1) {
958 goto error;
959 }
960
961 if (EC_KEY_set_public_key(ecdsa, q) != 1) {
962 goto error;
963 }
964
965 hostkey->type = type;
966 hostkey->ecdsa = ecdsa;
967 break;
968
969 default: // unknown key
970 goto error;
971 }
972
973 return (hostkey);
974
975 error:
976 if (rsa != NULL)
977 RSA_free(rsa);
978 if (dsa != NULL)
979 DSA_free(dsa);
980 if (ecdsa != NULL)
981 EC_KEY_free(ecdsa);
982
983 return NULL;
984 }
985
986
987 BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen)
988 {
989 buffer_t *msg = NULL;
990 char *s;
991
992 msg = buffer_init();
993 if (msg == NULL) {
994 // TODO: error check
995 return FALSE;
996 }
997
998 switch (keypair->type) {
999 case KEY_RSA: // RSA
1000 {
1001 const EVP_MD *evp_md = EVP_sha1();
1002 EVP_MD_CTX md;
1003 u_char digest[EVP_MAX_MD_SIZE], *sig;
1004 u_int slen, dlen, len;
1005 int ok, nid = NID_sha1;
1006
1007 // �_�C�W�F�X�g�l���v�Z
1008 EVP_DigestInit(&md, evp_md);
1009 EVP_DigestUpdate(&md, data, datalen);
1010 EVP_DigestFinal(&md, digest, &dlen);
1011
1012 slen = RSA_size(keypair->rsa);
1013 sig = malloc(slen);
1014 if (sig == NULL)
1015 goto error;
1016
1017 // �d�q�������v�Z
1018 ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa);
1019 memset(digest, 'd', sizeof(digest));
1020 if (ok != 1) { // error
1021 free(sig);
1022 goto error;
1023 }
1024 // �������T�C�Y���o�b�t�@���������������A�������������B�������[�����������B
1025 if (len < slen) {
1026 u_int diff = slen - len;
1027 memmove(sig + diff, sig, len);
1028 memset(sig, 0, diff);
1029
1030 } else if (len > slen) {
1031 free(sig);
1032 goto error;
1033
1034 } else {
1035 // do nothing
1036
1037 }
1038
1039 s = get_sshname_from_key(keypair);
1040 buffer_put_string(msg, s, strlen(s));
1041 buffer_append_length(msg, sig, slen);
1042 len = buffer_len(msg);
1043
1044 // setting
1045 *siglen = len;
1046 *sigptr = malloc(len);
1047 if (*sigptr == NULL) {
1048 free(sig);
1049 goto error;
1050 }
1051 memcpy(*sigptr, buffer_ptr(msg), len);
1052 free(sig);
1053
1054 break;
1055 }
1056 case KEY_DSA: // DSA
1057 {
1058 DSA_SIG *sig;
1059 const EVP_MD *evp_md = EVP_sha1();
1060 EVP_MD_CTX md;
1061 u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
1062 u_int rlen, slen, len, dlen;
1063
1064 // �_�C�W�F�X�g���v�Z
1065 EVP_DigestInit(&md, evp_md);
1066 EVP_DigestUpdate(&md, data, datalen);
1067 EVP_DigestFinal(&md, digest, &dlen);
1068
1069 // DSA�d�q�������v�Z
1070 sig = DSA_do_sign(digest, dlen, keypair->dsa);
1071 memset(digest, 'd', sizeof(digest));
1072 if (sig == NULL) {
1073 goto error;
1074 }
1075
1076 // BIGNUM�����o�C�i���l��������
1077 rlen = BN_num_bytes(sig->r);
1078 slen = BN_num_bytes(sig->s);
1079 if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
1080 DSA_SIG_free(sig);
1081 goto error;
1082 }
1083 memset(sigblob, 0, SIGBLOB_LEN);
1084 BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
1085 BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
1086 DSA_SIG_free(sig);
1087
1088 // setting
1089 s = get_sshname_from_key(keypair);
1090 buffer_put_string(msg, s, strlen(s));
1091 buffer_append_length(msg, sigblob, sizeof(sigblob));
1092 len = buffer_len(msg);
1093
1094 // setting
1095 *siglen = len;
1096 *sigptr = malloc(len);
1097 if (*sigptr == NULL) {
1098 goto error;
1099 }
1100 memcpy(*sigptr, buffer_ptr(msg), len);
1101
1102 break;
1103 }
1104 case KEY_ECDSA256: // ECDSA
1105 case KEY_ECDSA384:
1106 case KEY_ECDSA521:
1107 {
1108 ECDSA_SIG *sig;
1109 const EVP_MD *evp_md;
1110 EVP_MD_CTX md;
1111 u_char digest[EVP_MAX_MD_SIZE];
1112 u_int len, dlen, nid;
1113 buffer_t *buf2 = NULL;
1114
1115 switch (keypair->type) {
1116 case KEY_ECDSA256:
1117 nid = NID_sha256;
1118 break;
1119 case KEY_ECDSA384:
1120 nid = NID_sha384;
1121 break;
1122 case KEY_ECDSA521:
1123 nid = NID_sha512;
1124 break;
1125 }
1126 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
1127 goto error;
1128 }
1129 EVP_DigestInit(&md, evp_md);
1130 EVP_DigestUpdate(&md, data, datalen);
1131 EVP_DigestFinal(&md, digest, &dlen);
1132
1133 sig = ECDSA_do_sign(digest, dlen, keypair->ecdsa);
1134 memset(digest, 'd', sizeof(digest));
1135
1136 if (sig == NULL) {
1137 goto error;
1138 }
1139
1140 buf2 = buffer_init();
1141 if (buf2 == NULL) {
1142 // TODO: error check
1143 goto error;
1144 }
1145 buffer_put_bignum2(buf2, sig->r);
1146 buffer_put_bignum2(buf2, sig->s);
1147 ECDSA_SIG_free(sig);
1148
1149 s = get_sshname_from_key(keypair);
1150 buffer_put_string(msg, s, strlen(s));
1151 buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2));
1152 buffer_free(buf2);
1153 len = buffer_len(msg);
1154
1155 *siglen = len;
1156 *sigptr = malloc(len);
1157 if (*sigptr == NULL) {
1158 goto error;
1159 }
1160 memcpy(*sigptr, buffer_ptr(msg), len);
1161
1162 break;
1163 }
1164 default:
1165 buffer_free(msg);
1166 return FALSE;
1167 break;
1168 }
1169
1170 buffer_free(msg);
1171 return TRUE;
1172
1173 error:
1174 buffer_free(msg);
1175
1176 return FALSE;
1177 }
1178
1179
1180 BOOL get_SSH2_publickey_blob(PTInstVar pvar, buffer_t **blobptr, int *bloblen)
1181 {
1182 buffer_t *msg = NULL;
1183 Key *keypair;
1184 char *s, *tmp;
1185
1186 msg = buffer_init();
1187 if (msg == NULL) {
1188 // TODO: error check
1189 return FALSE;
1190 }
1191
1192 keypair = pvar->auth_state.cur_cred.key_pair;
1193
1194 switch (keypair->type) {
1195 case KEY_RSA: // RSA
1196 s = get_sshname_from_key(keypair);
1197 buffer_put_string(msg, s, strlen(s));
1198 buffer_put_bignum2(msg, keypair->rsa->e); // ���J�w��
1199 buffer_put_bignum2(msg, keypair->rsa->n); // p�~q
1200 break;
1201 case KEY_DSA: // DSA
1202 s = get_sshname_from_key(keypair);
1203 buffer_put_string(msg, s, strlen(s));
1204 buffer_put_bignum2(msg, keypair->dsa->p); // �f��
1205 buffer_put_bignum2(msg, keypair->dsa->q); // (p-1)���f����
1206 buffer_put_bignum2(msg, keypair->dsa->g); // ����
1207 buffer_put_bignum2(msg, keypair->dsa->pub_key); // ���J��
1208 break;
1209 case KEY_ECDSA256: // ECDSA
1210 case KEY_ECDSA384:
1211 case KEY_ECDSA521:
1212 s = get_sshname_from_key(keypair);
1213 buffer_put_string(msg, s, strlen(s));
1214 tmp = curve_keytype_to_name(keypair->type);
1215 buffer_put_string(msg, tmp, strlen(tmp));
1216 buffer_put_ecpoint(msg, EC_KEY_get0_group(keypair->ecdsa),
1217 EC_KEY_get0_public_key(keypair->ecdsa));
1218 break;
1219 default:
1220 return FALSE;
1221 }
1222
1223 *blobptr = msg;
1224 *bloblen = buffer_len(msg);
1225
1226 return TRUE;
1227 }

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