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 6809 - (show annotations) (download) (as text)
Mon Jun 19 12:50:42 2017 UTC (6 years, 9 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 59465 byte(s)
ログ関連を見直し。

・_snprintf_s() + notify_verbose_message() を logprintf() に置き換え。
・固定メッセージの notify_verbose_message() を logputs() に置き換え。

pvar を渡す必要が無くなったので、pvar が使えない状況でもログ出力が行える。

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

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