]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - sshpubk.c
INCOMPATIBLE CHANGE to the SSH2 private key file format. There is
[PuTTY.git] / sshpubk.c
1 /*
2  * Generic SSH public-key handling operations. In particular,
3  * reading of SSH public-key files, and also the generic `sign'
4  * operation for ssh2 (which checks the type of the key and
5  * dispatches to the appropriate key-type specific function).
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <assert.h>
11
12 #include "ssh.h"
13 #include "misc.h"
14
15 #define PUT_32BIT(cp, value) do { \
16   (cp)[3] = (value); \
17   (cp)[2] = (value) >> 8; \
18   (cp)[1] = (value) >> 16; \
19   (cp)[0] = (value) >> 24; } while (0)
20
21 #define GET_32BIT(cp) \
22     (((unsigned long)(unsigned char)(cp)[0] << 24) | \
23     ((unsigned long)(unsigned char)(cp)[1] << 16) | \
24     ((unsigned long)(unsigned char)(cp)[2] << 8) | \
25     ((unsigned long)(unsigned char)(cp)[3]))
26
27 #define rsa_signature "SSH PRIVATE KEY FILE FORMAT 1.1\n"
28
29 #define BASE64_TOINT(x) ( (x)-'A'<26 ? (x)-'A'+0 :\
30                           (x)-'a'<26 ? (x)-'a'+26 :\
31                           (x)-'0'<10 ? (x)-'0'+52 :\
32                           (x)=='+' ? 62 : \
33                           (x)=='/' ? 63 : 0 )
34
35 static int loadrsakey_main(FILE * fp, struct RSAKey *key,
36                            char **commentptr, char *passphrase)
37 {
38     unsigned char buf[16384];
39     unsigned char keybuf[16];
40     int len;
41     int i, j, ciphertype;
42     int ret = 0;
43     struct MD5Context md5c;
44     char *comment;
45
46     /* Slurp the whole file (minus the header) into a buffer. */
47     len = fread(buf, 1, sizeof(buf), fp);
48     fclose(fp);
49     if (len < 0 || len == sizeof(buf))
50         goto end;                      /* file too big or not read */
51
52     i = 0;
53
54     /*
55      * A zero byte. (The signature includes a terminating NUL.)
56      */
57     if (len - i < 1 || buf[i] != 0)
58         goto end;
59     i++;
60
61     /* One byte giving encryption type, and one reserved uint32. */
62     if (len - i < 1)
63         goto end;
64     ciphertype = buf[i];
65     if (ciphertype != 0 && ciphertype != SSH_CIPHER_3DES)
66         goto end;
67     i++;
68     if (len - i < 4)
69         goto end;                      /* reserved field not present */
70     if (buf[i] != 0 || buf[i + 1] != 0 || buf[i + 2] != 0
71         || buf[i + 3] != 0) goto end;  /* reserved field nonzero, panic! */
72     i += 4;
73
74     /* Now the serious stuff. An ordinary SSH 1 public key. */
75     i += makekey(buf + i, key, NULL, 1);
76     if (len - i < 0)
77         goto end;                      /* overran */
78
79     /* Next, the comment field. */
80     j = GET_32BIT(buf + i);
81     i += 4;
82     if (len - i < j)
83         goto end;
84     comment = smalloc(j + 1);
85     if (comment) {
86         memcpy(comment, buf + i, j);
87         comment[j] = '\0';
88     }
89     i += j;
90     if (commentptr)
91         *commentptr = comment;
92     if (key)
93         key->comment = comment;
94     if (!key) {
95         return ciphertype != 0;
96     }
97
98     /*
99      * Decrypt remainder of buffer.
100      */
101     if (ciphertype) {
102         MD5Init(&md5c);
103         MD5Update(&md5c, passphrase, strlen(passphrase));
104         MD5Final(keybuf, &md5c);
105         des3_decrypt_pubkey(keybuf, buf + i, (len - i + 7) & ~7);
106         memset(keybuf, 0, sizeof(keybuf));      /* burn the evidence */
107     }
108
109     /*
110      * We are now in the secret part of the key. The first four
111      * bytes should be of the form a, b, a, b.
112      */
113     if (len - i < 4)
114         goto end;
115     if (buf[i] != buf[i + 2] || buf[i + 1] != buf[i + 3]) {
116         ret = -1;
117         goto end;
118     }
119     i += 4;
120
121     /*
122      * After that, we have one further bignum which is our
123      * decryption exponent, and then the three auxiliary values
124      * (iqmp, q, p).
125      */
126     i += makeprivate(buf + i, key);
127     if (len - i < 0)
128         goto end;
129     i += ssh1_read_bignum(buf + i, &key->iqmp);
130     if (len - i < 0)
131         goto end;
132     i += ssh1_read_bignum(buf + i, &key->q);
133     if (len - i < 0)
134         goto end;
135     i += ssh1_read_bignum(buf + i, &key->p);
136     if (len - i < 0)
137         goto end;
138
139     if (!rsa_verify(key)) {
140         freersakey(key);
141         ret = 0;
142     } else
143         ret = 1;
144
145   end:
146     memset(buf, 0, sizeof(buf));       /* burn the evidence */
147     return ret;
148 }
149
150 int loadrsakey(char *filename, struct RSAKey *key, char *passphrase)
151 {
152     FILE *fp;
153     unsigned char buf[64];
154
155     fp = fopen(filename, "rb");
156     if (!fp)
157         return 0;                      /* doesn't even exist */
158
159     /*
160      * Read the first line of the file and see if it's a v1 private
161      * key file.
162      */
163     if (fgets(buf, sizeof(buf), fp) && !strcmp(buf, rsa_signature)) {
164         return loadrsakey_main(fp, key, NULL, passphrase);
165     }
166
167     /*
168      * Otherwise, we have nothing. Return empty-handed.
169      */
170     fclose(fp);
171     return 0;
172 }
173
174 /*
175  * See whether an RSA key is encrypted. Return its comment field as
176  * well.
177  */
178 int rsakey_encrypted(char *filename, char **comment)
179 {
180     FILE *fp;
181     unsigned char buf[64];
182
183     fp = fopen(filename, "rb");
184     if (!fp)
185         return 0;                      /* doesn't even exist */
186
187     /*
188      * Read the first line of the file and see if it's a v1 private
189      * key file.
190      */
191     if (fgets(buf, sizeof(buf), fp) && !strcmp(buf, rsa_signature)) {
192         return loadrsakey_main(fp, NULL, comment, NULL);
193     }
194     fclose(fp);
195     return 0;                          /* wasn't the right kind of file */
196 }
197
198 /*
199  * Save an RSA key file. Return nonzero on success.
200  */
201 int saversakey(char *filename, struct RSAKey *key, char *passphrase)
202 {
203     unsigned char buf[16384];
204     unsigned char keybuf[16];
205     struct MD5Context md5c;
206     unsigned char *p, *estart;
207     FILE *fp;
208
209     /*
210      * Write the initial signature.
211      */
212     p = buf;
213     memcpy(p, rsa_signature, sizeof(rsa_signature));
214     p += sizeof(rsa_signature);
215
216     /*
217      * One byte giving encryption type, and one reserved (zero)
218      * uint32.
219      */
220     *p++ = (passphrase ? SSH_CIPHER_3DES : 0);
221     PUT_32BIT(p, 0);
222     p += 4;
223
224     /*
225      * An ordinary SSH 1 public key consists of: a uint32
226      * containing the bit count, then two bignums containing the
227      * modulus and exponent respectively.
228      */
229     PUT_32BIT(p, bignum_bitcount(key->modulus));
230     p += 4;
231     p += ssh1_write_bignum(p, key->modulus);
232     p += ssh1_write_bignum(p, key->exponent);
233
234     /*
235      * A string containing the comment field.
236      */
237     if (key->comment) {
238         PUT_32BIT(p, strlen(key->comment));
239         p += 4;
240         memcpy(p, key->comment, strlen(key->comment));
241         p += strlen(key->comment);
242     } else {
243         PUT_32BIT(p, 0);
244         p += 4;
245     }
246
247     /*
248      * The encrypted portion starts here.
249      */
250     estart = p;
251
252     /*
253      * Two bytes, then the same two bytes repeated.
254      */
255     *p++ = random_byte();
256     *p++ = random_byte();
257     p[0] = p[-2];
258     p[1] = p[-1];
259     p += 2;
260
261     /*
262      * Four more bignums: the decryption exponent, then iqmp, then
263      * q, then p.
264      */
265     p += ssh1_write_bignum(p, key->private_exponent);
266     p += ssh1_write_bignum(p, key->iqmp);
267     p += ssh1_write_bignum(p, key->q);
268     p += ssh1_write_bignum(p, key->p);
269
270     /*
271      * Now write zeros until the encrypted portion is a multiple of
272      * 8 bytes.
273      */
274     while ((p - estart) % 8)
275         *p++ = '\0';
276
277     /*
278      * Now encrypt the encrypted portion.
279      */
280     if (passphrase) {
281         MD5Init(&md5c);
282         MD5Update(&md5c, passphrase, strlen(passphrase));
283         MD5Final(keybuf, &md5c);
284         des3_encrypt_pubkey(keybuf, estart, p - estart);
285         memset(keybuf, 0, sizeof(keybuf));      /* burn the evidence */
286     }
287
288     /*
289      * Done. Write the result to the file.
290      */
291     fp = fopen(filename, "wb");
292     if (fp) {
293         int ret = (fwrite(buf, 1, p - buf, fp) == (size_t) (p - buf));
294         ret = ret && (fclose(fp) == 0);
295         return ret;
296     } else
297         return 0;
298 }
299
300 /* ----------------------------------------------------------------------
301  * SSH2 private key load/store functions.
302  */
303
304 /*
305  * PuTTY's own format for SSH2 keys is as follows:
306  *
307  * The file is text. Lines are terminated by CRLF, although CR-only
308  * and LF-only are tolerated on input.
309  *
310  * The first line says "PuTTY-User-Key-File-2: " plus the name of the
311  * algorithm ("ssh-dss", "ssh-rsa" etc).
312  *
313  * The next line says "Encryption: " plus an encryption type.
314  * Currently the only supported encryption types are "aes256-cbc"
315  * and "none".
316  *
317  * The next line says "Comment: " plus the comment string.
318  *
319  * Next there is a line saying "Public-Lines: " plus a number N.
320  * The following N lines contain a base64 encoding of the public
321  * part of the key. This is encoded as the standard SSH2 public key
322  * blob (with no initial length): so for RSA, for example, it will
323  * read
324  *
325  *    string "ssh-rsa"
326  *    mpint  exponent
327  *    mpint  modulus
328  *
329  * Next, there is a line saying "Private-Lines: " plus a number N,
330  * and then N lines containing the (potentially encrypted) private
331  * part of the key. For the key type "ssh-rsa", this will be
332  * composed of
333  *
334  *    mpint  private_exponent
335  *    mpint  p                  (the larger of the two primes)
336  *    mpint  q                  (the smaller prime)
337  *    mpint  iqmp               (the inverse of q modulo p)
338  *    data   padding            (to reach a multiple of the cipher block size)
339  *
340  * And for "ssh-dss", it will be composed of
341  *
342  *    mpint  x                  (the private key parameter)
343  *  [ string hash   20-byte hash of mpints p || q || g   only in old format ]
344  * 
345  * Finally, there is a line saying "Private-MAC: " plus a hex
346  * representation of a HMAC-SHA-1 of:
347  *
348  *    string  name of algorithm ("ssh-dss", "ssh-rsa")
349  *    string  encryption type
350  *    string  comment
351  *    string  public-blob
352  *    string  private-plaintext (the plaintext version of the
353  *                               private part, including the final
354  *                               padding)
355  * 
356  * The key to the MAC is itself a SHA-1 hash of:
357  * 
358  *    data    "putty-private-key-file-mac-key"
359  *    data    passphrase
360  *
361  * Encrypted keys should have a MAC, whereas unencrypted ones must
362  * have a hash.
363  *
364  * If the key is encrypted, the encryption key is derived from the
365  * passphrase by means of a succession of SHA-1 hashes. Each hash
366  * is the hash of:
367  *
368  *    uint32  sequence-number
369  *    data    passphrase
370  *
371  * where the sequence-number increases from zero. As many of these
372  * hashes are used as necessary.
373  *
374  * For backwards compatibility with snapshots between 0.51 and
375  * 0.52, we also support the older key file format, which begins
376  * with "PuTTY-User-Key-File-1" (version number differs). In this
377  * format the Private-MAC: field only covers the private-plaintext
378  * field and nothing else (and without the 4-byte string length on
379  * the front too). Moreover, for RSA keys the Private-MAC: field
380  * can be replaced with a Private-Hash: field which is a plain
381  * SHA-1 hash instead of an HMAC. This is not allowable in DSA
382  * keys. (Yes, the old format was a mess. Guess why it changed :-)
383  */
384
385 static int read_header(FILE * fp, char *header)
386 {
387     int len = 39;
388     int c;
389
390     while (len > 0) {
391         c = fgetc(fp);
392         if (c == '\n' || c == '\r' || c == EOF)
393             return 0;                  /* failure */
394         if (c == ':') {
395             c = fgetc(fp);
396             if (c != ' ')
397                 return 0;
398             *header = '\0';
399             return 1;                  /* success! */
400         }
401         if (len == 0)
402             return 0;                  /* failure */
403         *header++ = c;
404         len--;
405     }
406     return 0;                          /* failure */
407 }
408
409 static char *read_body(FILE * fp)
410 {
411     char *text;
412     int len;
413     int size;
414     int c;
415
416     size = 128;
417     text = smalloc(size);
418     len = 0;
419     text[len] = '\0';
420
421     while (1) {
422         c = fgetc(fp);
423         if (c == '\r' || c == '\n') {
424             c = fgetc(fp);
425             if (c != '\r' && c != '\n' && c != EOF)
426                 ungetc(c, fp);
427             return text;
428         }
429         if (c == EOF) {
430             sfree(text);
431             return NULL;
432         }
433         if (len + 1 > size) {
434             size += 128;
435             text = srealloc(text, size);
436         }
437         text[len++] = c;
438         text[len] = '\0';
439     }
440 }
441
442 int base64_decode_atom(char *atom, unsigned char *out)
443 {
444     int vals[4];
445     int i, v, len;
446     unsigned word;
447     char c;
448
449     for (i = 0; i < 4; i++) {
450         c = atom[i];
451         if (c >= 'A' && c <= 'Z')
452             v = c - 'A';
453         else if (c >= 'a' && c <= 'z')
454             v = c - 'a' + 26;
455         else if (c >= '0' && c <= '9')
456             v = c - '0' + 52;
457         else if (c == '+')
458             v = 62;
459         else if (c == '/')
460             v = 63;
461         else if (c == '=')
462             v = -1;
463         else
464             return 0;                  /* invalid atom */
465         vals[i] = v;
466     }
467
468     if (vals[0] == -1 || vals[1] == -1)
469         return 0;
470     if (vals[2] == -1 && vals[3] != -1)
471         return 0;
472
473     if (vals[3] != -1)
474         len = 3;
475     else if (vals[2] != -1)
476         len = 2;
477     else
478         len = 1;
479
480     word = ((vals[0] << 18) |
481             (vals[1] << 12) | ((vals[2] & 0x3F) << 6) | (vals[3] & 0x3F));
482     out[0] = (word >> 16) & 0xFF;
483     if (len > 1)
484         out[1] = (word >> 8) & 0xFF;
485     if (len > 2)
486         out[2] = word & 0xFF;
487     return len;
488 }
489
490 static char *read_blob(FILE * fp, int nlines, int *bloblen)
491 {
492     unsigned char *blob;
493     char *line;
494     int linelen, len;
495     int i, j, k;
496
497     /* We expect at most 64 base64 characters, ie 48 real bytes, per line. */
498     blob = smalloc(48 * nlines);
499     len = 0;
500     for (i = 0; i < nlines; i++) {
501         line = read_body(fp);
502         if (!line) {
503             sfree(blob);
504             return NULL;
505         }
506         linelen = strlen(line);
507         if (linelen % 4 != 0 || linelen > 64) {
508             sfree(blob);
509             sfree(line);
510             return NULL;
511         }
512         for (j = 0; j < linelen; j += 4) {
513             k = base64_decode_atom(line + j, blob + len);
514             if (!k) {
515                 sfree(line);
516                 sfree(blob);
517                 return NULL;
518             }
519             len += k;
520         }
521         sfree(line);
522     }
523     *bloblen = len;
524     return blob;
525 }
526
527 /*
528  * Magic error return value for when the passphrase is wrong.
529  */
530 struct ssh2_userkey ssh2_wrong_passphrase = {
531     NULL, NULL, NULL
532 };
533
534 struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase)
535 {
536     FILE *fp;
537     char header[40], *b, *encryption, *comment, *mac;
538     const struct ssh_signkey *alg;
539     struct ssh2_userkey *ret;
540     int cipher, cipherblk;
541     unsigned char *public_blob, *private_blob;
542     int public_blob_len, private_blob_len;
543     int i, is_mac, old_fmt;
544     int passlen = passphrase ? strlen(passphrase) : 0;
545
546     ret = NULL;                        /* return NULL for most errors */
547     comment = mac = NULL;
548     public_blob = private_blob = NULL;
549
550     fp = fopen(filename, "rb");
551     if (!fp)
552         goto error;
553
554     /* Read the first header line which contains the key type. */
555     if (!read_header(fp, header))
556         goto error;
557     if (0 == strcmp(header, "PuTTY-User-Key-File-2")) {
558         old_fmt = 0;
559     } else if (0 == strcmp(header, "PuTTY-User-Key-File-1")) {
560         /* this is an old key file; warn and then continue */
561         old_keyfile_warning();
562         old_fmt = 1;
563     } else
564         goto error;
565     if ((b = read_body(fp)) == NULL)
566         goto error;
567     /* Select key algorithm structure. */
568     if (!strcmp(b, "ssh-rsa"))
569         alg = &ssh_rsa;
570     else if (!strcmp(b, "ssh-dss"))
571         alg = &ssh_dss;
572     else {
573         sfree(b);
574         goto error;
575     }
576     sfree(b);
577
578     /* Read the Encryption header line. */
579     if (!read_header(fp, header) || 0 != strcmp(header, "Encryption"))
580         goto error;
581     if ((encryption = read_body(fp)) == NULL)
582         goto error;
583     if (!strcmp(encryption, "aes256-cbc")) {
584         cipher = 1;
585         cipherblk = 16;
586     } else if (!strcmp(encryption, "none")) {
587         cipher = 0;
588         cipherblk = 1;
589     } else {
590         sfree(encryption);
591         goto error;
592     }
593
594     /* Read the Comment header line. */
595     if (!read_header(fp, header) || 0 != strcmp(header, "Comment"))
596         goto error;
597     if ((comment = read_body(fp)) == NULL)
598         goto error;
599
600     /* Read the Public-Lines header line and the public blob. */
601     if (!read_header(fp, header) || 0 != strcmp(header, "Public-Lines"))
602         goto error;
603     if ((b = read_body(fp)) == NULL)
604         goto error;
605     i = atoi(b);
606     sfree(b);
607     if ((public_blob = read_blob(fp, i, &public_blob_len)) == NULL)
608         goto error;
609
610     /* Read the Private-Lines header line and the Private blob. */
611     if (!read_header(fp, header) || 0 != strcmp(header, "Private-Lines"))
612         goto error;
613     if ((b = read_body(fp)) == NULL)
614         goto error;
615     i = atoi(b);
616     sfree(b);
617     if ((private_blob = read_blob(fp, i, &private_blob_len)) == NULL)
618         goto error;
619
620     /* Read the Private-MAC or Private-Hash header line. */
621     if (!read_header(fp, header))
622         goto error;
623     if (0 == strcmp(header, "Private-MAC")) {
624         if ((mac = read_body(fp)) == NULL)
625             goto error;
626         is_mac = 1;
627     } else if (0 == strcmp(header, "Private-Hash") &&
628                            alg == &ssh_rsa && old_fmt) {
629         if ((mac = read_body(fp)) == NULL)
630             goto error;
631         is_mac = 0;
632     } else
633         goto error;
634
635     fclose(fp);
636     fp = NULL;
637
638     /*
639      * Decrypt the private blob.
640      */
641     if (cipher) {
642         unsigned char key[40];
643         SHA_State s;
644
645         if (!passphrase)
646             goto error;
647         if (private_blob_len % cipherblk)
648             goto error;
649
650         SHA_Init(&s);
651         SHA_Bytes(&s, "\0\0\0\0", 4);
652         SHA_Bytes(&s, passphrase, passlen);
653         SHA_Final(&s, key + 0);
654         SHA_Init(&s);
655         SHA_Bytes(&s, "\0\0\0\1", 4);
656         SHA_Bytes(&s, passphrase, passlen);
657         SHA_Final(&s, key + 20);
658         aes256_decrypt_pubkey(key, private_blob, private_blob_len);
659     }
660
661     /*
662      * Verify the MAC.
663      */
664     {
665         char realmac[41];
666         unsigned char binary[20];
667         unsigned char *macdata;
668         int maclen;
669         int free_macdata;
670
671         if (old_fmt) {
672             /* MAC (or hash) only covers the private blob. */
673             macdata = private_blob;
674             maclen = private_blob_len;
675             free_macdata = 0;
676         } else {
677             unsigned char *p;
678             int namelen = strlen(alg->name);
679             int enclen = strlen(encryption);
680             int commlen = strlen(comment);
681             maclen = (4 + namelen +
682                       4 + enclen +
683                       4 + commlen +
684                       4 + public_blob_len +
685                       4 + private_blob_len);
686             macdata = smalloc(maclen);
687             p = macdata;
688 #define DO_STR(s,len) PUT_32BIT(p,(len));memcpy(p+4,(s),(len));p+=4+(len)
689             DO_STR(alg->name, namelen);
690             DO_STR(encryption, enclen);
691             DO_STR(comment, commlen);
692             DO_STR(public_blob, public_blob_len);
693             DO_STR(private_blob, private_blob_len);
694
695             free_macdata = 1;
696         }
697
698         if (is_mac) {
699             SHA_State s;
700             unsigned char mackey[20];
701             char header[] = "putty-private-key-file-mac-key";
702
703             SHA_Init(&s);
704             SHA_Bytes(&s, header, sizeof(header)-1);
705             if (passphrase)
706                 SHA_Bytes(&s, passphrase, passlen);
707             SHA_Final(&s, mackey);
708
709             hmac_sha1_simple(mackey, 20, macdata, maclen, binary);
710
711             memset(mackey, 0, sizeof(mackey));
712             memset(&s, 0, sizeof(s));
713         } else {
714             SHA_Simple(macdata, maclen, binary);
715         }
716
717         if (free_macdata) {
718             memset(macdata, 0, maclen);
719             sfree(macdata);
720         }
721
722         for (i = 0; i < 20; i++)
723             sprintf(realmac + 2 * i, "%02x", binary[i]);
724
725         if (strcmp(mac, realmac)) {
726             /* An incorrect MAC is an unconditional Error if the key is
727              * unencrypted. Otherwise, it means Wrong Passphrase. */
728             ret = cipher ? SSH2_WRONG_PASSPHRASE : NULL;
729             goto error;
730         }
731     }
732     sfree(mac);
733
734     /*
735      * Create and return the key.
736      */
737     ret = smalloc(sizeof(struct ssh2_userkey));
738     ret->alg = alg;
739     ret->comment = comment;
740     ret->data = alg->createkey(public_blob, public_blob_len,
741                                private_blob, private_blob_len);
742     if (!ret->data) {
743         sfree(ret->comment);
744         sfree(ret);
745         ret = NULL;
746     }
747     sfree(public_blob);
748     sfree(private_blob);
749     sfree(encryption);
750     return ret;
751
752     /*
753      * Error processing.
754      */
755   error:
756     if (fp)
757         fclose(fp);
758     if (comment)
759         sfree(comment);
760     if (encryption)
761         sfree(encryption);
762     if (mac)
763         sfree(mac);
764     if (public_blob)
765         sfree(public_blob);
766     if (private_blob)
767         sfree(private_blob);
768     return ret;
769 }
770
771 char *ssh2_userkey_loadpub(char *filename, char **algorithm,
772                            int *pub_blob_len)
773 {
774     FILE *fp;
775     char header[40], *b;
776     const struct ssh_signkey *alg;
777     unsigned char *public_blob;
778     int public_blob_len;
779     int i;
780
781     public_blob = NULL;
782
783     fp = fopen(filename, "rb");
784     if (!fp)
785         goto error;
786
787     /* Read the first header line which contains the key type. */
788     if (!read_header(fp, header)
789         || (0 != strcmp(header, "PuTTY-User-Key-File-2") &&
790             0 != strcmp(header, "PuTTY-User-Key-File-1")))
791         goto error;
792     if ((b = read_body(fp)) == NULL)
793         goto error;
794     /* Select key algorithm structure. Currently only ssh-rsa. */
795     if (!strcmp(b, "ssh-rsa"))
796         alg = &ssh_rsa;
797     else if (!strcmp(b, "ssh-dss"))
798         alg = &ssh_dss;
799     else {
800         sfree(b);
801         goto error;
802     }
803     sfree(b);
804
805     /* Read the Encryption header line. */
806     if (!read_header(fp, header) || 0 != strcmp(header, "Encryption"))
807         goto error;
808     if ((b = read_body(fp)) == NULL)
809         goto error;
810     sfree(b);                          /* we don't care */
811
812     /* Read the Comment header line. */
813     if (!read_header(fp, header) || 0 != strcmp(header, "Comment"))
814         goto error;
815     if ((b = read_body(fp)) == NULL)
816         goto error;
817     sfree(b);                          /* we don't care */
818
819     /* Read the Public-Lines header line and the public blob. */
820     if (!read_header(fp, header) || 0 != strcmp(header, "Public-Lines"))
821         goto error;
822     if ((b = read_body(fp)) == NULL)
823         goto error;
824     i = atoi(b);
825     sfree(b);
826     if ((public_blob = read_blob(fp, i, &public_blob_len)) == NULL)
827         goto error;
828
829     fclose(fp);
830     *pub_blob_len = public_blob_len;
831     *algorithm = alg->name;
832     return public_blob;
833
834     /*
835      * Error processing.
836      */
837   error:
838     if (fp)
839         fclose(fp);
840     if (public_blob)
841         sfree(public_blob);
842     return NULL;
843 }
844
845 int ssh2_userkey_encrypted(char *filename, char **commentptr)
846 {
847     FILE *fp;
848     char header[40], *b, *comment;
849     int ret;
850
851     if (commentptr)
852         *commentptr = NULL;
853
854     fp = fopen(filename, "rb");
855     if (!fp)
856         return 0;
857     if (!read_header(fp, header)
858         || (0 != strcmp(header, "PuTTY-User-Key-File-2") &&
859             0 != strcmp(header, "PuTTY-User-Key-File-1"))) {
860         fclose(fp);
861         return 0;
862     }
863     if ((b = read_body(fp)) == NULL) {
864         fclose(fp);
865         return 0;
866     }
867     sfree(b);                          /* we don't care about key type here */
868     /* Read the Encryption header line. */
869     if (!read_header(fp, header) || 0 != strcmp(header, "Encryption")) {
870         fclose(fp);
871         return 0;
872     }
873     if ((b = read_body(fp)) == NULL) {
874         fclose(fp);
875         return 0;
876     }
877
878     /* Read the Comment header line. */
879     if (!read_header(fp, header) || 0 != strcmp(header, "Comment")) {
880         fclose(fp);
881         sfree(b);
882         return 1;
883     }
884     if ((comment = read_body(fp)) == NULL) {
885         fclose(fp);
886         sfree(b);
887         return 1;
888     }
889
890     if (commentptr)
891         *commentptr = comment;
892
893     fclose(fp);
894     if (!strcmp(b, "aes256-cbc"))
895         ret = 1;
896     else
897         ret = 0;
898     sfree(b);
899     return ret;
900 }
901
902 int base64_lines(int datalen)
903 {
904     /* When encoding, we use 64 chars/line, which equals 48 real chars. */
905     return (datalen + 47) / 48;
906 }
907
908 void base64_encode_atom(unsigned char *data, int n, char *out)
909 {
910     static const char base64_chars[] =
911         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
912
913     unsigned word;
914
915     word = data[0] << 16;
916     if (n > 1)
917         word |= data[1] << 8;
918     if (n > 2)
919         word |= data[2];
920     out[0] = base64_chars[(word >> 18) & 0x3F];
921     out[1] = base64_chars[(word >> 12) & 0x3F];
922     if (n > 1)
923         out[2] = base64_chars[(word >> 6) & 0x3F];
924     else
925         out[2] = '=';
926     if (n > 2)
927         out[3] = base64_chars[word & 0x3F];
928     else
929         out[3] = '=';
930 }
931
932 void base64_encode(FILE * fp, unsigned char *data, int datalen)
933 {
934     int linelen = 0;
935     char out[4];
936     int n;
937
938     while (datalen > 0) {
939         if (linelen >= 64) {
940             linelen = 0;
941             fputc('\n', fp);
942         }
943         n = (datalen < 3 ? datalen : 3);
944         base64_encode_atom(data, n, out);
945         data += n;
946         datalen -= n;
947         fwrite(out, 1, 4, fp);
948         linelen += 4;
949     }
950     fputc('\n', fp);
951 }
952
953 int ssh2_save_userkey(char *filename, struct ssh2_userkey *key,
954                       char *passphrase)
955 {
956     FILE *fp;
957     unsigned char *pub_blob, *priv_blob, *priv_blob_encrypted;
958     int pub_blob_len, priv_blob_len, priv_encrypted_len;
959     int passlen;
960     int cipherblk;
961     int i;
962     char *cipherstr;
963     unsigned char priv_mac[20];
964
965     /*
966      * Fetch the key component blobs.
967      */
968     pub_blob = key->alg->public_blob(key->data, &pub_blob_len);
969     priv_blob = key->alg->private_blob(key->data, &priv_blob_len);
970     if (!pub_blob || !priv_blob) {
971         sfree(pub_blob);
972         sfree(priv_blob);
973         return 0;
974     }
975
976     /*
977      * Determine encryption details, and encrypt the private blob.
978      */
979     if (passphrase) {
980         cipherstr = "aes256-cbc";
981         cipherblk = 16;
982     } else {
983         cipherstr = "none";
984         cipherblk = 1;
985     }
986     priv_encrypted_len = priv_blob_len + cipherblk - 1;
987     priv_encrypted_len -= priv_encrypted_len % cipherblk;
988     priv_blob_encrypted = smalloc(priv_encrypted_len);
989     memset(priv_blob_encrypted, 0, priv_encrypted_len);
990     memcpy(priv_blob_encrypted, priv_blob, priv_blob_len);
991     /* Create padding based on the SHA hash of the unpadded blob. This prevents
992      * too easy a known-plaintext attack on the last block. */
993     SHA_Simple(priv_blob, priv_blob_len, priv_mac);
994     assert(priv_encrypted_len - priv_blob_len < 20);
995     memcpy(priv_blob_encrypted + priv_blob_len, priv_mac,
996            priv_encrypted_len - priv_blob_len);
997
998     /* Now create the MAC. */
999     {
1000         unsigned char *macdata;
1001         int maclen;
1002         unsigned char *p;
1003         int namelen = strlen(key->alg->name);
1004         int enclen = strlen(cipherstr);
1005         int commlen = strlen(key->comment);
1006         SHA_State s;
1007         unsigned char mackey[20];
1008         char header[] = "putty-private-key-file-mac-key";
1009
1010         maclen = (4 + namelen +
1011                   4 + enclen +
1012                   4 + commlen +
1013                   4 + pub_blob_len +
1014                   4 + priv_encrypted_len);
1015         macdata = smalloc(maclen);
1016         p = macdata;
1017 #define DO_STR(s,len) PUT_32BIT(p,(len));memcpy(p+4,(s),(len));p+=4+(len)
1018         DO_STR(key->alg->name, namelen);
1019         DO_STR(cipherstr, enclen);
1020         DO_STR(key->comment, commlen);
1021         DO_STR(pub_blob, pub_blob_len);
1022         DO_STR(priv_blob_encrypted, priv_encrypted_len);
1023
1024         SHA_Init(&s);
1025         SHA_Bytes(&s, header, sizeof(header)-1);
1026         if (passphrase)
1027             SHA_Bytes(&s, passphrase, strlen(passphrase));
1028         SHA_Final(&s, mackey);
1029         hmac_sha1_simple(mackey, 20, macdata, maclen, priv_mac);
1030         memset(macdata, 0, maclen);
1031         sfree(macdata);
1032         memset(mackey, 0, sizeof(mackey));
1033         memset(&s, 0, sizeof(s));
1034     }
1035
1036     if (passphrase) {
1037         char key[40];
1038         SHA_State s;
1039
1040         passlen = strlen(passphrase);
1041
1042         SHA_Init(&s);
1043         SHA_Bytes(&s, "\0\0\0\0", 4);
1044         SHA_Bytes(&s, passphrase, passlen);
1045         SHA_Final(&s, key + 0);
1046         SHA_Init(&s);
1047         SHA_Bytes(&s, "\0\0\0\1", 4);
1048         SHA_Bytes(&s, passphrase, passlen);
1049         SHA_Final(&s, key + 20);
1050         aes256_encrypt_pubkey(key, priv_blob_encrypted,
1051                               priv_encrypted_len);
1052
1053         memset(key, 0, sizeof(key));
1054         memset(&s, 0, sizeof(s));
1055     }
1056
1057     fp = fopen(filename, "w");
1058     if (!fp)
1059         return 0;
1060     fprintf(fp, "PuTTY-User-Key-File-2: %s\n", key->alg->name);
1061     fprintf(fp, "Encryption: %s\n", cipherstr);
1062     fprintf(fp, "Comment: %s\n", key->comment);
1063     fprintf(fp, "Public-Lines: %d\n", base64_lines(pub_blob_len));
1064     base64_encode(fp, pub_blob, pub_blob_len);
1065     fprintf(fp, "Private-Lines: %d\n", base64_lines(priv_encrypted_len));
1066     base64_encode(fp, priv_blob_encrypted, priv_encrypted_len);
1067     fprintf(fp, "Private-MAC: ");
1068     for (i = 0; i < 20; i++)
1069         fprintf(fp, "%02x", priv_mac[i]);
1070     fprintf(fp, "\n");
1071     fclose(fp);
1072
1073     sfree(pub_blob);
1074     memset(priv_blob, 0, priv_blob_len);
1075     sfree(priv_blob);
1076     sfree(priv_blob_encrypted);
1077     return 1;
1078 }
1079
1080 /* ----------------------------------------------------------------------
1081  * A function to determine which version of SSH to try on a private
1082  * key file. Returns 0 on failure, 1 or 2 on success.
1083  */
1084 int keyfile_version(char *filename)
1085 {
1086     FILE *fp;
1087     int i;
1088
1089     fp = fopen(filename, "r");
1090     if (!fp)
1091         return 0;
1092     i = fgetc(fp);
1093     fclose(fp);
1094     if (i == 'S')
1095         return 1;                      /* "SSH PRIVATE KEY FORMAT" etc */
1096     if (i == 'P')                      /* "PuTTY-User-Key-File" etc */
1097         return 2;
1098     return 0;                          /* unrecognised or EOF */
1099 }