char *modptr;
int modlen;
+ blob = NULL;
+
if (!key)
return NULL;
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);
/*
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;
}
/*
* 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;
}
{
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 */