| 153 |
FWDUI_init(pvar); |
FWDUI_init(pvar); |
| 154 |
|
|
| 155 |
ssh_heartbeat_lock_initialize(); |
ssh_heartbeat_lock_initialize(); |
| 156 |
|
|
| 157 |
|
pvar->evpcip[MODE_IN] = EVP_CIPHER_CTX_new(); |
| 158 |
|
pvar->evpcip[MODE_OUT] = EVP_CIPHER_CTX_new(); |
| 159 |
|
/*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335で処置予定) ***/ |
| 160 |
} |
} |
| 161 |
|
|
| 162 |
static void uninit_TTSSH(PTInstVar pvar) |
static void uninit_TTSSH(PTInstVar pvar) |
| 188 |
} |
} |
| 189 |
|
|
| 190 |
ssh_heartbeat_lock_finalize(); |
ssh_heartbeat_lock_finalize(); |
| 191 |
|
|
| 192 |
|
EVP_CIPHER_CTX_free(pvar->evpcip[MODE_IN]); |
| 193 |
|
EVP_CIPHER_CTX_free(pvar->evpcip[MODE_OUT]); |
| 194 |
} |
} |
| 195 |
|
|
| 196 |
static void PASCAL TTXInit(PTTSet ts, PComVar cv) |
static void PASCAL TTXInit(PTTSet ts, PComVar cv) |
| 3388 |
|
|
| 3389 |
static BOOL generate_ssh_key(ssh_keytype type, int bits, void (*cbfunc)(int, int, void *), void *cbarg) |
static BOOL generate_ssh_key(ssh_keytype type, int bits, void (*cbfunc)(int, int, void *), void *cbarg) |
| 3390 |
{ |
{ |
| 3391 |
|
|
| 3392 |
// if SSH key already is generated, should free the resource. |
// if SSH key already is generated, should free the resource. |
| 3393 |
free_ssh_key(); |
free_ssh_key(); |
| 3394 |
|
|
| 3398 |
{ |
{ |
| 3399 |
RSA *priv = NULL; |
RSA *priv = NULL; |
| 3400 |
RSA *pub = NULL; |
RSA *pub = NULL; |
| 3401 |
|
BIGNUM *e, *n; |
| 3402 |
|
BIGNUM *p_e, *p_n; |
| 3403 |
|
|
| 3404 |
// private key |
// private key |
| 3405 |
priv = RSA_generate_key(bits, 35, cbfunc, cbarg); |
priv = RSA_generate_key(bits, 35, cbfunc, cbarg); |
| 3409 |
|
|
| 3410 |
// public key |
// public key |
| 3411 |
pub = RSA_new(); |
pub = RSA_new(); |
| 3412 |
pub->n = BN_new(); |
n = BN_new(); |
| 3413 |
pub->e = BN_new(); |
e = BN_new(); |
| 3414 |
if (pub->n == NULL || pub->e == NULL) { |
RSA_set0_key(pub, n, e, NULL); |
| 3415 |
|
if (n == NULL || e == NULL) { |
| 3416 |
RSA_free(pub); |
RSA_free(pub); |
| 3417 |
goto error; |
goto error; |
| 3418 |
} |
} |
| 3419 |
|
|
| 3420 |
BN_copy(pub->n, priv->n); |
RSA_get0_key(priv, &p_n, &p_e, NULL); |
| 3421 |
BN_copy(pub->e, priv->e); |
|
| 3422 |
|
BN_copy(n, p_n); |
| 3423 |
|
BN_copy(e, p_e); |
| 3424 |
public_key.rsa = pub; |
public_key.rsa = pub; |
| 3425 |
break; |
break; |
| 3426 |
} |
} |
| 3429 |
{ |
{ |
| 3430 |
DSA *priv = NULL; |
DSA *priv = NULL; |
| 3431 |
DSA *pub = NULL; |
DSA *pub = NULL; |
| 3432 |
|
BIGNUM *p, *q, *g, *pub_key; |
| 3433 |
|
BIGNUM *sp, *sq, *sg, *spub_key; |
| 3434 |
|
|
| 3435 |
// private key |
// private key |
| 3436 |
priv = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, cbfunc, cbarg); |
priv = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, cbfunc, cbarg); |
| 3446 |
pub = DSA_new(); |
pub = DSA_new(); |
| 3447 |
if (pub == NULL) |
if (pub == NULL) |
| 3448 |
goto error; |
goto error; |
| 3449 |
pub->p = BN_new(); |
p = BN_new(); |
| 3450 |
pub->q = BN_new(); |
q = BN_new(); |
| 3451 |
pub->g = BN_new(); |
g = BN_new(); |
| 3452 |
pub->pub_key = BN_new(); |
DSA_set0_pqg(pub, p, q, g); |
| 3453 |
if (pub->p == NULL || pub->q == NULL || pub->g == NULL || pub->pub_key == NULL) { |
pub_key = BN_new(); |
| 3454 |
|
DSA_set0_key(pub, pub_key, NULL); |
| 3455 |
|
if (p == NULL || q == NULL || g == NULL || pub_key == NULL) { |
| 3456 |
DSA_free(pub); |
DSA_free(pub); |
| 3457 |
goto error; |
goto error; |
| 3458 |
} |
} |
| 3459 |
|
|
| 3460 |
BN_copy(pub->p, priv->p); |
DSA_get0_pqg(priv, &sp, &sq, &sg); |
| 3461 |
BN_copy(pub->q, priv->q); |
DSA_get0_key(priv, &spub_key, NULL); |
| 3462 |
BN_copy(pub->g, priv->g); |
|
| 3463 |
BN_copy(pub->pub_key, priv->pub_key); |
BN_copy(p, sp); |
| 3464 |
|
BN_copy(q, sq); |
| 3465 |
|
BN_copy(g, sg); |
| 3466 |
|
BN_copy(pub_key, spub_key); |
| 3467 |
public_key.dsa = pub; |
public_key.dsa = pub; |
| 3468 |
break; |
break; |
| 3469 |
} |
} |
| 3555 |
*/ |
*/ |
| 3556 |
struct ssh1_3des_ctx |
struct ssh1_3des_ctx |
| 3557 |
{ |
{ |
| 3558 |
EVP_CIPHER_CTX k1, k2, k3; |
EVP_CIPHER_CTX *k1, *k2, *k3; |
| 3559 |
}; |
}; |
| 3560 |
|
|
| 3561 |
static int ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, int enc) |
static int ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, int enc) |
| 3565 |
|
|
| 3566 |
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { |
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { |
| 3567 |
c = malloc(sizeof(*c)); |
c = malloc(sizeof(*c)); |
| 3568 |
|
c->k1 = EVP_CIPHER_CTX_new(); |
| 3569 |
|
c->k2 = EVP_CIPHER_CTX_new(); |
| 3570 |
|
c->k3 = EVP_CIPHER_CTX_new(); |
| 3571 |
|
/*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335で処置予定) ***/ |
| 3572 |
EVP_CIPHER_CTX_set_app_data(ctx, c); |
EVP_CIPHER_CTX_set_app_data(ctx, c); |
| 3573 |
} |
} |
| 3574 |
if (key == NULL) |
if (key == NULL) |
| 3575 |
return (1); |
return (1); |
| 3576 |
if (enc == -1) |
if (enc == -1) |
| 3577 |
enc = ctx->encrypt; |
enc = EVP_CIPHER_CTX_encrypting(ctx); // ctx->encrypt |
| 3578 |
k1 = k2 = k3 = (u_char *) key; |
k1 = k2 = k3 = (u_char *) key; |
| 3579 |
k2 += 8; |
k2 += 8; |
| 3580 |
if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) { |
if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) { |
| 3583 |
else |
else |
| 3584 |
k1 += 16; |
k1 += 16; |
| 3585 |
} |
} |
| 3586 |
EVP_CIPHER_CTX_init(&c->k1); |
EVP_CIPHER_CTX_init(c->k1); |
| 3587 |
EVP_CIPHER_CTX_init(&c->k2); |
EVP_CIPHER_CTX_init(c->k2); |
| 3588 |
EVP_CIPHER_CTX_init(&c->k3); |
EVP_CIPHER_CTX_init(c->k3); |
| 3589 |
if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || |
if (EVP_CipherInit(c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || |
| 3590 |
EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || |
EVP_CipherInit(c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || |
| 3591 |
EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { |
EVP_CipherInit(c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { |
| 3592 |
|
EVP_CIPHER_CTX_free(c->k1); |
| 3593 |
|
EVP_CIPHER_CTX_free(c->k2); |
| 3594 |
|
EVP_CIPHER_CTX_free(c->k3); |
| 3595 |
SecureZeroMemory(c, sizeof(*c)); |
SecureZeroMemory(c, sizeof(*c)); |
| 3596 |
free(c); |
free(c); |
| 3597 |
EVP_CIPHER_CTX_set_app_data(ctx, NULL); |
EVP_CIPHER_CTX_set_app_data(ctx, NULL); |
| 3608 |
//error("ssh1_3des_cbc: no context"); |
//error("ssh1_3des_cbc: no context"); |
| 3609 |
return (0); |
return (0); |
| 3610 |
} |
} |
| 3611 |
if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 || |
if (EVP_Cipher(c->k1, dest, (u_char *)src, len) == 0 || |
| 3612 |
EVP_Cipher(&c->k2, dest, dest, len) == 0 || |
EVP_Cipher(c->k2, dest, dest, len) == 0 || |
| 3613 |
EVP_Cipher(&c->k3, dest, dest, len) == 0) |
EVP_Cipher(c->k3, dest, dest, len) == 0) |
| 3614 |
return (0); |
return (0); |
| 3615 |
return (1); |
return (1); |
| 3616 |
} |
} |
| 3620 |
struct ssh1_3des_ctx *c; |
struct ssh1_3des_ctx *c; |
| 3621 |
|
|
| 3622 |
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { |
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { |
| 3623 |
EVP_CIPHER_CTX_cleanup(&c->k1); |
EVP_CIPHER_CTX_cleanup(c->k1); |
| 3624 |
EVP_CIPHER_CTX_cleanup(&c->k2); |
EVP_CIPHER_CTX_cleanup(c->k2); |
| 3625 |
EVP_CIPHER_CTX_cleanup(&c->k3); |
EVP_CIPHER_CTX_cleanup(c->k3); |
| 3626 |
SecureZeroMemory(c, sizeof(*c)); |
SecureZeroMemory(c, sizeof(*c)); |
| 3627 |
free(c); |
free(c); |
| 3628 |
EVP_CIPHER_CTX_set_app_data(ctx, NULL); |
EVP_CIPHER_CTX_set_app_data(ctx, NULL); |
| 3630 |
return (1); |
return (1); |
| 3631 |
} |
} |
| 3632 |
|
|
| 3633 |
|
// 下記関数は未使用。 |
| 3634 |
void ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len) |
void ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len) |
| 3635 |
{ |
{ |
| 3636 |
struct ssh1_3des_ctx *c; |
struct ssh1_3des_ctx *c; |
| 3645 |
|
|
| 3646 |
if (doset) { |
if (doset) { |
| 3647 |
//debug3("%s: Installed 3DES IV", __func__); |
//debug3("%s: Installed 3DES IV", __func__); |
| 3648 |
memcpy(c->k1.iv, iv, 8); |
memcpy(EVP_CIPHER_CTX_iv_noconst(c->k1), iv, 8); |
| 3649 |
memcpy(c->k2.iv, iv + 8, 8); |
memcpy(EVP_CIPHER_CTX_iv_noconst(c->k2), iv + 8, 8); |
| 3650 |
memcpy(c->k3.iv, iv + 16, 8); |
memcpy(EVP_CIPHER_CTX_iv_noconst(c->k3), iv + 16, 8); |
| 3651 |
} else { |
} else { |
| 3652 |
//debug3("%s: Copying 3DES IV", __func__); |
//debug3("%s: Copying 3DES IV", __func__); |
| 3653 |
memcpy(iv, c->k1.iv, 8); |
memcpy(iv, EVP_CIPHER_CTX_iv(c->k1), 8); |
| 3654 |
memcpy(iv + 8, c->k2.iv, 8); |
memcpy(iv + 8, EVP_CIPHER_CTX_iv(c->k2), 8); |
| 3655 |
memcpy(iv + 16, c->k3.iv, 8); |
memcpy(iv + 16, EVP_CIPHER_CTX_iv(c->k3), 8); |
| 3656 |
} |
} |
| 3657 |
} |
} |
| 3658 |
|
|
| 3659 |
const EVP_CIPHER *evp_ssh1_3des(void) |
const EVP_CIPHER *evp_ssh1_3des(void) |
| 3660 |
{ |
{ |
| 3661 |
static EVP_CIPHER ssh1_3des; |
static EVP_CIPHER *p = NULL; |
| 3662 |
|
|
| 3663 |
memset(&ssh1_3des, 0, sizeof(EVP_CIPHER)); |
if (p == NULL) { |
| 3664 |
ssh1_3des.nid = NID_undef; |
p = EVP_CIPHER_meth_new(NID_undef, /*block_size*/8, /*key_len*/16); |
| 3665 |
ssh1_3des.block_size = 8; |
/*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335で処置予定) ***/ |
| 3666 |
ssh1_3des.iv_len = 0; |
} |
| 3667 |
ssh1_3des.key_len = 16; |
if (p) { |
| 3668 |
ssh1_3des.init = ssh1_3des_init; |
EVP_CIPHER_meth_set_iv_length(p, 0); |
| 3669 |
ssh1_3des.cleanup = ssh1_3des_cleanup; |
EVP_CIPHER_meth_set_init(p, ssh1_3des_init); |
| 3670 |
ssh1_3des.do_cipher = ssh1_3des_cbc; |
EVP_CIPHER_meth_set_cleanup(p, ssh1_3des_cleanup); |
| 3671 |
ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH; |
EVP_CIPHER_meth_set_do_cipher(p, ssh1_3des_cbc); |
| 3672 |
return (&ssh1_3des); |
EVP_CIPHER_meth_set_flags(p, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH); |
| 3673 |
|
} |
| 3674 |
|
return (p); |
| 3675 |
} |
} |
| 3676 |
|
|
| 3677 |
static void ssh_make_comment(char *comment, int maxlen) |
static void ssh_make_comment(char *comment, int maxlen) |
| 4037 |
int blocksize, keylen, ivlen, authlen, i, n; |
int blocksize, keylen, ivlen, authlen, i, n; |
| 4038 |
unsigned char *key = NULL, salt[SALT_LEN]; |
unsigned char *key = NULL, salt[SALT_LEN]; |
| 4039 |
char *kdfname = KDFNAME; |
char *kdfname = KDFNAME; |
| 4040 |
EVP_CIPHER_CTX cipher_ctx; |
EVP_CIPHER_CTX *cipher_ctx = NULL; |
| 4041 |
Key keyblob; |
Key keyblob; |
| 4042 |
unsigned char *cp = NULL; |
unsigned char *cp = NULL; |
| 4043 |
unsigned int len, check; |
unsigned int len, check; |
| 4048 |
kdf = buffer_init(); |
kdf = buffer_init(); |
| 4049 |
encoded = buffer_init(); |
encoded = buffer_init(); |
| 4050 |
blob = buffer_init(); |
blob = buffer_init(); |
| 4051 |
if (b == NULL || kdf == NULL || encoded == NULL || blob == NULL) |
cipher_ctx = EVP_CIPHER_CTX_new(); |
| 4052 |
|
if (b == NULL || kdf == NULL || encoded == NULL || blob == NULL || cipher_ctx == NULL) |
| 4053 |
goto ed25519_error; |
goto ed25519_error; |
| 4054 |
|
|
| 4055 |
if (passphrase == NULL || !strlen(passphrase)) { |
if (passphrase == NULL || !strlen(passphrase)) { |
| 4076 |
// 暗号化の準備 |
// 暗号化の準備 |
| 4077 |
// TODO: OpenSSH 6.5では -Z オプションで、暗号化アルゴリズムを指定可能だが、 |
// TODO: OpenSSH 6.5では -Z オプションで、暗号化アルゴリズムを指定可能だが、 |
| 4078 |
// ここでは"AES256-CBC"に固定とする。 |
// ここでは"AES256-CBC"に固定とする。 |
| 4079 |
cipher_init_SSH2(&cipher_ctx, key, keylen, key + keylen, ivlen, CIPHER_ENCRYPT, |
cipher_init_SSH2(cipher_ctx, key, keylen, key + keylen, ivlen, CIPHER_ENCRYPT, |
| 4080 |
get_cipher_EVP_CIPHER(cipher), 0, 0, pvar); |
get_cipher_EVP_CIPHER(cipher), 0, 0, pvar); |
| 4081 |
SecureZeroMemory(key, keylen + ivlen); |
SecureZeroMemory(key, keylen + ivlen); |
| 4082 |
free(key); |
free(key); |
| 4120 |
|
|
| 4121 |
/* encrypt */ |
/* encrypt */ |
| 4122 |
cp = buffer_append_space(encoded, buffer_len(b) + authlen); |
cp = buffer_append_space(encoded, buffer_len(b) + authlen); |
| 4123 |
if (EVP_Cipher(&cipher_ctx, cp, buffer_ptr(b), buffer_len(b)) == 0) { |
if (EVP_Cipher(cipher_ctx, cp, buffer_ptr(b), buffer_len(b)) == 0) { |
| 4124 |
//strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE); |
//strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE); |
| 4125 |
//free(decrypted); |
//free(decrypted); |
| 4126 |
//goto error; |
//goto error; |
| 4127 |
} |
} |
| 4128 |
cipher_cleanup_SSH2(&cipher_ctx); |
cipher_cleanup_SSH2(cipher_ctx); |
| 4129 |
|
|
| 4130 |
len = 2 * buffer_len(encoded); |
len = 2 * buffer_len(encoded); |
| 4131 |
cp = malloc(len); |
cp = malloc(len); |
| 4175 |
buffer_free(kdf); |
buffer_free(kdf); |
| 4176 |
buffer_free(encoded); |
buffer_free(encoded); |
| 4177 |
buffer_free(blob); |
buffer_free(blob); |
| 4178 |
|
|
| 4179 |
|
if (cipher_ctx) { |
| 4180 |
|
EVP_CIPHER_CTX_free(cipher_ctx); |
| 4181 |
|
} |
| 4182 |
} |
} |
| 4183 |
|
|
| 4184 |
static INT_PTR CALLBACK TTXKeyGenerator(HWND dlg, UINT msg, WPARAM wParam, |
static INT_PTR CALLBACK TTXKeyGenerator(HWND dlg, UINT msg, WPARAM wParam, |
| 4358 |
|
|
| 4359 |
// set focus to passphrase edit control (2007.1.27 maya) |
// set focus to passphrase edit control (2007.1.27 maya) |
| 4360 |
SetFocus(GetDlgItem(dlg, IDC_KEY_EDIT)); |
SetFocus(GetDlgItem(dlg, IDC_KEY_EDIT)); |
| 4361 |
|
|
| 4362 |
|
} else { |
| 4363 |
|
// generate_ssh_key()が失敗した場合においても、ダイアログを |
| 4364 |
|
// クローズできるようにしておく。 |
| 4365 |
|
EnableWindow(GetDlgItem(dlg, IDOK), TRUE); |
| 4366 |
|
EnableWindow(GetDlgItem(dlg, IDCANCEL), TRUE); |
| 4367 |
|
|
| 4368 |
} |
} |
| 4369 |
return TRUE; |
return TRUE; |
| 4370 |
} |
} |
| 4574 |
RSA *rsa = public_key.rsa; |
RSA *rsa = public_key.rsa; |
| 4575 |
int bits; |
int bits; |
| 4576 |
char *buf; |
char *buf; |
| 4577 |
|
BIGNUM *e, *n; |
| 4578 |
|
|
| 4579 |
bits = BN_num_bits(rsa->n); |
RSA_get0_key(rsa, &n, &e, NULL); |
| 4580 |
|
|
| 4581 |
|
bits = BN_num_bits(n); |
| 4582 |
fprintf(fp, "%u", bits); |
fprintf(fp, "%u", bits); |
| 4583 |
|
|
| 4584 |
buf = BN_bn2dec(rsa->e); |
buf = BN_bn2dec(e); |
| 4585 |
fprintf(fp, " %s", buf); |
fprintf(fp, " %s", buf); |
| 4586 |
OPENSSL_free(buf); |
OPENSSL_free(buf); |
| 4587 |
|
|
| 4588 |
buf = BN_bn2dec(rsa->n); |
buf = BN_bn2dec(n); |
| 4589 |
fprintf(fp, " %s", buf); |
fprintf(fp, " %s", buf); |
| 4590 |
OPENSSL_free(buf); |
OPENSSL_free(buf); |
| 4591 |
|
|
| 4599 |
char *blob; |
char *blob; |
| 4600 |
char *uuenc; // uuencode data |
char *uuenc; // uuencode data |
| 4601 |
int uulen; |
int uulen; |
| 4602 |
|
BIGNUM *e, *n; |
| 4603 |
|
BIGNUM *p, *q, *g, *pub_key; |
| 4604 |
|
|
| 4605 |
b = buffer_init(); |
b = buffer_init(); |
| 4606 |
if (b == NULL) |
if (b == NULL) |
| 4608 |
|
|
| 4609 |
switch (public_key.type) { |
switch (public_key.type) { |
| 4610 |
case KEY_DSA: // DSA |
case KEY_DSA: // DSA |
| 4611 |
|
DSA_get0_pqg(dsa, &p, &q, &g); |
| 4612 |
|
DSA_get0_key(dsa, &pub_key, NULL); |
| 4613 |
|
|
| 4614 |
keyname = "ssh-dss"; |
keyname = "ssh-dss"; |
| 4615 |
buffer_put_string(b, keyname, strlen(keyname)); |
buffer_put_string(b, keyname, strlen(keyname)); |
| 4616 |
buffer_put_bignum2(b, dsa->p); |
buffer_put_bignum2(b, p); |
| 4617 |
buffer_put_bignum2(b, dsa->q); |
buffer_put_bignum2(b, q); |
| 4618 |
buffer_put_bignum2(b, dsa->g); |
buffer_put_bignum2(b, g); |
| 4619 |
buffer_put_bignum2(b, dsa->pub_key); |
buffer_put_bignum2(b, pub_key); |
| 4620 |
break; |
break; |
| 4621 |
|
|
| 4622 |
case KEY_RSA: // RSA |
case KEY_RSA: // RSA |
| 4623 |
|
RSA_get0_key(rsa, &n, &e, NULL); |
| 4624 |
keyname = "ssh-rsa"; |
keyname = "ssh-rsa"; |
| 4625 |
buffer_put_string(b, keyname, strlen(keyname)); |
buffer_put_string(b, keyname, strlen(keyname)); |
| 4626 |
buffer_put_bignum2(b, rsa->e); |
buffer_put_bignum2(b, e); |
| 4627 |
buffer_put_bignum2(b, rsa->n); |
buffer_put_bignum2(b, n); |
| 4628 |
break; |
break; |
| 4629 |
|
|
| 4630 |
case KEY_ECDSA256: // ECDSA |
case KEY_ECDSA256: // ECDSA |
| 4795 |
MD5_CTX md; |
MD5_CTX md; |
| 4796 |
unsigned char digest[16]; |
unsigned char digest[16]; |
| 4797 |
char *passphrase = buf; |
char *passphrase = buf; |
| 4798 |
EVP_CIPHER_CTX cipher_ctx; |
EVP_CIPHER_CTX *cipher_ctx = NULL; |
| 4799 |
FILE *fp; |
FILE *fp; |
| 4800 |
char wrapped[4096]; |
char wrapped[4096]; |
| 4801 |
|
BIGNUM *e, *n, *d, *dmp1, *dmq1, *iqmp, *p, *q; |
| 4802 |
|
|
| 4803 |
if (passphrase[0] == '\0') { // passphrase is empty |
if (passphrase[0] == '\0') { // passphrase is empty |
| 4804 |
cipher_num = SSH_CIPHER_NONE; |
cipher_num = SSH_CIPHER_NONE; |
| 4815 |
break; |
break; |
| 4816 |
} |
} |
| 4817 |
|
|
| 4818 |
|
cipher_ctx = EVP_CIPHER_CTX_new(); |
| 4819 |
|
/*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335で処置予定) ***/ |
| 4820 |
|
|
| 4821 |
// set random value |
// set random value |
| 4822 |
rnd = arc4random(); |
rnd = arc4random(); |
| 4823 |
tmp[0] = rnd & 0xff; |
tmp[0] = rnd & 0xff; |
| 4828 |
|
|
| 4829 |
// set private key |
// set private key |
| 4830 |
rsa = private_key.rsa; |
rsa = private_key.rsa; |
| 4831 |
buffer_put_bignum(b, rsa->d); |
RSA_get0_key(rsa, &n, &e, &d); |
| 4832 |
buffer_put_bignum(b, rsa->iqmp); |
RSA_get0_factors(rsa, &p, &q); |
| 4833 |
buffer_put_bignum(b, rsa->q); |
RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); |
| 4834 |
buffer_put_bignum(b, rsa->p); |
buffer_put_bignum(b, d); |
| 4835 |
|
buffer_put_bignum(b, iqmp); |
| 4836 |
|
buffer_put_bignum(b, q); |
| 4837 |
|
buffer_put_bignum(b, p); |
| 4838 |
|
|
| 4839 |
// padding with 8byte align |
// padding with 8byte align |
| 4840 |
while (buffer_len(b) % 8) { |
while (buffer_len(b) % 8) { |
| 4857 |
buffer_put_int(enc, 0); // type is 'int'!! (For future extension) |
buffer_put_int(enc, 0); // type is 'int'!! (For future extension) |
| 4858 |
|
|
| 4859 |
/* Store public key. This will be in plain text. */ |
/* Store public key. This will be in plain text. */ |
| 4860 |
buffer_put_int(enc, BN_num_bits(rsa->n)); |
buffer_put_int(enc, BN_num_bits(n)); |
| 4861 |
buffer_put_bignum(enc, rsa->n); |
buffer_put_bignum(enc, n); |
| 4862 |
buffer_put_bignum(enc, rsa->e); |
buffer_put_bignum(enc, e); |
| 4863 |
buffer_put_string(enc, comment, strlen(comment)); |
buffer_put_string(enc, comment, strlen(comment)); |
| 4864 |
|
|
| 4865 |
// setup the MD5ed passphrase to cipher encryption key |
// setup the MD5ed passphrase to cipher encryption key |
| 4867 |
MD5_Update(&md, (const unsigned char *)passphrase, strlen(passphrase)); |
MD5_Update(&md, (const unsigned char *)passphrase, strlen(passphrase)); |
| 4868 |
MD5_Final(digest, &md); |
MD5_Final(digest, &md); |
| 4869 |
if (cipher_num == SSH_CIPHER_NONE) { |
if (cipher_num == SSH_CIPHER_NONE) { |
| 4870 |
cipher_init_SSH2(&cipher_ctx, digest, 16, NULL, 0, CIPHER_ENCRYPT, EVP_enc_null(), 0, 0, pvar); |
cipher_init_SSH2(cipher_ctx, digest, 16, NULL, 0, CIPHER_ENCRYPT, EVP_enc_null(), 0, 0, pvar); |
| 4871 |
} else { |
} else { |
| 4872 |
cipher_init_SSH2(&cipher_ctx, digest, 16, NULL, 0, CIPHER_ENCRYPT, evp_ssh1_3des(), 0, 0, pvar); |
cipher_init_SSH2(cipher_ctx, digest, 16, NULL, 0, CIPHER_ENCRYPT, evp_ssh1_3des(), 0, 0, pvar); |
| 4873 |
} |
} |
| 4874 |
len = buffer_len(b); |
len = buffer_len(b); |
| 4875 |
if (len % 8) { // fatal error |
if (len % 8) { // fatal error |
| 4881 |
goto error; |
goto error; |
| 4882 |
} |
} |
| 4883 |
|
|
| 4884 |
if (EVP_Cipher(&cipher_ctx, wrapped, buffer_ptr(b), len) == 0) { |
if (EVP_Cipher(cipher_ctx, wrapped, buffer_ptr(b), len) == 0) { |
| 4885 |
goto error; |
goto error; |
| 4886 |
} |
} |
| 4887 |
if (EVP_CIPHER_CTX_cleanup(&cipher_ctx) == 0) { |
if (EVP_CIPHER_CTX_cleanup(cipher_ctx) == 0) { |
| 4888 |
goto error; |
goto error; |
| 4889 |
} |
} |
| 4890 |
|
|
| 4907 |
error:; |
error:; |
| 4908 |
buffer_free(b); |
buffer_free(b); |
| 4909 |
buffer_free(enc); |
buffer_free(enc); |
| 4910 |
|
if (cipher_ctx) { |
| 4911 |
|
EVP_CIPHER_CTX_free(cipher_ctx); |
| 4912 |
|
} |
| 4913 |
|
|
| 4914 |
} else if (private_key.type == KEY_ED25519) { // SSH2 ED25519 |
} else if (private_key.type == KEY_ED25519) { // SSH2 ED25519 |
| 4915 |
save_bcrypt_private_key(buf, filename, comment, dlg, pvar, rounds); |
save_bcrypt_private_key(buf, filename, comment, dlg, pvar, rounds); |