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