Re: [exim-dev] Exim 4.87 RC3 uploaded

Top Page

Reply to this message
Author: Andreas Vögele
Date:  
To: exim-dev
CC: exim-users
Subject: Re: [exim-dev] Exim 4.87 RC3 uploaded
Jeremy Harris writes:

> The ftp site:
>
> ftp://ftp.exim.org/pub/exim/exim4/test/
>
> now has RC3 of Exim 4.87 available. Built and
> signed by myself. [...]


DKIM signing fails with OpenSSL or rather the Base64 decoding of private
keys may fail. I get error messages in the panic.log:

2016-02-07 08:50:40 1aSK7D-0001QM-Ad DKIM: signing failed (RC -101)

Exim 4.86 works fine. The key was generated as follows:

openssl genrsa -out july2015.key 1024
openssl rsa -pubout -in july2015.key -out july2015.pub

In RC3 b64decode() fails to decode the key. But the key is valid:

# openssl rsa -in july2015.key -noout -check
RSA key ok

I've replaced the code in pdkim/pdkim.c that looks for the PEM header
and decodes the key data with functions from OpenSSL. Here's an example
that wraps the full PEM data in a memory BIO and then decodes the data:

    BIO *bio = BIO_new_mem_buf(privkey_pem, -1);
    if (bio != NULL) {
       RSA *rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
       BIO_free(bio);  
    }


BIO_new_mem_buf() and PEM_read_bio_RSAPrivateKey() are available since
OpenSSL 0.9.5 and 0.9.1 respectively.

Since Exim RC3 was released the code, that I've changed, was moved to
exim_rsa_signing_init() in the RSA_OPENSSL section of pdkim/rsa.c and
there's similar code in the RSA_GCRYPT section.

I use Slackware64-current with OpenSSL 1.0.2f.

Here's the patch that I use with RC3:

--- src/pdkim/pdkim.c.orig    2016-01-18 17:54:45.000000000 +0100
+++ src/pdkim/pdkim.c    2016-02-07 10:42:14.024148978 +0100
@@ -1866,8 +1866,7 @@
     {
 #ifdef RSA_OPENSSL
     RSA * rsa;
-    uschar * p, * q;
-    int len;
+    BIO * bio;
 #elif defined(RSA_GNUTLS)
     gnutls_x509_privkey_t rsa;
     gnutls_datum_t k;
@@ -1878,14 +1877,12 @@
     /* Import private key */
 #ifdef RSA_OPENSSL


-    if (  !(p = Ustrstr(sig->rsa_privkey, "-----BEGIN RSA PRIVATE KEY-----"))
-       || !(q = Ustrstr(p+=31, "-----END RSA PRIVATE KEY-----"))
-       )
+    bio = BIO_new_mem_buf(sig->rsa_privkey, -1);
+    if (bio == NULL)
       return PDKIM_ERR_RSA_PRIVKEY;
-    *q = '\0';
-    if (  (len = b64decode(p, &p)) < 0
-       || !(rsa = d2i_RSAPrivateKey(NULL, CUSS &p, len))
-       )
+    rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
+    BIO_free(bio);
+    if (rsa == NULL)
       /*XXX todo: get errstring from library */
       return PDKIM_ERR_RSA_PRIVKEY;