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 5941 - (hide annotations) (download) (as text)
Thu Aug 13 15:08:51 2015 UTC (8 years, 8 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 55050 byte(s)
Key typeが不定の場合、fingerprintの表示処理においてBOFで
アプリケーションが落ちる問題を修正した。

<発生条件>
・Host key rotationが有効である
・Host key rotationによりknown_hostsが更新される
・SSH接続後に、バージョンダイアログを表示する。

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    
1930 yutakapon 5931 switch (msg) {
1931     case WM_INITDIALOG:
1932     pvar = (PTInstVar)lParam;
1933     SetWindowLong(dlg, DWL_USER, lParam);
1934 yutakapon 5854
1935 yutakapon 5931 host = pvar->ssh_state.hostname;
1936     ctx = pvar->hostkey_ctx;
1937 yutakapon 5849
1938 yutakapon 5931 UTIL_get_lang_msg("DLG_HOSTKEY_ROTATION_WARNING", pvar,
1939 yutakapon 5854 "Remote server \"%s\" sent the set of host keys which are absent in your list of known hosts. \n"
1940     "The machine you have contacted may be a hostile machine pretending to be the server, or legitimate server supporting host key rotation. \n\n"
1941 yutakapon 5857 "If you choose to add %u latest key(s) and remove %u obsolete key(s) from this machine to the known hosts list and continue, then you will not receive this warning again.\n\n"
1942     "Do you want to update known hosts file with new key(s)?\n\n"
1943 yutakapon 5853 );
1944 yutakapon 5931 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1945 yutakapon 5855 pvar->ts->UIMsg, host, ctx->nnew, ctx->nold
1946     );
1947 yutakapon 5931 SetDlgItemText(dlg, IDC_HOSTKEY_MESSAGE, buf);
1948 yutakapon 5853
1949 yutakapon 5931 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%u latest key(s):\n", ctx->nnew);
1950     SetDlgItemText(dlg, IDC_ADDKEY_TEXT, buf);
1951     for (i = 0; i < ctx->nkeys; i++) {
1952     if (ctx->keys_seen[i])
1953     continue;
1954     fp = key_fingerprint(ctx->keys[i], SSH_FP_HEX);
1955     buf[0] = 0;
1956     strcat_s(buf, sizeof(buf), get_sshname_from_key(ctx->keys[i]));
1957     strcat_s(buf, sizeof(buf), " ");
1958     strcat_s(buf, sizeof(buf), fp);
1959     SendDlgItemMessage(dlg, IDC_ADDKEY_EDIT, EM_REPLACESEL, 0, (LPARAM)buf);
1960     SendDlgItemMessage(dlg, IDC_ADDKEY_EDIT, EM_REPLACESEL, 0, (LPARAM)"\r\n");
1961     free(fp);
1962 yutakapon 5853 }
1963    
1964 yutakapon 5931 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%u obsolete key(s):\n", ctx->nold);
1965     SetDlgItemText(dlg, IDC_REMOVEKEY_TEXT, buf);
1966     for (i = 0; i < ctx->nold; i++) {
1967     fp = key_fingerprint(ctx->old_keys[i], SSH_FP_HEX);
1968     buf[0] = 0;
1969     strcat_s(buf, sizeof(buf), get_sshname_from_key(ctx->old_keys[i]));
1970     strcat_s(buf, sizeof(buf), " ");
1971     strcat_s(buf, sizeof(buf), fp);
1972     SendDlgItemMessage(dlg, IDC_REMOVEKEY_EDIT, EM_REPLACESEL, 0, (LPARAM)buf);
1973     SendDlgItemMessage(dlg, IDC_REMOVEKEY_EDIT, EM_REPLACESEL, 0, (LPARAM)"\r\n");
1974     free(fp);
1975     }
1976 yutakapon 5857
1977 yutakapon 5931 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1978     GetObject(font, sizeof(LOGFONT), &logfont);
1979     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1980     SendDlgItemMessage(dlg, IDC_HOSTKEY_MESSAGE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1981     SendDlgItemMessage(dlg, IDC_ADDKEY_TEXT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1982     SendDlgItemMessage(dlg, IDC_ADDKEY_EDIT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1983     SendDlgItemMessage(dlg, IDC_REMOVEKEY_TEXT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1984     SendDlgItemMessage(dlg, IDC_REMOVEKEY_EDIT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1985     //SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1986     //SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1987     }
1988     else {
1989     DlgHostsAddFont = NULL;
1990     }
1991    
1992     return TRUE; /* because we do not set the focus */
1993    
1994     case WM_COMMAND:
1995     pvar = (PTInstVar)GetWindowLong(dlg, DWL_USER);
1996    
1997     switch (LOWORD(wParam)) {
1998     case IDOK:
1999    
2000     EndDialog(dlg, 1);
2001    
2002     if (DlgHostsAddFont != NULL) {
2003     DeleteObject(DlgHostsAddFont);
2004 yutakapon 5857 }
2005 yutakapon 5931
2006     return TRUE;
2007    
2008     case IDCANCEL: /* kill the connection */
2009     EndDialog(dlg, 0);
2010    
2011     if (DlgHostsAddFont != NULL) {
2012     DeleteObject(DlgHostsAddFont);
2013     }
2014    
2015     return TRUE;
2016    
2017     default:
2018     return FALSE;
2019 yutakapon 5857 }
2020    
2021 yutakapon 5931 default:
2022     return FALSE;
2023     }
2024     }
2025    
2026     static void update_known_hosts(PTInstVar pvar, struct hostkeys_update_ctx *ctx)
2027     {
2028     size_t i;
2029     int dlgresult;
2030     char msg[1024];
2031     char *host;
2032    
2033     host = pvar->ssh_state.hostname;
2034    
2035     // "/nosecuritywarning"���w�����������������A�X�V�������s�������B
2036     if (pvar->nocheck_known_hosts) {
2037     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because `/nosecuritywarning' option was specified.");
2038     notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2039     goto error;
2040     }
2041    
2042     // known_hosts�t�@�C�����X�V���s�������A���[�U���������������s���B
2043     if (pvar->settings.UpdateHostkeys == SSH_UPDATE_HOSTKEYS_ASK) {
2044     HWND cur_active = GetActiveWindow();
2045    
2046     pvar->hostkey_ctx = ctx;
2047     dlgresult = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUPDATE_HOSTKEY),
2048     cur_active != NULL ? cur_active : pvar->NotificationWindow,
2049     hosts_updatekey_dlg_proc, (LPARAM)pvar);
2050     if (dlgresult != 1) {
2051 yutakapon 5849 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because a user cancelled.");
2052     notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2053     goto error;
2054     }
2055     }
2056    
2057     // �����L�[�����������������B
2058     HOSTS_delete_all_hostkeys(pvar);
2059    
2060     // �V�����L�[���������o�^�����B
2061     for (i = 0; i < ctx->nkeys; i++) {
2062     HOSTS_add_host_key(pvar, ctx->keys[i]);
2063     }
2064     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was successfully updated to known_hosts file.");
2065     notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2066    
2067     error:
2068     return;
2069     }
2070    
2071 yutakapon 5853 static void client_global_hostkeys_private_confirm(PTInstVar pvar, int type, u_int32_t seq, void *_ctx)
2072 yutakapon 5850 {
2073 yutakapon 5853 struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
2074 yutakapon 5851 char msg[128];
2075     char *data;
2076     int len;
2077     unsigned char *blob = NULL;
2078     int bloblen;
2079     buffer_t *b = NULL;
2080     buffer_t *bsig = NULL;
2081     char *cp, *sig;
2082 yutakapon 5853 size_t i, ndone, siglen;
2083     int ret;
2084 yutakapon 5850
2085 yutakapon 5851 // SSH2 packet format:
2086     // [size(4) + padding size(1) + type(1)] + [payload(N) + padding(X)]
2087     // header body
2088     // ^data
2089     // <-----------------size------------------------------->
2090     // <---------len-------->
2091     //
2092     // data = payload(N) + padding(X): �p�f�B���O���������{�f�B���������w���B
2093     data = pvar->ssh_state.payload;
2094     // len = size - (padding size + 1): �p�f�B���O�������{�f�B�Btype�����������������B
2095     len = pvar->ssh_state.payloadlen;
2096 yutakapon 5853 len--; // type ��������
2097    
2098 yutakapon 5851 bsig = buffer_init();
2099     if (bsig == NULL)
2100     goto error;
2101     cp = buffer_append_space(bsig, len);
2102     memcpy(cp, data, len);
2103 yutakapon 5853
2104     if (ctx->nnew == 0) {
2105 yutakapon 5851 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey can not be updated because ctx->nnew %d(program bug).", ctx->nnew);
2106     notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2107 yutakapon 5853 goto error;
2108     }
2109     if (type != SSH2_MSG_REQUEST_SUCCESS) {
2110 yutakapon 5851 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Server failed to confirm ownership of private host keys(type %d)", type);
2111     notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2112 yutakapon 5853 goto error;
2113     }
2114     if (pvar->session_id_len == 0) {
2115 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);
2116     notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2117 yutakapon 5853 goto error;
2118     }
2119    
2120 yutakapon 5851 b = buffer_init();
2121     if (b == NULL)
2122     goto error;
2123    
2124     ndone = 0;
2125 yutakapon 5853 for (i = 0; i < ctx->nkeys; i++) {
2126     if (ctx->keys_seen[i])
2127     continue;
2128    
2129     buffer_clear(b);
2130 yutakapon 5851 buffer_put_cstring(b, "hostkeys-prove-00@openssh.com");
2131     buffer_put_string(b, pvar->session_id, pvar->session_id_len);
2132 yutakapon 5853 key_to_blob(ctx->keys[i], &blob, &bloblen);
2133     buffer_put_string(b, blob, bloblen);
2134     free(blob);
2135     blob = NULL;
2136    
2137 yutakapon 5851 sig = buffer_get_string_msg(bsig, &siglen);
2138     // Verify signature
2139     ret = key_verify(ctx->keys[i], sig, siglen, buffer_ptr(b), buffer_len(b));
2140 yutakapon 5853 free(sig);
2141     sig = NULL;
2142 yutakapon 5851 if (ret != 1) {
2143     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "server gave bad signature for %s key %u",
2144     get_sshname_from_key(ctx->keys[i]), i);
2145     notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2146 yutakapon 5853 goto error;
2147 yutakapon 5851 }
2148     ndone++;
2149     }
2150    
2151 yutakapon 5853 if (ndone != ctx->nnew) {
2152 yutakapon 5851 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey can not be updated because ndone != ctx->nnew (%u / %u)(program bug).",
2153     ndone, ctx->nnew);
2154     notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2155 yutakapon 5853 goto error;
2156     }
2157 yutakapon 5851
2158 yutakapon 5850 update_known_hosts(pvar, ctx);
2159    
2160 yutakapon 5851 error:
2161     buffer_free(b);
2162     buffer_free(bsig);
2163 yutakapon 5853 hostkeys_update_ctx_free(ctx);
2164 yutakapon 5850 }
2165    
2166 yutakapon 5847 //
2167 yutakapon 5838 // SSH�T�[�o�z�X�g��(known_hosts)�������X�V(OpenSSH 6.8 or later: host key rotation support)
2168     //
2169     // return 1: success
2170     // 0: fail
2171     //
2172     int update_client_input_hostkeys(PTInstVar pvar, char *dataptr, int datalen)
2173     {
2174     int success = 1; // OpenSSH 6.8�����������A�����������������������������������A
2175     // �������������� Tera Term �������������������������B
2176     int len;
2177 yutakapon 5843 size_t i;
2178 yutakapon 5838 char *cp, *fp;
2179     char msg[128];
2180     unsigned char *blob = NULL;
2181     buffer_t *b = NULL;
2182     struct hostkeys_update_ctx *ctx = NULL;
2183 yutakapon 5843 Key *key = NULL, **tmp;
2184 yutakapon 5850 unsigned char *outmsg;
2185 yutakapon 5838
2186 yutakapon 5839 // Tera Term���������A���Y�@�\���I���I�t�����������������������B
2187 yutakapon 5849 if (pvar->settings.UpdateHostkeys == SSH_UPDATE_HOSTKEYS_NO) {
2188 yutakapon 5839 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because ts.UpdateHostkeys is disabled.");
2189     notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2190 yutakapon 5843 return 1;
2191 yutakapon 5839 }
2192 yutakapon 5838
2193     ctx = calloc(1, sizeof(struct hostkeys_update_ctx));
2194     if (ctx == NULL)
2195     goto error;
2196    
2197     b = buffer_init();
2198     if (b == NULL)
2199     goto error;
2200    
2201     cp = buffer_append_space(b, datalen);
2202     memcpy(cp, dataptr, datalen);
2203    
2204     while (buffer_remain_len(b) > 0) {
2205     key_free(key);
2206     key = NULL;
2207    
2208     blob = buffer_get_string_msg(b, &len);
2209     key = key_from_blob(blob, len);
2210     if (key == NULL) {
2211 yutakapon 5841 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not found host key into blob %p (%d)", blob, len);
2212 yutakapon 5843 notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2213 yutakapon 5838 goto error;
2214     }
2215     free(blob);
2216     blob = NULL;
2217    
2218     fp = key_fingerprint(key, SSH_FP_HEX);
2219 yutakapon 5841 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Received %s host key %s",
2220 yutakapon 5838 get_sshname_from_key(key), fp);
2221     notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2222     free(fp);
2223 yutakapon 5841
2224     // �����������z�X�g�L�[�A���S���Y�������`�F�b�N�����B
2225     if (check_hostkey_algorithm(pvar, key) == 0) {
2226     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "%s host key is not permitted by ts.HostKeyOrder",
2227     get_sshname_from_key(key));
2228     notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2229     continue;
2230     }
2231    
2232 yutakapon 5843 // Skip certs: Tera Term�����������F�������T�|�[�g�B
2233 yutakapon 5841
2234 yutakapon 5843 // �d�������L�[�����M�������G���[�������B
2235     for (i = 0; i < ctx->nkeys; i++) {
2236     if (HOSTS_compare_public_key(key, ctx->keys[i]) == 1) {
2237     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Received duplicated %s host key",
2238     get_sshname_from_key(key));
2239     notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
2240     goto error;
2241     }
2242     }
2243    
2244     // �L�[���o�^�����B
2245     tmp = realloc(ctx->keys, (ctx->nkeys + 1)*sizeof(*ctx->keys));
2246     if (tmp == NULL) {
2247     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not memory: realloc ctx->keys %d",
2248     ctx->nkeys);
2249     notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2250     goto error;
2251     }
2252     ctx->keys = tmp;
2253     ctx->keys[ctx->nkeys++] = key;
2254     key = NULL;
2255 yutakapon 5838 }
2256    
2257 yutakapon 5843 if (ctx->nkeys == 0) {
2258     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "No host rotation key");
2259     notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2260     goto error;
2261     }
2262    
2263 yutakapon 5849 if ((ctx->keys_seen = calloc(ctx->nkeys, sizeof(*ctx->keys_seen))) == NULL) {
2264 yutakapon 5847 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not memory: calloc ctx->keys %d",
2265     ctx->nkeys);
2266     notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
2267     goto error;
2268 yutakapon 5849 }
2269 yutakapon 5846
2270 yutakapon 5847 HOSTS_hostkey_foreach(pvar, hostkeys_find, ctx);
2271    
2272 yutakapon 5848 // �T�[�o�������������������Q�����A�������������V�K���������������������B
2273 yutakapon 5849 ctx->nnew = 0;
2274     for (i = 0; i < ctx->nkeys; i++) {
2275     if (!ctx->keys_seen[i])
2276     ctx->nnew++;
2277 yutakapon 5848 }
2278 yutakapon 5849 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "%u keys from server: %u new, %u retained. %u to remove",
2279     ctx->nkeys, ctx->nnew, ctx->nkeys - ctx->nnew, ctx->nold);
2280 yutakapon 5848 notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE);
2281    
2282     // �V�K�������������[�������Adeprecated���������������B
2283     if (ctx->nnew == 0 && ctx->nold != 0) {
2284 yutakapon 5849 update_known_hosts(pvar, ctx);
2285 yutakapon 5848
2286     }
2287     else if (ctx->nnew != 0) { // �V�K�������������������������B
2288 yutakapon 5850 buffer_clear(b);
2289 yutakapon 5848
2290 yutakapon 5850 buffer_put_cstring(b, "hostkeys-prove-00@openssh.com");
2291     buffer_put_char(b, 1); /* bool: want reply */
2292    
2293 yutakapon 5853 for (i = 0; i < ctx->nkeys; i++) {
2294     if (ctx->keys_seen[i])
2295     continue;
2296     key_to_blob(ctx->keys[i], &blob, &len);
2297     buffer_put_string(b, blob, len);
2298     free(blob);
2299     blob = NULL;
2300     }
2301    
2302 yutakapon 5850 len = buffer_len(b);
2303     outmsg = begin_send_packet(pvar, SSH2_MSG_GLOBAL_REQUEST, len);
2304     memcpy(outmsg, buffer_ptr(b), len);
2305     finish_send_packet(pvar);
2306    
2307     // SSH2_MSG_GLOBAL_REQUEST�����X�|���X�����������n���h�����o�^�����B
2308     client_register_global_confirm(client_global_hostkeys_private_confirm, ctx);
2309     ctx = NULL; // callback���������������A��������NULL���������������B
2310 yutakapon 5848 }
2311    
2312 yutakapon 5838 success = 1;
2313    
2314     error:
2315     buffer_free(b);
2316     hostkeys_update_ctx_free(ctx);
2317     free(blob);
2318    
2319     return (success);
2320     }

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