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