DKIM: fix base64 decode to ignore whitespace; needed for private-key input
[exim.git] / src / src / pdkim / pdkim-rsa.c
index 9bd229ac93a4d5ae9a5a1c375b7a565b09ce8c0d..7f98fb008037581a69fcf31041d3c235dc36dd62 100644 (file)
@@ -1,5 +1,4 @@
 #include "pdkim-rsa.h"
-#include "polarssl/base64.h"
 #include <stdlib.h>
 #include <string.h>
 #include "polarssl/private-x509parse_c.h"
@@ -83,39 +82,48 @@ 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 );
         }
 
         len = 0;
-        ret = base64_decode( NULL, &len, s1, s2 - s1 );
-
-        if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
-            return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
+       {
+       extern unsigned char * string_copyn(const unsigned char *, int);
+       extern int b64decode(unsigned char *, unsigned char **);
+#define POLARSSL_ERR_BASE64_INVALID_CHARACTER              0x0012
 
-        if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
-            return( 1 );
-
-        if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
-        {
-            free( buf );
-            return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
-        }
+       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 );
         }
     }
@@ -142,10 +150,8 @@ int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
     if( ( ret = asn1_get_tag( &p, end, &len,
             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
     {
-        if( s1 != NULL )
-            free( buf );
-
         rsa_free( rsa );
+debug_printf("rsa_parse_key: err 6\n");
         return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
     }
 
@@ -153,19 +159,15 @@ int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
 
     if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
     {
-        if( s1 != NULL )
-            free( buf );
-
         rsa_free( rsa );
+debug_printf("rsa_parse_key: err 7\n");
         return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
     }
 
     if( rsa->ver != 0 )
     {
-        if( s1 != NULL )
-            free( buf );
-
         rsa_free( rsa );
+debug_printf("rsa_parse_key: err 8\n");
         return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
     }
 
@@ -178,10 +180,8 @@ int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
         ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
         ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
     {
-        if( s1 != NULL )
-            free( buf );
-
         rsa_free( rsa );
+debug_printf("rsa_parse_key: err 9\n");
         return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
     }
 
@@ -189,25 +189,18 @@ int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
 
     if( p != end )
     {
-        if( s1 != NULL )
-            free( buf );
-
         rsa_free( rsa );
+debug_printf("rsa_parse_key: err 10\n");
         return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
     }
 
     if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
     {
-        if( s1 != NULL )
-            free( buf );
-
         rsa_free( rsa );
+debug_printf("rsa_parse_key: err 11\n");
         return( ret );
     }
 
-    if( s1 != NULL )
-        free( buf );
-
     return( 0 );
 }