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