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