Consolidate base64 encode/decode routines.
authorJeremy Harris <jgh146exb@wizmail.org>
Wed, 30 Dec 2015 18:23:33 +0000 (18:23 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Wed, 30 Dec 2015 18:23:33 +0000 (18:23 +0000)
The functions previously in the auth directory, which allocate
exim-standard strings for output, are the main pair.  The file-IO
variant decode routine use by mime-handling is brought into
the same new source file.  The PDKIM functions are dropped.

23 files changed:
src/OS/Makefile-Base
src/scripts/MakeLinks
src/src/auths/Makefile
src/src/auths/b64decode.c [deleted file]
src/src/auths/b64encode.c [deleted file]
src/src/auths/cram_md5.c
src/src/auths/cyrus_sasl.c
src/src/auths/get_data.c
src/src/auths/heimdal_gssapi.c
src/src/auths/plaintext.c
src/src/base64.c [new file with mode: 0644]
src/src/expand.c
src/src/functions.h
src/src/lss.c
src/src/mime.c
src/src/mime.h
src/src/pdkim/Makefile
src/src/pdkim/base64.c [deleted file]
src/src/pdkim/pdkim-rsa.c
src/src/pdkim/pdkim.c
src/src/pdkim/polarssl/base64.h [deleted file]
src/src/rfc2047.c
src/src/tls-gnu.c

index 960c9af..9bc819d 100644 (file)
@@ -327,7 +327,7 @@ OBJ_EXPERIMENTAL = bmi_spam.o \
 
 OBJ_LOOKUPS = lookups/lf_quote.o lookups/lf_check_file.o lookups/lf_sqlperform.o
 
-OBJ_EXIM = acl.o child.o crypt16.o daemon.o dbfn.o debug.o deliver.o \
+OBJ_EXIM = acl.o base64.o child.o crypt16.o daemon.o dbfn.o debug.o deliver.o \
         directory.o dns.o drtables.o enq.o exim.o expand.o filter.o \
         filtertest.o globals.o dkim.o \
         header.o host.o ip.o log.o lss.o match.o moan.o \
@@ -580,6 +580,7 @@ local_scan.o:    config local_scan.h ../$(LOCAL_SCAN_SOURCE)
 # Dependencies for the "ordinary" exim modules
 
 acl.o:           $(HDRS) acl.c
+base64.o:        $(HDRS) mime.h base64.c
 child.o:         $(HDRS) child.c
 crypt16.o:       $(HDRS) crypt16.c
 daemon.o:        $(HDRS) daemon.c
@@ -632,7 +633,7 @@ dkim.o:          $(HDRS) pdkim/pdkim.h dkim.c
 # Dependencies for WITH_CONTENT_SCAN modules
 
 malware.o:       $(HDRS) malware.c
-mime.o:          $(HDRS) mime.c
+mime.o:          $(HDRS) mime.h mime.c
 regex.o:         $(HDRS) regex.c
 spam.o:          $(HDRS) spam.c
 spool_mbox.o:    $(HDRS) spool_mbox.c
index e011c3c..0e54979 100755 (executable)
@@ -68,7 +68,7 @@ cd ..
 # Likewise for the code for the authorization functions
 mkdir auths
 cd auths
-for f in README Makefile b64encode.c b64decode.c call_pam.c call_pwcheck.c \
+for f in README Makefile call_pam.c call_pwcheck.c \
   call_radius.c check_serv_cond.c cyrus_sasl.c cyrus_sasl.h gsasl_exim.c \
   gsasl_exim.h get_data.c get_no64_data.c heimdal_gssapi.c heimdal_gssapi.h \
   md5.c xtextencode.c xtextdecode.c cram_md5.c cram_md5.h plaintext.c plaintext.h \
@@ -82,7 +82,7 @@ cd ..
 # Likewise for the code for the PDKIM library
 mkdir pdkim
 cd pdkim
-for f in README Makefile base64.c bignum.c part-x509parse.c pdkim.c \
+for f in README Makefile bignum.c part-x509parse.c pdkim.c \
   pdkim.h pdkim-rsa.c pdkim-rsa.h rsa.c sha1.c sha2.c
 do
   ln -s ../../src/pdkim/$f $f
@@ -101,7 +101,7 @@ cd ../..
 for f in dbfunctions.h dbstuff.h exim.h functions.h globals.h local_scan.h \
   macros.h mytypes.h osfunctions.h store.h structs.h lookupapi.h \
   \
-  acl.c buildconfig.c child.c crypt16.c daemon.c dbfn.c debug.c deliver.c \
+  acl.c buildconfig.c base64.c child.c crypt16.c daemon.c dbfn.c debug.c deliver.c \
   directory.c dns.c drtables.c dummies.c enq.c exim.c exim_dbmbuild.c \
   exim_dbutil.c exim_lock.c expand.c filter.c filtertest.c globals.c \
   header.c host.c ip.c log.c lss.c match.c moan.c parse.c perl.c queue.c \
index 45d2949..358d018 100644 (file)
@@ -5,7 +5,7 @@
 # after cd'ing to the auths subdirectory. When the relevant AUTH_ macros are
 # defined, the equivalent modules herein is not included in the final binary.
 
-OBJ = auth-spa.o b64decode.o b64encode.o call_pam.o call_pwcheck.o \
+OBJ = auth-spa.o call_pam.o call_pwcheck.o \
       call_radius.o check_serv_cond.o cram_md5.o cyrus_sasl.o dovecot.o \
       get_data.o get_no64_data.o gsasl_exim.o heimdal_gssapi.o \
       md5.o plaintext.o pwcheck.o sha1.o \
@@ -22,8 +22,6 @@ auths.a:         $(OBJ)
                 $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) $*.c
 
 auth-spa.o:         $(HDRS) auth-spa.c
-b64encode.o:        $(HDRS) b64encode.c
-b64decode.o:        $(HDRS) b64decode.c
 call_pam.o:         $(HDRS) call_pam.c
 call_pwcheck.o:     $(HDRS) call_pwcheck.c pwcheck.h
 call_radius.o:      $(HDRS) call_radius.c
diff --git a/src/src/auths/b64decode.c b/src/src/auths/b64decode.c
deleted file mode 100644 (file)
index 0a3c2ec..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2009 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-#include "../exim.h"
-
-
-/*************************************************
-*          Decode byte-string in base 64         *
-*************************************************/
-
-/* This function decodes a string in base 64 format as defined in RFC 2045
-(MIME) and required by the SMTP AUTH extension (RFC 2554). The decoding
-algorithm is written out in a straightforward way. Turning it into some kind of
-compact loop is messy and would probably run more slowly.
-
-Arguments:
-  code        points to the coded string, zero-terminated
-  ptr         where to put the pointer to the result, which is in
-              dynamic store, and zero-terminated
-
-Returns:      the number of bytes in the result,
-              or -1 if the input was malformed
-
-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. */
-
-static uschar dec64table[] = {
-  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /*  0-15 */
-  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /* 16-31 */
-  255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63, /* 32-47 */
-   52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255,255,255,255, /* 48-63 */
-  255,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, /* 64-79 */
-   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, /* 80-95 */
-  255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 96-111 */
-   41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255  /* 112-127*/
-};
-
-int
-auth_b64decode(uschar *code, uschar **ptr)
-{
-register int x, y;
-uschar *result = store_get(3*(Ustrlen(code)/4) + 1);
-
-*ptr = result;
-
-/* Each cycle of the loop handles a quantum of 4 input bytes. For the last
-quantum this may decode to 1, 2, or 3 output bytes. */
-
-while ((x = (*code++)) != 0)
-  {
-  if (x > 127 || (x = dec64table[x]) == 255) return -1;
-  if ((y = (*code++)) == 0 || (y = dec64table[y]) == 255)
-    return -1;
-  *result++ = (x << 2) | (y >> 4);
-
-  if ((x = (*code++)) == '=')
-    {
-    if (*code++ != '=' || *code != 0) return -1;
-    }
-  else
-    {
-    if (x > 127 || (x = dec64table[x]) == 255) return -1;
-    *result++ = (y << 4) | (x >> 2);
-    if ((y = (*code++)) == '=')
-      {
-      if (*code != 0) return -1;
-      }
-    else
-      {
-      if (y > 127 || (y = dec64table[y]) == 255) return -1;
-      *result++ = (x << 6) | y;
-      }
-    }
-  }
-
-*result = 0;
-return result - *ptr;
-}
-
-/* End of b64decode.c */
diff --git a/src/src/auths/b64encode.c b/src/src/auths/b64encode.c
deleted file mode 100644 (file)
index 509590c..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2009 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-#include "../exim.h"
-
-
-/*************************************************
-*          Encode byte-string in base 64         *
-*************************************************/
-
-/* This function encodes a string of bytes, containing any values whatsoever,
-in base 64 as defined in RFC 2045 (MIME) and required by the SMTP AUTH
-extension (RFC 2554). The encoding algorithm is written out in a
-straightforward way. Turning it into some kind of compact loop is messy and
-would probably run more slowly.
-
-Arguments:
-  clear       points to the clear text bytes
-  len         the number of bytes to encode
-
-Returns:      a pointer to the zero-terminated base 64 string, which
-              is in working store
-*/
-
-static uschar *enc64table =
-  US"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-uschar *
-auth_b64encode(uschar *clear, int len)
-{
-uschar *code = store_get(4*((len+2)/3) + 1);
-uschar *p = code;
-
-while (len-- >0)
-  {
-  register int x, y;
-
-  x = *clear++;
-  *p++ = enc64table[(x >> 2) & 63];
-
-  if (len-- <= 0)
-    {
-    *p++ = enc64table[(x << 4) & 63];
-    *p++ = '=';
-    *p++ = '=';
-    break;
-    }
-
-  y = *clear++;
-  *p++ = enc64table[((x << 4) | ((y >> 4) & 15)) & 63];
-
-  if (len-- <= 0)
-    {
-    *p++ = enc64table[(y << 2) & 63];
-    *p++ = '=';
-    break;
-    }
-
-  x = *clear++;
-  *p++ = enc64table[((y << 2) | ((x >> 6) & 3)) & 63];
-
-  *p++ = enc64table[x & 63];
-  }
-
-*p = 0;
-
-return code;
-}
-
-/* End of b64encode.c */
index f744a89..83d47c1 100644 (file)
@@ -172,7 +172,7 @@ if (*data != 0) return UNEXPECTED;
 /* Send the challenge, read the return */
 
 if ((rc = auth_get_data(&data, challenge, Ustrlen(challenge))) != OK) return rc;
-if ((len = auth_b64decode(data, &clear)) < 0) return BAD64;
+if ((len = b64decode(data, &clear)) < 0) return BAD64;
 
 /* The return consists of a user name, space-separated from the CRAM-MD5
 digest, expressed in hex. Extract the user name and put it in $auth1 and $1.
@@ -285,7 +285,7 @@ if (smtp_write_command(outblock, FALSE, "AUTH %s\r\n", ablock->public_name) < 0)
 if (smtp_read_response(inblock, (uschar *)buffer, buffsize, '3', timeout) < 0)
   return FAIL;
 
-if (auth_b64decode(buffer + 4, &challenge) < 0)
+if (b64decode(buffer + 4, &challenge) < 0)
   {
   string_format(buffer, buffsize, "bad base 64 string in challenge: %s",
     big_buffer + 4);
@@ -310,11 +310,11 @@ for (i = 0; i < 16; i++)
   }
 
 /* Send the response, in base 64, and check the result. The response is
-in big_buffer, but auth_b64encode() returns its result in working store,
+in big_buffer, but b64encode() returns its result in working store,
 so calling smtp_write_command(), which uses big_buffer, is OK. */
 
 buffer[0] = 0;
-if (smtp_write_command(outblock, FALSE, "%s\r\n", auth_b64encode(big_buffer,
+if (smtp_write_command(outblock, FALSE, "%s\r\n", b64encode(big_buffer,
   p - big_buffer)) < 0) return FAIL_SEND;
 
 return smtp_read_response(inblock, (uschar *)buffer, buffsize, '2', timeout)?
index 5088cd3..bab2be3 100644 (file)
@@ -228,7 +228,7 @@ if((hname == NULL) ||
 
 if(inlen)
   {
-  clen=auth_b64decode(input, &clear);
+  clen = b64decode(input, &clear);
   if(clen < 0)
     {
     return BAD64;
@@ -363,7 +363,7 @@ while(rc==SASL_CONTINUE)
     HDEBUG(D_auth) debug=string_copy(input);
     if(inlen)
       {
-      clen=auth_b64decode(input, &clear);
+      clen = b64decode(input, &clear);
       if(clen < 0)
        {
         sasl_dispose(&conn);
index a121bde..6e344ce 100644 (file)
@@ -30,7 +30,7 @@ auth_get_data(uschar **aptr, uschar *challenge, int challen)
 {
 int c;
 int p = 0;
-smtp_printf("334 %s\r\n", auth_b64encode(challenge, challen));
+smtp_printf("334 %s\r\n", b64encode(challenge, challen));
 while ((c = receive_getc()) != '\n' && c != EOF)
   {
   if (p >= big_buffer_size - 1) return BAD64;
index 21ed75b..42b6450 100644 (file)
@@ -320,7 +320,7 @@ auth_heimdal_gssapi_server(auth_instance *ablock, uschar *initial_data)
         break;
 
       case 1:
-        gbufdesc_in.length = auth_b64decode(from_client, USS &gbufdesc_in.value);
+        gbufdesc_in.length = b64decode(from_client, USS &gbufdesc_in.value);
         if (gclient) {
           maj_stat = gss_release_name(&min_stat, &gclient);
           gclient = GSS_C_NO_NAME;
@@ -400,7 +400,7 @@ auth_heimdal_gssapi_server(auth_instance *ablock, uschar *initial_data)
         break;
 
       case 3:
-        gbufdesc_in.length = auth_b64decode(from_client, USS &gbufdesc_in.value);
+        gbufdesc_in.length = b64decode(from_client, USS &gbufdesc_in.value);
         maj_stat = gss_unwrap(&min_stat,
             gcontext,
             &gbufdesc_in,       /* data from client */
index 38dc4b1..aec079e 100644 (file)
@@ -99,7 +99,7 @@ if (*data != 0)
     }
   else
     {
-    if ((len = auth_b64decode(data, &clear)) < 0) return BAD64;
+    if ((len = b64decode(data, &clear)) < 0) return BAD64;
     end = clear + len;
     while (clear < end && expand_nmax < EXPAND_MAXN)
       {
@@ -121,7 +121,7 @@ while ((s = string_nextinlist(&prompts, &sep, big_buffer, big_buffer_size))
   {
   if (number++ <= expand_nmax) continue;
   if ((rc = auth_get_data(&data, s, Ustrlen(s))) != OK) return rc;
-  if ((len = auth_b64decode(data, &clear)) < 0) return BAD64;
+  if ((len = b64decode(data, &clear)) < 0) return BAD64;
   end = clear + len;
 
   /* This loop must run at least once, in case the length is zero */
@@ -228,13 +228,13 @@ while ((s = string_nextinlist(&text, &sep, big_buffer, big_buffer_size)) != NULL
     first = FALSE;
     if (smtp_write_command(outblock, FALSE, "AUTH %s%s%s\r\n",
          ablock->public_name, (len == 0)? "" : " ",
-         auth_b64encode(ss, len)) < 0)
+         b64encode(ss, len)) < 0)
       return FAIL_SEND;
     }
   else
     {
     if (smtp_write_command(outblock, FALSE, "%s\r\n",
-          auth_b64encode(ss, len)) < 0)
+          b64encode(ss, len)) < 0)
       return FAIL_SEND;
     }
 
@@ -265,7 +265,7 @@ while ((s = string_nextinlist(&text, &sep, big_buffer, big_buffer_size)) != NULL
   /* Now that we know we'll continue, we put the received data into $auth<n>,
   if possible. First, decode it: buffer+4 skips over the SMTP status code. */
 
-  clear_len = auth_b64decode(buffer+4, &clear);
+  clear_len = b64decode(buffer+4, &clear);
 
   /* If decoding failed, the default is to terminate the authentication, and
   return FAIL, with the SMTP response still in the buffer. However, if client_
diff --git a/src/src/base64.c b/src/src/base64.c
new file mode 100644 (file)
index 0000000..f4c4f23
--- /dev/null
@@ -0,0 +1,278 @@
+/*************************************************
+*     Exim - an Internet mail transport agent    *
+*************************************************/
+
+/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004, 2015 */
+/* License: GPL */
+
+/* Copyright (c) University of Cambridge 1995 - 2015 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+
+#include "exim.h"
+#ifdef WITH_CONTENT_SCAN       /* file-IO specific decode function */
+# include "mime.h"
+
+/* BASE64 decoder matrix */
+static unsigned char mime_b64[256]={
+/*   0 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
+/*  16 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
+/*  32 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,   62,  128,  128,  128,   63,
+/*  48 */   52,   53,   54,   55,   56,   57,   58,   59,   60,   61,  128,  128,  128,  255,  128,  128,
+/*  64 */  128,    0,    1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14,
+/*  80 */   15,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25,  128,  128,  128,  128,  128,
+/*  96 */  128,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   40,
+/* 112 */   41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,  128,  128,  128,  128,  128,
+/* 128 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
+/* 144 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
+/* 160 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
+/* 176 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
+/* 192 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
+/* 208 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
+/* 224 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
+/* 240 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128
+};
+
+/* decode base64 MIME part */
+ssize_t
+mime_decode_base64(FILE * in, FILE * out, uschar * boundary)
+{
+uschar ibuf[MIME_MAX_LINE_LENGTH], obuf[MIME_MAX_LINE_LENGTH];
+uschar *ipos, *opos;
+ssize_t len, size = 0;
+int bytestate = 0;
+
+opos = obuf;
+
+while (Ufgets(ibuf, MIME_MAX_LINE_LENGTH, in) != NULL)
+  {
+  if (boundary != NULL
+     && Ustrncmp(ibuf, "--", 2) == 0
+     && Ustrncmp((ibuf+2), boundary, Ustrlen(boundary)) == 0
+     )
+    break;
+
+  for (ipos = ibuf ; *ipos != '\r' && *ipos != '\n' && *ipos != 0; ++ipos)
+    if (*ipos == '=')                  /* skip padding */
+      ++bytestate;
+
+    else if (mime_b64[*ipos] == 128)   /* skip bad characters */
+      mime_set_anomaly(MIME_ANOMALY_BROKEN_BASE64);
+
+    /* simple state-machine */
+    else switch((bytestate++) & 3)
+      {
+      case 0:
+       *opos = mime_b64[*ipos] << 2; break;
+      case 1:
+       *opos++ |= mime_b64[*ipos] >> 4;
+       *opos = mime_b64[*ipos] << 4; break;
+      case 2:
+       *opos++ |= mime_b64[*ipos] >> 2;
+       *opos = mime_b64[*ipos] << 6; break;
+      case 3:
+       *opos++ |= mime_b64[*ipos]; break;
+      }
+
+  /* something to write? */
+  len = opos - obuf;
+  if (len > 0)
+    {
+    if (fwrite(obuf, 1, len, out) != len) return -1; /* error */
+    size += len;
+    /* copy incomplete last byte to start of obuf, where we continue */
+    if ((bytestate & 3) != 0)
+      *obuf = *opos;
+    opos = obuf;
+    }
+  } /* while */
+
+/* write out last byte if it was incomplete */
+if (bytestate & 3)
+  {
+  if (fwrite(obuf, 1, 1, out) != 1) return -1;
+  ++size;
+  }
+
+return size;
+}
+
+#endif /*WITH_CONTENT_SCAN*/
+
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+
+
+/*************************************************
+*          Decode byte-string in base 64         *
+*************************************************/
+
+/* This function decodes a string in base 64 format as defined in RFC 2045
+(MIME) and required by the SMTP AUTH extension (RFC 2554). The decoding
+algorithm is written out in a straightforward way. Turning it into some kind of
+compact loop is messy and would probably run more slowly.
+
+Arguments:
+  code        points to the coded string, zero-terminated
+  ptr         where to put the pointer to the result, which is in
+              dynamic store, and zero-terminated
+
+Returns:      the number of bytes in the result,
+              or -1 if the input was malformed
+
+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. */
+
+static uschar dec64table[] = {
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /*  0-15 */
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, /* 16-31 */
+  255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63, /* 32-47 */
+   52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255,255,255,255, /* 48-63 */
+  255,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, /* 64-79 */
+   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, /* 80-95 */
+  255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 96-111 */
+   41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255  /* 112-127*/
+};
+
+int
+b64decode(uschar *code, uschar **ptr)
+{
+int x, y;
+uschar *result = store_get(3*(Ustrlen(code)/4) + 1);
+
+*ptr = result;
+
+/* Each cycle of the loop handles a quantum of 4 input bytes. For the last
+quantum this may decode to 1, 2, or 3 output bytes. */
+
+while ((x = *code++) != 0)
+  {
+  if (x > 127 || (x = dec64table[x]) == 255) return -1;
+  if ((y = *code++) == 0 || (y = dec64table[y]) == 255)
+    return -1;
+
+  *result++ = (x << 2) | (y >> 4);
+
+  if ((x = *code++) == '=')
+    {
+    if (*code++ != '=' || *code != 0) return -1;
+    }
+  else
+    {
+    if (x > 127 || (x = dec64table[x]) == 255) return -1;
+    *result++ = (y << 4) | (x >> 2);
+    if ((y = (*code++)) == '=')
+      {
+      if (*code != 0) return -1;
+      }
+    else
+      {
+      if (y > 127 || (y = dec64table[y]) == 255) return -1;
+      *result++ = (x << 6) | y;
+      }
+    }
+  }
+
+*result = 0;
+return result - *ptr;
+}
+
+
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+/*************************************************
+
+/*************************************************
+*          Encode byte-string in base 64         *
+*************************************************/
+
+/* This function encodes a string of bytes, containing any values whatsoever,
+in base 64 as defined in RFC 2045 (MIME) and required by the SMTP AUTH
+extension (RFC 2554). The encoding algorithm is written out in a
+straightforward way. Turning it into some kind of compact loop is messy and
+would probably run more slowly.
+
+Arguments:
+  clear       points to the clear text bytes
+  len         the number of bytes to encode
+
+Returns:      a pointer to the zero-terminated base 64 string, which
+              is in working store
+*/
+
+static uschar *enc64table =
+  US"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+uschar *
+b64encode(uschar *clear, int len)
+{
+uschar *code = store_get(4*((len+2)/3) + 1);
+uschar *p = code;
+
+while (len-- >0)
+  {
+  register int x, y;
+
+  x = *clear++;
+  *p++ = enc64table[(x >> 2) & 63];
+
+  if (len-- <= 0)
+    {
+    *p++ = enc64table[(x << 4) & 63];
+    *p++ = '=';
+    *p++ = '=';
+    break;
+    }
+
+  y = *clear++;
+  *p++ = enc64table[((x << 4) | ((y >> 4) & 15)) & 63];
+
+  if (len-- <= 0)
+    {
+    *p++ = enc64table[(y << 2) & 63];
+    *p++ = '=';
+    break;
+    }
+
+  x = *clear++;
+  *p++ = enc64table[((y << 2) | ((x >> 6) & 3)) & 63];
+
+  *p++ = enc64table[x & 63];
+  }
+
+*p = 0;
+
+return code;
+}
+
+
+/* End of base64.c */
+/* vi: sw ai sw=2
+*/
index a51dac5..d707c2c 100644 (file)
@@ -2692,7 +2692,7 @@ switch(cond_type)
 
       if (sublen == 24)
         {
-        uschar *coded = auth_b64encode((uschar *)digest, 16);
+        uschar *coded = b64encode((uschar *)digest, 16);
         DEBUG(D_auth) debug_printf("crypteq: using MD5+B64 hashing\n"
           "  subject=%s\n  crypted=%s\n", coded, sub[1]+5);
         tempcond = (Ustrcmp(coded, sub[1]+5) == 0);
@@ -2730,7 +2730,7 @@ switch(cond_type)
 
       if (sublen == 28)
         {
-        uschar *coded = auth_b64encode((uschar *)digest, 20);
+        uschar *coded = b64encode((uschar *)digest, 20);
         DEBUG(D_auth) debug_printf("crypteq: using SHA1+B64 hashing\n"
           "  subject=%s\n  crypted=%s\n", coded, sub[1]+6);
         tempcond = (Ustrcmp(coded, sub[1]+6) == 0);
@@ -6242,7 +6242,7 @@ while (*s != 0)
             }
           }
 
-        enc = auth_b64encode(sub, out - sub);
+        enc = b64encode(sub, out - sub);
         yield = string_cat(yield, &size, &ptr, enc, Ustrlen(enc));
         continue;
         }
@@ -6884,7 +6884,7 @@ while (*s != 0)
 
       case EOP_STR2B64:
         {
-        uschar *encstr = auth_b64encode(sub, Ustrlen(sub));
+        uschar *encstr = b64encode(sub, Ustrlen(sub));
         yield = string_cat(yield, &size, &ptr, encstr, Ustrlen(encstr));
         continue;
         }
index 3b70087..d37b748 100644 (file)
@@ -84,8 +84,6 @@ extern int     acl_eval(int, uschar *, uschar **, uschar **);
 
 extern tree_node *acl_var_create(uschar *);
 extern void    acl_var_write(uschar *, uschar *, void *);
-extern uschar *auth_b64encode(uschar *, int);
-extern int     auth_b64decode(uschar *, uschar **);
 extern int     auth_call_pam(const uschar *, uschar **);
 extern int     auth_call_pwcheck(uschar *, uschar **);
 extern int     auth_call_radius(const uschar *, uschar **);
@@ -99,6 +97,8 @@ extern int     auth_get_no64_data(uschar **, uschar *);
 extern uschar *auth_xtextencode(uschar *, int);
 extern int     auth_xtextdecode(uschar *, uschar **);
 
+extern uschar *b64encode(uschar *, int);
+extern int     b64decode(uschar *, uschar **);
 extern void    bits_clear(unsigned int *, size_t, int *);
 extern void    bits_set(unsigned int *, size_t, int *);
 
@@ -264,7 +264,9 @@ struct mime_boundary_context;
 extern int     mime_acl_check(uschar *acl, FILE *f,
                  struct mime_boundary_context *, uschar **, uschar **);
 extern int     mime_decode(const uschar **);
+extern ssize_t mime_decode_base64(FILE *, FILE *, uschar *);
 extern int     mime_regex(const uschar **);
+extern void    mime_set_anomaly(int);
 #endif
 extern uschar *moan_check_errorcopy(uschar *);
 extern BOOL    moan_skipped_syntax_errors(uschar *, error_block *, uschar *,
index 62b0a35..59cbd7f 100644 (file)
@@ -117,7 +117,7 @@ Returns:      a pointer to the zero-terminated base 64 string, which
 uschar *
 lss_b64encode(uschar *clear, int len)
 {
-return auth_b64encode(clear, len);
+return b64encode(clear, len);
 }
 
 /*
@@ -135,7 +135,7 @@ be interpreted as text. This is not included in the count. */
 int
 lss_b64decode(uschar *code, uschar **ptr)
 {
-return auth_b64decode(code, ptr);
+return b64decode(code, ptr);
 }
 
 
index cc9ffb7..373774b 100644 (file)
@@ -19,13 +19,19 @@ uschar *mime_current_boundary = NULL;
 
 /* Small wrapper to set the two expandables which
    give info on detected "problems" in MIME
-   encodings. Those are defined in mime.h. */
+   encodings. Indexes are defined in mime.h. */
 
-static void
-mime_set_anomaly(int level, const char *text)
+void
+mime_set_anomaly(int idx)
 {
-  mime_anomaly_level = level;
-  mime_anomaly_text = CUS text;
+struct anom {
+  int level;
+  const uschar * text;
+} anom[] = { {1, CUS"Broken Quoted-Printable encoding detected"},
+            {2, CUS"Broken BASE64 encoding detected"} };
+
+mime_anomaly_level = anom[idx].level;
+mime_anomaly_text =  anom[idx].text;
 }
 
 
@@ -99,84 +105,6 @@ mime_decode_asis(FILE* in, FILE* out, uschar* boundary)
 }
 
 
-/* decode base64 MIME part */
-static ssize_t
-mime_decode_base64(FILE* in, FILE* out, uschar* boundary)
-{
-  uschar ibuf[MIME_MAX_LINE_LENGTH], obuf[MIME_MAX_LINE_LENGTH];
-  uschar *ipos, *opos;
-  ssize_t len, size = 0;
-  int bytestate = 0;
-
-  opos = obuf;
-
-  while (Ufgets(ibuf, MIME_MAX_LINE_LENGTH, in) != NULL)
-    {
-    if (boundary != NULL
-       && Ustrncmp(ibuf, "--", 2) == 0
-       && Ustrncmp((ibuf+2), boundary, Ustrlen(boundary)) == 0
-       )
-      break;
-
-    for (ipos = ibuf ; *ipos != '\r' && *ipos != '\n' && *ipos != 0; ++ipos)
-      {
-      if (*ipos == '=')                        /* skip padding */
-        {
-        ++bytestate;
-        continue;
-       }
-      if (mime_b64[*ipos] == 128)      /* skip bad characters */
-        {
-        mime_set_anomaly(MIME_ANOMALY_BROKEN_BASE64);
-        continue;
-       }
-
-      /* simple state-machine */
-      switch((bytestate++) & 3)
-        {
-        case 0:
-          *opos = mime_b64[*ipos] << 2;
-           break;
-        case 1:
-          *opos |= mime_b64[*ipos] >> 4;
-          ++opos;
-          *opos = mime_b64[*ipos] << 4;
-          break;
-        case 2:
-          *opos |= mime_b64[*ipos] >> 2;
-          ++opos;
-          *opos = mime_b64[*ipos] << 6;
-          break;
-        case 3:
-          *opos |= mime_b64[*ipos];
-          ++opos;
-          break;
-       } /* switch */
-      } /* for */
-
-    /* something to write? */
-    len = opos - obuf;
-    if (len > 0)
-      {
-      if (fwrite(obuf, 1, len, out) != len) return -1; /* error */
-      size += len;
-      /* copy incomplete last byte to start of obuf, where we continue */
-      if ((bytestate & 3) != 0)
-        *obuf = *opos;
-      opos = obuf;
-      }
-    } /* while */
-
-  /* write out last byte if it was incomplete */
-  if (bytestate & 3)
-    {
-    if (fwrite(obuf, 1, 1, out) != 1) return -1;
-    ++size;
-    }
-
-  return size;
-}
-
 
 /* decode quoted-printable MIME part */
 static ssize_t
index f2b9cf6..3022b18 100644 (file)
@@ -54,28 +54,8 @@ static mime_parameter mime_parameter_list[] = {
 
 
 /* MIME Anomaly list */
-#define MIME_ANOMALY_BROKEN_BASE64    2, "Broken BASE64 encoding detected"
-#define MIME_ANOMALY_BROKEN_QP        1, "Broken Quoted-Printable encoding detected"
-
-
-/* BASE64 decoder matrix */
-static unsigned char mime_b64[256]={
-/*   0 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
-/*  16 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
-/*  32 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,   62,  128,  128,  128,   63,
-/*  48 */   52,   53,   54,   55,   56,   57,   58,   59,   60,   61,  128,  128,  128,  255,  128,  128,
-/*  64 */  128,    0,    1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14,
-/*  80 */   15,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25,  128,  128,  128,  128,  128,
-/*  96 */  128,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   40,
-/* 112 */   41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,  128,  128,  128,  128,  128,
-/* 128 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
-/* 144 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
-/* 160 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
-/* 176 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
-/* 192 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
-/* 208 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
-/* 224 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
-/* 240 */  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128,  128
-};
+#define MIME_ANOMALY_BROKEN_BASE64    1
+#define MIME_ANOMALY_BROKEN_QP        0
+
 
 #endif
index 9f3dc79..62df49c 100644 (file)
@@ -1,6 +1,6 @@
 # Make file for building the pdkim library.
 
-OBJ = base64.o bignum.o pdkim.o rsa.o sha1.o sha2.o part-x509parse.o pdkim-rsa.o
+OBJ = bignum.o pdkim.o rsa.o sha1.o sha2.o part-x509parse.o pdkim-rsa.o
 
 pdkim.a:         $(OBJ)
                 @$(RM_COMMAND) -f pdkim.a
@@ -12,11 +12,10 @@ pdkim.a:         $(OBJ)
 .c.o:;           @echo "$(CC) $*.c"
                 $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) -I. $*.c
 
-base64.o:           $(HDRS) base64.c
 bignum.o:           $(HDRS) bignum.c
 part-x509parse.o:   $(HDRS) part-x509parse.c
 pdkim.o:            $(HDRS) pdkim.h pdkim-rsa.h pdkim.c
-pdkim-rsa.o:        $(HDRS) polarssl/private-x509parse_c.h polarssl/base64.h \
+pdkim-rsa.o:        $(HDRS) polarssl/private-x509parse_c.h \
                        pdkim-rsa.h pdkim-rsa.c
 rsa.o:              $(HDRS) rsa.c
 sha1.o:             $(HDRS) sha1.c
diff --git a/src/src/pdkim/base64.c b/src/src/pdkim/base64.c
deleted file mode 100644 (file)
index ae3c6b9..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- *  RFC 1521 base64 encoding/decoding
- *
- *  Copyright (C) 2006-2010, Brainspark B.V.
- *
- *  This file is part of PolarSSL (http://www.polarssl.org)
- *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- *  All rights reserved.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "polarssl/config.h"
-
-#if defined(POLARSSL_BASE64_C)
-
-#include "polarssl/base64.h"
-
-static const unsigned char base64_enc_map[64] =
-{
-    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
-    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
-    'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
-    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
-    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
-    'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
-    '8', '9', '+', '/'
-};
-
-static const unsigned char base64_dec_map[128] =
-{
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
-    127, 127, 127,  62, 127, 127, 127,  63,  52,  53,
-     54,  55,  56,  57,  58,  59,  60,  61, 127, 127,
-    127,  64, 127, 127, 127,   0,   1,   2,   3,   4,
-      5,   6,   7,   8,   9,  10,  11,  12,  13,  14,
-     15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
-     25, 127, 127, 127, 127, 127, 127,  26,  27,  28,
-     29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
-     39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
-     49,  50,  51, 127, 127, 127, 127, 127
-};
-
-/*
- * Encode a buffer into base64 format
- */
-int base64_encode( unsigned char *dst, int *dlen,
-                   const unsigned char *src, int  slen )
-{
-    int i, n;
-    int C1, C2, C3;
-    unsigned char *p;
-
-    if( slen == 0 )
-        return( 0 );
-
-    n = (slen << 3) / 6;
-
-    switch( (slen << 3) - (n * 6) )
-    {
-        case  2: n += 3; break;
-        case  4: n += 2; break;
-        default: break;
-    }
-
-    if( *dlen < n + 1 )
-    {
-        *dlen = n + 1;
-        return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
-    }
-
-    n = (slen / 3) * 3;
-
-    for( i = 0, p = dst; i < n; i += 3 )
-    {
-        C1 = *src++;
-        C2 = *src++;
-        C3 = *src++;
-
-        *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
-        *p++ = base64_enc_map[(((C1 &  3) << 4) + (C2 >> 4)) & 0x3F];
-        *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
-        *p++ = base64_enc_map[C3 & 0x3F];
-    }
-
-    if( i < slen )
-    {
-        C1 = *src++;
-        C2 = ((i + 1) < slen) ? *src++ : 0;
-
-        *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
-        *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
-
-        if( (i + 1) < slen )
-             *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
-        else *p++ = '=';
-
-        *p++ = '=';
-    }
-
-    *dlen = p - dst;
-    *p = 0;
-
-    return( 0 );
-}
-
-/*
- * Decode a base64-formatted buffer
- */
-int base64_decode( unsigned char *dst, int *dlen,
-                   const unsigned char *src, int  slen )
-{
-    int i, j, n;
-    unsigned long x;
-    unsigned char *p;
-
-    for( i = j = n = 0; i < slen; i++ )
-    {
-       unsigned char c = src[i];
-
-        if( ( slen - i ) >= 2 &&
-            c == '\r' && src[i + 1] == '\n' )
-            continue;
-
-        if( c == '\n' || c == ' ' || c == '\t' )
-            continue;
-
-        if( c == '=' && ++j > 2 )
-            return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
-
-        if( c > 127 || base64_dec_map[src[i]] == 127 )
-            return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
-
-        if( base64_dec_map[c] < 64 && j != 0 )
-            return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
-
-        n++;
-    }
-
-    if( n == 0 )
-        return( 0 );
-
-    n = ((n * 6) + 7) >> 3;
-
-    if( *dlen < n )
-    {
-        *dlen = n;
-        return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
-    }
-
-   for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
-   {
-       unsigned char c = *src;
-
-        if( c == '\r' || c == '\n' || c == ' ' || c == '\t' )
-            continue;
-
-        j -= ( base64_dec_map[c] == 64 );
-        x  = (x << 6) | ( base64_dec_map[c] & 0x3F );
-
-        if( ++n == 4 )
-        {
-            n = 0;
-            if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
-            if( j > 1 ) *p++ = (unsigned char)( x >>  8 );
-            if( j > 2 ) *p++ = (unsigned char)( x       );
-        }
-    }
-
-    *dlen = p - dst;
-
-    return( 0 );
-}
-
-#if defined(POLARSSL_SELF_TEST)
-
-#include <string.h>
-#include <stdio.h>
-
-static const unsigned char base64_test_dec[64] =
-{
-    0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
-    0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
-    0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
-    0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
-    0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
-    0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
-    0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
-    0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
-};
-
-static const unsigned char base64_test_enc[] =
-    "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
-    "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
-
-/*
- * Checkup routine
- */
-int base64_self_test( int verbose )
-{
-    int len;
-    unsigned char *src, buffer[128];
-
-    if( verbose != 0 )
-        printf( "  Base64 encoding test: " );
-
-    len = sizeof( buffer );
-    src = (unsigned char *) base64_test_dec;
-
-    if( base64_encode( buffer, &len, src, 64 ) != 0 ||
-         memcmp( base64_test_enc, buffer, 88 ) != 0 )
-    {
-        if( verbose != 0 )
-            printf( "failed\n" );
-
-        return( 1 );
-    }
-
-    if( verbose != 0 )
-        printf( "passed\n  Base64 decoding test: " );
-
-    len = sizeof( buffer );
-    src = (unsigned char *) base64_test_enc;
-
-    if( base64_decode( buffer, &len, src, 88 ) != 0 ||
-         memcmp( base64_test_dec, buffer, 64 ) != 0 )
-    {
-        if( verbose != 0 )
-            printf( "failed\n" );
-
-        return( 1 );
-    }
-
-    if( verbose != 0 )
-        printf( "passed\n\n" );
-
-    return( 0 );
-}
-
-#endif
-
-#endif
index 9bd229a..87cbac1 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"
@@ -98,19 +97,16 @@ int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
         }
 
         len = 0;
-        ret = base64_decode( NULL, &len, s1, s2 - s1 );
+       {
+       extern unsigned char * string_copyn(const unsigned char *, int);
+       extern int b64decode(unsigned char *, unsigned char **);
+#define POLARSSL_ERR_BASE64_INVALID_CHARACTER              0x0012
 
-        if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
-            return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
-
-        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)
+            return POLARSSL_ERR_BASE64_INVALID_CHARACTER
+               | POLARSSL_ERR_X509_KEY_INVALID_PEM;
+       }
 
         buflen = len;
 
@@ -142,9 +138,6 @@ 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 );
         return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
     }
@@ -153,18 +146,12 @@ 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 );
         return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
     }
 
     if( rsa->ver != 0 )
     {
-        if( s1 != NULL )
-            free( buf );
-
         rsa_free( rsa );
         return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
     }
@@ -178,9 +165,6 @@ 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 );
         return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
     }
@@ -189,9 +173,6 @@ int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
 
     if( p != end )
     {
-        if( s1 != NULL )
-            free( buf );
-
         rsa_free( rsa );
         return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
@@ -199,15 +180,9 @@ int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
 
     if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
     {
-        if( s1 != NULL )
-            free( buf );
-
         rsa_free( rsa );
         return( ret );
     }
 
-    if( s1 != NULL )
-        free( buf );
-
     return( 0 );
 }
index d9fbb8e..bd05c51 100644 (file)
@@ -27,7 +27,6 @@
 #include "polarssl/sha1.h"
 #include "polarssl/sha2.h"
 #include "polarssl/rsa.h"
-#include "polarssl/base64.h"
 
 #define PDKIM_SIGNATURE_VERSION     "1"
 #define PDKIM_PUB_RECORD_VERSION    "DKIM1"
@@ -307,7 +306,7 @@ if (pub)
   if (pub->keytype    ) free(pub->keytype);
   if (pub->srvtype    ) free(pub->srvtype);
   if (pub->notes      ) free(pub->notes);
-  if (pub->key        ) free(pub->key);
+/*  if (pub->key        ) free(pub->key); */
   free(pub);
   }
 }
@@ -331,8 +330,8 @@ if (sig)
     free(c);
     }
 
-  if (sig->sigdata         ) free(sig->sigdata);
-  if (sig->bodyhash        ) free(sig->bodyhash);
+/*  if (sig->sigdata         ) free(sig->sigdata); */
+/*  if (sig->bodyhash        ) free(sig->bodyhash); */
   if (sig->selector        ) free(sig->selector);
   if (sig->domain          ) free(sig->domain);
   if (sig->identity        ) free(sig->identity);
@@ -558,16 +557,16 @@ pdkim_decode_base64(char *str, int *num_decoded)
 {
 int dlen = 0;
 char *res;
+int old_pool = store_pool;
 
-base64_decode(NULL, &dlen, (unsigned char *)str, strlen(str));
+/* There is a store-reset between header & body reception
+so cannot use the main pool */
 
-if (!(res = malloc(dlen+1)))
-   return NULL;
-if (base64_decode((unsigned char *)res, &dlen, (unsigned char *)str, strlen(str)) != 0)
-  {
-  free(res);
-  return NULL;
-  }
+store_pool = POOL_PERM;
+dlen = b64decode(US str, USS &res);
+store_pool = old_pool;
+
+if (dlen < 0) return NULL;
 
 if (num_decoded) *num_decoded = dlen;
 return res;
@@ -579,19 +578,13 @@ return res;
 char *
 pdkim_encode_base64(char *str, int num)
 {
-int dlen = 0;
-char *res;
-
-base64_encode(NULL, &dlen, (unsigned char *)str, num);
+char * ret;
+int old_pool = store_pool;
 
-if (!(res = malloc(dlen+1)))
-  return NULL;
-if (base64_encode((unsigned char *)res, &dlen, (unsigned char *)str, num) != 0)
-  {
-  free(res);
-  return NULL;
-  }
-return res;
+store_pool = POOL_PERM;
+ret = CS b64encode(US str, num);
+store_pool = old_pool;
+return ret;
 }
 
 
@@ -1009,10 +1002,10 @@ return PDKIM_OK;
 int
 pdkim_finish_bodyhash(pdkim_ctx *ctx)
 {
-pdkim_signature *sig = ctx->sig;
+pdkim_signature *sig;
 
 /* Traverse all signatures */
-while (sig)
+for (sig = ctx->sig; sig; sig = sig->next)
   {                                    /* Finish hashes */
   unsigned char bh[32]; /* SHA-256 = 32 Bytes,  SHA-1 = 20 Bytes */
 
@@ -1034,9 +1027,7 @@ while (sig)
     {
     sig->bodyhash_len = (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32;
 
-    if (!(sig->bodyhash = malloc(sig->bodyhash_len)))
-      return PDKIM_ERR_OOM;
-    memcpy(sig->bodyhash, bh, sig->bodyhash_len);
+    sig->bodyhash = string_copyn(US bh, sig->bodyhash_len);
 
     /* If bodylength limit is set, and we have received less bytes
        than the requested amount, effectively remove the limit tag. */
@@ -1066,8 +1057,6 @@ while (sig)
       sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
       }
     }
-
-  sig = sig->next;
   }
 
 return PDKIM_OK;
@@ -1560,8 +1549,6 @@ rc = strdup(hdr->str);
 BAIL:
 pdkim_strfree(hdr);
 if (canon_all) pdkim_strfree(canon_all);
-if (base64_bh) free(base64_bh);
-if (base64_b ) free(base64_b);
 return rc;
 }
 
@@ -1781,8 +1768,7 @@ while (sig)
       return PDKIM_ERR_RSA_PRIVKEY;
 
     sig->sigdata_len = mpi_size(&(rsa.N));
-    if (!(sig->sigdata = malloc(sig->sigdata_len)))
-      return PDKIM_ERR_OOM;
+    sig->sigdata = store_get(sig->sigdata_len);
 
     if (rsa_pkcs1_sign( &rsa, RSA_PRIVATE,
                        ((sig->algo == PDKIM_ALGO_RSA_SHA1)?
diff --git a/src/src/pdkim/polarssl/base64.h b/src/src/pdkim/polarssl/base64.h
deleted file mode 100644 (file)
index 2ae4169..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * \file base64.h
- *
- *  Copyright (C) 2006-2010, Brainspark B.V.
- *
- *  This file is part of PolarSSL (http://www.polarssl.org)
- *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- *  All rights reserved.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef POLARSSL_BASE64_H
-#define POLARSSL_BASE64_H
-
-#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL               0x0010
-#define POLARSSL_ERR_BASE64_INVALID_CHARACTER              0x0012
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief          Encode a buffer into base64 format
- *
- * \param dst      destination buffer
- * \param dlen     size of the buffer
- * \param src      source buffer
- * \param slen     amount of data to be encoded
- *
- * \return         0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL.
- *                 *dlen is always updated to reflect the amount
- *                 of data that has (or would have) been written.
- *
- * \note           Call this function with *dlen = 0 to obtain the
- *                 required buffer size in *dlen
- */
-int base64_encode( unsigned char *dst, int *dlen,
-                   const unsigned char *src, int  slen );
-
-/**
- * \brief          Decode a base64-formatted buffer
- *
- * \param dst      destination buffer
- * \param dlen     size of the buffer
- * \param src      source buffer
- * \param slen     amount of data to be decoded
- *
- * \return         0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or
- *                 POLARSSL_ERR_BASE64_INVALID_DATA if the input data is not
- *                 correct. *dlen is always updated to reflect the amount
- *                 of data that has (or would have) been written.
- *
- * \note           Call this function with *dlen = 0 to obtain the
- *                 required buffer size in *dlen
- */
-int base64_decode( unsigned char *dst, int *dlen,
-                   const unsigned char *src, int  slen );
-
-/**
- * \brief          Checkup routine
- *
- * \return         0 if successful, or 1 if the test failed
- */
-int base64_self_test( int verbose );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* base64.h */
index 128e6b9..8c79d9c 100644 (file)
@@ -120,7 +120,7 @@ for (;; string = mimeword + 2)
   encoding = toupper((*q1ptr)[1]);
   **endptr = 0;
   if (encoding == 'B')
-    dlen = auth_b64decode(*q2ptr+1, dptrptr);
+    dlen = b64decode(*q2ptr+1, dptrptr);
   else if (encoding == 'Q')
     dlen = rfc2047_qpdecode(*q2ptr+1, dptrptr);
   **endptr = '?';   /* restore */
index 7364a66..6011974 100644 (file)
@@ -413,7 +413,7 @@ if (rc) {
 } else {
   old_pool = store_pool;
   store_pool = POOL_PERM;
-  tls_channelbinding_b64 = auth_b64encode(channel.data, (int)channel.size);
+  tls_channelbinding_b64 = b64encode(channel.data, (int)channel.size);
   store_pool = old_pool;
   DEBUG(D_tls) debug_printf("Have channel bindings cached for possible auth usage.\n");
 }