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

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