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

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