| 371 |
// bcrypt KDF 形式で読む |
// bcrypt KDF 形式で読む |
| 372 |
// based on key_parse_private2() @ OpenSSH 6.5 |
// based on key_parse_private2() @ OpenSSH 6.5 |
| 373 |
static Key *read_SSH2_private2_key(PTInstVar pvar, |
static Key *read_SSH2_private2_key(PTInstVar pvar, |
| 374 |
FILE * fp, |
FILE * fp, |
| 375 |
char * passphrase, |
char * passphrase, |
| 376 |
BOOL * invalid_passphrase, |
BOOL * invalid_passphrase, |
| 377 |
BOOL is_auto_login, |
BOOL is_auto_login, |
| 378 |
char *errmsg, |
char *errmsg, |
| 379 |
int errmsg_len) |
int errmsg_len) |
| 380 |
{ |
{ |
| 381 |
/* (A) |
/* (A) |
| 382 |
* buffer_consume系関数を使う場合は、buffer_lenとbuffer_ptrが使えないので、 |
* buffer_consume系関数を使う場合は、buffer_lenとbuffer_ptrが使えないので、 |
| 396 |
unsigned int len, klen, nkeys, blocksize, keylen, ivlen, slen, rounds; |
unsigned int len, klen, nkeys, blocksize, keylen, ivlen, slen, rounds; |
| 397 |
unsigned int check1, check2, m1len, m2len; |
unsigned int check1, check2, m1len, m2len; |
| 398 |
int dlen, i; |
int dlen, i; |
| 399 |
const SSH2Cipher *cipher; |
const struct ssh2cipher *cipher; |
| 400 |
size_t authlen; |
size_t authlen; |
| 401 |
EVP_CIPHER_CTX *cipher_ctx = NULL; |
struct sshcipher_ctx *cc = NULL; |
| 402 |
int ret; |
int ret; |
| 403 |
|
|
| 404 |
blob = buffer_init(); |
blob = buffer_init(); |
| 406 |
kdf = buffer_init(); |
kdf = buffer_init(); |
| 407 |
encoded = buffer_init(); |
encoded = buffer_init(); |
| 408 |
copy_consumed = buffer_init(); |
copy_consumed = buffer_init(); |
|
cipher_ctx = EVP_CIPHER_CTX_new(); |
|
| 409 |
|
|
| 410 |
if (blob == NULL || b == NULL || kdf == NULL || encoded == NULL || copy_consumed == NULL || cipher_ctx == NULL) |
if (blob == NULL || b == NULL || kdf == NULL || encoded == NULL || copy_consumed == NULL) |
| 411 |
goto error; |
goto error; |
| 412 |
|
|
| 413 |
// ファイルをすべて読み込む |
// ファイルをすべて読み込む |
| 568 |
|
|
| 569 |
// 復号化 |
// 復号化 |
| 570 |
cp = buffer_append_space(b, len); |
cp = buffer_append_space(b, len); |
| 571 |
cipher_init_SSH2(cipher_ctx, key, keylen, key + keylen, ivlen, CIPHER_DECRYPT, |
cipher_init_SSH2(&cc, cipher, key, keylen, key + keylen, ivlen, CIPHER_DECRYPT, pvar); |
| 572 |
get_cipher_EVP_CIPHER(cipher), 0, 0, pvar); |
ret = EVP_Cipher(cc->evp, cp, buffer_tail_ptr(copy_consumed), len); |
|
ret = EVP_Cipher(cipher_ctx, cp, buffer_tail_ptr(copy_consumed), len); |
|
| 573 |
if (ret == 0) { |
if (ret == 0) { |
|
cipher_cleanup_SSH2(cipher_ctx); |
|
| 574 |
goto error; |
goto error; |
| 575 |
} |
} |
|
cipher_cleanup_SSH2(cipher_ctx); |
|
| 576 |
buffer_consume(copy_consumed, len); |
buffer_consume(copy_consumed, len); |
| 577 |
|
|
| 578 |
if (buffer_remain_len(copy_consumed) != 0) { |
if (buffer_remain_len(copy_consumed) != 0) { |
| 620 |
buffer_free(kdf); |
buffer_free(kdf); |
| 621 |
buffer_free(encoded); |
buffer_free(encoded); |
| 622 |
buffer_free(copy_consumed); |
buffer_free(copy_consumed); |
| 623 |
|
cipher_free_SSH2(cc); |
| 624 |
|
|
| 625 |
free(ciphername); |
free(ciphername); |
| 626 |
free(kdfname); |
free(kdfname); |
| 629 |
free(salt); |
free(salt); |
| 630 |
free(comment); |
free(comment); |
| 631 |
|
|
|
if (cipher_ctx) { |
|
|
EVP_CIPHER_CTX_free(cipher_ctx); |
|
|
} |
|
|
|
|
| 632 |
// KDF ではなかった |
// KDF ではなかった |
| 633 |
if (keyfmt == NULL) { |
if (keyfmt == NULL) { |
| 634 |
fseek(fp, 0, SEEK_SET); |
fseek(fp, 0, SEEK_SET); |
| 827 |
int i, len, len2; |
int i, len, len2; |
| 828 |
char *encname = NULL, *comment = NULL, *private_mac = NULL; |
char *encname = NULL, *comment = NULL, *private_mac = NULL; |
| 829 |
buffer_t *pubkey = NULL, *prikey = NULL; |
buffer_t *pubkey = NULL, *prikey = NULL; |
| 830 |
|
const struct ssh2cipher *cipher = NULL; |
| 831 |
|
struct sshcipher_ctx *cc = NULL; |
| 832 |
|
|
| 833 |
result = (Key *)malloc(sizeof(Key)); |
result = (Key *)malloc(sizeof(Key)); |
| 834 |
ZeroMemory(result, sizeof(Key)); |
ZeroMemory(result, sizeof(Key)); |
| 955 |
} |
} |
| 956 |
|
|
| 957 |
cipher_ctx = EVP_CIPHER_CTX_new(); |
cipher_ctx = EVP_CIPHER_CTX_new(); |
| 958 |
if (ctx == NULL) { |
if (cipher_ctx == NULL) { |
| 959 |
EVP_MD_CTX_free(ctx); |
EVP_MD_CTX_free(ctx); |
| 960 |
goto error; |
goto error; |
| 961 |
} |
} |
| 975 |
memset(iv, 0, sizeof(iv)); |
memset(iv, 0, sizeof(iv)); |
| 976 |
|
|
| 977 |
// decrypt |
// decrypt |
| 978 |
cipher_init_SSH2(cipher_ctx, key, 32, iv, 16, CIPHER_DECRYPT, EVP_aes_256_cbc(), 0, 0, pvar); |
cipher = get_cipher_by_name("aes256-cbc"); |
| 979 |
|
cipher_init_SSH2(&cc, cipher, key, 32, iv, 16, CIPHER_DECRYPT, pvar); |
| 980 |
len = buffer_len(prikey); |
len = buffer_len(prikey); |
| 981 |
decrypted = (char *)malloc(len); |
decrypted = (char *)malloc(len); |
| 982 |
ret = EVP_Cipher(cipher_ctx, decrypted, prikey->buf, len); |
ret = EVP_Cipher(cc->evp, decrypted, prikey->buf, len); |
| 983 |
if (ret == 0) { |
if (ret == 0) { |
| 984 |
strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE); |
strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE); |
| 985 |
free(decrypted); |
free(decrypted); |
| 986 |
cipher_cleanup_SSH2(cipher_ctx); |
cipher_free_SSH2(cc); |
|
EVP_CIPHER_CTX_free(cipher_ctx); |
|
| 987 |
goto error; |
goto error; |
| 988 |
} |
} |
| 989 |
buffer_clear(prikey); |
buffer_clear(prikey); |
| 990 |
buffer_append(prikey, decrypted, len); |
buffer_append(prikey, decrypted, len); |
| 991 |
free(decrypted); |
free(decrypted); |
| 992 |
cipher_cleanup_SSH2(cipher_ctx); |
cipher_free_SSH2(cc); |
|
EVP_CIPHER_CTX_free(cipher_ctx); |
|
| 993 |
} |
} |
| 994 |
|
|
| 995 |
// verity MAC |
// verity MAC |
| 1000 |
|
|
| 1001 |
macdata = buffer_init(); |
macdata = buffer_init(); |
| 1002 |
|
|
| 1003 |
len = strlen(get_ssh_keytype_name(result->type)); |
len = strlen(get_ssh2_hostkey_type_name(result->type)); |
| 1004 |
buffer_put_int(macdata, len); |
buffer_put_int(macdata, len); |
| 1005 |
buffer_append(macdata, get_ssh_keytype_name(result->type), len); |
buffer_append(macdata, get_ssh2_hostkey_type_name(result->type), len); |
| 1006 |
len = strlen(encname); |
len = strlen(encname); |
| 1007 |
buffer_put_int(macdata, len); |
buffer_put_int(macdata, len); |
| 1008 |
buffer_append(macdata, encname, len); |
buffer_append(macdata, encname, len); |
| 1406 |
int encflag; |
int encflag; |
| 1407 |
char *encname = NULL; |
char *encname = NULL; |
| 1408 |
buffer_t *blob = NULL, *blob2 = NULL; |
buffer_t *blob = NULL, *blob2 = NULL; |
| 1409 |
|
const struct ssh2cipher *cipher = NULL; |
| 1410 |
|
struct sshcipher_ctx *cc = NULL; |
| 1411 |
|
|
| 1412 |
result = (Key *)malloc(sizeof(Key)); |
result = (Key *)malloc(sizeof(Key)); |
| 1413 |
ZeroMemory(result, sizeof(Key)); |
ZeroMemory(result, sizeof(Key)); |
| 1549 |
memset(iv, 0, sizeof(iv)); |
memset(iv, 0, sizeof(iv)); |
| 1550 |
|
|
| 1551 |
// decrypt |
// decrypt |
| 1552 |
cipher_init_SSH2(cipher_ctx, key, 24, iv, 8, CIPHER_DECRYPT, EVP_des_ede3_cbc(), 0, 0, pvar); |
cipher = get_cipher_by_name("3des-cbc"); |
| 1553 |
|
cipher_init_SSH2(&cc, cipher, key, 24, iv, 8, CIPHER_DECRYPT, pvar); |
| 1554 |
decrypted = (char *)malloc(len); |
decrypted = (char *)malloc(len); |
| 1555 |
ret = EVP_Cipher(cipher_ctx, decrypted, blob->buf + blob->offset, len); |
ret = EVP_Cipher(cc->evp, decrypted, blob->buf + blob->offset, len); |
| 1556 |
if (ret == 0) { |
if (ret == 0) { |
| 1557 |
strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE); |
strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE); |
| 1558 |
cipher_cleanup_SSH2(cipher_ctx); |
cipher_free_SSH2(cc); |
|
EVP_CIPHER_CTX_free(cipher_ctx); |
|
| 1559 |
goto error; |
goto error; |
| 1560 |
} |
} |
| 1561 |
buffer_append(blob2, decrypted, len); |
buffer_append(blob2, decrypted, len); |
| 1562 |
free(decrypted); |
free(decrypted); |
| 1563 |
cipher_cleanup_SSH2(cipher_ctx); |
cipher_free_SSH2(cc); |
|
EVP_CIPHER_CTX_free(cipher_ctx); |
|
| 1564 |
|
|
| 1565 |
*invalid_passphrase = TRUE; |
*invalid_passphrase = TRUE; |
| 1566 |
} |
} |