diff options
author | Greg Hudson <ghudson@mit.edu> | 2012-08-27 04:18:57 -0400 |
---|---|---|
committer | Greg Hudson <ghudson@mit.edu> | 2012-09-11 01:14:06 -0400 |
commit | 3b55b8aba850fa54a4d0c5017a91641538c16835 (patch) | |
tree | 53078a415a6e74b2cfd8ae669ffbda57c1ac2dce /src/util | |
parent | 43f507711689a71d3aaec8696721b8c981f8428e (diff) | |
download | krb5-3b55b8aba850fa54a4d0c5017a91641538c16835.tar.gz krb5-3b55b8aba850fa54a4d0c5017a91641538c16835.tar.xz krb5-3b55b8aba850fa54a4d0c5017a91641538c16835.zip |
Add internal base64 encoding and decoding support
Add base64 support based on Heimdal's libroken base64 code.
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/support/Makefile.in | 14 | ||||
-rw-r--r-- | src/util/support/base64.c | 145 | ||||
-rw-r--r-- | src/util/support/t_base64.c | 110 |
3 files changed, 266 insertions, 3 deletions
diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in index 6ac91755b4..ca04ad7134 100644 --- a/src/util/support/Makefile.in +++ b/src/util/support/Makefile.in @@ -74,6 +74,7 @@ STLIBOBJS= \ utf8_conv.o \ zap.o \ path.o \ + base64.o \ $(GETTIMEOFDAY_ST_OBJ) \ $(IPC_ST_OBJ) \ $(STRLCPY_ST_OBJ) \ @@ -93,6 +94,7 @@ LIBOBJS= \ $(OUTPRE)utf8_conv.$(OBJEXT) \ $(OUTPRE)zap.$(OBJEXT) \ $(OUTPRE)path.$(OBJEXT) \ + $(OUTPRE)base64.$(OBJECT) \ $(GETTIMEOFDAY_OBJ) \ $(IPC_OBJ) \ $(STRLCPY_OBJ) \ @@ -123,7 +125,8 @@ SRCS=\ $(srcdir)/t_k5buf.c \ $(srcdir)/t_unal.c \ $(srcdir)/zap.c \ - $(srcdir)/path.c + $(srcdir)/path.c \ + $(srcdir)/base64.c SHLIB_EXPDEPS = # Add -lm if dumping thread stats, for sqrt. @@ -186,20 +189,25 @@ t_path_win.o: $(srcdir)/t_path.c path_win.o: $(srcdir)/path.c $(CC) $(ALL_CFLAGS) -DWINDOWS_PATHS -c $(srcdir)/path.c -o $@ +t_base64: t_base64.o base64.o + $(CC_LINK) -o $@ t_base64.o base64.o + t_unal: t_unal.o $(CC_LINK) -o t_unal t_unal.o -TEST_PROGS= t_k5buf t_path t_path_win t_unal +TEST_PROGS= t_k5buf t_path t_path_win t_base64 t_unal check-unix:: $(TEST_PROGS) ./t_k5buf ./t_path ./t_path_win + ./t_base64 ./t_unal clean:: $(RM) t_k5buf.o t_k5buf t_unal.o t_unal path_win.o path_win - $(RM) t_path_win.o t_path_win t_path.o t_path libkrb5support.exports + $(RM) t_path_win.o t_path_win t_path.o t_path t_base64.o t_base64 + $(RM) libkrb5support.exports @lib_frag@ @libobj_frag@ diff --git a/src/util/support/base64.c b/src/util/support/base64.c new file mode 100644 index 0000000000..e964a389e6 --- /dev/null +++ b/src/util/support/base64.c @@ -0,0 +1,145 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* util/support/base64.c - base64 encoder and decoder */ +/* + * Copyright (c) 1995-2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <k5-platform.h> +#include <k5-base64.h> + +static const char base64_chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +char * +k5_base64_encode(const void *data, size_t len) +{ + char *s, *p; + size_t i; + unsigned int c; + const unsigned char *q; + + if (len > SIZE_MAX / 4) + return NULL; + + p = s = malloc(len * 4 / 3 + 4); + if (p == NULL) + return NULL; + q = (const unsigned char *)data; + + for (i = 0; i < len;) { + c = q[i++]; + c *= 256; + if (i < len) + c += q[i]; + i++; + c *= 256; + if (i < len) + c += q[i]; + i++; + p[0] = base64_chars[(c & 0x00fc0000) >> 18]; + p[1] = base64_chars[(c & 0x0003f000) >> 12]; + p[2] = base64_chars[(c & 0x00000fc0) >> 6]; + p[3] = base64_chars[(c & 0x0000003f) >> 0]; + if (i > len) + p[3] = '='; + if (i > len + 1) + p[2] = '='; + p += 4; + } + *p = '\0'; + return s; +} + +#define DECODE_ERROR 0xffffffff + +/* Decode token, which must be four bytes long. */ +static unsigned int +decode_token(const char *token) +{ + int i, marker = 0; + unsigned int val = 0; + const char *p; + + for (i = 0; i < 4; i++) { + val *= 64; + if (token[i] == '=') { + marker++; + } else if (marker > 0) { + return DECODE_ERROR; + } else { + p = strchr(base64_chars, token[i]); + if (p == NULL) + return DECODE_ERROR; + val += p - base64_chars; + } + } + if (marker > 2) + return DECODE_ERROR; + return (marker << 24) | val; +} + +void * +k5_base64_decode(const char *str, size_t *len_out) +{ + unsigned char *data, *q; + unsigned int val, marker; + size_t len; + + *len_out = SIZE_MAX; + + /* Allocate the output buffer. */ + len = strlen(str); + if (len % 4) + return NULL; + q = data = malloc(len / 4 * 3); + if (data == NULL) { + *len_out = 0; + return NULL; + } + + /* Decode the string. */ + for (; *str != '\0'; str += 4) { + val = decode_token(str); + if (val == DECODE_ERROR) { + free(data); + return NULL; + } + marker = (val >> 24) & 0xff; + *q++ = (val >> 16) & 0xff; + if (marker < 2) + *q++ = (val >> 8) & 0xff; + if (marker < 1) + *q++ = val & 0xff; + } + *len_out = q - data; + return data; +} diff --git a/src/util/support/t_base64.c b/src/util/support/t_base64.c new file mode 100644 index 0000000000..3b1fd458cc --- /dev/null +++ b/src/util/support/t_base64.c @@ -0,0 +1,110 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* util/support/t_base64.c - base64 encoding and decoding tests */ +/* + * Copyright (c) 1999 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <k5-platform.h> +#include <k5-base64.h> + +static struct test { + void *data; + size_t len; + const char *result; +} tests[] = { + { "", 0 , "" }, + { "1", 1, "MQ==" }, + { "22", 2, "MjI=" }, + { "333", 3, "MzMz" }, + { "4444", 4, "NDQ0NA==" }, + { "55555", 5, "NTU1NTU=" }, + { "abc:def", 7, "YWJjOmRlZg==" }, + { "f", 1, "Zg==" }, + { "fo", 2, "Zm8=" }, + { "foo", 3, "Zm9v" }, + { "foob", 4, "Zm9vYg==" }, + { "fooba", 5, "Zm9vYmE=" }, + { "foobar", 6, "Zm9vYmFy" }, + { NULL, 0, NULL } +}; + +static char *negative_tests[] = { + "M=M=", + "MM=M", + "MQ===", + "====", + "M===", + NULL +}; + +int +main(int argc, char **argv) +{ + char *str, **ntest; + void *data; + int numerr = 0, numtest = 1; + const struct test *t; + size_t len; + + for (t = tests; t->data != NULL; t++) { + str = k5_base64_encode(t->data, t->len); + if (strcmp(str, t->result) != 0) { + fprintf(stderr, "failed test %d: %s != %s\n", numtest, + str, t->result); + numerr++; + } + free(str); + data = k5_base64_decode(t->result, &len); + if (len != t->len) { + fprintf(stderr, "failed test %d: len %lu != %lu\n", numtest, + (unsigned long)len, (unsigned long)t->len); + numerr++; + } else if (memcmp(data, t->data, t->len) != 0) { + fprintf(stderr, "failed test %d: data\n", numtest); + numerr++; + } + free(data); + numtest++; + } + + for (ntest = negative_tests; *ntest != NULL; ntest++) { + data = k5_base64_decode(*ntest, &len); + if (data != NULL || len != SIZE_MAX) { + fprintf(stderr, "failed test %d: successful decode: %s\n", + numtest, *ntest); + numerr++; + } + numtest++; + } + + return numerr ? 1 : 0; +} |