summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2015-12-30 18:23:33 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2015-12-30 18:23:33 +0000
commitf4d091fbe1f4cc0a6a7c11c174eaca32402290ec (patch)
treeeee13ed56d786a04fc5434205c001f1739c3165d
parent10a831a31f38ad32dcf140ac50178b845a60a126 (diff)
Consolidate base64 encode/decode routines.
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.
-rw-r--r--src/OS/Makefile-Base5
-rwxr-xr-xsrc/scripts/MakeLinks6
-rw-r--r--src/src/auths/Makefile4
-rw-r--r--src/src/auths/b64decode.c84
-rw-r--r--src/src/auths/b64encode.c74
-rw-r--r--src/src/auths/cram_md5.c8
-rw-r--r--src/src/auths/cyrus_sasl.c4
-rw-r--r--src/src/auths/get_data.c2
-rw-r--r--src/src/auths/heimdal_gssapi.c4
-rw-r--r--src/src/auths/plaintext.c10
-rw-r--r--src/src/base64.c278
-rw-r--r--src/src/expand.c8
-rw-r--r--src/src/functions.h6
-rw-r--r--src/src/lss.c4
-rw-r--r--src/src/mime.c94
-rw-r--r--src/src/mime.h26
-rw-r--r--src/src/pdkim/Makefile5
-rw-r--r--src/src/pdkim/base64.c258
-rw-r--r--src/src/pdkim/pdkim-rsa.c43
-rw-r--r--src/src/pdkim/pdkim.c56
-rw-r--r--src/src/pdkim/polarssl/base64.h83
-rw-r--r--src/src/rfc2047.c2
-rw-r--r--src/src/tls-gnu.c2
23 files changed, 357 insertions, 709 deletions
diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base
index 960c9afd6..9bc819dd7 100644
--- a/src/OS/Makefile-Base
+++ b/src/OS/Makefile-Base
@@ -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
diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks
index e011c3ca1..0e5497943 100755
--- a/src/scripts/MakeLinks
+++ b/src/scripts/MakeLinks
@@ -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 \
diff --git a/src/src/auths/Makefile b/src/src/auths/Makefile
index 45d294932..358d018e3 100644
--- a/src/src/auths/Makefile
+++ b/src/src/auths/Makefile
@@ -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
index 0a3c2ec74..000000000
--- a/src/src/auths/b64decode.c
+++ /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
index 509590c0e..000000000
--- a/src/src/auths/b64encode.c
+++ /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 */
diff --git a/src/src/auths/cram_md5.c b/src/src/auths/cram_md5.c
index f744a89ea..83d47c181 100644
--- a/src/src/auths/cram_md5.c
+++ b/src/src/auths/cram_md5.c
@@ -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)?
diff --git a/src/src/auths/cyrus_sasl.c b/src/src/auths/cyrus_sasl.c
index 5088cd3ad..bab2be36c 100644
--- a/src/src/auths/cyrus_sasl.c
+++ b/src/src/auths/cyrus_sasl.c
@@ -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);
diff --git a/src/src/auths/get_data.c b/src/src/auths/get_data.c
index a121bde72..6e344ce39 100644
--- a/src/src/auths/get_data.c
+++ b/src/src/auths/get_data.c
@@ -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;
diff --git a/src/src/auths/heimdal_gssapi.c b/src/src/auths/heimdal_gssapi.c
index 21ed75bf4..42b6450b2 100644
--- a/src/src/auths/heimdal_gssapi.c
+++ b/src/src/auths/heimdal_gssapi.c
@@ -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 */
diff --git a/src/src/auths/plaintext.c b/src/src/auths/plaintext.c
index 38dc4b1dc..aec079e67 100644
--- a/src/src/auths/plaintext.c
+++ b/src/src/auths/plaintext.c
@@ -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
index 000000000..f4c4f233b
--- /dev/null
+++ b/src/src/base64.c
@@ -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
+*/
diff --git a/src/src/expand.c b/src/src/expand.c
index a51dac570..d707c2cdb 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -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;
}
diff --git a/src/src/functions.h b/src/src/functions.h
index 3b700873a..d37b7489b 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -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 *,
diff --git a/src/src/lss.c b/src/src/lss.c
index 62b0a35f1..59cbd7ff4 100644
--- a/src/src/lss.c
+++ b/src/src/lss.c
@@ -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);
}
diff --git a/src/src/mime.c b/src/src/mime.c
index cc9ffb7c6..373774b35 100644
--- a/src/src/mime.c
+++ b/src/src/mime.c
@@ -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
diff --git a/src/src/mime.h b/src/src/mime.h
index f2b9cf65d..3022b1870 100644
--- a/src/src/mime.h
+++ b/src/src/mime.h
@@ -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
diff --git a/src/src/pdkim/Makefile b/src/src/pdkim/Makefile
index 9f3dc7945..62df49cca 100644
--- a/src/src/pdkim/Makefile
+++ b/src/src/pdkim/Makefile
@@ -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
index ae3c6b9e5..000000000
--- a/src/src/pdkim/base64.c
+++ /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
diff --git a/src/src/pdkim/pdkim-rsa.c b/src/src/pdkim/pdkim-rsa.c
index 9bd229ac9..87cbac130 100644
--- a/src/src/pdkim/pdkim-rsa.c
+++ b/src/src/pdkim/pdkim-rsa.c
@@ -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 );
}
diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c
index d9fbb8e8b..bd05c51b5 100644
--- a/src/src/pdkim/pdkim.c
+++ b/src/src/pdkim/pdkim.c
@@ -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
index 2ae416920..000000000
--- a/src/src/pdkim/polarssl/base64.h
+++ /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 */
diff --git a/src/src/rfc2047.c b/src/src/rfc2047.c
index 128e6b9c8..8c79d9c64 100644
--- a/src/src/rfc2047.c
+++ b/src/src/rfc2047.c
@@ -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 */
diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c
index 7364a66ff..601197475 100644
--- a/src/src/tls-gnu.c
+++ b/src/src/tls-gnu.c
@@ -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");
}