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

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