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 4378 - (show annotations) (download) (as text)
Tue Mar 8 14:19:03 2011 UTC (13 years, 1 month ago) by maya
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 27254 byte(s)
SSH2 の 圧縮で none を利用できるように修正した。
ソース整理
  鍵形式・KEXプロトコル・MAC・圧縮の名前や関数を取得する関数を作成。
    これにより定義で順序を入れ替えてもよくなった。
  enum に型名を付けた。
  共通の関数を使えるところで使うようにした。
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, 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_key(Key *key)
704 {
705 return get_ssh_keytype_name(key->type);
706 }
707
708 //
709 // �L�[������������������������
710 //
711 ssh_keytype get_keytype_from_name(char *name)
712 {
713 if (strcmp(name, "rsa1") == 0) {
714 return KEY_RSA1;
715 } else if (strcmp(name, "rsa") == 0) {
716 return KEY_RSA;
717 } else if (strcmp(name, "dsa") == 0) {
718 return KEY_DSA;
719 } else if (strcmp(name, "ssh-rsa") == 0) {
720 return KEY_RSA;
721 } else if (strcmp(name, "ssh-dss") == 0) {
722 return KEY_DSA;
723 } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
724 return KEY_ECDSA256;
725 } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
726 return KEY_ECDSA384;
727 } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
728 return KEY_ECDSA521;
729 }
730 return KEY_UNSPEC;
731 }
732
733
734 ssh_keytype key_curve_name_to_keytype(char *name)
735 {
736 if (strcmp(name, "nistp256") == 0) {
737 return KEY_ECDSA256;
738 } else if (strcmp(name, "nistp384") == 0) {
739 return KEY_ECDSA384;
740 } else if (strcmp(name, "nistp521") == 0) {
741 return KEY_ECDSA521;
742 }
743 return KEY_UNSPEC;
744 }
745
746 char *curve_keytype_to_name(ssh_keytype type)
747 {
748 switch (type) {
749 case KEY_ECDSA256:
750 return "nistp256";
751 break;
752 case KEY_ECDSA384:
753 return "nistp384";
754 break;
755 case KEY_ECDSA521:
756 return "nistp521";
757 break;
758 }
759 return NULL;
760 }
761
762 //
763 // �L�[���������o�b�t�@���������� (for SSH2)
764 // NOTE:
765 //
766 int key_to_blob(Key *key, char **blobp, int *lenp)
767 {
768 buffer_t *b;
769 char *sshname, *tmp;
770 int len;
771 int ret = 1; // success
772
773 b = buffer_init();
774 sshname = get_sshname_from_key(key);
775
776 switch (key->type) {
777 case KEY_RSA:
778 buffer_put_string(b, sshname, strlen(sshname));
779 buffer_put_bignum2(b, key->rsa->e);
780 buffer_put_bignum2(b, key->rsa->n);
781 break;
782 case KEY_DSA:
783 buffer_put_string(b, sshname, strlen(sshname));
784 buffer_put_bignum2(b, key->dsa->p);
785 buffer_put_bignum2(b, key->dsa->q);
786 buffer_put_bignum2(b, key->dsa->g);
787 buffer_put_bignum2(b, key->dsa->pub_key);
788 break;
789 case KEY_ECDSA256:
790 case KEY_ECDSA384:
791 case KEY_ECDSA521:
792 buffer_put_string(b, sshname, strlen(sshname));
793 tmp = curve_keytype_to_name(key->type);
794 buffer_put_string(b, tmp, strlen(tmp));
795 buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
796 EC_KEY_get0_public_key(key->ecdsa));
797 break;
798
799 default:
800 ret = 0;
801 goto error;
802 }
803
804 len = buffer_len(b);
805 if (lenp != NULL)
806 *lenp = len;
807 if (blobp != NULL) {
808 *blobp = malloc(len);
809 if (*blobp == NULL) {
810 ret = 0;
811 goto error;
812 }
813 memcpy(*blobp, buffer_ptr(b), len);
814 }
815
816 error:
817 buffer_free(b);
818
819 return (ret);
820 }
821
822
823 //
824 // �o�b�t�@�����L�[�����������o��(for SSH2)
825 // NOTE: ���l���A���P�[�g���������������A�����o�������������������B
826 //
827 Key *key_from_blob(char *data, int blen)
828 {
829 int keynamelen;
830 char key[128];
831 RSA *rsa = NULL;
832 DSA *dsa = NULL;
833 EC_KEY *ecdsa = NULL;
834 EC_POINT *q = NULL;
835 char *curve = NULL;
836 Key *hostkey; // hostkey
837 ssh_keytype type;
838
839 hostkey = malloc(sizeof(Key));
840 if (hostkey == NULL)
841 goto error;
842
843 memset(hostkey, 0, sizeof(Key));
844
845 keynamelen = get_uint32_MSBfirst(data);
846 if (keynamelen >= sizeof(key)) {
847 goto error;
848 }
849 data += 4;
850 memcpy(key, data, keynamelen);
851 key[keynamelen] = 0;
852 data += keynamelen;
853
854 type = get_keytype_from_name(key);
855
856 switch (type) {
857 case KEY_RSA: // RSA key
858 rsa = RSA_new();
859 if (rsa == NULL) {
860 goto error;
861 }
862 rsa->n = BN_new();
863 rsa->e = BN_new();
864 if (rsa->n == NULL || rsa->e == NULL) {
865 goto error;
866 }
867
868 buffer_get_bignum2(&data, rsa->e);
869 buffer_get_bignum2(&data, rsa->n);
870
871 hostkey->type = type;
872 hostkey->rsa = rsa;
873 break;
874
875 case KEY_DSA: // DSA key
876 dsa = DSA_new();
877 if (dsa == NULL) {
878 goto error;
879 }
880 dsa->p = BN_new();
881 dsa->q = BN_new();
882 dsa->g = BN_new();
883 dsa->pub_key = BN_new();
884 if (dsa->p == NULL ||
885 dsa->q == NULL ||
886 dsa->g == NULL ||
887 dsa->pub_key == NULL) {
888 goto error;
889 }
890
891 buffer_get_bignum2(&data, dsa->p);
892 buffer_get_bignum2(&data, dsa->q);
893 buffer_get_bignum2(&data, dsa->g);
894 buffer_get_bignum2(&data, dsa->pub_key);
895
896 hostkey->type = type;
897 hostkey->dsa = dsa;
898 break;
899
900 case KEY_ECDSA256: // ECDSA
901 case KEY_ECDSA384:
902 case KEY_ECDSA521:
903 curve = buffer_get_string(&data, NULL);
904 if (type != key_curve_name_to_keytype(curve)) {
905 goto error;
906 }
907
908 ecdsa = EC_KEY_new_by_curve_name(keytype_to_cipher_nid(type));
909 if (ecdsa == NULL) {
910 goto error;
911 }
912
913 q = EC_POINT_new(EC_KEY_get0_group(ecdsa));
914 if (q == NULL) {
915 goto error;
916 }
917
918 buffer_get_ecpoint(&data, EC_KEY_get0_group(ecdsa), q);
919 if (key_ec_validate_public(EC_KEY_get0_group(ecdsa), q) == -1) {
920 goto error;
921 }
922
923 if (EC_KEY_set_public_key(ecdsa, q) != 1) {
924 goto error;
925 }
926
927 hostkey->type = type;
928 hostkey->ecdsa = ecdsa;
929 break;
930
931 default: // unknown key
932 goto error;
933 }
934
935 return (hostkey);
936
937 error:
938 if (rsa != NULL)
939 RSA_free(rsa);
940 if (dsa != NULL)
941 DSA_free(dsa);
942 if (ecdsa != NULL)
943 EC_KEY_free(ecdsa);
944
945 return NULL;
946 }
947
948
949 BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen)
950 {
951 buffer_t *msg = NULL;
952 char *s;
953
954 msg = buffer_init();
955 if (msg == NULL) {
956 // TODO: error check
957 return FALSE;
958 }
959
960 switch (keypair->type) {
961 case KEY_RSA: // RSA
962 {
963 const EVP_MD *evp_md = EVP_sha1();
964 EVP_MD_CTX md;
965 u_char digest[EVP_MAX_MD_SIZE], *sig;
966 u_int slen, dlen, len;
967 int ok, nid = NID_sha1;
968
969 // �_�C�W�F�X�g�l���v�Z
970 EVP_DigestInit(&md, evp_md);
971 EVP_DigestUpdate(&md, data, datalen);
972 EVP_DigestFinal(&md, digest, &dlen);
973
974 slen = RSA_size(keypair->rsa);
975 sig = malloc(slen);
976 if (sig == NULL)
977 goto error;
978
979 // �d�q�������v�Z
980 ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa);
981 memset(digest, 'd', sizeof(digest));
982 if (ok != 1) { // error
983 free(sig);
984 goto error;
985 }
986 // �������T�C�Y���o�b�t�@���������������A�������������B�������[�����������B
987 if (len < slen) {
988 u_int diff = slen - len;
989 memmove(sig + diff, sig, len);
990 memset(sig, 0, diff);
991
992 } else if (len > slen) {
993 free(sig);
994 goto error;
995
996 } else {
997 // do nothing
998
999 }
1000
1001 s = get_sshname_from_key(keypair);
1002 buffer_put_string(msg, s, strlen(s));
1003 buffer_append_length(msg, sig, slen);
1004 len = buffer_len(msg);
1005
1006 // setting
1007 *siglen = len;
1008 *sigptr = malloc(len);
1009 if (*sigptr == NULL) {
1010 free(sig);
1011 goto error;
1012 }
1013 memcpy(*sigptr, buffer_ptr(msg), len);
1014 free(sig);
1015
1016 break;
1017 }
1018 case KEY_DSA: // DSA
1019 {
1020 DSA_SIG *sig;
1021 const EVP_MD *evp_md = EVP_sha1();
1022 EVP_MD_CTX md;
1023 u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
1024 u_int rlen, slen, len, dlen;
1025
1026 // �_�C�W�F�X�g���v�Z
1027 EVP_DigestInit(&md, evp_md);
1028 EVP_DigestUpdate(&md, data, datalen);
1029 EVP_DigestFinal(&md, digest, &dlen);
1030
1031 // DSA�d�q�������v�Z
1032 sig = DSA_do_sign(digest, dlen, keypair->dsa);
1033 memset(digest, 'd', sizeof(digest));
1034 if (sig == NULL) {
1035 goto error;
1036 }
1037
1038 // BIGNUM�����o�C�i���l��������
1039 rlen = BN_num_bytes(sig->r);
1040 slen = BN_num_bytes(sig->s);
1041 if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
1042 DSA_SIG_free(sig);
1043 goto error;
1044 }
1045 memset(sigblob, 0, SIGBLOB_LEN);
1046 BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
1047 BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
1048 DSA_SIG_free(sig);
1049
1050 // setting
1051 s = get_sshname_from_key(keypair);
1052 buffer_put_string(msg, s, strlen(s));
1053 buffer_append_length(msg, sigblob, sizeof(sigblob));
1054 len = buffer_len(msg);
1055
1056 // setting
1057 *siglen = len;
1058 *sigptr = malloc(len);
1059 if (*sigptr == NULL) {
1060 goto error;
1061 }
1062 memcpy(*sigptr, buffer_ptr(msg), len);
1063
1064 break;
1065 }
1066 case KEY_ECDSA256: // ECDSA
1067 case KEY_ECDSA384:
1068 case KEY_ECDSA521:
1069 {
1070 ECDSA_SIG *sig;
1071 const EVP_MD *evp_md;
1072 EVP_MD_CTX md;
1073 u_char digest[EVP_MAX_MD_SIZE];
1074 u_int len, dlen, nid;
1075 buffer_t *buf2 = NULL;
1076
1077 nid = keytype_to_hash_nid(keypair->type);
1078 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
1079 goto error;
1080 }
1081 EVP_DigestInit(&md, evp_md);
1082 EVP_DigestUpdate(&md, data, datalen);
1083 EVP_DigestFinal(&md, digest, &dlen);
1084
1085 sig = ECDSA_do_sign(digest, dlen, keypair->ecdsa);
1086 memset(digest, 'd', sizeof(digest));
1087
1088 if (sig == NULL) {
1089 goto error;
1090 }
1091
1092 buf2 = buffer_init();
1093 if (buf2 == NULL) {
1094 // TODO: error check
1095 goto error;
1096 }
1097 buffer_put_bignum2(buf2, sig->r);
1098 buffer_put_bignum2(buf2, sig->s);
1099 ECDSA_SIG_free(sig);
1100
1101 s = get_sshname_from_key(keypair);
1102 buffer_put_string(msg, s, strlen(s));
1103 buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2));
1104 buffer_free(buf2);
1105 len = buffer_len(msg);
1106
1107 *siglen = len;
1108 *sigptr = malloc(len);
1109 if (*sigptr == NULL) {
1110 goto error;
1111 }
1112 memcpy(*sigptr, buffer_ptr(msg), len);
1113
1114 break;
1115 }
1116 default:
1117 buffer_free(msg);
1118 return FALSE;
1119 break;
1120 }
1121
1122 buffer_free(msg);
1123 return TRUE;
1124
1125 error:
1126 buffer_free(msg);
1127
1128 return FALSE;
1129 }
1130
1131
1132 BOOL get_SSH2_publickey_blob(PTInstVar pvar, buffer_t **blobptr, int *bloblen)
1133 {
1134 buffer_t *msg = NULL;
1135 Key *keypair;
1136 char *s, *tmp;
1137
1138 msg = buffer_init();
1139 if (msg == NULL) {
1140 // TODO: error check
1141 return FALSE;
1142 }
1143
1144 keypair = pvar->auth_state.cur_cred.key_pair;
1145
1146 switch (keypair->type) {
1147 case KEY_RSA: // RSA
1148 s = get_sshname_from_key(keypair);
1149 buffer_put_string(msg, s, strlen(s));
1150 buffer_put_bignum2(msg, keypair->rsa->e); // ���J�w��
1151 buffer_put_bignum2(msg, keypair->rsa->n); // p�~q
1152 break;
1153 case KEY_DSA: // DSA
1154 s = get_sshname_from_key(keypair);
1155 buffer_put_string(msg, s, strlen(s));
1156 buffer_put_bignum2(msg, keypair->dsa->p); // �f��
1157 buffer_put_bignum2(msg, keypair->dsa->q); // (p-1)���f����
1158 buffer_put_bignum2(msg, keypair->dsa->g); // ����
1159 buffer_put_bignum2(msg, keypair->dsa->pub_key); // ���J��
1160 break;
1161 case KEY_ECDSA256: // ECDSA
1162 case KEY_ECDSA384:
1163 case KEY_ECDSA521:
1164 s = get_sshname_from_key(keypair);
1165 buffer_put_string(msg, s, strlen(s));
1166 tmp = curve_keytype_to_name(keypair->type);
1167 buffer_put_string(msg, tmp, strlen(tmp));
1168 buffer_put_ecpoint(msg, EC_KEY_get0_group(keypair->ecdsa),
1169 EC_KEY_get0_public_key(keypair->ecdsa));
1170 break;
1171 default:
1172 return FALSE;
1173 }
1174
1175 *blobptr = msg;
1176 *bloblen = buffer_len(msg);
1177
1178 return TRUE;
1179 }
1180
1181 int kextype_to_cipher_nid(kex_algorithm type)
1182 {
1183 switch (type) {
1184 case KEX_ECDH_SHA2_256:
1185 return NID_X9_62_prime256v1;
1186 case KEX_ECDH_SHA2_384:
1187 return NID_secp384r1;
1188 case KEX_ECDH_SHA2_521:
1189 return NID_secp521r1;
1190 }
1191 return NID_undef;
1192 }
1193
1194 int keytype_to_hash_nid(ssh_keytype type)
1195 {
1196 switch (type) {
1197 case KEY_ECDSA256:
1198 return NID_sha256;
1199 case KEY_ECDSA384:
1200 return NID_sha384;
1201 case KEY_ECDSA521:
1202 return NID_sha512;
1203 }
1204 return NID_undef;
1205 }
1206
1207 int keytype_to_cipher_nid(ssh_keytype type)
1208 {
1209 switch (type) {
1210 case KEY_ECDSA256:
1211 return NID_X9_62_prime256v1;
1212 case KEY_ECDSA384:
1213 return NID_secp384r1;
1214 case KEY_ECDSA521:
1215 return NID_secp521r1;
1216 }
1217 return NID_undef;
1218 }
1219
1220 ssh_keytype nid_to_keytype(int nid)
1221 {
1222 switch (nid) {
1223 case NID_X9_62_prime256v1:
1224 return KEY_ECDSA256;
1225 case NID_secp384r1:
1226 return KEY_ECDSA384;
1227 case NID_secp521r1:
1228 return KEY_ECDSA521;
1229 }
1230 return KEY_UNSPEC;
1231 }

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