mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-25 01:02:24 +00:00
Support importing of new-style OpenSSH private keys (encrypted by
AES rather than 3DES). [originally from svn r8916]
This commit is contained in:
parent
332f233503
commit
108791e15c
43
import.c
43
import.c
@ -308,9 +308,10 @@ static int ssh2_read_mpint(void *data, int len, struct mpint_pos *ret)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
enum { OSSH_DSA, OSSH_RSA };
|
enum { OSSH_DSA, OSSH_RSA };
|
||||||
|
enum { OSSH_ENC_3DES, OSSH_ENC_AES };
|
||||||
struct openssh_key {
|
struct openssh_key {
|
||||||
int type;
|
int type;
|
||||||
int encrypted;
|
int encrypted, encryption;
|
||||||
char iv[32];
|
char iv[32];
|
||||||
unsigned char *keyblob;
|
unsigned char *keyblob;
|
||||||
int keyblob_len, keyblob_size;
|
int keyblob_len, keyblob_size;
|
||||||
@ -387,21 +388,29 @@ static struct openssh_key *load_openssh_key(const Filename *filename,
|
|||||||
if (!strcmp(p, "ENCRYPTED"))
|
if (!strcmp(p, "ENCRYPTED"))
|
||||||
ret->encrypted = 1;
|
ret->encrypted = 1;
|
||||||
} else if (!strcmp(line, "DEK-Info")) {
|
} else if (!strcmp(line, "DEK-Info")) {
|
||||||
int i, j;
|
int i, j, ivlen;
|
||||||
|
|
||||||
if (strncmp(p, "DES-EDE3-CBC,", 13)) {
|
if (!strncmp(p, "DES-EDE3-CBC,", 13)) {
|
||||||
errmsg = "ciphers other than DES-EDE3-CBC not supported";
|
ret->encryption = OSSH_ENC_3DES;
|
||||||
|
ivlen = 8;
|
||||||
|
} else if (!strncmp(p, "AES-128-CBC,", 12)) {
|
||||||
|
ret->encryption = OSSH_ENC_AES;
|
||||||
|
ivlen = 16;
|
||||||
|
} else {
|
||||||
|
errmsg = "unsupported cipher";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
p += 13;
|
p = strchr(p, ',') + 1;/* always non-NULL, by above checks */
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < ivlen; i++) {
|
||||||
if (1 != sscanf(p, "%2x", &j))
|
if (1 != sscanf(p, "%2x", &j)) {
|
||||||
break;
|
errmsg = "expected more iv data in DEK-Info";
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
ret->iv[i] = j;
|
ret->iv[i] = j;
|
||||||
p += 2;
|
p += 2;
|
||||||
}
|
}
|
||||||
if (i < 8) {
|
if (*p) {
|
||||||
errmsg = "expected 16-digit iv in DEK-Info";
|
errmsg = "more iv data than expected in DEK-Info";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -538,8 +547,18 @@ struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase,
|
|||||||
/*
|
/*
|
||||||
* Now decrypt the key blob.
|
* Now decrypt the key blob.
|
||||||
*/
|
*/
|
||||||
des3_decrypt_pubkey_ossh(keybuf, (unsigned char *)key->iv,
|
if (key->encryption == OSSH_ENC_3DES)
|
||||||
key->keyblob, key->keyblob_len);
|
des3_decrypt_pubkey_ossh(keybuf, (unsigned char *)key->iv,
|
||||||
|
key->keyblob, key->keyblob_len);
|
||||||
|
else {
|
||||||
|
void *ctx;
|
||||||
|
assert(key->encryption == OSSH_ENC_AES);
|
||||||
|
ctx = aes_make_context();
|
||||||
|
aes128_key(ctx, keybuf);
|
||||||
|
aes_iv(ctx, (unsigned char *)key->iv);
|
||||||
|
aes_ssh2_decrypt_blk(ctx, key->keyblob, key->keyblob_len);
|
||||||
|
aes_free_context(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
memset(&md5c, 0, sizeof(md5c));
|
memset(&md5c, 0, sizeof(md5c));
|
||||||
memset(keybuf, 0, sizeof(keybuf));
|
memset(keybuf, 0, sizeof(keybuf));
|
||||||
|
8
ssh.h
8
ssh.h
@ -290,6 +290,14 @@ extern const struct ssh_mac ssh_hmac_sha1_buggy;
|
|||||||
extern const struct ssh_mac ssh_hmac_sha1_96;
|
extern const struct ssh_mac ssh_hmac_sha1_96;
|
||||||
extern const struct ssh_mac ssh_hmac_sha1_96_buggy;
|
extern const struct ssh_mac ssh_hmac_sha1_96_buggy;
|
||||||
|
|
||||||
|
void *aes_make_context(void);
|
||||||
|
void aes_free_context(void *handle);
|
||||||
|
void aes128_key(void *handle, unsigned char *key);
|
||||||
|
void aes192_key(void *handle, unsigned char *key);
|
||||||
|
void aes256_key(void *handle, unsigned char *key);
|
||||||
|
void aes_iv(void *handle, unsigned char *iv);
|
||||||
|
void aes_ssh2_encrypt_blk(void *handle, unsigned char *blk, int len);
|
||||||
|
void aes_ssh2_decrypt_blk(void *handle, unsigned char *blk, int len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PuTTY version number formatted as an SSH version string.
|
* PuTTY version number formatted as an SSH version string.
|
||||||
|
16
sshaes.c
16
sshaes.c
@ -1097,35 +1097,35 @@ static void aes_sdctr(unsigned char *blk, int len, AESContext *ctx)
|
|||||||
memcpy(ctx->iv, iv, sizeof(iv));
|
memcpy(ctx->iv, iv, sizeof(iv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *aes_make_context(void)
|
void *aes_make_context(void)
|
||||||
{
|
{
|
||||||
return snew(AESContext);
|
return snew(AESContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aes_free_context(void *handle)
|
void aes_free_context(void *handle)
|
||||||
{
|
{
|
||||||
sfree(handle);
|
sfree(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aes128_key(void *handle, unsigned char *key)
|
void aes128_key(void *handle, unsigned char *key)
|
||||||
{
|
{
|
||||||
AESContext *ctx = (AESContext *)handle;
|
AESContext *ctx = (AESContext *)handle;
|
||||||
aes_setup(ctx, 16, key, 16);
|
aes_setup(ctx, 16, key, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aes192_key(void *handle, unsigned char *key)
|
void aes192_key(void *handle, unsigned char *key)
|
||||||
{
|
{
|
||||||
AESContext *ctx = (AESContext *)handle;
|
AESContext *ctx = (AESContext *)handle;
|
||||||
aes_setup(ctx, 16, key, 24);
|
aes_setup(ctx, 16, key, 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aes256_key(void *handle, unsigned char *key)
|
void aes256_key(void *handle, unsigned char *key)
|
||||||
{
|
{
|
||||||
AESContext *ctx = (AESContext *)handle;
|
AESContext *ctx = (AESContext *)handle;
|
||||||
aes_setup(ctx, 16, key, 32);
|
aes_setup(ctx, 16, key, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aes_iv(void *handle, unsigned char *iv)
|
void aes_iv(void *handle, unsigned char *iv)
|
||||||
{
|
{
|
||||||
AESContext *ctx = (AESContext *)handle;
|
AESContext *ctx = (AESContext *)handle;
|
||||||
int i;
|
int i;
|
||||||
@ -1133,13 +1133,13 @@ static void aes_iv(void *handle, unsigned char *iv)
|
|||||||
ctx->iv[i] = GET_32BIT_MSB_FIRST(iv + 4 * i);
|
ctx->iv[i] = GET_32BIT_MSB_FIRST(iv + 4 * i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aes_ssh2_encrypt_blk(void *handle, unsigned char *blk, int len)
|
void aes_ssh2_encrypt_blk(void *handle, unsigned char *blk, int len)
|
||||||
{
|
{
|
||||||
AESContext *ctx = (AESContext *)handle;
|
AESContext *ctx = (AESContext *)handle;
|
||||||
aes_encrypt_cbc(blk, len, ctx);
|
aes_encrypt_cbc(blk, len, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aes_ssh2_decrypt_blk(void *handle, unsigned char *blk, int len)
|
void aes_ssh2_decrypt_blk(void *handle, unsigned char *blk, int len)
|
||||||
{
|
{
|
||||||
AESContext *ctx = (AESContext *)handle;
|
AESContext *ctx = (AESContext *)handle;
|
||||||
aes_decrypt_cbc(blk, len, ctx);
|
aes_decrypt_cbc(blk, len, ctx);
|
||||||
|
Loading…
Reference in New Issue
Block a user