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