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 9210 - (hide annotations) (download) (as text)
Sat Apr 17 08:36:59 2021 UTC (2 years, 11 months ago) by nmaya
File MIME type: text/x-csrc
File size: 62063 byte(s)
ファイルを分割・コードを移動・関数名を整理・新しい OpenSSH からインポート

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