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 6117 - (hide annotations) (download) (as text)
Wed Nov 11 22:38:30 2015 UTC (8 years, 5 months ago) by maya
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 55543 byte(s)
SSH key fingerprint の hex 形式の出力を関数に移動(OpenSSH と同じ)
ダイジェストの形式を引数に追加

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

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