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 6147 - (hide annotations) (download) (as text)
Tue Nov 17 09:31:03 2015 UTC (8 years, 4 months ago) by maya
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 60279 byte(s)
key_init() 関数を追加
  key_free() はポインタでないと使えないため
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     memset(digest, 'd', sizeof(digest));
138    
139     DSA_SIG_free(sig);
140    
141     return ret;
142     }
143    
144    
145     //
146     // RSA
147     //
148    
149     /*
150     * See:
151     * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
152     * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
153     */
154     /*
155     * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
156     * oiw(14) secsig(3) algorithms(2) 26 }
157     */
158     static const u_char id_sha1[] = {
159     0x30, 0x21, /* type Sequence, length 0x21 (33) */
160     0x30, 0x09, /* type Sequence, length 0x09 */
161     0x06, 0x05, /* type OID, length 0x05 */
162     0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
163     0x05, 0x00, /* NULL */
164     0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
165     };
166     /*
167     * id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
168     * rsadsi(113549) digestAlgorithm(2) 5 }
169     */
170     static const u_char id_md5[] = {
171     0x30, 0x20, /* type Sequence, length 0x20 (32) */
172     0x30, 0x0c, /* type Sequence, length 0x09 */
173     0x06, 0x08, /* type OID, length 0x05 */
174     0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */
175     0x05, 0x00, /* NULL */
176     0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */
177     };
178    
179     static int openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
180     u_char *sigbuf, u_int siglen, RSA *rsa)
181     {
182     u_int ret, rsasize, oidlen = 0, hlen = 0;
183     int len;
184     const u_char *oid = NULL;
185     u_char *decrypted = NULL;
186    
187     ret = 0;
188     switch (type) {
189     case NID_sha1:
190     oid = id_sha1;
191     oidlen = sizeof(id_sha1);
192     hlen = 20;
193     break;
194     case NID_md5:
195     oid = id_md5;
196     oidlen = sizeof(id_md5);
197     hlen = 16;
198     break;
199     default:
200     goto done;
201     break;
202     }
203     if (hashlen != hlen) {
204     //error("bad hashlen");
205     goto done;
206     }
207     rsasize = RSA_size(rsa);
208     if (siglen == 0 || siglen > rsasize) {
209     //error("bad siglen");
210     goto done;
211     }
212     decrypted = malloc(rsasize);
213     if (decrypted == NULL)
214     return 1; // error
215    
216     if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
217     RSA_PKCS1_PADDING)) < 0) {
218     //error("RSA_public_decrypt failed: %s",
219     // ERR_error_string(ERR_get_error(), NULL));
220     goto done;
221     }
222     if (len != hlen + oidlen) {
223     //error("bad decrypted len: %d != %d + %d", len, hlen, oidlen);
224     goto done;
225     }
226     if (memcmp(decrypted, oid, oidlen) != 0) {
227     //error("oid mismatch");
228     goto done;
229     }
230     if (memcmp(decrypted + oidlen, hash, hlen) != 0) {
231     //error("hash mismatch");
232     goto done;
233     }
234     ret = 1;
235     done:
236     if (decrypted)
237     free(decrypted);
238     return ret;
239     }
240    
241     int ssh_rsa_verify(RSA *key,
242     u_char *signature, u_int signaturelen,
243     u_char *data, u_int datalen)
244     {
245     const EVP_MD *evp_md;
246     EVP_MD_CTX md;
247     // char *ktype;
248     u_char digest[EVP_MAX_MD_SIZE], *sigblob;
249     u_int len, dlen, modlen;
250     // int rlen, ret, nid;
251     int ret, nid;
252     char *ptr;
253    
254     OpenSSL_add_all_digests();
255    
256     if (key == NULL) {
257     return -2;
258     }
259     if (BN_num_bits(key->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
260     return -3;
261     }
262     //debug_print(41, signature, signaturelen);
263     ptr = signature;
264    
265     // step1
266     len = get_uint32_MSBfirst(ptr);
267     ptr += 4;
268     if (strncmp("ssh-rsa", ptr, len) != 0) {
269     return -4;
270     }
271     ptr += len;
272    
273     // step2
274     len = get_uint32_MSBfirst(ptr);
275     ptr += 4;
276     sigblob = ptr;
277     ptr += len;
278     #if 0
279     rlen = get_uint32_MSBfirst(ptr);
280     if (rlen != 0) {
281     return -1;
282     }
283     #endif
284    
285     /* RSA_verify expects a signature of RSA_size */
286     modlen = RSA_size(key);
287     if (len > modlen) {
288     return -5;
289    
290     } else if (len < modlen) {
291     u_int diff = modlen - len;
292     sigblob = realloc(sigblob, modlen);
293     memmove(sigblob + diff, sigblob, len);
294     memset(sigblob, 0, diff);
295     len = modlen;
296     }
297    
298     /* sha1 the data */
299     // nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
300     nid = NID_sha1;
301     if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
302     //error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid);
303     return -6;
304     }
305     EVP_DigestInit(&md, evp_md);
306     EVP_DigestUpdate(&md, data, datalen);
307     EVP_DigestFinal(&md, digest, &dlen);
308    
309     ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key);
310    
311     memset(digest, 'd', sizeof(digest));
312     memset(sigblob, 's', len);
313     //free(sigblob);
314     //debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
315    
316     return ret;
317     }
318    
319 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     memset(digest, 'd', sizeof(digest));
376    
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     memset(sigblob, 's', len);
438     free(sigblob);
439     }
440     if (sm) {
441     memset(sm, 'S', (size_t)smlen);
442     free(sm);
443     }
444     if (m) {
445     memset(m, 'm', (size_t)smlen); /* NB. mlen may be invalid if ret != 0 */
446     free(m);
447     }
448    
449     /* translate return code carefully */
450     return (ret == 0) ? 1 : -1;
451     }
452    
453 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 maya 6145 static char FAR *copy_mp_int(char FAR * num)
482     {
483     int len = (get_ushort16_MSBfirst(num) + 7) / 8 + 2;
484     char FAR *result = (char FAR *) malloc(len);
485    
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     memset(blob, 0, len);
664     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     field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
826     field[x][y] = len;
827    
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     memset(dgst_raw, 0, dgst_raw_len);
909     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     // �L�[����������������
1074     //
1075     void key_free(Key *key)
1076     {
1077 maya 4321 if (key == NULL) {
1078     return;
1079     }
1080    
1081 maya 6147 key_init(key);
1082 maya 4304
1083 maya 6147 free(key);
1084     }
1085 maya 4321
1086 maya 6147 void key_init(Key *key)
1087     {
1088     key->type = KEY_UNSPEC;
1089 yutakapon 5545
1090 maya 6147 // SSH1
1091     key->bits = 0;
1092     if (key->exp != NULL) {
1093     free(key->exp);
1094     key->exp = NULL;
1095 maya 4304 }
1096 maya 6147 if (key->mod != NULL) {
1097     free(key->mod);
1098     key->mod = NULL;
1099     }
1100    
1101     // SSH2
1102     if (key->dsa != NULL) {
1103     DSA_free(key->dsa);
1104     key->dsa = NULL;
1105     }
1106     if (key->rsa != NULL) {
1107     RSA_free(key->rsa);
1108     key->rsa = NULL;
1109     }
1110     if (key->ecdsa != NULL) {
1111     EC_KEY_free(key->ecdsa);
1112     key->ecdsa = NULL;
1113     }
1114     if (key->ed25519_pk != NULL) {
1115     memset(key->ed25519_pk, 0, ED25519_PK_SZ);
1116     free(key->ed25519_pk);
1117     key->ed25519_pk = NULL;
1118     }
1119     if (key->ed25519_sk) {
1120     memset(key->ed25519_sk, 0, ED25519_SK_SZ);
1121     free(key->ed25519_sk);
1122     key->ed25519_sk = NULL;
1123     }
1124 maya 4304 }
1125    
1126     //
1127     // �L�[���������������p����
1128     //
1129 maya 4321 char *get_sshname_from_key(Key *key)
1130     {
1131 maya 4378 return get_ssh_keytype_name(key->type);
1132 maya 4321 }
1133 maya 4304
1134     //
1135     // �L�[������������������������
1136     //
1137 maya 4378 ssh_keytype get_keytype_from_name(char *name)
1138 maya 4304 {
1139     if (strcmp(name, "rsa1") == 0) {
1140     return KEY_RSA1;
1141     } else if (strcmp(name, "rsa") == 0) {
1142     return KEY_RSA;
1143     } else if (strcmp(name, "dsa") == 0) {
1144     return KEY_DSA;
1145     } else if (strcmp(name, "ssh-rsa") == 0) {
1146     return KEY_RSA;
1147     } else if (strcmp(name, "ssh-dss") == 0) {
1148     return KEY_DSA;
1149 maya 4321 } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
1150     return KEY_ECDSA256;
1151     } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
1152     return KEY_ECDSA384;
1153     } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
1154     return KEY_ECDSA521;
1155 yutakapon 5545 } else if (strcmp(name, "ssh-ed25519") == 0) {
1156     return KEY_ED25519;
1157 maya 4304 }
1158     return KEY_UNSPEC;
1159     }
1160    
1161    
1162 maya 4378 ssh_keytype key_curve_name_to_keytype(char *name)
1163 maya 4321 {
1164     if (strcmp(name, "nistp256") == 0) {
1165     return KEY_ECDSA256;
1166     } else if (strcmp(name, "nistp384") == 0) {
1167     return KEY_ECDSA384;
1168     } else if (strcmp(name, "nistp521") == 0) {
1169     return KEY_ECDSA521;
1170     }
1171     return KEY_UNSPEC;
1172     }
1173    
1174 maya 4378 char *curve_keytype_to_name(ssh_keytype type)
1175 maya 4321 {
1176     switch (type) {
1177     case KEY_ECDSA256:
1178     return "nistp256";
1179     break;
1180     case KEY_ECDSA384:
1181     return "nistp384";
1182     break;
1183     case KEY_ECDSA521:
1184     return "nistp521";
1185     break;
1186     }
1187     return NULL;
1188     }
1189    
1190 maya 4304 //
1191     // �L�[���������o�b�t�@���������� (for SSH2)
1192     // NOTE:
1193     //
1194     int key_to_blob(Key *key, char **blobp, int *lenp)
1195     {
1196     buffer_t *b;
1197 maya 4321 char *sshname, *tmp;
1198 maya 4304 int len;
1199     int ret = 1; // success
1200    
1201     b = buffer_init();
1202     sshname = get_sshname_from_key(key);
1203    
1204 maya 4321 switch (key->type) {
1205     case KEY_RSA:
1206 maya 4304 buffer_put_string(b, sshname, strlen(sshname));
1207     buffer_put_bignum2(b, key->rsa->e);
1208     buffer_put_bignum2(b, key->rsa->n);
1209 maya 4321 break;
1210     case KEY_DSA:
1211 maya 4304 buffer_put_string(b, sshname, strlen(sshname));
1212     buffer_put_bignum2(b, key->dsa->p);
1213     buffer_put_bignum2(b, key->dsa->q);
1214     buffer_put_bignum2(b, key->dsa->g);
1215     buffer_put_bignum2(b, key->dsa->pub_key);
1216 maya 4321 break;
1217     case KEY_ECDSA256:
1218     case KEY_ECDSA384:
1219     case KEY_ECDSA521:
1220     buffer_put_string(b, sshname, strlen(sshname));
1221     tmp = curve_keytype_to_name(key->type);
1222     buffer_put_string(b, tmp, strlen(tmp));
1223     buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
1224     EC_KEY_get0_public_key(key->ecdsa));
1225     break;
1226 yutakapon 5545 case KEY_ED25519:
1227     buffer_put_cstring(b, sshname);
1228     buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
1229     break;
1230 maya 4304
1231 maya 4321 default:
1232 maya 4304 ret = 0;
1233     goto error;
1234     }
1235    
1236     len = buffer_len(b);
1237     if (lenp != NULL)
1238     *lenp = len;
1239     if (blobp != NULL) {
1240     *blobp = malloc(len);
1241     if (*blobp == NULL) {
1242     ret = 0;
1243     goto error;
1244     }
1245     memcpy(*blobp, buffer_ptr(b), len);
1246     }
1247    
1248     error:
1249     buffer_free(b);
1250    
1251     return (ret);
1252     }
1253    
1254    
1255     //
1256     // �o�b�t�@�����L�[�����������o��(for SSH2)
1257     // NOTE: ���l���A���P�[�g���������������A�����o�������������������B
1258     //
1259     Key *key_from_blob(char *data, int blen)
1260     {
1261 yutakapon 5545 int keynamelen, len;
1262 maya 4304 char key[128];
1263     RSA *rsa = NULL;
1264     DSA *dsa = NULL;
1265 maya 4321 EC_KEY *ecdsa = NULL;
1266     EC_POINT *q = NULL;
1267     char *curve = NULL;
1268 yutakapon 5838 Key *hostkey = NULL; // hostkey
1269 maya 4378 ssh_keytype type;
1270 yutakapon 5545 unsigned char *pk = NULL;
1271 maya 4304
1272 yutakapon 5838 if (data == NULL)
1273     goto error;
1274    
1275 maya 4304 hostkey = malloc(sizeof(Key));
1276     if (hostkey == NULL)
1277     goto error;
1278    
1279     memset(hostkey, 0, sizeof(Key));
1280    
1281     keynamelen = get_uint32_MSBfirst(data);
1282     if (keynamelen >= sizeof(key)) {
1283     goto error;
1284     }
1285     data += 4;
1286     memcpy(key, data, keynamelen);
1287     key[keynamelen] = 0;
1288     data += keynamelen;
1289    
1290     type = get_keytype_from_name(key);
1291    
1292 maya 4321 switch (type) {
1293     case KEY_RSA: // RSA key
1294 maya 4304 rsa = RSA_new();
1295     if (rsa == NULL) {
1296     goto error;
1297     }
1298     rsa->n = BN_new();
1299     rsa->e = BN_new();
1300     if (rsa->n == NULL || rsa->e == NULL) {
1301     goto error;
1302     }
1303    
1304     buffer_get_bignum2(&data, rsa->e);
1305     buffer_get_bignum2(&data, rsa->n);
1306    
1307     hostkey->type = type;
1308     hostkey->rsa = rsa;
1309 maya 4321 break;
1310 maya 4304
1311 maya 4321 case KEY_DSA: // DSA key
1312 maya 4304 dsa = DSA_new();
1313     if (dsa == NULL) {
1314     goto error;
1315     }
1316     dsa->p = BN_new();
1317     dsa->q = BN_new();
1318     dsa->g = BN_new();
1319     dsa->pub_key = BN_new();
1320     if (dsa->p == NULL ||
1321     dsa->q == NULL ||
1322     dsa->g == NULL ||
1323     dsa->pub_key == NULL) {
1324     goto error;
1325     }
1326    
1327     buffer_get_bignum2(&data, dsa->p);
1328     buffer_get_bignum2(&data, dsa->q);
1329     buffer_get_bignum2(&data, dsa->g);
1330     buffer_get_bignum2(&data, dsa->pub_key);
1331    
1332     hostkey->type = type;
1333     hostkey->dsa = dsa;
1334 maya 4321 break;
1335 maya 4304
1336 maya 4321 case KEY_ECDSA256: // ECDSA
1337     case KEY_ECDSA384:
1338     case KEY_ECDSA521:
1339     curve = buffer_get_string(&data, NULL);
1340     if (type != key_curve_name_to_keytype(curve)) {
1341     goto error;
1342     }
1343    
1344 maya 4327 ecdsa = EC_KEY_new_by_curve_name(keytype_to_cipher_nid(type));
1345 maya 4321 if (ecdsa == NULL) {
1346     goto error;
1347     }
1348    
1349     q = EC_POINT_new(EC_KEY_get0_group(ecdsa));
1350     if (q == NULL) {
1351     goto error;
1352     }
1353    
1354     buffer_get_ecpoint(&data, EC_KEY_get0_group(ecdsa), q);
1355     if (key_ec_validate_public(EC_KEY_get0_group(ecdsa), q) == -1) {
1356     goto error;
1357     }
1358    
1359     if (EC_KEY_set_public_key(ecdsa, q) != 1) {
1360     goto error;
1361     }
1362    
1363     hostkey->type = type;
1364     hostkey->ecdsa = ecdsa;
1365     break;
1366    
1367 yutakapon 5545 case KEY_ED25519:
1368     pk = buffer_get_string(&data, &len);
1369     if (pk == NULL)
1370     goto error;
1371     if (len != ED25519_PK_SZ)
1372     goto error;
1373    
1374     hostkey->type = type;
1375     hostkey->ed25519_pk = pk;
1376     pk = NULL;
1377     break;
1378    
1379 maya 4321 default: // unknown key
1380 maya 4304 goto error;
1381     }
1382    
1383     return (hostkey);
1384    
1385     error:
1386     if (rsa != NULL)
1387     RSA_free(rsa);
1388     if (dsa != NULL)
1389     DSA_free(dsa);
1390 maya 4321 if (ecdsa != NULL)
1391     EC_KEY_free(ecdsa);
1392 maya 4304
1393 yutakapon 5545 free(hostkey);
1394    
1395 maya 4304 return NULL;
1396     }
1397    
1398    
1399 yutakapon 5545 static int ssh_ed25519_sign(Key *key, char **sigp, int *lenp, char *data, int datalen)
1400     {
1401     char *sig;
1402     int slen, len;
1403     unsigned long long smlen;
1404     int ret;
1405     buffer_t *b;
1406    
1407     smlen = slen = datalen + crypto_sign_ed25519_BYTES;
1408     sig = malloc(slen);
1409    
1410     if ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen,
1411     key->ed25519_sk)) != 0 || smlen <= datalen) {
1412     //error("%s: crypto_sign_ed25519 failed: %d", __func__, ret);
1413     free(sig);
1414     return -1;
1415     }
1416     /* encode signature */
1417     b = buffer_init();
1418     buffer_put_cstring(b, "ssh-ed25519");
1419     buffer_put_string(b, sig, (int)(smlen - datalen));
1420     len = buffer_len(b);
1421     if (lenp != NULL)
1422     *lenp = len;
1423     if (sigp != NULL) {
1424     *sigp = malloc(len);
1425     memcpy(*sigp, buffer_ptr(b), len);
1426     }
1427     buffer_free(b);
1428     memset(sig, 's', slen);
1429     free(sig);
1430    
1431     return 0;
1432     }
1433    
1434    
1435 maya 4307 BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen)
1436 maya 4304 {
1437     buffer_t *msg = NULL;
1438     char *s;
1439 yutakapon 5545 int ret;
1440 maya 4304
1441     msg = buffer_init();
1442     if (msg == NULL) {
1443     // TODO: error check
1444     return FALSE;
1445     }
1446    
1447 maya 4324 switch (keypair->type) {
1448     case KEY_RSA: // RSA
1449     {
1450 maya 4307 const EVP_MD *evp_md = EVP_sha1();
1451 maya 4304 EVP_MD_CTX md;
1452     u_char digest[EVP_MAX_MD_SIZE], *sig;
1453     u_int slen, dlen, len;
1454 maya 4307 int ok, nid = NID_sha1;
1455 maya 4304
1456     // �_�C�W�F�X�g�l���v�Z
1457     EVP_DigestInit(&md, evp_md);
1458     EVP_DigestUpdate(&md, data, datalen);
1459     EVP_DigestFinal(&md, digest, &dlen);
1460    
1461 maya 4307 slen = RSA_size(keypair->rsa);
1462 maya 4304 sig = malloc(slen);
1463     if (sig == NULL)
1464     goto error;
1465    
1466     // �d�q�������v�Z
1467 maya 4307 ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa);
1468 maya 4304 memset(digest, 'd', sizeof(digest));
1469     if (ok != 1) { // error
1470     free(sig);
1471     goto error;
1472     }
1473     // �������T�C�Y���o�b�t�@���������������A�������������B�������[�����������B
1474     if (len < slen) {
1475     u_int diff = slen - len;
1476     memmove(sig + diff, sig, len);
1477     memset(sig, 0, diff);
1478    
1479     } else if (len > slen) {
1480     free(sig);
1481     goto error;
1482    
1483     } else {
1484     // do nothing
1485    
1486     }
1487    
1488 maya 4307 s = get_sshname_from_key(keypair);
1489 maya 4304 buffer_put_string(msg, s, strlen(s));
1490     buffer_append_length(msg, sig, slen);
1491     len = buffer_len(msg);
1492    
1493     // setting
1494     *siglen = len;
1495     *sigptr = malloc(len);
1496     if (*sigptr == NULL) {
1497     free(sig);
1498     goto error;
1499     }
1500     memcpy(*sigptr, buffer_ptr(msg), len);
1501     free(sig);
1502 maya 4324
1503     break;
1504 maya 4307 }
1505 maya 4324 case KEY_DSA: // DSA
1506     {
1507 maya 4304 DSA_SIG *sig;
1508     const EVP_MD *evp_md = EVP_sha1();
1509     EVP_MD_CTX md;
1510     u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
1511     u_int rlen, slen, len, dlen;
1512    
1513     // �_�C�W�F�X�g���v�Z
1514     EVP_DigestInit(&md, evp_md);
1515     EVP_DigestUpdate(&md, data, datalen);
1516     EVP_DigestFinal(&md, digest, &dlen);
1517    
1518     // DSA�d�q�������v�Z
1519 maya 4307 sig = DSA_do_sign(digest, dlen, keypair->dsa);
1520 maya 4304 memset(digest, 'd', sizeof(digest));
1521     if (sig == NULL) {
1522     goto error;
1523     }
1524    
1525     // BIGNUM�����o�C�i���l��������
1526     rlen = BN_num_bytes(sig->r);
1527     slen = BN_num_bytes(sig->s);
1528     if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
1529     DSA_SIG_free(sig);
1530     goto error;
1531     }
1532     memset(sigblob, 0, SIGBLOB_LEN);
1533     BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
1534     BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
1535     DSA_SIG_free(sig);
1536    
1537     // setting
1538 maya 4307 s = get_sshname_from_key(keypair);
1539 maya 4304 buffer_put_string(msg, s, strlen(s));
1540     buffer_append_length(msg, sigblob, sizeof(sigblob));
1541     len = buffer_len(msg);
1542    
1543     // setting
1544     *siglen = len;
1545     *sigptr = malloc(len);
1546     if (*sigptr == NULL) {
1547     goto error;
1548     }
1549     memcpy(*sigptr, buffer_ptr(msg), len);
1550    
1551 maya 4324 break;
1552 maya 4304 }
1553 maya 4324 case KEY_ECDSA256: // ECDSA
1554     case KEY_ECDSA384:
1555     case KEY_ECDSA521:
1556     {
1557     ECDSA_SIG *sig;
1558     const EVP_MD *evp_md;
1559     EVP_MD_CTX md;
1560     u_char digest[EVP_MAX_MD_SIZE];
1561     u_int len, dlen, nid;
1562     buffer_t *buf2 = NULL;
1563    
1564 maya 4327 nid = keytype_to_hash_nid(keypair->type);
1565 maya 4324 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
1566     goto error;
1567     }
1568     EVP_DigestInit(&md, evp_md);
1569     EVP_DigestUpdate(&md, data, datalen);
1570     EVP_DigestFinal(&md, digest, &dlen);
1571    
1572     sig = ECDSA_do_sign(digest, dlen, keypair->ecdsa);
1573     memset(digest, 'd', sizeof(digest));
1574    
1575     if (sig == NULL) {
1576     goto error;
1577     }
1578    
1579     buf2 = buffer_init();
1580     if (buf2 == NULL) {
1581     // TODO: error check
1582     goto error;
1583     }
1584     buffer_put_bignum2(buf2, sig->r);
1585     buffer_put_bignum2(buf2, sig->s);
1586     ECDSA_SIG_free(sig);
1587    
1588     s = get_sshname_from_key(keypair);
1589     buffer_put_string(msg, s, strlen(s));
1590     buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2));
1591     buffer_free(buf2);
1592     len = buffer_len(msg);
1593    
1594     *siglen = len;
1595     *sigptr = malloc(len);
1596     if (*sigptr == NULL) {
1597     goto error;
1598     }
1599     memcpy(*sigptr, buffer_ptr(msg), len);
1600    
1601     break;
1602     }
1603 yutakapon 5545
1604     case KEY_ED25519:
1605     ret = ssh_ed25519_sign(keypair, sigptr, siglen, data, datalen);
1606     if (ret != 0)
1607     goto error;
1608     break;
1609    
1610 maya 4324 default:
1611 maya 4307 buffer_free(msg);
1612     return FALSE;
1613 maya 4324 break;
1614 maya 4307 }
1615 maya 4304
1616     buffer_free(msg);
1617     return TRUE;
1618    
1619     error:
1620     buffer_free(msg);
1621    
1622     return FALSE;
1623     }
1624    
1625    
1626     BOOL get_SSH2_publickey_blob(PTInstVar pvar, buffer_t **blobptr, int *bloblen)
1627     {
1628     buffer_t *msg = NULL;
1629 maya 4307 Key *keypair;
1630 maya 4324 char *s, *tmp;
1631 maya 4304
1632     msg = buffer_init();
1633     if (msg == NULL) {
1634     // TODO: error check
1635     return FALSE;
1636     }
1637    
1638     keypair = pvar->auth_state.cur_cred.key_pair;
1639    
1640 maya 4324 switch (keypair->type) {
1641     case KEY_RSA: // RSA
1642 maya 4307 s = get_sshname_from_key(keypair);
1643 maya 4304 buffer_put_string(msg, s, strlen(s));
1644 maya 4307 buffer_put_bignum2(msg, keypair->rsa->e); // ���J�w��
1645     buffer_put_bignum2(msg, keypair->rsa->n); // p�~q
1646 maya 4324 break;
1647     case KEY_DSA: // DSA
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->dsa->p); // �f��
1651     buffer_put_bignum2(msg, keypair->dsa->q); // (p-1)���f����
1652     buffer_put_bignum2(msg, keypair->dsa->g); // ����
1653     buffer_put_bignum2(msg, keypair->dsa->pub_key); // ���J��
1654 maya 4324 break;
1655     case KEY_ECDSA256: // ECDSA
1656     case KEY_ECDSA384:
1657     case KEY_ECDSA521:
1658     s = get_sshname_from_key(keypair);
1659     buffer_put_string(msg, s, strlen(s));
1660     tmp = curve_keytype_to_name(keypair->type);
1661     buffer_put_string(msg, tmp, strlen(tmp));
1662     buffer_put_ecpoint(msg, EC_KEY_get0_group(keypair->ecdsa),
1663     EC_KEY_get0_public_key(keypair->ecdsa));
1664     break;
1665 yutakapon 5545 case KEY_ED25519:
1666     s = get_sshname_from_key(keypair);
1667     buffer_put_cstring(msg, s);
1668     buffer_put_string(msg, keypair->ed25519_pk, ED25519_PK_SZ);
1669     break;
1670 maya 4324 default:
1671 maya 4307 return FALSE;
1672     }
1673    
1674 maya 4304 *blobptr = msg;
1675     *bloblen = buffer_len(msg);
1676    
1677     return TRUE;
1678     }
1679 maya 4327
1680 maya 4378 int kextype_to_cipher_nid(kex_algorithm type)
1681 maya 4327 {
1682     switch (type) {
1683     case KEX_ECDH_SHA2_256:
1684     return NID_X9_62_prime256v1;
1685     case KEX_ECDH_SHA2_384:
1686     return NID_secp384r1;
1687     case KEX_ECDH_SHA2_521:
1688     return NID_secp521r1;
1689     }
1690     return NID_undef;
1691     }
1692    
1693 maya 4378 int keytype_to_hash_nid(ssh_keytype type)
1694 maya 4327 {
1695     switch (type) {
1696     case KEY_ECDSA256:
1697     return NID_sha256;
1698     case KEY_ECDSA384:
1699     return NID_sha384;
1700     case KEY_ECDSA521:
1701     return NID_sha512;
1702     }
1703     return NID_undef;
1704     }
1705    
1706 maya 4378 int keytype_to_cipher_nid(ssh_keytype type)
1707 maya 4327 {
1708     switch (type) {
1709     case KEY_ECDSA256:
1710     return NID_X9_62_prime256v1;
1711     case KEY_ECDSA384:
1712     return NID_secp384r1;
1713     case KEY_ECDSA521:
1714     return NID_secp521r1;
1715     }
1716     return NID_undef;
1717     }
1718    
1719 maya 4378 ssh_keytype nid_to_keytype(int nid)
1720 maya 4327 {
1721     switch (nid) {
1722     case NID_X9_62_prime256v1:
1723     return KEY_ECDSA256;
1724     case NID_secp384r1:
1725     return KEY_ECDSA384;
1726     case NID_secp521r1:
1727     return KEY_ECDSA521;
1728     }
1729     return KEY_UNSPEC;
1730     }
1731 yutakapon 5545
1732     void key_private_serialize(Key *key, buffer_t *b)
1733     {
1734     char *s;
1735    
1736     s = get_sshname_from_key(key);
1737     buffer_put_cstring(b, s);
1738    
1739     switch (key->type) {
1740     case KEY_RSA:
1741     buffer_put_bignum2(b, key->rsa->n);
1742     buffer_put_bignum2(b, key->rsa->e);
1743     buffer_put_bignum2(b, key->rsa->d);
1744     buffer_put_bignum2(b, key->rsa->iqmp);
1745     buffer_put_bignum2(b, key->rsa->p);
1746     buffer_put_bignum2(b, key->rsa->q);
1747     break;
1748    
1749     case KEY_DSA:
1750     buffer_put_bignum2(b, key->dsa->p);
1751     buffer_put_bignum2(b, key->dsa->q);
1752     buffer_put_bignum2(b, key->dsa->g);
1753     buffer_put_bignum2(b, key->dsa->pub_key);
1754     buffer_put_bignum2(b, key->dsa->priv_key);
1755     break;
1756    
1757     case KEY_ECDSA256:
1758     case KEY_ECDSA384:
1759     case KEY_ECDSA521:
1760     buffer_put_cstring(b, curve_keytype_to_name(key->type));
1761     buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
1762     EC_KEY_get0_public_key(key->ecdsa));
1763     buffer_put_bignum2(b, (BIGNUM *)EC_KEY_get0_private_key(key->ecdsa));
1764     break;
1765    
1766     case KEY_ED25519:
1767     buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
1768     buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ);
1769     break;
1770    
1771     default:
1772     break;
1773     }
1774     }
1775    
1776     /* calculate p-1 and q-1 */
1777     static void rsa_generate_additional_parameters(RSA *rsa)
1778     {
1779     BIGNUM *aux = NULL;
1780     BN_CTX *ctx = NULL;
1781    
1782     if ((aux = BN_new()) == NULL)
1783     goto error;
1784     if ((ctx = BN_CTX_new()) == NULL)
1785     goto error;
1786    
1787     if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) ||
1788     (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) ||
1789     (BN_sub(aux, rsa->p, BN_value_one()) == 0) ||
1790     (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0))
1791     goto error;
1792    
1793     error:
1794     if (aux)
1795     BN_clear_free(aux);
1796     if (ctx)
1797     BN_CTX_free(ctx);
1798     }
1799    
1800     static int key_ec_validate_private(EC_KEY *key)
1801     {
1802     BN_CTX *bnctx = NULL;
1803     BIGNUM *order, *tmp;
1804     int ret = -1;
1805    
1806     if ((bnctx = BN_CTX_new()) == NULL)
1807     goto out;
1808     BN_CTX_start(bnctx);
1809    
1810     if ((order = BN_CTX_get(bnctx)) == NULL ||
1811     (tmp = BN_CTX_get(bnctx)) == NULL)
1812     goto out;
1813    
1814     /* log2(private) > log2(order)/2 */
1815     if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1)
1816     goto out;
1817     if (BN_num_bits(EC_KEY_get0_private_key(key)) <=
1818     BN_num_bits(order) / 2) {
1819     goto out;
1820     }
1821    
1822     /* private < order - 1 */
1823     if (!BN_sub(tmp, order, BN_value_one()))
1824     goto out;
1825     if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) {
1826     goto out;
1827     }
1828     ret = 0;
1829    
1830     out:
1831     if (bnctx)
1832     BN_CTX_free(bnctx);
1833     return ret;
1834     }
1835    
1836     Key *key_private_deserialize(buffer_t *blob)
1837     {
1838     int success = 0;
1839     char *type_name = NULL;
1840     Key *k = NULL;
1841     unsigned int pklen, sklen;
1842     int type;
1843    
1844     type_name = buffer_get_string_msg(blob, NULL);
1845     if (type_name == NULL)
1846     goto error;
1847     type = get_keytype_from_name(type_name);
1848    
1849     k = key_new_private(type);
1850    
1851     switch (type) {
1852     case KEY_RSA:
1853     buffer_get_bignum2_msg(blob, k->rsa->n);
1854     buffer_get_bignum2_msg(blob, k->rsa->e);
1855     buffer_get_bignum2_msg(blob, k->rsa->d);
1856     buffer_get_bignum2_msg(blob, k->rsa->iqmp);
1857     buffer_get_bignum2_msg(blob, k->rsa->p);
1858     buffer_get_bignum2_msg(blob, k->rsa->q);
1859    
1860     /* Generate additional parameters */
1861     rsa_generate_additional_parameters(k->rsa);
1862     break;
1863    
1864     case KEY_DSA:
1865     buffer_get_bignum2_msg(blob, k->dsa->p);
1866     buffer_get_bignum2_msg(blob, k->dsa->q);
1867     buffer_get_bignum2_msg(blob, k->dsa->g);
1868     buffer_get_bignum2_msg(blob, k->dsa->pub_key);
1869     buffer_get_bignum2_msg(blob, k->dsa->priv_key);
1870     break;
1871    
1872     case KEY_ECDSA256:
1873     case KEY_ECDSA384:
1874     case KEY_ECDSA521:
1875     {
1876     int success = 0;
1877     unsigned int nid;
1878     char *curve = NULL;
1879     ssh_keytype skt;
1880     BIGNUM *exponent = NULL;
1881     EC_POINT *q = NULL;
1882    
1883     nid = keytype_to_cipher_nid(type);
1884     curve = buffer_get_string_msg(blob, NULL);
1885     skt = key_curve_name_to_keytype(curve);
1886     if (nid != keytype_to_cipher_nid(skt))
1887     goto ecdsa_error;
1888    
1889     k->ecdsa = EC_KEY_new_by_curve_name(nid);
1890     if (k->ecdsa == NULL)
1891     goto ecdsa_error;
1892    
1893     q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa));
1894     if (q == NULL)
1895     goto ecdsa_error;
1896    
1897     if ((exponent = BN_new()) == NULL)
1898     goto ecdsa_error;
1899     buffer_get_ecpoint_msg(blob,
1900     EC_KEY_get0_group(k->ecdsa), q);
1901     buffer_get_bignum2_msg(blob, exponent);
1902     if (EC_KEY_set_public_key(k->ecdsa, q) != 1)
1903     goto ecdsa_error;
1904     if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
1905     goto ecdsa_error;
1906     if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
1907     EC_KEY_get0_public_key(k->ecdsa)) != 0)
1908     goto ecdsa_error;
1909     if (key_ec_validate_private(k->ecdsa) != 0)
1910     goto ecdsa_error;
1911    
1912     success = 1;
1913    
1914     ecdsa_error:
1915     free(curve);
1916     if (exponent)
1917     BN_clear_free(exponent);
1918     if (q)
1919     EC_POINT_free(q);
1920     if (success == 0)
1921     goto error;
1922     }
1923     break;
1924    
1925     case KEY_ED25519:
1926     k->ed25519_pk = buffer_get_string_msg(blob, &pklen);
1927     k->ed25519_sk = buffer_get_string_msg(blob, &sklen);
1928     if (pklen != ED25519_PK_SZ)
1929     goto error;
1930     if (sklen != ED25519_SK_SZ)
1931     goto error;
1932     break;
1933    
1934     default:
1935     goto error;
1936     break;
1937     }
1938    
1939     /* enable blinding */
1940     switch (k->type) {
1941     case KEY_RSA1:
1942     case KEY_RSA:
1943     if (RSA_blinding_on(k->rsa, NULL) != 1)
1944     goto error;
1945     break;
1946     }
1947    
1948     success = 1;
1949    
1950     error:
1951     free(type_name);
1952    
1953     if (success == 0) {
1954     key_free(k);
1955     k = NULL;
1956     }
1957    
1958     return (k);
1959     }
1960 yutakapon 5838
1961    
1962     static void hostkeys_update_ctx_free(struct hostkeys_update_ctx *ctx)
1963     {
1964     size_t i;
1965    
1966     if (ctx == NULL)
1967     return;
1968     for (i = 0; i < ctx->nkeys; i++)
1969     key_free(ctx->keys[i]);
1970     free(ctx->keys);
1971     free(ctx->keys_seen);
1972     for (i = 0; i < ctx->nold; i++)
1973     key_free(ctx->old_keys[i]);
1974     free(ctx->old_keys);
1975     free(ctx->host_str);
1976     free(ctx->ip_str);
1977     free(ctx);
1978     }
1979    
1980 yutakapon 5841
1981     // �����������z�X�g���A���S���Y�������`�F�b�N�����B
1982 yutakapon 5838 //
1983 yutakapon 5841 // return 1: matched
1984     // 0: not matched
1985     //
1986     static int check_hostkey_algorithm(PTInstVar pvar, Key *key)
1987     {
1988     int ret = 0;
1989     int i, index;
1990    
1991     for (i = 0; pvar->settings.HostKeyOrder[i] != 0; i++) {
1992     index = pvar->settings.HostKeyOrder[i] - '0';
1993     if (index == KEY_NONE) // disabled line
1994     break;
1995    
1996     if (strcmp(get_sshname_from_key(key), get_ssh_keytype_name(index)) == 0)
1997     return 1;
1998     }
1999    
2000     return (ret);
2001     }
2002    
2003 yutakapon 5847 // Callback function
2004 yutakapon 5841 //
2005 yutakapon 5847 // argument:
2006     // key: known_hosts���o�^������������
2007     // _ctx: �T�[�o�����������������������Q
2008     //
2009     // return:
2010     // 1: deprecated key�������A��������key�������������~�B
2011     // 0: ����������key�������������K�v�B
2012     static int hostkeys_find(Key *key, void *_ctx)
2013     {
2014     struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
2015     int ret = 0;
2016     size_t i;
2017     Key **tmp;
2018    
2019     // SSH1�������O�B
2020     if (key->type == KEY_RSA1)
2021     goto error;
2022    
2023     // �������o�^�������������������T���B
2024     for (i = 0; i < ctx->nkeys; i++) {
2025     if (HOSTS_compare_public_key(key, ctx->keys[i]) == 1) {
2026     ctx->keys_seen[i] = 1;
2027     goto error;
2028     }
2029     }
2030    
2031     // deprecated�������A�����������X�g�������������B
2032     tmp = realloc(ctx->old_keys, (ctx->nold + 1)*sizeof(*ctx->old_keys));
2033     if (tmp != NULL) {
2034     ctx->old_keys = tmp;
2035     ctx->old_keys[ctx->nold++] = key;
2036     }
2037    
2038     ret = 1;
2039    
2040     error:
2041     return (ret);
2042     }
2043    
2044 maya 6132 static void hosts_updatekey_dlg_set_fingerprint(PTInstVar pvar, HWND dlg, digest_algorithm dgst_alg)
2045     {
2046 maya 6135 char *fp, *buf;
2047 maya 6132 size_t i;
2048 maya 6135 int buf_len;
2049 maya 6132 struct hostkeys_update_ctx *ctx;
2050    
2051     ctx = pvar->hostkey_ctx;
2052    
2053 maya 6135 if (ctx->nkeys > 0) {
2054     buf_len = 100 * ctx->nkeys;
2055     buf = calloc(100, ctx->nkeys);
2056     for (i = 0; i < ctx->nkeys; i++) {
2057     if (ctx->keys_seen[i])
2058     continue;
2059     switch (dgst_alg) {
2060     case SSH_DIGEST_MD5:
2061     fp = key_fingerprint(ctx->keys[i], SSH_FP_HEX, dgst_alg);
2062     break;
2063     case SSH_DIGEST_SHA256:
2064     fp = key_fingerprint(ctx->keys[i], SSH_FP_BASE64, dgst_alg);
2065     break;
2066     }
2067     strncat_s(buf, buf_len, get_sshname_from_key(ctx->keys[i]), _TRUNCATE);
2068     strncat_s(buf, buf_len, " ", _TRUNCATE);
2069     strncat_s(buf, buf_len, fp, _TRUNCATE);
2070     free(fp);
2071     if (i < ctx->nkeys - 1) {
2072     strncat_s(buf, buf_len, "\r\n", _TRUNCATE);
2073     }
2074     }
2075     SendDlgItemMessage(dlg, IDC_ADDKEY_EDIT, WM_SETTEXT, 0, (LPARAM)(char FAR *)buf);
2076     free(buf);
2077 maya 6132 }
2078    
2079 maya 6135 if (ctx->nold > 0) {
2080     buf_len = 100 * ctx->nold;
2081     buf = calloc(100, ctx->nold);
2082     SendDlgItemMessage(dlg, IDC_REMOVEKEY_EDIT, WM_SETTEXT, 0, (LPARAM)(char FAR *)"");
2083     for (i = 0; i < ctx->nold; i++) {
2084     switch (dgst_alg) {
2085     case SSH_DIGEST_MD5:
2086     fp = key_fingerprint(ctx->old_keys[i], SSH_FP_HEX, dgst_alg);
2087     break;
2088     case SSH_DIGEST_SHA256:
2089     fp = key_fingerprint(ctx->old_keys[i], SSH_FP_BASE64, dgst_alg);
2090     break;
2091     }
2092     strncat_s(buf, buf_len, get_sshname_from_key(ctx->old_keys[i]), _TRUNCATE);
2093     strncat_s(buf, buf_len, " ", _TRUNCATE);
2094     strncat_s(buf, buf_len, fp, _TRUNCATE);
2095     free(fp);
2096     if (i < ctx->nold - 1) {
2097     strncat_s(buf, buf_len, "\r\n", _TRUNCATE);
2098     }
2099 maya 6132 }
2100 maya 6135 SendDlgItemMessage(dlg, IDC_REMOVEKEY_EDIT, WM_SETTEXT, 0, (LPARAM)(char FAR *)buf);
2101     free(buf);
2102 maya 6132 }
2103     }
2104    
2105 yutakapon 5931 static BOOL CALLBACK hosts_updatekey_dlg_proc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam)
2106 yutakapon 5849 {
2107 yutakapon 5931 static HFONT DlgHostsAddFont;
2108     PTInstVar pvar;
2109     LOGFONT logfont;
2110     HFONT font;
2111     char buf[1024];
2112     char *host;
2113     struct hostkeys_update_ctx *ctx;
2114 maya 5964 char uimsg[MAX_UIMSG];
2115 yutakapon 5849
2116 yutakapon 5931 switch (msg) {
2117     case WM_INITDIALOG:
2118     pvar = (PTInstVar)lParam;
2119     SetWindowLong(dlg, DWL_USER, lParam);
2120 yutakapon 5854
2121 maya 5964 GetWindowText(dlg, uimsg, sizeof(uimsg));
2122     UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_TITLE", pvar, uimsg);
2123     SetWindowText(dlg, pvar->ts->UIMsg);
2124    
2125 yutakapon 5931 host = pvar->ssh_state.hostname;
2126     ctx = pvar->hostkey_ctx;
2127 maya 5964
2128     GetDlgItemText(dlg, IDC_HOSTKEY_MESSAGE, uimsg, sizeof(uimsg));
2129     UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_WARNING", pvar, uimsg);
2130 yutakapon 5931 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2131 yutakapon 5855 pvar->ts->UIMsg, host, ctx->nnew, ctx->nold
2132     );
2133 yutakapon 5931 SetDlgItemText(dlg, IDC_HOSTKEY_MESSAGE, buf);
2134 yutakapon 5853
2135 maya 6132 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2136     UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_FP_HASH_ALGORITHM", pvar, uimsg);
2137     SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2138    
2139 maya 5964 GetDlgItemText(dlg, IDC_ADDKEY_TEXT, uimsg, sizeof(uimsg));
2140     UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_ADD", pvar, uimsg);
2141     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, ctx->nnew);
2142 yutakapon 5931 SetDlgItemText(dlg, IDC_ADDKEY_TEXT, buf);
2143 yutakapon 5853
2144 maya 5964 GetDlgItemText(dlg, IDC_REMOVEKEY_TEXT, uimsg, sizeof(uimsg));
2145     UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_REMOVE", pvar, uimsg);
2146     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, ctx->nold);
2147 yutakapon 5931 SetDlgItemText(dlg, IDC_REMOVEKEY_TEXT, buf);
2148 yutakapon 5857
2149 maya 6145 CheckDlgButton(dlg, IDC_FP_HASH_ALG_SHA256, TRUE);
2150     hosts_updatekey_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2151 maya 6132
2152 maya 5969 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2153     UTIL_get_lang_msg("BTN_YES", pvar, uimsg);
2154     SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2155     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2156     UTIL_get_lang_msg("BTN_NO", pvar, uimsg);
2157     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2158    
2159 yutakapon 5931 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2160     GetObject(font, sizeof(LOGFONT), &logfont);
2161     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
2162     SendDlgItemMessage(dlg, IDC_HOSTKEY_MESSAGE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2163     SendDlgItemMessage(dlg, IDC_ADDKEY_TEXT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2164 maya 6132 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2165     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2166     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2167 yutakapon 5931 SendDlgItemMessage(dlg, IDC_ADDKEY_EDIT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2168     SendDlgItemMessage(dlg, IDC_REMOVEKEY_TEXT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2169     SendDlgItemMessage(dlg, IDC_REMOVEKEY_EDIT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2170 maya 5969 SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2171     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2172 yutakapon 5931 }
2173     else {
2174     DlgHostsAddFont = NULL;
2175     }
2176    
2177     return TRUE; /* because we do not set the focus */
2178    
2179     case WM_COMMAND:
2180     pvar = (PTInstVar)GetWindowLong(dlg, DWL_USER);
2181    
2182     switch (LOWORD(wParam)) {
2183     case IDOK:
2184    
2185     EndDialog(dlg, 1);
2186    
2187     if (DlgHostsAddFont != NULL) {
2188     DeleteObject(DlgHostsAddFont);
2189 yutakapon 5857 }
2190 yutakapon 5931
2191     return TRUE;
2192    
2193     case IDCANCEL: /* kill the connection */
2194     EndDialog(dlg, 0);
2195    
2196     if (DlgHostsAddFont != NULL) {
2197     DeleteObject(DlgHostsAddFont);
2198     }
2199    
2200     return TRUE;
2201    
2202 maya 6132 case IDC_FP_HASH_ALG_MD5:
2203     hosts_updatekey_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2204     return TRUE;
2205    
2206     case IDC_FP_HASH_ALG_SHA256:
2207     hosts_updatekey_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2208     return TRUE;
2209    
2210 yutakapon 5931 default:
2211     return FALSE;
2212 yutakapon 5857 }
2213    
2214 yutakapon 5931 default:
2215     return FALSE;
2216     }
2217     }
2218    
2219     static void update_known_hosts(PTInstVar pvar, struct hostkeys_update_ctx *ctx)
2220     {
2221     size_t i;
2222     int dlgresult;
2223     char msg[1024];
2224     char *host;
2225    
2226     host = pvar->ssh_state.hostname;
2227    
2228     // "/nosecuritywarning"���w�����������������A�X�V�������s�������B
2229     if (pvar->nocheck_known_hosts) {
2230     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because `/nosecuritywarning' option was specified.");
2231     notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2232     goto error;
2233     }
2234    
2235     // known_hosts�t�@�C�����X�V���s�������A���[�U���������������s���B
2236     if (pvar->settings.UpdateHostkeys == SSH_UPDATE_HOSTKEYS_ASK) {
2237     HWND cur_active = GetActiveWindow();
2238    
2239     pvar->hostkey_ctx = ctx;
2240     dlgresult = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUPDATE_HOSTKEY),
2241     cur_active != NULL ? cur_active : pvar->NotificationWindow,
2242     hosts_updatekey_dlg_proc, (LPARAM)pvar);
2243     if (dlgresult != 1) {
2244 yutakapon 5849 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because a user cancelled.");
2245     notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2246     goto error;
2247     }
2248     }
2249    
2250     // �����L�[�����������������B
2251     HOSTS_delete_all_hostkeys(pvar);
2252    
2253     // �V�����L�[���������o�^�����B
2254     for (i = 0; i < ctx->nkeys; i++) {
2255     HOSTS_add_host_key(pvar, ctx->keys[i]);
2256     }
2257     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was successfully updated to known_hosts file.");
2258     notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2259    
2260     error:
2261     return;
2262     }
2263    
2264 yutakapon 5853 static void client_global_hostkeys_private_confirm(PTInstVar pvar, int type, u_int32_t seq, void *_ctx)
2265 yutakapon 5850 {
2266 yutakapon 5853 struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
2267 yutakapon 5851 char msg[128];
2268     char *data;
2269     int len;
2270     unsigned char *blob = NULL;
2271     int bloblen;
2272     buffer_t *b = NULL;
2273     buffer_t *bsig = NULL;
2274     char *cp, *sig;
2275 yutakapon 5853 size_t i, ndone, siglen;
2276     int ret;
2277 yutakapon 5850
2278 yutakapon 5851 // SSH2 packet format:
2279     // [size(4) + padding size(1) + type(1)] + [payload(N) + padding(X)]
2280     // header body
2281     // ^data
2282     // <-----------------size------------------------------->
2283     // <---------len-------->
2284     //
2285     // data = payload(N) + padding(X): �p�f�B���O���������{�f�B���������w���B
2286     data = pvar->ssh_state.payload;
2287     // len = size - (padding size + 1): �p�f�B���O�������{�f�B�Btype�����������������B
2288     len = pvar->ssh_state.payloadlen;
2289 yutakapon 5853 len--; // type ��������
2290    
2291 yutakapon 5851 bsig = buffer_init();
2292     if (bsig == NULL)
2293     goto error;
2294     cp = buffer_append_space(bsig, len);
2295     memcpy(cp, data, len);
2296 yutakapon 5853
2297     if (ctx->nnew == 0) {
2298 yutakapon 5851 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey can not be updated because ctx->nnew %d(program bug).", ctx->nnew);
2299     notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2300 yutakapon 5853 goto error;
2301     }
2302     if (type != SSH2_MSG_REQUEST_SUCCESS) {
2303 yutakapon 5851 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Server failed to confirm ownership of private host keys(type %d)", type);
2304     notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2305 yutakapon 5853 goto error;
2306     }
2307     if (pvar->session_id_len == 0) {
2308 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);
2309     notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2310 yutakapon 5853 goto error;
2311     }
2312    
2313 yutakapon 5851 b = buffer_init();
2314     if (b == NULL)
2315     goto error;
2316    
2317     ndone = 0;
2318 yutakapon 5853 for (i = 0; i < ctx->nkeys; i++) {
2319     if (ctx->keys_seen[i])
2320     continue;
2321    
2322     buffer_clear(b);
2323 yutakapon 5851 buffer_put_cstring(b, "hostkeys-prove-00@openssh.com");
2324     buffer_put_string(b, pvar->session_id, pvar->session_id_len);
2325 yutakapon 5853 key_to_blob(ctx->keys[i], &blob, &bloblen);
2326     buffer_put_string(b, blob, bloblen);
2327     free(blob);
2328     blob = NULL;
2329    
2330 yutakapon 5851 sig = buffer_get_string_msg(bsig, &siglen);
2331     // Verify signature
2332     ret = key_verify(ctx->keys[i], sig, siglen, buffer_ptr(b), buffer_len(b));
2333 yutakapon 5853 free(sig);
2334     sig = NULL;
2335 yutakapon 5851 if (ret != 1) {
2336     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "server gave bad signature for %s key %u",
2337     get_sshname_from_key(ctx->keys[i]), i);
2338     notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2339 yutakapon 5853 goto error;
2340 yutakapon 5851 }
2341     ndone++;
2342     }
2343    
2344 yutakapon 5853 if (ndone != ctx->nnew) {
2345 yutakapon 5851 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey can not be updated because ndone != ctx->nnew (%u / %u)(program bug).",
2346     ndone, ctx->nnew);
2347     notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2348 yutakapon 5853 goto error;
2349     }
2350 yutakapon 5851
2351 yutakapon 5850 update_known_hosts(pvar, ctx);
2352    
2353 yutakapon 5851 error:
2354     buffer_free(b);
2355     buffer_free(bsig);
2356 yutakapon 5853 hostkeys_update_ctx_free(ctx);
2357 yutakapon 5850 }
2358    
2359 yutakapon 5847 //
2360 yutakapon 5838 // SSH�T�[�o�z�X�g��(known_hosts)�������X�V(OpenSSH 6.8 or later: host key rotation support)
2361     //
2362     // return 1: success
2363     // 0: fail
2364     //
2365     int update_client_input_hostkeys(PTInstVar pvar, char *dataptr, int datalen)
2366     {
2367     int success = 1; // OpenSSH 6.8�����������A�����������������������������������A
2368     // �������������� Tera Term �������������������������B
2369     int len;
2370 yutakapon 5843 size_t i;
2371 yutakapon 5838 char *cp, *fp;
2372     char msg[128];
2373     unsigned char *blob = NULL;
2374     buffer_t *b = NULL;
2375     struct hostkeys_update_ctx *ctx = NULL;
2376 yutakapon 5843 Key *key = NULL, **tmp;
2377 yutakapon 5850 unsigned char *outmsg;
2378 yutakapon 5838
2379 yutakapon 5839 // Tera Term���������A���Y�@�\���I���I�t�����������������������B
2380 yutakapon 5849 if (pvar->settings.UpdateHostkeys == SSH_UPDATE_HOSTKEYS_NO) {
2381 yutakapon 5839 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because ts.UpdateHostkeys is disabled.");
2382     notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2383 yutakapon 5843 return 1;
2384 yutakapon 5839 }
2385 yutakapon 5838
2386     ctx = calloc(1, sizeof(struct hostkeys_update_ctx));
2387     if (ctx == NULL)
2388     goto error;
2389    
2390     b = buffer_init();
2391     if (b == NULL)
2392     goto error;
2393    
2394     cp = buffer_append_space(b, datalen);
2395     memcpy(cp, dataptr, datalen);
2396    
2397     while (buffer_remain_len(b) > 0) {
2398     key_free(key);
2399     key = NULL;
2400    
2401     blob = buffer_get_string_msg(b, &len);
2402     key = key_from_blob(blob, len);
2403     if (key == NULL) {
2404 yutakapon 5841 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not found host key into blob %p (%d)", blob, len);
2405 yutakapon 5843 notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2406 yutakapon 5838 goto error;
2407     }
2408     free(blob);
2409     blob = NULL;
2410    
2411 maya 6120 fp = key_fingerprint(key, SSH_FP_HEX, SSH_DIGEST_MD5);
2412 yutakapon 5841 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Received %s host key %s",
2413 yutakapon 5838 get_sshname_from_key(key), fp);
2414     notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2415     free(fp);
2416 yutakapon 5841
2417     // �����������z�X�g�L�[�A���S���Y�������`�F�b�N�����B
2418     if (check_hostkey_algorithm(pvar, key) == 0) {
2419     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "%s host key is not permitted by ts.HostKeyOrder",
2420     get_sshname_from_key(key));
2421     notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2422     continue;
2423     }
2424    
2425 yutakapon 5843 // Skip certs: Tera Term�����������F�������T�|�[�g�B
2426 yutakapon 5841
2427 yutakapon 5843 // �d�������L�[�����M�������G���[�������B
2428     for (i = 0; i < ctx->nkeys; i++) {
2429     if (HOSTS_compare_public_key(key, ctx->keys[i]) == 1) {
2430     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Received duplicated %s host key",
2431     get_sshname_from_key(key));
2432     notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2433     goto error;
2434     }
2435     }
2436    
2437     // �L�[���o�^�����B
2438     tmp = realloc(ctx->keys, (ctx->nkeys + 1)*sizeof(*ctx->keys));
2439     if (tmp == NULL) {
2440     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not memory: realloc ctx->keys %d",
2441     ctx->nkeys);
2442     notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2443     goto error;
2444     }
2445     ctx->keys = tmp;
2446     ctx->keys[ctx->nkeys++] = key;
2447     key = NULL;
2448 yutakapon