From: Pekka Riikonen Date: Sun, 8 Jul 2007 17:25:43 +0000 (+0000) Subject: Added Base64 API to own files. X-Git-Tag: 1.2.beta1~210 X-Git-Url: http://git.silcnet.org/gitweb/?a=commitdiff_plain;h=befeb8f188a4a533bb8761d8cb4b02f2241c3bee;p=crypto.git Added Base64 API to own files. --- diff --git a/lib/silcutil/silcbase64.c b/lib/silcutil/silcbase64.c new file mode 100644 index 00000000..c5c4242e --- /dev/null +++ b/lib/silcutil/silcbase64.c @@ -0,0 +1,172 @@ +/* + + silcbase64.c + + Author: Pekka Riikonen + + Copyright (C) 2007 Pekka Riikonen + + 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; version 2 of the License. + + 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. + +*/ + +#include "silc.h" + +static unsigned char pem_enc[64] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* Encodes data into Base 64 encoding. Returns NULL terminated base 64 encoded + data string. */ + +char *silc_base64_encode(SilcStack stack, unsigned char *data, SilcUInt32 len) +{ + int i, j; + SilcUInt32 bits, c, char_count; + char *pem; + + char_count = 0; + bits = 0; + j = 0; + + pem = silc_scalloc(stack, ((len * 8 + 5) / 6) + 5, sizeof(*pem)); + + for (i = 0; i < len; i++) { + c = data[i]; + bits += c; + char_count++; + + if (char_count == 3) { + pem[j++] = pem_enc[bits >> 18]; + pem[j++] = pem_enc[(bits >> 12) & 0x3f]; + pem[j++] = pem_enc[(bits >> 6) & 0x3f]; + pem[j++] = pem_enc[bits & 0x3f]; + bits = 0; + char_count = 0; + } else { + bits <<= 8; + } + } + + if (char_count != 0) { + bits <<= 16 - (8 * char_count); + pem[j++] = pem_enc[bits >> 18]; + pem[j++] = pem_enc[(bits >> 12) & 0x3f]; + + if (char_count == 1) { + pem[j++] = '='; + pem[j] = '='; + } else { + pem[j++] = pem_enc[(bits >> 6) & 0x3f]; + pem[j] = '='; + } + } + + return pem; +} + +/* Same as above but puts newline ('\n') every 72 characters. */ + +char *silc_base64_encode_file(SilcStack stack, + unsigned char *data, SilcUInt32 data_len) +{ + int i, j; + SilcUInt32 len, cols; + char *pem, *pem2; + + pem = silc_base64_encode(stack, data, data_len); + len = strlen(pem); + + pem2 = silc_scalloc(stack, len + (len / 72) + 1, sizeof(*pem2)); + + for (i = 0, j = 0, cols = 1; i < len; i++, cols++) { + if (cols == 72) { + pem2[i] = '\n'; + cols = 0; + len++; + continue; + } + + pem2[i] = pem[j++]; + } + + silc_sfree(stack, pem); + return pem2; +} + +/* Decodes Base 64 into data. Returns the decoded data. */ + +unsigned char *silc_base64_decode(SilcStack stack, + unsigned char *base64, + SilcUInt32 base64_len, + SilcUInt32 *ret_len) +{ + int i, j; + SilcUInt32 len, c, char_count, bits; + unsigned char *data; + static char ialpha[256], decoder[256]; + + for (i = 64 - 1; i >= 0; i--) { + ialpha[pem_enc[i]] = 1; + decoder[pem_enc[i]] = i; + } + + char_count = 0; + bits = 0; + j = 0; + + if (!base64_len) + len = strlen(base64); + else + len = base64_len; + + data = silc_scalloc(stack, ((len * 6) / 8), sizeof(*data)); + + for (i = 0; i < len; i++) { + c = base64[i]; + + if (c == '=') + break; + + if (c > 127 || !ialpha[c]) + continue; + + bits += decoder[c]; + char_count++; + + if (char_count == 4) { + data[j++] = bits >> 16; + data[j++] = (bits >> 8) & 0xff; + data[j++] = bits & 0xff; + bits = 0; + char_count = 0; + } else { + bits <<= 6; + } + } + + switch(char_count) { + case 1: + silc_sfree(stack, data); + return NULL; + break; + case 2: + data[j++] = bits >> 10; + break; + case 3: + data[j++] = bits >> 16; + data[j++] = (bits >> 8) & 0xff; + break; + } + + if (ret_len) + *ret_len = j; + + return data; +} diff --git a/lib/silcutil/silcbase64.h b/lib/silcutil/silcbase64.h new file mode 100644 index 00000000..e060d4d7 --- /dev/null +++ b/lib/silcutil/silcbase64.h @@ -0,0 +1,87 @@ +/* + + silcbase64.h + + Author: Pekka Riikonen + + Copyright (C) 2007 Pekka Riikonen + + 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; version 2 of the License. + + 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. + +*/ + +/****h* silcutil/SILC Base64 API + * + * DESCRIPTION + * + * This interface provides Base64 encoding and decoding routines. + * + ***/ + +#ifndef SILCBASE64_H +#define SILCBASE64_H + +/****f* silcutil/SilcBase64API/silc_base64_encode + * + * SYNOPSIS + * + * char *silc_base64_encode(SilcStack stack, + * unsigned char *data, SilcUInt32 len); + * + * DESCRIPTION + * + * Encodes data into Base 64 (PEM) encoding. Returns NULL terminated + * Base 64 encoded data string. + * + * If `stack' is non-NULL the returned buffer is allocated from `stack'. + * + ***/ +char *silc_base64_encode(SilcStack stack, unsigned char *data, SilcUInt32 len); + +/****f* silcutil/SilcBase64API/silc_base64_encode_file + * + * SYNOPSIS + * + * char *silc_base64_encode_file(SilcStack stack, + * unsigned char *data, SilcUInt32 data_len); + * + * DESCRIPTION + * + * Same as silc_base64_encode() but puts newline ('\n') every 72 + * characters. + * + * If `stack' is non-NULL the returned buffer is allocated from `stack'. + * + ***/ +char *silc_base64_encode_file(SilcStack stack, + unsigned char *data, SilcUInt32 data_len); + +/****f* silcutil/SilcBase64API/silc_base_decode + * + * SYNOPSIS + * + * unsigned char *silc_base_decode(SilcStack stack, + * unsigned char *base64, + * SilcUInt32 base64_len, + * SilcUInt32 *ret_len); + * + * DESCRIPTION + * + * Decodes Base 64 (PEM) into data. Returns the decoded data. + * + * If `stack' is non-NULL the returned buffer is allocated from `stack'. + * + ***/ +unsigned char *silc_base64_decode(SilcStack stack, + unsigned char *base64, + SilcUInt32 base64_len, + SilcUInt32 *ret_len); + +#endif /* SILCBASE64_H */ diff --git a/lib/silcutil/silcstrutil.c b/lib/silcutil/silcstrutil.c index 1133c88d..e7344ad5 100644 --- a/lib/silcutil/silcstrutil.c +++ b/lib/silcutil/silcstrutil.c @@ -21,156 +21,6 @@ #include "silc.h" #include "silcstrutil.h" -static unsigned char pem_enc[64] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -/* Encodes data into Base 64 encoding. Returns NULL terminated base 64 encoded - data string. */ - -char *silc_base64_encode(unsigned char *data, SilcUInt32 len) -{ - int i, j; - SilcUInt32 bits, c, char_count; - char *pem; - - char_count = 0; - bits = 0; - j = 0; - - pem = silc_calloc(((len * 8 + 5) / 6) + 5, sizeof(*pem)); - - for (i = 0; i < len; i++) { - c = data[i]; - bits += c; - char_count++; - - if (char_count == 3) { - pem[j++] = pem_enc[bits >> 18]; - pem[j++] = pem_enc[(bits >> 12) & 0x3f]; - pem[j++] = pem_enc[(bits >> 6) & 0x3f]; - pem[j++] = pem_enc[bits & 0x3f]; - bits = 0; - char_count = 0; - } else { - bits <<= 8; - } - } - - if (char_count != 0) { - bits <<= 16 - (8 * char_count); - pem[j++] = pem_enc[bits >> 18]; - pem[j++] = pem_enc[(bits >> 12) & 0x3f]; - - if (char_count == 1) { - pem[j++] = '='; - pem[j] = '='; - } else { - pem[j++] = pem_enc[(bits >> 6) & 0x3f]; - pem[j] = '='; - } - } - - return pem; -} - -/* Same as above but puts newline ('\n') every 72 characters. */ - -char *silc_base64_encode_file(unsigned char *data, SilcUInt32 data_len) -{ - int i, j; - SilcUInt32 len, cols; - char *pem, *pem2; - - pem = silc_base64_encode(data, data_len); - len = strlen(pem); - - pem2 = silc_calloc(len + (len / 72) + 1, sizeof(*pem2)); - - for (i = 0, j = 0, cols = 1; i < len; i++, cols++) { - if (cols == 72) { - pem2[i] = '\n'; - cols = 0; - len++; - continue; - } - - pem2[i] = pem[j++]; - } - - silc_free(pem); - return pem2; -} - -/* Decodes Base 64 into data. Returns the decoded data. */ - -unsigned char *silc_base64_decode(unsigned char *base64, - SilcUInt32 base64_len, - SilcUInt32 *ret_len) -{ - int i, j; - SilcUInt32 len, c, char_count, bits; - unsigned char *data; - static char ialpha[256], decoder[256]; - - for (i = 64 - 1; i >= 0; i--) { - ialpha[pem_enc[i]] = 1; - decoder[pem_enc[i]] = i; - } - - char_count = 0; - bits = 0; - j = 0; - - if (!base64_len) - len = strlen(base64); - else - len = base64_len; - - data = silc_calloc(((len * 6) / 8), sizeof(*data)); - - for (i = 0; i < len; i++) { - c = base64[i]; - - if (c == '=') - break; - - if (c > 127 || !ialpha[c]) - continue; - - bits += decoder[c]; - char_count++; - - if (char_count == 4) { - data[j++] = bits >> 16; - data[j++] = (bits >> 8) & 0xff; - data[j++] = bits & 0xff; - bits = 0; - char_count = 0; - } else { - bits <<= 6; - } - } - - switch(char_count) { - case 1: - silc_free(data); - return NULL; - break; - case 2: - data[j++] = bits >> 10; - break; - case 3: - data[j++] = bits >> 16; - data[j++] = (bits >> 8) & 0xff; - break; - } - - if (ret_len) - *ret_len = j; - - return data; -} - /* Concatenates the `src' into `dest'. If `src_len' is more than the size of the `dest' (minus NULL at the end) the `src' will be truncated to fit. */ diff --git a/lib/silcutil/silcstrutil.h b/lib/silcutil/silcstrutil.h index 0860bb3a..1236e4fa 100644 --- a/lib/silcutil/silcstrutil.h +++ b/lib/silcutil/silcstrutil.h @@ -67,51 +67,6 @@ typedef enum { } SilcStringEncoding; /***/ -/****f* silcutil/SilcStrUtilAPI/silc_base64_encode - * - * SYNOPSIS - * - * char *silc_base64_encode(unsigned char *data, SilcUInt32 len); - * - * DESCRIPTION - * - * Encodes data into Base 64 (PEM) encoding. Returns NULL terminated - * Base 64 encoded data string. - * - ***/ -char *silc_base64_encode(unsigned char *data, SilcUInt32 len); - -/****f* silcutil/SilcStrUtilAPI/silc_base64_encode_file - * - * SYNOPSIS - * - * char *silc_base64_encode_file(unsigned char *data, SilcUInt32 data_len); - * - * DESCRIPTION - * - * Same as silc_base64_encode() but puts newline ('\n') every 72 - * characters. - * - ***/ -char *silc_base64_encode_file(unsigned char *data, SilcUInt32 data_len); - -/****f* silcutil/SilcStrUtilAPI/silc_base_decode - * - * SYNOPSIS - * - * unsigned char *silc_base_decode(unsigned char *base64, - * SilcUInt32 base64_len, - * SilcUInt32 *ret_len); - * - * DESCRIPTION - * - * Decodes Base 64 (PEM) into data. Returns the decoded data. - * - ***/ -unsigned char *silc_base64_decode(unsigned char *base64, - SilcUInt32 base64_len, - SilcUInt32 *ret_len); - /****f* silcutil/SilcStrStrUtilAPI/silc_strncat * * SYNOPSIS