Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/ttssh2/ttxssh/key.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9255 - (show annotations) (download) (as text)
Wed May 19 14:11:26 2021 UTC (2 years, 9 months ago) by nmaya
File MIME type: text/x-csrc
File size: 62063 byte(s)
SSH2 暗号化方式 chacha20-poly1305@openssh.com をサポート

merge from branches/ssh_chacha20poly1305
r9209, r9210, r9211, r9212, r9217, r9229, r9248, r9249, r9250, r9251, r9252, r9253
1 /*
2 * (C) 2011- TeraTerm Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 #include "key.h"
29 #include "resource.h"
30 #include "dlglib.h"
31
32 #include <openssl/rsa.h>
33 #include <openssl/dsa.h>
34 #include <openssl/ecdsa.h>
35 #include <openssl/buffer.h>
36
37 #undef DialogBoxParam
38 #define DialogBoxParam(p1,p2,p3,p4,p5) \
39 TTDialogBoxParam(p1,p2,p3,p4,p5)
40 #undef EndDialog
41 #define EndDialog(p1,p2) \
42 TTEndDialog(p1, p2)
43
44 #define INTBLOB_LEN 20
45 #define SIGBLOB_LEN (2*INTBLOB_LEN)
46
47
48 struct hostkeys_update_ctx {
49 /* The hostname and (optionally) IP address string for the server */
50 char *host_str, *ip_str;
51
52 /*
53 * Keys received from the server and a flag for each indicating
54 * whether they already exist in known_hosts.
55 * keys_seen is filled in by hostkeys_find() and later (for new
56 * keys) by client_global_hostkeys_private_confirm().
57 */
58 Key **keys;
59 int *keys_seen;
60 size_t nkeys;
61
62 size_t nnew;
63
64 /*
65 * Keys that are in known_hosts, but were not present in the update
66 * from the server (i.e. scheduled to be deleted).
67 * Filled in by hostkeys_find().
68 */
69 Key **old_keys;
70 size_t nold;
71 };
72
73
74 //////////////////////////////////////////////////////////////////////////////
75 //
76 // Key verify function
77 //
78 //////////////////////////////////////////////////////////////////////////////
79
80 //
81 // DSS
82 //
83
84 int ssh_dss_verify(DSA *key,
85 u_char *signature, u_int signaturelen,
86 u_char *data, u_int datalen)
87 {
88 DSA_SIG *sig;
89 const EVP_MD *evp_md = EVP_sha1();
90 EVP_MD_CTX *md = NULL;
91 unsigned char digest[EVP_MAX_MD_SIZE], *sigblob;
92 unsigned int len, dlen;
93 int ret = -1;
94 char *ptr;
95 BIGNUM *r, *s;
96
97 md = EVP_MD_CTX_new();
98 if (md == NULL) {
99 ret = -1;
100 goto error;
101 }
102
103 OpenSSL_add_all_digests();
104
105 if (key == NULL) {
106 ret = -2;
107 goto error;
108 }
109
110 ptr = signature;
111
112 // step1
113 if (signaturelen == 0x28) {
114 // workaround for SSH-2.0-2.0* and SSH-2.0-2.1* (2006.11.18 maya)
115 ptr -= 4;
116 }
117 else {
118 len = get_uint32_MSBfirst(ptr);
119 ptr += 4;
120 if (strncmp("ssh-dss", ptr, len) != 0) {
121 ret = -3;
122 goto error;
123 }
124 ptr += len;
125 }
126
127 // step2
128 len = get_uint32_MSBfirst(ptr);
129 ptr += 4;
130 sigblob = ptr;
131 ptr += len;
132
133 if (len != SIGBLOB_LEN) {
134 ret = -4;
135 goto error;
136 }
137
138 /* parse signature */
139 if ((sig = DSA_SIG_new()) == NULL) {
140 ret = -5;
141 goto error;
142 }
143 if ((r = BN_new()) == NULL) {
144 ret = -6;
145 goto error;
146 }
147 if ((s = BN_new()) == NULL) {
148 ret = -7;
149 goto error;
150 }
151 DSA_SIG_set0(sig, r, s);
152 BN_bin2bn(sigblob, INTBLOB_LEN, r);
153 BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, s);
154
155 /* sha1 the data */
156 EVP_DigestInit(md, evp_md);
157 EVP_DigestUpdate(md, data, datalen);
158 EVP_DigestFinal(md, digest, &dlen);
159
160 ret = DSA_do_verify(digest, dlen, sig, key);
161 SecureZeroMemory(digest, sizeof(digest));
162
163 DSA_SIG_free(sig);
164
165 error:
166 if (md)
167 EVP_MD_CTX_free(md);
168
169 return ret;
170 }
171
172
173 //
174 // RSA
175 //
176
177 /*
178 * See:
179 * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
180 * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
181 */
182 /*
183 * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
184 * oiw(14) secsig(3) algorithms(2) 26 }
185 */
186 static const u_char id_sha1[] = {
187 0x30, 0x21, /* type Sequence, length 0x21 (33) */
188 0x30, 0x09, /* type Sequence, length 0x09 */
189 0x06, 0x05, /* type OID, length 0x05 */
190 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
191 0x05, 0x00, /* NULL */
192 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
193 };
194 /*
195 * id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
196 * rsadsi(113549) digestAlgorithm(2) 5 }
197 */
198 static const u_char id_md5[] = {
199 0x30, 0x20, /* type Sequence, length 0x20 (32) */
200 0x30, 0x0c, /* type Sequence, length 0x09 */
201 0x06, 0x08, /* type OID, length 0x05 */
202 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */
203 0x05, 0x00, /* NULL */
204 0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */
205 };
206
207 static int openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
208 u_char *sigbuf, u_int siglen, RSA *rsa)
209 {
210 u_int ret, rsasize, oidlen = 0, hlen = 0;
211 int len;
212 const u_char *oid = NULL;
213 u_char *decrypted = NULL;
214
215 ret = 0;
216 switch (type) {
217 case NID_sha1:
218 oid = id_sha1;
219 oidlen = sizeof(id_sha1);
220 hlen = 20;
221 break;
222 case NID_md5:
223 oid = id_md5;
224 oidlen = sizeof(id_md5);
225 hlen = 16;
226 break;
227 default:
228 goto done;
229 break;
230 }
231 if (hashlen != hlen) {
232 //error("bad hashlen");
233 goto done;
234 }
235 rsasize = RSA_size(rsa);
236 if (siglen == 0 || siglen > rsasize) {
237 //error("bad siglen");
238 goto done;
239 }
240 decrypted = malloc(rsasize);
241 if (decrypted == NULL)
242 return 0; // error
243
244 if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
245 RSA_PKCS1_PADDING)) < 0) {
246 //error("RSA_public_decrypt failed: %s",
247 // ERR_error_string(ERR_get_error(), NULL));
248 goto done;
249 }
250 if (len != hlen + oidlen) {
251 //error("bad decrypted len: %d != %d + %d", len, hlen, oidlen);
252 goto done;
253 }
254 if (memcmp(decrypted, oid, oidlen) != 0) {
255 //error("oid mismatch");
256 goto done;
257 }
258 if (memcmp(decrypted + oidlen, hash, hlen) != 0) {
259 //error("hash mismatch");
260 goto done;
261 }
262 ret = 1;
263 done:
264 if (decrypted)
265 free(decrypted);
266 return ret;
267 }
268
269 int ssh_rsa_verify(RSA *key,
270 u_char *signature, u_int signaturelen,
271 u_char *data, u_int datalen)
272 {
273 const EVP_MD *evp_md;
274 EVP_MD_CTX *md = NULL;
275 // char *ktype;
276 u_char digest[EVP_MAX_MD_SIZE], *sigblob;
277 u_int len, dlen, modlen;
278 // int rlen, ret, nid;
279 int ret = -1, nid;
280 char *ptr;
281 BIGNUM *n;
282
283 md = EVP_MD_CTX_new();
284 if (md == NULL) {
285 ret = -1;
286 goto error;
287 }
288
289 OpenSSL_add_all_digests();
290
291 if (key == NULL) {
292 ret = -2;
293 goto error;
294 }
295
296 RSA_get0_key(key, &n, NULL, NULL);
297 if (BN_num_bits(n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
298 ret = -3;
299 goto error;
300 }
301 //debug_print(41, signature, signaturelen);
302 ptr = signature;
303
304 // step1
305 len = get_uint32_MSBfirst(ptr);
306 ptr += 4;
307 if (strncmp("ssh-rsa", ptr, len) != 0) {
308 ret = -4;
309 goto error;
310 }
311 ptr += len;
312
313 // step2
314 len = get_uint32_MSBfirst(ptr);
315 ptr += 4;
316 sigblob = ptr;
317 ptr += len;
318 #if 0
319 rlen = get_uint32_MSBfirst(ptr);
320 if (rlen != 0) {
321 return -1;
322 }
323 #endif
324
325 /* RSA_verify expects a signature of RSA_size */
326 modlen = RSA_size(key);
327 if (len > modlen) {
328 ret = -5;
329 goto error;
330
331 } else if (len < modlen) {
332 u_int diff = modlen - len;
333 sigblob = realloc(sigblob, modlen);
334 memmove(sigblob + diff, sigblob, len);
335 memset(sigblob, 0, diff);
336 len = modlen;
337 }
338
339 /* sha1 the data */
340 // nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
341 nid = NID_sha1;
342 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
343 //error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid);
344 ret = -6;
345 goto error;
346 }
347 EVP_DigestInit(md, evp_md);
348 EVP_DigestUpdate(md, data, datalen);
349 EVP_DigestFinal(md, digest, &dlen);
350
351 ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key);
352
353 SecureZeroMemory(digest, sizeof(digest));
354 SecureZeroMemory(sigblob, len);
355 //free(sigblob);
356 //debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
357
358 error:
359 if (md)
360 EVP_MD_CTX_free(md);
361
362 return ret;
363 }
364
365 int ssh_ecdsa_verify(EC_KEY *key, ssh_keytype keytype,
366 u_char *signature, u_int signaturelen,
367 u_char *data, u_int datalen)
368 {
369 ECDSA_SIG *sig;
370 const EVP_MD *evp_md;
371 EVP_MD_CTX *md = NULL;
372 unsigned char digest[EVP_MAX_MD_SIZE], *sigblob;
373 unsigned int len, dlen;
374 int ret = -1, nid = NID_undef;
375 char *ptr;
376 BIGNUM *r, *s;
377
378 md = EVP_MD_CTX_new();
379 if (md == NULL) {
380 ret = -1;
381 goto error;
382 }
383
384 OpenSSL_add_all_digests();
385
386 if (key == NULL) {
387 ret = -2;
388 goto error;
389 }
390
391 ptr = signature;
392
393 len = get_uint32_MSBfirst(ptr);
394 ptr += 4;
395 if (strncmp(get_ssh2_hostkey_type_name(keytype), ptr, len) != 0) {
396 ret = -3;
397 goto error;
398 }
399 ptr += len;
400
401 len = get_uint32_MSBfirst(ptr);
402 ptr += 4;
403 sigblob = ptr;
404 ptr += len;
405
406 /* parse signature */
407 if ((sig = ECDSA_SIG_new()) == NULL) {
408 ret = -4;
409 goto error;
410 }
411 if ((r = BN_new()) == NULL) {
412 ret = -5;
413 goto error;
414 }
415 if ((s = BN_new()) == NULL) {
416 ret = -6;
417 goto error;
418 }
419
420 ECDSA_SIG_set0(sig, r, s);
421 buffer_get_bignum2(&sigblob, r);
422 buffer_get_bignum2(&sigblob, s);
423 if (sigblob != ptr) {
424 ret = -7;
425 goto error;
426 }
427
428 /* hash the data */
429 nid = keytype_to_hash_nid(keytype);
430 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
431 ret = -8;
432 goto error;
433 }
434 EVP_DigestInit(md, evp_md);
435 EVP_DigestUpdate(md, data, datalen);
436 EVP_DigestFinal(md, digest, &dlen);
437
438 ret = ECDSA_do_verify(digest, dlen, sig, key);
439 SecureZeroMemory(digest, sizeof(digest));
440
441 ECDSA_SIG_free(sig);
442
443 error:
444 if (md)
445 EVP_MD_CTX_free(md);
446
447 return ret;
448 }
449
450 static int ssh_ed25519_verify(Key *key, unsigned char *signature, unsigned int signaturelen,
451 unsigned char *data, unsigned int datalen)
452 {
453 buffer_t *b;
454 char *ktype = NULL;
455 unsigned char *sigblob = NULL, *sm = NULL, *m = NULL;
456 unsigned int len;
457 unsigned long long smlen, mlen;
458 int rlen, ret;
459 char *bptr;
460
461 ret = -1;
462 b = buffer_init();
463 if (b == NULL)
464 goto error;
465
466 buffer_append(b, signature, signaturelen);
467 bptr = buffer_ptr(b);
468 ktype = buffer_get_string(&bptr, NULL);
469 if (strcmp("ssh-ed25519", ktype) != 0) {
470 goto error;
471 }
472 sigblob = buffer_get_string(&bptr, &len);
473 rlen = buffer_remain_len(b);
474 if (rlen != 0) {
475 goto error;
476 }
477 if (len > crypto_sign_ed25519_BYTES) {
478 goto error;
479 }
480
481 smlen = len + datalen;
482 sm = malloc((size_t)smlen);
483 memcpy(sm, sigblob, len);
484 memcpy(sm+len, data, datalen);
485 mlen = smlen;
486 m = malloc((size_t)mlen);
487
488 if ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen,
489 key->ed25519_pk)) != 0) {
490 //debug2("%s: crypto_sign_ed25519_open failed: %d",
491 // __func__, ret);
492 }
493 if (ret == 0 && mlen != datalen) {
494 //debug2("%s: crypto_sign_ed25519_open "
495 // "mlen != datalen (%llu != %u)", __func__, mlen, datalen);
496 ret = -1;
497 }
498 /* XXX compare 'm' and 'data' ? */
499
500 error:
501 buffer_free(b);
502 free(ktype);
503
504 if (sigblob) {
505 SecureZeroMemory(sigblob, len);
506 free(sigblob);
507 }
508 if (sm) {
509 SecureZeroMemory(sm, (size_t)smlen);
510 free(sm);
511 }
512 if (m) {
513 SecureZeroMemory(m, (size_t)smlen); /* NB. mlen may be invalid if ret != 0 */
514 free(m);
515 }
516
517 /* translate return code carefully */
518 return (ret == 0) ? 1 : -1;
519 }
520
521 int key_verify(Key *key,
522 unsigned char *signature, unsigned int signaturelen,
523 unsigned char *data, unsigned int datalen)
524 {
525 int ret = 0;
526
527 switch (key->type) {
528 case KEY_RSA:
529 ret = ssh_rsa_verify(key->rsa, signature, signaturelen, data, datalen);
530 break;
531 case KEY_DSA:
532 ret = ssh_dss_verify(key->dsa, signature, signaturelen, data, datalen);
533 break;
534 case KEY_ECDSA256:
535 case KEY_ECDSA384:
536 case KEY_ECDSA521:
537 ret = ssh_ecdsa_verify(key->ecdsa, key->type, signature, signaturelen, data, datalen);
538 break;
539 case KEY_ED25519:
540 ret = ssh_ed25519_verify(key, signature, signaturelen, data, datalen);
541 break;
542 default:
543 return -1;
544 }
545
546 return (ret); // success
547 }
548
549 static char *copy_mp_int(char *num)
550 {
551 int len = (get_ushort16_MSBfirst(num) + 7) / 8 + 2;
552 char *result = (char *) malloc(len);
553
554 if (result != NULL) {
555 memcpy(result, num, len);
556 }
557
558 return result;
559 }
560
561 //
562 // RSA�\����������
563 //
564 RSA *duplicate_RSA(RSA *src)
565 {
566 RSA *rsa = NULL;
567 BIGNUM *e = NULL, *n = NULL;
568 BIGNUM *se = NULL, *sn = NULL;
569
570 rsa = RSA_new();
571 if (rsa == NULL)
572 goto error;
573 n = BN_new();
574 e = BN_new();
575 RSA_set0_key(rsa, n, e, NULL);
576 if (n == NULL || e == NULL) {
577 RSA_free(rsa);
578 goto error;
579 }
580
581 RSA_get0_key(src, &sn, &se, NULL);
582
583 // �[���R�s�[(deep copy)���s���B�����R�s�[(shallow copy)��NG�B
584 BN_copy(n, sn);
585 BN_copy(e, se);
586
587 error:
588 return (rsa);
589 }
590
591
592 //
593 // DSA�\����������
594 //
595 DSA *duplicate_DSA(DSA *src)
596 {
597 DSA *dsa = NULL;
598 BIGNUM *p, *q, *g, *pub_key;
599 BIGNUM *sp, *sq, *sg, *spub_key;
600
601 dsa = DSA_new();
602 if (dsa == NULL)
603 goto error;
604 p = BN_new();
605 q = BN_new();
606 g = BN_new();
607 pub_key = BN_new();
608 DSA_set0_pqg(dsa, p, q, g);
609 DSA_set0_key(dsa, pub_key, NULL);
610 if (p == NULL ||
611 q == NULL ||
612 g == NULL ||
613 pub_key == NULL) {
614 DSA_free(dsa);
615 // ������������������������NULL�����������������B
616 // �����������`�F�b�N��ticket#39335�����u�\���B
617 dsa = NULL;
618 goto error;
619 }
620
621 // �[���R�s�[(deep copy)���s���B�����R�s�[(shallow copy)��NG�B
622 DSA_get0_pqg(src, &sp, &sq, &sg);
623 DSA_get0_key(src, &spub_key, NULL);
624 BN_copy(p, sp);
625 BN_copy(q, sq);
626 BN_copy(g, sg);
627 BN_copy(pub_key, spub_key);
628
629 error:
630 return (dsa);
631 }
632
633 unsigned char *duplicate_ED25519_PK(unsigned char *src)
634 {
635 unsigned char *ptr = NULL;
636
637 ptr = malloc(ED25519_PK_SZ);
638 if (ptr) {
639 memcpy(ptr, src, ED25519_PK_SZ);
640 }
641 return (ptr);
642 }
643
644 BOOL key_copy(Key *dest, Key *src)
645 {
646 key_init(dest);
647 switch (src->type) {
648 case KEY_RSA1: // SSH1
649 dest->type = KEY_RSA1;
650 dest->bits = src->bits;
651 dest->exp = copy_mp_int(src->exp);
652 dest->mod = copy_mp_int(src->mod);
653 break;
654 case KEY_RSA: // SSH2 RSA
655 dest->type = KEY_RSA;
656 dest->rsa = duplicate_RSA(src->rsa);
657 break;
658 case KEY_DSA: // SSH2 DSA
659 dest->type = KEY_DSA;
660 dest->dsa = duplicate_DSA(src->dsa);
661 break;
662 case KEY_ECDSA256:
663 case KEY_ECDSA384:
664 case KEY_ECDSA521:
665 dest->type = src->type;
666 dest->ecdsa = EC_KEY_dup(src->ecdsa);
667 break;
668 case KEY_ED25519:
669 dest->type = src->type;
670 dest->ed25519_pk = duplicate_ED25519_PK(src->ed25519_pk);
671 break;
672 default:
673 return FALSE;
674 }
675 return TRUE;
676 }
677
678 char* key_fingerprint_raw(Key *k, digest_algorithm dgst_alg, int *dgst_raw_length)
679 {
680 const EVP_MD *md = NULL;
681 EVP_MD_CTX *ctx = NULL;
682 char *blob = NULL;
683 char *retval = NULL;
684 int len = 0;
685 int nlen, elen;
686 RSA *rsa;
687 BIGNUM *e = NULL, *n = NULL;
688
689 ctx = EVP_MD_CTX_new();
690 if (ctx == NULL) {
691 goto error;
692 }
693
694 *dgst_raw_length = 0;
695
696 switch (dgst_alg) {
697 case SSH_DIGEST_MD5:
698 md = EVP_md5();
699 break;
700 case SSH_DIGEST_SHA1:
701 md = EVP_sha1();
702 break;
703 case SSH_DIGEST_SHA256:
704 md = EVP_sha256();
705 break;
706 default:
707 md = EVP_md5();
708 }
709
710 switch (k->type) {
711 case KEY_RSA1:
712 rsa = make_key(NULL, k->bits, k->exp, k->mod);
713 RSA_get0_key(rsa, &n, &e, NULL);
714 nlen = BN_num_bytes(n);
715 elen = BN_num_bytes(e);
716 len = nlen + elen;
717 blob = malloc(len);
718 if (blob == NULL) {
719 // TODO:
720 }
721 BN_bn2bin(n, blob);
722 BN_bn2bin(e, blob + nlen);
723 RSA_free(rsa);
724 break;
725
726 case KEY_DSA:
727 case KEY_RSA:
728 case KEY_ECDSA256:
729 case KEY_ECDSA384:
730 case KEY_ECDSA521:
731 case KEY_ED25519:
732 key_to_blob(k, &blob, &len);
733 break;
734
735 case KEY_UNSPEC:
736 return retval;
737 break;
738
739 default:
740 //fatal("key_fingerprint_raw: bad key type %d", dgst_alg);
741 break;
742 }
743
744 if (blob != NULL) {
745 retval = malloc(EVP_MAX_MD_SIZE);
746 if (retval == NULL) {
747 // TODO:
748 }
749 EVP_DigestInit(ctx, md);
750 EVP_DigestUpdate(ctx, blob, len);
751 EVP_DigestFinal(ctx, retval, dgst_raw_length);
752 SecureZeroMemory(blob, len);
753 free(blob);
754 } else {
755 //fatal("key_fingerprint_raw: blob is null");
756 }
757
758 error:
759 if (ctx)
760 EVP_MD_CTX_free(ctx);
761
762 return retval;
763 }
764
765
766 const char *
767 ssh_key_type(ssh_keytype type)
768 {
769 switch (type) {
770 case KEY_RSA1:
771 return "RSA1";
772 case KEY_RSA:
773 return "RSA";
774 case KEY_DSA:
775 return "DSA";
776 case KEY_ECDSA256:
777 case KEY_ECDSA384:
778 case KEY_ECDSA521:
779 return "ECDSA";
780 case KEY_ED25519:
781 return "ED25519";
782 }
783 return "unknown";
784 }
785
786 unsigned int
787 key_size(const Key *k)
788 {
789 BIGNUM *n = NULL;
790 BIGNUM *p = NULL;
791
792 switch (k->type) {
793 case KEY_RSA1:
794 // SSH1�������� key->rsa �� key->dsa �� NULL �����������A�g�������B
795 return k->bits;
796 case KEY_RSA:
797 RSA_get0_key(k->rsa, &n, NULL, NULL);
798 return BN_num_bits(n);
799 case KEY_DSA:
800 DSA_get0_pqg(k->dsa, &p, NULL, NULL);
801 return BN_num_bits(p);
802 case KEY_ECDSA256:
803 return 256;
804 case KEY_ECDSA384:
805 return 384;
806 case KEY_ECDSA521:
807 return 521;
808 case KEY_ED25519:
809 return 256; /* XXX */
810 }
811 return 0;
812 }
813
814 // based on OpenSSH 7.1
815 static char *
816 key_fingerprint_b64(const char *alg, u_char *dgst_raw, u_int dgst_raw_len)
817 {
818 char *retval;
819 unsigned int i, retval_len;
820 BIO *bio, *b64;
821 BUF_MEM *bufferPtr;
822
823 retval_len = strlen(alg) + 1 + ((dgst_raw_len + 2) / 3) * 4 + 1;
824 retval = malloc(retval_len);
825 retval[0] = '\0';
826
827 strncat_s(retval, retval_len, alg, _TRUNCATE);
828 strncat_s(retval, retval_len, ":", _TRUNCATE);
829
830 b64 = BIO_new(BIO_f_base64());
831 bio = BIO_new(BIO_s_mem());
832 bio = BIO_push(b64, bio);
833
834 BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
835 BIO_write(bio, dgst_raw, dgst_raw_len);
836 BIO_flush(bio);
837 BIO_get_mem_ptr(bio, &bufferPtr);
838 strncat_s(retval, retval_len, bufferPtr->data, _TRUNCATE);
839 BIO_set_close(bio, BIO_NOCLOSE);
840 BIO_free_all(bio);
841
842 /* Remove the trailing '=' character */
843 for (i = strlen(retval) - 1; retval[i] == '='; i--) {
844 retval[i] = '\0';
845 }
846
847 return (retval);
848 }
849
850 static char *
851 key_fingerprint_hex(const char *alg, u_char *dgst_raw, u_int dgst_raw_len)
852 {
853 char *retval;
854 unsigned int i, retval_len;
855
856 retval_len = strlen(alg) + 1 + dgst_raw_len * 3 + 1;
857 retval = malloc(retval_len);
858 retval[0] = '\0';
859
860 strncat_s(retval, retval_len, alg, _TRUNCATE);
861 strncat_s(retval, retval_len, ":", _TRUNCATE);
862
863 for (i = 0; i < dgst_raw_len; i++) {
864 char hex[4];
865 _snprintf_s(hex, sizeof(hex), _TRUNCATE, "%02x:", dgst_raw[i]);
866 strncat_s(retval, retval_len, hex, _TRUNCATE);
867 }
868
869 /* Remove the trailing ':' character */
870 retval[retval_len - 2] = '\0';
871
872 return (retval);
873 }
874
875 #define FLDBASE 8
876 #define FLDSIZE_Y (FLDBASE + 1)
877 #define FLDSIZE_X (FLDBASE * 2 + 1)
878 static char *
879 key_fingerprint_randomart(const char *alg, u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
880 {
881 /*
882 * Chars to be used after each other every time the worm
883 * intersects with itself. Matter of taste.
884 */
885 char *augmentation_string = " .o+=*BOX@%&#/^SE";
886 char *retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X];
887 unsigned char field[FLDSIZE_X][FLDSIZE_Y];
888 size_t i, tlen, hlen;
889 unsigned int b;
890 int x, y, r;
891 size_t len = strlen(augmentation_string) - 1;
892
893 retval = calloc((FLDSIZE_X + 3 + 1), (FLDSIZE_Y + 2));
894
895 /* initialize field */
896 memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
897 x = FLDSIZE_X / 2;
898 y = FLDSIZE_Y / 2;
899
900 /* process raw key */
901 for (i = 0; i < dgst_raw_len; i++) {
902 int input;
903 /* each byte conveys four 2-bit move commands */
904 input = dgst_raw[i];
905 for (b = 0; b < 4; b++) {
906 /* evaluate 2 bit, rest is shifted later */
907 x += (input & 0x1) ? 1 : -1;
908 y += (input & 0x2) ? 1 : -1;
909
910 /* assure we are still in bounds */
911 x = max(x, 0);
912 y = max(y, 0);
913 x = min(x, FLDSIZE_X - 1);
914 y = min(y, FLDSIZE_Y - 1);
915
916 /* augment the field */
917 if (field[x][y] < len - 2)
918 field[x][y]++;
919 input = input >> 2;
920 }
921 }
922
923 /* mark starting point and end point*/
924 field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = (unsigned char)(len - 1);
925 field[x][y] = (unsigned char)len;
926
927 /* assemble title */
928 r = _snprintf_s(title, sizeof(title), _TRUNCATE, "[%s %u]",
929 ssh_key_type(k->type), key_size(k));
930 /* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */
931 if (r < 0 || r >(int)sizeof(title))
932 r = _snprintf_s(title, sizeof(title), _TRUNCATE, "[%s]",
933 ssh_key_type(k->type));
934 tlen = (r <= 0) ? 0 : strlen(title);
935
936 /* assemble hash ID. */
937 r = _snprintf_s(hash, sizeof(hash), _TRUNCATE, "[%s]", alg);
938 hlen = (r <= 0) ? 0 : strlen(hash);
939
940 /* output upper border */
941 p = retval;
942 *p++ = '+';
943 for (i = 0; i < (FLDSIZE_X - tlen) / 2; i++)
944 *p++ = '-';
945 memcpy(p, title, tlen);
946 p += tlen;
947 for (i += tlen; i < FLDSIZE_X; i++)
948 *p++ = '-';
949 *p++ = '+';
950 *p++ = '\r';
951 *p++ = '\n';
952
953 /* output content */
954 for (y = 0; y < FLDSIZE_Y; y++) {
955 *p++ = '|';
956 for (x = 0; x < FLDSIZE_X; x++)
957 *p++ = augmentation_string[min(field[x][y], len)];
958 *p++ = '|';
959 *p++ = '\r';
960 *p++ = '\n';
961 }
962
963 /* output lower border */
964 *p++ = '+';
965 for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++)
966 *p++ = '-';
967 memcpy(p, hash, hlen);
968 p += hlen;
969 for (i += hlen; i < FLDSIZE_X; i++)
970 *p++ = '-';
971 *p++ = '+';
972
973 return retval;
974 }
975 #undef FLDBASE
976 #undef FLDSIZE_Y
977 #undef FLDSIZE_X
978
979 //
980 // fingerprint�i�w���F�z�X�g���J�����n�b�V���j����������
981 //
982 char *key_fingerprint(Key *key, fp_rep dgst_rep, digest_algorithm dgst_alg)
983 {
984 char *retval = NULL, *alg;
985 unsigned char *dgst_raw;
986 int dgst_raw_len;
987
988 // fingerprint���n�b�V���l�i�o�C�i���j��������
989 dgst_raw = key_fingerprint_raw(key, dgst_alg, &dgst_raw_len);
990 if (dgst_raw == NULL)
991 return NULL;
992
993 alg = get_digest_algorithm_name(dgst_alg);
994
995 switch (dgst_rep) {
996 case SSH_FP_HEX:
997 retval = key_fingerprint_hex(alg, dgst_raw, dgst_raw_len);
998 break;
999 case SSH_FP_BASE64:
1000 retval = key_fingerprint_b64(alg, dgst_raw, dgst_raw_len);
1001 break;
1002 case SSH_FP_RANDOMART:
1003 retval = key_fingerprint_randomart(alg, dgst_raw, dgst_raw_len, key);
1004 break;
1005 }
1006
1007 SecureZeroMemory(dgst_raw, dgst_raw_len);
1008 free(dgst_raw);
1009
1010 return (retval);
1011 }
1012
1013 //
1014 // �L�[�������������m��
1015 //
1016 static void key_add_private(Key *k)
1017 {
1018 BIGNUM *d, *iqmp, *q, *p, *dmq1, *dmp1;
1019 BIGNUM *priv_key = NULL;
1020
1021 d = iqmp = q = p = dmq1 = dmp1 = NULL;
1022
1023 switch (k->type) {
1024 case KEY_RSA1:
1025 case KEY_RSA:
1026 d = BN_new();
1027 RSA_set0_key(k->rsa, NULL, NULL, d);
1028
1029 iqmp = BN_new();
1030 q = BN_new();
1031 p = BN_new();
1032 RSA_set0_factors(k->rsa, p, q);
1033
1034 dmq1 = BN_new();
1035 dmp1 = BN_new();
1036 RSA_set0_crt_params(k->rsa, dmp1, dmq1, iqmp);
1037
1038 if (d == NULL || iqmp == NULL || q == NULL ||
1039 p == NULL || dmq1 == NULL || dmp1 == NULL)
1040 goto error;
1041 break;
1042
1043 case KEY_DSA:
1044 priv_key = BN_new();
1045 DSA_set0_key(k->dsa, NULL, priv_key);
1046 if (priv_key == NULL)
1047 goto error;
1048 break;
1049
1050 case KEY_ECDSA256:
1051 case KEY_ECDSA384:
1052 case KEY_ECDSA521:
1053 /* Cannot do anything until we know the group */
1054 break;
1055
1056 case KEY_ED25519:
1057 /* no need to prealloc */
1058 break;
1059
1060 case KEY_UNSPEC:
1061 break;
1062
1063 default:
1064 goto error;
1065 break;
1066 }
1067 return;
1068
1069 error:
1070 if (d) {
1071 BN_free(d);
1072 // k->rsa->d�� NULL ���Z�b�g�������������������B
1073 // RSA_set0_key()���� NULL ���n�����������������B
1074 }
1075 if (iqmp) {
1076 BN_free(iqmp);
1077 }
1078 if (q) {
1079 BN_free(q);
1080 }
1081 if (p) {
1082 BN_free(p);
1083 }
1084 if (dmq1) {
1085 BN_free(dmq1);
1086 }
1087 if (dmp1) {
1088 BN_free(dmp1);
1089 }
1090
1091
1092 if (priv_key == NULL) {
1093 BN_free(priv_key);
1094 }
1095
1096 }
1097
1098 Key *key_new_private(int type)
1099 {
1100 Key *k = key_new(type);
1101
1102 key_add_private(k);
1103 return (k);
1104 }
1105
1106
1107 Key *key_new(int type)
1108 {
1109 int success = 0;
1110 Key *k = NULL;
1111 RSA *rsa;
1112 DSA *dsa;
1113 BIGNUM *e = NULL, *n = NULL;
1114 BIGNUM *p, *q, *g, *pub_key;
1115
1116 k = calloc(1, sizeof(Key));
1117 if (k == NULL)
1118 goto error;
1119 k->type = type;
1120 k->ecdsa = NULL;
1121 k->dsa = NULL;
1122 k->rsa = NULL;
1123 k->ed25519_pk = NULL;
1124 k->ed25519_sk = NULL;
1125
1126 switch (k->type) {
1127 case KEY_RSA1:
1128 case KEY_RSA:
1129 rsa = RSA_new();
1130 if (rsa == NULL)
1131 goto error;
1132 n = BN_new();
1133 e = BN_new();
1134 RSA_set0_key(rsa, n, e, NULL);
1135 if (n == NULL || e == NULL)
1136 goto error;
1137 k->rsa = rsa;
1138 break;
1139
1140 case KEY_DSA:
1141 dsa = DSA_new();
1142 if (dsa == NULL)
1143 goto error;
1144 p = BN_new();
1145 q = BN_new();
1146 g = BN_new();
1147 DSA_set0_pqg(dsa, p, q, g);
1148 pub_key = BN_new();
1149 DSA_set0_key(dsa, pub_key, NULL);
1150 if (p == NULL || q == NULL || g == NULL || pub_key == NULL)
1151 goto error;
1152 k->dsa = dsa;
1153 break;
1154
1155 case KEY_ECDSA256:
1156 case KEY_ECDSA384:
1157 case KEY_ECDSA521:
1158 /* Cannot do anything until we know the group */
1159 break;
1160
1161 case KEY_ED25519:
1162 /* no need to prealloc */
1163 break;
1164
1165 case KEY_UNSPEC:
1166 break;
1167
1168 default:
1169 goto error;
1170 break;
1171 }
1172 success = 1;
1173
1174 error:
1175 if (success == 0) {
1176 key_free(k);
1177 k = NULL;
1178 }
1179 return (k);
1180 }
1181
1182
1183 //
1184 // Key �\�����������o�������������� key ��������������
1185 // key_new() ������ malloc �������������|�C���^���n��
1186 // Key �\�������n��������������
1187 //
1188 void key_free(Key *key)
1189 {
1190 if (key == NULL) {
1191 return;
1192 }
1193
1194 key_init(key);
1195
1196 free(key);
1197 }
1198
1199 //
1200 // Key �\�����������o����������������
1201 // �����o�������������Akey ����������������
1202 //
1203 void key_init(Key *key)
1204 {
1205 key->type = KEY_UNSPEC;
1206
1207 // SSH1
1208 key->bits = 0;
1209 if (key->exp != NULL) {
1210 free(key->exp);
1211 key->exp = NULL;
1212 }
1213 if (key->mod != NULL) {
1214 free(key->mod);
1215 key->mod = NULL;
1216 }
1217
1218 // SSH2
1219 if (key->dsa != NULL) {
1220 DSA_free(key->dsa);
1221 key->dsa = NULL;
1222 }
1223 if (key->rsa != NULL) {
1224 RSA_free(key->rsa);
1225 key->rsa = NULL;
1226 }
1227 if (key->ecdsa != NULL) {
1228 EC_KEY_free(key->ecdsa);
1229 key->ecdsa = NULL;
1230 }
1231 if (key->ed25519_pk != NULL) {
1232 SecureZeroMemory(key->ed25519_pk, ED25519_PK_SZ);
1233 free(key->ed25519_pk);
1234 key->ed25519_pk = NULL;
1235 }
1236 if (key->ed25519_sk) {
1237 SecureZeroMemory(key->ed25519_sk, ED25519_SK_SZ);
1238 free(key->ed25519_sk);
1239 key->ed25519_sk = NULL;
1240 }
1241 }
1242
1243 ssh_keytype key_curve_name_to_keytype(char *name)
1244 {
1245 if (strcmp(name, "nistp256") == 0) {
1246 return KEY_ECDSA256;
1247 } else if (strcmp(name, "nistp384") == 0) {
1248 return KEY_ECDSA384;
1249 } else if (strcmp(name, "nistp521") == 0) {
1250 return KEY_ECDSA521;
1251 }
1252 return KEY_UNSPEC;
1253 }
1254
1255 char *curve_keytype_to_name(ssh_keytype type)
1256 {
1257 switch (type) {
1258 case KEY_ECDSA256:
1259 return "nistp256";
1260 break;
1261 case KEY_ECDSA384:
1262 return "nistp384";
1263 break;
1264 case KEY_ECDSA521:
1265 return "nistp521";
1266 break;
1267 }
1268 return NULL;
1269 }
1270
1271 //
1272 // �L�[���������o�b�t�@���������� (for SSH2)
1273 // NOTE:
1274 //
1275 int key_to_blob(Key *key, char **blobp, int *lenp)
1276 {
1277 buffer_t *b;
1278 char *sshname, *tmp;
1279 int len;
1280 int ret = 1; // success
1281 BIGNUM *e = NULL, *n = NULL;
1282 BIGNUM *p, *q, *g, *pub_key;
1283
1284 b = buffer_init();
1285 sshname = get_ssh2_hostkey_type_name_from_key(key);
1286
1287 switch (key->type) {
1288 case KEY_RSA:
1289 RSA_get0_key(key->rsa, &n, &e, NULL);
1290 buffer_put_string(b, sshname, strlen(sshname));
1291 buffer_put_bignum2(b, e);
1292 buffer_put_bignum2(b, n);
1293 break;
1294 case KEY_DSA:
1295 DSA_get0_pqg(key->dsa, &p, &q, &g);
1296 DSA_get0_key(key->dsa, &pub_key, NULL);
1297 buffer_put_string(b, sshname, strlen(sshname));
1298 buffer_put_bignum2(b, p);
1299 buffer_put_bignum2(b, q);
1300 buffer_put_bignum2(b, g);
1301 buffer_put_bignum2(b, pub_key);
1302 break;
1303 case KEY_ECDSA256:
1304 case KEY_ECDSA384:
1305 case KEY_ECDSA521:
1306 buffer_put_string(b, sshname, strlen(sshname));
1307 tmp = curve_keytype_to_name(key->type);
1308 buffer_put_string(b, tmp, strlen(tmp));
1309 buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
1310 EC_KEY_get0_public_key(key->ecdsa));
1311 break;
1312 case KEY_ED25519:
1313 buffer_put_cstring(b, sshname);
1314 buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
1315 break;
1316
1317 default:
1318 ret = 0;
1319 goto error;
1320 }
1321
1322 len = buffer_len(b);
1323 if (lenp != NULL)
1324 *lenp = len;
1325 if (blobp != NULL) {
1326 *blobp = malloc(len);
1327 if (*blobp == NULL) {
1328 ret = 0;
1329 goto error;
1330 }
1331 memcpy(*blobp, buffer_ptr(b), len);
1332 }
1333
1334 error:
1335 buffer_free(b);
1336
1337 return (ret);
1338 }
1339
1340
1341 //
1342 // �o�b�t�@�����L�[�����������o��(for SSH2)
1343 // NOTE: ���l���A���P�[�g���������������A�����o�������������������B
1344 //
1345 Key *key_from_blob(char *data, int blen)
1346 {
1347 int keynamelen, len;
1348 char key[128];
1349 RSA *rsa = NULL;
1350 DSA *dsa = NULL;
1351 EC_KEY *ecdsa = NULL;
1352 EC_POINT *q = NULL;
1353 char *curve = NULL;
1354 Key *hostkey = NULL; // hostkey
1355 ssh_keytype type;
1356 unsigned char *pk = NULL;
1357 BIGNUM *e = NULL, *n = NULL;
1358 BIGNUM *p, *dsa_q, *g, *pub_key;
1359
1360 if (data == NULL)
1361 goto error;
1362
1363 hostkey = malloc(sizeof(Key));
1364 if (hostkey == NULL)
1365 goto error;
1366
1367 memset(hostkey, 0, sizeof(Key));
1368
1369 keynamelen = get_uint32_MSBfirst(data);
1370 if (keynamelen >= sizeof(key)) {
1371 goto error;
1372 }
1373 data += 4;
1374 memcpy(key, data, keynamelen);
1375 key[keynamelen] = 0;
1376 data += keynamelen;
1377
1378 type = get_hostkey_type_from_name(key);
1379
1380 switch (type) {
1381 case KEY_RSA: // RSA key
1382 rsa = RSA_new();
1383 if (rsa == NULL) {
1384 goto error;
1385 }
1386 n = BN_new();
1387 e = BN_new();
1388 RSA_set0_key(rsa, n, e, NULL);
1389 if (n == NULL || e == NULL) {
1390 goto error;
1391 }
1392
1393 buffer_get_bignum2(&data, e);
1394 buffer_get_bignum2(&data, n);
1395
1396 hostkey->type = type;
1397 hostkey->rsa = rsa;
1398 break;
1399
1400 case KEY_DSA: // DSA key
1401 dsa = DSA_new();
1402 if (dsa == NULL) {
1403 goto error;
1404 }
1405 p = BN_new();
1406 dsa_q = BN_new();
1407 g = BN_new();
1408 pub_key = BN_new();
1409 DSA_set0_pqg(dsa, p, dsa_q, g);
1410 DSA_set0_key(dsa, pub_key, NULL);
1411 if (p == NULL ||
1412 dsa_q == NULL ||
1413 g == NULL ||
1414 pub_key == NULL) {
1415 goto error;
1416 }
1417
1418 buffer_get_bignum2(&data, p);
1419 buffer_get_bignum2(&data, dsa_q);
1420 buffer_get_bignum2(&data, g);
1421 buffer_get_bignum2(&data, pub_key);
1422
1423 hostkey->type = type;
1424 hostkey->dsa = dsa;
1425 break;
1426
1427 case KEY_ECDSA256: // ECDSA
1428 case KEY_ECDSA384:
1429 case KEY_ECDSA521:
1430 curve = buffer_get_string(&data, NULL);
1431 if (type != key_curve_name_to_keytype(curve)) {
1432 goto error;
1433 }
1434
1435 ecdsa = EC_KEY_new_by_curve_name(keytype_to_cipher_nid(type));
1436 if (ecdsa == NULL) {
1437 goto error;
1438 }
1439
1440 q = EC_POINT_new(EC_KEY_get0_group(ecdsa));
1441 if (q == NULL) {
1442 goto error;
1443 }
1444
1445 buffer_get_ecpoint(&data, EC_KEY_get0_group(ecdsa), q);
1446 if (key_ec_validate_public(EC_KEY_get0_group(ecdsa), q) == -1) {
1447 goto error;
1448 }
1449
1450 if (EC_KEY_set_public_key(ecdsa, q) != 1) {
1451 goto error;
1452 }
1453
1454 hostkey->type = type;
1455 hostkey->ecdsa = ecdsa;
1456 break;
1457
1458 case KEY_ED25519:
1459 pk = buffer_get_string(&data, &len);
1460 if (pk == NULL)
1461 goto error;
1462 if (len != ED25519_PK_SZ)
1463 goto error;
1464
1465 hostkey->type = type;
1466 hostkey->ed25519_pk = pk;
1467 pk = NULL;
1468 break;
1469
1470 default: // unknown key
1471 goto error;
1472 }
1473
1474 return (hostkey);
1475
1476 error:
1477 if (rsa != NULL)
1478 RSA_free(rsa);
1479 if (dsa != NULL)
1480 DSA_free(dsa);
1481 if (ecdsa != NULL)
1482 EC_KEY_free(ecdsa);
1483
1484 free(hostkey);
1485
1486 return NULL;
1487 }
1488
1489
1490 static int ssh_ed25519_sign(Key *key, char **sigp, int *lenp, char *data, int datalen)
1491 {
1492 char *sig;
1493 int slen, len;
1494 unsigned long long smlen;
1495 int ret;
1496 buffer_t *b;
1497
1498 smlen = slen = datalen + crypto_sign_ed25519_BYTES;
1499 sig = malloc(slen);
1500
1501 if ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen,
1502 key->ed25519_sk)) != 0 || smlen <= datalen) {
1503 //error("%s: crypto_sign_ed25519 failed: %d", __func__, ret);
1504 free(sig);
1505 return -1;
1506 }
1507 /* encode signature */
1508 b = buffer_init();
1509 buffer_put_cstring(b, "ssh-ed25519");
1510 buffer_put_string(b, sig, (int)(smlen - datalen));
1511 len = buffer_len(b);
1512 if (lenp != NULL)
1513 *lenp = len;
1514 if (sigp != NULL) {
1515 *sigp = malloc(len);
1516 memcpy(*sigp, buffer_ptr(b), len);
1517 }
1518 buffer_free(b);
1519 SecureZeroMemory(sig, slen);
1520 free(sig);
1521
1522 return 0;
1523 }
1524
1525
1526 BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen)
1527 {
1528 buffer_t *msg = NULL;
1529 char *s;
1530 int ret;
1531
1532 msg = buffer_init();
1533 if (msg == NULL) {
1534 // TODO: error check
1535 return FALSE;
1536 }
1537
1538 switch (keypair->type) {
1539 case KEY_RSA: // RSA
1540 {
1541 const EVP_MD *evp_md = EVP_sha1();
1542 EVP_MD_CTX *md = NULL;
1543 u_char digest[EVP_MAX_MD_SIZE], *sig;
1544 u_int slen, dlen, len;
1545 int ok, nid = NID_sha1;
1546
1547 md = EVP_MD_CTX_new();
1548 if (md == NULL)
1549 goto error;
1550
1551 // �_�C�W�F�X�g�l���v�Z
1552 EVP_DigestInit(md, evp_md);
1553 EVP_DigestUpdate(md, data, datalen);
1554 EVP_DigestFinal(md, digest, &dlen);
1555
1556 EVP_MD_CTX_free(md);
1557
1558 slen = RSA_size(keypair->rsa);
1559 sig = malloc(slen);
1560 if (sig == NULL)
1561 goto error;
1562
1563 // �d�q�������v�Z
1564 ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa);
1565 SecureZeroMemory(digest, sizeof(digest));
1566 if (ok != 1) { // error
1567 free(sig);
1568 goto error;
1569 }
1570 // �������T�C�Y���o�b�t�@���������������A�������������B�������[�����������B
1571 if (len < slen) {
1572 u_int diff = slen - len;
1573 memmove(sig + diff, sig, len);
1574 memset(sig, 0, diff);
1575
1576 } else if (len > slen) {
1577 free(sig);
1578 goto error;
1579
1580 } else {
1581 // do nothing
1582
1583 }
1584
1585 s = get_ssh2_hostkey_type_name_from_key(keypair);
1586 buffer_put_string(msg, s, strlen(s));
1587 buffer_append_length(msg, sig, slen);
1588 len = buffer_len(msg);
1589
1590 // setting
1591 *siglen = len;
1592 *sigptr = malloc(len);
1593 if (*sigptr == NULL) {
1594 free(sig);
1595 goto error;
1596 }
1597 memcpy(*sigptr, buffer_ptr(msg), len);
1598 free(sig);
1599
1600 break;
1601 }
1602 case KEY_DSA: // DSA
1603 {
1604 DSA_SIG *sig;
1605 const EVP_MD *evp_md = EVP_sha1();
1606 EVP_MD_CTX *md = NULL;
1607 u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
1608 u_int rlen, slen, len, dlen;
1609 BIGNUM *bignum_r, *bignum_s;
1610
1611 md = EVP_MD_CTX_new();
1612 if (md == NULL)
1613 goto error;
1614
1615 // �_�C�W�F�X�g���v�Z
1616 EVP_DigestInit(md, evp_md);
1617 EVP_DigestUpdate(md, data, datalen);
1618 EVP_DigestFinal(md, digest, &dlen);
1619
1620 EVP_MD_CTX_free(md);
1621
1622 // DSA�d�q�������v�Z
1623 sig = DSA_do_sign(digest, dlen, keypair->dsa);
1624 SecureZeroMemory(digest, sizeof(digest));
1625 if (sig == NULL) {
1626 goto error;
1627 }
1628
1629 // BIGNUM�����o�C�i���l��������
1630 DSA_SIG_get0(sig, &bignum_r, &bignum_s);
1631 rlen = BN_num_bytes(bignum_r);
1632 slen = BN_num_bytes(bignum_s);
1633 if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
1634 DSA_SIG_free(sig);
1635 goto error;
1636 }
1637 memset(sigblob, 0, SIGBLOB_LEN);
1638 BN_bn2bin(bignum_r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
1639 BN_bn2bin(bignum_s, sigblob+ SIGBLOB_LEN - slen);
1640 DSA_SIG_free(sig);
1641
1642 // setting
1643 s = get_ssh2_hostkey_type_name_from_key(keypair);
1644 buffer_put_string(msg, s, strlen(s));
1645 buffer_append_length(msg, sigblob, sizeof(sigblob));
1646 len = buffer_len(msg);
1647
1648 // setting
1649 *siglen = len;
1650 *sigptr = malloc(len);
1651 if (*sigptr == NULL) {
1652 goto error;
1653 }
1654 memcpy(*sigptr, buffer_ptr(msg), len);
1655
1656 break;
1657 }
1658 case KEY_ECDSA256: // ECDSA
1659 case KEY_ECDSA384:
1660 case KEY_ECDSA521:
1661 {
1662 ECDSA_SIG *sig;
1663 const EVP_MD *evp_md;
1664 EVP_MD_CTX *md = NULL;
1665 u_char digest[EVP_MAX_MD_SIZE];
1666 u_int len, dlen, nid;
1667 buffer_t *buf2 = NULL;
1668 BIGNUM *br, *bs;
1669
1670 nid = keytype_to_hash_nid(keypair->type);
1671 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
1672 goto error;
1673 }
1674
1675 md = EVP_MD_CTX_new();
1676 if (md == NULL)
1677 goto error;
1678
1679 EVP_DigestInit(md, evp_md);
1680 EVP_DigestUpdate(md, data, datalen);
1681 EVP_DigestFinal(md, digest, &dlen);
1682
1683 EVP_MD_CTX_free(md);
1684
1685 sig = ECDSA_do_sign(digest, dlen, keypair->ecdsa);
1686 SecureZeroMemory(digest, sizeof(digest));
1687
1688 if (sig == NULL) {
1689 goto error;
1690 }
1691
1692 buf2 = buffer_init();
1693 if (buf2 == NULL) {
1694 // TODO: error check
1695 goto error;
1696 }
1697 ECDSA_SIG_get0(sig, &br, &bs);
1698 buffer_put_bignum2(buf2, br);
1699 buffer_put_bignum2(buf2, bs);
1700 ECDSA_SIG_free(sig);
1701
1702 s = get_ssh2_hostkey_type_name_from_key(keypair);
1703 buffer_put_string(msg, s, strlen(s));
1704 buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2));
1705 buffer_free(buf2);
1706 len = buffer_len(msg);
1707
1708 *siglen = len;
1709 *sigptr = malloc(len);
1710 if (*sigptr == NULL) {
1711 goto error;
1712 }
1713 memcpy(*sigptr, buffer_ptr(msg), len);
1714
1715 break;
1716 }
1717
1718 case KEY_ED25519:
1719 ret = ssh_ed25519_sign(keypair, sigptr, siglen, data, datalen);
1720 if (ret != 0)
1721 goto error;
1722 break;
1723
1724 default:
1725 buffer_free(msg);
1726 return FALSE;
1727 break;
1728 }
1729
1730 buffer_free(msg);
1731 return TRUE;
1732
1733 error:
1734 buffer_free(msg);
1735
1736 return FALSE;
1737 }
1738
1739
1740 BOOL get_SSH2_publickey_blob(PTInstVar pvar, buffer_t **blobptr, int *bloblen)
1741 {
1742 buffer_t *msg = NULL;
1743 Key *keypair;
1744 char *s, *tmp;
1745 BIGNUM *e = NULL, *n = NULL;
1746 BIGNUM *p, *q, *g, *pub_key;
1747
1748 msg = buffer_init();
1749 if (msg == NULL) {
1750 // TODO: error check
1751 return FALSE;
1752 }
1753
1754 keypair = pvar->auth_state.cur_cred.key_pair;
1755
1756 switch (keypair->type) {
1757 case KEY_RSA: // RSA
1758 s = get_ssh2_hostkey_type_name_from_key(keypair);
1759 RSA_get0_key(keypair->rsa, &n, &e, NULL);
1760 buffer_put_string(msg, s, strlen(s));
1761 buffer_put_bignum2(msg, e); // ���J�w��
1762 buffer_put_bignum2(msg, n); // p�~q
1763 break;
1764 case KEY_DSA: // DSA
1765 DSA_get0_pqg(keypair->dsa, &p, &q, &g);
1766 DSA_get0_key(keypair->dsa, &pub_key, NULL);
1767 s = get_ssh2_hostkey_type_name_from_key(keypair);
1768 buffer_put_string(msg, s, strlen(s));
1769 buffer_put_bignum2(msg, p); // �f��
1770 buffer_put_bignum2(msg, q); // (p-1)���f����
1771 buffer_put_bignum2(msg, g); // ����
1772 buffer_put_bignum2(msg, pub_key); // ���J��
1773 break;
1774 case KEY_ECDSA256: // ECDSA
1775 case KEY_ECDSA384:
1776 case KEY_ECDSA521:
1777 s = get_ssh2_hostkey_type_name_from_key(keypair);
1778 buffer_put_string(msg, s, strlen(s));
1779 tmp = curve_keytype_to_name(keypair->type);
1780 buffer_put_string(msg, tmp, strlen(tmp));
1781 buffer_put_ecpoint(msg, EC_KEY_get0_group(keypair->ecdsa),
1782 EC_KEY_get0_public_key(keypair->ecdsa));
1783 break;
1784 case KEY_ED25519:
1785 s = get_ssh2_hostkey_type_name_from_key(keypair);
1786 buffer_put_cstring(msg, s);
1787 buffer_put_string(msg, keypair->ed25519_pk, ED25519_PK_SZ);
1788 break;
1789 default:
1790 return FALSE;
1791 }
1792
1793 *blobptr = msg;
1794 *bloblen = buffer_len(msg);
1795
1796 return TRUE;
1797 }
1798
1799 int kextype_to_cipher_nid(kex_algorithm type)
1800 {
1801 switch (type) {
1802 case KEX_ECDH_SHA2_256:
1803 return NID_X9_62_prime256v1;
1804 case KEX_ECDH_SHA2_384:
1805 return NID_secp384r1;
1806 case KEX_ECDH_SHA2_521:
1807 return NID_secp521r1;
1808 }
1809 return NID_undef;
1810 }
1811
1812 int keytype_to_hash_nid(ssh_keytype type)
1813 {
1814 switch (type) {
1815 case KEY_ECDSA256:
1816 return NID_sha256;
1817 case KEY_ECDSA384:
1818 return NID_sha384;
1819 case KEY_ECDSA521:
1820 return NID_sha512;
1821 }
1822 return NID_undef;
1823 }
1824
1825 int keytype_to_cipher_nid(ssh_keytype type)
1826 {
1827 switch (type) {
1828 case KEY_ECDSA256:
1829 return NID_X9_62_prime256v1;
1830 case KEY_ECDSA384:
1831 return NID_secp384r1;
1832 case KEY_ECDSA521:
1833 return NID_secp521r1;
1834 }
1835 return NID_undef;
1836 }
1837
1838 ssh_keytype nid_to_keytype(int nid)
1839 {
1840 switch (nid) {
1841 case NID_X9_62_prime256v1:
1842 return KEY_ECDSA256;
1843 case NID_secp384r1:
1844 return KEY_ECDSA384;
1845 case NID_secp521r1:
1846 return KEY_ECDSA521;
1847 }
1848 return KEY_UNSPEC;
1849 }
1850
1851 void key_private_serialize(Key *key, buffer_t *b)
1852 {
1853 char *s;
1854 BIGNUM *e, *n, *d, *iqmp, *p, *q;
1855 BIGNUM *g, *pub_key, *priv_key;
1856
1857 s = get_ssh2_hostkey_type_name_from_key(key);
1858 buffer_put_cstring(b, s);
1859
1860 switch (key->type) {
1861 case KEY_RSA:
1862 RSA_get0_key(key->rsa, &n, &e, &d);
1863 RSA_get0_factors(key->rsa, &p, &q);
1864 RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp);
1865
1866 buffer_put_bignum2(b, n);
1867 buffer_put_bignum2(b, e);
1868 buffer_put_bignum2(b, d);
1869 buffer_put_bignum2(b, iqmp);
1870 buffer_put_bignum2(b, p);
1871 buffer_put_bignum2(b, q);
1872 break;
1873
1874 case KEY_DSA:
1875 DSA_get0_pqg(key->dsa, &p, &q, &g);
1876 DSA_get0_key(key->dsa, &pub_key, &priv_key);
1877 buffer_put_bignum2(b, p);
1878 buffer_put_bignum2(b, q);
1879 buffer_put_bignum2(b, g);
1880 buffer_put_bignum2(b, pub_key);
1881 buffer_put_bignum2(b, priv_key);
1882 break;
1883
1884 case KEY_ECDSA256:
1885 case KEY_ECDSA384:
1886 case KEY_ECDSA521:
1887 buffer_put_cstring(b, curve_keytype_to_name(key->type));
1888 buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
1889 EC_KEY_get0_public_key(key->ecdsa));
1890 buffer_put_bignum2(b, (BIGNUM *)EC_KEY_get0_private_key(key->ecdsa));
1891 break;
1892
1893 case KEY_ED25519:
1894 buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
1895 buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ);
1896 break;
1897
1898 default:
1899 break;
1900 }
1901 }
1902
1903 /* calculate p-1 and q-1 */
1904 static void rsa_generate_additional_parameters(RSA *rsa)
1905 {
1906 BIGNUM *aux = NULL;
1907 BN_CTX *ctx = NULL;
1908 BIGNUM *e, *n, *d, *dmp1, *dmq1, *iqmp, *p, *q;
1909
1910 if ((aux = BN_new()) == NULL)
1911 goto error;
1912 if ((ctx = BN_CTX_new()) == NULL)
1913 goto error;
1914
1915 RSA_get0_key(rsa, &n, &e, &d);
1916 RSA_get0_factors(rsa, &p, &q);
1917 RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
1918
1919 if ((BN_sub(aux, q, BN_value_one()) == 0) ||
1920 (BN_mod(dmq1, d, aux, ctx) == 0) ||
1921 (BN_sub(aux, p, BN_value_one()) == 0) ||
1922 (BN_mod(dmp1, d, aux, ctx) == 0))
1923 goto error;
1924
1925 error:
1926 if (aux)
1927 BN_clear_free(aux);
1928 if (ctx)
1929 BN_CTX_free(ctx);
1930 }
1931
1932 Key *key_private_deserialize(buffer_t *blob)
1933 {
1934 int success = 0;
1935 char *type_name = NULL;
1936 Key *k = NULL;
1937 unsigned int pklen, sklen;
1938 int type;
1939 BIGNUM *e, *n, *d, *dmp1, *dmq1, *iqmp, *p, *q;
1940 BIGNUM *g, *pub_key, *priv_key;
1941
1942 type_name = buffer_get_string_msg(blob, NULL);
1943 if (type_name == NULL)
1944 goto error;
1945 type = get_hostkey_type_from_name(type_name);
1946
1947 k = key_new_private(type);
1948
1949 switch (type) {
1950 case KEY_RSA:
1951 RSA_get0_key(k->rsa, &n, &e, &d);
1952 RSA_get0_factors(k->rsa, &p, &q);
1953 RSA_get0_crt_params(k->rsa, &dmp1, &dmq1, &iqmp);
1954
1955 buffer_get_bignum2_msg(blob, n);
1956 buffer_get_bignum2_msg(blob, e);
1957 buffer_get_bignum2_msg(blob, d);
1958 buffer_get_bignum2_msg(blob, iqmp);
1959 buffer_get_bignum2_msg(blob, p);
1960 buffer_get_bignum2_msg(blob, q);
1961
1962 /* Generate additional parameters */
1963 rsa_generate_additional_parameters(k->rsa);
1964 break;
1965
1966 case KEY_DSA:
1967 DSA_get0_pqg(k->dsa, &p, &q, &g);
1968 DSA_get0_key(k->dsa, &pub_key, &priv_key);
1969 buffer_get_bignum2_msg(blob, p);
1970 buffer_get_bignum2_msg(blob, q);
1971 buffer_get_bignum2_msg(blob, g);
1972 buffer_get_bignum2_msg(blob, pub_key);
1973 buffer_get_bignum2_msg(blob, priv_key);
1974 break;
1975
1976 case KEY_ECDSA256:
1977 case KEY_ECDSA384:
1978 case KEY_ECDSA521:
1979 {
1980 int success = 0;
1981 unsigned int nid;
1982 char *curve = NULL;
1983 ssh_keytype skt;
1984 BIGNUM *exponent = NULL;
1985 EC_POINT *q = NULL;
1986
1987 nid = keytype_to_cipher_nid(type);
1988 curve = buffer_get_string_msg(blob, NULL);
1989 skt = key_curve_name_to_keytype(curve);
1990 if (nid != keytype_to_cipher_nid(skt))
1991 goto ecdsa_error;
1992
1993 if ((k->ecdsa = EC_KEY_new_by_curve_name(nid)) == NULL)
1994 goto ecdsa_error;
1995 if ((q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa))) == NULL)
1996 goto ecdsa_error;
1997 if ((exponent = BN_new()) == NULL)
1998 goto ecdsa_error;
1999
2000 buffer_get_ecpoint_msg(blob, EC_KEY_get0_group(k->ecdsa), q);
2001 buffer_get_bignum2_msg(blob, exponent);
2002 if (EC_KEY_set_public_key(k->ecdsa, q) != 1)
2003 goto ecdsa_error;
2004 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
2005 goto ecdsa_error;
2006 if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
2007 EC_KEY_get0_public_key(k->ecdsa)) != 0)
2008 goto ecdsa_error;
2009 if (key_ec_validate_private(k->ecdsa) != 0)
2010 goto ecdsa_error;
2011
2012 success = 1;
2013
2014 ecdsa_error:
2015 free(curve);
2016 if (exponent)
2017 BN_clear_free(exponent);
2018 if (q)
2019 EC_POINT_free(q);
2020 if (success == 0)
2021 goto error;
2022 }
2023 break;
2024
2025 case KEY_ED25519:
2026 k->ed25519_pk = buffer_get_string_msg(blob, &pklen);
2027 k->ed25519_sk = buffer_get_string_msg(blob, &sklen);
2028 if (pklen != ED25519_PK_SZ)
2029 goto error;
2030 if (sklen != ED25519_SK_SZ)
2031 goto error;
2032 break;
2033
2034 default:
2035 goto error;
2036 break;
2037 }
2038
2039 /* enable blinding */
2040 switch (k->type) {
2041 case KEY_RSA1:
2042 case KEY_RSA:
2043 if (RSA_blinding_on(k->rsa, NULL) != 1)
2044 goto error;
2045 break;
2046 }
2047
2048 success = 1;
2049
2050 error:
2051 free(type_name);
2052
2053 if (success == 0) {
2054 key_free(k);
2055 k = NULL;
2056 }
2057
2058 return (k);
2059 }
2060
2061
2062 int key_ec_validate_private(EC_KEY *key)
2063 {
2064 BN_CTX *bnctx = NULL;
2065 BIGNUM *order, *tmp;
2066 int ret = -1;
2067
2068 if ((bnctx = BN_CTX_new()) == NULL)
2069 goto out;
2070 BN_CTX_start(bnctx);
2071
2072 if ((order = BN_CTX_get(bnctx)) == NULL ||
2073 (tmp = BN_CTX_get(bnctx)) == NULL)
2074 goto out;
2075
2076 /* log2(private) > log2(order)/2 */
2077 if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1)
2078 goto out;
2079 if (BN_num_bits(EC_KEY_get0_private_key(key)) <=
2080 BN_num_bits(order) / 2) {
2081 goto out;
2082 }
2083
2084 /* private < order - 1 */
2085 if (!BN_sub(tmp, order, BN_value_one()))
2086 goto out;
2087 if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) {
2088 goto out;
2089 }
2090 ret = 0;
2091
2092 out:
2093 if (bnctx)
2094 BN_CTX_free(bnctx);
2095 return ret;
2096 }
2097
2098 // from openssh 5.8p1 key.c
2099 int key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
2100 {
2101 BN_CTX *bnctx;
2102 EC_POINT *nq = NULL;
2103 BIGNUM *order, *x, *y, *tmp;
2104 int ret = -1;
2105
2106 if ((bnctx = BN_CTX_new()) == NULL) {
2107 return ret;
2108 }
2109 BN_CTX_start(bnctx);
2110
2111 /*
2112 * We shouldn't ever hit this case because bignum_get_ecpoint()
2113 * refuses to load GF2m points.
2114 */
2115 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
2116 NID_X9_62_prime_field) {
2117 goto out;
2118 }
2119
2120 /* Q != infinity */
2121 if (EC_POINT_is_at_infinity(group, public)) {
2122 goto out;
2123 }
2124
2125 if ((x = BN_CTX_get(bnctx)) == NULL ||
2126 (y = BN_CTX_get(bnctx)) == NULL ||
2127 (order = BN_CTX_get(bnctx)) == NULL ||
2128 (tmp = BN_CTX_get(bnctx)) == NULL) {
2129 goto out;
2130 }
2131
2132 /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */
2133 if (EC_GROUP_get_order(group, order, bnctx) != 1) {
2134 goto out;
2135 }
2136 if (EC_POINT_get_affine_coordinates_GFp(group, public,
2137 x, y, bnctx) != 1) {
2138 goto out;
2139 }
2140 if (BN_num_bits(x) <= BN_num_bits(order) / 2) {
2141 goto out;
2142 }
2143 if (BN_num_bits(y) <= BN_num_bits(order) / 2) {
2144 goto out;
2145 }
2146
2147 /* nQ == infinity (n == order of subgroup) */
2148 if ((nq = EC_POINT_new(group)) == NULL) {
2149 goto out;
2150 }
2151 if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) {
2152 goto out;
2153 }
2154 if (EC_POINT_is_at_infinity(group, nq) != 1) {
2155 goto out;
2156 }
2157
2158 /* x < order - 1, y < order - 1 */
2159 if (!BN_sub(tmp, order, BN_value_one())) {
2160 goto out;
2161 }
2162 if (BN_cmp(x, tmp) >= 0) {
2163 goto out;
2164 }
2165 if (BN_cmp(y, tmp) >= 0) {
2166 goto out;
2167 }
2168 ret = 0;
2169 out:
2170 BN_CTX_free(bnctx);
2171 EC_POINT_free(nq);
2172 return ret;
2173 }
2174
2175 static void hostkeys_update_ctx_free(struct hostkeys_update_ctx *ctx)
2176 {
2177 size_t i;
2178
2179 if (ctx == NULL)
2180 return;
2181 for (i = 0; i < ctx->nkeys; i++)
2182 key_free(ctx->keys[i]);
2183 free(ctx->keys);
2184 free(ctx->keys_seen);
2185 for (i = 0; i < ctx->nold; i++)
2186 key_free(ctx->old_keys[i]);
2187 free(ctx->old_keys);
2188 free(ctx->host_str);
2189 free(ctx->ip_str);
2190 free(ctx);
2191 }
2192
2193
2194 // �����������z�X�g���A���S���Y�������`�F�b�N�����B
2195 //
2196 // return 1: matched
2197 // 0: not matched
2198 //
2199 static int check_hostkey_algorithm(PTInstVar pvar, Key *key)
2200 {
2201 int ret = 0;
2202 int i, index;
2203
2204 for (i = 0; pvar->settings.HostKeyOrder[i] != 0; i++) {
2205 index = pvar->settings.HostKeyOrder[i] - '0';
2206 if (index == KEY_NONE) // disabled line
2207 break;
2208
2209 if (strcmp(get_ssh2_hostkey_type_name_from_key(key),
2210 get_ssh2_hostkey_type_name(index)) == 0)
2211 return 1;
2212 }
2213
2214 return (ret);
2215 }
2216
2217 // Callback function
2218 //
2219 // argument:
2220 // key: known_hosts���o�^������������
2221 // _ctx: �T�[�o�����������������������Q
2222 //
2223 // return:
2224 // 1: deprecated key�������A��������key�������������~�B
2225 // 0: ����������key�������������K�v�B
2226 static int hostkeys_find(Key *key, void *_ctx)
2227 {
2228 struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
2229 int ret = 0;
2230 size_t i;
2231 Key **tmp;
2232
2233 // SSH1�������O�B
2234 if (key->type == KEY_RSA1)
2235 goto error;
2236
2237 // �������o�^�������������������T���B
2238 for (i = 0; i < ctx->nkeys; i++) {
2239 if (HOSTS_compare_public_key(key, ctx->keys[i]) == 1) {
2240 ctx->keys_seen[i] = 1;
2241 goto error;
2242 }
2243 }
2244
2245 // deprecated�������A�����������X�g�������������B
2246 tmp = realloc(ctx->old_keys, (ctx->nold + 1)*sizeof(*ctx->old_keys));
2247 if (tmp != NULL) {
2248 ctx->old_keys = tmp;
2249 ctx->old_keys[ctx->nold++] = key;
2250 }
2251
2252 ret = 1;
2253
2254 error:
2255 return (ret);
2256 }
2257
2258 static void hosts_updatekey_dlg_set_fingerprint(PTInstVar pvar, HWND dlg, digest_algorithm dgst_alg)
2259 {
2260 char *fp, *buf;
2261 size_t i;
2262 int buf_len;
2263 struct hostkeys_update_ctx *ctx;
2264
2265 ctx = pvar->hostkey_ctx;
2266
2267 if (ctx->nkeys > 0) {
2268 buf_len = 100 * ctx->nkeys;
2269 buf = calloc(100, ctx->nkeys);
2270 for (i = 0; i < ctx->nkeys; i++) {
2271 if (ctx->keys_seen[i])
2272 continue;
2273 switch (dgst_alg) {
2274 case SSH_DIGEST_MD5:
2275 fp = key_fingerprint(ctx->keys[i], SSH_FP_HEX, dgst_alg);
2276 break;
2277 case SSH_DIGEST_SHA256:
2278 default:
2279 fp = key_fingerprint(ctx->keys[i], SSH_FP_BASE64, SSH_DIGEST_SHA256);
2280 break;
2281 }
2282 strncat_s(buf, buf_len, get_ssh2_hostkey_type_name_from_key(ctx->keys[i]), _TRUNCATE);
2283 strncat_s(buf, buf_len, " ", _TRUNCATE);
2284 if (fp != NULL) {
2285 strncat_s(buf, buf_len, fp, _TRUNCATE);
2286 free(fp);
2287 }
2288 if (i < ctx->nkeys - 1) {
2289 strncat_s(buf, buf_len, "\r\n", _TRUNCATE);
2290 }
2291 }
2292 SetDlgItemTextA(dlg, IDC_ADDKEY_EDIT, buf);
2293 free(buf);
2294 }
2295
2296 if (ctx->nold > 0) {
2297 buf_len = 100 * ctx->nold;
2298 buf = calloc(100, ctx->nold);
2299 SetDlgItemTextA(dlg, IDC_REMOVEKEY_EDIT, "");
2300 for (i = 0; i < ctx->nold; i++) {
2301 switch (dgst_alg) {
2302 case SSH_DIGEST_MD5:
2303 fp = key_fingerprint(ctx->old_keys[i], SSH_FP_HEX, dgst_alg);
2304 break;
2305 case SSH_DIGEST_SHA256:
2306 default:
2307 fp = key_fingerprint(ctx->old_keys[i], SSH_FP_BASE64, SSH_DIGEST_SHA256);
2308 break;
2309 }
2310 strncat_s(buf, buf_len, get_ssh2_hostkey_type_name_from_key(ctx->old_keys[i]), _TRUNCATE);
2311 strncat_s(buf, buf_len, " ", _TRUNCATE);
2312 if (fp != NULL) {
2313 strncat_s(buf, buf_len, fp, _TRUNCATE);
2314 free(fp);
2315 }
2316 if (i < ctx->nold - 1) {
2317 strncat_s(buf, buf_len, "\r\n", _TRUNCATE);
2318 }
2319 }
2320 SetDlgItemTextA(dlg, IDC_REMOVEKEY_EDIT, buf);
2321 free(buf);
2322 }
2323 }
2324
2325 static UINT_PTR CALLBACK hosts_updatekey_dlg_proc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam)
2326 {
2327 PTInstVar pvar;
2328 char buf[1024];
2329 char *host;
2330 struct hostkeys_update_ctx *ctx;
2331 char uimsg[MAX_UIMSG];
2332
2333 switch (msg) {
2334 case WM_INITDIALOG:
2335 pvar = (PTInstVar)lParam;
2336 SetWindowLongPtr(dlg, DWLP_USER, lParam);
2337
2338 GetWindowText(dlg, uimsg, sizeof(uimsg));
2339 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_TITLE", pvar, uimsg);
2340 SetWindowText(dlg, pvar->ts->UIMsg);
2341
2342 host = pvar->ssh_state.hostname;
2343 ctx = pvar->hostkey_ctx;
2344
2345 GetDlgItemText(dlg, IDC_HOSTKEY_MESSAGE, uimsg, sizeof(uimsg));
2346 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_WARNING", pvar, uimsg);
2347 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2348 pvar->ts->UIMsg, host, ctx->nnew, ctx->nold
2349 );
2350 SetDlgItemText(dlg, IDC_HOSTKEY_MESSAGE, buf);
2351
2352 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2353 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_FP_HASH_ALGORITHM", pvar, uimsg);
2354 SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2355
2356 GetDlgItemText(dlg, IDC_ADDKEY_TEXT, uimsg, sizeof(uimsg));
2357 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_ADD", pvar, uimsg);
2358 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, ctx->nnew);
2359 SetDlgItemText(dlg, IDC_ADDKEY_TEXT, buf);
2360
2361 GetDlgItemText(dlg, IDC_REMOVEKEY_TEXT, uimsg, sizeof(uimsg));
2362 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_REMOVE", pvar, uimsg);
2363 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, ctx->nold);
2364 SetDlgItemText(dlg, IDC_REMOVEKEY_TEXT, buf);
2365
2366 CheckDlgButton(dlg, IDC_FP_HASH_ALG_SHA256, TRUE);
2367 hosts_updatekey_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2368
2369 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2370 UTIL_get_lang_msg("BTN_YES", pvar, uimsg);
2371 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2372 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2373 UTIL_get_lang_msg("BTN_NO", pvar, uimsg);
2374 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2375
2376 CenterWindow(dlg, GetParent(dlg));
2377 return TRUE; /* because we do not set the focus */
2378
2379 case WM_COMMAND:
2380 pvar = (PTInstVar)GetWindowLongPtr(dlg, DWLP_USER);
2381
2382 switch (LOWORD(wParam)) {
2383 case IDOK:
2384 EndDialog(dlg, 1);
2385 return TRUE;
2386
2387 case IDCANCEL: /* kill the connection */
2388 EndDialog(dlg, 0);
2389 return TRUE;
2390
2391 case IDC_FP_HASH_ALG_MD5:
2392 hosts_updatekey_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2393 return TRUE;
2394
2395 case IDC_FP_HASH_ALG_SHA256:
2396 hosts_updatekey_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2397 return TRUE;
2398
2399 default:
2400 return FALSE;
2401 }
2402
2403 default:
2404 return FALSE;
2405 }
2406 }
2407
2408 static void update_known_hosts(PTInstVar pvar, struct hostkeys_update_ctx *ctx)
2409 {
2410 size_t i;
2411 int dlgresult;
2412 char *host;
2413
2414 host = pvar->ssh_state.hostname;
2415
2416 // "/nosecuritywarning"���w�����������������A�X�V�������s�������B
2417 if (pvar->nocheck_known_hosts) {
2418 logputs(LOG_LEVEL_VERBOSE, "Hostkey was not updated because `/nosecuritywarning' option was specified.");
2419 goto error;
2420 }
2421
2422 // known_hosts�t�@�C�����X�V���s�������A���[�U���������������s���B
2423 if (pvar->settings.UpdateHostkeys == SSH_UPDATE_HOSTKEYS_ASK) {
2424 HWND cur_active = GetActiveWindow();
2425
2426 pvar->hostkey_ctx = ctx;
2427 dlgresult = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUPDATE_HOSTKEY),
2428 cur_active != NULL ? cur_active : pvar->NotificationWindow,
2429 hosts_updatekey_dlg_proc, (LPARAM)pvar);
2430 if (dlgresult != 1) {
2431 logputs(LOG_LEVEL_VERBOSE, "Hostkey was not updated because a user cancelled.");
2432 goto error;
2433 }
2434 }
2435
2436 // �����L�[�����������������B
2437 HOSTS_delete_all_hostkeys(pvar);
2438
2439 // �V�����L�[���������o�^�����B
2440 for (i = 0; i < ctx->nkeys; i++) {
2441 HOSTS_add_host_key(pvar, ctx->keys[i]);
2442 }
2443 logputs(LOG_LEVEL_VERBOSE, "Hostkey was successfully updated to known_hosts file.");
2444
2445 error:
2446 return;
2447 }
2448
2449 static void client_global_hostkeys_private_confirm(PTInstVar pvar, int type, u_int32_t seq, void *_ctx)
2450 {
2451 struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
2452 char *data;
2453 int len;
2454 unsigned char *blob = NULL;
2455 int bloblen;
2456 buffer_t *b = NULL;
2457 buffer_t *bsig = NULL;
2458 char *cp, *sig;
2459 size_t i, ndone, siglen;
2460 int siglen_i;
2461 int ret;
2462
2463 // SSH2 packet format:
2464 // [size(4) + padding size(1) + type(1)] + [payload(N) + padding(X)]
2465 // header body
2466 // ^data
2467 // <-----------------size------------------------------->
2468 // <---------len-------->
2469 //
2470 // data = payload(N) + padding(X): �p�f�B���O���������{�f�B���������w���B
2471 data = pvar->ssh_state.payload;
2472 // len = size - (padding size + 1): �p�f�B���O�������{�f�B�Btype�����������������B
2473 len = pvar->ssh_state.payloadlen;
2474 len--; // type ��������
2475
2476 bsig = buffer_init();
2477 if (bsig == NULL)
2478 goto error;
2479 cp = buffer_append_space(bsig, len);
2480 memcpy(cp, data, len);
2481
2482 if (ctx->nnew == 0) {
2483 logprintf(LOG_LEVEL_FATAL,
2484 "Hostkey can not be updated because ctx->nnew %d(program bug).", ctx->nnew);
2485 goto error;
2486 }
2487 if (type != SSH2_MSG_REQUEST_SUCCESS) {
2488 logprintf(LOG_LEVEL_ERROR,
2489 "Server failed to confirm ownership of private host keys(type %d)", type);
2490 goto error;
2491 }
2492 if (pvar->session_id_len == 0) {
2493 logprintf(LOG_LEVEL_FATAL,
2494 "Hostkey can not be updated because pvar->session_id_len %d(program bug).",
2495 pvar->session_id_len);
2496 goto error;
2497 }
2498
2499 b = buffer_init();
2500 if (b == NULL)
2501 goto error;
2502
2503 ndone = 0;
2504 for (i = 0; i < ctx->nkeys; i++) {
2505 if (ctx->keys_seen[i])
2506 continue;
2507
2508 buffer_clear(b);
2509 buffer_put_cstring(b, "hostkeys-prove-00@openssh.com");
2510 buffer_put_string(b, pvar->session_id, pvar->session_id_len);
2511 key_to_blob(ctx->keys[i], &blob, &bloblen);
2512 buffer_put_string(b, blob, bloblen);
2513 free(blob);
2514 blob = NULL;
2515
2516 sig = buffer_get_string_msg(bsig, &siglen_i);
2517 siglen = siglen_i;
2518 // Verify signature
2519 ret = key_verify(ctx->keys[i], sig, siglen, buffer_ptr(b), buffer_len(b));
2520 free(sig);
2521 sig = NULL;
2522 if (ret != 1) {
2523 logprintf(LOG_LEVEL_ERROR,
2524 "server gave bad signature for %s key %u",
2525 get_ssh2_hostkey_type_name_from_key(ctx->keys[i]), i);
2526 goto error;
2527 }
2528 ndone++;
2529 }
2530
2531 if (ndone != ctx->nnew) {
2532 logprintf(LOG_LEVEL_FATAL,
2533 "Hostkey can not be updated because ndone != ctx->nnew (%u / %u)(program bug).",
2534 ndone, ctx->nnew);
2535 goto error;
2536 }
2537
2538 update_known_hosts(pvar, ctx);
2539
2540 error:
2541 buffer_free(b);
2542 buffer_free(bsig);
2543 hostkeys_update_ctx_free(ctx);
2544 }
2545
2546 //
2547 // SSH�T�[�o�z�X�g��(known_hosts)�������X�V(OpenSSH 6.8 or later: host key rotation support)
2548 //
2549 // return 1: success
2550 // 0: fail
2551 //
2552 int update_client_input_hostkeys(PTInstVar pvar, char *dataptr, int datalen)
2553 {
2554 int success = 1; // OpenSSH 6.8�����������A�����������������������������������A
2555 // �������������� Tera Term �������������������������B
2556 int len;
2557 size_t i;
2558 char *cp, *fp;
2559 unsigned char *blob = NULL;
2560 buffer_t *b = NULL;
2561 struct hostkeys_update_ctx *ctx = NULL;
2562 Key *key = NULL, **tmp;
2563 unsigned char *outmsg;
2564
2565 // Tera Term���������A���Y�@�\���I���I�t�����������������������B
2566 if (pvar->settings.UpdateHostkeys == SSH_UPDATE_HOSTKEYS_NO) {
2567 logputs(LOG_LEVEL_VERBOSE, "Hostkey was not updated because ts.UpdateHostkeys is disabled.");
2568 return 1;
2569 }
2570
2571 ctx = calloc(1, sizeof(struct hostkeys_update_ctx));
2572 if (ctx == NULL)
2573 goto error;
2574
2575 b = buffer_init();
2576 if (b == NULL)
2577 goto error;
2578
2579 cp = buffer_append_space(b, datalen);
2580 memcpy(cp, dataptr, datalen);
2581
2582 while (buffer_remain_len(b) > 0) {
2583 key_free(key);
2584 key = NULL;
2585
2586 blob = buffer_get_string_msg(b, &len);
2587 key = key_from_blob(blob, len);
2588 if (key == NULL) {
2589 logprintf(LOG_LEVEL_ERROR, "Not found host key into blob %p (%d)", blob, len);
2590 goto error;
2591 }
2592 free(blob);
2593 blob = NULL;
2594
2595 fp = key_fingerprint(key, SSH_FP_HEX, SSH_DIGEST_MD5);
2596 logprintf(LOG_LEVEL_VERBOSE, "Received %s host key %s",
2597 get_ssh2_hostkey_type_name_from_key(key), fp);
2598 free(fp);
2599
2600 // �����������z�X�g�L�[�A���S���Y�������`�F�b�N�����B
2601 if (check_hostkey_algorithm(pvar, key) == 0) {
2602 logprintf(LOG_LEVEL_VERBOSE, "%s host key is not permitted by ts.HostKeyOrder",
2603 get_ssh2_hostkey_type_name_from_key(key));
2604 continue;
2605 }
2606
2607 // Skip certs: Tera Term�����������F�������T�|�[�g�B
2608
2609 // �d�������L�[�����M�������G���[�������B
2610 for (i = 0; i < ctx->nkeys; i++) {
2611 if (HOSTS_compare_public_key(key, ctx->keys[i]) == 1) {
2612 logprintf(LOG_LEVEL_ERROR, "Received duplicated %s host key",
2613 get_ssh2_hostkey_type_name_from_key(key));
2614 goto error;
2615 }
2616 }
2617
2618 // �L�[���o�^�����B
2619 tmp = realloc(ctx->keys, (ctx->nkeys + 1)*sizeof(*ctx->keys));
2620 if (tmp == NULL) {
2621 logprintf(LOG_LEVEL_FATAL, "Not memory: realloc ctx->keys %d",
2622 ctx->nkeys);
2623 goto error;
2624 }
2625 ctx->keys = tmp;
2626 ctx->keys[ctx->nkeys++] = key;
2627 key = NULL;
2628 }
2629
2630 if (ctx->nkeys == 0) {
2631 logputs(LOG_LEVEL_VERBOSE, "No host rotation key");
2632 goto error;
2633 }
2634
2635 if ((ctx->keys_seen = calloc(ctx->nkeys, sizeof(*ctx->keys_seen))) == NULL) {
2636 logprintf(LOG_LEVEL_FATAL, "Not memory: calloc ctx->keys %d",
2637 ctx->nkeys);
2638 goto error;
2639 }
2640
2641 HOSTS_hostkey_foreach(pvar, hostkeys_find, ctx);
2642
2643 // �T�[�o�������������������Q�����A�������������V�K���������������������B
2644 ctx->nnew = 0;
2645 for (i = 0; i < ctx->nkeys; i++) {
2646 if (!ctx->keys_seen[i])
2647 ctx->nnew++;
2648 }
2649 logprintf(LOG_LEVEL_VERBOSE, "%u keys from server: %u new, %u retained. %u to remove",
2650 ctx->nkeys, ctx->nnew, ctx->nkeys - ctx->nnew, ctx->nold);
2651
2652 // �V�K�������������[�������Adeprecated���������������B
2653 if (ctx->nnew == 0 && ctx->nold != 0) {
2654 update_known_hosts(pvar, ctx);
2655
2656 }
2657 else if (ctx->nnew != 0) { // �V�K�������������������������B
2658 buffer_clear(b);
2659
2660 buffer_put_cstring(b, "hostkeys-prove-00@openssh.com");
2661 buffer_put_char(b, 1); /* bool: want reply */
2662
2663 for (i = 0; i < ctx->nkeys; i++) {
2664 if (ctx->keys_seen[i])
2665 continue;
2666 key_to_blob(ctx->keys[i], &blob, &len);
2667 buffer_put_string(b, blob, len);
2668 free(blob);
2669 blob = NULL;
2670 }
2671
2672 len = buffer_len(b);
2673 outmsg = begin_send_packet(pvar, SSH2_MSG_GLOBAL_REQUEST, len);
2674 memcpy(outmsg, buffer_ptr(b), len);
2675 finish_send_packet(pvar);
2676
2677 // SSH2_MSG_GLOBAL_REQUEST�����X�|���X�����������n���h�����o�^�����B
2678 client_register_global_confirm(client_global_hostkeys_private_confirm, ctx);
2679 ctx = NULL; // callback���������������A��������NULL���������������B
2680 }
2681
2682 success = 1;
2683
2684 error:
2685 buffer_free(b);
2686 hostkeys_update_ctx_free(ctx);
2687 free(blob);
2688
2689 return (success);
2690 }

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