summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-11-16 00:10:51 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-11-16 00:10:51 (GMT)
commitb92c2f64953e8aabbf3644dc03524de048764c6a (patch)
treefe0ad7b96fe45e8ec8c8f0d55652907751494e3b /src
parentc60cc4c17191bc432e89af914dde700724633b38 (diff)
downloaduscxml-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')
-rw-r--r--src/uscxml/util/Base64.c188
-rw-r--r--src/uscxml/util/Base64.cpp129
-rw-r--r--src/uscxml/util/Base64.h64
-rw-r--r--src/uscxml/util/Base64.hpp46
-rw-r--r--src/uscxml/util/MD5.c (renamed from src/uscxml/util/MD5.cpp)30
-rw-r--r--src/uscxml/util/MD5.h18
-rw-r--r--src/uscxml/util/MD5.hpp60
-rwxr-xr-xsrc/uscxml/util/SHA1.c388
-rwxr-xr-xsrc/uscxml/util/SHA1.h79
-rw-r--r--src/uscxml/util/SHA1.hpp56
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 */