diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-11-16 00:10:51 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-11-16 00:10:51 (GMT) |
commit | b92c2f64953e8aabbf3644dc03524de048764c6a (patch) | |
tree | fe0ad7b96fe45e8ec8c8f0d55652907751494e3b /src/uscxml | |
parent | c60cc4c17191bc432e89af914dde700724633b38 (diff) | |
download | uscxml-b92c2f64953e8aabbf3644dc03524de048764c6a.zip uscxml-b92c2f64953e8aabbf3644dc03524de048764c6a.tar.gz uscxml-b92c2f64953e8aabbf3644dc03524de048764c6a.tar.bz2 |
Have crypto available from C with C++ bindings via header only
Diffstat (limited to 'src/uscxml')
-rw-r--r-- | src/uscxml/util/Base64.c | 188 | ||||
-rw-r--r-- | src/uscxml/util/Base64.cpp | 129 | ||||
-rw-r--r-- | src/uscxml/util/Base64.h | 64 | ||||
-rw-r--r-- | src/uscxml/util/Base64.hpp | 46 | ||||
-rw-r--r-- | src/uscxml/util/MD5.c (renamed from src/uscxml/util/MD5.cpp) | 30 | ||||
-rw-r--r-- | src/uscxml/util/MD5.h | 18 | ||||
-rw-r--r-- | src/uscxml/util/MD5.hpp | 60 | ||||
-rwxr-xr-x | src/uscxml/util/SHA1.c | 388 | ||||
-rwxr-xr-x | src/uscxml/util/SHA1.h | 79 | ||||
-rw-r--r-- | src/uscxml/util/SHA1.hpp | 56 |
10 files changed, 875 insertions, 183 deletions
diff --git a/src/uscxml/util/Base64.c b/src/uscxml/util/Base64.c new file mode 100644 index 0000000..002bd48 --- /dev/null +++ b/src/uscxml/util/Base64.c @@ -0,0 +1,188 @@ +/* +cdecoder.c - c source to a base64 decoding algorithm implementation + +This is part of the libb64 project, and has been placed in the public domain. +For details, see http://sourceforge.net/projects/libb64 +*/ + +#include "Base64.h" + +int base64_decode_value(char value_in) +{ + static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-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,-1,-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}; + static const char decoding_size = sizeof(decoding); + value_in -= 43; + if (value_in < 0 || value_in > decoding_size) return -1; + return decoding[(int)value_in]; +} + +void base64_init_decodestate(base64_decodestate* state_in) +{ + state_in->step = step_a; + state_in->plainchar = 0; +} + +int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in) +{ + const char* codechar = code_in; + char* plainchar = plaintext_out; + char fragment; + + *plainchar = state_in->plainchar; + + switch (state_in->step) + { + while (1) + { + case step_a: + do { + if (codechar == code_in+length_in) + { + state_in->step = step_a; + state_in->plainchar = *plainchar; + return plainchar - plaintext_out; + } + fragment = (char)base64_decode_value(*codechar++); + } while (fragment < 0); + *plainchar = (fragment & 0x03f) << 2; + case step_b: + do { + if (codechar == code_in+length_in) + { + state_in->step = step_b; + state_in->plainchar = *plainchar; + return plainchar - plaintext_out; + } + fragment = (char)base64_decode_value(*codechar++); + } while (fragment < 0); + *plainchar++ |= (fragment & 0x030) >> 4; + *plainchar = (fragment & 0x00f) << 4; + case step_c: + do { + if (codechar == code_in+length_in) + { + state_in->step = step_c; + state_in->plainchar = *plainchar; + return plainchar - plaintext_out; + } + fragment = (char)base64_decode_value(*codechar++); + } while (fragment < 0); + *plainchar++ |= (fragment & 0x03c) >> 2; + *plainchar = (fragment & 0x003) << 6; + case step_d: + do { + if (codechar == code_in+length_in) + { + state_in->step = step_d; + state_in->plainchar = *plainchar; + return plainchar - plaintext_out; + } + fragment = (char)base64_decode_value(*codechar++); + } while (fragment < 0); + *plainchar++ |= (fragment & 0x03f); + } + } + /* control should not reach here */ + return plainchar - plaintext_out; +} + +const int CHARS_PER_LINE = 72; + +void base64_init_encodestate(base64_encodestate* state_in) +{ + state_in->step = step_A; + state_in->result = 0; + state_in->stepcount = 0; +} + +char base64_encode_value(char value_in) +{ + static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + if (value_in > 63) return '='; + return encoding[(int)value_in]; +} + +int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in) +{ + const char* plainchar = plaintext_in; + const char* const plaintextend = plaintext_in + length_in; + char* codechar = code_out; + char result; + char fragment; + + result = state_in->result; + + switch (state_in->step) + { + while (1) + { + case step_A: + if (plainchar == plaintextend) + { + state_in->result = result; + state_in->step = step_A; + return codechar - code_out; + } + fragment = *plainchar++; + result = (fragment & 0x0fc) >> 2; + *codechar++ = base64_encode_value(result); + result = (fragment & 0x003) << 4; + case step_B: + if (plainchar == plaintextend) + { + state_in->result = result; + state_in->step = step_B; + return codechar - code_out; + } + fragment = *plainchar++; + result |= (fragment & 0x0f0) >> 4; + *codechar++ = base64_encode_value(result); + result = (fragment & 0x00f) << 2; + case step_C: + if (plainchar == plaintextend) + { + state_in->result = result; + state_in->step = step_C; + return codechar - code_out; + } + fragment = *plainchar++; + result |= (fragment & 0x0c0) >> 6; + *codechar++ = base64_encode_value(result); + result = (fragment & 0x03f) >> 0; + *codechar++ = base64_encode_value(result); + + ++(state_in->stepcount); + if (state_in->stepcount == CHARS_PER_LINE/4) + { + *codechar++ = '\n'; + state_in->stepcount = 0; + } + } + } + /* control should not reach here */ + return codechar - code_out; +} + +int base64_encode_blockend(char* code_out, base64_encodestate* state_in) +{ + char* codechar = code_out; + + switch (state_in->step) + { + case step_B: + *codechar++ = base64_encode_value(state_in->result); + *codechar++ = '='; + *codechar++ = '='; + break; + case step_C: + *codechar++ = base64_encode_value(state_in->result); + *codechar++ = '='; + break; + case step_A: + break; + } + *codechar++ = '\n'; + + return codechar - code_out; +} + diff --git a/src/uscxml/util/Base64.cpp b/src/uscxml/util/Base64.cpp deleted file mode 100644 index 20cfbc3..0000000 --- a/src/uscxml/util/Base64.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - base64.cpp and base64.h - - Copyright (C) 2004-2008 René Nyffenegger - - This source code is provided 'as-is', without any express or implied - warranty. In no event will the author be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this source code must not be misrepresented; you must not - claim that you wrote the original source code. If you use this source code - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original source code. - - 3. This notice may not be removed or altered from any source distribution. - - René Nyffenegger rene.nyffenegger@adp-gmbh.ch - - Moved to namespace umundo - -*/ - -#include "Base64.h" -#include <iostream> - -namespace uscxml { - -static const std::string base64_chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - - -static inline bool is_base64(unsigned char c) { - return (isalnum(c) || (c == '+') || (c == '/')); -} - -std::string base64_encode(char const* bytes_to_encode, unsigned int in_len) { - std::string ret; - int i = 0; - int j = 0; - unsigned char char_array_3[3]; - unsigned char char_array_4[4]; - - while (in_len--) { - char_array_3[i++] = *(bytes_to_encode++); - if (i == 3) { - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for(i = 0; (i <4) ; i++) - ret += base64_chars[char_array_4[i]]; - i = 0; - } - } - - if (i) { - for(j = i; j < 3; j++) - char_array_3[j] = '\0'; - - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for (j = 0; (j < i + 1); j++) - ret += base64_chars[char_array_4[j]]; - - while((i++ < 3)) - ret += '='; - - } - - return ret; - -} - -std::string base64_decode(std::string const& encoded_string) { - int in_len = encoded_string.size(); - int i = 0; - int j = 0; - int in_ = 0; - unsigned char char_array_4[4], char_array_3[3]; - std::string ret; - - while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { - char_array_4[i++] = encoded_string[in_]; - in_++; - if (i ==4) { - for (i = 0; i <4; i++) - char_array_4[i] = base64_chars.find(char_array_4[i]); - - char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); - char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - - for (i = 0; (i < 3); i++) - ret += char_array_3[i]; - i = 0; - } - } - - if (i) { - for (j = i; j <4; j++) - char_array_4[j] = 0; - - for (j = 0; j <4; j++) - char_array_4[j] = base64_chars.find(char_array_4[j]); - - char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); - char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - - for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; - } - - return ret; -} - -}
\ No newline at end of file diff --git a/src/uscxml/util/Base64.h b/src/uscxml/util/Base64.h index 0102046..3bd4c6c 100644 --- a/src/uscxml/util/Base64.h +++ b/src/uscxml/util/Base64.h @@ -1,15 +1,61 @@ -// taken from http://www.adp-gmbh.ch/cpp/common/base64.html -#ifndef BASE64_H_5FKG12HF -#define BASE64_H_5FKG12HF +/* +cdecode.h - c header for a base64 decoding algorithm -#include <string> -#include "uscxml/Common.h" +This is part of the libb64 project, and has been placed in the public domain. +For details, see http://sourceforge.net/projects/libb64 +*/ -namespace uscxml { +#ifndef BASE64_H_MMR5NHB7 +#define BASE64_H_MMR5NHB7 -USCXML_API std::string base64_encode(char const* , unsigned int len); -USCXML_API std::string base64_decode(std::string const& s); +#ifdef __cplusplus +extern "C" { +#endif +/// DECODE + +typedef enum +{ + step_a, step_b, step_c, step_d +} base64_decodestep; + +typedef struct +{ + base64_decodestep step; + char plainchar; +} base64_decodestate; + +void base64_init_decodestate(base64_decodestate* state_in); + +int base64_decode_value(char value_in); + +int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in); + +/// ENDCODE + +typedef enum +{ + step_A, step_B, step_C +} base64_encodestep; + +typedef struct +{ + base64_encodestep step; + char result; + int stepcount; +} base64_encodestate; + +void base64_init_encodestate(base64_encodestate* state_in); + +char base64_encode_value(char value_in); + +int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); + +int base64_encode_blockend(char* code_out, base64_encodestate* state_in); + +#ifdef __cplusplus } +#endif + -#endif /* end of include guard: BASE64_H_5FKG12HF */ +#endif /* end of include guard: BASE64_H_MMR5NHB7 */ diff --git a/src/uscxml/util/Base64.hpp b/src/uscxml/util/Base64.hpp new file mode 100644 index 0000000..a106a12 --- /dev/null +++ b/src/uscxml/util/Base64.hpp @@ -0,0 +1,46 @@ +// taken from http://www.adp-gmbh.ch/cpp/common/base64.html +#ifndef BASE64_H_5FKG12HF +#define BASE64_H_5FKG12HF + +extern "C" { +#include "Base64.h" +} + +#include <stdlib.h> +#include <string> +#include "uscxml/Common.h" + +namespace uscxml { + +USCXML_API inline std::string base64Encode(const char* data, unsigned int len) { + base64_encodestate* ctx = (base64_encodestate*)malloc(sizeof(base64_encodestate)); + base64_init_encodestate(ctx); + + /** + * Wikipedia: Very roughly, the final size of Base64-encoded binary data is equal to 1.37 + * times the original data size + 814 bytes (for headers). The size of the decoded data can + * be approximated with this formula: + */ + + char* out = (char*)malloc(len * 1.4 + 814); + base64_encode_block(data, len, out, ctx); + free(ctx); + std::string result(out); + free(out); + return result; +} + +USCXML_API inline std::string base64Decode(const std::string& data) { + base64_decodestate* ctx = (base64_decodestate*)malloc(sizeof(base64_decodestate)); + base64_init_decodestate(ctx); + + char* out = (char*)malloc(data.size()); + base64_decode_block(data.data(), data.size(), out, ctx); + free(ctx); + std::string result(out); + free(out); + return result; +} + +} +#endif /* end of include guard: BASE64_H_5FKG12HF */ diff --git a/src/uscxml/util/MD5.cpp b/src/uscxml/util/MD5.c index 3fee55c..1bf05e4 100644 --- a/src/uscxml/util/MD5.cpp +++ b/src/uscxml/util/MD5.c @@ -52,13 +52,6 @@ */ #include "MD5.h" -#include <string.h> - -#include <iostream> -#include <sstream> -#include <iomanip> - -namespace uscxml { #undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ #ifdef ARCH_IS_BIG_ENDIAN @@ -381,26 +374,3 @@ md5_finish(md5_state_t *pms, md5_byte_t digest[16]) { for (i = 0; i < 16; ++i) digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); } - -std::string md5(const char* data, size_t length) { - md5_state_t state; - md5_byte_t digest[16]; - - md5_init(&state); - md5_append(&state, (const md5_byte_t *)data, length); - md5_finish(&state, digest); - - std::ostringstream ss; - ss << std::hex << std::uppercase << std::setfill( '0' ); - for (int i = 0; i < 16; i++) { - ss << std::setw( 2 ) << (int)digest[i]; - } - - return ss.str(); -} - -std::string md5(const std::string& data) { - return md5(data.data(), data.size()); -} - -} diff --git a/src/uscxml/util/MD5.h b/src/uscxml/util/MD5.h index c842e51..a3468d9 100644 --- a/src/uscxml/util/MD5.h +++ b/src/uscxml/util/MD5.h @@ -50,16 +50,9 @@ #ifndef md5_INCLUDED # define md5_INCLUDED -/** - * C++ convinience - */ -#include <string> -#include "uscxml/Common.h" - -namespace uscxml { - -extern USCXML_API std::string md5(const char* data, size_t length); -extern USCXML_API std::string md5(const std::string& data); +#ifdef __cplusplus +extern "C" { +#endif /* * This package supports both compile-time and run-time determination of CPU @@ -81,10 +74,6 @@ typedef struct md5_state_s { md5_byte_t buf[64]; /* accumulate block */ } md5_state_t; -#ifdef __cplusplus -extern "C" -{ -#endif /* Initialize the algorithm. */ void md5_init(md5_state_t *pms); @@ -99,5 +88,4 @@ extern "C" } /* end extern "C" */ #endif -} #endif /* md5_INCLUDED */ diff --git a/src/uscxml/util/MD5.hpp b/src/uscxml/util/MD5.hpp new file mode 100644 index 0000000..4dae3b3 --- /dev/null +++ b/src/uscxml/util/MD5.hpp @@ -0,0 +1,60 @@ +/** + * @file + * @author 2012-2013 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * 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. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef MD5_HPP_70TU4G5T +#define MD5_HPP_70TU4G5T + +extern "C" { +#include "MD5.h" +} + +#include <string.h> + +#include <iostream> +#include <sstream> +#include <iomanip> +#include "uscxml/Common.h" + +namespace uscxml { + + USCXML_API inline std::string md5(const char* data, size_t length) { + md5_state_t state; + md5_byte_t digest[16]; + + md5_init(&state); + md5_append(&state, (const md5_byte_t *)data, length); + md5_finish(&state, digest); + + std::ostringstream ss; + ss << std::hex << std::uppercase << std::setfill( '0' ); + for (int i = 0; i < 16; i++) { + ss << std::setw( 2 ) << (int)digest[i]; + } + + return ss.str(); + } + + USCXML_API inline std::string md5(const std::string& data) { + return md5(data.data(), data.size()); + } + +} + + +#endif /* end of include guard: MD5_HPP_70TU4G5T */ diff --git a/src/uscxml/util/SHA1.c b/src/uscxml/util/SHA1.c new file mode 100755 index 0000000..b9300ae --- /dev/null +++ b/src/uscxml/util/SHA1.c @@ -0,0 +1,388 @@ +/** + Copyright (C) 1998, 2009 + Paul E. Jones <paulej@packetizer.com> + + Freeware Public License (FPL) + + This software is licensed as "freeware." Permission to distribute + this software in source and binary forms, including incorporation + into other products, is hereby granted without a fee. THIS SOFTWARE + IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHOR SHALL NOT BE HELD + LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE, EITHER + DIRECTLY OR INDIRECTLY, INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA + OR DATA BEING RENDERED INACCURATE. +*/ + +/* + * sha1.c + * + * Copyright (C) 1998, 2009 + * Paul E. Jones <paulej@packetizer.com> + * All Rights Reserved + * + ***************************************************************************** + * $Id: sha1.c 12 2009-06-22 19:34:25Z paulej $ + ***************************************************************************** + * + * Description: + * This file implements the Secure Hashing Standard as defined + * in FIPS PUB 180-1 published April 17, 1995. + * + * The Secure Hashing Standard, which uses the Secure Hashing + * Algorithm (SHA), produces a 160-bit message digest for a + * given data stream. In theory, it is highly improbable that + * two messages will produce the same message digest. Therefore, + * this algorithm can serve as a means of providing a "fingerprint" + * for a message. + * + * Portability Issues: + * SHA-1 is defined in terms of 32-bit "words". This code was + * written with the expectation that the processor has at least + * a 32-bit machine word size. If the machine word size is larger, + * the code should still function properly. One caveat to that + * is that the input functions taking characters and character + * arrays assume that only 8 bits of information are stored in each + * character. + * + * Caveats: + * SHA-1 is designed to work with messages less than 2^64 bits + * long. Although SHA-1 allows a message digest to be generated for + * messages of any number of bits less than 2^64, this + * implementation only works with messages with a length that is a + * multiple of the size of an 8-bit character. + * + */ + +#include "SHA1.h" + +/* + * Define the circular shift macro + */ +#define SHA1CircularShift(bits,word) \ + ((((word) << (bits)) & 0xFFFFFFFF) | \ + ((word) >> (32-(bits)))) + +/* Function prototypes */ +void SHA1ProcessMessageBlock(SHA1Context *); +void SHA1PadMessage(SHA1Context *); + +/* + * SHA1Reset + * + * Description: + * This function will initialize the SHA1Context in preparation + * for computing a new message digest. + * + * Parameters: + * context: [in/out] + * The context to reset. + * + * Returns: + * Nothing. + * + * Comments: + * + */ +void SHA1Reset(SHA1Context *context) +{ + context->Length_Low = 0; + context->Length_High = 0; + context->Message_Block_Index = 0; + + context->Message_Digest[0] = 0x67452301; + context->Message_Digest[1] = 0xEFCDAB89; + context->Message_Digest[2] = 0x98BADCFE; + context->Message_Digest[3] = 0x10325476; + context->Message_Digest[4] = 0xC3D2E1F0; + + context->Computed = 0; + context->Corrupted = 0; +} + +/* + * SHA1Result + * + * Description: + * This function will return the 160-bit message digest into the + * Message_Digest array within the SHA1Context provided + * + * Parameters: + * context: [in/out] + * The context to use to calculate the SHA-1 hash. + * + * Returns: + * 1 if successful, 0 if it failed. + * + * Comments: + * + */ +int SHA1Result(SHA1Context *context) +{ + + if (context->Corrupted) + { + return 0; + } + + if (!context->Computed) + { + SHA1PadMessage(context); + context->Computed = 1; + } + + return 1; +} + +/* + * SHA1Input + * + * Description: + * This function accepts an array of octets as the next portion of + * the message. + * + * Parameters: + * context: [in/out] + * The SHA-1 context to update + * message_array: [in] + * An array of characters representing the next portion of the + * message. + * length: [in] + * The length of the message in message_array + * + * Returns: + * Nothing. + * + * Comments: + * + */ +void SHA1Input( SHA1Context *context, + const unsigned char *message_array, + unsigned length) +{ + if (!length) + { + return; + } + + if (context->Computed || context->Corrupted) + { + context->Corrupted = 1; + return; + } + + while(length-- && !context->Corrupted) + { + context->Message_Block[context->Message_Block_Index++] = + (*message_array & 0xFF); + + context->Length_Low += 8; + /* Force it to 32 bits */ + context->Length_Low &= 0xFFFFFFFF; + if (context->Length_Low == 0) + { + context->Length_High++; + /* Force it to 32 bits */ + context->Length_High &= 0xFFFFFFFF; + if (context->Length_High == 0) + { + /* Message is too long */ + context->Corrupted = 1; + } + } + + if (context->Message_Block_Index == 64) + { + SHA1ProcessMessageBlock(context); + } + + message_array++; + } +} + +/* + * SHA1ProcessMessageBlock + * + * Description: + * This function will process the next 512 bits of the message + * stored in the Message_Block array. + * + * Parameters: + * None. + * + * Returns: + * Nothing. + * + * Comments: + * Many of the variable names in the SHAContext, especially the + * single character names, were used because those were the names + * used in the publication. + * + * + */ +void SHA1ProcessMessageBlock(SHA1Context *context) +{ + const unsigned K[] = /* Constants defined in SHA-1 */ + { + 0x5A827999, + 0x6ED9EBA1, + 0x8F1BBCDC, + 0xCA62C1D6 + }; + int t; /* Loop counter */ + unsigned temp; /* Temporary word value */ + unsigned W[80]; /* Word sequence */ + unsigned A, B, C, D, E; /* Word buffers */ + + /* + * Initialize the first 16 words in the array W + */ + for(t = 0; t < 16; t++) + { + W[t] = ((unsigned) context->Message_Block[t * 4]) << 24; + W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16; + W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8; + W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]); + } + + for(t = 16; t < 80; t++) + { + W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); + } + + A = context->Message_Digest[0]; + B = context->Message_Digest[1]; + C = context->Message_Digest[2]; + D = context->Message_Digest[3]; + E = context->Message_Digest[4]; + + for(t = 0; t < 20; t++) + { + temp = SHA1CircularShift(5,A) + + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 20; t < 40; t++) + { + temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 40; t < 60; t++) + { + temp = SHA1CircularShift(5,A) + + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 60; t < 80; t++) + { + temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + context->Message_Digest[0] = + (context->Message_Digest[0] + A) & 0xFFFFFFFF; + context->Message_Digest[1] = + (context->Message_Digest[1] + B) & 0xFFFFFFFF; + context->Message_Digest[2] = + (context->Message_Digest[2] + C) & 0xFFFFFFFF; + context->Message_Digest[3] = + (context->Message_Digest[3] + D) & 0xFFFFFFFF; + context->Message_Digest[4] = + (context->Message_Digest[4] + E) & 0xFFFFFFFF; + + context->Message_Block_Index = 0; +} + +/* + * SHA1PadMessage + * + * Description: + * According to the standard, the message must be padded to an even + * 512 bits. The first padding bit must be a '1'. The last 64 + * bits represent the length of the original message. All bits in + * between should be 0. This function will pad the message + * according to those rules by filling the Message_Block array + * accordingly. It will also call SHA1ProcessMessageBlock() + * appropriately. When it returns, it can be assumed that the + * message digest has been computed. + * + * Parameters: + * context: [in/out] + * The context to pad + * + * Returns: + * Nothing. + * + * Comments: + * + */ +void SHA1PadMessage(SHA1Context *context) +{ + /* + * Check to see if the current message block is too small to hold + * the initial padding bits and length. If so, we will pad the + * block, process it, and then continue padding into a second + * block. + */ + if (context->Message_Block_Index > 55) + { + context->Message_Block[context->Message_Block_Index++] = 0x80; + while(context->Message_Block_Index < 64) + { + context->Message_Block[context->Message_Block_Index++] = 0; + } + + SHA1ProcessMessageBlock(context); + + while(context->Message_Block_Index < 56) + { + context->Message_Block[context->Message_Block_Index++] = 0; + } + } + else + { + context->Message_Block[context->Message_Block_Index++] = 0x80; + while(context->Message_Block_Index < 56) + { + context->Message_Block[context->Message_Block_Index++] = 0; + } + } + + /* + * Store the message length as the last 8 octets + */ + context->Message_Block[56] = (context->Length_High >> 24) & 0xFF; + context->Message_Block[57] = (context->Length_High >> 16) & 0xFF; + context->Message_Block[58] = (context->Length_High >> 8) & 0xFF; + context->Message_Block[59] = (context->Length_High) & 0xFF; + context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF; + context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF; + context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF; + context->Message_Block[63] = (context->Length_Low) & 0xFF; + + SHA1ProcessMessageBlock(context); +} diff --git a/src/uscxml/util/SHA1.h b/src/uscxml/util/SHA1.h new file mode 100755 index 0000000..2b1f466 --- /dev/null +++ b/src/uscxml/util/SHA1.h @@ -0,0 +1,79 @@ +/** + Copyright (C) 1998, 2009 + Paul E. Jones <paulej@packetizer.com> + + Freeware Public License (FPL) + + This software is licensed as "freeware." Permission to distribute + this software in source and binary forms, including incorporation + into other products, is hereby granted without a fee. THIS SOFTWARE + IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHOR SHALL NOT BE HELD + LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE, EITHER + DIRECTLY OR INDIRECTLY, INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA + OR DATA BEING RENDERED INACCURATE. +*/ + +/* + * sha1.h + * + * Copyright (C) 1998, 2009 + * Paul E. Jones <paulej@packetizer.com> + * All Rights Reserved + * + ***************************************************************************** + * $Id: sha1.h 12 2009-06-22 19:34:25Z paulej $ + ***************************************************************************** + * + * Description: + * This class implements the Secure Hashing Standard as defined + * in FIPS PUB 180-1 published April 17, 1995. + * + * Many of the variable names in the SHA1Context, especially the + * single character names, were used because those were the names + * used in the publication. + * + * Please read the file sha1.c for more information. + * + */ + +#ifndef _SHA1_H_ +#define _SHA1_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This structure will hold context information for the hashing + * operation + */ +typedef struct SHA1Context +{ + unsigned Message_Digest[5]; /* Message Digest (output) */ + + unsigned Length_Low; /* Message length in bits */ + unsigned Length_High; /* Message length in bits */ + + unsigned char Message_Block[64]; /* 512-bit message blocks */ + int Message_Block_Index; /* Index into message block array */ + + int Computed; /* Is the digest computed? */ + int Corrupted; /* Is the message digest corruped? */ +} SHA1Context; + +/* + * Function Prototypes + */ +void SHA1Reset(SHA1Context *); +int SHA1Result(SHA1Context *); +void SHA1Input(SHA1Context *, + const unsigned char *, + unsigned); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/uscxml/util/SHA1.hpp b/src/uscxml/util/SHA1.hpp new file mode 100644 index 0000000..61df5db --- /dev/null +++ b/src/uscxml/util/SHA1.hpp @@ -0,0 +1,56 @@ +/** + * @file + * @author 2012-2013 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * 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. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef SHA1_HPP_XJADWV5G +#define SHA1_HPP_XJADWV5G + +extern "C" { +#include "SHA1.h" +} + +#include <string.h> +#include <iostream> +#include <sstream> +#include <iomanip> +#include "uscxml/Common.h" + +namespace uscxml { + USCXML_API inline std::string sha1(const char* data, size_t length) { + SHA1Context sha; + SHA1Reset(&sha); + SHA1Input(&sha, (const unsigned char*)data, length); + if (!SHA1Result(&sha)) { + return ""; + } else { + std::ostringstream ss; + ss << std::hex << std::uppercase << std::setfill( '0' ); + for (int i = 0; i < 5; i++) { + ss << std::setw( 2 ) << sha.Message_Digest[i]; + } + + return ss.str(); + } + } + + USCXML_API inline std::string sha1(const std::string& data) { + return sha1(data.data(), data.size()); + } +} + +#endif /* end of include guard: SHA1_HPP_XJADWV5G */ |