]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - import.c
Teach PuTTYgen to import from OpenSSH's new key format.
[PuTTY.git] / import.c
1 /*
2  * Code for PuTTY to import and export private key files in other
3  * SSH clients' formats.
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <assert.h>
9 #include <ctype.h>
10
11 #include "putty.h"
12 #include "ssh.h"
13 #include "misc.h"
14
15 int openssh_encrypted(const Filename *filename);
16 struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase,
17                                   const char **errmsg_p);
18 int openssh_write(const Filename *filename, struct ssh2_userkey *key,
19                   char *passphrase);
20
21 int sshcom_encrypted(const Filename *filename, char **comment);
22 struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
23                                  const char **errmsg_p);
24 int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
25                  char *passphrase);
26
27 /*
28  * Given a key type, determine whether we know how to import it.
29  */
30 int import_possible(int type)
31 {
32     if (type == SSH_KEYTYPE_OPENSSH)
33         return 1;
34     if (type == SSH_KEYTYPE_SSHCOM)
35         return 1;
36     return 0;
37 }
38
39 /*
40  * Given a key type, determine what native key type
41  * (SSH_KEYTYPE_SSH1 or SSH_KEYTYPE_SSH2) it will come out as once
42  * we've imported it.
43  */
44 int import_target_type(int type)
45 {
46     /*
47      * There are no known foreign SSH-1 key formats.
48      */
49     return SSH_KEYTYPE_SSH2;
50 }
51
52 /*
53  * Determine whether a foreign key is encrypted.
54  */
55 int import_encrypted(const Filename *filename, int type, char **comment)
56 {
57     if (type == SSH_KEYTYPE_OPENSSH) {
58         /* OpenSSH doesn't do key comments */
59         *comment = dupstr(filename_to_str(filename));
60         return openssh_encrypted(filename);
61     }
62     if (type == SSH_KEYTYPE_SSHCOM) {
63         return sshcom_encrypted(filename, comment);
64     }
65     return 0;
66 }
67
68 /*
69  * Import an SSH-1 key.
70  */
71 int import_ssh1(const Filename *filename, int type,
72                 struct RSAKey *key, char *passphrase, const char **errmsg_p)
73 {
74     return 0;
75 }
76
77 /*
78  * Import an SSH-2 key.
79  */
80 struct ssh2_userkey *import_ssh2(const Filename *filename, int type,
81                                  char *passphrase, const char **errmsg_p)
82 {
83     if (type == SSH_KEYTYPE_OPENSSH)
84         return openssh_read(filename, passphrase, errmsg_p);
85     if (type == SSH_KEYTYPE_SSHCOM)
86         return sshcom_read(filename, passphrase, errmsg_p);
87     return NULL;
88 }
89
90 /*
91  * Export an SSH-1 key.
92  */
93 int export_ssh1(const Filename *filename, int type, struct RSAKey *key,
94                 char *passphrase)
95 {
96     return 0;
97 }
98
99 /*
100  * Export an SSH-2 key.
101  */
102 int export_ssh2(const Filename *filename, int type,
103                 struct ssh2_userkey *key, char *passphrase)
104 {
105     if (type == SSH_KEYTYPE_OPENSSH)
106         return openssh_write(filename, key, passphrase);
107     if (type == SSH_KEYTYPE_SSHCOM)
108         return sshcom_write(filename, key, passphrase);
109     return 0;
110 }
111
112 /*
113  * Strip trailing CRs and LFs at the end of a line of text.
114  */
115 void strip_crlf(char *str)
116 {
117     char *p = str + strlen(str);
118
119     while (p > str && (p[-1] == '\r' || p[-1] == '\n'))
120         *--p = '\0';
121 }
122
123 /* ----------------------------------------------------------------------
124  * Helper routines. (The base64 ones are defined in sshpubk.c.)
125  */
126
127 #define isbase64(c) (    ((c) >= 'A' && (c) <= 'Z') || \
128                          ((c) >= 'a' && (c) <= 'z') || \
129                          ((c) >= '0' && (c) <= '9') || \
130                          (c) == '+' || (c) == '/' || (c) == '=' \
131                          )
132
133 /*
134  * Read an ASN.1/BER identifier and length pair.
135  * 
136  * Flags are a combination of the #defines listed below.
137  * 
138  * Returns -1 if unsuccessful; otherwise returns the number of
139  * bytes used out of the source data.
140  */
141
142 /* ASN.1 tag classes. */
143 #define ASN1_CLASS_UNIVERSAL        (0 << 6)
144 #define ASN1_CLASS_APPLICATION      (1 << 6)
145 #define ASN1_CLASS_CONTEXT_SPECIFIC (2 << 6)
146 #define ASN1_CLASS_PRIVATE          (3 << 6)
147 #define ASN1_CLASS_MASK             (3 << 6)
148
149 /* Primitive versus constructed bit. */
150 #define ASN1_CONSTRUCTED            (1 << 5)
151
152 static int ber_read_id_len(void *source, int sourcelen,
153                            int *id, int *length, int *flags)
154 {
155     unsigned char *p = (unsigned char *) source;
156
157     if (sourcelen == 0)
158         return -1;
159
160     *flags = (*p & 0xE0);
161     if ((*p & 0x1F) == 0x1F) {
162         *id = 0;
163         while (*p & 0x80) {
164             p++, sourcelen--;
165             if (sourcelen == 0)
166                 return -1;
167             *id = (*id << 7) | (*p & 0x7F);
168         }
169         p++, sourcelen--;
170     } else {
171         *id = *p & 0x1F;
172         p++, sourcelen--;
173     }
174
175     if (sourcelen == 0)
176         return -1;
177
178     if (*p & 0x80) {
179         int n = *p & 0x7F;
180         p++, sourcelen--;
181         if (sourcelen < n)
182             return -1;
183         *length = 0;
184         while (n--)
185             *length = (*length << 8) | (*p++);
186         sourcelen -= n;
187     } else {
188         *length = *p;
189         p++, sourcelen--;
190     }
191
192     return p - (unsigned char *) source;
193 }
194
195 /*
196  * Write an ASN.1/BER identifier and length pair. Returns the
197  * number of bytes consumed. Assumes dest contains enough space.
198  * Will avoid writing anything if dest is NULL, but still return
199  * amount of space required.
200  */
201 static int ber_write_id_len(void *dest, int id, int length, int flags)
202 {
203     unsigned char *d = (unsigned char *)dest;
204     int len = 0;
205
206     if (id <= 30) {
207         /*
208          * Identifier is one byte.
209          */
210         len++;
211         if (d) *d++ = id | flags;
212     } else {
213         int n;
214         /*
215          * Identifier is multiple bytes: the first byte is 11111
216          * plus the flags, and subsequent bytes encode the value of
217          * the identifier, 7 bits at a time, with the top bit of
218          * each byte 1 except the last one which is 0.
219          */
220         len++;
221         if (d) *d++ = 0x1F | flags;
222         for (n = 1; (id >> (7*n)) > 0; n++)
223             continue;                  /* count the bytes */
224         while (n--) {
225             len++;
226             if (d) *d++ = (n ? 0x80 : 0) | ((id >> (7*n)) & 0x7F);
227         }
228     }
229
230     if (length < 128) {
231         /*
232          * Length is one byte.
233          */
234         len++;
235         if (d) *d++ = length;
236     } else {
237         int n;
238         /*
239          * Length is multiple bytes. The first is 0x80 plus the
240          * number of subsequent bytes, and the subsequent bytes
241          * encode the actual length.
242          */
243         for (n = 1; (length >> (8*n)) > 0; n++)
244             continue;                  /* count the bytes */
245         len++;
246         if (d) *d++ = 0x80 | n;
247         while (n--) {
248             len++;
249             if (d) *d++ = (length >> (8*n)) & 0xFF;
250         }
251     }
252
253     return len;
254 }
255
256 static int put_string(void *target, void *data, int len)
257 {
258     unsigned char *d = (unsigned char *)target;
259
260     PUT_32BIT(d, len);
261     memcpy(d+4, data, len);
262     return len+4;
263 }
264
265 static int put_mp(void *target, void *data, int len)
266 {
267     unsigned char *d = (unsigned char *)target;
268     unsigned char *i = (unsigned char *)data;
269
270     if (*i & 0x80) {
271         PUT_32BIT(d, len+1);
272         d[4] = 0;
273         memcpy(d+5, data, len);
274         return len+5;
275     } else {
276         PUT_32BIT(d, len);
277         memcpy(d+4, data, len);
278         return len+4;
279     }
280 }
281
282 /* Simple structure to point to an mp-int within a blob. */
283 struct mpint_pos { void *start; int bytes; };
284
285 static int ssh2_read_mpint(void *data, int len, struct mpint_pos *ret)
286 {
287     int bytes;
288     unsigned char *d = (unsigned char *) data;
289
290     if (len < 4)
291         goto error;
292     bytes = toint(GET_32BIT(d));
293     if (bytes < 0 || len-4 < bytes)
294         goto error;
295
296     ret->start = d + 4;
297     ret->bytes = bytes;
298     return bytes+4;
299
300     error:
301     ret->start = NULL;
302     ret->bytes = -1;
303     return len;                        /* ensure further calls fail as well */
304 }
305
306 /* ----------------------------------------------------------------------
307  * Code to read and write OpenSSH private keys.
308  */
309
310 typedef enum {
311     OSSH_DSA, OSSH_RSA, OSSH_ECDSA, OSSH_DUNNO_YET
312 } openssh_keytype;
313 typedef enum {
314     OSSH_FMT_OLD, OSSH_FMT_NEW
315 } openssh_keyfmt;
316 typedef enum {
317     OSSH_ENC_3DES, OSSH_ENC_AES
318 } openssh_old_enc;
319 typedef enum {
320     OSSH_E_NONE, OSSH_E_AES256CBC
321 } openssh_new_cipher;
322 typedef enum {
323     OSSH_K_NONE, OSSH_K_BCRYPT
324 } openssh_new_kdf;
325
326 struct openssh_key {
327     openssh_keytype keytype;
328     openssh_keyfmt keyfmt;
329     int encrypted;
330     union {
331         struct {
332             openssh_old_enc encryption;
333             char iv[32];
334         } old;
335         struct {
336             openssh_new_cipher cipher;
337             openssh_new_kdf kdf;
338             union {
339                 struct {
340                     int rounds;
341                     /* This points to a position within keyblob, not a
342                      * separately allocated thing */
343                     const unsigned char *salt;
344                     int saltlen;
345                 } bcrypt;
346             } kdfopts;
347             int nkeys, key_wanted;
348             /* This too points to a position within keyblob */
349             unsigned char *privatestr;
350             int privatelen;
351         } new;
352     } u;
353     unsigned char *keyblob;
354     int keyblob_len, keyblob_size;
355 };
356
357 static int decrypt_openssh_key(struct openssh_key *key,
358                                const char *passphrase,
359                                char **errmsg)
360 {
361     assert(key->encrypted);
362     if (key->keyfmt == OSSH_FMT_OLD) {
363         /*
364          * Derive encryption key from passphrase and iv/salt:
365          * 
366          *  - let block A equal MD5(passphrase || iv)
367          *  - let block B equal MD5(A || passphrase || iv)
368          *  - block C would be MD5(B || passphrase || iv) and so on
369          *  - encryption key is the first N bytes of A || B
370          *
371          * (Note that only 8 bytes of the iv are used for key
372          * derivation, even when the key is encrypted with AES and
373          * hence there are 16 bytes available.)
374          */
375         struct MD5Context md5c;
376         unsigned char keybuf[32];
377
378         MD5Init(&md5c);
379         MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
380         MD5Update(&md5c, (unsigned char *)key->u.old.iv, 8);
381         MD5Final(keybuf, &md5c);
382
383         MD5Init(&md5c);
384         MD5Update(&md5c, keybuf, 16);
385         MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
386         MD5Update(&md5c, (unsigned char *)key->u.old.iv, 8);
387         MD5Final(keybuf+16, &md5c);
388
389         /*
390          * Now decrypt the key blob.
391          */
392         if (key->u.old.encryption == OSSH_ENC_3DES)
393             des3_decrypt_pubkey_ossh(keybuf, (unsigned char *)key->u.old.iv,
394                                      key->keyblob, key->keyblob_len);
395         else {
396             void *ctx;
397             assert(key->u.old.encryption == OSSH_ENC_AES);
398             ctx = aes_make_context();
399             aes128_key(ctx, keybuf);
400             aes_iv(ctx, (unsigned char *)key->u.old.iv);
401             aes_ssh2_decrypt_blk(ctx, key->keyblob, key->keyblob_len);
402             aes_free_context(ctx);
403         }
404
405         smemclr(&md5c, sizeof(md5c));
406         smemclr(keybuf, sizeof(keybuf));
407
408         return TRUE;
409     }
410
411     if (key->keyfmt == OSSH_FMT_NEW) {
412         unsigned char keybuf[48];
413         int keysize;
414
415         /*
416          * Construct the decryption key, and decrypt the string.
417          */
418         switch (key->u.new.cipher) {
419           case OSSH_E_NONE:
420             keysize = 0;
421             break;
422           case OSSH_E_AES256CBC:
423             keysize = 48;              /* 32 byte key + 16 byte IV */
424             break;
425           default:
426             assert(0 && "Bad cipher enumeration value");
427         }
428         assert(keysize <= sizeof(keybuf));
429         switch (key->u.new.kdf) {
430           case OSSH_K_NONE:
431             memset(keybuf, 0, keysize);
432             break;
433           case OSSH_K_BCRYPT:
434             openssh_bcrypt(passphrase,
435                            key->u.new.kdfopts.bcrypt.salt,
436                            key->u.new.kdfopts.bcrypt.saltlen,
437                            key->u.new.kdfopts.bcrypt.rounds,
438                            keybuf, keysize);
439             break;
440           default:
441             assert(0 && "Bad kdf enumeration value");
442         }
443         switch (key->u.new.cipher) {
444           case OSSH_E_NONE:
445             break;
446           case OSSH_E_AES256CBC:
447             if (key->u.new.privatelen % 16 != 0) {
448                 *errmsg = "private key container length is not a"
449                     " multiple of AES block size\n";
450                 return FALSE;
451             }
452             {
453                 void *ctx = aes_make_context();
454                 aes256_key(ctx, keybuf);
455                 aes_iv(ctx, keybuf + 32);
456                 aes_ssh2_decrypt_blk(ctx, key->u.new.privatestr,
457                                      key->u.new.privatelen);
458                 aes_free_context(ctx);
459             }
460             break;
461           default:
462             assert(0 && "Bad cipher enumeration value");
463         }
464         return TRUE;
465     }
466
467     assert(0 && "Bad key format in decrypt_openssh_key");
468 }
469
470 static struct openssh_key *load_openssh_key(const Filename *filename,
471                                             const char **errmsg_p)
472 {
473     struct openssh_key *ret;
474     FILE *fp = NULL;
475     char *line = NULL;
476     char *errmsg, *p;
477     int headers_done;
478     char base64_bit[4];
479     int base64_chars = 0;
480
481     ret = snew(struct openssh_key);
482     ret->keyblob = NULL;
483     ret->keyblob_len = ret->keyblob_size = 0;
484
485     fp = f_open(filename, "r", FALSE);
486     if (!fp) {
487         errmsg = "unable to open key file";
488         goto error;
489     }
490
491     if (!(line = fgetline(fp))) {
492         errmsg = "unexpected end of file";
493         goto error;
494     }
495     strip_crlf(line);
496     if (0 != strncmp(line, "-----BEGIN ", 11) ||
497         0 != strcmp(line+strlen(line)-16, "PRIVATE KEY-----")) {
498         errmsg = "file does not begin with OpenSSH key header";
499         goto error;
500     }
501     /*
502      * Parse the BEGIN line. For old-format keys, this tells us the
503      * type of the key; for new-format keys, all it tells us is the
504      * format, and we'll find out the key type once we parse the
505      * base64.
506      */
507     if (!strcmp(line, "-----BEGIN RSA PRIVATE KEY-----")) {
508         ret->keyfmt = OSSH_FMT_OLD;
509         ret->keytype = OSSH_RSA;
510     } else if (!strcmp(line, "-----BEGIN DSA PRIVATE KEY-----")) {
511         ret->keyfmt = OSSH_FMT_OLD;
512         ret->keytype = OSSH_DSA;
513     } else if (!strcmp(line, "-----BEGIN EC PRIVATE KEY-----")) {
514         ret->keyfmt = OSSH_FMT_OLD;
515         ret->keytype = OSSH_ECDSA;
516     } else if (!strcmp(line, "-----BEGIN OPENSSH PRIVATE KEY-----")) {
517         ret->keyfmt = OSSH_FMT_NEW;
518         ret->keytype = OSSH_DUNNO_YET;
519     } else {
520         errmsg = "unrecognised key type";
521         goto error;
522     }
523     smemclr(line, strlen(line));
524     sfree(line);
525     line = NULL;
526
527     if (ret->keyfmt == OSSH_FMT_OLD) {
528         ret->encrypted = FALSE;
529         memset(ret->u.old.iv, 0, sizeof(ret->u.old.iv));
530     }
531
532     headers_done = 0;
533     while (1) {
534         if (!(line = fgetline(fp))) {
535             errmsg = "unexpected end of file";
536             goto error;
537         }
538         strip_crlf(line);
539         if (0 == strncmp(line, "-----END ", 9) &&
540             0 == strcmp(line+strlen(line)-16, "PRIVATE KEY-----")) {
541             sfree(line);
542             line = NULL;
543             break;                     /* done */
544         }
545         if ((p = strchr(line, ':')) != NULL) {
546             if (ret->keyfmt != OSSH_FMT_OLD) {
547                 errmsg = "expected no headers in new-style OpenSSH key format";
548                 goto error;
549             }
550             if (headers_done) {
551                 errmsg = "header found in body of key data";
552                 goto error;
553             }
554             *p++ = '\0';
555             while (*p && isspace((unsigned char)*p)) p++;
556             if (!strcmp(line, "Proc-Type")) {
557                 if (p[0] != '4' || p[1] != ',') {
558                     errmsg = "Proc-Type is not 4 (only 4 is supported)";
559                     goto error;
560                 }
561                 p += 2;
562                 if (!strcmp(p, "ENCRYPTED"))
563                     ret->encrypted = TRUE;
564             } else if (!strcmp(line, "DEK-Info")) {
565                 int i, j, ivlen;
566
567                 if (!strncmp(p, "DES-EDE3-CBC,", 13)) {
568                     ret->u.old.encryption = OSSH_ENC_3DES;
569                     ivlen = 8;
570                 } else if (!strncmp(p, "AES-128-CBC,", 12)) {
571                     ret->u.old.encryption = OSSH_ENC_AES;
572                     ivlen = 16;
573                 } else {
574                     errmsg = "unsupported cipher";
575                     goto error;
576                 }
577                 p = strchr(p, ',') + 1;/* always non-NULL, by above checks */
578                 for (i = 0; i < ivlen; i++) {
579                     if (1 != sscanf(p, "%2x", &j)) {
580                         errmsg = "expected more iv data in DEK-Info";
581                         goto error;
582                     }
583                     ret->u.old.iv[i] = j;
584                     p += 2;
585                 }
586                 if (*p) {
587                     errmsg = "more iv data than expected in DEK-Info";
588                     goto error;
589                 }
590             }
591         } else {
592             headers_done = 1;
593
594             p = line;
595             while (isbase64(*p)) {
596                 base64_bit[base64_chars++] = *p;
597                 if (base64_chars == 4) {
598                     unsigned char out[3];
599                     int len;
600
601                     base64_chars = 0;
602
603                     len = base64_decode_atom(base64_bit, out);
604
605                     if (len <= 0) {
606                         errmsg = "invalid base64 encoding";
607                         goto error;
608                     }
609
610                     if (ret->keyblob_len + len > ret->keyblob_size) {
611                         ret->keyblob_size = ret->keyblob_len + len + 256;
612                         ret->keyblob = sresize(ret->keyblob, ret->keyblob_size,
613                                                unsigned char);
614                     }
615
616                     memcpy(ret->keyblob + ret->keyblob_len, out, len);
617                     ret->keyblob_len += len;
618
619                     smemclr(out, sizeof(out));
620                 }
621
622                 p++;
623             }
624         }
625         smemclr(line, strlen(line));
626         sfree(line);
627         line = NULL;
628     }
629
630     fclose(fp);
631     fp = NULL;
632
633     if (ret->keyblob_len == 0 || !ret->keyblob) {
634         errmsg = "key body not present";
635         goto error;
636     }
637
638     if (ret->keyfmt == OSSH_FMT_NEW) {
639         /*
640          * If we get here, then we haven't boiled down to a private
641          * key blob after all; we've merely stripped the base64
642          * wrapping from a new-style OpenSSH private key file. Now we
643          * have to parse that in turn, or at least get as far as the
644          * encrypted section.
645          */
646         const void *filedata = ret->keyblob;
647         int filelen = ret->keyblob_len;
648         const void *string, *kdfopts, *bcryptsalt, *pubkey;
649         int stringlen, kdfoptlen, bcryptsaltlen, pubkeylen;
650         unsigned bcryptrounds, nkeys, key_index;
651
652         if (filelen < 15 || 0 != memcmp(filedata, "openssh-key-v1\0", 15)) {
653             errmsg = "new-style OpenSSH magic number missing\n";
654             goto error;
655         }
656         filedata = (const char *)filedata + 15;
657         filelen -= 15;
658
659         if (!(string = get_ssh_string(&filelen, &filedata, &stringlen))) {
660             errmsg = "encountered EOF before cipher name\n";
661             goto error;
662         }
663         if (match_ssh_id(stringlen, string, "none")) {
664             ret->u.new.cipher = OSSH_E_NONE;
665         } else if (match_ssh_id(stringlen, string, "aes256-cbc")) {
666             ret->u.new.cipher = OSSH_E_AES256CBC;
667         } else {
668             errmsg = "unrecognised cipher name\n";
669             goto error;
670         }
671
672         if (!(string = get_ssh_string(&filelen, &filedata, &stringlen))) {
673             errmsg = "encountered EOF before kdf name\n";
674             goto error;
675         }
676         if (match_ssh_id(stringlen, string, "none")) {
677             ret->u.new.kdf = OSSH_K_NONE;
678         } else if (match_ssh_id(stringlen, string, "bcrypt")) {
679             ret->u.new.kdf = OSSH_K_BCRYPT;
680         } else {
681             errmsg = "unrecognised kdf name\n";
682             goto error;
683         }
684
685         if (!(kdfopts = get_ssh_string(&filelen, &filedata, &kdfoptlen))) {
686             errmsg = "encountered EOF before kdf options\n";
687             goto error;
688         }
689         switch (ret->u.new.kdf) {
690           case OSSH_K_NONE:
691             if (kdfoptlen != 0) {
692                 errmsg = "expected empty options string for 'none' kdf";
693                 goto error;
694             }
695             break;
696           case OSSH_K_BCRYPT:
697             if (!(bcryptsalt = get_ssh_string(&kdfoptlen, &kdfopts,
698                                               &bcryptsaltlen))) {
699                 errmsg = "bcrypt options string did not contain salt\n";
700                 goto error;
701             }
702             if (!get_ssh_uint32(&kdfoptlen, &kdfopts, &bcryptrounds)) {
703                 errmsg = "bcrypt options string did not contain round count\n";
704                 goto error;
705             }
706             ret->u.new.kdfopts.bcrypt.salt = bcryptsalt;
707             ret->u.new.kdfopts.bcrypt.saltlen = bcryptsaltlen;
708             ret->u.new.kdfopts.bcrypt.rounds = bcryptrounds;
709             break;
710         }
711
712         ret->encrypted = (ret->u.new.cipher != OSSH_E_NONE);
713
714         /*
715          * At this point we expect a uint32 saying how many keys are
716          * stored in this file. OpenSSH new-style key files can
717          * contain more than one. Currently we don't have any user
718          * interface to specify which one we're trying to extract, so
719          * we just bomb out with an error if more than one is found in
720          * the file. However, I've put in all the mechanism here to
721          * extract the nth one for a given n, in case we later connect
722          * up some UI to that mechanism. Just arrange that the
723          * 'key_wanted' field is set to a value in the range [0,
724          * nkeys) by some mechanism.
725          */
726         if (!get_ssh_uint32(&filelen, &filedata, &nkeys)) {
727             errmsg = "encountered EOF before key count\n";
728             goto error;
729         }
730         if (nkeys != 1) {
731             errmsg = "multiple keys in new-style OpenSSH key file "
732                 "not supported\n";
733             goto error;
734         }
735         ret->u.new.nkeys = nkeys;
736         ret->u.new.key_wanted = 0;
737
738         for (key_index = 0; key_index < nkeys; key_index++) {
739             int this_keytype;
740             if (!(pubkey = get_ssh_string(&filelen, &filedata, &pubkeylen))) {
741                 errmsg = "encountered EOF before kdf options\n";
742                 goto error;
743             }
744             /*
745              * Check the key type, and make sure it's something we
746              * understand.
747              */
748             if (!(string = get_ssh_string(&pubkeylen, &pubkey,
749                                           &stringlen))) {
750                 errmsg = "public key did not start with type string\n";
751                 goto error;
752             }
753             if (match_ssh_id(stringlen, string, "ssh-rsa")) {
754                 this_keytype = OSSH_RSA;
755             } else if (match_ssh_id(stringlen, string, "ssh-dss")) {
756                 this_keytype = OSSH_DSA;
757             } else if (match_ssh_id(stringlen, string,
758                                     "ecdsa-sha2-nistp256") ||
759                        match_ssh_id(stringlen, string,
760                                     "ecdsa-sha2-nistp384") ||
761                        match_ssh_id(stringlen, string,
762                                     "ecdsa-sha2-nistp521")) {
763                 this_keytype = OSSH_ECDSA;
764             } else {
765                 errmsg = "public key did not start with type string\n";
766                 goto error;
767             }
768             if (key_index == ret->u.new.key_wanted)
769                 ret->keytype = this_keytype;
770         }
771
772         /*
773          * Now we expect a string containing the encrypted part of the
774          * key file.
775          */
776         if (!(string = get_ssh_string(&filelen, &filedata, &stringlen))) {
777             errmsg = "encountered EOF before private key container\n";
778             goto error;
779         }
780         ret->u.new.privatestr = (unsigned char *)string;
781         ret->u.new.privatelen = stringlen;
782
783         /*
784          * And now we're done, until asked to actually decrypt.
785          */
786     }
787
788     if (ret->keyfmt == OSSH_FMT_OLD) {
789         if (ret->encrypted && ret->keyblob_len % 8 != 0) {
790             errmsg = "encrypted key blob is not a multiple of "
791                 "cipher block size";
792             goto error;
793         }
794     }
795
796     smemclr(base64_bit, sizeof(base64_bit));
797     if (errmsg_p) *errmsg_p = NULL;
798     return ret;
799
800     error:
801     if (line) {
802         smemclr(line, strlen(line));
803         sfree(line);
804         line = NULL;
805     }
806     smemclr(base64_bit, sizeof(base64_bit));
807     if (ret) {
808         if (ret->keyblob) {
809             smemclr(ret->keyblob, ret->keyblob_size);
810             sfree(ret->keyblob);
811         }
812         smemclr(ret, sizeof(*ret));
813         sfree(ret);
814     }
815     if (errmsg_p) *errmsg_p = errmsg;
816     if (fp) fclose(fp);
817     return NULL;
818 }
819
820 int openssh_encrypted(const Filename *filename)
821 {
822     struct openssh_key *key = load_openssh_key(filename, NULL);
823     int ret;
824
825     if (!key)
826         return 0;
827     ret = key->encrypted;
828     smemclr(key->keyblob, key->keyblob_size);
829     sfree(key->keyblob);
830     smemclr(key, sizeof(*key));
831     sfree(key);
832     return ret;
833 }
834
835 struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase,
836                                   const char **errmsg_p)
837 {
838     struct openssh_key *key = load_openssh_key(filename, errmsg_p);
839     struct ssh2_userkey *retkey;
840     unsigned char *p;
841     int ret, id, len, flags;
842     int i, num_integers;
843     struct ssh2_userkey *retval = NULL;
844     char *errmsg;
845     unsigned char *blob;
846     int blobsize = 0, blobptr, privptr;
847     char *modptr = NULL;
848     int modlen = 0;
849
850     blob = NULL;
851
852     if (!key)
853         return NULL;
854
855     if (key->encrypted) {
856         if (!decrypt_openssh_key(key, passphrase, &errmsg))
857             goto error;
858     }
859
860     if (key->keyfmt == OSSH_FMT_OLD) {
861         /*
862          * Now we have a decrypted key blob, which contains an ASN.1
863          * encoded private key. We must now untangle the ASN.1.
864          *
865          * We expect the whole key blob to be formatted as a SEQUENCE
866          * (0x30 followed by a length code indicating that the rest of
867          * the blob is part of the sequence). Within that SEQUENCE we
868          * expect to see a bunch of INTEGERs. What those integers mean
869          * depends on the key type:
870          *
871          *  - For RSA, we expect the integers to be 0, n, e, d, p, q,
872          *    dmp1, dmq1, iqmp in that order. (The last three are d mod
873          *    (p-1), d mod (q-1), inverse of q mod p respectively.)
874          *
875          *  - For DSA, we expect them to be 0, p, q, g, y, x in that
876          *    order.
877          *
878          *  - In ECDSA the format is totally different: we see the
879          *    SEQUENCE, but beneath is an INTEGER 1, OCTET STRING priv
880          *    EXPLICIT [0] OID curve, EXPLICIT [1] BIT STRING pubPoint
881          */
882     
883         p = key->keyblob;
884
885         /* Expect the SEQUENCE header. Take its absence as a failure to
886          * decrypt, if the key was encrypted. */
887         ret = ber_read_id_len(p, key->keyblob_len, &id, &len, &flags);
888         p += ret;
889         if (ret < 0 || id != 16) {
890             errmsg = "ASN.1 decoding failure";
891             retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
892             goto error;
893         }
894
895         /* Expect a load of INTEGERs. */
896         if (key->keytype == OSSH_RSA)
897             num_integers = 9;
898         else if (key->keytype == OSSH_DSA)
899             num_integers = 6;
900         else
901             num_integers = 0;          /* placate compiler warnings */
902
903
904         if (key->keytype == OSSH_ECDSA) {
905             /* And now for something completely different */
906             unsigned char *priv;
907             int privlen;
908             struct ec_curve *curve;
909             /* Read INTEGER 1 */
910             ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
911                                   &id, &len, &flags);
912             p += ret;
913             if (ret < 0 || id != 2 || key->keyblob+key->keyblob_len-p < len ||
914                 len != 1 || p[0] != 1) {
915                 errmsg = "ASN.1 decoding failure";
916                 retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
917                 goto error;
918             }
919             p += 1;
920             /* Read private key OCTET STRING */
921             ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
922                                   &id, &len, &flags);
923             p += ret;
924             if (ret < 0 || id != 4 || key->keyblob+key->keyblob_len-p < len) {
925                 errmsg = "ASN.1 decoding failure";
926                 retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
927                 goto error;
928             }
929             priv = p;
930             privlen = len;
931             p += len;
932             /* Read curve OID */
933             ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
934                                   &id, &len, &flags);
935             p += ret;
936             if (ret < 0 || id != 0 || key->keyblob+key->keyblob_len-p < len) {
937                 errmsg = "ASN.1 decoding failure";
938                 retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
939                 goto error;
940             }
941             ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
942                                   &id, &len, &flags);
943             p += ret;
944             if (ret < 0 || id != 6 || key->keyblob+key->keyblob_len-p < len) {
945                 errmsg = "ASN.1 decoding failure";
946                 retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
947                 goto error;
948             }
949             if (len == 8 && !memcmp(p, nistp256_oid, nistp256_oid_len)) {
950                 curve = ec_p256();
951             } else if (len == 5 && !memcmp(p, nistp384_oid,
952                                            nistp384_oid_len)) {
953                 curve = ec_p384();
954             } else if (len == 5 && !memcmp(p, nistp521_oid,
955                                            nistp521_oid_len)) {
956                 curve = ec_p521();
957             } else {
958                 errmsg = "Unsupported ECDSA curve.";
959                 retval = NULL;
960                 goto error;
961             }
962             p += len;
963             /* Read BIT STRING point */
964             ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
965                                   &id, &len, &flags);
966             p += ret;
967             if (ret < 0 || id != 1 || key->keyblob+key->keyblob_len-p < len) {
968                 errmsg = "ASN.1 decoding failure";
969                 retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
970                 goto error;
971             }
972             ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
973                                   &id, &len, &flags);
974             p += ret;
975             if (ret < 0 || id != 3 || key->keyblob+key->keyblob_len-p < len ||
976                 len != ((((curve->fieldBits + 7) / 8) * 2) + 2)) {
977                 errmsg = "ASN.1 decoding failure";
978                 retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
979                 goto error;
980             }
981             p += 1; len -= 1; /* Skip 0x00 before point */
982
983             /* Construct the key */
984             retkey = snew(struct ssh2_userkey);
985             if (!retkey) {
986                 errmsg = "out of memory";
987                 goto error;
988             }
989             if (curve->fieldBits == 256) {
990                 retkey->alg = &ssh_ecdsa_nistp256;
991             } else if (curve->fieldBits == 384) {
992                 retkey->alg = &ssh_ecdsa_nistp384;
993             } else {
994                 retkey->alg = &ssh_ecdsa_nistp521;
995             }
996             blob = snewn((4+19 + 4+8 + 4+len) + (4+privlen), unsigned char);
997             if (!blob) {
998                 sfree(retkey);
999                 errmsg = "out of memory";
1000                 goto error;
1001             }
1002             PUT_32BIT(blob, 19);
1003             sprintf((char*)blob+4, "ecdsa-sha2-nistp%d", curve->fieldBits);
1004             PUT_32BIT(blob+4+19, 8);
1005             sprintf((char*)blob+4+19+4, "nistp%d", curve->fieldBits);
1006             PUT_32BIT(blob+4+19+4+8, len);
1007             memcpy(blob+4+19+4+8+4, p, len);
1008             PUT_32BIT(blob+4+19+4+8+4+len, privlen);
1009             memcpy(blob+4+19+4+8+4+len+4, priv, privlen);
1010             retkey->data = retkey->alg->createkey(blob, 4+19+4+8+4+len,
1011                                                   blob+4+19+4+8+4+len,
1012                                                   4+privlen);
1013             if (!retkey->data) {
1014                 sfree(retkey);
1015                 errmsg = "unable to create key data structure";
1016                 goto error;
1017             }
1018
1019         } else if (key->keytype == OSSH_RSA || key->keytype == OSSH_DSA) {
1020
1021             /*
1022              * Space to create key blob in.
1023              */
1024             blobsize = 256+key->keyblob_len;
1025             blob = snewn(blobsize, unsigned char);
1026             PUT_32BIT(blob, 7);
1027             if (key->keytype == OSSH_DSA)
1028                 memcpy(blob+4, "ssh-dss", 7);
1029             else if (key->keytype == OSSH_RSA)
1030                 memcpy(blob+4, "ssh-rsa", 7);
1031             blobptr = 4+7;
1032             privptr = -1;
1033
1034             for (i = 0; i < num_integers; i++) {
1035                 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
1036                                       &id, &len, &flags);
1037                 p += ret;
1038                 if (ret < 0 || id != 2 ||
1039                     key->keyblob+key->keyblob_len-p < len) {
1040                     errmsg = "ASN.1 decoding failure";
1041                     retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
1042                     goto error;
1043                 }
1044
1045                 if (i == 0) {
1046                     /*
1047                      * The first integer should be zero always (I think
1048                      * this is some sort of version indication).
1049                      */
1050                     if (len != 1 || p[0] != 0) {
1051                         errmsg = "version number mismatch";
1052                         goto error;
1053                     }
1054                 } else if (key->keytype == OSSH_RSA) {
1055                     /*
1056                      * Integers 1 and 2 go into the public blob but in the
1057                      * opposite order; integers 3, 4, 5 and 8 go into the
1058                      * private blob. The other two (6 and 7) are ignored.
1059                      */
1060                     if (i == 1) {
1061                         /* Save the details for after we deal with number 2. */
1062                         modptr = (char *)p;
1063                         modlen = len;
1064                     } else if (i != 6 && i != 7) {
1065                         PUT_32BIT(blob+blobptr, len);
1066                         memcpy(blob+blobptr+4, p, len);
1067                         blobptr += 4+len;
1068                         if (i == 2) {
1069                             PUT_32BIT(blob+blobptr, modlen);
1070                             memcpy(blob+blobptr+4, modptr, modlen);
1071                             blobptr += 4+modlen;
1072                             privptr = blobptr;
1073                         }
1074                     }
1075                 } else if (key->keytype == OSSH_DSA) {
1076                     /*
1077                      * Integers 1-4 go into the public blob; integer 5 goes
1078                      * into the private blob.
1079                      */
1080                     PUT_32BIT(blob+blobptr, len);
1081                     memcpy(blob+blobptr+4, p, len);
1082                     blobptr += 4+len;
1083                     if (i == 4)
1084                         privptr = blobptr;
1085                 }
1086
1087                 /* Skip past the number. */
1088                 p += len;
1089             }
1090
1091             /*
1092              * Now put together the actual key. Simplest way to do this is
1093              * to assemble our own key blobs and feed them to the createkey
1094              * functions; this is a bit faffy but it does mean we get all
1095              * the sanity checks for free.
1096              */
1097             assert(privptr > 0);          /* should have bombed by now if not */
1098             retkey = snew(struct ssh2_userkey);
1099             retkey->alg = (key->keytype == OSSH_RSA ? &ssh_rsa : &ssh_dss);
1100             retkey->data = retkey->alg->createkey(blob, privptr,
1101                                                   blob+privptr,
1102                                                   blobptr-privptr);
1103             if (!retkey->data) {
1104                 sfree(retkey);
1105                 errmsg = "unable to create key data structure";
1106                 goto error;
1107             }
1108
1109         } else {
1110             assert(0 && "Bad key type from load_openssh_key");
1111         }
1112
1113         /*
1114          * The old key format doesn't include a comment in the private
1115          * key file.
1116          */
1117         retkey->comment = dupstr("imported-openssh-key");
1118     } else if (key->keyfmt == OSSH_FMT_NEW) {
1119         unsigned checkint0, checkint1;
1120         const void *priv, *string;
1121         int privlen, stringlen, key_index;
1122         const struct ssh_signkey *alg;
1123
1124         /*
1125          * OpenSSH's new key format. Here we must parse the entire
1126          * encrypted section, and extract the key identified by
1127          * key_wanted.
1128          */
1129         priv = key->u.new.privatestr;
1130         privlen = key->u.new.privatelen;
1131
1132         if (!get_ssh_uint32(&privlen, &priv, &checkint0) ||
1133             !get_ssh_uint32(&privlen, &priv, &checkint1) ||
1134             checkint0 != checkint1) {
1135             errmsg = "decryption check failed";
1136             goto error;
1137         }
1138
1139         retkey = NULL;
1140         for (key_index = 0; key_index < key->u.new.nkeys; key_index++) {
1141             unsigned char *thiskey;
1142             openssh_keytype this_keytype;
1143             int thiskeylen, npieces;
1144
1145             /*
1146              * Read the key type, which will tell us how to scan over
1147              * the key to get to the next one.
1148              */
1149             if (!(string = get_ssh_string(&privlen, &priv, &stringlen))) {
1150                 errmsg = "expected key type in private string";
1151                 goto error;
1152             }
1153
1154             /*
1155              * Preliminary key type identification, and decide how
1156              * many pieces of key we expect to see. Currently
1157              * (conveniently) all key types can be seen as some number
1158              * of strings, so we just need to know how many of them to
1159              * skip over. (The numbers below exclude the key comment.)
1160              */
1161             if (match_ssh_id(stringlen, string, "ssh-rsa")) {
1162                 this_keytype = OSSH_RSA;
1163                 alg = &ssh_rsa;
1164                 npieces = 6;           /* n,e,d,iqmp,q,p */
1165             } else if (match_ssh_id(stringlen, string, "ssh-dss")) {
1166                 this_keytype = OSSH_DSA;
1167                 alg = &ssh_dss;
1168                 npieces = 5;           /* p,q,g,y,x */
1169             } else if (match_ssh_id(stringlen, string,
1170                                     "ecdsa-sha2-nistp256")) {
1171                 this_keytype = OSSH_ECDSA;
1172                 alg = &ssh_ecdsa_nistp256;
1173                 npieces = 3;      /* curve name, point, private exponent */
1174             } else if (match_ssh_id(stringlen, string,
1175                                     "ecdsa-sha2-nistp384")) {
1176                 this_keytype = OSSH_ECDSA;
1177                 alg = &ssh_ecdsa_nistp384;
1178                 npieces = 3;      /* curve name, point, private exponent */
1179             } else if (match_ssh_id(stringlen, string,
1180                                     "ecdsa-sha2-nistp521")) {
1181                 this_keytype = OSSH_ECDSA;
1182                 alg = &ssh_ecdsa_nistp521;
1183                 npieces = 3;      /* curve name, point, private exponent */
1184             } else {
1185                 errmsg = "private key did not start with type string\n";
1186                 goto error;
1187             }
1188
1189             thiskey = (unsigned char *)priv;
1190
1191             /*
1192              * Skip over the pieces of key.
1193              */
1194             for (i = 0; i < npieces; i++) {
1195                 if (!(string = get_ssh_string(&privlen, &priv, &stringlen))) {
1196                     errmsg = "ran out of data in mid-private-key";
1197                     goto error;
1198                 }
1199             }
1200
1201             thiskeylen = (int)((const unsigned char *)priv -
1202                                (const unsigned char *)thiskey);
1203             if (key_index == key->u.new.key_wanted) {
1204                 if (this_keytype != key->keytype) {
1205                     errmsg = "public and private key types did not match";
1206                     goto error;
1207                 }
1208                 retkey = snew(struct ssh2_userkey);
1209                 retkey->alg = alg;
1210                 retkey->data = alg->openssh_createkey(&thiskey, &thiskeylen);
1211                 if (!retkey->data) {
1212                     sfree(retkey);
1213                     errmsg = "unable to create key data structure";
1214                     goto error;
1215                 }
1216             }
1217
1218             /*
1219              * Read the key comment.
1220              */
1221             if (!(string = get_ssh_string(&privlen, &priv, &stringlen))) {
1222                 errmsg = "ran out of data at key comment";
1223                 goto error;
1224             }
1225             if (key_index == key->u.new.key_wanted) {
1226                 assert(retkey);
1227                 retkey->comment = dupprintf("%.*s", stringlen,
1228                                             (const char *)string);
1229             }
1230         }
1231
1232         if (!retkey) {
1233             errmsg = "key index out of range";
1234             goto error;
1235         }
1236
1237         /*
1238          * Now we expect nothing left but padding.
1239          */
1240         for (i = 0; i < privlen; i++) {
1241             if (((const unsigned char *)priv)[i] != (unsigned char)(i+1)) {
1242                 errmsg = "padding at end of private string did not match";
1243                 goto error;
1244             }
1245         }
1246     } else {
1247         assert(0 && "Bad key format from load_openssh_key");
1248     }
1249
1250     errmsg = NULL;                     /* no error */
1251     retval = retkey;
1252
1253     error:
1254     if (blob) {
1255         smemclr(blob, blobsize);
1256         sfree(blob);
1257     }
1258     smemclr(key->keyblob, key->keyblob_size);
1259     sfree(key->keyblob);
1260     smemclr(key, sizeof(*key));
1261     sfree(key);
1262     if (errmsg_p) *errmsg_p = errmsg;
1263     return retval;
1264 }
1265
1266 int openssh_write(const Filename *filename, struct ssh2_userkey *key,
1267                   char *passphrase)
1268 {
1269     unsigned char *pubblob, *privblob, *spareblob;
1270     int publen, privlen, sparelen = 0;
1271     unsigned char *outblob;
1272     int outlen;
1273     struct mpint_pos numbers[9];
1274     int nnumbers, pos, len, seqlen, i;
1275     char *header, *footer;
1276     char zero[1];
1277     unsigned char iv[8];
1278     int ret = 0;
1279     FILE *fp;
1280
1281     /*
1282      * Fetch the key blobs.
1283      */
1284     pubblob = key->alg->public_blob(key->data, &publen);
1285     privblob = key->alg->private_blob(key->data, &privlen);
1286     spareblob = outblob = NULL;
1287
1288     outblob = NULL;
1289     len = 0;
1290
1291     /*
1292      * Encode the OpenSSH key blob, and also decide on the header
1293      * line.
1294      */
1295     if (key->alg == &ssh_rsa || key->alg == &ssh_dss) {
1296         /*
1297          * The RSA and DSS handlers share some code because the two
1298          * key types have very similar ASN.1 representations, as a
1299          * plain SEQUENCE of big integers. So we set up a list of
1300          * bignums per key type and then construct the actual blob in
1301          * common code after that.
1302          */
1303         if (key->alg == &ssh_rsa) {
1304             int pos;
1305             struct mpint_pos n, e, d, p, q, iqmp, dmp1, dmq1;
1306             Bignum bd, bp, bq, bdmp1, bdmq1;
1307
1308             /*
1309              * These blobs were generated from inside PuTTY, so we needn't
1310              * treat them as untrusted.
1311              */
1312             pos = 4 + GET_32BIT(pubblob);
1313             pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e);
1314             pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n);
1315             pos = 0;
1316             pos += ssh2_read_mpint(privblob+pos, privlen-pos, &d);
1317             pos += ssh2_read_mpint(privblob+pos, privlen-pos, &p);
1318             pos += ssh2_read_mpint(privblob+pos, privlen-pos, &q);
1319             pos += ssh2_read_mpint(privblob+pos, privlen-pos, &iqmp);
1320
1321             assert(e.start && iqmp.start); /* can't go wrong */
1322
1323             /* We also need d mod (p-1) and d mod (q-1). */
1324             bd = bignum_from_bytes(d.start, d.bytes);
1325             bp = bignum_from_bytes(p.start, p.bytes);
1326             bq = bignum_from_bytes(q.start, q.bytes);
1327             decbn(bp);
1328             decbn(bq);
1329             bdmp1 = bigmod(bd, bp);
1330             bdmq1 = bigmod(bd, bq);
1331             freebn(bd);
1332             freebn(bp);
1333             freebn(bq);
1334
1335             dmp1.bytes = (bignum_bitcount(bdmp1)+8)/8;
1336             dmq1.bytes = (bignum_bitcount(bdmq1)+8)/8;
1337             sparelen = dmp1.bytes + dmq1.bytes;
1338             spareblob = snewn(sparelen, unsigned char);
1339             dmp1.start = spareblob;
1340             dmq1.start = spareblob + dmp1.bytes;
1341             for (i = 0; i < dmp1.bytes; i++)
1342                 spareblob[i] = bignum_byte(bdmp1, dmp1.bytes-1 - i);
1343             for (i = 0; i < dmq1.bytes; i++)
1344                 spareblob[i+dmp1.bytes] = bignum_byte(bdmq1, dmq1.bytes-1 - i);
1345             freebn(bdmp1);
1346             freebn(bdmq1);
1347
1348             numbers[0].start = zero; numbers[0].bytes = 1; zero[0] = '\0';
1349             numbers[1] = n;
1350             numbers[2] = e;
1351             numbers[3] = d;
1352             numbers[4] = p;
1353             numbers[5] = q;
1354             numbers[6] = dmp1;
1355             numbers[7] = dmq1;
1356             numbers[8] = iqmp;
1357
1358             nnumbers = 9;
1359             header = "-----BEGIN RSA PRIVATE KEY-----\n";
1360             footer = "-----END RSA PRIVATE KEY-----\n";
1361         } else {                       /* ssh-dss */
1362             int pos;
1363             struct mpint_pos p, q, g, y, x;
1364
1365             /*
1366              * These blobs were generated from inside PuTTY, so we needn't
1367              * treat them as untrusted.
1368              */
1369             pos = 4 + GET_32BIT(pubblob);
1370             pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p);
1371             pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q);
1372             pos += ssh2_read_mpint(pubblob+pos, publen-pos, &g);
1373             pos += ssh2_read_mpint(pubblob+pos, publen-pos, &y);
1374             pos = 0;
1375             pos += ssh2_read_mpint(privblob+pos, privlen-pos, &x);
1376
1377             assert(y.start && x.start); /* can't go wrong */
1378
1379             numbers[0].start = zero; numbers[0].bytes = 1; zero[0] = '\0';
1380             numbers[1] = p;
1381             numbers[2] = q;
1382             numbers[3] = g;
1383             numbers[4] = y;
1384             numbers[5] = x;
1385
1386             nnumbers = 6;
1387             header = "-----BEGIN DSA PRIVATE KEY-----\n";
1388             footer = "-----END DSA PRIVATE KEY-----\n";
1389         }
1390
1391         /*
1392          * Now count up the total size of the ASN.1 encoded integers,
1393          * so as to determine the length of the containing SEQUENCE.
1394          */
1395         len = 0;
1396         for (i = 0; i < nnumbers; i++) {
1397             len += ber_write_id_len(NULL, 2, numbers[i].bytes, 0);
1398             len += numbers[i].bytes;
1399         }
1400         seqlen = len;
1401         /* Now add on the SEQUENCE header. */
1402         len += ber_write_id_len(NULL, 16, seqlen, ASN1_CONSTRUCTED);
1403
1404         /*
1405          * Now we know how big outblob needs to be. Allocate it.
1406          */
1407         outblob = snewn(len, unsigned char);
1408
1409         /*
1410          * And write the data into it.
1411          */
1412         pos = 0;
1413         pos += ber_write_id_len(outblob+pos, 16, seqlen, ASN1_CONSTRUCTED);
1414         for (i = 0; i < nnumbers; i++) {
1415             pos += ber_write_id_len(outblob+pos, 2, numbers[i].bytes, 0);
1416             memcpy(outblob+pos, numbers[i].start, numbers[i].bytes);
1417             pos += numbers[i].bytes;
1418         }
1419     } else if (key->alg == &ssh_ecdsa_nistp256 ||
1420                key->alg == &ssh_ecdsa_nistp384 ||
1421                key->alg == &ssh_ecdsa_nistp521) {
1422         unsigned char *oid;
1423         int oidlen;
1424         int pointlen;
1425
1426         /*
1427          * Structure of asn1:
1428          * SEQUENCE
1429          *   INTEGER 1
1430          *   OCTET STRING (private key)
1431          *   [0]
1432          *     OID (curve)
1433          *   [1]
1434          *     BIT STRING (0x00 public key point)
1435          */
1436         switch (((struct ec_key *)key->data)->publicKey.curve->fieldBits) {
1437           case 256:
1438             /* OID: 1.2.840.10045.3.1.7 (ansiX9p256r1) */
1439             oid = nistp256_oid;
1440             oidlen = nistp256_oid_len;
1441             pointlen = 32 * 2;
1442             break;
1443           case 384:
1444             /* OID: 1.3.132.0.34 (secp384r1) */
1445             oid = nistp384_oid;
1446             oidlen = nistp384_oid_len;
1447             pointlen = 48 * 2;
1448             break;
1449           case 521:
1450             /* OID: 1.3.132.0.35 (secp521r1) */
1451             oid = nistp521_oid;
1452             oidlen = nistp521_oid_len;
1453             pointlen = 66 * 2;
1454             break;
1455           default:
1456             assert(0);
1457         }
1458
1459         len = ber_write_id_len(NULL, 2, 1, 0);
1460         len += 1;
1461         len += ber_write_id_len(NULL, 4, privlen - 4, 0);
1462         len+= privlen - 4;
1463         len += ber_write_id_len(NULL, 0, oidlen +
1464                                 ber_write_id_len(NULL, 6, oidlen, 0),
1465                                 ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED);
1466         len += ber_write_id_len(NULL, 6, oidlen, 0);
1467         len += oidlen;
1468         len += ber_write_id_len(NULL, 1, 2 + pointlen +
1469                                 ber_write_id_len(NULL, 3, 2 + pointlen, 0),
1470                                 ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED);
1471         len += ber_write_id_len(NULL, 3, 2 + pointlen, 0);
1472         len += 2 + pointlen;
1473
1474         seqlen = len;
1475         len += ber_write_id_len(NULL, 16, seqlen, ASN1_CONSTRUCTED);
1476
1477         outblob = snewn(len, unsigned char);
1478         assert(outblob);
1479
1480         pos = 0;
1481         pos += ber_write_id_len(outblob+pos, 16, seqlen, ASN1_CONSTRUCTED);
1482         pos += ber_write_id_len(outblob+pos, 2, 1, 0);
1483         outblob[pos++] = 1;
1484         pos += ber_write_id_len(outblob+pos, 4, privlen - 4, 0);
1485         memcpy(outblob+pos, privblob + 4, privlen - 4);
1486         pos += privlen - 4;
1487         pos += ber_write_id_len(outblob+pos, 0, oidlen +
1488                                 ber_write_id_len(NULL, 6, oidlen, 0),
1489                                 ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED);
1490         pos += ber_write_id_len(outblob+pos, 6, oidlen, 0);
1491         memcpy(outblob+pos, oid, oidlen);
1492         pos += oidlen;
1493         pos += ber_write_id_len(outblob+pos, 1, 2 + pointlen +
1494                                 ber_write_id_len(NULL, 3, 2 + pointlen, 0),
1495                                 ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED);
1496         pos += ber_write_id_len(outblob+pos, 3, 2 + pointlen, 0);
1497         outblob[pos++] = 0;
1498         memcpy(outblob+pos, pubblob+39, 1 + pointlen);
1499         pos += 1 + pointlen;
1500
1501         header = "-----BEGIN EC PRIVATE KEY-----\n";
1502         footer = "-----END EC PRIVATE KEY-----\n";
1503     } else {
1504         assert(0);                     /* zoinks! */
1505         exit(1); /* XXX: GCC doesn't understand assert() on some systems. */
1506     }
1507
1508     /*
1509      * Encrypt the key.
1510      *
1511      * For the moment, we still encrypt our OpenSSH keys using
1512      * old-style 3DES.
1513      */
1514     if (passphrase) {
1515         struct MD5Context md5c;
1516         unsigned char keybuf[32];
1517
1518         /*
1519          * Round up to the cipher block size, ensuring we have at
1520          * least one byte of padding (see below).
1521          */
1522         outlen = (len+8) &~ 7;
1523         {
1524             unsigned char *tmp = snewn(outlen, unsigned char);
1525             memcpy(tmp, outblob, len);
1526             smemclr(outblob, len);
1527             sfree(outblob);
1528             outblob = tmp;
1529         }
1530
1531         /*
1532          * Padding on OpenSSH keys is deterministic. The number of
1533          * padding bytes is always more than zero, and always at most
1534          * the cipher block length. The value of each padding byte is
1535          * equal to the number of padding bytes. So a plaintext that's
1536          * an exact multiple of the block size will be padded with 08
1537          * 08 08 08 08 08 08 08 (assuming a 64-bit block cipher); a
1538          * plaintext one byte less than a multiple of the block size
1539          * will be padded with just 01.
1540          *
1541          * This enables the OpenSSL key decryption function to strip
1542          * off the padding algorithmically and return the unpadded
1543          * plaintext to the next layer: it looks at the final byte, and
1544          * then expects to find that many bytes at the end of the data
1545          * with the same value. Those are all removed and the rest is
1546          * returned.
1547          */
1548         assert(pos == len);
1549         while (pos < outlen) {
1550             outblob[pos++] = outlen - len;
1551         }
1552
1553         /*
1554          * Invent an iv. Then derive encryption key from passphrase
1555          * and iv/salt:
1556          * 
1557          *  - let block A equal MD5(passphrase || iv)
1558          *  - let block B equal MD5(A || passphrase || iv)
1559          *  - block C would be MD5(B || passphrase || iv) and so on
1560          *  - encryption key is the first N bytes of A || B
1561          */
1562         for (i = 0; i < 8; i++) iv[i] = random_byte();
1563
1564         MD5Init(&md5c);
1565         MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
1566         MD5Update(&md5c, iv, 8);
1567         MD5Final(keybuf, &md5c);
1568
1569         MD5Init(&md5c);
1570         MD5Update(&md5c, keybuf, 16);
1571         MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
1572         MD5Update(&md5c, iv, 8);
1573         MD5Final(keybuf+16, &md5c);
1574
1575         /*
1576          * Now encrypt the key blob.
1577          */
1578         des3_encrypt_pubkey_ossh(keybuf, iv, outblob, outlen);
1579
1580         smemclr(&md5c, sizeof(md5c));
1581         smemclr(keybuf, sizeof(keybuf));
1582     } else {
1583         /*
1584          * If no encryption, the blob has exactly its original
1585          * cleartext size.
1586          */
1587         outlen = len;
1588     }
1589
1590     /*
1591      * And save it. We'll use Unix line endings just in case it's
1592      * subsequently transferred in binary mode.
1593      */
1594     fp = f_open(filename, "wb", TRUE);      /* ensure Unix line endings */
1595     if (!fp)
1596         goto error;
1597     fputs(header, fp);
1598     if (passphrase) {
1599         fprintf(fp, "Proc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,");
1600         for (i = 0; i < 8; i++)
1601             fprintf(fp, "%02X", iv[i]);
1602         fprintf(fp, "\n\n");
1603     }
1604     base64_encode(fp, outblob, outlen, 64);
1605     fputs(footer, fp);
1606     fclose(fp);
1607     ret = 1;
1608
1609     error:
1610     if (outblob) {
1611         smemclr(outblob, outlen);
1612         sfree(outblob);
1613     }
1614     if (spareblob) {
1615         smemclr(spareblob, sparelen);
1616         sfree(spareblob);
1617     }
1618     if (privblob) {
1619         smemclr(privblob, privlen);
1620         sfree(privblob);
1621     }
1622     if (pubblob) {
1623         smemclr(pubblob, publen);
1624         sfree(pubblob);
1625     }
1626     return ret;
1627 }
1628
1629 /* ----------------------------------------------------------------------
1630  * Code to read ssh.com private keys.
1631  */
1632
1633 /*
1634  * The format of the base64 blob is largely SSH-2-packet-formatted,
1635  * except that mpints are a bit different: they're more like the
1636  * old SSH-1 mpint. You have a 32-bit bit count N, followed by
1637  * (N+7)/8 bytes of data.
1638  * 
1639  * So. The blob contains:
1640  * 
1641  *  - uint32 0x3f6ff9eb       (magic number)
1642  *  - uint32 size             (total blob size)
1643  *  - string key-type         (see below)
1644  *  - string cipher-type      (tells you if key is encrypted)
1645  *  - string encrypted-blob
1646  * 
1647  * (The first size field includes the size field itself and the
1648  * magic number before it. All other size fields are ordinary SSH-2
1649  * strings, so the size field indicates how much data is to
1650  * _follow_.)
1651  * 
1652  * The encrypted blob, once decrypted, contains a single string
1653  * which in turn contains the payload. (This allows padding to be
1654  * added after that string while still making it clear where the
1655  * real payload ends. Also it probably makes for a reasonable
1656  * decryption check.)
1657  * 
1658  * The payload blob, for an RSA key, contains:
1659  *  - mpint e
1660  *  - mpint d
1661  *  - mpint n  (yes, the public and private stuff is intermixed)
1662  *  - mpint u  (presumably inverse of p mod q)
1663  *  - mpint p  (p is the smaller prime)
1664  *  - mpint q  (q is the larger)
1665  * 
1666  * For a DSA key, the payload blob contains:
1667  *  - uint32 0
1668  *  - mpint p
1669  *  - mpint g
1670  *  - mpint q
1671  *  - mpint y
1672  *  - mpint x
1673  * 
1674  * Alternatively, if the parameters are `predefined', that
1675  * (0,p,g,q) sequence can be replaced by a uint32 1 and a string
1676  * containing some predefined parameter specification. *shudder*,
1677  * but I doubt we'll encounter this in real life.
1678  * 
1679  * The key type strings are ghastly. The RSA key I looked at had a
1680  * type string of
1681  * 
1682  *   `if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}'
1683  * 
1684  * and the DSA key wasn't much better:
1685  * 
1686  *   `dl-modp{sign{dsa-nist-sha1},dh{plain}}'
1687  * 
1688  * It isn't clear that these will always be the same. I think it
1689  * might be wise just to look at the `if-modn{sign{rsa' and
1690  * `dl-modp{sign{dsa' prefixes.
1691  * 
1692  * Finally, the encryption. The cipher-type string appears to be
1693  * either `none' or `3des-cbc'. Looks as if this is SSH-2-style
1694  * 3des-cbc (i.e. outer cbc rather than inner). The key is created
1695  * from the passphrase by means of yet another hashing faff:
1696  * 
1697  *  - first 16 bytes are MD5(passphrase)
1698  *  - next 16 bytes are MD5(passphrase || first 16 bytes)
1699  *  - if there were more, they'd be MD5(passphrase || first 32),
1700  *    and so on.
1701  */
1702
1703 #define SSHCOM_MAGIC_NUMBER 0x3f6ff9eb
1704
1705 struct sshcom_key {
1706     char comment[256];                 /* allowing any length is overkill */
1707     unsigned char *keyblob;
1708     int keyblob_len, keyblob_size;
1709 };
1710
1711 static struct sshcom_key *load_sshcom_key(const Filename *filename,
1712                                           const char **errmsg_p)
1713 {
1714     struct sshcom_key *ret;
1715     FILE *fp;
1716     char *line = NULL;
1717     int hdrstart, len;
1718     char *errmsg, *p;
1719     int headers_done;
1720     char base64_bit[4];
1721     int base64_chars = 0;
1722
1723     ret = snew(struct sshcom_key);
1724     ret->comment[0] = '\0';
1725     ret->keyblob = NULL;
1726     ret->keyblob_len = ret->keyblob_size = 0;
1727
1728     fp = f_open(filename, "r", FALSE);
1729     if (!fp) {
1730         errmsg = "unable to open key file";
1731         goto error;
1732     }
1733     if (!(line = fgetline(fp))) {
1734         errmsg = "unexpected end of file";
1735         goto error;
1736     }
1737     strip_crlf(line);
1738     if (0 != strcmp(line, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----")) {
1739         errmsg = "file does not begin with ssh.com key header";
1740         goto error;
1741     }
1742     smemclr(line, strlen(line));
1743     sfree(line);
1744     line = NULL;
1745
1746     headers_done = 0;
1747     while (1) {
1748         if (!(line = fgetline(fp))) {
1749             errmsg = "unexpected end of file";
1750             goto error;
1751         }
1752         strip_crlf(line);
1753         if (!strcmp(line, "---- END SSH2 ENCRYPTED PRIVATE KEY ----")) {
1754             sfree(line);
1755             line = NULL;
1756             break;                     /* done */
1757         }
1758         if ((p = strchr(line, ':')) != NULL) {
1759             if (headers_done) {
1760                 errmsg = "header found in body of key data";
1761                 goto error;
1762             }
1763             *p++ = '\0';
1764             while (*p && isspace((unsigned char)*p)) p++;
1765             hdrstart = p - line;
1766
1767             /*
1768              * Header lines can end in a trailing backslash for
1769              * continuation.
1770              */
1771             len = hdrstart + strlen(line+hdrstart);
1772             assert(!line[len]);
1773             while (line[len-1] == '\\') {
1774                 char *line2;
1775                 int line2len;
1776
1777                 line2 = fgetline(fp);
1778                 if (!line2) {
1779                     errmsg = "unexpected end of file";
1780                     goto error;
1781                 }
1782                 strip_crlf(line2);
1783
1784                 line2len = strlen(line2);
1785                 line = sresize(line, len + line2len + 1, char);
1786                 strcpy(line + len - 1, line2);
1787                 len += line2len - 1;
1788                 assert(!line[len]);
1789
1790                 smemclr(line2, strlen(line2));
1791                 sfree(line2);
1792                 line2 = NULL;
1793             }
1794             p = line + hdrstart;
1795             strip_crlf(p);
1796             if (!strcmp(line, "Comment")) {
1797                 /* Strip quotes in comment if present. */
1798                 if (p[0] == '"' && p[strlen(p)-1] == '"') {
1799                     p++;
1800                     p[strlen(p)-1] = '\0';
1801                 }
1802                 strncpy(ret->comment, p, sizeof(ret->comment));
1803                 ret->comment[sizeof(ret->comment)-1] = '\0';
1804             }
1805         } else {
1806             headers_done = 1;
1807
1808             p = line;
1809             while (isbase64(*p)) {
1810                 base64_bit[base64_chars++] = *p;
1811                 if (base64_chars == 4) {
1812                     unsigned char out[3];
1813
1814                     base64_chars = 0;
1815
1816                     len = base64_decode_atom(base64_bit, out);
1817
1818                     if (len <= 0) {
1819                         errmsg = "invalid base64 encoding";
1820                         goto error;
1821                     }
1822
1823                     if (ret->keyblob_len + len > ret->keyblob_size) {
1824                         ret->keyblob_size = ret->keyblob_len + len + 256;
1825                         ret->keyblob = sresize(ret->keyblob, ret->keyblob_size,
1826                                                unsigned char);
1827                     }
1828
1829                     memcpy(ret->keyblob + ret->keyblob_len, out, len);
1830                     ret->keyblob_len += len;
1831                 }
1832
1833                 p++;
1834             }
1835         }
1836         smemclr(line, strlen(line));
1837         sfree(line);
1838         line = NULL;
1839     }
1840
1841     if (ret->keyblob_len == 0 || !ret->keyblob) {
1842         errmsg = "key body not present";
1843         goto error;
1844     }
1845
1846     fclose(fp);
1847     if (errmsg_p) *errmsg_p = NULL;
1848     return ret;
1849
1850     error:
1851     if (fp)
1852         fclose(fp);
1853
1854     if (line) {
1855         smemclr(line, strlen(line));
1856         sfree(line);
1857         line = NULL;
1858     }
1859     if (ret) {
1860         if (ret->keyblob) {
1861             smemclr(ret->keyblob, ret->keyblob_size);
1862             sfree(ret->keyblob);
1863         }
1864         smemclr(ret, sizeof(*ret));
1865         sfree(ret);
1866     }
1867     if (errmsg_p) *errmsg_p = errmsg;
1868     return NULL;
1869 }
1870
1871 int sshcom_encrypted(const Filename *filename, char **comment)
1872 {
1873     struct sshcom_key *key = load_sshcom_key(filename, NULL);
1874     int pos, len, answer;
1875
1876     answer = 0;
1877
1878     *comment = NULL;
1879     if (!key)
1880         goto done;
1881
1882     /*
1883      * Check magic number.
1884      */
1885     if (GET_32BIT(key->keyblob) != 0x3f6ff9eb) {
1886         goto done;                     /* key is invalid */
1887     }
1888
1889     /*
1890      * Find the cipher-type string.
1891      */
1892     pos = 8;
1893     if (key->keyblob_len < pos+4)
1894         goto done;                     /* key is far too short */
1895     len = toint(GET_32BIT(key->keyblob + pos));
1896     if (len < 0 || len > key->keyblob_len - pos - 4)
1897         goto done;                     /* key is far too short */
1898     pos += 4 + len;                    /* skip key type */
1899     len = toint(GET_32BIT(key->keyblob + pos)); /* find cipher-type length */
1900     if (len < 0 || len > key->keyblob_len - pos - 4)
1901         goto done;                     /* cipher type string is incomplete */
1902     if (len != 4 || 0 != memcmp(key->keyblob + pos + 4, "none", 4))
1903         answer = 1;
1904
1905     done:
1906     if (key) {
1907         *comment = dupstr(key->comment);
1908         smemclr(key->keyblob, key->keyblob_size);
1909         sfree(key->keyblob);
1910         smemclr(key, sizeof(*key));
1911         sfree(key);
1912     } else {
1913         *comment = dupstr("");
1914     }
1915     return answer;
1916 }
1917
1918 static int sshcom_read_mpint(void *data, int len, struct mpint_pos *ret)
1919 {
1920     unsigned bits, bytes;
1921     unsigned char *d = (unsigned char *) data;
1922
1923     if (len < 4)
1924         goto error;
1925     bits = GET_32BIT(d);
1926
1927     bytes = (bits + 7) / 8;
1928     if (len < 4+bytes)
1929         goto error;
1930
1931     ret->start = d + 4;
1932     ret->bytes = bytes;
1933     return bytes+4;
1934
1935     error:
1936     ret->start = NULL;
1937     ret->bytes = -1;
1938     return len;                        /* ensure further calls fail as well */
1939 }
1940
1941 static int sshcom_put_mpint(void *target, void *data, int len)
1942 {
1943     unsigned char *d = (unsigned char *)target;
1944     unsigned char *i = (unsigned char *)data;
1945     int bits = len * 8 - 1;
1946
1947     while (bits > 0) {
1948         if (*i & (1 << (bits & 7)))
1949             break;
1950         if (!(bits-- & 7))
1951             i++, len--;
1952     }
1953
1954     PUT_32BIT(d, bits+1);
1955     memcpy(d+4, i, len);
1956     return len+4;
1957 }
1958
1959 struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
1960                                  const char **errmsg_p)
1961 {
1962     struct sshcom_key *key = load_sshcom_key(filename, errmsg_p);
1963     char *errmsg;
1964     int pos, len;
1965     const char prefix_rsa[] = "if-modn{sign{rsa";
1966     const char prefix_dsa[] = "dl-modp{sign{dsa";
1967     enum { RSA, DSA } type;
1968     int encrypted;
1969     char *ciphertext;
1970     int cipherlen;
1971     struct ssh2_userkey *ret = NULL, *retkey;
1972     const struct ssh_signkey *alg;
1973     unsigned char *blob = NULL;
1974     int blobsize = 0, publen, privlen;
1975
1976     if (!key)
1977         return NULL;
1978
1979     /*
1980      * Check magic number.
1981      */
1982     if (GET_32BIT(key->keyblob) != SSHCOM_MAGIC_NUMBER) {
1983         errmsg = "key does not begin with magic number";
1984         goto error;
1985     }
1986
1987     /*
1988      * Determine the key type.
1989      */
1990     pos = 8;
1991     if (key->keyblob_len < pos+4 ||
1992         (len = toint(GET_32BIT(key->keyblob + pos))) < 0 ||
1993         len > key->keyblob_len - pos - 4) {
1994         errmsg = "key blob does not contain a key type string";
1995         goto error;
1996     }
1997     if (len > sizeof(prefix_rsa) - 1 &&
1998         !memcmp(key->keyblob+pos+4, prefix_rsa, sizeof(prefix_rsa) - 1)) {
1999         type = RSA;
2000     } else if (len > sizeof(prefix_dsa) - 1 &&
2001         !memcmp(key->keyblob+pos+4, prefix_dsa, sizeof(prefix_dsa) - 1)) {
2002         type = DSA;
2003     } else {
2004         errmsg = "key is of unknown type";
2005         goto error;
2006     }
2007     pos += 4+len;
2008
2009     /*
2010      * Determine the cipher type.
2011      */
2012     if (key->keyblob_len < pos+4 ||
2013         (len = toint(GET_32BIT(key->keyblob + pos))) < 0 ||
2014         len > key->keyblob_len - pos - 4) {
2015         errmsg = "key blob does not contain a cipher type string";
2016         goto error;
2017     }
2018     if (len == 4 && !memcmp(key->keyblob+pos+4, "none", 4))
2019         encrypted = 0;
2020     else if (len == 8 && !memcmp(key->keyblob+pos+4, "3des-cbc", 8))
2021         encrypted = 1;
2022     else {
2023         errmsg = "key encryption is of unknown type";
2024         goto error;
2025     }
2026     pos += 4+len;
2027
2028     /*
2029      * Get hold of the encrypted part of the key.
2030      */
2031     if (key->keyblob_len < pos+4 ||
2032         (len = toint(GET_32BIT(key->keyblob + pos))) < 0 ||
2033         len > key->keyblob_len - pos - 4) {
2034         errmsg = "key blob does not contain actual key data";
2035         goto error;
2036     }
2037     ciphertext = (char *)key->keyblob + pos + 4;
2038     cipherlen = len;
2039     if (cipherlen == 0) {
2040         errmsg = "length of key data is zero";
2041         goto error;
2042     }
2043
2044     /*
2045      * Decrypt it if necessary.
2046      */
2047     if (encrypted) {
2048         /*
2049          * Derive encryption key from passphrase and iv/salt:
2050          * 
2051          *  - let block A equal MD5(passphrase)
2052          *  - let block B equal MD5(passphrase || A)
2053          *  - block C would be MD5(passphrase || A || B) and so on
2054          *  - encryption key is the first N bytes of A || B
2055          */
2056         struct MD5Context md5c;
2057         unsigned char keybuf[32], iv[8];
2058
2059         if (cipherlen % 8 != 0) {
2060             errmsg = "encrypted part of key is not a multiple of cipher block"
2061                 " size";
2062             goto error;
2063         }
2064
2065         MD5Init(&md5c);
2066         MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
2067         MD5Final(keybuf, &md5c);
2068
2069         MD5Init(&md5c);
2070         MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
2071         MD5Update(&md5c, keybuf, 16);
2072         MD5Final(keybuf+16, &md5c);
2073
2074         /*
2075          * Now decrypt the key blob.
2076          */
2077         memset(iv, 0, sizeof(iv));
2078         des3_decrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,
2079                                  cipherlen);
2080
2081         smemclr(&md5c, sizeof(md5c));
2082         smemclr(keybuf, sizeof(keybuf));
2083
2084         /*
2085          * Hereafter we return WRONG_PASSPHRASE for any parsing
2086          * error. (But only if we've just tried to decrypt it!
2087          * Returning WRONG_PASSPHRASE for an unencrypted key is
2088          * automatic doom.)
2089          */
2090         if (encrypted)
2091             ret = SSH2_WRONG_PASSPHRASE;
2092     }
2093
2094     /*
2095      * Strip away the containing string to get to the real meat.
2096      */
2097     len = toint(GET_32BIT(ciphertext));
2098     if (len < 0 || len > cipherlen-4) {
2099         errmsg = "containing string was ill-formed";
2100         goto error;
2101     }
2102     ciphertext += 4;
2103     cipherlen = len;
2104
2105     /*
2106      * Now we break down into RSA versus DSA. In either case we'll
2107      * construct public and private blobs in our own format, and
2108      * end up feeding them to alg->createkey().
2109      */
2110     blobsize = cipherlen + 256;
2111     blob = snewn(blobsize, unsigned char);
2112     privlen = 0;
2113     if (type == RSA) {
2114         struct mpint_pos n, e, d, u, p, q;
2115         int pos = 0;
2116         pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &e);
2117         pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &d);
2118         pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &n);
2119         pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &u);
2120         pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p);
2121         pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q);
2122         if (!q.start) {
2123             errmsg = "key data did not contain six integers";
2124             goto error;
2125         }
2126
2127         alg = &ssh_rsa;
2128         pos = 0;
2129         pos += put_string(blob+pos, "ssh-rsa", 7);
2130         pos += put_mp(blob+pos, e.start, e.bytes);
2131         pos += put_mp(blob+pos, n.start, n.bytes);
2132         publen = pos;
2133         pos += put_string(blob+pos, d.start, d.bytes);
2134         pos += put_mp(blob+pos, q.start, q.bytes);
2135         pos += put_mp(blob+pos, p.start, p.bytes);
2136         pos += put_mp(blob+pos, u.start, u.bytes);
2137         privlen = pos - publen;
2138     } else {
2139         struct mpint_pos p, q, g, x, y;
2140         int pos = 4;
2141
2142         assert(type == DSA); /* the only other option from the if above */
2143
2144         if (GET_32BIT(ciphertext) != 0) {
2145             errmsg = "predefined DSA parameters not supported";
2146             goto error;
2147         }
2148         pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p);
2149         pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &g);
2150         pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q);
2151         pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &y);
2152         pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &x);
2153         if (!x.start) {
2154             errmsg = "key data did not contain five integers";
2155             goto error;
2156         }
2157
2158         alg = &ssh_dss;
2159         pos = 0;
2160         pos += put_string(blob+pos, "ssh-dss", 7);
2161         pos += put_mp(blob+pos, p.start, p.bytes);
2162         pos += put_mp(blob+pos, q.start, q.bytes);
2163         pos += put_mp(blob+pos, g.start, g.bytes);
2164         pos += put_mp(blob+pos, y.start, y.bytes);
2165         publen = pos;
2166         pos += put_mp(blob+pos, x.start, x.bytes);
2167         privlen = pos - publen;
2168     }
2169
2170     assert(privlen > 0);               /* should have bombed by now if not */
2171
2172     retkey = snew(struct ssh2_userkey);
2173     retkey->alg = alg;
2174     retkey->data = alg->createkey(blob, publen, blob+publen, privlen);
2175     if (!retkey->data) {
2176         sfree(retkey);
2177         errmsg = "unable to create key data structure";
2178         goto error;
2179     }
2180     retkey->comment = dupstr(key->comment);
2181
2182     errmsg = NULL; /* no error */
2183     ret = retkey;
2184
2185     error:
2186     if (blob) {
2187         smemclr(blob, blobsize);
2188         sfree(blob);
2189     }
2190     smemclr(key->keyblob, key->keyblob_size);
2191     sfree(key->keyblob);
2192     smemclr(key, sizeof(*key));
2193     sfree(key);
2194     if (errmsg_p) *errmsg_p = errmsg;
2195     return ret;
2196 }
2197
2198 int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
2199                  char *passphrase)
2200 {
2201     unsigned char *pubblob, *privblob;
2202     int publen, privlen;
2203     unsigned char *outblob;
2204     int outlen;
2205     struct mpint_pos numbers[6];
2206     int nnumbers, initial_zero, pos, lenpos, i;
2207     char *type;
2208     char *ciphertext;
2209     int cipherlen;
2210     int ret = 0;
2211     FILE *fp;
2212
2213     /*
2214      * Fetch the key blobs.
2215      */
2216     pubblob = key->alg->public_blob(key->data, &publen);
2217     privblob = key->alg->private_blob(key->data, &privlen);
2218     outblob = NULL;
2219
2220     /*
2221      * Find the sequence of integers to be encoded into the OpenSSH
2222      * key blob, and also decide on the header line.
2223      */
2224     if (key->alg == &ssh_rsa) {
2225         int pos;
2226         struct mpint_pos n, e, d, p, q, iqmp;
2227
2228         /*
2229          * These blobs were generated from inside PuTTY, so we needn't
2230          * treat them as untrusted.
2231          */
2232         pos = 4 + GET_32BIT(pubblob);
2233         pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e);
2234         pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n);
2235         pos = 0;
2236         pos += ssh2_read_mpint(privblob+pos, privlen-pos, &d);
2237         pos += ssh2_read_mpint(privblob+pos, privlen-pos, &p);
2238         pos += ssh2_read_mpint(privblob+pos, privlen-pos, &q);
2239         pos += ssh2_read_mpint(privblob+pos, privlen-pos, &iqmp);
2240
2241         assert(e.start && iqmp.start); /* can't go wrong */
2242
2243         numbers[0] = e;
2244         numbers[1] = d;
2245         numbers[2] = n;
2246         numbers[3] = iqmp;
2247         numbers[4] = q;
2248         numbers[5] = p;
2249
2250         nnumbers = 6;
2251         initial_zero = 0;
2252         type = "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}";
2253     } else if (key->alg == &ssh_dss) {
2254         int pos;
2255         struct mpint_pos p, q, g, y, x;
2256
2257         /*
2258          * These blobs were generated from inside PuTTY, so we needn't
2259          * treat them as untrusted.
2260          */
2261         pos = 4 + GET_32BIT(pubblob);
2262         pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p);
2263         pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q);
2264         pos += ssh2_read_mpint(pubblob+pos, publen-pos, &g);
2265         pos += ssh2_read_mpint(pubblob+pos, publen-pos, &y);
2266         pos = 0;
2267         pos += ssh2_read_mpint(privblob+pos, privlen-pos, &x);
2268
2269         assert(y.start && x.start); /* can't go wrong */
2270
2271         numbers[0] = p;
2272         numbers[1] = g;
2273         numbers[2] = q;
2274         numbers[3] = y;
2275         numbers[4] = x;
2276
2277         nnumbers = 5;
2278         initial_zero = 1;
2279         type = "dl-modp{sign{dsa-nist-sha1},dh{plain}}";
2280     } else {
2281         assert(0);                     /* zoinks! */
2282         exit(1); /* XXX: GCC doesn't understand assert() on some systems. */
2283     }
2284
2285     /*
2286      * Total size of key blob will be somewhere under 512 plus
2287      * combined length of integers. We'll calculate the more
2288      * precise size as we construct the blob.
2289      */
2290     outlen = 512;
2291     for (i = 0; i < nnumbers; i++)
2292         outlen += 4 + numbers[i].bytes;
2293     outblob = snewn(outlen, unsigned char);
2294
2295     /*
2296      * Create the unencrypted key blob.
2297      */
2298     pos = 0;
2299     PUT_32BIT(outblob+pos, SSHCOM_MAGIC_NUMBER); pos += 4;
2300     pos += 4;                          /* length field, fill in later */
2301     pos += put_string(outblob+pos, type, strlen(type));
2302     {
2303         char *ciphertype = passphrase ? "3des-cbc" : "none";
2304         pos += put_string(outblob+pos, ciphertype, strlen(ciphertype));
2305     }
2306     lenpos = pos;                      /* remember this position */
2307     pos += 4;                          /* encrypted-blob size */
2308     pos += 4;                          /* encrypted-payload size */
2309     if (initial_zero) {
2310         PUT_32BIT(outblob+pos, 0);
2311         pos += 4;
2312     }
2313     for (i = 0; i < nnumbers; i++)
2314         pos += sshcom_put_mpint(outblob+pos,
2315                                 numbers[i].start, numbers[i].bytes);
2316     /* Now wrap up the encrypted payload. */
2317     PUT_32BIT(outblob+lenpos+4, pos - (lenpos+8));
2318     /* Pad encrypted blob to a multiple of cipher block size. */
2319     if (passphrase) {
2320         int padding = -(pos - (lenpos+4)) & 7;
2321         while (padding--)
2322             outblob[pos++] = random_byte();
2323     }
2324     ciphertext = (char *)outblob+lenpos+4;
2325     cipherlen = pos - (lenpos+4);
2326     assert(!passphrase || cipherlen % 8 == 0);
2327     /* Wrap up the encrypted blob string. */
2328     PUT_32BIT(outblob+lenpos, cipherlen);
2329     /* And finally fill in the total length field. */
2330     PUT_32BIT(outblob+4, pos);
2331
2332     assert(pos < outlen);
2333
2334     /*
2335      * Encrypt the key.
2336      */
2337     if (passphrase) {
2338         /*
2339          * Derive encryption key from passphrase and iv/salt:
2340          * 
2341          *  - let block A equal MD5(passphrase)
2342          *  - let block B equal MD5(passphrase || A)
2343          *  - block C would be MD5(passphrase || A || B) and so on
2344          *  - encryption key is the first N bytes of A || B
2345          */
2346         struct MD5Context md5c;
2347         unsigned char keybuf[32], iv[8];
2348
2349         MD5Init(&md5c);
2350         MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
2351         MD5Final(keybuf, &md5c);
2352
2353         MD5Init(&md5c);
2354         MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
2355         MD5Update(&md5c, keybuf, 16);
2356         MD5Final(keybuf+16, &md5c);
2357
2358         /*
2359          * Now decrypt the key blob.
2360          */
2361         memset(iv, 0, sizeof(iv));
2362         des3_encrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,
2363                                  cipherlen);
2364
2365         smemclr(&md5c, sizeof(md5c));
2366         smemclr(keybuf, sizeof(keybuf));
2367     }
2368
2369     /*
2370      * And save it. We'll use Unix line endings just in case it's
2371      * subsequently transferred in binary mode.
2372      */
2373     fp = f_open(filename, "wb", TRUE);      /* ensure Unix line endings */
2374     if (!fp)
2375         goto error;
2376     fputs("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);
2377     fprintf(fp, "Comment: \"");
2378     /*
2379      * Comment header is broken with backslash-newline if it goes
2380      * over 70 chars. Although it's surrounded by quotes, it
2381      * _doesn't_ escape backslashes or quotes within the string.
2382      * Don't ask me, I didn't design it.
2383      */
2384     {
2385         int slen = 60;                 /* starts at 60 due to "Comment: " */
2386         char *c = key->comment;
2387         while ((int)strlen(c) > slen) {
2388             fprintf(fp, "%.*s\\\n", slen, c);
2389             c += slen;
2390             slen = 70;                 /* allow 70 chars on subsequent lines */
2391         }
2392         fprintf(fp, "%s\"\n", c);
2393     }
2394     base64_encode(fp, outblob, pos, 70);
2395     fputs("---- END SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);
2396     fclose(fp);
2397     ret = 1;
2398
2399     error:
2400     if (outblob) {
2401         smemclr(outblob, outlen);
2402         sfree(outblob);
2403     }
2404     if (privblob) {
2405         smemclr(privblob, privlen);
2406         sfree(privblob);
2407     }
2408     if (pubblob) {
2409         smemclr(pubblob, publen);
2410         sfree(pubblob);
2411     }
2412     return ret;
2413 }