Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.c

Parent Directory Parent Directory | Revision Log Revision Log


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