Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/keyfiles.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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