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