Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/ttssh2/ttxssh/key.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10618 - (show annotations) (download) (as text)
Fri Mar 3 15:15:16 2023 UTC (13 months, 1 week ago) by zmatsuo
File MIME type: text/x-csrc
File size: 63875 byte(s)
ttxsshで tttset.UIMsg[] ではなく TInstVar.UIMsg[] を使用するよう修正

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

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