Skip to content
This repository
Browse code

Support importing of new-style OpenSSH private keys (encrypted by

AES rather than 3DES).


git-svn-id: svn://svn.tartarus.org/sgt/putty@8916 cda61777-01e9-0310-a592-d414129be87e
  • Loading branch information...
commit 06e09f436f7fd784822ec29f66d37e60d01e24a4 1 parent af04c42
simon authored

Showing 3 changed files with 48 additions and 21 deletions. Show diff stats Hide diff stats

  1. +32 13 import.c
  2. +8 0 ssh.h
  3. +8 8 sshaes.c
45 import.c
@@ -308,9 +308,10 @@ static int ssh2_read_mpint(void *data, int len, struct mpint_pos *ret)
308 308 */
309 309
310 310 enum { OSSH_DSA, OSSH_RSA };
  311 +enum { OSSH_ENC_3DES, OSSH_ENC_AES };
311 312 struct openssh_key {
312 313 int type;
313   - int encrypted;
  314 + int encrypted, encryption;
314 315 char iv[32];
315 316 unsigned char *keyblob;
316 317 int keyblob_len, keyblob_size;
@@ -387,21 +388,29 @@ static struct openssh_key *load_openssh_key(const Filename *filename,
387 388 if (!strcmp(p, "ENCRYPTED"))
388 389 ret->encrypted = 1;
389 390 } else if (!strcmp(line, "DEK-Info")) {
390   - int i, j;
391   -
392   - if (strncmp(p, "DES-EDE3-CBC,", 13)) {
393   - errmsg = "ciphers other than DES-EDE3-CBC not supported";
  391 + int i, j, ivlen;
  392 +
  393 + if (!strncmp(p, "DES-EDE3-CBC,", 13)) {
  394 + ret->encryption = OSSH_ENC_3DES;
  395 + ivlen = 8;
  396 + } else if (!strncmp(p, "AES-128-CBC,", 12)) {
  397 + ret->encryption = OSSH_ENC_AES;
  398 + ivlen = 16;
  399 + } else {
  400 + errmsg = "unsupported cipher";
394 401 goto error;
395 402 }
396   - p += 13;
397   - for (i = 0; i < 8; i++) {
398   - if (1 != sscanf(p, "%2x", &j))
399   - break;
  403 + p = strchr(p, ',') + 1;/* always non-NULL, by above checks */
  404 + for (i = 0; i < ivlen; i++) {
  405 + if (1 != sscanf(p, "%2x", &j)) {
  406 + errmsg = "expected more iv data in DEK-Info";
  407 + goto error;
  408 + }
400 409 ret->iv[i] = j;
401 410 p += 2;
402 411 }
403   - if (i < 8) {
404   - errmsg = "expected 16-digit iv in DEK-Info";
  412 + if (*p) {
  413 + errmsg = "more iv data than expected in DEK-Info";
405 414 goto error;
406 415 }
407 416 }
@@ -538,8 +547,18 @@ struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase,
538 547 /*
539 548 * Now decrypt the key blob.
540 549 */
541   - des3_decrypt_pubkey_ossh(keybuf, (unsigned char *)key->iv,
542   - key->keyblob, key->keyblob_len);
  550 + if (key->encryption == OSSH_ENC_3DES)
  551 + des3_decrypt_pubkey_ossh(keybuf, (unsigned char *)key->iv,
  552 + key->keyblob, key->keyblob_len);
  553 + else {
  554 + void *ctx;
  555 + assert(key->encryption == OSSH_ENC_AES);
  556 + ctx = aes_make_context();
  557 + aes128_key(ctx, keybuf);
  558 + aes_iv(ctx, (unsigned char *)key->iv);
  559 + aes_ssh2_decrypt_blk(ctx, key->keyblob, key->keyblob_len);
  560 + aes_free_context(ctx);
  561 + }
543 562
544 563 memset(&md5c, 0, sizeof(md5c));
545 564 memset(keybuf, 0, sizeof(keybuf));
8 ssh.h
@@ -290,6 +290,14 @@ extern const struct ssh_mac ssh_hmac_sha1_buggy;
290 290 extern const struct ssh_mac ssh_hmac_sha1_96;
291 291 extern const struct ssh_mac ssh_hmac_sha1_96_buggy;
292 292
  293 +void *aes_make_context(void);
  294 +void aes_free_context(void *handle);
  295 +void aes128_key(void *handle, unsigned char *key);
  296 +void aes192_key(void *handle, unsigned char *key);
  297 +void aes256_key(void *handle, unsigned char *key);
  298 +void aes_iv(void *handle, unsigned char *iv);
  299 +void aes_ssh2_encrypt_blk(void *handle, unsigned char *blk, int len);
  300 +void aes_ssh2_decrypt_blk(void *handle, unsigned char *blk, int len);
293 301
294 302 /*
295 303 * PuTTY version number formatted as an SSH version string.
16 sshaes.c
@@ -1097,35 +1097,35 @@ static void aes_sdctr(unsigned char *blk, int len, AESContext *ctx)
1097 1097 memcpy(ctx->iv, iv, sizeof(iv));
1098 1098 }
1099 1099
1100   -static void *aes_make_context(void)
  1100 +void *aes_make_context(void)
1101 1101 {
1102 1102 return snew(AESContext);
1103 1103 }
1104 1104
1105   -static void aes_free_context(void *handle)
  1105 +void aes_free_context(void *handle)
1106 1106 {
1107 1107 sfree(handle);
1108 1108 }
1109 1109
1110   -static void aes128_key(void *handle, unsigned char *key)
  1110 +void aes128_key(void *handle, unsigned char *key)
1111 1111 {
1112 1112 AESContext *ctx = (AESContext *)handle;
1113 1113 aes_setup(ctx, 16, key, 16);
1114 1114 }
1115 1115
1116   -static void aes192_key(void *handle, unsigned char *key)
  1116 +void aes192_key(void *handle, unsigned char *key)
1117 1117 {
1118 1118 AESContext *ctx = (AESContext *)handle;
1119 1119 aes_setup(ctx, 16, key, 24);
1120 1120 }
1121 1121
1122   -static void aes256_key(void *handle, unsigned char *key)
  1122 +void aes256_key(void *handle, unsigned char *key)
1123 1123 {
1124 1124 AESContext *ctx = (AESContext *)handle;
1125 1125 aes_setup(ctx, 16, key, 32);
1126 1126 }
1127 1127
1128   -static void aes_iv(void *handle, unsigned char *iv)
  1128 +void aes_iv(void *handle, unsigned char *iv)
1129 1129 {
1130 1130 AESContext *ctx = (AESContext *)handle;
1131 1131 int i;
@@ -1133,13 +1133,13 @@ static void aes_iv(void *handle, unsigned char *iv)
1133 1133 ctx->iv[i] = GET_32BIT_MSB_FIRST(iv + 4 * i);
1134 1134 }
1135 1135
1136   -static void aes_ssh2_encrypt_blk(void *handle, unsigned char *blk, int len)
  1136 +void aes_ssh2_encrypt_blk(void *handle, unsigned char *blk, int len)
1137 1137 {
1138 1138 AESContext *ctx = (AESContext *)handle;
1139 1139 aes_encrypt_cbc(blk, len, ctx);
1140 1140 }
1141 1141
1142   -static void aes_ssh2_decrypt_blk(void *handle, unsigned char *blk, int len)
  1142 +void aes_ssh2_decrypt_blk(void *handle, unsigned char *blk, int len)
1143 1143 {
1144 1144 AESContext *ctx = (AESContext *)handle;
1145 1145 aes_decrypt_cbc(blk, len, ctx);

0 comments on commit 06e09f4

Please sign in to comment.
Something went wrong with that request. Please try again.