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

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