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