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 5849 - (hide annotations) (download) (as text)
Tue May 5 18:08:23 2015 UTC (8 years, 11 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 47316 byte(s)
チケット #35047 SSH サーバホスト公開鍵の自動更新

・UpdateHostkeys エントリに"2"(ASK)を追加した。
・known_hosts ファイルの更新処理を追加した。

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

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