Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9211 - (show annotations) (download) (as text)
Sat Apr 17 09:52:01 2021 UTC (2 years, 10 months ago) by nmaya
File MIME type: text/x-csrc
File size: 50300 byte(s)
cipher_init_SSH2() に渡すのを EVP_CIPHER_CTX から sshcipher_ctx に変更

- cipher_init_SSH2() の中で sshcipher_ctx, EVP_CIPHER_CTX のメモリを確保する
- cipher_free_SSH2() の中でメモリを解放する
  これで
  cipher_init_SSH2() -> cipher_free_SSH2()
  EVP_CIPHER_CTX_new() -> EVP_CIPHER_CTX_free()
  という対応になる
1 /*
2 * Copyright (c) 1998-2001, Robert O'Callahan
3 * (C) 2004- TeraTerm Project
4 * 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
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 #include "key.h"
38
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 #include <openssl/md5.h>
49 #include <openssl/err.h>
50
51 #include "cipher.h"
52
53 static char ID_string[] = "SSH PRIVATE KEY FILE FORMAT 1.1\n";
54
55 static BIGNUM *get_bignum(unsigned char *bytes)
56 {
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 static BOOL normalize_key(RSA *key)
68 {
69 BOOL OK = FALSE;
70 BIGNUM *r = BN_new();
71 BN_CTX *ctx = BN_CTX_new();
72 BIGNUM *e, *n, *d, *dmp1, *dmq1, *iqmp, *p, *q;
73
74 e = n = d = dmp1 = dmq1 = iqmp = p = q = NULL;
75
76 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 }
83
84 if (r != NULL && ctx != NULL) {
85 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
90 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 }
96 }
97
98 BN_free(r);
99 BN_CTX_free(ctx);
100
101 return OK;
102 }
103
104 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 {
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 RSA *key;
117 unsigned int E_index, N_index, D_index, U_index, P_index, Q_index = 0;
118 BIGNUM *e, *n, *d, *p, *q;
119
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 SecureZeroMemory(keyfile_data, length);
269 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 SecureZeroMemory(keyfile_data, length);
298 free(keyfile_data);
299 return NULL;
300 }
301
302 key = RSA_new();
303 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
311 if (!normalize_key(key)) {
312 UTIL_get_lang_msg("MSG_KEYFILES_CRYPTOLIB_ERROR", pvar,
313 "Error in cryptography library.\n"
314 "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 SecureZeroMemory(keyfile_data, length);
322 free(keyfile_data);
323 return key;
324 }
325
326 Key *KEYFILES_read_private_key(PTInstVar pvar,
327 char * relative_name,
328 char * passphrase,
329 BOOL * invalid_passphrase,
330 BOOL is_auto_login)
331 {
332 RSA *RSA_key = read_RSA_private_key(pvar, relative_name,
333 passphrase, invalid_passphrase,
334 is_auto_login);
335
336 if (RSA_key == NULL) {
337 return FALSE;
338 } else {
339 Key *result = (Key *) malloc(sizeof(Key));
340
341 // �t���[���������� 0 ���������������������������B(2004.12.20 yutaka)
342 ZeroMemory(result, sizeof(Key));
343
344 result->rsa = RSA_key;
345 return result;
346 }
347 }
348
349
350 //
351 // SSH2
352 //
353
354 // bcrypt KDF �`��������
355 // based on key_parse_private2() @ OpenSSH 6.5
356 static Key *read_SSH2_private2_key(PTInstVar pvar,
357 FILE * fp,
358 char * passphrase,
359 BOOL * invalid_passphrase,
360 BOOL is_auto_login,
361 char *errmsg,
362 int errmsg_len)
363 {
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 const struct ssh2cipher *cipher;
383 size_t authlen;
384 struct sshcipher_ctx *cc = NULL;
385 int ret;
386
387 blob = buffer_init();
388 b = buffer_init();
389 kdf = buffer_init();
390 encoded = buffer_init();
391 copy_consumed = buffer_init();
392
393 if (blob == NULL || b == NULL || kdf == NULL || encoded == NULL || copy_consumed == NULL)
394 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 logprintf(LOG_LEVEL_WARNING, "%s: key file too large.", __FUNCTION__);
402 goto error;
403 }
404 if (len < sizeof(buf))
405 break;
406 }
407
408 /* base64 decode */
409 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 logprintf(LOG_LEVEL_VERBOSE, "%s: missing begin marker", __FUNCTION__);
415 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 logprintf(LOG_LEVEL_VERBOSE, "%s: no end marker", __FUNCTION__);
434 goto error;
435 }
436
437 // �t�@�C�����X�L�������I�����������Abase64 decode�����B
438 len = buffer_len(encoded);
439 if ((cp = buffer_append_space(copy_consumed, len)) == NULL) {
440 logprintf(LOG_LEVEL_ERROR, "%s: buffer_append_space", __FUNCTION__);
441 goto error;
442 }
443 if ((dlen = b64decode(cp, len, buffer_ptr(encoded))) < 0) {
444 logprintf(LOG_LEVEL_ERROR, "%s: base64 decode failed", __FUNCTION__);
445 goto error;
446 }
447 if ((unsigned int)dlen > len) {
448 logprintf(LOG_LEVEL_ERROR, "%s: crazy base64 length %d > %u", __FUNCTION__, dlen, len);
449 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 logprintf(LOG_LEVEL_ERROR, "%s: bad magic", __FUNCTION__);
456 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 cipher = get_cipher_by_name(ciphername);
466 if (cipher == NULL && strcmp(ciphername, "none") != 0) {
467 logprintf(LOG_LEVEL_ERROR, "%s: unknown cipher name", __FUNCTION__);
468 goto error;
469 }
470 // �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 /* passphrase required */
474 goto error;
475 }
476
477 kdfname = buffer_get_string_msg(copy_consumed, NULL);
478 if (kdfname == NULL ||
479 (!strcmp(kdfname, "none") && !strcmp(kdfname, KDFNAME))) {
480 logprintf(LOG_LEVEL_ERROR, "%s: unknown kdf name", __FUNCTION__ );
481 goto error;
482 }
483 if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) {
484 logprintf(LOG_LEVEL_ERROR, "%s: cipher %s requires kdf", __FUNCTION__, ciphername);
485 goto error;
486 }
487
488 /* kdf options */
489 kdfp = buffer_get_string_msg(copy_consumed, &klen);
490 if (kdfp == NULL) {
491 logprintf(LOG_LEVEL_ERROR, "%s: kdf options not set", __FUNCTION__);
492 goto error;
493 }
494 if (klen > 0) {
495 if ((cp = buffer_append_space(kdf, klen)) == NULL) {
496 logprintf(LOG_LEVEL_ERROR, "%s: kdf alloc failed", __FUNCTION__);
497 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 logprintf(LOG_LEVEL_ERROR, "%s: key counter missing", __FUNCTION__);
505 goto error;
506 }
507 if (nkeys != 1) {
508 logprintf(LOG_LEVEL_ERROR, "%s: only one key supported", __FUNCTION__);
509 goto error;
510 }
511
512 /* pubkey */
513 cp = buffer_get_string_msg(copy_consumed, &len);
514 if (cp == NULL) {
515 logprintf(LOG_LEVEL_ERROR, "%s: pubkey not found", __FUNCTION__);
516 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 blocksize = get_cipher_block_size(cipher);
523 authlen = 0; // TODO: ����������������
524 if (len < blocksize) {
525 logprintf(LOG_LEVEL_ERROR, "%s: encrypted data too small", __FUNCTION__);
526 goto error;
527 }
528 if (len % blocksize) {
529 logprintf(LOG_LEVEL_ERROR, "%s: length not multiple of blocksize", __FUNCTION__);
530 goto error;
531 }
532
533 /* setup key */
534 keylen = get_cipher_key_len(cipher);
535 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 logprintf(LOG_LEVEL_ERROR, "%s: salt not set", __FUNCTION__);
541 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 logprintf(LOG_LEVEL_ERROR, "%s: bcrypt_pbkdf failed", __FUNCTION__);
548 goto error;
549 }
550 }
551
552 // ������
553 cp = buffer_append_space(b, len);
554 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 if (ret == 0) {
557 goto error;
558 }
559 buffer_consume(copy_consumed, len);
560
561 if (buffer_remain_len(copy_consumed) != 0) {
562 logprintf(LOG_LEVEL_ERROR, "%s: key blob has trailing data (len = %u)", __FUNCTION__,
563 buffer_remain_len(copy_consumed));
564 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 logprintf(LOG_LEVEL_ERROR, "%s: check bytes missing", __FUNCTION__);
571 goto error;
572 }
573 if (check1 != check2) {
574 logprintf(LOG_LEVEL_VERBOSE, "%s: decrypt failed: 0x%08x != 0x%08x", __FUNCTION__,
575 check1, check2);
576 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 logprintf(LOG_LEVEL_ERROR, "%s: bad padding", __FUNCTION__);
591 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 cipher_free_SSH2(cc);
607
608 free(ciphername);
609 free(kdfname);
610 free(kdfp);
611 free(key);
612 free(salt);
613 free(comment);
614
615 // KDF ������������
616 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 // OpenSSL format
629 Key *read_SSH2_private_key(PTInstVar pvar,
630 FILE * fp,
631 char * passphrase,
632 BOOL * invalid_passphrase,
633 BOOL is_auto_login,
634 char *errmsg,
635 int errmsg_len)
636 {
637 Key *result = NULL;
638 EVP_PKEY *pk = NULL;
639 unsigned long err = 0;
640 int pk_type;
641
642 OpenSSL_add_all_algorithms();
643 ERR_load_crypto_strings();
644 //seed_prng();
645
646 result = read_SSH2_private2_key(pvar, fp, passphrase, invalid_passphrase, is_auto_login, errmsg, errmsg_len);
647 if (result)
648 return (result);
649
650 result = (Key *)malloc(sizeof(Key));
651 ZeroMemory(result, sizeof(Key));
652
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 pk_type = EVP_PKEY_id(pk);
663 switch (pk_type) {
664 case EVP_PKEY_RSA: // RSA key
665 result->type = KEY_RSA;
666 result->rsa = EVP_PKEY_get1_RSA(pk);
667 result->dsa = NULL;
668 result->ecdsa = NULL;
669
670 // RSA�������������L���������i�^�C�~���O�U���������h���j
671 if (RSA_blinding_on(result->rsa, NULL) != 1) {
672 err = ERR_get_error();
673 ERR_error_string_n(err, errmsg, errmsg_len);
674 goto error;
675 }
676 break;
677
678 case EVP_PKEY_DSA: // DSA key
679 result->type = KEY_DSA;
680 result->rsa = NULL;
681 result->dsa = EVP_PKEY_get1_DSA(pk);
682 result->ecdsa = NULL;
683 break;
684
685 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 result->type = nid_to_keytype(EC_GROUP_get_curve_name(g));
692 if (result->type == KEY_UNSPEC) {
693 goto error;
694 }
695 }
696 break;
697
698 default:
699 goto error;
700 break;
701 }
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 key_free(result);
715
716 if (fp != NULL)
717 fclose(fp);
718
719 return (NULL);
720 }
721
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 * 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 * "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
814 result = (Key *)malloc(sizeof(Key));
815 ZeroMemory(result, sizeof(Key));
816 result->type = KEY_NONE;
817 result->rsa = NULL;
818 result->dsa = NULL;
819 result->ecdsa = NULL;
820
821 const struct ssh2cipher *cipher = NULL;
822 struct sshcipher_ctx *cc = NULL;
823
824 pubkey = buffer_init();
825 prikey = buffer_init();
826
827 // parse keyfile & decode blob
828 {
829 char line[200], buf[100];
830 BIO *bmem, *b64, *chain;
831 while (fgets(line, sizeof(line), fp) != NULL) {
832 if (strncmp(line, "PuTTY-User-Key-File-2: ", strlen("PuTTY-User-Key-File-2: ")) == 0) {
833 if (strncmp(line + strlen("PuTTY-User-Key-File-2: "), "ssh-dss", strlen("ssh-dss")) == 0) {
834 result->type = KEY_DSA;
835 }
836 else if (strncmp(line + strlen("PuTTY-User-Key-File-2: "), "ssh-rsa", strlen("ssh-rsa")) == 0) {
837 result->type = KEY_RSA;
838 }
839 else if (strncmp(line + strlen("PuTTY-User-Key-File-2: "), "ecdsa-sha2-nistp256", strlen("ecdsa-sha2-nistp256")) == 0) {
840 result->type = KEY_ECDSA256;
841 }
842 else if (strncmp(line + strlen("PuTTY-User-Key-File-2: "), "ecdsa-sha2-nistp384", strlen("ecdsa-sha2-nistp384")) == 0) {
843 result->type = KEY_ECDSA384;
844 }
845 else if (strncmp(line + strlen("PuTTY-User-Key-File-2: "), "ecdsa-sha2-nistp521", strlen("ecdsa-sha2-nistp521")) == 0) {
846 result->type = KEY_ECDSA521;
847 }
848 else if (strncmp(line + strlen("PuTTY-User-Key-File-2: "), "ssh-ed25519", strlen("ssh-ed25519")) == 0) {
849 result->type = KEY_ED25519;
850 }
851 else {
852 strncpy_s(errmsg, errmsg_len, "not a PuTTY SSH-2 private key", _TRUNCATE);
853 goto error;
854 }
855 }
856 else if (strncmp(line, "Encryption: ", strlen("Encryption: ")) == 0) {
857 len = strlen(line + strlen("Encryption: "));
858 encname = (char *)malloc(len); // trim \n
859 strncpy_s(encname, len, line + strlen("Encryption: "), _TRUNCATE);
860 if (strcmp(encname, "aes256-cbc") == 0) {
861 // NOP
862 }
863 else if (strcmp(encname, "none") == 0) {
864 // NOP
865 }
866 else {
867 strncpy_s(errmsg, errmsg_len, "unknown encryption type", _TRUNCATE);
868 goto error;
869 }
870 }
871 else if (strncmp(line, "Comment: ", strlen("Comment: ")) == 0) {
872 len = strlen(line + strlen("Comment: "));
873 comment = (char *)malloc(len); // trim \n
874 strncpy_s(comment, len, line + strlen("Comment: "), _TRUNCATE);
875 }
876 else if (strncmp(line, "Private-MAC: ", strlen("Private-MAC: ")) == 0) {
877 len = strlen(line + strlen("Private-MAC: "));
878 private_mac = (char *)malloc(len); // trim \n
879 strncpy_s(private_mac, len, line + strlen("Private-MAC: "), _TRUNCATE);
880 }
881 else if (strncmp(line, "Private-HASH: ", strlen("Private-HASH: ")) == 0) {
882 strncpy_s(errmsg, errmsg_len, "not a PuTTY SSH-2 private key", _TRUNCATE);
883 goto error;
884 }
885 else if (strncmp(line, "Public-Lines: ", strlen("Public-Lines: ")) == 0) {
886 len = atoi(line + strlen("Public-Lines: "));
887 b64 = BIO_new(BIO_f_base64());
888 bmem = BIO_new(BIO_s_mem());
889 for (i=0; i<len && fgets(line, sizeof(line), fp)!=NULL; i++) {
890 BIO_write(bmem, line, strlen(line));
891 }
892 BIO_flush(bmem);
893 chain = BIO_push(b64, bmem);
894 BIO_set_mem_eof_return(chain, 0);
895 while ((len2 = BIO_read(chain, buf, sizeof(buf))) > 0) {
896 buffer_append(pubkey, buf, len2);
897 }
898 BIO_free_all(chain);
899 }
900 else if (strncmp(line, "Private-Lines: ", strlen("Private-Lines: ")) == 0) {
901 len = atoi(line + strlen("Private-Lines: "));
902 b64 = BIO_new(BIO_f_base64());
903 bmem = BIO_new(BIO_s_mem());
904 for (i=0; i<len && fgets(line, sizeof(line), fp)!=NULL; i++) {
905 BIO_write(bmem, line, strlen(line));
906 }
907 BIO_flush(bmem);
908 chain = BIO_push(b64, bmem);
909 BIO_set_mem_eof_return(chain, 0);
910 while ((len2 = BIO_read(chain, buf, sizeof(buf))) > 0) {
911 buffer_append(prikey, buf, len2);
912 }
913 BIO_free_all(chain);
914 }
915 else {
916 strncpy_s(errmsg, errmsg_len, "not a PuTTY SSH-2 private key", _TRUNCATE);
917 goto error;
918 }
919 }
920 }
921
922 if (result->type == KEY_NONE || strlen(encname) == 0 || buffer_len(pubkey) == 0 || buffer_len(prikey) == 0) {
923 strncpy_s(errmsg, errmsg_len, "key file format error", _TRUNCATE);
924 goto error;
925 }
926
927 // decrypt prikey with aes256-cbc
928 if (strcmp(encname, "aes256-cbc") == 0) {
929 const EVP_MD *md = EVP_sha1();
930 EVP_MD_CTX *ctx = NULL;
931 unsigned char key[40], iv[32];
932 EVP_CIPHER_CTX *cipher_ctx = NULL;
933 char *decrypted = NULL;
934 int ret;
935
936 ctx = EVP_MD_CTX_new();
937 if (ctx == NULL) {
938 goto error;
939 }
940
941 cipher_ctx = EVP_CIPHER_CTX_new();
942 if (cipher_ctx == NULL) {
943 EVP_MD_CTX_free(ctx);
944 goto error;
945 }
946
947 EVP_DigestInit(ctx, md);
948 EVP_DigestUpdate(ctx, "\0\0\0\0", 4);
949 EVP_DigestUpdate(ctx, passphrase, strlen(passphrase));
950 EVP_DigestFinal(ctx, key, &len);
951
952 EVP_DigestInit(ctx, md);
953 EVP_DigestUpdate(ctx, "\0\0\0\1", 4);
954 EVP_DigestUpdate(ctx, passphrase, strlen(passphrase));
955 EVP_DigestFinal(ctx, key + 20, &len);
956
957 EVP_MD_CTX_free(ctx);
958
959 memset(iv, 0, sizeof(iv));
960
961 // decrypt
962 cipher = get_cipher_by_name("aes256-cbc");
963 cipher_init_SSH2(&cc, cipher, key, 32, iv, 16, CIPHER_DECRYPT, pvar);
964 len = buffer_len(prikey);
965 decrypted = (char *)malloc(len);
966 ret = EVP_Cipher(cc->evp, decrypted, prikey->buf, len);
967 if (ret == 0) {
968 strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE);
969 free(decrypted);
970 cipher_free_SSH2(cc);
971 goto error;
972 }
973 buffer_clear(prikey);
974 buffer_append(prikey, decrypted, len);
975 free(decrypted);
976 cipher_free_SSH2(cc);
977 }
978
979 // verity MAC
980 {
981 char realmac[41];
982 unsigned char binary[20];
983 buffer_t *macdata;
984
985 macdata = buffer_init();
986
987 len = strlen(get_ssh2_hostkey_type_name(result->type));
988 buffer_put_int(macdata, len);
989 buffer_append(macdata, get_ssh2_hostkey_type_name(result->type), len);
990 len = strlen(encname);
991 buffer_put_int(macdata, len);
992 buffer_append(macdata, encname, len);
993 len = strlen(comment);
994 buffer_put_int(macdata, len);
995 buffer_append(macdata, comment, len);
996 buffer_put_int(macdata, pubkey->len);
997 buffer_append(macdata, pubkey->buf, pubkey->len);
998 buffer_put_int(macdata, prikey->len);
999 buffer_append(macdata, prikey->buf, prikey->len);
1000
1001 if (private_mac != NULL) {
1002 unsigned char mackey[20];
1003 char header[] = "putty-private-key-file-mac-key";
1004 const EVP_MD *md = EVP_sha1();
1005 EVP_MD_CTX *ctx = NULL;
1006
1007 ctx = EVP_MD_CTX_new();
1008 if (ctx == NULL) {
1009 goto error;
1010 }
1011
1012 EVP_DigestInit(ctx, md);
1013 EVP_DigestUpdate(ctx, header, sizeof(header)-1);
1014 len = strlen(passphrase);
1015 if (strcmp(encname, "aes256-cbc") == 0 && len > 0) {
1016 EVP_DigestUpdate(ctx, passphrase, len);
1017 }
1018 EVP_DigestFinal(ctx, mackey, &len);
1019 EVP_MD_CTX_free(ctx);
1020
1021 //hmac_sha1_simple(mackey, sizeof(mackey), macdata->buf, macdata->len, binary);
1022 {
1023 EVP_MD_CTX *ctx[2] = {0, 0};
1024 unsigned char intermediate[20];
1025 unsigned char foo[64];
1026 int i;
1027
1028 ctx[0] = EVP_MD_CTX_new();
1029 if (ctx[0] == NULL) {
1030 goto error;
1031 }
1032 ctx[1] = EVP_MD_CTX_new();
1033 if (ctx[1] == NULL) {
1034 EVP_MD_CTX_free(ctx[0]);
1035 goto error;
1036 }
1037
1038 memset(foo, 0x36, sizeof(foo));
1039 for (i = 0; i < sizeof(mackey) && i < sizeof(foo); i++) {
1040 foo[i] ^= mackey[i];
1041 }
1042 EVP_DigestInit(ctx[0], md);
1043 EVP_DigestUpdate(ctx[0], foo, sizeof(foo));
1044
1045 memset(foo, 0x5C, sizeof(foo));
1046 for (i = 0; i < sizeof(mackey) && i < sizeof(foo); i++) {
1047 foo[i] ^= mackey[i];
1048 }
1049 EVP_DigestInit(ctx[1], md);
1050 EVP_DigestUpdate(ctx[1], foo, sizeof(foo));
1051
1052 memset(foo, 0, sizeof(foo));
1053
1054 EVP_DigestUpdate(ctx[0], macdata->buf, macdata->len);
1055 EVP_DigestFinal(ctx[0], intermediate, &len);
1056
1057 EVP_DigestUpdate(ctx[1], intermediate, sizeof(intermediate));
1058 EVP_DigestFinal(ctx[1], binary, &len);
1059
1060 EVP_MD_CTX_free(ctx[0]);
1061 EVP_MD_CTX_free(ctx[1]);
1062 }
1063
1064 memset(mackey, 0, sizeof(mackey));
1065
1066 }
1067 else {
1068 strncpy_s(errmsg, errmsg_len, "key file format error", _TRUNCATE);
1069 buffer_free(macdata);
1070 goto error;
1071 }
1072
1073 buffer_free(macdata);
1074
1075 for (i=0; i<20; i++) {
1076 sprintf(realmac + 2*i, "%02x", binary[i]);
1077 }
1078
1079 if (strcmp(private_mac, realmac) != 0) {
1080 if (strcmp(encname, "aes256-cbc") == 0) {
1081 strncpy_s(errmsg, errmsg_len, "wrong passphrase", _TRUNCATE);
1082 *invalid_passphrase = TRUE;
1083 goto error;
1084 }
1085 else {
1086 strncpy_s(errmsg, errmsg_len, "MAC verify failed", _TRUNCATE);
1087 goto error;
1088 }
1089 }
1090 }
1091
1092 switch (result->type) {
1093 case KEY_RSA:
1094 {
1095 char *pubkey_type, *pub, *pri;
1096 BIGNUM *e, *n, *d, *iqmp, *p, *q;
1097
1098 pub = pubkey->buf;
1099 pri = prikey->buf;
1100 pubkey_type = buffer_get_string(&pub, NULL);
1101 if (strcmp(pubkey_type, "ssh-rsa") != 0) {
1102 strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
1103 free(pubkey_type);
1104 goto error;
1105 }
1106 free(pubkey_type);
1107
1108 result->rsa = RSA_new();
1109 if (result->rsa == NULL) {
1110 strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1111 goto error;
1112 }
1113 e = BN_new();
1114 n = BN_new();
1115 d = BN_new();
1116 RSA_set0_key(result->rsa, n, e, d);
1117 p = BN_new();
1118 q = BN_new();
1119 RSA_set0_factors(result->rsa, p, q);
1120 iqmp = BN_new();
1121 RSA_set0_crt_params(result->rsa, NULL, NULL, iqmp);
1122 if (e == NULL ||
1123 n == NULL ||
1124 d == NULL ||
1125 p == NULL ||
1126 q == NULL ||
1127 iqmp == NULL) {
1128 strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1129 goto error;
1130 }
1131
1132 buffer_get_bignum2(&pub, e);
1133 buffer_get_bignum2(&pub, n);
1134
1135 buffer_get_bignum2(&pri, d);
1136 buffer_get_bignum2(&pri, p);
1137 buffer_get_bignum2(&pri, q);
1138 buffer_get_bignum2(&pri, iqmp);
1139
1140 break;
1141 }
1142 case KEY_DSA:
1143 {
1144 char *pubkey_type, *pub, *pri;
1145 BIGNUM *p, *q, *g, *pub_key, *priv_key;
1146
1147 pub = pubkey->buf;
1148 pri = prikey->buf;
1149 pubkey_type = buffer_get_string(&pub, NULL);
1150 if (strcmp(pubkey_type, "ssh-dss") != 0) {
1151 strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
1152 free(pubkey_type);
1153 goto error;
1154 }
1155 free(pubkey_type);
1156
1157 result->dsa = DSA_new();
1158 if (result->dsa == NULL) {
1159 strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1160 goto error;
1161 }
1162 p = BN_new();
1163 q = BN_new();
1164 g = BN_new();
1165 DSA_set0_pqg(result->dsa, p, q, g);
1166 pub_key = BN_new();
1167 priv_key = BN_new();
1168 DSA_set0_key(result->dsa, pub_key, priv_key);
1169 if (p == NULL ||
1170 q == NULL ||
1171 g == NULL ||
1172 pub_key == NULL ||
1173 priv_key == NULL) {
1174 strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1175 goto error;
1176 }
1177
1178 buffer_get_bignum2(&pub, p);
1179 buffer_get_bignum2(&pub, q);
1180 buffer_get_bignum2(&pub, g);
1181 buffer_get_bignum2(&pub, pub_key);
1182
1183 buffer_get_bignum2(&pri, priv_key);
1184
1185 break;
1186 }
1187 case KEY_ECDSA256:
1188 case KEY_ECDSA384:
1189 case KEY_ECDSA521:
1190 {
1191 char *pubkey_type, *pub, *pri;
1192 int success = 0;
1193 unsigned int nid;
1194 char *curve = NULL;
1195 ssh_keytype skt;
1196 BIGNUM *exponent = NULL;
1197 EC_POINT *q = NULL;
1198
1199 pub = pubkey->buf;
1200 pri = prikey->buf;
1201 pubkey_type = buffer_get_string(&pub, NULL);
1202 if ((result->type == KEY_ECDSA256 && strcmp(pubkey_type, "ecdsa-sha2-nistp256") != 0) ||
1203 (result->type == KEY_ECDSA384 && strcmp(pubkey_type, "ecdsa-sha2-nistp384") != 0) ||
1204 (result->type == KEY_ECDSA521 && strcmp(pubkey_type, "ecdsa-sha2-nistp521") != 0)) {
1205 strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
1206 free(pubkey_type);
1207 goto error;
1208 }
1209 free(pubkey_type);
1210
1211 nid = keytype_to_cipher_nid(result->type);
1212 curve = buffer_get_string(&pub, NULL);
1213 skt = key_curve_name_to_keytype(curve);
1214 if (nid != keytype_to_cipher_nid(skt))
1215 goto ecdsa_error;
1216
1217 if ((result->ecdsa = EC_KEY_new_by_curve_name(nid)) == NULL)
1218 goto ecdsa_error;
1219 if ((q = EC_POINT_new(EC_KEY_get0_group(result->ecdsa))) == NULL)
1220 goto ecdsa_error;
1221 if ((exponent = BN_new()) == NULL)
1222 goto ecdsa_error;
1223
1224 buffer_get_ecpoint(&pub, EC_KEY_get0_group(result->ecdsa), q);
1225 buffer_get_bignum2(&pri, exponent);
1226 if (EC_KEY_set_public_key(result->ecdsa, q) != 1)
1227 goto ecdsa_error;
1228 if (EC_KEY_set_private_key(result->ecdsa, exponent) != 1)
1229 goto ecdsa_error;
1230 if (key_ec_validate_public(EC_KEY_get0_group(result->ecdsa),
1231 EC_KEY_get0_public_key(result->ecdsa)) != 0)
1232 goto ecdsa_error;
1233 if (key_ec_validate_private(result->ecdsa) != 0)
1234 goto ecdsa_error;
1235
1236 success = 1;
1237
1238 ecdsa_error:
1239 free(curve);
1240 if (exponent)
1241 BN_clear_free(exponent);
1242 if (q)
1243 EC_POINT_free(q);
1244 if (success == 0)
1245 goto error;
1246
1247 break;
1248 }
1249 case KEY_ED25519:
1250 {
1251 char *pubkey_type, *pub, *pri;
1252 unsigned int pklen, sklen;
1253 char *sk;
1254 pub = pubkey->buf;
1255 pri = prikey->buf;
1256 pubkey_type = buffer_get_string(&pub, NULL);
1257 if (strcmp(pubkey_type, "ssh-ed25519") != 0) {
1258 strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
1259 free(pubkey_type);
1260 goto error;
1261 }
1262 free(pubkey_type);
1263
1264 result->ed25519_pk = buffer_get_string(&pub, &pklen);
1265 sk = buffer_get_string(&pri, &sklen);
1266 result->ed25519_sk = malloc(pklen + sklen + 1);
1267 memcpy(result->ed25519_sk, sk, sklen);
1268 memcpy(result->ed25519_sk + sklen, result->ed25519_pk, pklen);
1269 result->ed25519_sk[sklen + pklen] = '\0';
1270 free(sk);
1271
1272 if (pklen != ED25519_PK_SZ)
1273 goto error;
1274 if (sklen + pklen != ED25519_SK_SZ)
1275 goto error;
1276
1277 break;
1278 }
1279 default:
1280 strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
1281 goto error;
1282 break;
1283 }
1284
1285 fclose(fp);
1286
1287 if (encname != NULL)
1288 free(encname);
1289
1290 if (comment != NULL)
1291 free(comment);
1292
1293 if (pubkey != NULL)
1294 buffer_free(pubkey);
1295
1296 if (prikey != NULL)
1297 buffer_free(prikey);
1298
1299 if (private_mac != NULL)
1300 free(private_mac);
1301
1302 return (result);
1303
1304 error:
1305 if (result != NULL)
1306 key_free(result);
1307
1308 if (fp != NULL)
1309 fclose(fp);
1310
1311 if (encname != NULL)
1312 free(encname);
1313
1314 if (comment != NULL)
1315 free(comment);
1316
1317 if (pubkey != NULL)
1318 buffer_free(pubkey);
1319
1320 if (prikey != NULL)
1321 buffer_free(prikey);
1322
1323 if (private_mac != NULL)
1324 free(private_mac);
1325
1326 return (NULL);
1327 }
1328
1329 // SECSH(ssh.com) format
1330 /*
1331 * Code to read ssh.com private keys.
1332 *
1333 * "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
1334 * "Comment:..."
1335 * "Base64..."
1336 * "---- END SSH2 ENCRYPTED PRIVATE KEY ----"
1337 *
1338 * Body of key data
1339 *
1340 * - uint32 0x3f6ff9eb (magic number)
1341 * - uint32 size (total blob size)
1342 * - string key-type (see below)
1343 * - string cipher-type (tells you if key is encrypted)
1344 * - string encrypted-blob
1345 *
1346 * The key type strings are ghastly. The RSA key I looked at had a type string of
1347 *
1348 * `if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}'
1349 * `dl-modp{sign{dsa-nist-sha1},dh{plain}}'
1350 * `ec-modp'
1351 *
1352 * The encryption. The cipher-type string appears to be either
1353 *
1354 * `none'
1355 * `3des-cbc'
1356 *
1357 * The payload blob, for an RSA key, contains:
1358 * - mpint e
1359 * - mpint d
1360 * - mpint n (yes, the public and private stuff is intermixed)
1361 * - mpint u (presumably inverse of p mod q)
1362 * - mpint p (p is the smaller prime)
1363 * - mpint q (q is the larger)
1364 *
1365 * For a DSA key, the payload blob contains:
1366 * - uint32 0
1367 * - mpint p
1368 * - mpint g
1369 * - mpint q
1370 * - mpint y
1371 * - mpint x
1372 *
1373 * For a ECDSA key, the payload blob contains:
1374 * - uint32 1
1375 * - string [identifier] ("nistp256" or "nistp384" or "nistp521")
1376 * - mpint n
1377 */
1378 Key *read_SSH2_SECSH_private_key(PTInstVar pvar,
1379 FILE * fp,
1380 char * passphrase,
1381 BOOL * invalid_passphrase,
1382 BOOL is_auto_login,
1383 char *errmsg,
1384 int errmsg_len)
1385 {
1386 Key *result = NULL;
1387 unsigned long err = 0;
1388 int i, len2;
1389 unsigned int len;
1390 int encflag;
1391 char *encname = NULL;
1392 buffer_t *blob = NULL, *blob2 = NULL;
1393
1394 result = (Key *)malloc(sizeof(Key));
1395 ZeroMemory(result, sizeof(Key));
1396 result->type = KEY_NONE;
1397 result->rsa = NULL;
1398 result->dsa = NULL;
1399 result->ecdsa = NULL;
1400
1401 blob = buffer_init();
1402 blob2 = buffer_init();
1403
1404 const struct ssh2cipher *cipher = NULL;
1405 struct sshcipher_ctx *cc = NULL;
1406
1407 // parse keyfile & decode blob
1408 {
1409 char line[200], buf[100];
1410 BIO *bmem, *b64, *chain;
1411 int st = 0;
1412
1413 b64 = BIO_new(BIO_f_base64());
1414 bmem = BIO_new(BIO_s_mem());
1415
1416 while (fgets(line, sizeof(line), fp) != NULL) {
1417 if (strncmp(line, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----", strlen("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----")) == 0) {
1418 if (st == 0) {
1419 st = 1;
1420 continue;
1421 }
1422 else {
1423 break;
1424 }
1425 }
1426 else if (strncmp(line, "---- END SSH2 ENCRYPTED PRIVATE KEY ----", strlen("---- END SSH2 ENCRYPTED PRIVATE KEY ----")) == 0) {
1427 break;
1428 }
1429
1430 if (st == 0) {
1431 continue;
1432 }
1433
1434 if (strchr(line, ':') != NULL) {
1435 if (st == 1) {
1436 continue;
1437 }
1438 strncpy_s(errmsg, errmsg_len, "header found in body of key data", _TRUNCATE);
1439 BIO_free_all(bmem);
1440 goto error;
1441 }
1442 else if (st == 1) {
1443 st = 2;
1444 }
1445
1446 BIO_write(bmem, line, strlen(line));
1447 }
1448
1449 BIO_flush(bmem);
1450 chain = BIO_push(b64, bmem);
1451 BIO_set_mem_eof_return(chain, 0);
1452 while ((len2 = BIO_read(chain, buf, sizeof(buf))) > 0) {
1453 buffer_append(blob, buf, len2);
1454 }
1455 BIO_free_all(chain);
1456 buffer_rewind(blob);
1457 }
1458
1459 if (blob->len < 8) {
1460 strncpy_s(errmsg, errmsg_len, "key body not present", _TRUNCATE);
1461 goto error;
1462 }
1463 i = buffer_get_int(blob);
1464 if (i != 0x3f6ff9eb) {
1465 strncpy_s(errmsg, errmsg_len, "magic number error", _TRUNCATE);
1466 goto error;
1467 }
1468 len = buffer_get_int(blob);
1469 if (len == 0 || len > blob->len) {
1470 strncpy_s(errmsg, errmsg_len, "body size error", _TRUNCATE);
1471 goto error;
1472 }
1473
1474 len = buffer_get_int(blob);
1475 if (strncmp(blob->buf + blob->offset, "if-modn{sign{rsa", strlen("if-modn{sign{rsa") - 1) == 0) {
1476 result->type = KEY_RSA;
1477 }
1478 else if (strncmp(blob->buf + blob->offset, "dl-modp{sign{dsa", strlen("dl-modp{sign{dsa") - 1) == 0) {
1479 result->type = KEY_DSA;
1480 }
1481 else if (strncmp(blob->buf + blob->offset, "ec-modp", strlen("ec-modp") - 1) == 0) {
1482 result->type = KEY_ECDSA256;
1483 }
1484 else {
1485 strncpy_s(errmsg, errmsg_len, "unknown key type", _TRUNCATE);
1486 goto error;
1487 }
1488 buffer_consume(blob, len);
1489
1490 len = buffer_get_int(blob);
1491 encname = (char *)malloc(len + 1);
1492 strncpy_s(encname, len + 1, blob->buf + blob->offset, _TRUNCATE);
1493 if (strcmp(encname, "3des-cbc") == 0) {
1494 encflag = 1;
1495 }
1496 else if (strcmp(encname, "none") == 0) {
1497 encflag = 0;
1498 }
1499 else {
1500 strncpy_s(errmsg, errmsg_len, "unknown encryption type", _TRUNCATE);
1501 goto error;
1502 }
1503 buffer_consume(blob, len);
1504
1505 len = buffer_get_int(blob);
1506 if (len > (blob->len - blob->offset)) {
1507 strncpy_s(errmsg, errmsg_len, "body size error", _TRUNCATE);
1508 goto error;
1509 }
1510
1511 // decrypt privkey with 3des-cbc
1512 if (strcmp(encname, "3des-cbc") == 0) {
1513 MD5_CTX md;
1514 unsigned char key[32], iv[16];
1515 EVP_CIPHER_CTX *cipher_ctx = NULL;
1516 char *decrypted = NULL;
1517 int ret;
1518
1519 cipher_ctx = EVP_CIPHER_CTX_new();
1520 if (cipher_ctx == NULL) {
1521 strncpy_s(errmsg, errmsg_len, "Out of memory: EVP_CIPHER_CTX_new()", _TRUNCATE);
1522 goto error;
1523 }
1524
1525 MD5_Init(&md);
1526 MD5_Update(&md, passphrase, strlen(passphrase));
1527 MD5_Final(key, &md);
1528
1529 MD5_Init(&md);
1530 MD5_Update(&md, passphrase, strlen(passphrase));
1531 MD5_Update(&md, key, 16);
1532 MD5_Final(key + 16, &md);
1533
1534 memset(iv, 0, sizeof(iv));
1535
1536 // decrypt
1537 cipher = get_cipher_by_name("3des-cbc");
1538 cipher_init_SSH2(&cc, cipher, key, 24, iv, 8, CIPHER_DECRYPT, pvar);
1539 decrypted = (char *)malloc(len);
1540 ret = EVP_Cipher(cc->evp, decrypted, blob->buf + blob->offset, len);
1541 if (ret == 0) {
1542 strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE);
1543 cipher_free_SSH2(cc);
1544 goto error;
1545 }
1546 buffer_append(blob2, decrypted, len);
1547 free(decrypted);
1548 cipher_free_SSH2(cc);
1549
1550 *invalid_passphrase = TRUE;
1551 }
1552 else { // none
1553 buffer_append(blob2, blob->buf + blob->offset, len);
1554 }
1555 buffer_rewind(blob2);
1556
1557 len = buffer_get_int(blob2);
1558 if (len <= 0 || len > (blob2->len - blob2->offset)) {
1559 strncpy_s(errmsg, errmsg_len, "blob size error", _TRUNCATE);
1560 goto error;
1561 }
1562
1563 switch (result->type) {
1564 case KEY_RSA:
1565 {
1566 BIGNUM *e, *n, *d, *iqmp, *p, *q;
1567
1568 result->rsa = RSA_new();
1569 if (result->rsa == NULL) {
1570 strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1571 goto error;
1572 }
1573 e = BN_new();
1574 n = BN_new();
1575 d = BN_new();
1576 RSA_set0_key(result->rsa, n, e, d);
1577 p = BN_new();
1578 q = BN_new();
1579 RSA_set0_factors(result->rsa, p, q);
1580 iqmp = BN_new();
1581 RSA_set0_crt_params(result->rsa, NULL, NULL, iqmp);
1582 if (e == NULL ||
1583 n == NULL ||
1584 d == NULL ||
1585 p == NULL ||
1586 q == NULL ||
1587 iqmp == NULL) {
1588 strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1589 goto error;
1590 }
1591
1592 buffer_get_bignum_SECSH(blob2, e);
1593 buffer_get_bignum_SECSH(blob2, d);
1594 buffer_get_bignum_SECSH(blob2, n);
1595 buffer_get_bignum_SECSH(blob2, iqmp);
1596 buffer_get_bignum_SECSH(blob2, p);
1597 buffer_get_bignum_SECSH(blob2, q);
1598
1599 break;
1600 }
1601 case KEY_DSA:
1602 {
1603 int param;
1604 BIGNUM *p, *q, *g, *pub_key, *priv_key;
1605
1606 result->dsa = DSA_new();
1607 if (result->dsa == NULL) {
1608 strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1609 goto error;
1610 }
1611 p = BN_new();
1612 q = BN_new();
1613 g = BN_new();
1614 DSA_set0_pqg(result->dsa, p, q, g);
1615 pub_key = BN_new();
1616 priv_key = BN_new();
1617 DSA_set0_key(result->dsa, pub_key, priv_key);
1618 if (p == NULL ||
1619 q == NULL ||
1620 g == NULL ||
1621 pub_key == NULL ||
1622 priv_key == NULL) {
1623 strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
1624 goto error;
1625 }
1626
1627 param = buffer_get_int(blob2);
1628 if (param != 0) {
1629 strncpy_s(errmsg, errmsg_len, "predefined DSA parameters not supported", _TRUNCATE);
1630 goto error;
1631 }
1632 buffer_get_bignum_SECSH(blob2, p);
1633 buffer_get_bignum_SECSH(blob2, g);
1634 buffer_get_bignum_SECSH(blob2, q);
1635 buffer_get_bignum_SECSH(blob2, pub_key);
1636 buffer_get_bignum_SECSH(blob2, priv_key);
1637
1638 break;
1639 }
1640 case KEY_ECDSA256:
1641 {
1642 unsigned int dummy, nid;
1643 int success = 0;
1644 char *curve = NULL;
1645 BIGNUM *exponent = NULL;
1646 EC_POINT *q = NULL;
1647 BN_CTX *ctx = NULL;
1648
1649 dummy = buffer_get_int(blob2);
1650 curve = buffer_get_string_msg(blob2, NULL);
1651
1652 if (strncmp(curve, "nistp256", strlen("nistp256")) == 0) {
1653 result->type = KEY_ECDSA256;
1654 }
1655 else if (strncmp(curve, "nistp384", strlen("nistp384")) == 0) {
1656 result->type = KEY_ECDSA384;
1657 }
1658 else if (strncmp(curve, "nistp521", strlen("nistp521")) == 0) {
1659 result->type = KEY_ECDSA521;
1660 }
1661 else {
1662 strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
1663 goto error;
1664 }
1665
1666 nid = keytype_to_cipher_nid(result->type);
1667 if ((result->ecdsa = EC_KEY_new_by_curve_name(nid)) == NULL)
1668 goto ecdsa_error;
1669 if ((q = EC_POINT_new(EC_KEY_get0_group(result->ecdsa))) == NULL)
1670 goto ecdsa_error;
1671 if ((exponent = BN_new()) == NULL)
1672 goto ecdsa_error;
1673
1674 buffer_get_bignum_SECSH(blob2, exponent);
1675 if (EC_KEY_set_private_key(result->ecdsa, exponent) != 1)
1676 goto ecdsa_error;
1677 if (key_ec_validate_private(result->ecdsa) != 0)
1678 goto ecdsa_error;
1679
1680 // �t�@�C�����������������i�[�������������������J�����v�Z��������
1681 if ((ctx = BN_CTX_new()) == NULL)
1682 goto ecdsa_error;
1683 if (!EC_POINT_mul(EC_KEY_get0_group(result->ecdsa), q, exponent, NULL, NULL, ctx)) {
1684 goto ecdsa_error;
1685 }
1686 if (EC_KEY_set_public_key(result->ecdsa, q) != 1)
1687 goto ecdsa_error;
1688 if (key_ec_validate_public(EC_KEY_get0_group(result->ecdsa),
1689 EC_KEY_get0_public_key(result->ecdsa)) != 0)
1690 goto ecdsa_error;
1691
1692 success = 1;
1693
1694 ecdsa_error:
1695 free(curve);
1696 if (exponent)
1697 BN_clear_free(exponent);
1698 if (q)
1699 EC_POINT_free(q);
1700 if (ctx)
1701 BN_CTX_free(ctx);
1702 if (success == 0)
1703 goto error;
1704
1705 break;
1706 }
1707 default:
1708 strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
1709 goto error;
1710 break;
1711 }
1712
1713 *invalid_passphrase = FALSE;
1714
1715 fclose(fp);
1716
1717 if (encname != NULL)
1718 free(encname);
1719
1720 if (blob != NULL)
1721 buffer_free(blob);
1722
1723 if (blob2 != NULL)
1724 buffer_free(blob2);
1725
1726 return (result);
1727
1728 error:
1729 if (result != NULL)
1730 key_free(result);
1731
1732 if (fp != NULL)
1733 fclose(fp);
1734
1735 if (encname != NULL)
1736 free(encname);
1737
1738 if (blob != NULL)
1739 buffer_free(blob);
1740
1741 if (blob2 != NULL)
1742 buffer_free(blob2);
1743
1744 return (NULL);
1745 }
1746
1747 ssh2_keyfile_type get_ssh2_keytype(char *relative_name,
1748 FILE **fp,
1749 char *errmsg,
1750 int errmsg_len) {
1751 ssh2_keyfile_type ret = SSH2_KEYFILE_TYPE_NONE;
1752 char filename[2048];
1753 char line[200];
1754 int i;
1755
1756 // �����p�X�������p�X�����������B�������������������A�u�h�b�g���n�����v�f�B���N�g����
1757 // �����t�@�C�������������������������B(2005.2.7 yutaka)
1758 get_teraterm_dir_relative_name(filename, sizeof(filename),
1759 relative_name);
1760
1761 *fp = fopen(filename, "r");
1762 if (*fp == NULL) {
1763 strncpy_s(errmsg, errmsg_len, strerror(errno), _TRUNCATE);
1764 return ret;
1765 }
1766
1767 while (fgets(line, sizeof(line), *fp) != NULL) {
1768 for (i=0; keyfile_headers[i].type != SSH2_KEYFILE_TYPE_NONE; i++) {
1769 if ( strncmp(line, keyfile_headers[i].header, strlen(keyfile_headers[i].header)) == 0) {
1770 ret = keyfile_headers[i].type;
1771 break;
1772 }
1773 }
1774 if (ret != SSH2_KEYFILE_TYPE_NONE)
1775 break;
1776 }
1777
1778 if (ret == SSH2_KEYFILE_TYPE_NONE) {
1779 strncpy_s(errmsg, errmsg_len, "Unknown key file type.", _TRUNCATE);
1780 fseek(*fp, 0, SEEK_SET);
1781 return ret;
1782 }
1783
1784 fseek(*fp, 0, SEEK_SET);
1785 return ret;
1786 }

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