diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2016-01-05 14:54:02 +0000 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2016-01-05 16:46:36 +0000 |
commit | 69a70afa8b22ee4ee72ccf583db2efd249e36721 (patch) | |
tree | 831d90de73dca71dba10edd9e73a18f95c295b7f /src | |
parent | 59b87190a41a0ac34aee74edfff9184785a73485 (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.c | 17 | ||||
-rw-r--r-- | src/src/pdkim/pdkim-rsa.c | 20 | ||||
-rw-r--r-- | src/src/pdkim/pdkim.c | 8 |
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); |