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

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