d118cb6cb4b36b4bdd61572302c012464095c152
2 * Code for PuTTY to import and export private key files in other
3 * SSH clients' formats.
14 #define PUT_32BIT(cp, value) do { \
16 (cp)[2] = (value) >> 8; \
17 (cp)[1] = (value) >> 16; \
18 (cp)[0] = (value) >> 24; } while (0)
20 #define GET_32BIT(cp) \
21 (((unsigned long)(unsigned char)(cp)[0] << 24) | \
22 ((unsigned long)(unsigned char)(cp)[1] << 16) | \
23 ((unsigned long)(unsigned char)(cp)[2] << 8) | \
24 ((unsigned long)(unsigned char)(cp)[3]))
26 int openssh_encrypted(char *filename
);
27 struct ssh2_userkey
*openssh_read(char *filename
, char *passphrase
);
30 * Given a key type, determine whether we know how to import it.
32 int import_possible(int type
)
34 if (type
== SSH_KEYTYPE_OPENSSH
)
40 * Given a key type, determine what native key type
41 * (SSH_KEYTYPE_SSH1 or SSH_KEYTYPE_SSH2) it will come out as once
44 int import_target_type(int type
)
47 * There are no known foreign SSH1 key formats.
49 return SSH_KEYTYPE_SSH2
;
53 * Determine whether a foreign key is encrypted.
55 int import_encrypted(char *filename
, int type
, char **comment
)
57 if (type
== SSH_KEYTYPE_OPENSSH
) {
58 *comment
= filename
; /* OpenSSH doesn't do key comments */
59 return openssh_encrypted(filename
);
67 int import_ssh1(char *filename
, int type
, struct RSAKey
*key
, char *passphrase
)
75 struct ssh2_userkey
*import_ssh2(char *filename
, int type
, char *passphrase
)
77 if (type
== SSH_KEYTYPE_OPENSSH
)
78 return openssh_read(filename
, passphrase
);
82 /* ----------------------------------------------------------------------
83 * Helper routines. (The base64 ones are defined in sshpubk.c.)
86 #define isbase64(c) ( ((c) >= 'A' && (c) <= 'Z') || \
87 ((c) >= 'a' && (c) <= 'z') || \
88 ((c) >= '0' && (c) <= '9') || \
89 (c) == '+' || (c) == '/' || (c) == '=' \
92 extern int base64_decode_atom(char *atom
, unsigned char *out
);
93 extern int base64_lines(int datalen
);
94 extern void base64_encode_atom(unsigned char *data
, int n
, char *out
);
95 extern void base64_encode(FILE * fp
, unsigned char *data
, int datalen
);
98 * Read an ASN.1/BER identifier and length pair.
100 * Flags are a combination of the #defines listed below.
102 * Returns -1 if unsuccessful; otherwise returns the number of
103 * bytes used out of the source data.
106 /* ASN.1 tag classes. */
107 #define ASN1_CLASS_UNIVERSAL (0 << 6)
108 #define ASN1_CLASS_APPLICATION (1 << 6)
109 #define ASN1_CLASS_CONTEXT_SPECIFIC (2 << 6)
110 #define ASN1_CLASS_PRIVATE (3 << 6)
111 #define ASN1_CLASS_MASK (3 << 6)
113 /* Primitive versus constructed bit. */
114 #define ASN1_CONSTRUCTED (1 << 5)
116 int ber_read_id_len(void *source
, int sourcelen
,
117 int *id
, int *length
, int *flags
)
119 unsigned char *p
= (unsigned char *) source
;
124 *flags
= (*p
& 0xE0);
125 if ((*p
& 0x1F) == 0x1F) {
128 *id
= (*id
<< 7) | (*p
& 0x7F);
133 *id
= (*id
<< 7) | (*p
& 0x7F);
150 *length
= (*length
<< 8) | (*p
++);
157 return p
- (unsigned char *) source
;
160 /* ----------------------------------------------------------------------
161 * Code to read OpenSSH private keys.
164 enum { OSSH_DSA
, OSSH_RSA
};
169 unsigned char *keyblob
;
170 int keyblob_len
, keyblob_size
;
173 struct openssh_key
*load_openssh_key(char *filename
)
175 struct openssh_key
*ret
;
181 ret
= smalloc(sizeof(*ret
));
183 ret
->keyblob_len
= ret
->keyblob_size
= 0;
185 memset(ret
->iv
, 0, sizeof(ret
->iv
));
187 fp
= fopen(filename
, "r");
189 errmsg
= "Unable to open key file";
192 if (!fgets(buffer
, sizeof(buffer
), fp
) ||
193 0 != strncmp(buffer
, "-----BEGIN ", 11) ||
194 0 != strcmp(buffer
+strlen(buffer
)-17, "PRIVATE KEY-----\n")) {
195 errmsg
= "File does not begin with OpenSSH key header";
198 if (!strcmp(buffer
, "-----BEGIN RSA PRIVATE KEY-----\n"))
199 ret
->type
= OSSH_RSA
;
200 else if (!strcmp(buffer
, "-----BEGIN DSA PRIVATE KEY-----\n"))
201 ret
->type
= OSSH_DSA
;
203 errmsg
= "Unrecognised key type";
209 if (!fgets(buffer
, sizeof(buffer
), fp
)) {
210 errmsg
= "Unexpected end of file";
213 if (0 == strncmp(buffer
, "-----END ", 9) &&
214 0 == strcmp(buffer
+strlen(buffer
)-17, "PRIVATE KEY-----\n"))
216 if ((p
= strchr(buffer
, ':')) != NULL
) {
218 errmsg
= "Header found in body of key data";
222 while (*p
&& isspace((unsigned char)*p
)) p
++;
223 if (!strcmp(buffer
, "Proc-Type")) {
224 if (p
[0] != '4' || p
[1] != ',') {
225 errmsg
= "Proc-Type is not 4 (only 4 is supported)";
229 if (!strcmp(p
, "ENCRYPTED\n"))
231 } else if (!strcmp(buffer
, "DEK-Info")) {
234 if (strncmp(p
, "DES-EDE3-CBC,", 13)) {
235 errmsg
= "Ciphers other than DES-EDE3-CBC not supported";
239 for (i
= 0; i
< 8; i
++) {
240 if (1 != sscanf(p
, "%2x", &j
))
246 errmsg
= "Expected 16-digit iv in DEK-Info";
254 while (isbase64(p
[0]) && isbase64(p
[1]) &&
255 isbase64(p
[2]) && isbase64(p
[3])) {
257 unsigned char out
[3];
259 len
= base64_decode_atom(p
, out
);
262 errmsg
= "Invalid base64 encoding";
266 if (ret
->keyblob_len
+ len
> ret
->keyblob_size
) {
267 ret
->keyblob_size
= ret
->keyblob_len
+ len
+ 256;
268 ret
->keyblob
= srealloc(ret
->keyblob
, ret
->keyblob_size
);
271 memcpy(ret
->keyblob
+ ret
->keyblob_len
, out
, len
);
272 ret
->keyblob_len
+= len
;
278 errmsg
= "base64 characters left at end of line";
284 if (ret
->keyblob_len
== 0 || !ret
->keyblob
) {
285 errmsg
= "Key body not present";
289 if (ret
->encrypted
&& ret
->keyblob_len
% 8 != 0) {
290 errmsg
= "Encrypted key blob is not a multiple of cipher block size";
298 if (ret
->keyblob
) sfree(ret
->keyblob
);
304 int openssh_encrypted(char *filename
)
306 struct openssh_key
*key
= load_openssh_key(filename
);
311 ret
= key
->encrypted
;
317 struct ssh2_userkey
*openssh_read(char *filename
, char *passphrase
)
319 struct openssh_key
*key
= load_openssh_key(filename
);
320 struct ssh2_userkey
*retkey
;
322 int ret
, id
, len
, flags
;
324 struct ssh2_userkey
*retval
= NULL
;
327 int blobptr
, privptr
;
334 if (key
->encrypted
) {
336 * Derive encryption key from passphrase and iv/salt:
338 * - let block A equal MD5(passphrase || iv)
339 * - let block B equal MD5(A || passphrase || iv)
340 * - block C would be MD5(B || passphrase || iv) and so on
341 * - encryption key is the first N bytes of A || B
343 struct MD5Context md5c
;
344 unsigned char keybuf
[32];
347 MD5Update(&md5c
, passphrase
, strlen(passphrase
));
348 MD5Update(&md5c
, key
->iv
, 8);
349 MD5Final(keybuf
, &md5c
);
352 MD5Update(&md5c
, keybuf
, 16);
353 MD5Update(&md5c
, passphrase
, strlen(passphrase
));
354 MD5Update(&md5c
, key
->iv
, 8);
355 MD5Final(keybuf
+16, &md5c
);
358 * Now decrypt the key blob.
360 des3_decrypt_pubkey_ossh(keybuf
, key
->iv
,
361 key
->keyblob
, key
->keyblob_len
);
365 * Now we have a decrypted key blob, which contains an ASN.1
366 * encoded private key. We must now untangle the ASN.1.
368 * We expect the whole key blob to be formatted as a SEQUENCE
369 * (0x30 followed by a length code indicating that the rest of
370 * the blob is part of the sequence). Within that SEQUENCE we
371 * expect to see a bunch of INTEGERs. What those integers mean
372 * depends on the key type:
374 * - For RSA, we expect the integers to be 0, n, e, d, p, q,
375 * dmp1, dmq1, iqmp in that order. (The last three are d mod
376 * (p-1), d mod (q-1), inverse of q mod p respectively.)
378 * - For DSA, we expect them to be 0, p, q, g, y, x in that
384 /* Expect the SEQUENCE header. Take its absence as a failure to decrypt. */
385 ret
= ber_read_id_len(p
, key
->keyblob_len
, &id
, &len
, &flags
);
387 if (ret
< 0 || id
!= 16) {
388 errmsg
= "ASN.1 decoding failure";
389 retval
= SSH2_WRONG_PASSPHRASE
;
393 /* Expect a load of INTEGERs. */
394 if (key
->type
== OSSH_RSA
)
396 else if (key
->type
== OSSH_DSA
)
400 * Space to create key blob in.
402 blob
= smalloc(256+key
->keyblob_len
);
404 if (key
->type
== OSSH_DSA
)
405 memcpy(blob
+4, "ssh-dss", 7);
406 else if (key
->type
== OSSH_RSA
)
407 memcpy(blob
+4, "ssh-rsa", 7);
411 for (i
= 0; i
< num_integers
; i
++) {
412 ret
= ber_read_id_len(p
, key
->keyblob
+key
->keyblob_len
-p
,
415 if (ret
< 0 || id
!= 2 ||
416 key
->keyblob
+key
->keyblob_len
-p
< len
) {
417 errmsg
= "ASN.1 decoding failure";
423 * The first integer should be zero always (I think
424 * this is some sort of version indication).
426 if (len
!= 1 || p
[0] != 0) {
427 errmsg
= "Version number mismatch";
430 } else if (key
->type
== OSSH_RSA
) {
432 * Integers 1 and 2 go into the public blob but in the
433 * opposite order; integers 3, 4, 5 and 8 go into the
434 * private blob. The other two (6 and 7) are ignored.
437 /* Save the details for after we deal with number 2. */
440 } else if (i
!= 6 && i
!= 7) {
441 PUT_32BIT(blob
+blobptr
, len
);
442 memcpy(blob
+blobptr
+4, p
, len
);
445 PUT_32BIT(blob
+blobptr
, modlen
);
446 memcpy(blob
+blobptr
+4, modptr
, modlen
);
451 } else if (key
->type
== OSSH_DSA
) {
453 * Integers 1-4 go into the public blob; integer 5 goes
454 * into the private blob.
456 PUT_32BIT(blob
+blobptr
, len
);
457 memcpy(blob
+blobptr
+4, p
, len
);
463 /* Skip past the number. */
468 * Now put together the actual key. Simplest way to do this is
469 * to assemble our own key blobs and feed them to the createkey
470 * functions; this is a bit faffy but it does mean we get all
471 * the sanity checks for free.
473 assert(privptr
> 0); /* should have bombed by now if not */
474 retkey
= smalloc(sizeof(struct ssh2_userkey
));
475 retkey
->alg
= (key
->type
== OSSH_RSA ?
&ssh_rsa
: &ssh_dss
);
476 retkey
->data
= retkey
->alg
->createkey(blob
, privptr
,
477 blob
+privptr
, blobptr
-privptr
);
480 errmsg
= "unable to create key data structure";
484 retkey
->comment
= dupstr("imported-openssh-key");
485 if (blob
) sfree(blob
);
491 if (blob
) sfree(blob
);