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 9208 - (show annotations) (download) (as text)
Sat Apr 17 06:15:51 2021 UTC (2 years, 11 months ago) by nmaya
File MIME type: text/x-csrc
File size: 62606 byte(s)
create a branch for chacha20-poly1305

from 4-stable
planned to merge to 4-stable and trunk

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

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