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