From e6d4db6a9da6bc1bc59c6cb471e53d5e1a236966 Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Tue, 10 Feb 2015 21:38:47 +0100 Subject: Implement URL safe base64 coding, as specified by RFC 4648. --- ChangeLog | 13 +++++++++- Makefile.in | 1 + base64.h | 10 ++++++++ base64url-decode.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ base64url-encode.c | 48 +++++++++++++++++++++++++++++++++++++ testsuite/base64-test.c | 4 ++++ 6 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 base64url-decode.c create mode 100644 base64url-encode.c diff --git a/ChangeLog b/ChangeLog index 9ee8aeae..091d6d40 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,17 @@ 2015-02-10 Niels Möller - Base-64 generalization, contributed by Amos Jeffries. + Base-64 generalization to support RFC4648 URL safe alphabet, + contributed by Amos Jeffries. + * base64url-decode.c (base64url_decode_init): New file and + function. + * base64url-encode.c (base64url_encode_init): New file and + function. + * Makefile.in (nettle_SOURCES): Added base64url-encode.c and + base64url-decode.c. + * base64.h: Declare new functions. + * testsuite/base64-test.c (test_fuzz): Test base64url encoding and + decoding. + * base64.h (struct base64_encode_ctx): Added pointer to alphabet. (struct base64_decode_ctx): Added pointer to decoding table. * base64-decode.c (base64_decode_init): Initialize table pointer. diff --git a/Makefile.in b/Makefile.in index fce79ea2..e861b23a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -81,6 +81,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \ arctwo.c arctwo-meta.c blowfish.c \ base16-encode.c base16-decode.c base16-meta.c \ base64-encode.c base64-decode.c base64-meta.c \ + base64url-encode.c base64url-decode.c \ buffer.c buffer-init.c \ camellia-crypt-internal.c camellia-table.c \ camellia-absorb.c camellia-invert-key.c \ diff --git a/base64.h b/base64.h index 07a8e2b7..10c4965c 100644 --- a/base64.h +++ b/base64.h @@ -42,12 +42,14 @@ extern "C" { /* Name mangling */ #define base64_encode_init nettle_base64_encode_init +#define base64url_encode_init nettle_base64url_encode_init #define base64_encode_single nettle_base64_encode_single #define base64_encode_update nettle_base64_encode_update #define base64_encode_final nettle_base64_encode_final #define base64_encode_raw nettle_base64_encode_raw #define base64_encode_group nettle_base64_encode_group #define base64_decode_init nettle_base64_decode_init +#define base64url_decode_init nettle_base64url_decode_init #define base64_decode_single nettle_base64_decode_single #define base64_decode_update nettle_base64_decode_update #define base64_decode_final nettle_base64_decode_final @@ -80,6 +82,10 @@ struct base64_encode_ctx void base64_encode_init(struct base64_encode_ctx *ctx); +/* Initialize encoding context for URL safe alphabet, RFC 4648. */ +void +base64url_encode_init(struct base64_encode_ctx *ctx); + /* Encodes a single byte. Returns amount of output (always 1 or 2). */ size_t base64_encode_single(struct base64_encode_ctx *ctx, @@ -132,6 +138,10 @@ struct base64_decode_ctx void base64_decode_init(struct base64_decode_ctx *ctx); +/* Initialize encoding context for URL safe alphabet, RFC 4648. */ +void +base64url_decode_init(struct base64_decode_ctx *ctx); + /* Decodes a single byte. Returns amount of output (0 or 1), or -1 on * errors. */ int diff --git a/base64url-decode.c b/base64url-decode.c new file mode 100644 index 00000000..448d5a66 --- /dev/null +++ b/base64url-decode.c @@ -0,0 +1,64 @@ +/* base64url-decode.c + + Copyright (C) 2015 Amos Jeffries, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "base64.h" + +void +base64url_decode_init(struct base64_decode_ctx *ctx) +{ + static const signed char base64url_decode_table[0x100] = + { + /* White space is HT, VT, FF, CR, LF and SPC */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -3, -1, -1, + -1, 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, -1, -1, -1, -1, 63, + -1, 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, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + + ctx->word = ctx->bits = ctx->padding = 0; + ctx->table = base64url_decode_table; +} diff --git a/base64url-encode.c b/base64url-encode.c new file mode 100644 index 00000000..6af33fb8 --- /dev/null +++ b/base64url-encode.c @@ -0,0 +1,48 @@ +/* base64url-encode.c + + Copyright (C) 2015 Amos Jeffries, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "base64.h" + +void +base64url_encode_init(struct base64_encode_ctx *ctx) +{ + static const uint8_t base64url_encode_table[64] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789-_"; + + ctx->word = ctx->bits = 0; + ctx->alphabet = base64url_encode_table; +} diff --git a/testsuite/base64-test.c b/testsuite/base64-test.c index 1a1e67d6..9fe544f9 100644 --- a/testsuite/base64-test.c +++ b/testsuite/base64-test.c @@ -59,6 +59,10 @@ test_fuzz(void) base64_encode_init(&encode); base64_decode_init(&decode); test_fuzz_once(&encode, &decode, length, input); + + base64url_encode_init(&encode); + base64url_decode_init(&decode); + test_fuzz_once(&encode, &decode, length, input); } } -- cgit v1.2.1