Fix the gcc warnings in this module (since we now seem to be
[u/mdw/putty] / import.c
index 7ad09ac..2ec1fa2 100644 (file)
--- a/import.c
+++ b/import.c
@@ -122,11 +122,6 @@ int export_ssh2(char *filename, int type,
                          (c) == '+' || (c) == '/' || (c) == '=' \
                          )
 
-extern int base64_decode_atom(char *atom, unsigned char *out);
-extern int base64_lines(int datalen);
-extern void base64_encode_atom(unsigned char *data, int n, char *out);
-extern void base64_encode(FILE *fp, unsigned char *data, int datalen, int cpl);
-
 /*
  * Read an ASN.1/BER identifier and length pair.
  * 
@@ -485,6 +480,8 @@ struct ssh2_userkey *openssh_read(char *filename, char *passphrase)
     char *modptr;
     int modlen;
 
+    blob = NULL;
+
     if (!key)
        return NULL;
 
@@ -777,14 +774,15 @@ int openssh_write(char *filename, struct ssh2_userkey *key, char *passphrase)
     seqlen = len;
     /* Now add on the SEQUENCE header. */
     len += ber_write_id_len(NULL, 16, seqlen, ASN1_CONSTRUCTED);
-    /* And round up to the cipher block size. */
+    /* Round up to the cipher block size, ensuring we have at least one
+     * byte of padding (see below). */
+    outlen = len;
     if (passphrase)
-       len = (len+7) &~ 7;
+       outlen = (outlen+8) &~ 7;
 
     /*
      * Now we know how big outblob needs to be. Allocate it.
      */
-    outlen = len;
     outblob = smalloc(outlen);
 
     /*
@@ -797,8 +795,27 @@ int openssh_write(char *filename, struct ssh2_userkey *key, char *passphrase)
        memcpy(outblob+pos, numbers[i].start, numbers[i].bytes);
        pos += numbers[i].bytes;
     }
+
+    /*
+     * Padding on OpenSSH keys is deterministic. The number of
+     * padding bytes is always more than zero, and always at most
+     * the cipher block length. The value of each padding byte is
+     * equal to the number of padding bytes. So a plaintext that's
+     * an exact multiple of the block size will be padded with 08
+     * 08 08 08 08 08 08 08 (assuming a 64-bit block cipher); a
+     * plaintext one byte less than a multiple of the block size
+     * will be padded with just 01.
+     * 
+     * This enables the OpenSSL key decryption function to strip
+     * off the padding algorithmically and return the unpadded
+     * plaintext to the next layer: it looks at the final byte, and
+     * then expects to find that many bytes at the end of the data
+     * with the same value. Those are all removed and the rest is
+     * returned.
+     */
+    assert(pos == len);
     while (pos < outlen) {
-       outblob[pos++] = random_byte();
+        outblob[pos++] = outlen - len;
     }
 
     /*
@@ -1006,9 +1023,9 @@ struct sshcom_key *load_sshcom_key(char *filename)
              * Header lines can end in a trailing backslash for
              * continuation.
              */
-            while ((len = strlen(p)) > sizeof(buffer) - (p-buffer) -1 ||
+            while ((len = strlen(p)) > (int)(sizeof(buffer) - (p-buffer) -1) ||
                    p[len-1] != '\n' || p[len-2] == '\\') {
-                if (len > (p-buffer) + sizeof(buffer)-2) {
+                if (len > (int)((p-buffer) + sizeof(buffer)-2)) {
                     errmsg = "Header line too long to deal with";
                     goto error;
                 }
@@ -1568,7 +1585,7 @@ int sshcom_write(char *filename, struct ssh2_userkey *key, char *passphrase)
     {
        int slen = 60;                 /* starts at 60 due to "Comment: " */
        char *c = key->comment;
-       while (strlen(c) > slen) {
+       while ((int)strlen(c) > slen) {
            fprintf(fp, "%.*s\\\n", slen, c);
            c += slen;
            slen = 70;                 /* allow 70 chars on subsequent lines */