From 608e5adab4915ada5c2881d66d20e3d6fa0efba5 Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 31 Oct 2012 14:36:00 +0000 Subject: Add apps/netutils/codecs and associated NSH commands from Darcy Gong git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5280 42af7a65-404d-4744-a932-0658087f49c3 --- apps/netutils/codecs/Kconfig | 59 ++++++ apps/netutils/codecs/Makefile | 91 +++++++++ apps/netutils/codecs/base64.c | 359 ++++++++++++++++++++++++++++++++ apps/netutils/codecs/md5.c | 402 ++++++++++++++++++++++++++++++++++++ apps/netutils/codecs/urldecode.c | 429 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 1340 insertions(+) create mode 100644 apps/netutils/codecs/Kconfig create mode 100644 apps/netutils/codecs/Makefile create mode 100644 apps/netutils/codecs/base64.c create mode 100644 apps/netutils/codecs/md5.c create mode 100644 apps/netutils/codecs/urldecode.c (limited to 'apps/netutils/codecs') diff --git a/apps/netutils/codecs/Kconfig b/apps/netutils/codecs/Kconfig new file mode 100644 index 000000000..5248f1d5d --- /dev/null +++ b/apps/netutils/codecs/Kconfig @@ -0,0 +1,59 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +config NETUTILS_CODECS + bool "CODEC Library" + default n + ---help--- + Enables the netutils/code library: Base64 coding, URL coding, MD5. + +if NETUTILS_CODECS + +config CODECS_BASE64 + bool "Base 64 Support" + default n + ---help--- + Enables support for the following interfaces: base64_encode(), + base64_decode(), base64w_encode(), and base64w_decode(), + + Contributed NuttX by Darcy Gong. + +config CODECS_HASH_MD5 + bool "MD5 Support" + default n + ---help--- + Enables support for the following interfaces: MD5Init(), + MD5Update(), MD5Final(), MD5Transform(), md5_sum() and md5_hash() + + Contributed NuttX by Darcy Gong. + +config CODECS_URLCODE + bool "URL Decode Support" + default n + ---help--- + Enables support for the following interfaces: urlencode() and + urldecode() + + Contributed NuttX by Darcy Gong. + +config CODECS_URLCODE_NEWMEMORY + bool "URL Allocating Decode Support" + default n + ---help--- + Enables support for the following interfaces: url_encode() and + url_decode() + + Contributed NuttX by Darcy Gong. + +config CODECS_AVR_URLCODE + bool "URL Raw Decode Support" + default n + ---help--- + Enables support for the following interfaces: urlrawdecode() and + urlrawencode() + + Contributed NuttX by Darcy Gong. + +endif diff --git a/apps/netutils/codecs/Makefile b/apps/netutils/codecs/Makefile new file mode 100644 index 000000000..d1b84d460 --- /dev/null +++ b/apps/netutils/codecs/Makefile @@ -0,0 +1,91 @@ +############################################################################ +# apps/netutils/codecs/Makefile +# +# Copyright (C) 2012 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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 NuttX 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 COPYRIGHT HOLDERS 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 +# COPYRIGHT OWNER 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 $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +ASRCS = +CSRCS = urldecode.c base64.c md5.c + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}" +else + BIN = "$(APPDIR)/libapps$(LIBEXT)" +endif + +ROOTDEPPATH = --dep-path . + +# Common build + +VPATH = + +all: .built +.PHONY: context depend clean distclean + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +.built: $(OBJS) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) + @touch .built + +context: + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/apps/netutils/codecs/base64.c b/apps/netutils/codecs/base64.c new file mode 100644 index 000000000..c1656b343 --- /dev/null +++ b/apps/netutils/codecs/base64.c @@ -0,0 +1,359 @@ +/**************************************************************************** + * apps/include/netutils/base64.h + * + * This file is part of the NuttX RTOS: + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Darcy Gong + * + * Reference: + * + * Base64 encoding/decoding (RFC1341) + * Copyright (c) 2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + * + * And is re-released under the NuttX modified BSD license: + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include + +#ifdef CONFIG_CODECS_BASE64 + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: base64_tab + ****************************************************************************/ + +static void base64_tab(unsigned char *tab, size_t len, bool websafe) +{ + static const char *_tab = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + memset(tab, 0, len); + if (len >= 64) + { + memcpy(tab, _tab, 64); + } + + if (websafe) + { + tab[62] = '-'; + tab[63] = '_'; + } +} + +/**************************************************************************** + * Name: _base64_encode + * + * Description: + * Base64 encode + * + * Caller is responsible for freeing the returned buffer. Returned buffer + * is nul terminated to make it easier to use as a C string. The nul + * terminator is not included in out_len. + * + * Input Parameters: + * src: Data to be encoded + * len: Length of the data to be encoded + * out_len: Pointer to output length variable, or NULL if not used + * + * Returned Value: + * Returns: Allocated buffer of out_len bytes of encoded data, + * or NULL on failure + * + ****************************************************************************/ + +static unsigned char *_base64_encode(const unsigned char *src, size_t len, + unsigned char *dst, size_t * out_len, + bool websafe) +{ + unsigned char *out; + unsigned char *pos; + const unsigned char *end; + const unsigned char *in; + size_t olen; +/*int line_len; */ + unsigned char base64_table[64]; + char ch = '='; + + if (websafe) + { + ch = '.'; + } + + base64_tab(base64_table, sizeof(base64_table), websafe); + olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */ + +#if 0 + olen += olen / 72; /* line feeds */ + olen++; /* nul termination */ + out = malloc(olen); + if (out == NULL) + { + return NULL; + } +#endif + + end = src + len; + in = src; + + if (dst) + { + pos = out = dst; + } + else + { + pos = out = malloc(olen); + if (out == NULL) + { + return NULL; + } + } + +/*line_len = 0; */ + while (end - in >= 3) + { + *pos++ = base64_table[in[0] >> 2]; + *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; + *pos++ = base64_table[in[2] & 0x3f]; + in += 3; + /* line_len += 4; */ + } + + if (end - in) + { + *pos++ = base64_table[in[0] >> 2]; + if (end - in == 1) + { + *pos++ = base64_table[(in[0] & 0x03) << 4]; + *pos++ = ch; /* *pos++ = '='; */ + } + else + { + *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + *pos++ = base64_table[(in[1] & 0x0f) << 2]; + } + *pos++ = ch; /* *pos++ = '='; */ + /* line_len += 4; */ + } + +#if 0 + if (line_len) + { + *pos++ = '\n'; + } +#endif + + *pos = '\0'; + if (out_len) + { + *out_len = pos - out; + } + +/*out[*out_len] = '\0'; */ + return out; +} + +/**************************************************************************** + * Name: _base64_decode + * + * Description: + * Base64 decode + * + * Caller is responsible for freeing the returned buffer. + * + * Input Parameters: + * src: Data to be decoded + * len: Length of the data to be decoded + * out_len: Pointer to output length variable + * + * Returned Value: + * Returns: Allocated buffer of out_len bytes of decoded data, + * or NULL on failure + * + ****************************************************************************/ + +static unsigned char *_base64_decode(const unsigned char *src, size_t len, + unsigned char *dst, size_t * out_len, + bool websafe) +{ + unsigned char dtable[256]; + unsigned char *out; + unsigned char *pos; + unsigned char in[4]; + unsigned char block[4]; + unsigned char tmp; + size_t count; + size_t i; + unsigned char base64_table[64]; + char ch = '='; + + if (websafe) + { + ch = '.'; + } + base64_tab(base64_table, sizeof(base64_table), websafe); + + memset(dtable, 0x80, 256); + for (i = 0; i < sizeof(base64_table); i++) + { + dtable[base64_table[i]] = i; + } + + dtable[(int)ch] = 0; /* dtable['='] = 0; */ + + count = 0; + for (i = 0; i < len; i++) + { + if (dtable[src[i]] != 0x80) + { + count++; + } + } + + if (count % 4) + { + return NULL; + } + + if (dst) + { + pos = out = dst; + } + else + { + pos = out = malloc(count); + if (out == NULL) + { + return NULL; + } + } + + count = 0; + for (i = 0; i < len; i++) + { + tmp = dtable[src[i]]; + if (tmp == 0x80) + { + continue; + } + + in[count] = src[i]; + block[count] = tmp; + count++; + if (count == 4) + { + *pos++ = (block[0] << 2) | (block[1] >> 4); + *pos++ = (block[1] << 4) | (block[2] >> 2); + *pos++ = (block[2] << 6) | block[3]; + count = 0; + } + } + + if (pos > out) + { + if (in[2] == ch) /* if (in[2] == '=') */ + { + pos -= 2; + } + else if (in[3] == ch) /* else if (in[3] == '=') */ + { + pos--; + } + } + + *out_len = pos - out; + return out; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: base64_encode + ****************************************************************************/ + +unsigned char *base64_encode(const unsigned char *src, size_t len, + unsigned char *dst, size_t * out_len) +{ + return _base64_encode(src, len, dst, out_len, false); +} + +/**************************************************************************** + * Name: base64_decode + ****************************************************************************/ + +unsigned char *base64_decode(const unsigned char *src, size_t len, + unsigned char *dst, size_t * out_len) +{ + return _base64_decode(src, len, dst, out_len, false); +} + +/**************************************************************************** + * Name: base64w_encode + ****************************************************************************/ + +unsigned char *base64w_encode(const unsigned char *src, size_t len, + unsigned char *dst, size_t * out_len) +{ + return _base64_encode(src, len, dst, out_len, true); +} + +/**************************************************************************** + * Name: base64w_decode + ****************************************************************************/ + +unsigned char *base64w_decode(const unsigned char *src, size_t len, + unsigned char *dst, size_t * out_len) +{ + return _base64_decode(src, len, dst, out_len, true); +} + +#endif /* CONFIG_CODECS_BASE64 */ diff --git a/apps/netutils/codecs/md5.c b/apps/netutils/codecs/md5.c new file mode 100644 index 000000000..da25d14b1 --- /dev/null +++ b/apps/netutils/codecs/md5.c @@ -0,0 +1,402 @@ +/**************************************************************************** + * apps/include/netutils/base64.h + * + * This file is part of the NuttX RTOS: + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Darcy Gong + * + * Reference: + * + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + * + * See README and COPYING for more details. + * + * And is re-released under the NuttX modified BSD license: + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#ifdef CONFIG_CODECS_HASH_MD5 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +# define F1(x, y, z) (z ^ (x & (y ^ z))) +# define F2(x, y, z) F1(z, x, y) +# define F3(x, y, z) (x ^ y ^ z) +# define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +# define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: byteReverse + ****************************************************************************/ + +#ifndef CONFIG_ENDIAN_BIG +# define byteReverse(buf, len) +#else +static void byteReverse(unsigned char *buf, unsigned longs) +{ + uint32_t t; + do + { + t = ((uint32_t)buf[3] << 8) | + ((uint32_t)buf[2]) << 16) | + ((uint32_t)buf[1] << 8) | + (uint32_t)buf[0]; + + *(uint32_t*)buf = t; + buf += 4; + } + while (--longs); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: MD5Init + * + * Description: + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + * + ****************************************************************************/ + +void MD5Init(struct MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/**************************************************************************** + * Name: MD5Update + * + * Description: + * Update context to reflect the concatenation of another buffer full + * of bytes. + * + ****************************************************************************/ + +void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) +{ + uint32_t t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) + { + /* Carry from low to high */ + + ctx->bits[1]++; + } + + ctx->bits[1] += len >> 29; + + /* Bytes already in shsInfo->data */ + + t = (t >> 3) & 0x3f; + + /* Handle any leading odd-sized chunks */ + + if (t) + { + unsigned char *p = (unsigned char *)ctx->in + t; + + t = 64 - t; + if (len < t) + { + memcpy(p, buf, len); + return; + } + + memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + buf += t; + len -= t; + } + + /* Process data in 64-byte chunks */ + + while (len >= 64) + { + memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memcpy(ctx->in, buf, len); +} + +/**************************************************************************** + * Name: MD5Final + * + * Description: + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + * + ****************************************************************************/ + +void MD5Final(unsigned char digest[16], struct MD5Context *ctx) +{ + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + + count = (ctx->bits[0] >> 3) & 0x3f; + + /* Set the first char of padding to 0x80. This is safe since there is + * always at least one byte free. + */ + + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + + if (count < 8) + { + /* Two lots of padding: Pad the first block to 64 bytes */ + + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + + /* Now fill the next block with 56 bytes */ + + memset(ctx->in, 0, 56); + } + else + { + /* Pad block to 56 bytes */ + + memset(p, 0, count - 8); + } + + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + + ((uint32_t *)ctx->in)[14] = ctx->bits[0]; + ((uint32_t *)ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + byteReverse((unsigned char *)ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ +} + +/**************************************************************************** + * Name: MD5Transform + * + * Description: + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + * + ****************************************************************************/ + +void MD5Transform(uint32_t buf[4], uint32_t const in[16]) +{ + register uint32_t a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +/**************************************************************************** + * Name: md5_sum + * + * Description: + * MD5 hash for a data block + * + * Input Parameters: + * addr: Pointers to the data area + * len: Lengths of the data block + * mac: Buffer for the hash + * + ****************************************************************************/ + +void md5_sum(const uint8_t * addr, const size_t len, uint8_t * mac) +{ + MD5_CTX ctx; + + MD5Init(&ctx); + MD5Update(&ctx, addr, len); + MD5Final(mac, &ctx); +} + +/**************************************************************************** + * Name: md5_hash + ****************************************************************************/ + +char *md5_hash(const uint8_t * addr, const size_t len) +{ + uint8_t digest[16]; + char *hash; + int i; + + hash = malloc(33); + md5_sum(addr, len, digest); + for (i = 0; i < 16; i++) + { + vsprintf(&hash[i * 2], "%.2x", digest[i]); + } + + hash[32] = 0; + return hash; +} + +#endif /* CONFIG_CODECS_HASH_MD5 */ diff --git a/apps/netutils/codecs/urldecode.c b/apps/netutils/codecs/urldecode.c new file mode 100644 index 000000000..9b3b60955 --- /dev/null +++ b/apps/netutils/codecs/urldecode.c @@ -0,0 +1,429 @@ +/**************************************************************************** + * apps/include/netutils/base64.h + * + * This file is part of the NuttX RTOS: + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Darcy Gong + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_CODECS_URLCODE +# define IS_HEX_CHAR(ch) \ + ((ch >= '0' && ch <= '9') || \ + (ch >= 'a' && ch <= 'f') || \ + (ch >= 'A' && ch <= 'F')) + +# define HEX_VALUE(ch, value) \ + if (ch >= '0' && ch <= '9') \ + { \ + value = ch - '0'; \ + } \ + else if (ch >= 'a' && ch <= 'f') \ + { \ + value = ch - 'a' + 10; \ + } \ + else \ + { \ + value = ch - 'A' + 10; \ + } +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: from_hex + * + * Description: + * Converts a hex character to its integer value, + * + ****************************************************************************/ + +#ifdef CONFIG_CODECS_URLCODE_NEWMEMORY +static char from_hex(char ch) +{ + return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10; +} +#endif + +/**************************************************************************** + * Name: + * + * Description: + * Converts an integer value to its hex character, + * + ****************************************************************************/ + +#ifdef CONFIG_CODECS_URLCODE_NEWMEMORY +static char to_hex(char code) +{ + static const char hex[] = "0123456789abcdef"; + return hex[code & 15]; +} +#endif + +/**************************************************************************** + * Name: int2h + * + * Description: + * Convert a single character to a 2 digit hex str a terminating '\0' is + * added + * + ****************************************************************************/ + +#ifdef CONFIG_CODECS_AVR_URLCODE +static void int2h(char c, char *hstr) +{ + hstr[1] = (c & 0xf) + '0'; + if ((c & 0xf) > 9) + { + hstr[1] = (c & 0xf) - 10 + 'a'; + } + + c = (c >> 4) & 0xf; + hstr[0] = c + '0'; + if (c > 9) + { + hstr[0] = c - 10 + 'a'; + } + + hstr[2] = '\0'; +} +#endif + +/**************************************************************************** + * Name: h2int + * + * Description: + * Convert a single hex digit character to its integer value. + * + ****************************************************************************/ + +#ifdef CONFIG_CODECS_AVR_URLCODE +static unsigned char h2int(char c) +{ + if (c >= '0' && c <= '9') + { + return ((unsigned char)c - '0'); + } + + if (c >= 'a' && c <= 'f') + { + return ((unsigned char)c - 'a' + 10); + } + + if (c >= 'A' && c <= 'F') + { + return ((unsigned char)c - 'A' + 10); + } + + return 0; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: + * + * Description: + * Returns a url-encoded version of str. + * + * IMPORTANT: be sure to free() the returned string after use. + * + ****************************************************************************/ + +#ifdef CONFIG_CODECS_URLCODE_NEWMEMORY +char *url_encode(char *str) +{ + char *pstr = str; + char *buf = malloc(strlen(str) * 3 + 1); + char *pbuf = buf; + + while (*pstr) + { + if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') + { + *pbuf++ = *pstr; + } + else if (*pstr == ' ') + { + *pbuf++ = '+'; + } + else + { + *pbuf++ = '%'; + *pbuf++ = to_hex(*pstr >> 4); + *pbuf++ = to_hex(*pstr & 15); + } + + pstr++; + } + + *pbuf = '\0'; + return buf; +} +#endif + +/**************************************************************************** + * Name: url_decode + * + * Description: + * Returns a url-decoded version of str. + * + * IMPORTANT: be sure to free() the returned string after use. + * + ****************************************************************************/ + +#ifdef CONFIG_CODECS_URLCODE_NEWMEMORY +char *url_decode(char *str) +{ + char *pstr = str; + char *buf = malloc(strlen(str) + 1); + char *pbuf = buf; + + while (*pstr) + { + if (*pstr == '%') + { + if (pstr[1] && pstr[2]) + { + *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]); + pstr += 2; + } + } + else if (*pstr == '+') + { + *pbuf++ = ' '; + } + else + { + *pbuf++ = *pstr; + } + + pstr++; + } + + *pbuf = '\0'; + return buf; +} +#endif + +/**************************************************************************** + * Name: urlencode + ****************************************************************************/ + +#ifdef CONFIG_CODECS_URLCODE +char *urlencode(const char *src, const int src_len, char *dest, int *dest_len) +{ + static const unsigned char hex_chars[] = "0123456789ABCDEF"; + const unsigned char *pSrc; + const unsigned char *pEnd; + char *pDest; + + pDest = dest; + pEnd = (unsigned char *)src + src_len; + for (pSrc = (unsigned char *)src; pSrc < pEnd; pSrc++) + { + if ((*pSrc >= '0' && *pSrc <= '9') || + (*pSrc >= 'a' && *pSrc <= 'z') || + (*pSrc >= 'A' && *pSrc <= 'Z') || + (*pSrc == '_' || *pSrc == '-' || *pSrc == '.' || *pSrc == '~')) + { + *pDest++ = *pSrc; + } + else if (*pSrc == ' ') + { + *pDest++ = '+'; + } + else + { + *pDest++ = '%'; + *pDest++ = hex_chars[(*pSrc) >> 4]; + *pDest++ = hex_chars[(*pSrc) & 0x0F]; + } + } + + *pDest = '\0'; + *dest_len = pDest - dest; + return dest; +} +#endif + +/**************************************************************************** + * Name: urldecode + ****************************************************************************/ + +#ifdef CONFIG_CODECS_URLCODE +char *urldecode(const char *src, const int src_len, char *dest, int *dest_len) +{ + const unsigned char *pSrc; + const unsigned char *pEnd; + char *pDest; + unsigned char cHigh; + unsigned char cLow; + int valHigh; + int valLow; + + pDest = dest; + pSrc = (unsigned char *)src; + pEnd = (unsigned char *)src + src_len; + while (pSrc < pEnd) + { + if (*pSrc == '%' && pSrc + 2 < pEnd) + { + cHigh = *(pSrc + 1); + cLow = *(pSrc + 2); + + if (IS_HEX_CHAR(cHigh) && IS_HEX_CHAR(cLow)) + { + HEX_VALUE(cHigh, valHigh) + HEX_VALUE(cLow, valLow) + *pDest++ = (valHigh << 4) | valLow; + pSrc += 3; + } + else + { + *pDest++ = *pSrc; + pSrc++; + } + } + else if (*pSrc == '+') + { + *pDest++ = ' '; + pSrc++; + } + else + { + *pDest++ = *pSrc; + pSrc++; + } + } + + *pDest = '\0'; + *dest_len = pDest - dest; + return dest; +} +#endif + +/**************************************************************************** + * Name: urlrawdecode + * + * Description: + * decode a url string e.g "hello%20joe" or "hello+joe" becomes "hello joe" + * + ****************************************************************************/ + +#ifdef CONFIG_CODECS_AVR_URLCODE +void urlrawdecode(char *urlbuf) +{ + char c; + char *dst; + dst = urlbuf; + while ((c = *urlbuf)) + { + if (c == '+') + { + c = ' '; + } + + if (c == '%') + { + urlbuf++; + c = *urlbuf; + urlbuf++; + c = (h2int(c) << 4) | h2int(*urlbuf); + } + + *dst = c; + dst++; + urlbuf++; + } + + *dst = '\0'; +} +#endif + +/**************************************************************************** + * Name: urlrawencode + * + * Description: + * There must be enoug space in urlbuf. In the worst case that is 3 times + * the length of str + * + ****************************************************************************/ + +#ifdef CONFIG_CODECS_AVR_URLCODE +void urlrawencode(char *str, char *urlbuf) +{ + char c; + while ((c = *str)) + { + if (c == ' ' || isalnum(c) || c == '_' || c == '-' || c == '.' || c == '~') + { + if (c == ' ') + { + c = '+'; + } + + *urlbuf = c; + str++; + urlbuf++; + continue; + } + + *urlbuf = '%'; + urlbuf++; + int2h(c, urlbuf); + urlbuf++; + urlbuf++; + str++; + } + + *urlbuf = '\0'; +} +#endif -- cgit v1.2.3