summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2016-01-05 14:54:02 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2016-01-05 16:46:36 +0000
commit69a70afa8b22ee4ee72ccf583db2efd249e36721 (patch)
tree831d90de73dca71dba10edd9e73a18f95c295b7f /src
parent59b87190a41a0ac34aee74edfff9184785a73485 (diff)
DKIM: fix base64 decode to ignore whitespace; needed for private-key input
from file. Use this for general-purpose b64decode also. Testsuite: DKIM signing testcase
Diffstat (limited to 'src')
-rw-r--r--src/src/base64.c17
-rw-r--r--src/src/pdkim/pdkim-rsa.c20
-rw-r--r--src/src/pdkim/pdkim.c8
3 files changed, 38 insertions, 7 deletions
diff --git a/src/src/base64.c b/src/src/base64.c
index f4c4f233b..61b600f6c 100644
--- a/src/src/base64.c
+++ b/src/src/base64.c
@@ -134,6 +134,7 @@ Arguments:
Returns: the number of bytes in the result,
or -1 if the input was malformed
+Whitespace in the input is ignored.
A zero is added on to the end to make it easy in cases where the result is to
be interpreted as text. This is not included in the count. */
@@ -161,21 +162,29 @@ quantum this may decode to 1, 2, or 3 output bytes. */
while ((x = *code++) != 0)
{
+ if (isspace(x)) continue;
+
if (x > 127 || (x = dec64table[x]) == 255) return -1;
- if ((y = *code++) == 0 || (y = dec64table[y]) == 255)
+
+ while (isspace(y = *code++)) ;
+ if (y == 0 || (y = dec64table[y]) == 255)
return -1;
*result++ = (x << 2) | (y >> 4);
- if ((x = *code++) == '=')
+ while (isspace(x = *code++)) ;
+ if (x == '=')
{
- if (*code++ != '=' || *code != 0) return -1;
+ while (isspace(x = *code++)) ;
+ if (x != '=' || *code != 0) return -1;
}
else
{
if (x > 127 || (x = dec64table[x]) == 255) return -1;
*result++ = (y << 4) | (x >> 2);
- if ((y = (*code++)) == '=')
+
+ while (isspace(y = *code++)) ;
+ if (y == '=')
{
if (*code != 0) return -1;
}
diff --git a/src/src/pdkim/pdkim-rsa.c b/src/src/pdkim/pdkim-rsa.c
index 87cbac130..7f98fb008 100644
--- a/src/src/pdkim/pdkim-rsa.c
+++ b/src/src/pdkim/pdkim-rsa.c
@@ -82,17 +82,25 @@ int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
"-----END RSA PRIVATE KEY-----" );
if( s2 == NULL || s2 <= s1 )
+{
+debug_printf("rsa_parse_key: err 1\n");
return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
+}
s1 += 31;
if( *s1 == '\r' ) s1++;
if( *s1 == '\n' ) s1++;
- else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
+ else
+{
+debug_printf("rsa_parse_key: err 2\n");
+ return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
+}
enc = 0;
if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
{
+debug_printf("rsa_parse_key: err 3\n");
return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
}
@@ -104,14 +112,18 @@ int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
s1 = string_copyn(s1, s2-s1); /* need nul-terminated string */
if ((len = b64decode(s1, &buf)) < 0)
+{
+debug_printf("rsa_parse_key: err 4\n");
return POLARSSL_ERR_BASE64_INVALID_CHARACTER
| POLARSSL_ERR_X509_KEY_INVALID_PEM;
+}
}
buflen = len;
if( enc != 0 )
{
+debug_printf("rsa_parse_key: err 5\n");
return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
}
}
@@ -139,6 +151,7 @@ int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
{
rsa_free( rsa );
+debug_printf("rsa_parse_key: err 6\n");
return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
}
@@ -147,12 +160,14 @@ int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
{
rsa_free( rsa );
+debug_printf("rsa_parse_key: err 7\n");
return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
}
if( rsa->ver != 0 )
{
rsa_free( rsa );
+debug_printf("rsa_parse_key: err 8\n");
return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
}
@@ -166,6 +181,7 @@ int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
{
rsa_free( rsa );
+debug_printf("rsa_parse_key: err 9\n");
return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
}
@@ -174,6 +190,7 @@ int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
if( p != end )
{
rsa_free( rsa );
+debug_printf("rsa_parse_key: err 10\n");
return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
}
@@ -181,6 +198,7 @@ int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
{
rsa_free( rsa );
+debug_printf("rsa_parse_key: err 11\n");
return( ret );
}
diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c
index bd05c51b5..f93bda087 100644
--- a/src/src/pdkim/pdkim.c
+++ b/src/src/pdkim/pdkim.c
@@ -1759,13 +1759,17 @@ while (sig)
if (ctx->mode == PDKIM_MODE_SIGN)
{
rsa_context rsa;
+int perr;
rsa_init(&rsa, RSA_PKCS_V15, 0);
/* Perform private key operation */
- if (rsa_parse_key(&rsa, (unsigned char *)sig->rsa_privkey,
- strlen(sig->rsa_privkey), NULL, 0) != 0)
+ if ((perr = rsa_parse_key(&rsa, (unsigned char *)sig->rsa_privkey,
+ strlen(sig->rsa_privkey), NULL, 0)) != 0)
+{
+debug_printf("rsa_parse_key: perr 0x%x\n", perr);
return PDKIM_ERR_RSA_PRIVKEY;
+}
sig->sigdata_len = mpi_size(&(rsa.N));
sig->sigdata = store_get(sig->sigdata_len);