Fix some compiler warnings.
[u/mdw/putty] / import.c
index 2ff3698..ff43816 100644 (file)
--- a/import.c
+++ b/import.c
@@ -62,7 +62,7 @@ int import_target_type(int type)
 int import_encrypted(char *filename, int type, char **comment)
 {
     if (type == SSH_KEYTYPE_OPENSSH) {
-       *comment = filename;           /* OpenSSH doesn't do key comments */
+       *comment = dupstr(filename);   /* OpenSSH doesn't do key comments */
        return openssh_encrypted(filename);
     }
     if (type == SSH_KEYTYPE_SSHCOM) {
@@ -485,6 +485,8 @@ struct ssh2_userkey *openssh_read(char *filename, char *passphrase)
     char *modptr;
     int modlen;
 
+    blob = NULL;
+
     if (!key)
        return NULL;
 
@@ -777,14 +779,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 +800,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 +1028,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 +1590,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 */