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