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