From f4d091fbe1f4cc0a6a7c11c174eaca32402290ec Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Wed, 30 Dec 2015 18:23:33 +0000 Subject: [PATCH] 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. --- src/OS/Makefile-Base | 5 +- src/scripts/MakeLinks | 6 +- src/src/auths/Makefile | 4 +- src/src/auths/b64decode.c | 84 ---------- src/src/auths/b64encode.c | 74 --------- src/src/auths/cram_md5.c | 8 +- src/src/auths/cyrus_sasl.c | 4 +- src/src/auths/get_data.c | 2 +- src/src/auths/heimdal_gssapi.c | 4 +- src/src/auths/plaintext.c | 10 +- src/src/base64.c | 278 ++++++++++++++++++++++++++++++++ src/src/expand.c | 8 +- src/src/functions.h | 6 +- src/src/lss.c | 4 +- src/src/mime.c | 94 ++--------- src/src/mime.h | 26 +-- src/src/pdkim/Makefile | 5 +- src/src/pdkim/base64.c | 258 ----------------------------- src/src/pdkim/pdkim-rsa.c | 43 ++--- src/src/pdkim/pdkim.c | 56 +++---- src/src/pdkim/polarssl/base64.h | 83 ---------- src/src/rfc2047.c | 2 +- src/src/tls-gnu.c | 2 +- 23 files changed, 357 insertions(+), 709 deletions(-) delete mode 100644 src/src/auths/b64decode.c delete mode 100644 src/src/auths/b64encode.c create mode 100644 src/src/base64.c delete mode 100644 src/src/pdkim/base64.c delete mode 100644 src/src/pdkim/polarssl/base64.h 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, 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 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 - * - * 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 -#include - -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 #include #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 - * - * 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"); } -- 2.30.2