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 6118 - (show annotations) (download) (as text)
Thu Nov 12 14:33:12 2015 UTC (8 years, 5 months ago) by maya
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 56421 byte(s)
SSH key fingerprint を base64 形式で出力する関数を追加
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 //
482 // RSA�\����������
483 //
484 RSA *duplicate_RSA(RSA *src)
485 {
486 RSA *rsa = NULL;
487
488 rsa = RSA_new();
489 if (rsa == NULL)
490 goto error;
491 rsa->n = BN_new();
492 rsa->e = BN_new();
493 if (rsa->n == NULL || rsa->e == NULL) {
494 RSA_free(rsa);
495 goto error;
496 }
497
498 // �[���R�s�[(deep copy)���s���B�����R�s�[(shallow copy)��NG�B
499 BN_copy(rsa->n, src->n);
500 BN_copy(rsa->e, src->e);
501
502 error:
503 return (rsa);
504 }
505
506
507 //
508 // DSA�\����������
509 //
510 DSA *duplicate_DSA(DSA *src)
511 {
512 DSA *dsa = NULL;
513
514 dsa = DSA_new();
515 if (dsa == NULL)
516 goto error;
517 dsa->p = BN_new();
518 dsa->q = BN_new();
519 dsa->g = BN_new();
520 dsa->pub_key = BN_new();
521 if (dsa->p == NULL ||
522 dsa->q == NULL ||
523 dsa->g == NULL ||
524 dsa->pub_key == NULL) {
525 DSA_free(dsa);
526 goto error;
527 }
528
529 // �[���R�s�[(deep copy)���s���B�����R�s�[(shallow copy)��NG�B
530 BN_copy(dsa->p, src->p);
531 BN_copy(dsa->q, src->q);
532 BN_copy(dsa->g, src->g);
533 BN_copy(dsa->pub_key, src->pub_key);
534
535 error:
536 return (dsa);
537 }
538
539 unsigned char *duplicate_ED25519_PK(unsigned char *src)
540 {
541 unsigned char *ptr = NULL;
542
543 ptr = malloc(ED25519_PK_SZ);
544 if (ptr) {
545 memcpy(ptr, src, ED25519_PK_SZ);
546 }
547 return (ptr);
548 }
549
550
551 char* key_fingerprint_raw(Key *k, enum fp_type dgst_type, int *dgst_raw_length)
552 {
553 const EVP_MD *md = NULL;
554 EVP_MD_CTX ctx;
555 char *blob = NULL;
556 char *retval = NULL;
557 int len = 0;
558 int nlen, elen;
559 RSA *rsa;
560
561 *dgst_raw_length = 0;
562
563 switch (dgst_type) {
564 case SSH_FP_MD5:
565 md = EVP_md5();
566 break;
567 case SSH_FP_SHA1:
568 md = EVP_sha1();
569 break;
570 case SSH_FP_SHA256:
571 md = EVP_sha256();
572 break;
573 default:
574 md = EVP_md5();
575 }
576
577 switch (k->type) {
578 case KEY_RSA1:
579 rsa = make_key(NULL, k->bits, k->exp, k->mod);
580 nlen = BN_num_bytes(rsa->n);
581 elen = BN_num_bytes(rsa->e);
582 len = nlen + elen;
583 blob = malloc(len);
584 if (blob == NULL) {
585 // TODO:
586 }
587 BN_bn2bin(rsa->n, blob);
588 BN_bn2bin(rsa->e, blob + nlen);
589 RSA_free(rsa);
590 break;
591
592 case KEY_DSA:
593 case KEY_RSA:
594 case KEY_ECDSA256:
595 case KEY_ECDSA384:
596 case KEY_ECDSA521:
597 case KEY_ED25519:
598 key_to_blob(k, &blob, &len);
599 break;
600
601 case KEY_UNSPEC:
602 return retval;
603 break;
604
605 default:
606 //fatal("key_fingerprint_raw: bad key type %d", k->type);
607 break;
608 }
609
610 if (blob != NULL) {
611 retval = malloc(EVP_MAX_MD_SIZE);
612 if (retval == NULL) {
613 // TODO:
614 }
615 EVP_DigestInit(&ctx, md);
616 EVP_DigestUpdate(&ctx, blob, len);
617 EVP_DigestFinal(&ctx, retval, dgst_raw_length);
618 memset(blob, 0, len);
619 free(blob);
620 } else {
621 //fatal("key_fingerprint_raw: blob is null");
622 }
623 return retval;
624 }
625
626
627 const char *
628 ssh_key_type(ssh_keytype type)
629 {
630 switch (type) {
631 case KEY_RSA1:
632 return "RSA1";
633 case KEY_RSA:
634 return "RSA";
635 case KEY_DSA:
636 return "DSA";
637 case KEY_ECDSA256:
638 case KEY_ECDSA384:
639 case KEY_ECDSA521:
640 return "ECDSA";
641 case KEY_ED25519:
642 return "ED25519";
643 }
644 return "unknown";
645 }
646
647 unsigned int
648 key_size(const Key *k)
649 {
650 switch (k->type) {
651 case KEY_RSA1:
652 // SSH1�������� key->rsa �� key->dsa �� NULL �����������A�g�������B
653 return k->bits;
654 case KEY_RSA:
655 return BN_num_bits(k->rsa->n);
656 case KEY_DSA:
657 return BN_num_bits(k->dsa->p);
658 case KEY_ECDSA256:
659 return 256;
660 case KEY_ECDSA384:
661 return 384;
662 case KEY_ECDSA521:
663 return 521;
664 case KEY_ED25519:
665 return 256; /* XXX */
666 }
667 return 0;
668 }
669
670 static char *
671 key_fingerprint_b64(u_char *dgst_raw, u_int dgst_raw_len)
672 {
673 char *retval;
674 unsigned int i, retval_len;
675 BIO *bio, *b64;
676 BUF_MEM *bufferPtr;
677
678 retval_len = ((dgst_raw_len + 2) / 3) * 4 + 1;
679 retval = malloc(retval_len);
680 retval[0] = '\0';
681
682 b64 = BIO_new(BIO_f_base64());
683 bio = BIO_new(BIO_s_mem());
684 bio = BIO_push(b64, bio);
685
686 BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
687 BIO_write(bio, dgst_raw, dgst_raw_len);
688 BIO_flush(bio);
689 BIO_get_mem_ptr(bio, &bufferPtr);
690 strncat_s(retval, retval_len, bufferPtr->data, _TRUNCATE);
691 BIO_set_close(bio, BIO_NOCLOSE);
692 BIO_free_all(bio);
693
694 /* Remove the trailing '=' character */
695 for (i = strlen(retval) - 1; retval[i] == '='; i--) {
696 retval[i] = '\0';
697 }
698
699 return (retval);
700 }
701
702 static char *
703 key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len)
704 {
705 char *retval;
706 unsigned int i, retval_len;
707
708 retval_len = dgst_raw_len * 3 + 1;
709 retval = malloc(retval_len);
710 retval[0] = '\0';
711 for (i = 0; i < dgst_raw_len; i++) {
712 char hex[4];
713 _snprintf_s(hex, sizeof(hex), _TRUNCATE, "%02x:", dgst_raw[i]);
714 strncat_s(retval, retval_len, hex, _TRUNCATE);
715 }
716
717 /* Remove the trailing ':' character */
718 retval[(dgst_raw_len * 3) - 1] = '\0';
719
720 return (retval);
721 }
722
723 // based on OpenSSH 5.1
724 #define FLDBASE 8
725 #define FLDSIZE_Y (FLDBASE + 1)
726 #define FLDSIZE_X (FLDBASE * 2 + 1)
727 static char *
728 key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
729 {
730 /*
731 * Chars to be used after each other every time the worm
732 * intersects with itself. Matter of taste.
733 */
734 char *augmentation_string = " .o+=*BOX@%&#/^SE";
735 char *retval, *p;
736 unsigned char field[FLDSIZE_X][FLDSIZE_Y];
737 unsigned int i, b;
738 int x, y;
739 size_t len = strlen(augmentation_string) - 1;
740
741 retval = calloc(1, (FLDSIZE_X + 3 + 1) * (FLDSIZE_Y + 2));
742
743 /* initialize field */
744 memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
745 x = FLDSIZE_X / 2;
746 y = FLDSIZE_Y / 2;
747
748 /* process raw key */
749 for (i = 0; i < dgst_raw_len; i++) {
750 int input;
751 /* each byte conveys four 2-bit move commands */
752 input = dgst_raw[i];
753 for (b = 0; b < 4; b++) {
754 /* evaluate 2 bit, rest is shifted later */
755 x += (input & 0x1) ? 1 : -1;
756 y += (input & 0x2) ? 1 : -1;
757
758 /* assure we are still in bounds */
759 x = max(x, 0);
760 y = max(y, 0);
761 x = min(x, FLDSIZE_X - 1);
762 y = min(y, FLDSIZE_Y - 1);
763
764 /* augment the field */
765 field[x][y]++;
766 input = input >> 2;
767 }
768 }
769
770 /* mark starting point and end point*/
771 field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
772 field[x][y] = len;
773
774 /* fill in retval */
775 _snprintf_s(retval, FLDSIZE_X, _TRUNCATE, "+--[%4s %4u]", ssh_key_type(k->type), key_size(k));
776 p = strchr(retval, '\0');
777
778 /* output upper border */
779 for (i = p - retval - 1; i < FLDSIZE_X; i++)
780 *p++ = '-';
781 *p++ = '+';
782 *p++ = '\r';
783 *p++ = '\n';
784
785 /* output content */
786 for (y = 0; y < FLDSIZE_Y; y++) {
787 *p++ = '|';
788 for (x = 0; x < FLDSIZE_X; x++)
789 *p++ = augmentation_string[min(field[x][y], len)];
790 *p++ = '|';
791 *p++ = '\r';
792 *p++ = '\n';
793 }
794
795 /* output lower border */
796 *p++ = '+';
797 for (i = 0; i < FLDSIZE_X; i++)
798 *p++ = '-';
799 *p++ = '+';
800
801 return retval;
802 }
803 #undef FLDBASE
804 #undef FLDSIZE_Y
805 #undef FLDSIZE_X
806
807 //
808 // fingerprint�i�w���F�z�X�g���J�����n�b�V���j����������
809 //
810 char *key_fingerprint(Key *key, enum fp_rep dgst_rep, enum fp_type dgst_type)
811 {
812 char *retval = NULL;
813 unsigned char *dgst_raw;
814 int dgst_raw_len;
815
816 // fingerprint���n�b�V���l�i�o�C�i���j��������
817 dgst_raw = key_fingerprint_raw(key, dgst_type, &dgst_raw_len);
818 if (dgst_raw == NULL)
819 return NULL;
820
821 switch (dgst_rep) {
822 case SSH_FP_HEX:
823 retval = key_fingerprint_hex(dgst_raw, dgst_raw_len);
824 break;
825 case SSH_FP_BASE64:
826 retval = key_fingerprint_b64(dgst_raw, dgst_raw_len);
827 break;
828 case SSH_FP_RANDOMART:
829 retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, key);
830 break;
831 }
832
833 memset(dgst_raw, 0, dgst_raw_len);
834 free(dgst_raw);
835
836 return (retval);
837 }
838
839 //
840 // �L�[�������������m��
841 //
842 static void key_add_private(Key *k)
843 {
844 switch (k->type) {
845 case KEY_RSA1:
846 case KEY_RSA:
847 k->rsa->d = BN_new();
848 k->rsa->iqmp = BN_new();
849 k->rsa->q = BN_new();
850 k->rsa->p = BN_new();
851 k->rsa->dmq1 = BN_new();
852 k->rsa->dmp1 = BN_new();
853 if (k->rsa->d == NULL || k->rsa->iqmp == NULL || k->rsa->q == NULL ||
854 k->rsa->p == NULL || k->rsa->dmq1 == NULL || k->rsa->dmp1 == NULL)
855 goto error;
856 break;
857
858 case KEY_DSA:
859 k->dsa->priv_key = BN_new();
860 if (k->dsa->priv_key == NULL)
861 goto error;
862 break;
863
864 case KEY_ECDSA256:
865 case KEY_ECDSA384:
866 case KEY_ECDSA521:
867 /* Cannot do anything until we know the group */
868 break;
869
870 case KEY_ED25519:
871 /* no need to prealloc */
872 break;
873
874 case KEY_UNSPEC:
875 break;
876
877 default:
878 goto error;
879 break;
880 }
881 return;
882
883 error:
884 if (k->rsa->d) {
885 BN_free(k->rsa->d);
886 k->rsa->d = NULL;
887 }
888 if (k->rsa->iqmp) {
889 BN_free(k->rsa->iqmp);
890 k->rsa->iqmp = NULL;
891 }
892 if (k->rsa->q) {
893 BN_free(k->rsa->q);
894 k->rsa->q = NULL;
895 }
896 if (k->rsa->p) {
897 BN_free(k->rsa->p);
898 k->rsa->p = NULL;
899 }
900 if (k->rsa->dmq1) {
901 BN_free(k->rsa->dmq1);
902 k->rsa->dmq1 = NULL;
903 }
904 if (k->rsa->dmp1) {
905 BN_free(k->rsa->dmp1);
906 k->rsa->dmp1 = NULL;
907 }
908
909
910 if (k->dsa->priv_key == NULL) {
911 BN_free(k->dsa->priv_key);
912 k->dsa->priv_key = NULL;
913 }
914
915 }
916
917 Key *key_new_private(int type)
918 {
919 Key *k = key_new(type);
920
921 key_add_private(k);
922 return (k);
923 }
924
925
926 Key *key_new(int type)
927 {
928 int success = 0;
929 Key *k = NULL;
930 RSA *rsa;
931 DSA *dsa;
932
933 k = calloc(1, sizeof(Key));
934 if (k == NULL)
935 goto error;
936 k->type = type;
937 k->ecdsa = NULL;
938 k->dsa = NULL;
939 k->rsa = NULL;
940 k->ed25519_pk = NULL;
941 k->ed25519_sk = NULL;
942
943 switch (k->type) {
944 case KEY_RSA1:
945 case KEY_RSA:
946 rsa = RSA_new();
947 if (rsa == NULL)
948 goto error;
949 rsa->n = BN_new();
950 rsa->e = BN_new();
951 if (rsa->n == NULL || rsa->e == NULL)
952 goto error;
953 k->rsa = rsa;
954 break;
955
956 case KEY_DSA:
957 dsa = DSA_new();
958 if (dsa == NULL)
959 goto error;
960 dsa->p = BN_new();
961 dsa->q = BN_new();
962 dsa->g = BN_new();
963 dsa->pub_key = BN_new();
964 if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL || dsa->pub_key == NULL)
965 goto error;
966 k->dsa = dsa;
967 break;
968
969 case KEY_ECDSA256:
970 case KEY_ECDSA384:
971 case KEY_ECDSA521:
972 /* Cannot do anything until we know the group */
973 break;
974
975 case KEY_ED25519:
976 /* no need to prealloc */
977 break;
978
979 case KEY_UNSPEC:
980 break;
981
982 default:
983 goto error;
984 break;
985 }
986 success = 1;
987
988 error:
989 if (success == 0) {
990 key_free(k);
991 k = NULL;
992 }
993 return (k);
994 }
995
996
997 //
998 // �L�[����������������
999 //
1000 void key_free(Key *key)
1001 {
1002 if (key == NULL) {
1003 return;
1004 }
1005
1006 switch (key->type) {
1007 case KEY_RSA1:
1008 case KEY_RSA:
1009 if (key->rsa != NULL)
1010 RSA_free(key->rsa);
1011 key->rsa = NULL;
1012 break;
1013
1014 case KEY_DSA:
1015 if (key->dsa != NULL)
1016 DSA_free(key->dsa);
1017 key->dsa = NULL;
1018 break;
1019
1020 case KEY_ECDSA256:
1021 case KEY_ECDSA384:
1022 case KEY_ECDSA521:
1023 if (key->ecdsa != NULL)
1024 EC_KEY_free(key->ecdsa);
1025 key->ecdsa = NULL;
1026 break;
1027
1028 case KEY_ED25519:
1029 if (key->ed25519_pk) {
1030 memset(key->ed25519_pk, 0, ED25519_PK_SZ);
1031 free(key->ed25519_pk);
1032 key->ed25519_pk = NULL;
1033 }
1034 if (key->ed25519_sk) {
1035 memset(key->ed25519_sk, 0, ED25519_SK_SZ);
1036 free(key->ed25519_sk);
1037 key->ed25519_sk = NULL;
1038 }
1039 break;
1040 }
1041 free(key);
1042 }
1043
1044 //
1045 // �L�[���������������p����
1046 //
1047 char *get_sshname_from_key(Key *key)
1048 {
1049 return get_ssh_keytype_name(key->type);
1050 }
1051
1052 //
1053 // �L�[������������������������
1054 //
1055 ssh_keytype get_keytype_from_name(char *name)
1056 {
1057 if (strcmp(name, "rsa1") == 0) {
1058 return KEY_RSA1;
1059 } else if (strcmp(name, "rsa") == 0) {
1060 return KEY_RSA;
1061 } else if (strcmp(name, "dsa") == 0) {
1062 return KEY_DSA;
1063 } else if (strcmp(name, "ssh-rsa") == 0) {
1064 return KEY_RSA;
1065 } else if (strcmp(name, "ssh-dss") == 0) {
1066 return KEY_DSA;
1067 } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
1068 return KEY_ECDSA256;
1069 } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
1070 return KEY_ECDSA384;
1071 } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
1072 return KEY_ECDSA521;
1073 } else if (strcmp(name, "ssh-ed25519") == 0) {
1074 return KEY_ED25519;
1075 }
1076 return KEY_UNSPEC;
1077 }
1078
1079
1080 ssh_keytype key_curve_name_to_keytype(char *name)
1081 {
1082 if (strcmp(name, "nistp256") == 0) {
1083 return KEY_ECDSA256;
1084 } else if (strcmp(name, "nistp384") == 0) {
1085 return KEY_ECDSA384;
1086 } else if (strcmp(name, "nistp521") == 0) {
1087 return KEY_ECDSA521;
1088 }
1089 return KEY_UNSPEC;
1090 }
1091
1092 char *curve_keytype_to_name(ssh_keytype type)
1093 {
1094 switch (type) {
1095 case KEY_ECDSA256:
1096 return "nistp256";
1097 break;
1098 case KEY_ECDSA384:
1099 return "nistp384";
1100 break;
1101 case KEY_ECDSA521:
1102 return "nistp521";
1103 break;
1104 }
1105 return NULL;
1106 }
1107
1108 //
1109 // �L�[���������o�b�t�@���������� (for SSH2)
1110 // NOTE:
1111 //
1112 int key_to_blob(Key *key, char **blobp, int *lenp)
1113 {
1114 buffer_t *b;
1115 char *sshname, *tmp;
1116 int len;
1117 int ret = 1; // success
1118
1119 b = buffer_init();
1120 sshname = get_sshname_from_key(key);
1121
1122 switch (key->type) {
1123 case KEY_RSA:
1124 buffer_put_string(b, sshname, strlen(sshname));
1125 buffer_put_bignum2(b, key->rsa->e);
1126 buffer_put_bignum2(b, key->rsa->n);
1127 break;
1128 case KEY_DSA:
1129 buffer_put_string(b, sshname, strlen(sshname));
1130 buffer_put_bignum2(b, key->dsa->p);
1131 buffer_put_bignum2(b, key->dsa->q);
1132 buffer_put_bignum2(b, key->dsa->g);
1133 buffer_put_bignum2(b, key->dsa->pub_key);
1134 break;
1135 case KEY_ECDSA256:
1136 case KEY_ECDSA384:
1137 case KEY_ECDSA521:
1138 buffer_put_string(b, sshname, strlen(sshname));
1139 tmp = curve_keytype_to_name(key->type);
1140 buffer_put_string(b, tmp, strlen(tmp));
1141 buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
1142 EC_KEY_get0_public_key(key->ecdsa));
1143 break;
1144 case KEY_ED25519:
1145 buffer_put_cstring(b, sshname);
1146 buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
1147 break;
1148
1149 default:
1150 ret = 0;
1151 goto error;
1152 }
1153
1154 len = buffer_len(b);
1155 if (lenp != NULL)
1156 *lenp = len;
1157 if (blobp != NULL) {
1158 *blobp = malloc(len);
1159 if (*blobp == NULL) {
1160 ret = 0;
1161 goto error;
1162 }
1163 memcpy(*blobp, buffer_ptr(b), len);
1164 }
1165
1166 error:
1167 buffer_free(b);
1168
1169 return (ret);
1170 }
1171
1172
1173 //
1174 // �o�b�t�@�����L�[�����������o��(for SSH2)
1175 // NOTE: ���l���A���P�[�g���������������A�����o�������������������B
1176 //
1177 Key *key_from_blob(char *data, int blen)
1178 {
1179 int keynamelen, len;
1180 char key[128];
1181 RSA *rsa = NULL;
1182 DSA *dsa = NULL;
1183 EC_KEY *ecdsa = NULL;
1184 EC_POINT *q = NULL;
1185 char *curve = NULL;
1186 Key *hostkey = NULL; // hostkey
1187 ssh_keytype type;
1188 unsigned char *pk = NULL;
1189
1190 if (data == NULL)
1191 goto error;
1192
1193 hostkey = malloc(sizeof(Key));
1194 if (hostkey == NULL)
1195 goto error;
1196
1197 memset(hostkey, 0, sizeof(Key));
1198
1199 keynamelen = get_uint32_MSBfirst(data);
1200 if (keynamelen >= sizeof(key)) {
1201 goto error;
1202 }
1203 data += 4;
1204 memcpy(key, data, keynamelen);
1205 key[keynamelen] = 0;
1206 data += keynamelen;
1207
1208 type = get_keytype_from_name(key);
1209
1210 switch (type) {
1211 case KEY_RSA: // RSA key
1212 rsa = RSA_new();
1213 if (rsa == NULL) {
1214 goto error;
1215 }
1216 rsa->n = BN_new();
1217 rsa->e = BN_new();
1218 if (rsa->n == NULL || rsa->e == NULL) {
1219 goto error;
1220 }
1221
1222 buffer_get_bignum2(&data, rsa->e);
1223 buffer_get_bignum2(&data, rsa->n);
1224
1225 hostkey->type = type;
1226 hostkey->rsa = rsa;
1227 break;
1228
1229 case KEY_DSA: // DSA key
1230 dsa = DSA_new();
1231 if (dsa == NULL) {
1232 goto error;
1233 }
1234 dsa->p = BN_new();
1235 dsa->q = BN_new();
1236 dsa->g = BN_new();
1237 dsa->pub_key = BN_new();
1238 if (dsa->p == NULL ||
1239 dsa->q == NULL ||
1240 dsa->g == NULL ||
1241 dsa->pub_key == NULL) {
1242 goto error;
1243 }
1244
1245 buffer_get_bignum2(&data, dsa->p);
1246 buffer_get_bignum2(&data, dsa->q);
1247 buffer_get_bignum2(&data, dsa->g);
1248 buffer_get_bignum2(&data, dsa->pub_key);
1249
1250 hostkey->type = type;
1251 hostkey->dsa = dsa;
1252 break;
1253
1254 case KEY_ECDSA256: // ECDSA
1255 case KEY_ECDSA384:
1256 case KEY_ECDSA521:
1257 curve = buffer_get_string(&data, NULL);
1258 if (type != key_curve_name_to_keytype(curve)) {
1259 goto error;
1260 }
1261
1262 ecdsa = EC_KEY_new_by_curve_name(keytype_to_cipher_nid(type));
1263 if (ecdsa == NULL) {
1264 goto error;
1265 }
1266
1267 q = EC_POINT_new(EC_KEY_get0_group(ecdsa));
1268 if (q == NULL) {
1269 goto error;
1270 }
1271
1272 buffer_get_ecpoint(&data, EC_KEY_get0_group(ecdsa), q);
1273 if (key_ec_validate_public(EC_KEY_get0_group(ecdsa), q) == -1) {
1274 goto error;
1275 }
1276
1277 if (EC_KEY_set_public_key(ecdsa, q) != 1) {
1278 goto error;
1279 }
1280
1281 hostkey->type = type;
1282 hostkey->ecdsa = ecdsa;
1283 break;
1284
1285 case KEY_ED25519:
1286 pk = buffer_get_string(&data, &len);
1287 if (pk == NULL)
1288 goto error;
1289 if (len != ED25519_PK_SZ)
1290 goto error;
1291
1292 hostkey->type = type;
1293 hostkey->ed25519_pk = pk;
1294 pk = NULL;
1295 break;
1296
1297 default: // unknown key
1298 goto error;
1299 }
1300
1301 return (hostkey);
1302
1303 error:
1304 if (rsa != NULL)
1305 RSA_free(rsa);
1306 if (dsa != NULL)
1307 DSA_free(dsa);
1308 if (ecdsa != NULL)
1309 EC_KEY_free(ecdsa);
1310
1311 free(hostkey);
1312
1313 return NULL;
1314 }
1315
1316
1317 static int ssh_ed25519_sign(Key *key, char **sigp, int *lenp, char *data, int datalen)
1318 {
1319 char *sig;
1320 int slen, len;
1321 unsigned long long smlen;
1322 int ret;
1323 buffer_t *b;
1324
1325 smlen = slen = datalen + crypto_sign_ed25519_BYTES;
1326 sig = malloc(slen);
1327
1328 if ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen,
1329 key->ed25519_sk)) != 0 || smlen <= datalen) {
1330 //error("%s: crypto_sign_ed25519 failed: %d", __func__, ret);
1331 free(sig);
1332 return -1;
1333 }
1334 /* encode signature */
1335 b = buffer_init();
1336 buffer_put_cstring(b, "ssh-ed25519");
1337 buffer_put_string(b, sig, (int)(smlen - datalen));
1338 len = buffer_len(b);
1339 if (lenp != NULL)
1340 *lenp = len;
1341 if (sigp != NULL) {
1342 *sigp = malloc(len);
1343 memcpy(*sigp, buffer_ptr(b), len);
1344 }
1345 buffer_free(b);
1346 memset(sig, 's', slen);
1347 free(sig);
1348
1349 return 0;
1350 }
1351
1352
1353 BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen)
1354 {
1355 buffer_t *msg = NULL;
1356 char *s;
1357 int ret;
1358
1359 msg = buffer_init();
1360 if (msg == NULL) {
1361 // TODO: error check
1362 return FALSE;
1363 }
1364
1365 switch (keypair->type) {
1366 case KEY_RSA: // RSA
1367 {
1368 const EVP_MD *evp_md = EVP_sha1();
1369 EVP_MD_CTX md;
1370 u_char digest[EVP_MAX_MD_SIZE], *sig;
1371 u_int slen, dlen, len;
1372 int ok, nid = NID_sha1;
1373
1374 // �_�C�W�F�X�g�l���v�Z
1375 EVP_DigestInit(&md, evp_md);
1376 EVP_DigestUpdate(&md, data, datalen);
1377 EVP_DigestFinal(&md, digest, &dlen);
1378
1379 slen = RSA_size(keypair->rsa);
1380 sig = malloc(slen);
1381 if (sig == NULL)
1382 goto error;
1383
1384 // �d�q�������v�Z
1385 ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa);
1386 memset(digest, 'd', sizeof(digest));
1387 if (ok != 1) { // error
1388 free(sig);
1389 goto error;
1390 }
1391 // �������T�C�Y���o�b�t�@���������������A�������������B�������[�����������B
1392 if (len < slen) {
1393 u_int diff = slen - len;
1394 memmove(sig + diff, sig, len);
1395 memset(sig, 0, diff);
1396
1397 } else if (len > slen) {
1398 free(sig);
1399 goto error;
1400
1401 } else {
1402 // do nothing
1403
1404 }
1405
1406 s = get_sshname_from_key(keypair);
1407 buffer_put_string(msg, s, strlen(s));
1408 buffer_append_length(msg, sig, slen);
1409 len = buffer_len(msg);
1410
1411 // setting
1412 *siglen = len;
1413 *sigptr = malloc(len);
1414 if (*sigptr == NULL) {
1415 free(sig);
1416 goto error;
1417 }
1418 memcpy(*sigptr, buffer_ptr(msg), len);
1419 free(sig);
1420
1421 break;
1422 }
1423 case KEY_DSA: // DSA
1424 {
1425 DSA_SIG *sig;
1426 const EVP_MD *evp_md = EVP_sha1();
1427 EVP_MD_CTX md;
1428 u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
1429 u_int rlen, slen, len, dlen;
1430
1431 // �_�C�W�F�X�g���v�Z
1432 EVP_DigestInit(&md, evp_md);
1433 EVP_DigestUpdate(&md, data, datalen);
1434 EVP_DigestFinal(&md, digest, &dlen);
1435
1436 // DSA�d�q�������v�Z
1437 sig = DSA_do_sign(digest, dlen, keypair->dsa);
1438 memset(digest, 'd', sizeof(digest));
1439 if (sig == NULL) {
1440 goto error;
1441 }
1442
1443 // BIGNUM�����o�C�i���l��������
1444 rlen = BN_num_bytes(sig->r);
1445 slen = BN_num_bytes(sig->s);
1446 if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
1447 DSA_SIG_free(sig);
1448 goto error;
1449 }
1450 memset(sigblob, 0, SIGBLOB_LEN);
1451 BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
1452 BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
1453 DSA_SIG_free(sig);
1454
1455 // setting
1456 s = get_sshname_from_key(keypair);
1457 buffer_put_string(msg, s, strlen(s));
1458 buffer_append_length(msg, sigblob, sizeof(sigblob));
1459 len = buffer_len(msg);
1460
1461 // setting
1462 *siglen = len;
1463 *sigptr = malloc(len);
1464 if (*sigptr == NULL) {
1465 goto error;
1466 }
1467 memcpy(*sigptr, buffer_ptr(msg), len);
1468
1469 break;
1470 }
1471 case KEY_ECDSA256: // ECDSA
1472 case KEY_ECDSA384:
1473 case KEY_ECDSA521:
1474 {
1475 ECDSA_SIG *sig;
1476 const EVP_MD *evp_md;
1477 EVP_MD_CTX md;
1478 u_char digest[EVP_MAX_MD_SIZE];
1479 u_int len, dlen, nid;
1480 buffer_t *buf2 = NULL;
1481
1482 nid = keytype_to_hash_nid(keypair->type);
1483 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
1484 goto error;
1485 }
1486 EVP_DigestInit(&md, evp_md);
1487 EVP_DigestUpdate(&md, data, datalen);
1488 EVP_DigestFinal(&md, digest, &dlen);
1489
1490 sig = ECDSA_do_sign(digest, dlen, keypair->ecdsa);
1491 memset(digest, 'd', sizeof(digest));
1492
1493 if (sig == NULL) {
1494 goto error;
1495 }
1496
1497 buf2 = buffer_init();
1498 if (buf2 == NULL) {
1499 // TODO: error check
1500 goto error;
1501 }
1502 buffer_put_bignum2(buf2, sig->r);
1503 buffer_put_bignum2(buf2, sig->s);
1504 ECDSA_SIG_free(sig);
1505
1506 s = get_sshname_from_key(keypair);
1507 buffer_put_string(msg, s, strlen(s));
1508 buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2));
1509 buffer_free(buf2);
1510 len = buffer_len(msg);
1511
1512 *siglen = len;
1513 *sigptr = malloc(len);
1514 if (*sigptr == NULL) {
1515 goto error;
1516 }
1517 memcpy(*sigptr, buffer_ptr(msg), len);
1518
1519 break;
1520 }
1521
1522 case KEY_ED25519:
1523 ret = ssh_ed25519_sign(keypair, sigptr, siglen, data, datalen);
1524 if (ret != 0)
1525 goto error;
1526 break;
1527
1528 default:
1529 buffer_free(msg);
1530 return FALSE;
1531 break;
1532 }
1533
1534 buffer_free(msg);
1535 return TRUE;
1536
1537 error:
1538 buffer_free(msg);
1539
1540 return FALSE;
1541 }
1542
1543
1544 BOOL get_SSH2_publickey_blob(PTInstVar pvar, buffer_t **blobptr, int *bloblen)
1545 {
1546 buffer_t *msg = NULL;
1547 Key *keypair;
1548 char *s, *tmp;
1549
1550 msg = buffer_init();
1551 if (msg == NULL) {
1552 // TODO: error check
1553 return FALSE;
1554 }
1555
1556 keypair = pvar->auth_state.cur_cred.key_pair;
1557
1558 switch (keypair->type) {
1559 case KEY_RSA: // RSA
1560 s = get_sshname_from_key(keypair);
1561 buffer_put_string(msg, s, strlen(s));
1562 buffer_put_bignum2(msg, keypair->rsa->e); // ���J�w��
1563 buffer_put_bignum2(msg, keypair->rsa->n); // p�~q
1564 break;
1565 case KEY_DSA: // DSA
1566 s = get_sshname_from_key(keypair);
1567 buffer_put_string(msg, s, strlen(s));
1568 buffer_put_bignum2(msg, keypair->dsa->p); // �f��
1569 buffer_put_bignum2(msg, keypair->dsa->q); // (p-1)���f����
1570 buffer_put_bignum2(msg, keypair->dsa->g); // ����
1571 buffer_put_bignum2(msg, keypair->dsa->pub_key); // ���J��
1572 break;
1573 case KEY_ECDSA256: // ECDSA
1574 case KEY_ECDSA384:
1575 case KEY_ECDSA521:
1576 s = get_sshname_from_key(keypair);
1577 buffer_put_string(msg, s, strlen(s));
1578 tmp = curve_keytype_to_name(keypair->type);
1579 buffer_put_string(msg, tmp, strlen(tmp));
1580 buffer_put_ecpoint(msg, EC_KEY_get0_group(keypair->ecdsa),
1581 EC_KEY_get0_public_key(keypair->ecdsa));
1582 break;
1583 case KEY_ED25519:
1584 s = get_sshname_from_key(keypair);
1585 buffer_put_cstring(msg, s);
1586 buffer_put_string(msg, keypair->ed25519_pk, ED25519_PK_SZ);
1587 break;
1588 default:
1589 return FALSE;
1590 }
1591
1592 *blobptr = msg;
1593 *bloblen = buffer_len(msg);
1594
1595 return TRUE;
1596 }
1597
1598 int kextype_to_cipher_nid(kex_algorithm type)
1599 {
1600 switch (type) {
1601 case KEX_ECDH_SHA2_256:
1602 return NID_X9_62_prime256v1;
1603 case KEX_ECDH_SHA2_384:
1604 return NID_secp384r1;
1605 case KEX_ECDH_SHA2_521:
1606 return NID_secp521r1;
1607 }
1608 return NID_undef;
1609 }
1610
1611 int keytype_to_hash_nid(ssh_keytype type)
1612 {
1613 switch (type) {
1614 case KEY_ECDSA256:
1615 return NID_sha256;
1616 case KEY_ECDSA384:
1617 return NID_sha384;
1618 case KEY_ECDSA521:
1619 return NID_sha512;
1620 }
1621 return NID_undef;
1622 }
1623
1624 int keytype_to_cipher_nid(ssh_keytype type)
1625 {
1626 switch (type) {
1627 case KEY_ECDSA256:
1628 return NID_X9_62_prime256v1;
1629 case KEY_ECDSA384:
1630 return NID_secp384r1;
1631 case KEY_ECDSA521:
1632 return NID_secp521r1;
1633 }
1634 return NID_undef;
1635 }
1636
1637 ssh_keytype nid_to_keytype(int nid)
1638 {
1639 switch (nid) {
1640 case NID_X9_62_prime256v1:
1641 return KEY_ECDSA256;
1642 case NID_secp384r1:
1643 return KEY_ECDSA384;
1644 case NID_secp521r1:
1645 return KEY_ECDSA521;
1646 }
1647 return KEY_UNSPEC;
1648 }
1649
1650 void key_private_serialize(Key *key, buffer_t *b)
1651 {
1652 char *s;
1653
1654 s = get_sshname_from_key(key);
1655 buffer_put_cstring(b, s);
1656
1657 switch (key->type) {
1658 case KEY_RSA:
1659 buffer_put_bignum2(b, key->rsa->n);
1660 buffer_put_bignum2(b, key->rsa->e);
1661 buffer_put_bignum2(b, key->rsa->d);
1662 buffer_put_bignum2(b, key->rsa->iqmp);
1663 buffer_put_bignum2(b, key->rsa->p);
1664 buffer_put_bignum2(b, key->rsa->q);
1665 break;
1666
1667 case KEY_DSA:
1668 buffer_put_bignum2(b, key->dsa->p);
1669 buffer_put_bignum2(b, key->dsa->q);
1670 buffer_put_bignum2(b, key->dsa->g);
1671 buffer_put_bignum2(b, key->dsa->pub_key);
1672 buffer_put_bignum2(b, key->dsa->priv_key);
1673 break;
1674
1675 case KEY_ECDSA256:
1676 case KEY_ECDSA384:
1677 case KEY_ECDSA521:
1678 buffer_put_cstring(b, curve_keytype_to_name(key->type));
1679 buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
1680 EC_KEY_get0_public_key(key->ecdsa));
1681 buffer_put_bignum2(b, (BIGNUM *)EC_KEY_get0_private_key(key->ecdsa));
1682 break;
1683
1684 case KEY_ED25519:
1685 buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
1686 buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ);
1687 break;
1688
1689 default:
1690 break;
1691 }
1692 }
1693
1694 /* calculate p-1 and q-1 */
1695 static void rsa_generate_additional_parameters(RSA *rsa)
1696 {
1697 BIGNUM *aux = NULL;
1698 BN_CTX *ctx = NULL;
1699
1700 if ((aux = BN_new()) == NULL)
1701 goto error;
1702 if ((ctx = BN_CTX_new()) == NULL)
1703 goto error;
1704
1705 if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) ||
1706 (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) ||
1707 (BN_sub(aux, rsa->p, BN_value_one()) == 0) ||
1708 (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0))
1709 goto error;
1710
1711 error:
1712 if (aux)
1713 BN_clear_free(aux);
1714 if (ctx)
1715 BN_CTX_free(ctx);
1716 }
1717
1718 static int key_ec_validate_private(EC_KEY *key)
1719 {
1720 BN_CTX *bnctx = NULL;
1721 BIGNUM *order, *tmp;
1722 int ret = -1;
1723
1724 if ((bnctx = BN_CTX_new()) == NULL)
1725 goto out;
1726 BN_CTX_start(bnctx);
1727
1728 if ((order = BN_CTX_get(bnctx)) == NULL ||
1729 (tmp = BN_CTX_get(bnctx)) == NULL)
1730 goto out;
1731
1732 /* log2(private) > log2(order)/2 */
1733 if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1)
1734 goto out;
1735 if (BN_num_bits(EC_KEY_get0_private_key(key)) <=
1736 BN_num_bits(order) / 2) {
1737 goto out;
1738 }
1739
1740 /* private < order - 1 */
1741 if (!BN_sub(tmp, order, BN_value_one()))
1742 goto out;
1743 if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) {
1744 goto out;
1745 }
1746 ret = 0;
1747
1748 out:
1749 if (bnctx)
1750 BN_CTX_free(bnctx);
1751 return ret;
1752 }
1753
1754 Key *key_private_deserialize(buffer_t *blob)
1755 {
1756 int success = 0;
1757 char *type_name = NULL;
1758 Key *k = NULL;
1759 unsigned int pklen, sklen;
1760 int type;
1761
1762 type_name = buffer_get_string_msg(blob, NULL);
1763 if (type_name == NULL)
1764 goto error;
1765 type = get_keytype_from_name(type_name);
1766
1767 k = key_new_private(type);
1768
1769 switch (type) {
1770 case KEY_RSA:
1771 buffer_get_bignum2_msg(blob, k->rsa->n);
1772 buffer_get_bignum2_msg(blob, k->rsa->e);
1773 buffer_get_bignum2_msg(blob, k->rsa->d);
1774 buffer_get_bignum2_msg(blob, k->rsa->iqmp);
1775 buffer_get_bignum2_msg(blob, k->rsa->p);
1776 buffer_get_bignum2_msg(blob, k->rsa->q);
1777
1778 /* Generate additional parameters */
1779 rsa_generate_additional_parameters(k->rsa);
1780 break;
1781
1782 case KEY_DSA:
1783 buffer_get_bignum2_msg(blob, k->dsa->p);
1784 buffer_get_bignum2_msg(blob, k->dsa->q);
1785 buffer_get_bignum2_msg(blob, k->dsa->g);
1786 buffer_get_bignum2_msg(blob, k->dsa->pub_key);
1787 buffer_get_bignum2_msg(blob, k->dsa->priv_key);
1788 break;
1789
1790 case KEY_ECDSA256:
1791 case KEY_ECDSA384:
1792 case KEY_ECDSA521:
1793 {
1794 int success = 0;
1795 unsigned int nid;
1796 char *curve = NULL;
1797 ssh_keytype skt;
1798 BIGNUM *exponent = NULL;
1799 EC_POINT *q = NULL;
1800
1801 nid = keytype_to_cipher_nid(type);
1802 curve = buffer_get_string_msg(blob, NULL);
1803 skt = key_curve_name_to_keytype(curve);
1804 if (nid != keytype_to_cipher_nid(skt))
1805 goto ecdsa_error;
1806
1807 k->ecdsa = EC_KEY_new_by_curve_name(nid);
1808 if (k->ecdsa == NULL)
1809 goto ecdsa_error;
1810
1811 q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa));
1812 if (q == NULL)
1813 goto ecdsa_error;
1814
1815 if ((exponent = BN_new()) == NULL)
1816 goto ecdsa_error;
1817 buffer_get_ecpoint_msg(blob,
1818 EC_KEY_get0_group(k->ecdsa), q);
1819 buffer_get_bignum2_msg(blob, exponent);
1820 if (EC_KEY_set_public_key(k->ecdsa, q) != 1)
1821 goto ecdsa_error;
1822 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
1823 goto ecdsa_error;
1824 if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
1825 EC_KEY_get0_public_key(k->ecdsa)) != 0)
1826 goto ecdsa_error;
1827 if (key_ec_validate_private(k->ecdsa) != 0)
1828 goto ecdsa_error;
1829
1830 success = 1;
1831
1832 ecdsa_error:
1833 free(curve);
1834 if (exponent)
1835 BN_clear_free(exponent);
1836 if (q)
1837 EC_POINT_free(q);
1838 if (success == 0)
1839 goto error;
1840 }
1841 break;
1842
1843 case KEY_ED25519:
1844 k->ed25519_pk = buffer_get_string_msg(blob, &pklen);
1845 k->ed25519_sk = buffer_get_string_msg(blob, &sklen);
1846 if (pklen != ED25519_PK_SZ)
1847 goto error;
1848 if (sklen != ED25519_SK_SZ)
1849 goto error;
1850 break;
1851
1852 default:
1853 goto error;
1854 break;
1855 }
1856
1857 /* enable blinding */
1858 switch (k->type) {
1859 case KEY_RSA1:
1860 case KEY_RSA:
1861 if (RSA_blinding_on(k->rsa, NULL) != 1)
1862 goto error;
1863 break;
1864 }
1865
1866 success = 1;
1867
1868 error:
1869 free(type_name);
1870
1871 if (success == 0) {
1872 key_free(k);
1873 k = NULL;
1874 }
1875
1876 return (k);
1877 }
1878
1879
1880 static void hostkeys_update_ctx_free(struct hostkeys_update_ctx *ctx)
1881 {
1882 size_t i;
1883
1884 if (ctx == NULL)
1885 return;
1886 for (i = 0; i < ctx->nkeys; i++)
1887 key_free(ctx->keys[i]);
1888 free(ctx->keys);
1889 free(ctx->keys_seen);
1890 for (i = 0; i < ctx->nold; i++)
1891 key_free(ctx->old_keys[i]);
1892 free(ctx->old_keys);
1893 free(ctx->host_str);
1894 free(ctx->ip_str);
1895 free(ctx);
1896 }
1897
1898
1899 // �����������z�X�g���A���S���Y�������`�F�b�N�����B
1900 //
1901 // return 1: matched
1902 // 0: not matched
1903 //
1904 static int check_hostkey_algorithm(PTInstVar pvar, Key *key)
1905 {
1906 int ret = 0;
1907 int i, index;
1908
1909 for (i = 0; pvar->settings.HostKeyOrder[i] != 0; i++) {
1910 index = pvar->settings.HostKeyOrder[i] - '0';
1911 if (index == KEY_NONE) // disabled line
1912 break;
1913
1914 if (strcmp(get_sshname_from_key(key), get_ssh_keytype_name(index)) == 0)
1915 return 1;
1916 }
1917
1918 return (ret);
1919 }
1920
1921 // Callback function
1922 //
1923 // argument:
1924 // key: known_hosts���o�^������������
1925 // _ctx: �T�[�o�����������������������Q
1926 //
1927 // return:
1928 // 1: deprecated key�������A��������key�������������~�B
1929 // 0: ����������key�������������K�v�B
1930 static int hostkeys_find(Key *key, void *_ctx)
1931 {
1932 struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
1933 int ret = 0;
1934 size_t i;
1935 Key **tmp;
1936
1937 // SSH1�������O�B
1938 if (key->type == KEY_RSA1)
1939 goto error;
1940
1941 // �������o�^�������������������T���B
1942 for (i = 0; i < ctx->nkeys; i++) {
1943 if (HOSTS_compare_public_key(key, ctx->keys[i]) == 1) {
1944 ctx->keys_seen[i] = 1;
1945 goto error;
1946 }
1947 }
1948
1949 // deprecated�������A�����������X�g�������������B
1950 tmp = realloc(ctx->old_keys, (ctx->nold + 1)*sizeof(*ctx->old_keys));
1951 if (tmp != NULL) {
1952 ctx->old_keys = tmp;
1953 ctx->old_keys[ctx->nold++] = key;
1954 }
1955
1956 ret = 1;
1957
1958 error:
1959 return (ret);
1960 }
1961
1962 static BOOL CALLBACK hosts_updatekey_dlg_proc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam)
1963 {
1964 static HFONT DlgHostsAddFont;
1965 PTInstVar pvar;
1966 LOGFONT logfont;
1967 HFONT font;
1968 char buf[1024];
1969 char *host;
1970 struct hostkeys_update_ctx *ctx;
1971 char *fp;
1972 size_t i;
1973 char uimsg[MAX_UIMSG];
1974
1975 switch (msg) {
1976 case WM_INITDIALOG:
1977 pvar = (PTInstVar)lParam;
1978 SetWindowLong(dlg, DWL_USER, lParam);
1979
1980 GetWindowText(dlg, uimsg, sizeof(uimsg));
1981 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_TITLE", pvar, uimsg);
1982 SetWindowText(dlg, pvar->ts->UIMsg);
1983
1984 host = pvar->ssh_state.hostname;
1985 ctx = pvar->hostkey_ctx;
1986
1987 GetDlgItemText(dlg, IDC_HOSTKEY_MESSAGE, uimsg, sizeof(uimsg));
1988 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_WARNING", pvar, uimsg);
1989 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1990 pvar->ts->UIMsg, host, ctx->nnew, ctx->nold
1991 );
1992 SetDlgItemText(dlg, IDC_HOSTKEY_MESSAGE, buf);
1993
1994 GetDlgItemText(dlg, IDC_ADDKEY_TEXT, uimsg, sizeof(uimsg));
1995 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_ADD", pvar, uimsg);
1996 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, ctx->nnew);
1997 SetDlgItemText(dlg, IDC_ADDKEY_TEXT, buf);
1998 for (i = 0; i < ctx->nkeys; i++) {
1999 if (ctx->keys_seen[i])
2000 continue;
2001 fp = key_fingerprint(ctx->keys[i], SSH_FP_HEX, SSH_FP_MD5);
2002 buf[0] = 0;
2003 strcat_s(buf, sizeof(buf), get_sshname_from_key(ctx->keys[i]));
2004 strcat_s(buf, sizeof(buf), " ");
2005 strcat_s(buf, sizeof(buf), fp);
2006 SendDlgItemMessage(dlg, IDC_ADDKEY_EDIT, EM_REPLACESEL, 0, (LPARAM)buf);
2007 SendDlgItemMessage(dlg, IDC_ADDKEY_EDIT, EM_REPLACESEL, 0, (LPARAM)"\r\n");
2008 free(fp);
2009 }
2010
2011 GetDlgItemText(dlg, IDC_REMOVEKEY_TEXT, uimsg, sizeof(uimsg));
2012 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_REMOVE", pvar, uimsg);
2013 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, ctx->nold);
2014 SetDlgItemText(dlg, IDC_REMOVEKEY_TEXT, buf);
2015 for (i = 0; i < ctx->nold; i++) {
2016 fp = key_fingerprint(ctx->old_keys[i], SSH_FP_HEX, SSH_FP_MD5);
2017 buf[0] = 0;
2018 strcat_s(buf, sizeof(buf), get_sshname_from_key(ctx->old_keys[i]));
2019 strcat_s(buf, sizeof(buf), " ");
2020 strcat_s(buf, sizeof(buf), fp);
2021 SendDlgItemMessage(dlg, IDC_REMOVEKEY_EDIT, EM_REPLACESEL, 0, (LPARAM)buf);
2022 SendDlgItemMessage(dlg, IDC_REMOVEKEY_EDIT, EM_REPLACESEL, 0, (LPARAM)"\r\n");
2023 free(fp);
2024 }
2025
2026 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2027 UTIL_get_lang_msg("BTN_YES", pvar, uimsg);
2028 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2029 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2030 UTIL_get_lang_msg("BTN_NO", pvar, uimsg);
2031 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2032
2033 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2034 GetObject(font, sizeof(LOGFONT), &logfont);
2035 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
2036 SendDlgItemMessage(dlg, IDC_HOSTKEY_MESSAGE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2037 SendDlgItemMessage(dlg, IDC_ADDKEY_TEXT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2038 SendDlgItemMessage(dlg, IDC_ADDKEY_EDIT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2039 SendDlgItemMessage(dlg, IDC_REMOVEKEY_TEXT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2040 SendDlgItemMessage(dlg, IDC_REMOVEKEY_EDIT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2041 SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2042 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2043 }
2044 else {
2045 DlgHostsAddFont = NULL;
2046 }
2047
2048 return TRUE; /* because we do not set the focus */
2049
2050 case WM_COMMAND:
2051 pvar = (PTInstVar)GetWindowLong(dlg, DWL_USER);
2052
2053 switch (LOWORD(wParam)) {
2054 case IDOK:
2055
2056 EndDialog(dlg, 1);
2057
2058 if (DlgHostsAddFont != NULL) {
2059 DeleteObject(DlgHostsAddFont);
2060 }
2061
2062 return TRUE;
2063
2064 case IDCANCEL: /* kill the connection */
2065 EndDialog(dlg, 0);
2066
2067 if (DlgHostsAddFont != NULL) {
2068 DeleteObject(DlgHostsAddFont);
2069 }
2070
2071 return TRUE;
2072
2073 default:
2074 return FALSE;
2075 }
2076
2077 default:
2078 return FALSE;
2079 }
2080 }
2081
2082 static void update_known_hosts(PTInstVar pvar, struct hostkeys_update_ctx *ctx)
2083 {
2084 size_t i;
2085 int dlgresult;
2086 char msg[1024];
2087 char *host;
2088
2089 host = pvar->ssh_state.hostname;
2090
2091 // "/nosecuritywarning"���w�����������������A�X�V�������s�������B
2092 if (pvar->nocheck_known_hosts) {
2093 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because `/nosecuritywarning' option was specified.");
2094 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2095 goto error;
2096 }
2097
2098 // known_hosts�t�@�C�����X�V���s�������A���[�U���������������s���B
2099 if (pvar->settings.UpdateHostkeys == SSH_UPDATE_HOSTKEYS_ASK) {
2100 HWND cur_active = GetActiveWindow();
2101
2102 pvar->hostkey_ctx = ctx;
2103 dlgresult = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUPDATE_HOSTKEY),
2104 cur_active != NULL ? cur_active : pvar->NotificationWindow,
2105 hosts_updatekey_dlg_proc, (LPARAM)pvar);
2106 if (dlgresult != 1) {
2107 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because a user cancelled.");
2108 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2109 goto error;
2110 }
2111 }
2112
2113 // �����L�[�����������������B
2114 HOSTS_delete_all_hostkeys(pvar);
2115
2116 // �V�����L�[���������o�^�����B
2117 for (i = 0; i < ctx->nkeys; i++) {
2118 HOSTS_add_host_key(pvar, ctx->keys[i]);
2119 }
2120 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was successfully updated to known_hosts file.");
2121 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2122
2123 error:
2124 return;
2125 }
2126
2127 static void client_global_hostkeys_private_confirm(PTInstVar pvar, int type, u_int32_t seq, void *_ctx)
2128 {
2129 struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
2130 char msg[128];
2131 char *data;
2132 int len;
2133 unsigned char *blob = NULL;
2134 int bloblen;
2135 buffer_t *b = NULL;
2136 buffer_t *bsig = NULL;
2137 char *cp, *sig;
2138 size_t i, ndone, siglen;
2139 int ret;
2140
2141 // SSH2 packet format:
2142 // [size(4) + padding size(1) + type(1)] + [payload(N) + padding(X)]
2143 // header body
2144 // ^data
2145 // <-----------------size------------------------------->
2146 // <---------len-------->
2147 //
2148 // data = payload(N) + padding(X): �p�f�B���O���������{�f�B���������w���B
2149 data = pvar->ssh_state.payload;
2150 // len = size - (padding size + 1): �p�f�B���O�������{�f�B�Btype�����������������B
2151 len = pvar->ssh_state.payloadlen;
2152 len--; // type ��������
2153
2154 bsig = buffer_init();
2155 if (bsig == NULL)
2156 goto error;
2157 cp = buffer_append_space(bsig, len);
2158 memcpy(cp, data, len);
2159
2160 if (ctx->nnew == 0) {
2161 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey can not be updated because ctx->nnew %d(program bug).", ctx->nnew);
2162 notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2163 goto error;
2164 }
2165 if (type != SSH2_MSG_REQUEST_SUCCESS) {
2166 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Server failed to confirm ownership of private host keys(type %d)", type);
2167 notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2168 goto error;
2169 }
2170 if (pvar->session_id_len == 0) {
2171 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey can not be updated because pvar->session_id_len %d(program bug).", pvar->session_id_len);
2172 notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2173 goto error;
2174 }
2175
2176 b = buffer_init();
2177 if (b == NULL)
2178 goto error;
2179
2180 ndone = 0;
2181 for (i = 0; i < ctx->nkeys; i++) {
2182 if (ctx->keys_seen[i])
2183 continue;
2184
2185 buffer_clear(b);
2186 buffer_put_cstring(b, "hostkeys-prove-00@openssh.com");
2187 buffer_put_string(b, pvar->session_id, pvar->session_id_len);
2188 key_to_blob(ctx->keys[i], &blob, &bloblen);
2189 buffer_put_string(b, blob, bloblen);
2190 free(blob);
2191 blob = NULL;
2192
2193 sig = buffer_get_string_msg(bsig, &siglen);
2194 // Verify signature
2195 ret = key_verify(ctx->keys[i], sig, siglen, buffer_ptr(b), buffer_len(b));
2196 free(sig);
2197 sig = NULL;
2198 if (ret != 1) {
2199 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "server gave bad signature for %s key %u",
2200 get_sshname_from_key(ctx->keys[i]), i);
2201 notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2202 goto error;
2203 }
2204 ndone++;
2205 }
2206
2207 if (ndone != ctx->nnew) {
2208 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey can not be updated because ndone != ctx->nnew (%u / %u)(program bug).",
2209 ndone, ctx->nnew);
2210 notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2211 goto error;
2212 }
2213
2214 update_known_hosts(pvar, ctx);
2215
2216 error:
2217 buffer_free(b);
2218 buffer_free(bsig);
2219 hostkeys_update_ctx_free(ctx);
2220 }
2221
2222 //
2223 // SSH�T�[�o�z�X�g��(known_hosts)�������X�V(OpenSSH 6.8 or later: host key rotation support)
2224 //
2225 // return 1: success
2226 // 0: fail
2227 //
2228 int update_client_input_hostkeys(PTInstVar pvar, char *dataptr, int datalen)
2229 {
2230 int success = 1; // OpenSSH 6.8�����������A�����������������������������������A
2231 // �������������� Tera Term �������������������������B
2232 int len;
2233 size_t i;
2234 char *cp, *fp;
2235 char msg[128];
2236 unsigned char *blob = NULL;
2237 buffer_t *b = NULL;
2238 struct hostkeys_update_ctx *ctx = NULL;
2239 Key *key = NULL, **tmp;
2240 unsigned char *outmsg;
2241
2242 // Tera Term���������A���Y�@�\���I���I�t�����������������������B
2243 if (pvar->settings.UpdateHostkeys == SSH_UPDATE_HOSTKEYS_NO) {
2244 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because ts.UpdateHostkeys is disabled.");
2245 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2246 return 1;
2247 }
2248
2249 ctx = calloc(1, sizeof(struct hostkeys_update_ctx));
2250 if (ctx == NULL)
2251 goto error;
2252
2253 b = buffer_init();
2254 if (b == NULL)
2255 goto error;
2256
2257 cp = buffer_append_space(b, datalen);
2258 memcpy(cp, dataptr, datalen);
2259
2260 while (buffer_remain_len(b) > 0) {
2261 key_free(key);
2262 key = NULL;
2263
2264 blob = buffer_get_string_msg(b, &len);
2265 key = key_from_blob(blob, len);
2266 if (key == NULL) {
2267 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not found host key into blob %p (%d)", blob, len);
2268 notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2269 goto error;
2270 }
2271 free(blob);
2272 blob = NULL;
2273
2274 fp = key_fingerprint(key, SSH_FP_HEX, SSH_FP_MD5);
2275 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Received %s host key %s",
2276 get_sshname_from_key(key), fp);
2277 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2278 free(fp);
2279
2280 // �����������z�X�g�L�[�A���S���Y�������`�F�b�N�����B
2281 if (check_hostkey_algorithm(pvar, key) == 0) {
2282 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "%s host key is not permitted by ts.HostKeyOrder",
2283 get_sshname_from_key(key));
2284 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2285 continue;
2286 }
2287
2288 // Skip certs: Tera Term�����������F�������T�|�[�g�B
2289
2290 // �d�������L�[�����M�������G���[�������B
2291 for (i = 0; i < ctx->nkeys; i++) {
2292 if (HOSTS_compare_public_key(key, ctx->keys[i]) == 1) {
2293 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Received duplicated %s host key",
2294 get_sshname_from_key(key));
2295 notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2296 goto error;
2297 }
2298 }
2299
2300 // �L�[���o�^�����B
2301 tmp = realloc(ctx->keys, (ctx->nkeys + 1)*sizeof(*ctx->keys));
2302 if (tmp == NULL) {
2303 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not memory: realloc ctx->keys %d",
2304 ctx->nkeys);
2305 notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2306 goto error;
2307 }
2308 ctx->keys = tmp;
2309 ctx->keys[ctx->nkeys++] = key;
2310 key = NULL;
2311 }
2312
2313 if (ctx->nkeys == 0) {
2314 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "No host rotation key");
2315 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2316 goto error;
2317 }
2318
2319 if ((ctx->keys_seen = calloc(ctx->nkeys, sizeof(*ctx->keys_seen))) == NULL) {
2320 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not memory: calloc ctx->keys %d",
2321 ctx->nkeys);
2322 notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2323 goto error;
2324 }
2325
2326 HOSTS_hostkey_foreach(pvar, hostkeys_find, ctx);
2327
2328 // �T�[�o�������������������Q�����A�������������V�K���������������������B
2329 ctx->nnew = 0;
2330 for (i = 0; i < ctx->nkeys; i++) {
2331 if (!ctx->keys_seen[i])
2332 ctx->nnew++;
2333 }
2334 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "%u keys from server: %u new, %u retained. %u to remove",
2335 ctx->nkeys, ctx->nnew, ctx->nkeys - ctx->nnew, ctx->nold);
2336 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2337
2338 // �V�K�������������[�������Adeprecated���������������B
2339 if (ctx->nnew == 0 && ctx->nold != 0) {
2340 update_known_hosts(pvar, ctx);
2341
2342 }
2343 else if (ctx->nnew != 0) { // �V�K�������������������������B
2344 buffer_clear(b);
2345
2346 buffer_put_cstring(b, "hostkeys-prove-00@openssh.com");
2347 buffer_put_char(b, 1); /* bool: want reply */
2348
2349 for (i = 0; i < ctx->nkeys; i++) {
2350 if (ctx->keys_seen[i])
2351 continue;
2352 key_to_blob(ctx->keys[i], &blob, &len);
2353 buffer_put_string(b, blob, len);
2354 free(blob);
2355 blob = NULL;
2356 }
2357
2358 len = buffer_len(b);
2359 outmsg = begin_send_packet(pvar, SSH2_MSG_GLOBAL_REQUEST, len);
2360 memcpy(outmsg, buffer_ptr(b), len);
2361 finish_send_packet(pvar);
2362
2363 // SSH2_MSG_GLOBAL_REQUEST�����X�|���X�����������n���h�����o�^�����B
2364 client_register_global_confirm(client_global_hostkeys_private_confirm, ctx);
2365 ctx = NULL; // callback���������������A��������NULL���������������B
2366 }
2367
2368 success = 1;
2369
2370 error:
2371 buffer_free(b);
2372 hostkeys_update_ctx_free(ctx);
2373 free(blob);
2374
2375 return (success);
2376 }

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