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 6145 - (show annotations) (download) (as text)
Tue Nov 17 04:37:00 2015 UTC (8 years, 4 months ago) by maya
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 60229 byte(s)
鍵のコピーを関数化
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 memset(digest, 'd', 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 memset(digest, 'd', sizeof(digest));
312 memset(sigblob, 's', 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 memset(digest, 'd', 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 memset(sigblob, 's', len);
438 free(sigblob);
439 }
440 if (sm) {
441 memset(sm, 'S', (size_t)smlen);
442 free(sm);
443 }
444 if (m) {
445 memset(m, '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 FAR *copy_mp_int(char FAR * num)
482 {
483 int len = (get_ushort16_MSBfirst(num) + 7) / 8 + 2;
484 char FAR *result = (char FAR *) 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 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, enum 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 memset(blob, 0, 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] = len - 1;
825 field[x][y] = 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, enum 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 memset(dgst_raw, 0, 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 // �L�[����������������
1073 //
1074 void key_free(Key *key)
1075 {
1076 if (key == NULL) {
1077 return;
1078 }
1079
1080 switch (key->type) {
1081 case KEY_RSA1:
1082 case KEY_RSA:
1083 if (key->rsa != NULL)
1084 RSA_free(key->rsa);
1085 key->rsa = NULL;
1086 break;
1087
1088 case KEY_DSA:
1089 if (key->dsa != NULL)
1090 DSA_free(key->dsa);
1091 key->dsa = NULL;
1092 break;
1093
1094 case KEY_ECDSA256:
1095 case KEY_ECDSA384:
1096 case KEY_ECDSA521:
1097 if (key->ecdsa != NULL)
1098 EC_KEY_free(key->ecdsa);
1099 key->ecdsa = NULL;
1100 break;
1101
1102 case KEY_ED25519:
1103 if (key->ed25519_pk) {
1104 memset(key->ed25519_pk, 0, ED25519_PK_SZ);
1105 free(key->ed25519_pk);
1106 key->ed25519_pk = NULL;
1107 }
1108 if (key->ed25519_sk) {
1109 memset(key->ed25519_sk, 0, ED25519_SK_SZ);
1110 free(key->ed25519_sk);
1111 key->ed25519_sk = NULL;
1112 }
1113 break;
1114 }
1115 free(key);
1116 }
1117
1118 //
1119 // �L�[���������������p����
1120 //
1121 char *get_sshname_from_key(Key *key)
1122 {
1123 return get_ssh_keytype_name(key->type);
1124 }
1125
1126 //
1127 // �L�[������������������������
1128 //
1129 ssh_keytype get_keytype_from_name(char *name)
1130 {
1131 if (strcmp(name, "rsa1") == 0) {
1132 return KEY_RSA1;
1133 } else if (strcmp(name, "rsa") == 0) {
1134 return KEY_RSA;
1135 } else if (strcmp(name, "dsa") == 0) {
1136 return KEY_DSA;
1137 } else if (strcmp(name, "ssh-rsa") == 0) {
1138 return KEY_RSA;
1139 } else if (strcmp(name, "ssh-dss") == 0) {
1140 return KEY_DSA;
1141 } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
1142 return KEY_ECDSA256;
1143 } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
1144 return KEY_ECDSA384;
1145 } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
1146 return KEY_ECDSA521;
1147 } else if (strcmp(name, "ssh-ed25519") == 0) {
1148 return KEY_ED25519;
1149 }
1150 return KEY_UNSPEC;
1151 }
1152
1153
1154 ssh_keytype key_curve_name_to_keytype(char *name)
1155 {
1156 if (strcmp(name, "nistp256") == 0) {
1157 return KEY_ECDSA256;
1158 } else if (strcmp(name, "nistp384") == 0) {
1159 return KEY_ECDSA384;
1160 } else if (strcmp(name, "nistp521") == 0) {
1161 return KEY_ECDSA521;
1162 }
1163 return KEY_UNSPEC;
1164 }
1165
1166 char *curve_keytype_to_name(ssh_keytype type)
1167 {
1168 switch (type) {
1169 case KEY_ECDSA256:
1170 return "nistp256";
1171 break;
1172 case KEY_ECDSA384:
1173 return "nistp384";
1174 break;
1175 case KEY_ECDSA521:
1176 return "nistp521";
1177 break;
1178 }
1179 return NULL;
1180 }
1181
1182 //
1183 // �L�[���������o�b�t�@���������� (for SSH2)
1184 // NOTE:
1185 //
1186 int key_to_blob(Key *key, char **blobp, int *lenp)
1187 {
1188 buffer_t *b;
1189 char *sshname, *tmp;
1190 int len;
1191 int ret = 1; // success
1192
1193 b = buffer_init();
1194 sshname = get_sshname_from_key(key);
1195
1196 switch (key->type) {
1197 case KEY_RSA:
1198 buffer_put_string(b, sshname, strlen(sshname));
1199 buffer_put_bignum2(b, key->rsa->e);
1200 buffer_put_bignum2(b, key->rsa->n);
1201 break;
1202 case KEY_DSA:
1203 buffer_put_string(b, sshname, strlen(sshname));
1204 buffer_put_bignum2(b, key->dsa->p);
1205 buffer_put_bignum2(b, key->dsa->q);
1206 buffer_put_bignum2(b, key->dsa->g);
1207 buffer_put_bignum2(b, key->dsa->pub_key);
1208 break;
1209 case KEY_ECDSA256:
1210 case KEY_ECDSA384:
1211 case KEY_ECDSA521:
1212 buffer_put_string(b, sshname, strlen(sshname));
1213 tmp = curve_keytype_to_name(key->type);
1214 buffer_put_string(b, tmp, strlen(tmp));
1215 buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
1216 EC_KEY_get0_public_key(key->ecdsa));
1217 break;
1218 case KEY_ED25519:
1219 buffer_put_cstring(b, sshname);
1220 buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
1221 break;
1222
1223 default:
1224 ret = 0;
1225 goto error;
1226 }
1227
1228 len = buffer_len(b);
1229 if (lenp != NULL)
1230 *lenp = len;
1231 if (blobp != NULL) {
1232 *blobp = malloc(len);
1233 if (*blobp == NULL) {
1234 ret = 0;
1235 goto error;
1236 }
1237 memcpy(*blobp, buffer_ptr(b), len);
1238 }
1239
1240 error:
1241 buffer_free(b);
1242
1243 return (ret);
1244 }
1245
1246
1247 //
1248 // �o�b�t�@�����L�[�����������o��(for SSH2)
1249 // NOTE: ���l���A���P�[�g���������������A�����o�������������������B
1250 //
1251 Key *key_from_blob(char *data, int blen)
1252 {
1253 int keynamelen, len;
1254 char key[128];
1255 RSA *rsa = NULL;
1256 DSA *dsa = NULL;
1257 EC_KEY *ecdsa = NULL;
1258 EC_POINT *q = NULL;
1259 char *curve = NULL;
1260 Key *hostkey = NULL; // hostkey
1261 ssh_keytype type;
1262 unsigned char *pk = NULL;
1263
1264 if (data == NULL)
1265 goto error;
1266
1267 hostkey = malloc(sizeof(Key));
1268 if (hostkey == NULL)
1269 goto error;
1270
1271 memset(hostkey, 0, sizeof(Key));
1272
1273 keynamelen = get_uint32_MSBfirst(data);
1274 if (keynamelen >= sizeof(key)) {
1275 goto error;
1276 }
1277 data += 4;
1278 memcpy(key, data, keynamelen);
1279 key[keynamelen] = 0;
1280 data += keynamelen;
1281
1282 type = get_keytype_from_name(key);
1283
1284 switch (type) {
1285 case KEY_RSA: // RSA key
1286 rsa = RSA_new();
1287 if (rsa == NULL) {
1288 goto error;
1289 }
1290 rsa->n = BN_new();
1291 rsa->e = BN_new();
1292 if (rsa->n == NULL || rsa->e == NULL) {
1293 goto error;
1294 }
1295
1296 buffer_get_bignum2(&data, rsa->e);
1297 buffer_get_bignum2(&data, rsa->n);
1298
1299 hostkey->type = type;
1300 hostkey->rsa = rsa;
1301 break;
1302
1303 case KEY_DSA: // DSA key
1304 dsa = DSA_new();
1305 if (dsa == NULL) {
1306 goto error;
1307 }
1308 dsa->p = BN_new();
1309 dsa->q = BN_new();
1310 dsa->g = BN_new();
1311 dsa->pub_key = BN_new();
1312 if (dsa->p == NULL ||
1313 dsa->q == NULL ||
1314 dsa->g == NULL ||
1315 dsa->pub_key == NULL) {
1316 goto error;
1317 }
1318
1319 buffer_get_bignum2(&data, dsa->p);
1320 buffer_get_bignum2(&data, dsa->q);
1321 buffer_get_bignum2(&data, dsa->g);
1322 buffer_get_bignum2(&data, dsa->pub_key);
1323
1324 hostkey->type = type;
1325 hostkey->dsa = dsa;
1326 break;
1327
1328 case KEY_ECDSA256: // ECDSA
1329 case KEY_ECDSA384:
1330 case KEY_ECDSA521:
1331 curve = buffer_get_string(&data, NULL);
1332 if (type != key_curve_name_to_keytype(curve)) {
1333 goto error;
1334 }
1335
1336 ecdsa = EC_KEY_new_by_curve_name(keytype_to_cipher_nid(type));
1337 if (ecdsa == NULL) {
1338 goto error;
1339 }
1340
1341 q = EC_POINT_new(EC_KEY_get0_group(ecdsa));
1342 if (q == NULL) {
1343 goto error;
1344 }
1345
1346 buffer_get_ecpoint(&data, EC_KEY_get0_group(ecdsa), q);
1347 if (key_ec_validate_public(EC_KEY_get0_group(ecdsa), q) == -1) {
1348 goto error;
1349 }
1350
1351 if (EC_KEY_set_public_key(ecdsa, q) != 1) {
1352 goto error;
1353 }
1354
1355 hostkey->type = type;
1356 hostkey->ecdsa = ecdsa;
1357 break;
1358
1359 case KEY_ED25519:
1360 pk = buffer_get_string(&data, &len);
1361 if (pk == NULL)
1362 goto error;
1363 if (len != ED25519_PK_SZ)
1364 goto error;
1365
1366 hostkey->type = type;
1367 hostkey->ed25519_pk = pk;
1368 pk = NULL;
1369 break;
1370
1371 default: // unknown key
1372 goto error;
1373 }
1374
1375 return (hostkey);
1376
1377 error:
1378 if (rsa != NULL)
1379 RSA_free(rsa);
1380 if (dsa != NULL)
1381 DSA_free(dsa);
1382 if (ecdsa != NULL)
1383 EC_KEY_free(ecdsa);
1384
1385 free(hostkey);
1386
1387 return NULL;
1388 }
1389
1390
1391 static int ssh_ed25519_sign(Key *key, char **sigp, int *lenp, char *data, int datalen)
1392 {
1393 char *sig;
1394 int slen, len;
1395 unsigned long long smlen;
1396 int ret;
1397 buffer_t *b;
1398
1399 smlen = slen = datalen + crypto_sign_ed25519_BYTES;
1400 sig = malloc(slen);
1401
1402 if ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen,
1403 key->ed25519_sk)) != 0 || smlen <= datalen) {
1404 //error("%s: crypto_sign_ed25519 failed: %d", __func__, ret);
1405 free(sig);
1406 return -1;
1407 }
1408 /* encode signature */
1409 b = buffer_init();
1410 buffer_put_cstring(b, "ssh-ed25519");
1411 buffer_put_string(b, sig, (int)(smlen - datalen));
1412 len = buffer_len(b);
1413 if (lenp != NULL)
1414 *lenp = len;
1415 if (sigp != NULL) {
1416 *sigp = malloc(len);
1417 memcpy(*sigp, buffer_ptr(b), len);
1418 }
1419 buffer_free(b);
1420 memset(sig, 's', slen);
1421 free(sig);
1422
1423 return 0;
1424 }
1425
1426
1427 BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen)
1428 {
1429 buffer_t *msg = NULL;
1430 char *s;
1431 int ret;
1432
1433 msg = buffer_init();
1434 if (msg == NULL) {
1435 // TODO: error check
1436 return FALSE;
1437 }
1438
1439 switch (keypair->type) {
1440 case KEY_RSA: // RSA
1441 {
1442 const EVP_MD *evp_md = EVP_sha1();
1443 EVP_MD_CTX md;
1444 u_char digest[EVP_MAX_MD_SIZE], *sig;
1445 u_int slen, dlen, len;
1446 int ok, nid = NID_sha1;
1447
1448 // �_�C�W�F�X�g�l���v�Z
1449 EVP_DigestInit(&md, evp_md);
1450 EVP_DigestUpdate(&md, data, datalen);
1451 EVP_DigestFinal(&md, digest, &dlen);
1452
1453 slen = RSA_size(keypair->rsa);
1454 sig = malloc(slen);
1455 if (sig == NULL)
1456 goto error;
1457
1458 // �d�q�������v�Z
1459 ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa);
1460 memset(digest, 'd', sizeof(digest));
1461 if (ok != 1) { // error
1462 free(sig);
1463 goto error;
1464 }
1465 // �������T�C�Y���o�b�t�@���������������A�������������B�������[�����������B
1466 if (len < slen) {
1467 u_int diff = slen - len;
1468 memmove(sig + diff, sig, len);
1469 memset(sig, 0, diff);
1470
1471 } else if (len > slen) {
1472 free(sig);
1473 goto error;
1474
1475 } else {
1476 // do nothing
1477
1478 }
1479
1480 s = get_sshname_from_key(keypair);
1481 buffer_put_string(msg, s, strlen(s));
1482 buffer_append_length(msg, sig, slen);
1483 len = buffer_len(msg);
1484
1485 // setting
1486 *siglen = len;
1487 *sigptr = malloc(len);
1488 if (*sigptr == NULL) {
1489 free(sig);
1490 goto error;
1491 }
1492 memcpy(*sigptr, buffer_ptr(msg), len);
1493 free(sig);
1494
1495 break;
1496 }
1497 case KEY_DSA: // DSA
1498 {
1499 DSA_SIG *sig;
1500 const EVP_MD *evp_md = EVP_sha1();
1501 EVP_MD_CTX md;
1502 u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
1503 u_int rlen, slen, len, dlen;
1504
1505 // �_�C�W�F�X�g���v�Z
1506 EVP_DigestInit(&md, evp_md);
1507 EVP_DigestUpdate(&md, data, datalen);
1508 EVP_DigestFinal(&md, digest, &dlen);
1509
1510 // DSA�d�q�������v�Z
1511 sig = DSA_do_sign(digest, dlen, keypair->dsa);
1512 memset(digest, 'd', sizeof(digest));
1513 if (sig == NULL) {
1514 goto error;
1515 }
1516
1517 // BIGNUM�����o�C�i���l��������
1518 rlen = BN_num_bytes(sig->r);
1519 slen = BN_num_bytes(sig->s);
1520 if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
1521 DSA_SIG_free(sig);
1522 goto error;
1523 }
1524 memset(sigblob, 0, SIGBLOB_LEN);
1525 BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
1526 BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
1527 DSA_SIG_free(sig);
1528
1529 // setting
1530 s = get_sshname_from_key(keypair);
1531 buffer_put_string(msg, s, strlen(s));
1532 buffer_append_length(msg, sigblob, sizeof(sigblob));
1533 len = buffer_len(msg);
1534
1535 // setting
1536 *siglen = len;
1537 *sigptr = malloc(len);
1538 if (*sigptr == NULL) {
1539 goto error;
1540 }
1541 memcpy(*sigptr, buffer_ptr(msg), len);
1542
1543 break;
1544 }
1545 case KEY_ECDSA256: // ECDSA
1546 case KEY_ECDSA384:
1547 case KEY_ECDSA521:
1548 {
1549 ECDSA_SIG *sig;
1550 const EVP_MD *evp_md;
1551 EVP_MD_CTX md;
1552 u_char digest[EVP_MAX_MD_SIZE];
1553 u_int len, dlen, nid;
1554 buffer_t *buf2 = NULL;
1555
1556 nid = keytype_to_hash_nid(keypair->type);
1557 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
1558 goto error;
1559 }
1560 EVP_DigestInit(&md, evp_md);
1561 EVP_DigestUpdate(&md, data, datalen);
1562 EVP_DigestFinal(&md, digest, &dlen);
1563
1564 sig = ECDSA_do_sign(digest, dlen, keypair->ecdsa);
1565 memset(digest, 'd', sizeof(digest));
1566
1567 if (sig == NULL) {
1568 goto error;
1569 }
1570
1571 buf2 = buffer_init();
1572 if (buf2 == NULL) {
1573 // TODO: error check
1574 goto error;
1575 }
1576 buffer_put_bignum2(buf2, sig->r);
1577 buffer_put_bignum2(buf2, sig->s);
1578 ECDSA_SIG_free(sig);
1579
1580 s = get_sshname_from_key(keypair);
1581 buffer_put_string(msg, s, strlen(s));
1582 buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2));
1583 buffer_free(buf2);
1584 len = buffer_len(msg);
1585
1586 *siglen = len;
1587 *sigptr = malloc(len);
1588 if (*sigptr == NULL) {
1589 goto error;
1590 }
1591 memcpy(*sigptr, buffer_ptr(msg), len);
1592
1593 break;
1594 }
1595
1596 case KEY_ED25519:
1597 ret = ssh_ed25519_sign(keypair, sigptr, siglen, data, datalen);
1598 if (ret != 0)
1599 goto error;
1600 break;
1601
1602 default:
1603 buffer_free(msg);
1604 return FALSE;
1605 break;
1606 }
1607
1608 buffer_free(msg);
1609 return TRUE;
1610
1611 error:
1612 buffer_free(msg);
1613
1614 return FALSE;
1615 }
1616
1617
1618 BOOL get_SSH2_publickey_blob(PTInstVar pvar, buffer_t **blobptr, int *bloblen)
1619 {
1620 buffer_t *msg = NULL;
1621 Key *keypair;
1622 char *s, *tmp;
1623
1624 msg = buffer_init();
1625 if (msg == NULL) {
1626 // TODO: error check
1627 return FALSE;
1628 }
1629
1630 keypair = pvar->auth_state.cur_cred.key_pair;
1631
1632 switch (keypair->type) {
1633 case KEY_RSA: // RSA
1634 s = get_sshname_from_key(keypair);
1635 buffer_put_string(msg, s, strlen(s));
1636 buffer_put_bignum2(msg, keypair->rsa->e); // ���J�w��
1637 buffer_put_bignum2(msg, keypair->rsa->n); // p�~q
1638 break;
1639 case KEY_DSA: // DSA
1640 s = get_sshname_from_key(keypair);
1641 buffer_put_string(msg, s, strlen(s));
1642 buffer_put_bignum2(msg, keypair->dsa->p); // �f��
1643 buffer_put_bignum2(msg, keypair->dsa->q); // (p-1)���f����
1644 buffer_put_bignum2(msg, keypair->dsa->g); // ����
1645 buffer_put_bignum2(msg, keypair->dsa->pub_key); // ���J��
1646 break;
1647 case KEY_ECDSA256: // ECDSA
1648 case KEY_ECDSA384:
1649 case KEY_ECDSA521:
1650 s = get_sshname_from_key(keypair);
1651 buffer_put_string(msg, s, strlen(s));
1652 tmp = curve_keytype_to_name(keypair->type);
1653 buffer_put_string(msg, tmp, strlen(tmp));
1654 buffer_put_ecpoint(msg, EC_KEY_get0_group(keypair->ecdsa),
1655 EC_KEY_get0_public_key(keypair->ecdsa));
1656 break;
1657 case KEY_ED25519:
1658 s = get_sshname_from_key(keypair);
1659 buffer_put_cstring(msg, s);
1660 buffer_put_string(msg, keypair->ed25519_pk, ED25519_PK_SZ);
1661 break;
1662 default:
1663 return FALSE;
1664 }
1665
1666 *blobptr = msg;
1667 *bloblen = buffer_len(msg);
1668
1669 return TRUE;
1670 }
1671
1672 int kextype_to_cipher_nid(kex_algorithm type)
1673 {
1674 switch (type) {
1675 case KEX_ECDH_SHA2_256:
1676 return NID_X9_62_prime256v1;
1677 case KEX_ECDH_SHA2_384:
1678 return NID_secp384r1;
1679 case KEX_ECDH_SHA2_521:
1680 return NID_secp521r1;
1681 }
1682 return NID_undef;
1683 }
1684
1685 int keytype_to_hash_nid(ssh_keytype type)
1686 {
1687 switch (type) {
1688 case KEY_ECDSA256:
1689 return NID_sha256;
1690 case KEY_ECDSA384:
1691 return NID_sha384;
1692 case KEY_ECDSA521:
1693 return NID_sha512;
1694 }
1695 return NID_undef;
1696 }
1697
1698 int keytype_to_cipher_nid(ssh_keytype type)
1699 {
1700 switch (type) {
1701 case KEY_ECDSA256:
1702 return NID_X9_62_prime256v1;
1703 case KEY_ECDSA384:
1704 return NID_secp384r1;
1705 case KEY_ECDSA521:
1706 return NID_secp521r1;
1707 }
1708 return NID_undef;
1709 }
1710
1711 ssh_keytype nid_to_keytype(int nid)
1712 {
1713 switch (nid) {
1714 case NID_X9_62_prime256v1:
1715 return KEY_ECDSA256;
1716 case NID_secp384r1:
1717 return KEY_ECDSA384;
1718 case NID_secp521r1:
1719 return KEY_ECDSA521;
1720 }
1721 return KEY_UNSPEC;
1722 }
1723
1724 void key_private_serialize(Key *key, buffer_t *b)
1725 {
1726 char *s;
1727
1728 s = get_sshname_from_key(key);
1729 buffer_put_cstring(b, s);
1730
1731 switch (key->type) {
1732 case KEY_RSA:
1733 buffer_put_bignum2(b, key->rsa->n);
1734 buffer_put_bignum2(b, key->rsa->e);
1735 buffer_put_bignum2(b, key->rsa->d);
1736 buffer_put_bignum2(b, key->rsa->iqmp);
1737 buffer_put_bignum2(b, key->rsa->p);
1738 buffer_put_bignum2(b, key->rsa->q);
1739 break;
1740
1741 case KEY_DSA:
1742 buffer_put_bignum2(b, key->dsa->p);
1743 buffer_put_bignum2(b, key->dsa->q);
1744 buffer_put_bignum2(b, key->dsa->g);
1745 buffer_put_bignum2(b, key->dsa->pub_key);
1746 buffer_put_bignum2(b, key->dsa->priv_key);
1747 break;
1748
1749 case KEY_ECDSA256:
1750 case KEY_ECDSA384:
1751 case KEY_ECDSA521:
1752 buffer_put_cstring(b, curve_keytype_to_name(key->type));
1753 buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
1754 EC_KEY_get0_public_key(key->ecdsa));
1755 buffer_put_bignum2(b, (BIGNUM *)EC_KEY_get0_private_key(key->ecdsa));
1756 break;
1757
1758 case KEY_ED25519:
1759 buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
1760 buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ);
1761 break;
1762
1763 default:
1764 break;
1765 }
1766 }
1767
1768 /* calculate p-1 and q-1 */
1769 static void rsa_generate_additional_parameters(RSA *rsa)
1770 {
1771 BIGNUM *aux = NULL;
1772 BN_CTX *ctx = NULL;
1773
1774 if ((aux = BN_new()) == NULL)
1775 goto error;
1776 if ((ctx = BN_CTX_new()) == NULL)
1777 goto error;
1778
1779 if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) ||
1780 (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) ||
1781 (BN_sub(aux, rsa->p, BN_value_one()) == 0) ||
1782 (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0))
1783 goto error;
1784
1785 error:
1786 if (aux)
1787 BN_clear_free(aux);
1788 if (ctx)
1789 BN_CTX_free(ctx);
1790 }
1791
1792 static int key_ec_validate_private(EC_KEY *key)
1793 {
1794 BN_CTX *bnctx = NULL;
1795 BIGNUM *order, *tmp;
1796 int ret = -1;
1797
1798 if ((bnctx = BN_CTX_new()) == NULL)
1799 goto out;
1800 BN_CTX_start(bnctx);
1801
1802 if ((order = BN_CTX_get(bnctx)) == NULL ||
1803 (tmp = BN_CTX_get(bnctx)) == NULL)
1804 goto out;
1805
1806 /* log2(private) > log2(order)/2 */
1807 if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1)
1808 goto out;
1809 if (BN_num_bits(EC_KEY_get0_private_key(key)) <=
1810 BN_num_bits(order) / 2) {
1811 goto out;
1812 }
1813
1814 /* private < order - 1 */
1815 if (!BN_sub(tmp, order, BN_value_one()))
1816 goto out;
1817 if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) {
1818 goto out;
1819 }
1820 ret = 0;
1821
1822 out:
1823 if (bnctx)
1824 BN_CTX_free(bnctx);
1825 return ret;
1826 }
1827
1828 Key *key_private_deserialize(buffer_t *blob)
1829 {
1830 int success = 0;
1831 char *type_name = NULL;
1832 Key *k = NULL;
1833 unsigned int pklen, sklen;
1834 int type;
1835
1836 type_name = buffer_get_string_msg(blob, NULL);
1837 if (type_name == NULL)
1838 goto error;
1839 type = get_keytype_from_name(type_name);
1840
1841 k = key_new_private(type);
1842
1843 switch (type) {
1844 case KEY_RSA:
1845 buffer_get_bignum2_msg(blob, k->rsa->n);
1846 buffer_get_bignum2_msg(blob, k->rsa->e);
1847 buffer_get_bignum2_msg(blob, k->rsa->d);
1848 buffer_get_bignum2_msg(blob, k->rsa->iqmp);
1849 buffer_get_bignum2_msg(blob, k->rsa->p);
1850 buffer_get_bignum2_msg(blob, k->rsa->q);
1851
1852 /* Generate additional parameters */
1853 rsa_generate_additional_parameters(k->rsa);
1854 break;
1855
1856 case KEY_DSA:
1857 buffer_get_bignum2_msg(blob, k->dsa->p);
1858 buffer_get_bignum2_msg(blob, k->dsa->q);
1859 buffer_get_bignum2_msg(blob, k->dsa->g);
1860 buffer_get_bignum2_msg(blob, k->dsa->pub_key);
1861 buffer_get_bignum2_msg(blob, k->dsa->priv_key);
1862 break;
1863
1864 case KEY_ECDSA256:
1865 case KEY_ECDSA384:
1866 case KEY_ECDSA521:
1867 {
1868 int success = 0;
1869 unsigned int nid;
1870 char *curve = NULL;
1871 ssh_keytype skt;
1872 BIGNUM *exponent = NULL;
1873 EC_POINT *q = NULL;
1874
1875 nid = keytype_to_cipher_nid(type);
1876 curve = buffer_get_string_msg(blob, NULL);
1877 skt = key_curve_name_to_keytype(curve);
1878 if (nid != keytype_to_cipher_nid(skt))
1879 goto ecdsa_error;
1880
1881 k->ecdsa = EC_KEY_new_by_curve_name(nid);
1882 if (k->ecdsa == NULL)
1883 goto ecdsa_error;
1884
1885 q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa));
1886 if (q == NULL)
1887 goto ecdsa_error;
1888
1889 if ((exponent = BN_new()) == NULL)
1890 goto ecdsa_error;
1891 buffer_get_ecpoint_msg(blob,
1892 EC_KEY_get0_group(k->ecdsa), q);
1893 buffer_get_bignum2_msg(blob, exponent);
1894 if (EC_KEY_set_public_key(k->ecdsa, q) != 1)
1895 goto ecdsa_error;
1896 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
1897 goto ecdsa_error;
1898 if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
1899 EC_KEY_get0_public_key(k->ecdsa)) != 0)
1900 goto ecdsa_error;
1901 if (key_ec_validate_private(k->ecdsa) != 0)
1902 goto ecdsa_error;
1903
1904 success = 1;
1905
1906 ecdsa_error:
1907 free(curve);
1908 if (exponent)
1909 BN_clear_free(exponent);
1910 if (q)
1911 EC_POINT_free(q);
1912 if (success == 0)
1913 goto error;
1914 }
1915 break;
1916
1917 case KEY_ED25519:
1918 k->ed25519_pk = buffer_get_string_msg(blob, &pklen);
1919 k->ed25519_sk = buffer_get_string_msg(blob, &sklen);
1920 if (pklen != ED25519_PK_SZ)
1921 goto error;
1922 if (sklen != ED25519_SK_SZ)
1923 goto error;
1924 break;
1925
1926 default:
1927 goto error;
1928 break;
1929 }
1930
1931 /* enable blinding */
1932 switch (k->type) {
1933 case KEY_RSA1:
1934 case KEY_RSA:
1935 if (RSA_blinding_on(k->rsa, NULL) != 1)
1936 goto error;
1937 break;
1938 }
1939
1940 success = 1;
1941
1942 error:
1943 free(type_name);
1944
1945 if (success == 0) {
1946 key_free(k);
1947 k = NULL;
1948 }
1949
1950 return (k);
1951 }
1952
1953
1954 static void hostkeys_update_ctx_free(struct hostkeys_update_ctx *ctx)
1955 {
1956 size_t i;
1957
1958 if (ctx == NULL)
1959 return;
1960 for (i = 0; i < ctx->nkeys; i++)
1961 key_free(ctx->keys[i]);
1962 free(ctx->keys);
1963 free(ctx->keys_seen);
1964 for (i = 0; i < ctx->nold; i++)
1965 key_free(ctx->old_keys[i]);
1966 free(ctx->old_keys);
1967 free(ctx->host_str);
1968 free(ctx->ip_str);
1969 free(ctx);
1970 }
1971
1972
1973 // �����������z�X�g���A���S���Y�������`�F�b�N�����B
1974 //
1975 // return 1: matched
1976 // 0: not matched
1977 //
1978 static int check_hostkey_algorithm(PTInstVar pvar, Key *key)
1979 {
1980 int ret = 0;
1981 int i, index;
1982
1983 for (i = 0; pvar->settings.HostKeyOrder[i] != 0; i++) {
1984 index = pvar->settings.HostKeyOrder[i] - '0';
1985 if (index == KEY_NONE) // disabled line
1986 break;
1987
1988 if (strcmp(get_sshname_from_key(key), get_ssh_keytype_name(index)) == 0)
1989 return 1;
1990 }
1991
1992 return (ret);
1993 }
1994
1995 // Callback function
1996 //
1997 // argument:
1998 // key: known_hosts���o�^������������
1999 // _ctx: �T�[�o�����������������������Q
2000 //
2001 // return:
2002 // 1: deprecated key�������A��������key�������������~�B
2003 // 0: ����������key�������������K�v�B
2004 static int hostkeys_find(Key *key, void *_ctx)
2005 {
2006 struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
2007 int ret = 0;
2008 size_t i;
2009 Key **tmp;
2010
2011 // SSH1�������O�B
2012 if (key->type == KEY_RSA1)
2013 goto error;
2014
2015 // �������o�^�������������������T���B
2016 for (i = 0; i < ctx->nkeys; i++) {
2017 if (HOSTS_compare_public_key(key, ctx->keys[i]) == 1) {
2018 ctx->keys_seen[i] = 1;
2019 goto error;
2020 }
2021 }
2022
2023 // deprecated�������A�����������X�g�������������B
2024 tmp = realloc(ctx->old_keys, (ctx->nold + 1)*sizeof(*ctx->old_keys));
2025 if (tmp != NULL) {
2026 ctx->old_keys = tmp;
2027 ctx->old_keys[ctx->nold++] = key;
2028 }
2029
2030 ret = 1;
2031
2032 error:
2033 return (ret);
2034 }
2035
2036 static void hosts_updatekey_dlg_set_fingerprint(PTInstVar pvar, HWND dlg, digest_algorithm dgst_alg)
2037 {
2038 char *fp, *buf;
2039 size_t i;
2040 int buf_len;
2041 struct hostkeys_update_ctx *ctx;
2042
2043 ctx = pvar->hostkey_ctx;
2044
2045 if (ctx->nkeys > 0) {
2046 buf_len = 100 * ctx->nkeys;
2047 buf = calloc(100, ctx->nkeys);
2048 for (i = 0; i < ctx->nkeys; i++) {
2049 if (ctx->keys_seen[i])
2050 continue;
2051 switch (dgst_alg) {
2052 case SSH_DIGEST_MD5:
2053 fp = key_fingerprint(ctx->keys[i], SSH_FP_HEX, dgst_alg);
2054 break;
2055 case SSH_DIGEST_SHA256:
2056 fp = key_fingerprint(ctx->keys[i], SSH_FP_BASE64, dgst_alg);
2057 break;
2058 }
2059 strncat_s(buf, buf_len, get_sshname_from_key(ctx->keys[i]), _TRUNCATE);
2060 strncat_s(buf, buf_len, " ", _TRUNCATE);
2061 strncat_s(buf, buf_len, fp, _TRUNCATE);
2062 free(fp);
2063 if (i < ctx->nkeys - 1) {
2064 strncat_s(buf, buf_len, "\r\n", _TRUNCATE);
2065 }
2066 }
2067 SendDlgItemMessage(dlg, IDC_ADDKEY_EDIT, WM_SETTEXT, 0, (LPARAM)(char FAR *)buf);
2068 free(buf);
2069 }
2070
2071 if (ctx->nold > 0) {
2072 buf_len = 100 * ctx->nold;
2073 buf = calloc(100, ctx->nold);
2074 SendDlgItemMessage(dlg, IDC_REMOVEKEY_EDIT, WM_SETTEXT, 0, (LPARAM)(char FAR *)"");
2075 for (i = 0; i < ctx->nold; i++) {
2076 switch (dgst_alg) {
2077 case SSH_DIGEST_MD5:
2078 fp = key_fingerprint(ctx->old_keys[i], SSH_FP_HEX, dgst_alg);
2079 break;
2080 case SSH_DIGEST_SHA256:
2081 fp = key_fingerprint(ctx->old_keys[i], SSH_FP_BASE64, dgst_alg);
2082 break;
2083 }
2084 strncat_s(buf, buf_len, get_sshname_from_key(ctx->old_keys[i]), _TRUNCATE);
2085 strncat_s(buf, buf_len, " ", _TRUNCATE);
2086 strncat_s(buf, buf_len, fp, _TRUNCATE);
2087 free(fp);
2088 if (i < ctx->nold - 1) {
2089 strncat_s(buf, buf_len, "\r\n", _TRUNCATE);
2090 }
2091 }
2092 SendDlgItemMessage(dlg, IDC_REMOVEKEY_EDIT, WM_SETTEXT, 0, (LPARAM)(char FAR *)buf);
2093 free(buf);
2094 }
2095 }
2096
2097 static BOOL CALLBACK hosts_updatekey_dlg_proc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam)
2098 {
2099 static HFONT DlgHostsAddFont;
2100 PTInstVar pvar;
2101 LOGFONT logfont;
2102 HFONT font;
2103 char buf[1024];
2104 char *host;
2105 struct hostkeys_update_ctx *ctx;
2106 char uimsg[MAX_UIMSG];
2107
2108 switch (msg) {
2109 case WM_INITDIALOG:
2110 pvar = (PTInstVar)lParam;
2111 SetWindowLong(dlg, DWL_USER, lParam);
2112
2113 GetWindowText(dlg, uimsg, sizeof(uimsg));
2114 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_TITLE", pvar, uimsg);
2115 SetWindowText(dlg, pvar->ts->UIMsg);
2116
2117 host = pvar->ssh_state.hostname;
2118 ctx = pvar->hostkey_ctx;
2119
2120 GetDlgItemText(dlg, IDC_HOSTKEY_MESSAGE, uimsg, sizeof(uimsg));
2121 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_WARNING", pvar, uimsg);
2122 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2123 pvar->ts->UIMsg, host, ctx->nnew, ctx->nold
2124 );
2125 SetDlgItemText(dlg, IDC_HOSTKEY_MESSAGE, buf);
2126
2127 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2128 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_FP_HASH_ALGORITHM", pvar, uimsg);
2129 SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2130
2131 GetDlgItemText(dlg, IDC_ADDKEY_TEXT, uimsg, sizeof(uimsg));
2132 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_ADD", pvar, uimsg);
2133 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, ctx->nnew);
2134 SetDlgItemText(dlg, IDC_ADDKEY_TEXT, buf);
2135
2136 GetDlgItemText(dlg, IDC_REMOVEKEY_TEXT, uimsg, sizeof(uimsg));
2137 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_REMOVE", pvar, uimsg);
2138 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, ctx->nold);
2139 SetDlgItemText(dlg, IDC_REMOVEKEY_TEXT, buf);
2140
2141 CheckDlgButton(dlg, IDC_FP_HASH_ALG_SHA256, TRUE);
2142 hosts_updatekey_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2143
2144 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2145 UTIL_get_lang_msg("BTN_YES", pvar, uimsg);
2146 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2147 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2148 UTIL_get_lang_msg("BTN_NO", pvar, uimsg);
2149 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2150
2151 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2152 GetObject(font, sizeof(LOGFONT), &logfont);
2153 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
2154 SendDlgItemMessage(dlg, IDC_HOSTKEY_MESSAGE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2155 SendDlgItemMessage(dlg, IDC_ADDKEY_TEXT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2156 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2157 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2158 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2159 SendDlgItemMessage(dlg, IDC_ADDKEY_EDIT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2160 SendDlgItemMessage(dlg, IDC_REMOVEKEY_TEXT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2161 SendDlgItemMessage(dlg, IDC_REMOVEKEY_EDIT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2162 SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2163 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2164 }
2165 else {
2166 DlgHostsAddFont = NULL;
2167 }
2168
2169 return TRUE; /* because we do not set the focus */
2170
2171 case WM_COMMAND:
2172 pvar = (PTInstVar)GetWindowLong(dlg, DWL_USER);
2173
2174 switch (LOWORD(wParam)) {
2175 case IDOK:
2176
2177 EndDialog(dlg, 1);
2178
2179 if (DlgHostsAddFont != NULL) {
2180 DeleteObject(DlgHostsAddFont);
2181 }
2182
2183 return TRUE;
2184
2185 case IDCANCEL: /* kill the connection */
2186 EndDialog(dlg, 0);
2187
2188 if (DlgHostsAddFont != NULL) {
2189 DeleteObject(DlgHostsAddFont);
2190 }
2191
2192 return TRUE;
2193
2194 case IDC_FP_HASH_ALG_MD5:
2195 hosts_updatekey_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2196 return TRUE;
2197
2198 case IDC_FP_HASH_ALG_SHA256:
2199 hosts_updatekey_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2200 return TRUE;
2201
2202 default:
2203 return FALSE;
2204 }
2205
2206 default:
2207 return FALSE;
2208 }
2209 }
2210
2211 static void update_known_hosts(PTInstVar pvar, struct hostkeys_update_ctx *ctx)
2212 {
2213 size_t i;
2214 int dlgresult;
2215 char msg[1024];
2216 char *host;
2217
2218 host = pvar->ssh_state.hostname;
2219
2220 // "/nosecuritywarning"���w�����������������A�X�V�������s�������B
2221 if (pvar->nocheck_known_hosts) {
2222 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because `/nosecuritywarning' option was specified.");
2223 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2224 goto error;
2225 }
2226
2227 // known_hosts�t�@�C�����X�V���s�������A���[�U���������������s���B
2228 if (pvar->settings.UpdateHostkeys == SSH_UPDATE_HOSTKEYS_ASK) {
2229 HWND cur_active = GetActiveWindow();
2230
2231 pvar->hostkey_ctx = ctx;
2232 dlgresult = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUPDATE_HOSTKEY),
2233 cur_active != NULL ? cur_active : pvar->NotificationWindow,
2234 hosts_updatekey_dlg_proc, (LPARAM)pvar);
2235 if (dlgresult != 1) {
2236 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because a user cancelled.");
2237 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2238 goto error;
2239 }
2240 }
2241
2242 // �����L�[�����������������B
2243 HOSTS_delete_all_hostkeys(pvar);
2244
2245 // �V�����L�[���������o�^�����B
2246 for (i = 0; i < ctx->nkeys; i++) {
2247 HOSTS_add_host_key(pvar, ctx->keys[i]);
2248 }
2249 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was successfully updated to known_hosts file.");
2250 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2251
2252 error:
2253 return;
2254 }
2255
2256 static void client_global_hostkeys_private_confirm(PTInstVar pvar, int type, u_int32_t seq, void *_ctx)
2257 {
2258 struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
2259 char msg[128];
2260 char *data;
2261 int len;
2262 unsigned char *blob = NULL;
2263 int bloblen;
2264 buffer_t *b = NULL;
2265 buffer_t *bsig = NULL;
2266 char *cp, *sig;
2267 size_t i, ndone, siglen;
2268 int ret;
2269
2270 // SSH2 packet format:
2271 // [size(4) + padding size(1) + type(1)] + [payload(N) + padding(X)]
2272 // header body
2273 // ^data
2274 // <-----------------size------------------------------->
2275 // <---------len-------->
2276 //
2277 // data = payload(N) + padding(X): �p�f�B���O���������{�f�B���������w���B
2278 data = pvar->ssh_state.payload;
2279 // len = size - (padding size + 1): �p�f�B���O�������{�f�B�Btype�����������������B
2280 len = pvar->ssh_state.payloadlen;
2281 len--; // type ��������
2282
2283 bsig = buffer_init();
2284 if (bsig == NULL)
2285 goto error;
2286 cp = buffer_append_space(bsig, len);
2287 memcpy(cp, data, len);
2288
2289 if (ctx->nnew == 0) {
2290 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey can not be updated because ctx->nnew %d(program bug).", ctx->nnew);
2291 notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2292 goto error;
2293 }
2294 if (type != SSH2_MSG_REQUEST_SUCCESS) {
2295 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Server failed to confirm ownership of private host keys(type %d)", type);
2296 notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2297 goto error;
2298 }
2299 if (pvar->session_id_len == 0) {
2300 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey can not be updated because pvar->session_id_len %d(program bug).", pvar->session_id_len);
2301 notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2302 goto error;
2303 }
2304
2305 b = buffer_init();
2306 if (b == NULL)
2307 goto error;
2308
2309 ndone = 0;
2310 for (i = 0; i < ctx->nkeys; i++) {
2311 if (ctx->keys_seen[i])
2312 continue;
2313
2314 buffer_clear(b);
2315 buffer_put_cstring(b, "hostkeys-prove-00@openssh.com");
2316 buffer_put_string(b, pvar->session_id, pvar->session_id_len);
2317 key_to_blob(ctx->keys[i], &blob, &bloblen);
2318 buffer_put_string(b, blob, bloblen);
2319 free(blob);
2320 blob = NULL;
2321
2322 sig = buffer_get_string_msg(bsig, &siglen);
2323 // Verify signature
2324 ret = key_verify(ctx->keys[i], sig, siglen, buffer_ptr(b), buffer_len(b));
2325 free(sig);
2326 sig = NULL;
2327 if (ret != 1) {
2328 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "server gave bad signature for %s key %u",
2329 get_sshname_from_key(ctx->keys[i]), i);
2330 notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2331 goto error;
2332 }
2333 ndone++;
2334 }
2335
2336 if (ndone != ctx->nnew) {
2337 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey can not be updated because ndone != ctx->nnew (%u / %u)(program bug).",
2338 ndone, ctx->nnew);
2339 notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2340 goto error;
2341 }
2342
2343 update_known_hosts(pvar, ctx);
2344
2345 error:
2346 buffer_free(b);
2347 buffer_free(bsig);
2348 hostkeys_update_ctx_free(ctx);
2349 }
2350
2351 //
2352 // SSH�T�[�o�z�X�g��(known_hosts)�������X�V(OpenSSH 6.8 or later: host key rotation support)
2353 //
2354 // return 1: success
2355 // 0: fail
2356 //
2357 int update_client_input_hostkeys(PTInstVar pvar, char *dataptr, int datalen)
2358 {
2359 int success = 1; // OpenSSH 6.8�����������A�����������������������������������A
2360 // �������������� Tera Term �������������������������B
2361 int len;
2362 size_t i;
2363 char *cp, *fp;
2364 char msg[128];
2365 unsigned char *blob = NULL;
2366 buffer_t *b = NULL;
2367 struct hostkeys_update_ctx *ctx = NULL;
2368 Key *key = NULL, **tmp;
2369 unsigned char *outmsg;
2370
2371 // Tera Term���������A���Y�@�\���I���I�t�����������������������B
2372 if (pvar->settings.UpdateHostkeys == SSH_UPDATE_HOSTKEYS_NO) {
2373 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because ts.UpdateHostkeys is disabled.");
2374 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2375 return 1;
2376 }
2377
2378 ctx = calloc(1, sizeof(struct hostkeys_update_ctx));
2379 if (ctx == NULL)
2380 goto error;
2381
2382 b = buffer_init();
2383 if (b == NULL)
2384 goto error;
2385
2386 cp = buffer_append_space(b, datalen);
2387 memcpy(cp, dataptr, datalen);
2388
2389 while (buffer_remain_len(b) > 0) {
2390 key_free(key);
2391 key = NULL;
2392
2393 blob = buffer_get_string_msg(b, &len);
2394 key = key_from_blob(blob, len);
2395 if (key == NULL) {
2396 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not found host key into blob %p (%d)", blob, len);
2397 notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2398 goto error;
2399 }
2400 free(blob);
2401 blob = NULL;
2402
2403 fp = key_fingerprint(key, SSH_FP_HEX, SSH_DIGEST_MD5);
2404 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Received %s host key %s",
2405 get_sshname_from_key(key), fp);
2406 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2407 free(fp);
2408
2409 // �����������z�X�g�L�[�A���S���Y�������`�F�b�N�����B
2410 if (check_hostkey_algorithm(pvar, key) == 0) {
2411 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "%s host key is not permitted by ts.HostKeyOrder",
2412 get_sshname_from_key(key));
2413 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2414 continue;
2415 }
2416
2417 // Skip certs: Tera Term�����������F�������T�|�[�g�B
2418
2419 // �d�������L�[�����M�������G���[�������B
2420 for (i = 0; i < ctx->nkeys; i++) {
2421 if (HOSTS_compare_public_key(key, ctx->keys[i]) == 1) {
2422 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Received duplicated %s host key",
2423 get_sshname_from_key(key));
2424 notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2425 goto error;
2426 }
2427 }
2428
2429 // �L�[���o�^�����B
2430 tmp = realloc(ctx->keys, (ctx->nkeys + 1)*sizeof(*ctx->keys));
2431 if (tmp == NULL) {
2432 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not memory: realloc ctx->keys %d",
2433 ctx->nkeys);
2434 notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2435 goto error;
2436 }
2437 ctx->keys = tmp;
2438 ctx->keys[ctx->nkeys++] = key;
2439 key = NULL;
2440 }
2441
2442 if (ctx->nkeys == 0) {
2443 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "No host rotation key");
2444 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2445 goto error;
2446 }
2447
2448 if ((ctx->keys_seen = calloc(ctx->nkeys, sizeof(*ctx->keys_seen))) == NULL) {
2449 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not memory: calloc ctx->keys %d",
2450 ctx->nkeys);
2451 notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2452 goto error;
2453 }
2454
2455 HOSTS_hostkey_foreach(pvar, hostkeys_find, ctx);
2456
2457 // �T�[�o�������������������Q�����A�������������V�K���������������������B
2458 ctx->nnew = 0;
2459 for (i = 0; i < ctx->nkeys; i++) {
2460 if (!ctx->keys_seen[i])
2461 ctx->nnew++;
2462 }
2463 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "%u keys from server: %u new, %u retained. %u to remove",
2464 ctx->nkeys, ctx->nnew, ctx->nkeys - ctx->nnew, ctx->nold);
2465 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2466
2467 // �V�K�������������[�������Adeprecated���������������B
2468 if (ctx->nnew == 0 && ctx->nold != 0) {
2469 update_known_hosts(pvar, ctx);
2470
2471 }
2472 else if (ctx->nnew != 0) { // �V�K�������������������������B
2473 buffer_clear(b);
2474
2475 buffer_put_cstring(b, "hostkeys-prove-00@openssh.com");
2476 buffer_put_char(b, 1); /* bool: want reply */
2477
2478 for (i = 0; i < ctx->nkeys; i++) {
2479 if (ctx->keys_seen[i])
2480 continue;
2481 key_to_blob(ctx->keys[i], &blob, &len);
2482 buffer_put_string(b, blob, len);
2483 free(blob);
2484 blob = NULL;
2485 }
2486
2487 len = buffer_len(b);
2488 outmsg = begin_send_packet(pvar, SSH2_MSG_GLOBAL_REQUEST, len);
2489 memcpy(outmsg, buffer_ptr(b), len);
2490 finish_send_packet(pvar);
2491
2492 // SSH2_MSG_GLOBAL_REQUEST�����X�|���X�����������n���h�����o�^�����B
2493 client_register_global_confirm(client_global_hostkeys_private_confirm, ctx);
2494 ctx = NULL; // callback���������������A��������NULL���������������B
2495 }
2496
2497 success = 1;
2498
2499 error:
2500 buffer_free(b);
2501 hostkeys_update_ctx_free(ctx);
2502 free(blob);
2503
2504 return (success);
2505 }

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