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

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