summaryrefslogtreecommitdiff
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
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
-rw-r--r--src/src/base64.c17
-rw-r--r--src/src/pdkim/pdkim-rsa.c20
-rw-r--r--src/src/pdkim/pdkim.c8
-rw-r--r--test/confs/450347
-rw-r--r--test/dnszones-src/db.test.ex2
-rw-r--r--test/log/45039
-rw-r--r--test/scripts/4500-Domain-Keys-Identified-Mail/450310
7 files changed, 105 insertions, 8 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);
diff --git a/test/confs/4503 b/test/confs/4503
new file mode 100644
index 000000000..e9f2d5d47
--- /dev/null
+++ b/test/confs/4503
@@ -0,0 +1,47 @@
+# Exim test configuration 4503
+
+SERVER=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+log_selector = +outgoing_port
+acl_smtp_rcpt = accept
+acl_smtp_dkim = accept logwrite = signer: $dkim_cur_signer bits: $dkim_key_length
+
+# ----- Routers
+
+begin routers
+
+server_dump:
+ driver = redirect
+ condition = ${if eq {SERVER}{server}{yes}{no}}
+ data = :blackhole:
+
+client:
+ driver = accept
+ transport = send_to_server
+
+# ----- Transports
+
+begin transports
+
+send_to_server:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTIPV4
+ port = PORT_D
+
+ dkim_domain = test.ex
+ dkim_selector = sel
+ dkim_private_key = DIR/aux-fixed/dkim/dkim.private
+
+# End
diff --git a/test/dnszones-src/db.test.ex b/test/dnszones-src/db.test.ex
index 859626106..cde5b4321 100644
--- a/test/dnszones-src/db.test.ex
+++ b/test/dnszones-src/db.test.ex
@@ -472,7 +472,7 @@ DELAY=1500 delay1500 A HOSTIPV4
; ------- DKIM ---------
-; public key, base64 - matches private key in aux-fixed/dkim/dkim/private
+; public key, base64 - matches private key in aux-fixed/dkim/dkim.private
; openssl genrsa -out aux-fixed/dkim/dkim.private 1024
; openssl rsa -in aux-fixed/dkim/dkim.private -out /dev/stdout -pubout -outform PEM
;
diff --git a/test/log/4503 b/test/log/4503
new file mode 100644
index 000000000..056b52946
--- /dev/null
+++ b/test/log/4503
@@ -0,0 +1,9 @@
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha256 b=1024 [verification succeeded]
+1999-03-02 09:44:33 10HmaY-0005vi-00 signer: test.ex bits: 1024
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <a@test.ex> R=server_dump
+1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
diff --git a/test/scripts/4500-Domain-Keys-Identified-Mail/4503 b/test/scripts/4500-Domain-Keys-Identified-Mail/4503
new file mode 100644
index 000000000..7ca338275
--- /dev/null
+++ b/test/scripts/4500-Domain-Keys-Identified-Mail/4503
@@ -0,0 +1,10 @@
+# DKIM signing
+#
+exim -bd -DSERVER=server -oX PORT_D
+****
+exim a@test.ex
+content
+****
+millisleep 200
+killdaemon
+no_msglog_check