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