Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/ttssh2/ttxssh/key.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10618 - (hide annotations) (download) (as text)
Fri Mar 3 15:15:16 2023 UTC (13 months, 1 week ago) by zmatsuo
File MIME type: text/x-csrc
File size: 63875 byte(s)
ttxsshで tttset.UIMsg[] ではなく TInstVar.UIMsg[] を使用するよう修正

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