Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/ttssh2/ttxssh/keyfiles.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: 52253 byte(s)
ttxsshで tttset.UIMsg[] ではなく TInstVar.UIMsg[] を使用するよう修正

- lng(i18n)用文字列領域
- ttxssh 以外は tttset.UIMsg[] を使用しなくなった
  - Unicode(wchar_t)版動的な文字列取得に切り替えた
  - tttset.UIMsg[] は ANSI(char) 文字列
- プラグイン用ワーク内に TInstVar.UIMsg[] を新設した
1 maya 3227 /*
2 doda 6841 * Copyright (c) 1998-2001, Robert O'Callahan
3 nmaya 9048 * (C) 2004- TeraTerm Project
4 doda 6841 * All rights reserved.
5     *
6     * Redistribution and use in source and binary forms, with or without
7     * modification, are permitted provided that the following conditions
8     * are met:
9     *
10     * 1. Redistributions of source code must retain the above copyright
11     * notice, this list of conditions and the following disclaimer.
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the distribution.
15     * 3. The name of the author may not be used to endorse or promote products
16     * derived from this software without specific prior written permission.
17     *
18     * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21     * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28     */
29 maya 3227
30     /*
31     This code is copyright (C) 1998-1999 Robert O'Callahan.
32     See LICENSE.TXT for the license.
33     */
34    
35     #include "ttxssh.h"
36     #include "keyfiles.h"
37 nmaya 9258 #include "keyfiles-putty.h"
38 maya 4307 #include "key.h"
39 nmaya 9258 #include "hostkey.h"
40     #include "argon2.h"
41 maya 3227
42     #include <io.h>
43     #include <fcntl.h>
44     #include <stdio.h>
45     #include <stdlib.h>
46     #include <errno.h>
47     #include <openssl/rsa.h>
48     #include <openssl/dsa.h>
49     #include <openssl/evp.h>
50     #include <openssl/pem.h>
51 maya 5056 #include <openssl/md5.h>
52 maya 3227 #include <openssl/err.h>
53    
54 maya 5056 #include "cipher.h"
55    
56 maya 3227 static char ID_string[] = "SSH PRIVATE KEY FILE FORMAT 1.1\n";
57    
58 zmatsuo 8527 typedef struct keyfile_header {
59     ssh2_keyfile_type type;
60     char *header;
61     } keyfile_header_t;
62    
63     static keyfile_header_t keyfile_headers[] = {
64     {SSH2_KEYFILE_TYPE_OPENSSH, "-----BEGIN RSA PRIVATE KEY-----"},
65     {SSH2_KEYFILE_TYPE_OPENSSH, "-----BEGIN DSA PRIVATE KEY-----"},
66     {SSH2_KEYFILE_TYPE_OPENSSH, "-----BEGIN EC PRIVATE KEY-----"},
67     {SSH2_KEYFILE_TYPE_OPENSSH, "-----BEGIN ENCRYPTED PRIVATE KEY-----"},
68     {SSH2_KEYFILE_TYPE_OPENSSH, "-----BEGIN PRIVATE KEY-----"},
69 zmatsuo 10618 {SSH2_KEYFILE_TYPE_OPENSSH, "-----BEGIN OPENSSH PRIVATE KEY-----"},
70 zmatsuo 8527 {SSH2_KEYFILE_TYPE_PUTTY, "PuTTY-User-Key-File-2"},
71 nmaya 9781 {SSH2_KEYFILE_TYPE_PUTTY, "PuTTY-User-Key-File-3"},
72 zmatsuo 8527 {SSH2_KEYFILE_TYPE_SECSH, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"},
73     {SSH2_KEYFILE_TYPE_NONE, NULL},
74     };
75    
76 doda 6801 static BIGNUM *get_bignum(unsigned char *bytes)
77 maya 3227 {
78     int bits = get_ushort16_MSBfirst(bytes);
79    
80     return BN_bin2bn(bytes + 2, (bits + 7) / 8, NULL);
81     }
82    
83     /* normalize the RSA key by precomputing various bits of it.
84     This code is adapted from libeay's rsa_gen.c
85     It's needed to work around "issues" with LIBEAY/RSAREF.
86     If this function returns 0, then something went wrong and the
87     key must be discarded. */
88 doda 6801 static BOOL normalize_key(RSA *key)
89 maya 3227 {
90     BOOL OK = FALSE;
91     BIGNUM *r = BN_new();
92     BN_CTX *ctx = BN_CTX_new();
93 yutakapon 8316 BIGNUM *e, *n, *d, *dmp1, *dmq1, *iqmp, *p, *q;
94 maya 3227
95 yutakapon 8316 e = n = d = dmp1 = dmq1 = iqmp = p = q = NULL;
96 maya 3227
97 yutakapon 8316 RSA_get0_key(key, &n, &e, &d);
98     RSA_get0_factors(key, &p, &q);
99     RSA_get0_crt_params(key, &dmp1, &dmq1, &iqmp);
100    
101     if (BN_cmp(p, q) < 0) {
102     BN_swap(p, q);
103 maya 3227 }
104    
105     if (r != NULL && ctx != NULL) {
106 yutakapon 8316 dmp1 = BN_new();
107     dmq1 = BN_new();
108     iqmp = BN_mod_inverse(NULL, q, p, ctx);
109     RSA_set0_crt_params(key, dmp1, dmq1, iqmp);
110 maya 3227
111 yutakapon 8316 if (dmp1 != NULL && dmq1 != NULL && iqmp != NULL) {
112     OK = BN_sub(r, p, BN_value_one())
113     && BN_mod(dmp1, d, r, ctx)
114     && BN_sub(r, q, BN_value_one())
115     && BN_mod(dmq1, d, r, ctx);
116 maya 3227 }
117     }
118    
119     BN_free(r);
120     BN_CTX_free(ctx);
121    
122     return OK;
123     }
124    
125 maya 4307 static RSA *read_RSA_private_key(PTInstVar pvar,
126     char * relative_name,
127     char * passphrase,
128     BOOL * invalid_passphrase,
129     BOOL is_auto_login)
130 maya 3227 {
131     char filename[2048];
132     int fd;
133     unsigned int length, amount_read;
134     unsigned char *keyfile_data;
135     unsigned int index;
136     int cipher;
137 doda 6801 RSA *key;
138 maya 3227 unsigned int E_index, N_index, D_index, U_index, P_index, Q_index = 0;
139 yutakapon 8316 BIGNUM *e, *n, *d, *p, *q;
140 maya 3227
141     *invalid_passphrase = FALSE;
142    
143     get_teraterm_dir_relative_name(filename, sizeof(filename),
144     relative_name);
145    
146     fd = _open(filename, _O_RDONLY | _O_SEQUENTIAL | _O_BINARY);
147     if (fd == -1) {
148     if (errno == ENOENT) {
149     UTIL_get_lang_msg("MSG_KEYFILES_READ_ENOENT_ERROR", pvar,
150     "An error occurred while trying to read the key file.\n"
151     "The specified filename does not exist.");
152 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
153 maya 3227 } else {
154     UTIL_get_lang_msg("MSG_KEYFILES_READ_ERROR", pvar,
155     "An error occurred while trying to read the key file.");
156 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
157 maya 3227 }
158     return NULL;
159     }
160    
161     length = (int) _lseek(fd, 0, SEEK_END);
162     _lseek(fd, 0, SEEK_SET);
163    
164     if (length >= 0 && length < 0x7FFFFFFF) {
165     keyfile_data = malloc(length + 1);
166     if (keyfile_data == NULL) {
167     UTIL_get_lang_msg("MSG_KEYFILES_READ_ALLOC_ERROR", pvar,
168     "Memory ran out while trying to allocate space to read the key file.");
169 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
170 maya 3227 _close(fd);
171     return NULL;
172     }
173     } else {
174     UTIL_get_lang_msg("MSG_KEYFILES_READ_ERROR", pvar,
175     "An error occurred while trying to read the key file.");
176 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
177 maya 3227 _close(fd);
178     return NULL;
179     }
180    
181     amount_read = _read(fd, keyfile_data, length);
182     /* terminate it with 0 so that the strncmp below is guaranteed not to
183     crash */
184     keyfile_data[length] = 0;
185    
186     _close(fd);
187    
188     if (amount_read != length) {
189     UTIL_get_lang_msg("MSG_KEYFILES_READ_ERROR", pvar,
190     "An error occurred while trying to read the key file.");
191 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
192 maya 3227 free(keyfile_data);
193     return NULL;
194     }
195    
196     if (strcmp(keyfile_data, ID_string) != 0) {
197     UTIL_get_lang_msg("MSG_KEYFILES_PRIVATEKEY_NOTCONTAIN_ERROR", pvar,
198     "The specified key file does not contain an SSH private key.");
199 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
200 maya 3227 free(keyfile_data);
201     return NULL;
202     }
203    
204     index = NUM_ELEM(ID_string);
205    
206     if (length < index + 9) {
207     UTIL_get_lang_msg("MSG_KEYFILES_PRIVATEKEY_TRUNCATE_ERROR", pvar,
208     "The specified key file has been truncated and does not contain a valid private key.");
209 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
210 maya 3227 free(keyfile_data);
211     return NULL;
212     }
213    
214     cipher = keyfile_data[index];
215     /* skip reserved int32, public key bits int32 */
216     index += 9;
217     /* skip public key e and n mp_ints */
218     if (length < index + 2) {
219     UTIL_get_lang_msg("MSG_KEYFILES_PRIVATEKEY_TRUNCATE_ERROR", pvar,
220     "The specified key file has been truncated and does not contain a valid private key.");
221 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
222 maya 3227 free(keyfile_data);
223     return NULL;
224     }
225     N_index = index;
226     index += (get_ushort16_MSBfirst(keyfile_data + index) + 7) / 8 + 2;
227     if (length < index + 2) {
228     UTIL_get_lang_msg("MSG_KEYFILES_PRIVATEKEY_TRUNCATE_ERROR", pvar,
229     "The specified key file has been truncated and does not contain a valid private key.");
230 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
231 maya 3227 free(keyfile_data);
232     return NULL;
233     }
234     E_index = index;
235     index += (get_ushort16_MSBfirst(keyfile_data + index) + 7) / 8 + 2;
236     /* skip comment */
237     if (length < index + 4) {
238     UTIL_get_lang_msg("MSG_KEYFILES_PRIVATEKEY_TRUNCATE_ERROR", pvar,
239     "The specified key file has been truncated and does not contain a valid private key.");
240 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
241 maya 3227 free(keyfile_data);
242     return NULL;
243     }
244     index += get_uint32_MSBfirst(keyfile_data + index) + 4;
245    
246     if (length < index + 6) {
247     UTIL_get_lang_msg("MSG_KEYFILES_PRIVATEKEY_TRUNCATE_ERROR", pvar,
248     "The specified key file has been truncated and does not contain a valid private key.");
249 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
250 maya 3227 free(keyfile_data);
251     return NULL;
252     }
253     if (cipher != SSH_CIPHER_NONE) {
254     if ((length - index) % 8 != 0) {
255     UTIL_get_lang_msg("MSG_KEYFILES_PRIVATEKEY_LENGTH_ERROR", pvar,
256     "The specified key file cannot be decrypted using the passphrase.\n"
257     "The file does not have the correct length.");
258 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
259 maya 3227 free(keyfile_data);
260     return NULL;
261     }
262     if (!CRYPT_passphrase_decrypt
263     (cipher, passphrase, keyfile_data + index, length - index)) {
264     UTIL_get_lang_msg("MSG_KEYFILES_PRIVATEKEY_NOCIPHER_ERROR", pvar,
265     "The specified key file cannot be decrypted using the passphrase.\n"
266     "The cipher type used to encrypt the file is not supported by TTSSH for this purpose.");
267 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
268 maya 3227 free(keyfile_data);
269     return NULL;
270     }
271     }
272    
273     if (keyfile_data[index] != keyfile_data[index + 2]
274     || keyfile_data[index + 1] != keyfile_data[index + 3]) {
275     *invalid_passphrase = TRUE;
276     if (is_auto_login) {
277     UTIL_get_lang_msg("MSG_KEYFILES_PASSPHRASE_EMPTY_ERROR", pvar,
278     "The specified key file cannot be decrypted using the empty passphrase.\n"
279     "For auto-login, you must create a key file with no passphrase.\n"
280     "BEWARE: This means the key can easily be stolen.");
281 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
282 maya 3227 }
283     else {
284     UTIL_get_lang_msg("MSG_KEYFILES_PASSPHRASE_ERROR", pvar,
285     "The specified key file cannot be decrypted using the passphrase.\n"
286     "The passphrase is incorrect.");
287 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
288 maya 3227 }
289 yutakapon 6229 SecureZeroMemory(keyfile_data, length);
290 maya 3227 free(keyfile_data);
291     return NULL;
292     }
293     index += 4;
294    
295     D_index = index;
296     if (length >= D_index + 2) {
297     U_index =
298     D_index + (get_ushort16_MSBfirst(keyfile_data + D_index) +
299     7) / 8 + 2;
300     if (length >= U_index + 2) {
301     P_index =
302     U_index + (get_ushort16_MSBfirst(keyfile_data + U_index) +
303     7) / 8 + 2;
304     if (length >= P_index + 2) {
305     Q_index =
306     P_index +
307     (get_ushort16_MSBfirst(keyfile_data + P_index) +
308     7) / 8 + 2;
309     }
310     }
311     }
312     if (Q_index == 0
313     || length <
314     Q_index + (get_ushort16_MSBfirst(keyfile_data + Q_index) + 7) / 8 + 2) {
315     UTIL_get_lang_msg("MSG_KEYFILES_PRIVATEKEY_TRUNCATE_ERROR", pvar,
316     "The specified key file has been truncated and does not contain a valid private key.");
317 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
318 yutakapon 6229 SecureZeroMemory(keyfile_data, length);
319 maya 3227 free(keyfile_data);
320     return NULL;
321     }
322    
323     key = RSA_new();
324 yutakapon 8316 n = get_bignum(keyfile_data + N_index);
325     e = get_bignum(keyfile_data + E_index);
326     d = get_bignum(keyfile_data + D_index);
327     RSA_set0_key(key, n, e, d);
328     p = get_bignum(keyfile_data + P_index);
329     q = get_bignum(keyfile_data + Q_index);
330     RSA_set0_factors(key, p, q);
331 maya 3227
332     if (!normalize_key(key)) {
333     UTIL_get_lang_msg("MSG_KEYFILES_CRYPTOLIB_ERROR", pvar,
334 yutakapon 6019 "Error in cryptography library.\n"
335 maya 3227 "Perhaps the stored key is invalid.");
336 zmatsuo 10618 notify_nonfatal_error(pvar, pvar->UIMsg);
337 maya 3227
338     RSA_free(key);
339     key = NULL;
340     }
341    
342 yutakapon 6229 SecureZeroMemory(keyfile_data, length);
343 maya 3227 free(keyfile_data);
344     return key;
345     }
346    
347 maya 4307 Key *KEYFILES_read_private_key(PTInstVar pvar,
348     char * relative_name,
349     char * passphrase,
350     BOOL * invalid_passphrase,
351     BOOL is_auto_login)
352 maya 3227 {
353 maya 4307 RSA *RSA_key = read_RSA_private_key(pvar, relative_name,
354     passphrase, invalid_passphrase,
355     is_auto_login);
356 maya 3227
357     if (RSA_key == NULL) {
358     return FALSE;
359     } else {
360 maya 4307 Key *result = (Key *) malloc(sizeof(Key));
361 maya 3227
362     // �t���[���������� 0 ���������������������������B(2004.12.20 yutaka)
363 zmatsuo 10618 ZeroMemory(result, sizeof(Key));
364 maya 3227
365 maya 4307 result->rsa = RSA_key;
366 maya 3227 return result;
367     }
368     }
369    
370    
371     //
372     // SSH2
373     //
374    
375 yutakapon 5545 // bcrypt KDF �`��������
376     // based on key_parse_private2() @ OpenSSH 6.5
377     static Key *read_SSH2_private2_key(PTInstVar pvar,
378 nmaya 9255 FILE * fp,
379     char * passphrase,
380     BOOL * invalid_passphrase,
381     BOOL is_auto_login,
382     char *errmsg,
383     int errmsg_len)
384 yutakapon 5545 {
385 zmatsuo 10618 /* (A)
386 yutakapon 5545 * buffer_consume�n�������g���������Abuffer_len��buffer_ptr���g�����������A
387     * buffer_len -> buffer_remain_len
388     * buffer_ptr -> buffer_tail_ptr
389     * �������g�p���������B
390     */
391     buffer_t *blob = NULL;
392     buffer_t *b = NULL;
393     buffer_t *kdf = NULL;
394     buffer_t *encoded = NULL;
395     buffer_t *copy_consumed = NULL; // (A)
396     Key *keyfmt = NULL;
397     unsigned char buf[1024];
398     unsigned char *cp, last, pad;
399     char *ciphername = NULL, *kdfname = NULL, *kdfp = NULL, *key = NULL, *salt = NULL, *comment = NULL;
400     unsigned int len, klen, nkeys, blocksize, keylen, ivlen, slen, rounds;
401 zmatsuo 10618 unsigned int check1, check2, m1len, m2len;
402 yutakapon 5545 int dlen, i;
403 nmaya 9255 const struct ssh2cipher *cipher;
404 yutakapon 5545 size_t authlen;
405 nmaya 9255 struct sshcipher_ctx *cc = NULL;
406 yutakapon 8316 int ret;
407 yutakapon 5545
408     blob = buffer_init();
409     b = buffer_init();
410     kdf = buffer_init();
411     encoded = buffer_init();
412     copy_consumed = buffer_init();
413 yutakapon 8316
414 nmaya 9255 if (blob == NULL || b == NULL || kdf == NULL || encoded == NULL || copy_consumed == NULL)
415 yutakapon 5545 goto error;
416    
417     // �t�@�C������������������
418     for (;;) {
419     len = fread(buf, 1, sizeof(buf), fp);
420     buffer_append(blob, buf, len);
421     if (buffer_len(blob) > MAX_KEY_FILE_SIZE) {
422 zmatsuo 7536 logprintf(LOG_LEVEL_WARNING, "%s: key file too large.", __FUNCTION__);
423 yutakapon 5545 goto error;
424     }
425     if (len < sizeof(buf))
426     break;
427     }
428    
429 doda 6621 /* base64 decode */
430 yutakapon 5545 m1len = sizeof(MARK_BEGIN) - 1;
431     m2len = sizeof(MARK_END) - 1;
432     cp = buffer_ptr(blob);
433     len = buffer_len(blob);
434     if (len < m1len || memcmp(cp, MARK_BEGIN, m1len)) {
435 zmatsuo 7536 logprintf(LOG_LEVEL_VERBOSE, "%s: missing begin marker", __FUNCTION__);
436 yutakapon 5545 goto error;
437     }
438     cp += m1len;
439     len -= m1len;
440     while (len) {
441     if (*cp != '\n' && *cp != '\r')
442     buffer_put_char(encoded, *cp);
443     last = *cp;
444     len--;
445     cp++;
446     if (last == '\n') {
447     if (len >= m2len && !memcmp(cp, MARK_END, m2len)) {
448     buffer_put_char(encoded, '\0');
449     break;
450     }
451     }
452     }
453     if (!len) {
454 zmatsuo 7536 logprintf(LOG_LEVEL_VERBOSE, "%s: no end marker", __FUNCTION__);
455 yutakapon 5545 goto error;
456     }
457    
458 doda 6621 // �t�@�C�����X�L�������I�����������Abase64 decode�����B
459 yutakapon 5545 len = buffer_len(encoded);
460     if ((cp = buffer_append_space(copy_consumed, len)) == NULL) {
461 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: buffer_append_space", __FUNCTION__);
462 yutakapon 5545 goto error;
463     }
464 doda 6621 if ((dlen = b64decode(cp, len, buffer_ptr(encoded))) < 0) {
465 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: base64 decode failed", __FUNCTION__);
466 yutakapon 5545 goto error;
467     }
468     if ((unsigned int)dlen > len) {
469 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: crazy base64 length %d > %u", __FUNCTION__, dlen, len);
470 yutakapon 5545 goto error;
471     }
472    
473     buffer_consume_end(copy_consumed, len - dlen);
474     if (buffer_remain_len(copy_consumed) < sizeof(AUTH_MAGIC) ||
475     memcmp(buffer_tail_ptr(copy_consumed), AUTH_MAGIC, sizeof(AUTH_MAGIC))) {
476 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: bad magic", __FUNCTION__);
477 yutakapon 5545 goto error;
478     }
479     buffer_consume(copy_consumed, sizeof(AUTH_MAGIC));
480    
481     /*
482     * �f�R�[�h�����f�[�^�����������B
483     */
484     // �������A���S���Y�������O
485     ciphername = buffer_get_string_msg(copy_consumed, NULL);
486 doda 7002 cipher = get_cipher_by_name(ciphername);
487 doda 7005 if (cipher == NULL && strcmp(ciphername, "none") != 0) {
488 doda 6808 logprintf(LOG_LEVEL_ERROR, "%s: unknown cipher name", __FUNCTION__);
489 yutakapon 5545 goto error;
490     }
491 maya 5768 // �p�X�t���[�Y���`�F�b�N�B�������� none �����������������p�X���[�h���F�������B
492     if ((passphrase == NULL || strlen(passphrase) == 0) &&
493     strcmp(ciphername, "none") != 0) {
494 yutakapon 5545 /* passphrase required */
495     goto error;
496     }
497    
498     kdfname = buffer_get_string_msg(copy_consumed, NULL);
499 maya 5768 if (kdfname == NULL ||
500     (!strcmp(kdfname, "none") && !strcmp(kdfname, KDFNAME))) {
501 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: unknown kdf name", __FUNCTION__ );
502 yutakapon 5545 goto error;
503     }
504 maya 5768 if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) {
505 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: cipher %s requires kdf", __FUNCTION__, ciphername);
506 maya 5768 goto error;
507     }
508 yutakapon 5545
509     /* kdf options */
510     kdfp = buffer_get_string_msg(copy_consumed, &klen);
511     if (kdfp == NULL) {
512 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: kdf options not set", __FUNCTION__);
513 yutakapon 5545 goto error;
514     }
515     if (klen > 0) {
516     if ((cp = buffer_append_space(kdf, klen)) == NULL) {
517 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: kdf alloc failed", __FUNCTION__);
518 yutakapon 5545 goto error;
519     }
520     memcpy(cp, kdfp, klen);
521     }
522    
523     /* number of keys */
524     if (buffer_get_int_ret(&nkeys, copy_consumed) < 0) {
525 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: key counter missing", __FUNCTION__);
526 yutakapon 5545 goto error;
527     }
528     if (nkeys != 1) {
529 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: only one key supported", __FUNCTION__);
530 yutakapon 5545 goto error;
531     }
532    
533     /* pubkey */
534     cp = buffer_get_string_msg(copy_consumed, &len);
535     if (cp == NULL) {
536 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: pubkey not found", __FUNCTION__);
537 yutakapon 5545 goto error;
538     }
539     free(cp); /* XXX check pubkey against decrypted private key */
540    
541     /* size of encrypted key blob */
542     len = buffer_get_int(copy_consumed);
543 doda 7002 blocksize = get_cipher_block_size(cipher);
544 yutakapon 5545 authlen = 0; // TODO: ����������������
545     if (len < blocksize) {
546 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: encrypted data too small", __FUNCTION__);
547 yutakapon 5545 goto error;
548     }
549     if (len % blocksize) {
550 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: length not multiple of blocksize", __FUNCTION__);
551 yutakapon 5545 goto error;
552     }
553    
554     /* setup key */
555 doda 7002 keylen = get_cipher_key_len(cipher);
556 yutakapon 5545 ivlen = blocksize;
557     key = calloc(1, keylen + ivlen);
558     if (!strcmp(kdfname, KDFNAME)) {
559     salt = buffer_get_string_msg(kdf, &slen);
560     if (salt == NULL) {
561 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: salt not set", __FUNCTION__);
562 yutakapon 5545 goto error;
563     }
564     rounds = buffer_get_int(kdf);
565     // TODO: error check
566     if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen,
567     key, keylen + ivlen, rounds) < 0) {
568 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: bcrypt_pbkdf failed", __FUNCTION__);
569 yutakapon 5545 goto error;
570     }
571     }
572    
573     // ������
574     cp = buffer_append_space(b, len);
575 nmaya 9255 cipher_init_SSH2(&cc, cipher, key, keylen, key + keylen, ivlen, CIPHER_DECRYPT, pvar);
576     ret = EVP_Cipher(cc->evp, cp, buffer_tail_ptr(copy_consumed), len);
577 yutakapon 8316 if (ret == 0) {
578 yutakapon 5545 goto error;
579     }
580     buffer_consume(copy_consumed, len);
581    
582     if (buffer_remain_len(copy_consumed) != 0) {
583 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: key blob has trailing data (len = %u)", __FUNCTION__,
584 doda 6808 buffer_remain_len(copy_consumed));
585 yutakapon 5545 goto error;
586     }
587    
588     /* check bytes */
589     if (buffer_get_int_ret(&check1, b) < 0 ||
590     buffer_get_int_ret(&check2, b) < 0) {
591 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: check bytes missing", __FUNCTION__);
592 yutakapon 5545 goto error;
593     }
594     if (check1 != check2) {
595 zmatsuo 7536 logprintf(LOG_LEVEL_VERBOSE, "%s: decrypt failed: 0x%08x != 0x%08x", __FUNCTION__,
596 doda 6808 check1, check2);
597 yutakapon 5545 goto error;
598     }
599    
600     keyfmt = key_private_deserialize(b);
601     if (keyfmt == NULL)
602     goto error;
603    
604     /* comment */
605     comment = buffer_get_string_msg(b, NULL);
606    
607     i = 0;
608     while (buffer_remain_len(b)) {
609     if (buffer_get_char_ret(&pad, b) == -1 ||
610     pad != (++i & 0xff)) {
611 zmatsuo 7536 logprintf(LOG_LEVEL_ERROR, "%s: bad padding", __FUNCTION__);
612 yutakapon 5545 key_free(keyfmt);
613     keyfmt = NULL;
614     goto error;
615     }
616     }
617    
618     /* success */
619     keyfmt->bcrypt_kdf = 1;
620    
621     error:
622     buffer_free(blob);
623     buffer_free(b);
624     buffer_free(kdf);
625     buffer_free(encoded);
626     buffer_free(copy_consumed);
627 nmaya 9255 cipher_free_SSH2(cc);
628 yutakapon 5545
629     free(ciphername);
630     free(kdfname);
631     free(kdfp);
632     free(key);
633     free(salt);
634     free(comment);
635    
636 maya 5767 // KDF ������������
637 yutakapon 5545 if (keyfmt == NULL) {
638     fseek(fp, 0, SEEK_SET);
639    
640     } else {
641     fclose(fp);
642    
643     }
644    
645     return (keyfmt);
646     }
647    
648    
649 maya 5056 // OpenSSL format
650 maya 4307 Key *read_SSH2_private_key(PTInstVar pvar,
651 maya 5056 FILE * fp,
652 maya 4307 char * passphrase,
653     BOOL * invalid_passphrase,
654     BOOL is_auto_login,
655     char *errmsg,
656     int errmsg_len)
657 maya 3227 {
658 maya 4307 Key *result = NULL;
659 maya 3227 EVP_PKEY *pk = NULL;
660     unsigned long err = 0;
661 yutakapon 8316 int pk_type;
662 maya 3227
663     OpenSSL_add_all_algorithms();
664     ERR_load_crypto_strings();
665     //seed_prng();
666    
667 yutakapon 5545 result = read_SSH2_private2_key(pvar, fp, passphrase, invalid_passphrase, is_auto_login, errmsg, errmsg_len);
668     if (result)
669     return (result);
670    
671 maya 4307 result = (Key *)malloc(sizeof(Key));
672 zmatsuo 10618 ZeroMemory(result, sizeof(Key));
673 maya 3227
674     // �t�@�C�������p�X�t���[�Y�����������������������B
675     pk = PEM_read_PrivateKey(fp, NULL, NULL, passphrase);
676     if (pk == NULL) {
677     err = ERR_get_error();
678     ERR_error_string_n(err, errmsg, errmsg_len);
679     *invalid_passphrase = TRUE;
680     goto error;
681     }
682    
683 yutakapon 8316 pk_type = EVP_PKEY_id(pk);
684     switch (pk_type) {
685 maya 4324 case EVP_PKEY_RSA: // RSA key
686 maya 4307 result->type = KEY_RSA;
687     result->rsa = EVP_PKEY_get1_RSA(pk);
688     result->dsa = NULL;
689 maya 4324 result->ecdsa = NULL;
690 maya 3227
691     // RSA�������������L���������i�^�C�~���O�U���������h���j
692 maya 4307 if (RSA_blinding_on(result->rsa, NULL) != 1) {
693 maya 3227 err = ERR_get_error();
694     ERR_error_string_n(err, errmsg, errmsg_len);
695     goto error;
696     }
697 maya 4324 break;
698 maya 3227
699 maya 4324 case EVP_PKEY_DSA: // DSA key
700 maya 4307 result->type = KEY_DSA;
701     result->rsa = NULL;
702     result->dsa = EVP_PKEY_get1_DSA(pk);
703 maya 4324 result->ecdsa = NULL;
704     break;
705 maya 3227
706 maya 4324 case EVP_PKEY_EC: // ECDSA key
707     result->rsa = NULL;
708     result->dsa = NULL;
709     result->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
710     {
711     const EC_GROUP *g = EC_KEY_get0_group(result->ecdsa);
712 maya 4327 result->type = nid_to_keytype(EC_GROUP_get_curve_name(g));
713     if (result->type == KEY_UNSPEC) {
714     goto error;
715 maya 4324 }
716     }
717     break;
718    
719     default:
720 maya 3227 goto error;
721 maya 4324 break;
722 maya 3227 }
723    
724     if (pk != NULL)
725     EVP_PKEY_free(pk);
726    
727     fclose(fp);
728     return (result);
729    
730     error:
731     if (pk != NULL)
732     EVP_PKEY_free(pk);
733    
734     if (result != NULL)
735 maya 4307 key_free(result);
736 maya 3227
737     if (fp != NULL)
738     fclose(fp);
739    
740     return (NULL);
741     }
742 maya 5056
743     // PuTTY format
744     /*
745     * PuTTY-User-Key-File-2: ssh-dss
746     * Encryption: aes256-cbc
747     * Comment: imported-openssh-key
748     * Public-Lines: 10
749     * Base64...
750     * Private-Lines: 1
751     * Base64...
752     * Private-MAC: Base16...
753 zmatsuo 10618 *
754 maya 5056 * for "ssh-rsa", it will be composed of
755     *
756     * "Public-Lines: " plus a number N.
757     *
758     * string "ssh-rsa"
759     * mpint exponent
760     * mpint modulus
761     *
762     * "Private-Lines: " plus a number N,
763     *
764     * mpint private_exponent
765     * mpint p (the larger of the two primes)
766     * mpint q (the smaller prime)
767     * mpint iqmp (the inverse of q modulo p)
768     * data padding (to reach a multiple of the cipher block size)
769     *
770     * for "ssh-dss", it will be composed of
771     *
772     * "Public-Lines: " plus a number N.
773     *
774     * string "ssh-rsa"
775     * mpint p
776     * mpint q
777     * mpint g
778     * mpint y
779     *
780     * "Private-Lines: " plus a number N,
781     *
782     * mpint x (the private key parameter)
783     *
784 maya 6828 * for "ecdsa-sha2-nistp256" or
785     * "ecdsa-sha2-nistp384" or
786     * "ecdsa-sha2-nistp521", it will be composed of
787     *
788     * "Public-Lines: " plus a number N.
789     *
790     * string "ecdsa-sha2-[identifier]" ("ecdsa-sha2-nistp256" or
791     * "ecdsa-sha2-nistp384" or
792     * "ecdsa-sha2-nistp521")
793     * string [identifier] ("nistp256" or "nistp384" or "nistp521")
794     * string Q (EC_POINT)
795     *
796     * "Private-Lines: " plus a number N,
797     *
798     * mpint n
799     *
800     * for "ssh-ed25519", it will be composed of
801     *
802     * "Public-Lines: " plus a number N.
803     *
804     * string "ssh-ed25519"
805     * string key
806     *
807     * "Private-Lines: " plus a number N,
808     *
809     * string key
810     *
811 maya 5056 * "Private-MAC: " plus a hex, HMAC-SHA-1 of:
812     *
813     * string name of algorithm ("ssh-dss", "ssh-rsa")
814     * string encryption type
815     * string comment
816     * string public-blob
817     * string private-plaintext
818     */
819     Key *read_SSH2_PuTTY_private_key(PTInstVar pvar,
820     FILE * fp,
821     char * passphrase,
822     BOOL * invalid_passphrase,
823     BOOL is_auto_login,
824     char *errmsg,
825     int errmsg_len)
826     {
827 nmaya 9258 char header[40], *b = NULL, *encryption = NULL, *comment = NULL, *mac = NULL;
828 maya 5056 Key *result = NULL;
829 nmaya 9258 buffer_t *public_blob = NULL, *private_blob = NULL, *cipher_mac_keys_blob = NULL;
830     unsigned char *cipherkey = NULL, *cipheriv = NULL, *mackey = NULL;
831     unsigned int cipherkey_len, cipheriv_len, mackey_len;
832     buffer_t *passphrase_salt = buffer_init();
833     const struct ssh2cipher *ciphertype;
834     int lines, len;
835     ppk_argon2_parameters params;
836     unsigned fmt_version = 0;
837 maya 5056
838     result = (Key *)malloc(sizeof(Key));
839 zmatsuo 10618 ZeroMemory(result, sizeof(Key));
840 maya 5056 result->type = KEY_NONE;
841     result->rsa = NULL;
842     result->dsa = NULL;
843     result->ecdsa = NULL;
844    
845 nmaya 9258 // version and algorithm-name
846     if (!ppk_read_header(fp, header)) {
847     strncpy_s(errmsg, errmsg_len, "no header line found in key file", _TRUNCATE);
848     goto error;
849     }
850     if (0 == strcmp(header, "PuTTY-User-Key-File-3")) {
851     fmt_version = 3;
852     }
853     else if (0 == strcmp(header, "PuTTY-User-Key-File-2")) {
854     fmt_version = 2;
855     }
856     else if (0 == strcmp(header, "PuTTY-User-Key-File-1")) {
857     strncpy_s(errmsg, errmsg_len, "PuTTY key format too old", _TRUNCATE);
858     goto error;
859     }
860     else if (0 == strncmp(header, "PuTTY-User-Key-File-", 20)) {
861     strncpy_s(errmsg, errmsg_len, "PuTTY key format too new", _TRUNCATE);
862     goto error;
863     }
864     if ((b = ppk_read_body(fp)) == NULL) {
865     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
866     goto error;
867     }
868     if (0 == strcmp(b, "ssh-dss")) {
869     result->type = KEY_DSA;
870     }
871     else if (0 == strcmp(b, "ssh-rsa")) {
872     result->type = KEY_RSA;
873     }
874     else if (0 == strcmp(b, "ecdsa-sha2-nistp256")) {
875     result->type = KEY_ECDSA256;
876     }
877     else if (0 == strcmp(b, "ecdsa-sha2-nistp384")) {
878     result->type = KEY_ECDSA384;
879     }
880     else if (0 == strcmp(b, "ecdsa-sha2-nistp521")) {
881     result->type = KEY_ECDSA521;
882     }
883     else if (0 == strcmp(b, "ssh-ed25519")) {
884     result->type = KEY_ED25519;
885     }
886     else {
887     strncpy_s(errmsg, errmsg_len, "unsupported key algorithm", _TRUNCATE);
888     free(b);
889     goto error;
890     }
891     free(b);
892 maya 5056
893 nmaya 9258 // encryption-type
894     if (!ppk_read_header(fp, header) || 0 != strcmp(header, "Encryption")) {
895     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
896     goto error;
897     }
898     if ((encryption = ppk_read_body(fp)) == NULL) {
899     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
900     goto error;
901     }
902     if (strcmp(encryption, "aes256-cbc") == 0) {
903     ciphertype = get_cipher_by_name(encryption);
904     }
905     else if (strcmp(encryption, "none") == 0) {
906     ciphertype = get_cipher_by_name(encryption);
907     }
908     else {
909     strncpy_s(errmsg, errmsg_len, "unknown encryption type", _TRUNCATE);
910     goto error;
911     }
912    
913     // key-comment-string
914     if (!ppk_read_header(fp, header) || 0 != strcmp(header, "Comment")) {
915     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
916     goto error;
917     }
918     if ((comment = ppk_read_body(fp)) == NULL) {
919     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
920     goto error;
921     }
922    
923     // public key
924     if (!ppk_read_header(fp, header) || 0 != strcmp(header, "Public-Lines")) {
925     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
926     goto error;
927     }
928     if ((b = ppk_read_body(fp)) == NULL) {
929     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
930     free(b);
931     goto error;
932     }
933     lines = atoi(b);
934     free(b);
935     public_blob = buffer_init();
936     if (!ppk_read_blob(fp, lines, public_blob)) {
937     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
938     goto error;
939     }
940    
941     if (fmt_version >= 3 && ciphertype->key_len != 0) {
942     size_t i;
943    
944     // argon2-flavour
945     if (!ppk_read_header(fp, header) || 0 != strcmp(header, "Key-Derivation")) {
946     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
947     goto error;
948 maya 5056 }
949 nmaya 9258 if ((b = ppk_read_body(fp)) == NULL) {
950     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
951     free(b);
952     goto error;
953 maya 5056 }
954 nmaya 9258 if (!strcmp(b, "Argon2d")) {
955     params.type = Argon2_d;
956 maya 5056 }
957 nmaya 9258 else if (!strcmp(b, "Argon2i")) {
958     params.type = Argon2_i;
959 maya 5056 }
960 nmaya 9258 else if (!strcmp(b, "Argon2id")) {
961     params.type = Argon2_id;
962     }
963     else {
964     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
965     free(b);
966 maya 5056 goto error;
967     }
968 nmaya 9258 free(b);
969    
970     if (!ppk_read_header(fp, header) || 0 != strcmp(header, "Argon2-Memory")) {
971     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
972     goto error;
973 maya 5056 }
974 nmaya 9258 if ((b = ppk_read_body(fp)) == NULL) {
975     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
976     free(b);
977     goto error;
978 maya 5056 }
979 nmaya 9258 if (!str_to_uint32_t(b, &params.argon2_mem)) {
980     free(b);
981 maya 5056 goto error;
982     }
983 nmaya 9258 free(b);
984 maya 5056
985 nmaya 9258 if (!ppk_read_header(fp, header) || 0 != strcmp(header, "Argon2-Passes")) {
986     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
987     goto error;
988     }
989     if ((b = ppk_read_body(fp)) == NULL) {
990     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
991     free(b);
992     goto error;
993     }
994     if (!str_to_uint32_t(b, &params.argon2_passes)) {
995     free(b);
996     goto error;
997     }
998     free(b);
999 maya 5056
1000 nmaya 9258 if (!ppk_read_header(fp, header) || 0 != strcmp(header, "Argon2-Parallelism")) {
1001     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
1002 yutakapon 8316 goto error;
1003     }
1004 nmaya 9258 if ((b = ppk_read_body(fp)) == NULL) {
1005     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
1006     free(b);
1007     goto error;
1008     }
1009     if (!str_to_uint32_t(b, &params.argon2_parallelism)) {
1010     free(b);
1011     goto error;
1012     }
1013     free(b);
1014 maya 5056
1015 nmaya 9258 if (!ppk_read_header(fp, header) || 0 != strcmp(header, "Argon2-Salt")) {
1016     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
1017 yutakapon 8316 goto error;
1018     }
1019 nmaya 9258 if ((b = ppk_read_body(fp)) == NULL) {
1020     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
1021     free(b);
1022     goto error;
1023     }
1024     for (i = 0; b[i]; i += 2) {
1025     if (isxdigit((unsigned char)b[i]) && b[i+1] &&
1026     isxdigit((unsigned char)b[i+1])) {
1027     char s[3];
1028     s[0] = b[i];
1029     s[1] = b[i+1];
1030     s[2] = '\0';
1031     buffer_put_char(passphrase_salt, strtoul(s, NULL, 16));
1032     }
1033     else {
1034     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
1035     free(b);
1036     goto error;
1037     }
1038     }
1039     params.salt = buffer_ptr(passphrase_salt);
1040     params.saltlen = buffer_len(passphrase_salt);
1041     free(b);
1042     }
1043 maya 5056
1044 nmaya 9258 // private key
1045     if (!ppk_read_header(fp, header) || 0 != strcmp(header, "Private-Lines")) {
1046     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
1047     goto error;
1048     }
1049     if ((b = ppk_read_body(fp)) == NULL) {
1050     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
1051     free(b);
1052     goto error;
1053     }
1054     lines = atoi(b);
1055     free(b);
1056     private_blob = buffer_init();
1057     if (!ppk_read_blob(fp, lines, private_blob)) {
1058     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
1059     goto error;
1060     }
1061 yutakapon 8316
1062 nmaya 9258 // hex-mac-data
1063     if (!ppk_read_header(fp, header) || 0 != strcmp(header, "Private-MAC")) {
1064     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
1065     goto error;
1066     }
1067     if ((mac = ppk_read_body(fp)) == NULL) {
1068     strncpy_s(errmsg, errmsg_len, "file format error", _TRUNCATE);
1069     goto error;
1070     }
1071 yutakapon 8316
1072 nmaya 9258 fclose(fp);
1073 yutakapon 8316
1074 nmaya 9258 if (result->type == KEY_NONE || strlen(encryption) == 0 || buffer_len(public_blob) == 0 || buffer_len(private_blob) == 0) {
1075     strncpy_s(errmsg, errmsg_len, "key file format error", _TRUNCATE);
1076     goto error;
1077     }
1078 maya 5056
1079 nmaya 9258 // derive key, iv, mackey
1080     cipher_mac_keys_blob = buffer_init();
1081     ssh2_ppk_derive_keys(fmt_version, ciphertype,
1082     passphrase,
1083     cipher_mac_keys_blob,
1084     &cipherkey, &cipherkey_len,
1085     &cipheriv, &cipheriv_len,
1086     &mackey, &mackey_len,
1087     &params);
1088    
1089     // decrypt priate key with aes256-cbc
1090     if (strcmp(encryption, "aes256-cbc") == 0) {
1091     struct sshcipher_ctx *cc = NULL;
1092     char *decrypted = NULL;
1093     int ret;
1094    
1095 maya 5056 // decrypt
1096 nmaya 9258 ciphertype = get_cipher_by_name("aes256-cbc");
1097     cipher_init_SSH2(&cc, ciphertype, cipherkey, 32, cipheriv, 16, CIPHER_DECRYPT, pvar);
1098     len = buffer_len(private_blob);
1099 maya 5056 decrypted = (char *)malloc(len);
1100 nmaya 9258 ret = EVP_Cipher(cc->evp, decrypted, private_blob->buf, len);
1101 yutakapon 8316 if (ret == 0) {
1102 maya 5056 strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE);
1103     free(decrypted);
1104 nmaya 9255 cipher_free_SSH2(cc);
1105 maya 5056 goto error;
1106     }
1107 nmaya 9258 buffer_clear(private_blob);
1108     buffer_append(private_blob, decrypted, len);
1109 maya 5056 free(decrypted);
1110 nmaya 9255 cipher_free_SSH2(cc);
1111 maya 5056 }
1112    
1113     // verity MAC
1114     {
1115 nmaya 9258 unsigned char binary[32];
1116     char realmac[sizeof(binary) * 2 + 1];
1117     const EVP_MD *md;
1118     buffer_t *macdata;
1119 maya 5056 int i;
1120    
1121 nmaya 9258 macdata = buffer_init();
1122     buffer_put_cstring(macdata, get_ssh2_hostkey_type_name(result->type));
1123     buffer_put_cstring(macdata, encryption);
1124     buffer_put_cstring(macdata, comment);
1125     buffer_put_string(macdata, public_blob->buf, public_blob->len);
1126     buffer_put_string(macdata, private_blob->buf, private_blob->len);
1127 yutakapon 8316
1128 nmaya 9258 if (fmt_version == 2) {
1129     md = EVP_sha1();
1130 maya 5056 }
1131 nmaya 9258 else {
1132     md = EVP_sha256();
1133 maya 5056 }
1134 nmaya 9258 mac_simple(md, (unsigned char *)mackey, mackey_len, macdata->buf, macdata->len, binary);
1135 maya 5056
1136 nmaya 9258 buffer_free(macdata);
1137 maya 5056
1138 nmaya 9258 for (i=0; i<EVP_MD_size(md); i++) {
1139     sprintf(realmac + 2*i, "%02x", binary[i]);
1140 maya 5056 }
1141    
1142 nmaya 9258 if (strcmp(mac, realmac) != 0) {
1143     if (ciphertype->key_len > 0) {
1144     strncpy_s(errmsg, errmsg_len, "wrong passphrase", _TRUNCATE);
1145     *invalid_passphrase = TRUE;
1146     goto error;
1147     }
1148     else {
1149     strncpy_s(errmsg, errmsg_len, "MAC verify failed", _TRUNCATE);
1150     goto error;
1151     }
1152 maya 5056 }
1153     }
1154    
1155     switch (result->type) {
1156     case KEY_RSA:
1157     {
1158     char *pubkey_type, *pub, *pri;
1159 yutakapon 8316 BIGNUM *e, *n, *d, *iqmp, *p, *q;
1160    
1161 nmaya 9258 pub = public_blob->buf;
1162     pri = private_blob->buf;
1163 maya 5056 pubkey_type = buffer_get_string(&pub, NULL);
1164     if (strcmp(pubkey_type, "ssh-rsa") != 0) {
1165     strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
1166     free(pubkey_type);
1167     goto error;
1168     }
1169     free(pubkey_type);
1170    
1171     result->rsa = RSA_new();
1172     if (result->rsa == NULL) {
1173     strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1174     goto error;
1175     }
1176 yutakapon 8316 e = BN_new();
1177     n = BN_new();
1178     d = BN_new();
1179     RSA_set0_key(result->rsa, n, e, d);
1180     p = BN_new();
1181     q = BN_new();
1182     RSA_set0_factors(result->rsa, p, q);
1183     iqmp = BN_new();
1184     RSA_set0_crt_params(result->rsa, NULL, NULL, iqmp);
1185     if (e == NULL ||
1186     n == NULL ||
1187     d == NULL ||
1188     p == NULL ||
1189     q == NULL ||
1190     iqmp == NULL) {
1191 maya 5056 strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1192     goto error;
1193     }
1194    
1195 yutakapon 8316 buffer_get_bignum2(&pub, e);
1196     buffer_get_bignum2(&pub, n);
1197 maya 5056
1198 yutakapon 8316 buffer_get_bignum2(&pri, d);
1199     buffer_get_bignum2(&pri, p);
1200     buffer_get_bignum2(&pri, q);
1201     buffer_get_bignum2(&pri, iqmp);
1202 maya 5056
1203     break;
1204     }
1205     case KEY_DSA:
1206     {
1207     char *pubkey_type, *pub, *pri;
1208 yutakapon 8316 BIGNUM *p, *q, *g, *pub_key, *priv_key;
1209    
1210 nmaya 9258 pub = public_blob->buf;
1211     pri = private_blob->buf;
1212 maya 5056 pubkey_type = buffer_get_string(&pub, NULL);
1213     if (strcmp(pubkey_type, "ssh-dss") != 0) {
1214     strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
1215     free(pubkey_type);
1216     goto error;
1217     }
1218     free(pubkey_type);
1219    
1220     result->dsa = DSA_new();
1221     if (result->dsa == NULL) {
1222     strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1223     goto error;
1224     }
1225 yutakapon 8316 p = BN_new();
1226     q = BN_new();
1227     g = BN_new();
1228     DSA_set0_pqg(result->dsa, p, q, g);
1229     pub_key = BN_new();
1230     priv_key = BN_new();
1231     DSA_set0_key(result->dsa, pub_key, priv_key);
1232     if (p == NULL ||
1233     q == NULL ||
1234     g == NULL ||
1235     pub_key == NULL ||
1236     priv_key == NULL) {
1237 maya 5056 strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1238     goto error;
1239     }
1240    
1241 yutakapon 8316 buffer_get_bignum2(&pub, p);
1242     buffer_get_bignum2(&pub, q);
1243     buffer_get_bignum2(&pub, g);
1244     buffer_get_bignum2(&pub, pub_key);
1245 maya 5056
1246 yutakapon 8316 buffer_get_bignum2(&pri, priv_key);
1247 maya 5056
1248     break;
1249     }
1250 maya 6818 case KEY_ECDSA256:
1251     case KEY_ECDSA384:
1252     case KEY_ECDSA521:
1253     {
1254     char *pubkey_type, *pub, *pri;
1255     int success = 0;
1256     unsigned int nid;
1257     char *curve = NULL;
1258     ssh_keytype skt;
1259     BIGNUM *exponent = NULL;
1260     EC_POINT *q = NULL;
1261    
1262 nmaya 9258 pub = public_blob->buf;
1263     pri = private_blob->buf;
1264 maya 6818 pubkey_type = buffer_get_string(&pub, NULL);
1265     if ((result->type == KEY_ECDSA256 && strcmp(pubkey_type, "ecdsa-sha2-nistp256") != 0) ||
1266     (result->type == KEY_ECDSA384 && strcmp(pubkey_type, "ecdsa-sha2-nistp384") != 0) ||
1267     (result->type == KEY_ECDSA521 && strcmp(pubkey_type, "ecdsa-sha2-nistp521") != 0)) {
1268     strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
1269     free(pubkey_type);
1270     goto error;
1271     }
1272     free(pubkey_type);
1273    
1274     nid = keytype_to_cipher_nid(result->type);
1275     curve = buffer_get_string(&pub, NULL);
1276     skt = key_curve_name_to_keytype(curve);
1277     if (nid != keytype_to_cipher_nid(skt))
1278     goto ecdsa_error;
1279    
1280     if ((result->ecdsa = EC_KEY_new_by_curve_name(nid)) == NULL)
1281     goto ecdsa_error;
1282     if ((q = EC_POINT_new(EC_KEY_get0_group(result->ecdsa))) == NULL)
1283     goto ecdsa_error;
1284     if ((exponent = BN_new()) == NULL)
1285     goto ecdsa_error;
1286    
1287     buffer_get_ecpoint(&pub, EC_KEY_get0_group(result->ecdsa), q);
1288     buffer_get_bignum2(&pri, exponent);
1289     if (EC_KEY_set_public_key(result->ecdsa, q) != 1)
1290     goto ecdsa_error;
1291     if (EC_KEY_set_private_key(result->ecdsa, exponent) != 1)
1292     goto ecdsa_error;
1293     if (key_ec_validate_public(EC_KEY_get0_group(result->ecdsa),
1294     EC_KEY_get0_public_key(result->ecdsa)) != 0)
1295     goto ecdsa_error;
1296     if (key_ec_validate_private(result->ecdsa) != 0)
1297     goto ecdsa_error;
1298    
1299     success = 1;
1300    
1301     ecdsa_error:
1302     free(curve);
1303     if (exponent)
1304     BN_clear_free(exponent);
1305     if (q)
1306     EC_POINT_free(q);
1307     if (success == 0)
1308     goto error;
1309    
1310     break;
1311     }
1312     case KEY_ED25519:
1313     {
1314     char *pubkey_type, *pub, *pri;
1315     unsigned int pklen, sklen;
1316     char *sk;
1317 nmaya 9258 pub = public_blob->buf;
1318     pri = private_blob->buf;
1319 maya 6818 pubkey_type = buffer_get_string(&pub, NULL);
1320     if (strcmp(pubkey_type, "ssh-ed25519") != 0) {
1321     strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
1322     free(pubkey_type);
1323     goto error;
1324     }
1325     free(pubkey_type);
1326    
1327     result->ed25519_pk = buffer_get_string(&pub, &pklen);
1328     sk = buffer_get_string(&pri, &sklen);
1329     result->ed25519_sk = malloc(pklen + sklen + 1);
1330     memcpy(result->ed25519_sk, sk, sklen);
1331     memcpy(result->ed25519_sk + sklen, result->ed25519_pk, pklen);
1332     result->ed25519_sk[sklen + pklen] = '\0';
1333     free(sk);
1334    
1335     if (pklen != ED25519_PK_SZ)
1336     goto error;
1337     if (sklen + pklen != ED25519_SK_SZ)
1338     goto error;
1339    
1340     break;
1341     }
1342 maya 5056 default:
1343     strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
1344     goto error;
1345     break;
1346     }
1347    
1348 nmaya 9258 if (encryption != NULL)
1349     free(encryption);
1350 maya 5056 if (comment != NULL)
1351     free(comment);
1352 nmaya 9258 if (mac != NULL)
1353     free(mac);
1354     if (public_blob != NULL)
1355     buffer_free(public_blob);
1356     if (private_blob != NULL)
1357     buffer_free(private_blob);
1358     if (cipher_mac_keys_blob != NULL)
1359     buffer_free(cipher_mac_keys_blob);
1360     if (passphrase_salt != NULL)
1361     buffer_free(passphrase_salt);
1362 maya 5056
1363     return (result);
1364    
1365     error:
1366     if (result != NULL)
1367     key_free(result);
1368     if (fp != NULL)
1369     fclose(fp);
1370 nmaya 9258 if (encryption != NULL)
1371     free(encryption);
1372 maya 5056 if (comment != NULL)
1373     free(comment);
1374 nmaya 9258 if (mac != NULL)
1375     free(mac);
1376     if (public_blob != NULL)
1377     buffer_free(public_blob);
1378     if (private_blob != NULL)
1379     buffer_free(private_blob);
1380     if (cipher_mac_keys_blob != NULL)
1381     buffer_free(cipher_mac_keys_blob);
1382     if (passphrase_salt != NULL)
1383     buffer_free(passphrase_salt);
1384 maya 5056
1385     return (NULL);
1386     }
1387    
1388     // SECSH(ssh.com) format
1389     /*
1390     * Code to read ssh.com private keys.
1391     *
1392     * "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
1393     * "Comment:..."
1394     * "Base64..."
1395     * "---- END SSH2 ENCRYPTED PRIVATE KEY ----"
1396     *
1397     * Body of key data
1398     *
1399     * - uint32 0x3f6ff9eb (magic number)
1400     * - uint32 size (total blob size)
1401     * - string key-type (see below)
1402     * - string cipher-type (tells you if key is encrypted)
1403     * - string encrypted-blob
1404     *
1405     * The key type strings are ghastly. The RSA key I looked at had a type string of
1406 zmatsuo 10618 *
1407 maya 5056 * `if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}'
1408     * `dl-modp{sign{dsa-nist-sha1},dh{plain}}'
1409 maya 6828 * `ec-modp'
1410 maya 5056 *
1411     * The encryption. The cipher-type string appears to be either
1412     *
1413     * `none'
1414     * `3des-cbc'
1415     *
1416     * The payload blob, for an RSA key, contains:
1417     * - mpint e
1418     * - mpint d
1419     * - mpint n (yes, the public and private stuff is intermixed)
1420     * - mpint u (presumably inverse of p mod q)
1421     * - mpint p (p is the smaller prime)
1422     * - mpint q (q is the larger)
1423 zmatsuo 10618 *
1424 maya 5056 * For a DSA key, the payload blob contains:
1425     * - uint32 0
1426     * - mpint p
1427     * - mpint g
1428     * - mpint q
1429     * - mpint y
1430     * - mpint x
1431 maya 6828 *
1432     * For a ECDSA key, the payload blob contains:
1433     * - uint32 1
1434     * - string [identifier] ("nistp256" or "nistp384" or "nistp521")
1435     * - mpint n
1436 maya 5056 */
1437     Key *read_SSH2_SECSH_private_key(PTInstVar pvar,
1438     FILE * fp,
1439     char * passphrase,
1440     BOOL * invalid_passphrase,
1441     BOOL is_auto_login,
1442     char *errmsg,
1443     int errmsg_len)
1444     {
1445     Key *result = NULL;
1446     unsigned long err = 0;
1447 doda 6711 int i, len2;
1448     unsigned int len;
1449 maya 5056 int encflag;
1450     char *encname = NULL;
1451     buffer_t *blob = NULL, *blob2 = NULL;
1452 nmaya 9255 const struct ssh2cipher *cipher = NULL;
1453     struct sshcipher_ctx *cc = NULL;
1454 maya 5056
1455     result = (Key *)malloc(sizeof(Key));
1456 zmatsuo 10618 ZeroMemory(result, sizeof(Key));
1457 maya 5056 result->type = KEY_NONE;
1458     result->rsa = NULL;
1459     result->dsa = NULL;
1460     result->ecdsa = NULL;
1461    
1462     blob = buffer_init();
1463     blob2 = buffer_init();
1464    
1465     // parse keyfile & decode blob
1466     {
1467     char line[200], buf[100];
1468     BIO *bmem, *b64, *chain;
1469     int st = 0;
1470    
1471     b64 = BIO_new(BIO_f_base64());
1472     bmem = BIO_new(BIO_s_mem());
1473    
1474     while (fgets(line, sizeof(line), fp) != NULL) {
1475     if (strncmp(line, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----", strlen("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----")) == 0) {
1476     if (st == 0) {
1477     st = 1;
1478     continue;
1479     }
1480     else {
1481     break;
1482     }
1483     }
1484     else if (strncmp(line, "---- END SSH2 ENCRYPTED PRIVATE KEY ----", strlen("---- END SSH2 ENCRYPTED PRIVATE KEY ----")) == 0) {
1485     break;
1486     }
1487    
1488     if (st == 0) {
1489     continue;
1490     }
1491    
1492     if (strchr(line, ':') != NULL) {
1493     if (st == 1) {
1494     continue;
1495     }
1496     strncpy_s(errmsg, errmsg_len, "header found in body of key data", _TRUNCATE);
1497     BIO_free_all(bmem);
1498     goto error;
1499     }
1500     else if (st == 1) {
1501     st = 2;
1502     }
1503    
1504     BIO_write(bmem, line, strlen(line));
1505     }
1506    
1507     BIO_flush(bmem);
1508     chain = BIO_push(b64, bmem);
1509     BIO_set_mem_eof_return(chain, 0);
1510     while ((len2 = BIO_read(chain, buf, sizeof(buf))) > 0) {
1511     buffer_append(blob, buf, len2);
1512     }
1513     BIO_free_all(chain);
1514     buffer_rewind(blob);
1515     }
1516    
1517     if (blob->len < 8) {
1518     strncpy_s(errmsg, errmsg_len, "key body not present", _TRUNCATE);
1519     goto error;
1520     }
1521     i = buffer_get_int(blob);
1522     if (i != 0x3f6ff9eb) {
1523     strncpy_s(errmsg, errmsg_len, "magic number error", _TRUNCATE);
1524     goto error;
1525     }
1526     len = buffer_get_int(blob);
1527 doda 6711 if (len == 0 || len > blob->len) {
1528 maya 5056 strncpy_s(errmsg, errmsg_len, "body size error", _TRUNCATE);
1529     goto error;
1530     }
1531    
1532     len = buffer_get_int(blob);
1533     if (strncmp(blob->buf + blob->offset, "if-modn{sign{rsa", strlen("if-modn{sign{rsa") - 1) == 0) {
1534     result->type = KEY_RSA;
1535     }
1536     else if (strncmp(blob->buf + blob->offset, "dl-modp{sign{dsa", strlen("dl-modp{sign{dsa") - 1) == 0) {
1537     result->type = KEY_DSA;
1538     }
1539 maya 6825 else if (strncmp(blob->buf + blob->offset, "ec-modp", strlen("ec-modp") - 1) == 0) {
1540     result->type = KEY_ECDSA256;
1541     }
1542 maya 5056 else {
1543     strncpy_s(errmsg, errmsg_len, "unknown key type", _TRUNCATE);
1544     goto error;
1545     }
1546     buffer_consume(blob, len);
1547    
1548     len = buffer_get_int(blob);
1549     encname = (char *)malloc(len + 1);
1550     strncpy_s(encname, len + 1, blob->buf + blob->offset, _TRUNCATE);
1551     if (strcmp(encname, "3des-cbc") == 0) {
1552     encflag = 1;
1553     }
1554     else if (strcmp(encname, "none") == 0) {
1555     encflag = 0;
1556     }
1557     else {
1558     strncpy_s(errmsg, errmsg_len, "unknown encryption type", _TRUNCATE);
1559     goto error;
1560     }
1561     buffer_consume(blob, len);
1562    
1563     len = buffer_get_int(blob);
1564     if (len > (blob->len - blob->offset)) {
1565     strncpy_s(errmsg, errmsg_len, "body size error", _TRUNCATE);
1566     goto error;
1567     }
1568    
1569     // decrypt privkey with 3des-cbc
1570     if (strcmp(encname, "3des-cbc") == 0) {
1571     MD5_CTX md;
1572     unsigned char key[32], iv[16];
1573 yutakapon 8316 EVP_CIPHER_CTX *cipher_ctx = NULL;
1574 maya 5056 char *decrypted = NULL;
1575 yutakapon 8316 int ret;
1576 maya 5056
1577 yutakapon 8316 cipher_ctx = EVP_CIPHER_CTX_new();
1578     if (cipher_ctx == NULL) {
1579     strncpy_s(errmsg, errmsg_len, "Out of memory: EVP_CIPHER_CTX_new()", _TRUNCATE);
1580     goto error;
1581     }
1582    
1583 maya 5056 MD5_Init(&md);
1584     MD5_Update(&md, passphrase, strlen(passphrase));
1585     MD5_Final(key, &md);
1586    
1587     MD5_Init(&md);
1588     MD5_Update(&md, passphrase, strlen(passphrase));
1589     MD5_Update(&md, key, 16);
1590     MD5_Final(key + 16, &md);
1591    
1592     memset(iv, 0, sizeof(iv));
1593    
1594     // decrypt
1595 nmaya 9255 cipher = get_cipher_by_name("3des-cbc");
1596     cipher_init_SSH2(&cc, cipher, key, 24, iv, 8, CIPHER_DECRYPT, pvar);
1597 maya 5056 decrypted = (char *)malloc(len);
1598 nmaya 9255 ret = EVP_Cipher(cc->evp, decrypted, blob->buf + blob->offset, len);
1599 yutakapon 8316 if (ret == 0) {
1600 maya 5056 strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE);
1601 nmaya 9255 cipher_free_SSH2(cc);
1602 maya 5056 goto error;
1603     }
1604     buffer_append(blob2, decrypted, len);
1605     free(decrypted);
1606 nmaya 9255 cipher_free_SSH2(cc);
1607 maya 5056
1608     *invalid_passphrase = TRUE;
1609     }
1610     else { // none
1611     buffer_append(blob2, blob->buf + blob->offset, len);
1612     }
1613     buffer_rewind(blob2);
1614    
1615     len = buffer_get_int(blob2);
1616     if (len <= 0 || len > (blob2->len - blob2->offset)) {
1617     strncpy_s(errmsg, errmsg_len, "blob size error", _TRUNCATE);
1618     goto error;
1619     }
1620    
1621     switch (result->type) {
1622     case KEY_RSA:
1623     {
1624 yutakapon 8316 BIGNUM *e, *n, *d, *iqmp, *p, *q;
1625    
1626 maya 5056 result->rsa = RSA_new();
1627     if (result->rsa == NULL) {
1628     strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1629     goto error;
1630     }
1631 yutakapon 8316 e = BN_new();
1632     n = BN_new();
1633     d = BN_new();
1634     RSA_set0_key(result->rsa, n, e, d);
1635     p = BN_new();
1636     q = BN_new();
1637     RSA_set0_factors(result->rsa, p, q);
1638     iqmp = BN_new();
1639     RSA_set0_crt_params(result->rsa, NULL, NULL, iqmp);
1640     if (e == NULL ||
1641     n == NULL ||
1642     d == NULL ||
1643     p == NULL ||
1644     q == NULL ||
1645     iqmp == NULL) {
1646 maya 5056 strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1647     goto error;
1648     }
1649    
1650 yutakapon 8316 buffer_get_bignum_SECSH(blob2, e);
1651     buffer_get_bignum_SECSH(blob2, d);
1652     buffer_get_bignum_SECSH(blob2, n);
1653     buffer_get_bignum_SECSH(blob2, iqmp);
1654     buffer_get_bignum_SECSH(blob2, p);
1655     buffer_get_bignum_SECSH(blob2, q);
1656 maya 5056
1657     break;
1658     }
1659     case KEY_DSA:
1660     {
1661     int param;
1662 yutakapon 8316 BIGNUM *p, *q, *g, *pub_key, *priv_key;
1663 maya 5056
1664     result->dsa = DSA_new();
1665     if (result->dsa == NULL) {
1666     strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1667     goto error;
1668     }
1669 yutakapon 8316 p = BN_new();
1670     q = BN_new();
1671     g = BN_new();
1672     DSA_set0_pqg(result->dsa, p, q, g);
1673     pub_key = BN_new();
1674     priv_key = BN_new();
1675     DSA_set0_key(result->dsa, pub_key, priv_key);
1676     if (p == NULL ||
1677     q == NULL ||
1678     g == NULL ||
1679     pub_key == NULL ||
1680     priv_key == NULL) {
1681 maya 5056 strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1682     goto error;
1683     }
1684    
1685     param = buffer_get_int(blob2);
1686     if (param != 0) {
1687     strncpy_s(errmsg, errmsg_len, "predefined DSA parameters not supported", _TRUNCATE);
1688     goto error;
1689     }
1690 yutakapon 8316 buffer_get_bignum_SECSH(blob2, p);
1691     buffer_get_bignum_SECSH(blob2, g);
1692     buffer_get_bignum_SECSH(blob2, q);
1693     buffer_get_bignum_SECSH(blob2, pub_key);
1694     buffer_get_bignum_SECSH(blob2, priv_key);
1695 maya 5056
1696     break;
1697     }
1698 maya 6825 case KEY_ECDSA256:
1699     {
1700     unsigned int dummy, nid;
1701     int success = 0;
1702     char *curve = NULL;
1703     BIGNUM *exponent = NULL;
1704     EC_POINT *q = NULL;
1705     BN_CTX *ctx = NULL;
1706    
1707     dummy = buffer_get_int(blob2);
1708     curve = buffer_get_string_msg(blob2, NULL);
1709    
1710     if (strncmp(curve, "nistp256", strlen("nistp256")) == 0) {
1711     result->type = KEY_ECDSA256;
1712     }
1713     else if (strncmp(curve, "nistp384", strlen("nistp384")) == 0) {
1714     result->type = KEY_ECDSA384;
1715     }
1716     else if (strncmp(curve, "nistp521", strlen("nistp521")) == 0) {
1717     result->type = KEY_ECDSA521;
1718     }
1719     else {
1720     strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
1721     goto error;
1722     }
1723    
1724     nid = keytype_to_cipher_nid(result->type);
1725     if ((result->ecdsa = EC_KEY_new_by_curve_name(nid)) == NULL)
1726     goto ecdsa_error;
1727     if ((q = EC_POINT_new(EC_KEY_get0_group(result->ecdsa))) == NULL)
1728     goto ecdsa_error;
1729     if ((exponent = BN_new()) == NULL)
1730     goto ecdsa_error;
1731    
1732     buffer_get_bignum_SECSH(blob2, exponent);
1733     if (EC_KEY_set_private_key(result->ecdsa, exponent) != 1)
1734     goto ecdsa_error;
1735     if (key_ec_validate_private(result->ecdsa) != 0)
1736     goto ecdsa_error;
1737    
1738     // �t�@�C�����������������i�[�������������������J�����v�Z��������
1739     if ((ctx = BN_CTX_new()) == NULL)
1740     goto ecdsa_error;
1741     if (!EC_POINT_mul(EC_KEY_get0_group(result->ecdsa), q, exponent, NULL, NULL, ctx)) {
1742     goto ecdsa_error;
1743     }
1744     if (EC_KEY_set_public_key(result->ecdsa, q) != 1)
1745     goto ecdsa_error;
1746     if (key_ec_validate_public(EC_KEY_get0_group(result->ecdsa),
1747     EC_KEY_get0_public_key(result->ecdsa)) != 0)
1748     goto ecdsa_error;
1749    
1750     success = 1;
1751    
1752     ecdsa_error:
1753     free(curve);
1754     if (exponent)
1755     BN_clear_free(exponent);
1756     if (q)
1757     EC_POINT_free(q);
1758     if (ctx)
1759     BN_CTX_free(ctx);
1760     if (success == 0)
1761     goto error;
1762    
1763     break;
1764     }
1765 maya 5056 default:
1766     strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
1767     goto error;
1768     break;
1769     }
1770    
1771     *invalid_passphrase = FALSE;
1772    
1773     fclose(fp);
1774    
1775     if (encname != NULL)
1776     free(encname);
1777    
1778     if (blob != NULL)
1779     buffer_free(blob);
1780    
1781     if (blob2 != NULL)
1782     buffer_free(blob2);
1783    
1784     return (result);
1785    
1786     error:
1787     if (result != NULL)
1788     key_free(result);
1789    
1790     if (fp != NULL)
1791     fclose(fp);
1792    
1793     if (encname != NULL)
1794     free(encname);
1795    
1796     if (blob != NULL)
1797     buffer_free(blob);
1798    
1799     if (blob2 != NULL)
1800     buffer_free(blob2);
1801    
1802     return (NULL);
1803     }
1804    
1805     ssh2_keyfile_type get_ssh2_keytype(char *relative_name,
1806     FILE **fp,
1807     char *errmsg,
1808     int errmsg_len) {
1809     ssh2_keyfile_type ret = SSH2_KEYFILE_TYPE_NONE;
1810     char filename[2048];
1811     char line[200];
1812 doda 5284 int i;
1813 maya 5056
1814     // �����p�X�������p�X�����������B�������������������A�u�h�b�g���n�����v�f�B���N�g����
1815     // �����t�@�C�������������������������B(2005.2.7 yutaka)
1816     get_teraterm_dir_relative_name(filename, sizeof(filename),
1817     relative_name);
1818    
1819     *fp = fopen(filename, "r");
1820     if (*fp == NULL) {
1821     strncpy_s(errmsg, errmsg_len, strerror(errno), _TRUNCATE);
1822     return ret;
1823     }
1824    
1825     while (fgets(line, sizeof(line), *fp) != NULL) {
1826 doda 5284 for (i=0; keyfile_headers[i].type != SSH2_KEYFILE_TYPE_NONE; i++) {
1827     if ( strncmp(line, keyfile_headers[i].header, strlen(keyfile_headers[i].header)) == 0) {
1828     ret = keyfile_headers[i].type;
1829     break;
1830     }
1831 maya 5056 }
1832 doda 5284 if (ret != SSH2_KEYFILE_TYPE_NONE)
1833 maya 5056 break;
1834     }
1835 zmatsuo 10618
1836 maya 5056 if (ret == SSH2_KEYFILE_TYPE_NONE) {
1837     strncpy_s(errmsg, errmsg_len, "Unknown key file type.", _TRUNCATE);
1838 maya 5552 fseek(*fp, 0, SEEK_SET);
1839 maya 5056 return ret;
1840     }
1841 zmatsuo 10618
1842 maya 5056 fseek(*fp, 0, SEEK_SET);
1843     return ret;
1844     }

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