src/commands/GSSPseudoRandom.cpp
src/commands/GSSWrap.cpp
src/commands/GSSUnwrap.cpp
+ src/util_base64.cpp
src/util_json.cpp
+ src/util_random.cpp
src/cache/GSSContextCache.cpp
src/cache/GSSNameCache.cpp
src/datamodel/GSSContext.cpp
*
*/
-// #include <glib.h>
#include <stdexcept>
-#include <openssl/err.h>
-#include <openssl/rand.h>
+#include "util_random.h"
+#include "util_base64.h"
-#include "utils/base64.h"
#include "GSSContextCache.h"
#define KEYLEN 128
bool GSSContextCache::generateKey(std::string &key)
{
/* Variables */
- int osslReturn = 0;
unsigned char theKey[KEYLEN];
- bool existingErrors = false;
-
- /* Error checking */
- // See if there are any queued OpenSSL errors already.
- existingErrors = ( 0 == ERR_peek_error() );
-
- /* Setup */
- /* Main */
- // Generate random byte string
- osslReturn = RAND_pseudo_bytes(theKey, KEYLEN);
-
- // Discard the error message if there weren't any OpenSSL errors to begin with.
- if (osslReturn == 1 && !existingErrors)
- {
- while (0 != ERR_get_error() );
- return(false);
- }
+
+ if (!randGenPseudoRandom(theKey, KEYLEN))
+ return false;
// Encode the binary string
- key = (char *)theKey;
- key = base64_encode(key);
-
+ base64EncodeStr(theKey, KEYLEN, key);
+
/* Cleanup */
/* Return */
return(true);
* For license details, see the LICENSE file in the root of this project.
*
*/
-
-// #include <glib.h>
#include <stdexcept>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-
#include "GSSNameCache.h"
-#include "utils/base64.h"
+#include "util_base64.h"
+#include "util_random.h"
#define KEYLEN 128
bool GSSNameCache::generateKey(std::string &key)
{
/* Variables */
- int osslReturn = 0;
unsigned char theKey[KEYLEN];
- bool existingErrors = false;
-
- /* Error checking */
- // See if there are any queued OpenSSL errors already.
- existingErrors = ( 0 == ERR_peek_error() );
/* Setup */
/* Main */
// Generate random byte string
- osslReturn = RAND_pseudo_bytes(theKey, KEYLEN);
-
- // Discard the error message if there weren't any OpenSSL errors to begin with.
- if (osslReturn == 1 && !existingErrors)
- {
- while (0 != ERR_get_error() );
+ if (!randGenPseudoRandom(theKey, KEYLEN))
return(false);
- }
// Encode the binary string
- key = (char *)theKey;
- key = base64_encode(key);
-
+ base64EncodeStr(theKey, KEYLEN, key);
/* Cleanup */
/* Return */
return(true);
#include <stdlib.h>
#include <string.h>
-#include "utils/base64.h"
+#include "util_base64.h"
typedef OM_uint32 (*init_sec_context)(
OM_uint32 *, /* minor_status */
std::string("") == params->get("input_token").string())))
{
token = params->get("input_token").string();
- this->input_token.value = base64_decode(token, &this->input_token.length);
+ input_token.value = base64Decode(token.c_str(), &input_token.length);
}
/* Cleanup */
if (this->output_token.length > 0)
gss_release_buffer(&minor, &output_token);
- if (this->input_token.length > 0)
- gss_release_buffer(&minor, &input_token);
+ if (this->input_token.value) {
+ base64Free(input_token.value);
+ input_token.value = NULL;
+ input_token.length = 0;
+ }
}
// Now set things to reasonable defaults
{
/* Variables */
// MRW -- values should be scoped to the class, so execute can set error values?
- std::string output_str((char *)output_token.value, output_token.length);
+ std::string output_str;
JSONObject *values = new JSONObject();
+ base64EncodeStr(output_token.value, output_token.length, output_str);
/* Error checking */
values->set("minor_status", this->minor_status);
values->set("context_handle", this->contextKey.c_str());
values->set("actual_mech_type", this->getActualMechType().toString().c_str());
- // MRW -- is output_token.value guaranteed to be null-terminated?
- //output_str = (char *)output_token.value;
- values->set("output_token", base64_encode(output_str));
+ values->set("output_token", output_str.c_str());
values->set("ret_flags", this->ret_flags);
values->set("time_rec", this->time_rec);
// MRW -- modify for new error handling
--- /dev/null
+/*
+ * Copyright (c) 1995-2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <pthread.h>
+#endif
+#include <string>
+#include <limits.h>
+#include <malloc.h>
+#include <string.h>
+#include "util_base64.h"
+
+#ifdef WIN32
+#define GSSWEB_THREAD_ONCE INIT_ONCE
+#define GSSWEB_ONCE_CALLBACK(cb) BOOL CALLBACK cb(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
+#define GSSWEB_ONCE_LEAVE do { return TRUE; } while (0)
+#define GSSWEB_ONCE(o, i) InitOnceExecuteOnce((o), (i), NULL, NULL)
+#define GSSWEB_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT
+#else
+#define GSSWEB_THREAD_ONCE pthread_once_t
+#define GSSWEB_ONCE_CALLBACK(cb) void cb(void)
+#define GSSWEB_ONCE(o, i) pthread_once((o), (i))
+#define GSSWEB_ONCE_INITIALIZER PTHREAD_ONCE_INIT
+#define GSSWEB_ONCE_LEAVE do { } while (0)
+#endif
+
+size_t
+base64Size(const char *str);
+
+#define BASE64_EXPAND(n) (n * 4 / 3 + 4)
+
+static const char base64_chars[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static char base64_decode[SCHAR_MAX];
+
+static GSSWEB_ONCE_CALLBACK(init_decode_table)
+{
+ int i;
+ memset(&base64_decode[0], -1, sizeof(base64_decode));
+ for (i = 0; i < sizeof(base64_chars) / sizeof(base64_chars[0]); i++)
+ base64_decode[base64_chars[i]] = (char )i;
+ GSSWEB_ONCE_LEAVE;
+}
+
+static int
+pos(char c)
+{
+ if (c <= 0)
+ return -1;
+ return base64_decode[c];
+}
+
+void
+base64EncodeStr(const void *data, size_t size, std::string &str)
+{
+
+ char *s = base64Encode(data, size);
+ str = s;
+ base64Free(s);
+}
+
+char *
+base64Encode(const void *data, size_t size)
+{
+ char *s, *p;
+ size_t i;
+ int c;
+ const unsigned char *q;
+
+ if (size > INT_MAX/4 || size < 0) {
+ return NULL;
+ }
+
+ p = s = (char *)malloc(BASE64_EXPAND(size));
+ if (p == NULL) {
+ return NULL;
+ }
+ q = (const unsigned char *) data;
+
+ for (i = 0; i < size;) {
+ c = q[i++];
+ c *= 256;
+ if (i < size)
+ c += q[i];
+ i++;
+ c *= 256;
+ if (i < size)
+ c += q[i];
+ i++;
+ p[0] = base64_chars[(c & 0x00fc0000) >> 18];
+ p[1] = base64_chars[(c & 0x0003f000) >> 12];
+ p[2] = base64_chars[(c & 0x00000fc0) >> 6];
+ p[3] = base64_chars[(c & 0x0000003f) >> 0];
+ if (i > size)
+ p[3] = '=';
+ if (i > size + 1)
+ p[2] = '=';
+ p += 4;
+ }
+ *p = 0;
+ return s;
+}
+
+#define DECODE_ERROR 0xffffffff
+
+static unsigned int
+token_decode(const char *token)
+{
+ int i, decode;
+ unsigned int val = 0;
+ unsigned int marker = 0;
+
+ for (i = 0; i < 4; i++) {
+ val *= 64;
+ if (token[i] == '=')
+ marker++;
+ else if (marker > 0)
+ return DECODE_ERROR;
+ else {
+ decode = pos(token[i]);
+ if (decode < 0)
+ return DECODE_ERROR;
+ val += decode;
+ }
+ }
+ if (marker > 2)
+ return DECODE_ERROR;
+ return (marker << 24) | val;
+}
+
+void *
+base64Decode(const char *str, size_t *size)
+{
+ static GSSWEB_THREAD_ONCE decode_table_once = GSSWEB_ONCE_INITIALIZER;
+ const char *p;
+ unsigned char *q;
+ void *data = NULL;
+ GSSWEB_ONCE(&decode_table_once, init_decode_table);
+
+ *size = base64Size(str);
+ if (*size > 0)
+ data = malloc(*size);
+ if (data == NULL)
+ return data;
+
+ q = static_cast<unsigned char *>(data);
+ p = str;
+
+ while (*p) {
+ unsigned int val = token_decode(p);
+ unsigned int marker = (val >> 24) & 0xff;
+ if (val == DECODE_ERROR) {
+ free(data);
+ *size = 0;
+ return NULL;
+ }
+ *q++ = (val >> 16) & 0xff;
+ if (marker < 2)
+ *q++ = (val >> 8) & 0xff;
+ if (marker < 1)
+ *q++ = val & 0xff;
+ p += 4;
+ if (*p == '\n')
+ p++;
+ }
+ return data;
+}
+
+/* Return the size, in bytes, of the data encoded by str
+ * Return -1 if str is not a valid base64 encoding
+ */
+size_t
+base64Size(const char *str)
+{
+ const char *p = str;
+ size_t size = 0;
+
+ while (*p) {
+ unsigned int val = token_decode(p);
+ unsigned int marker = (val >> 24) & 0x3;
+ if (val == DECODE_ERROR)
+ return 0;
+
+ size += 3 - marker;
+ p += 4;
+ if (*p == '\n')
+ p++;
+ }
+ return size;
+}
+
+void
+base64Free(void *mem)
+{
+ free(mem);
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+/* $Id$ */
+
+#ifndef _UTIL_BASE64_H_
+#define _UTIL_BASE64_H_
+
+#ifdef WIN32
+#include <basetsd.h>
+#else
+#include <sys/types.h>
+#endif
+#include <stddef.h>
+
+#include <string>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char *
+base64Encode(const void *, size_t);
+
+void
+base64EncodeStr(const void *data, size_t, std::string &str);
+
+void *
+base64Decode(const char *, size_t *);
+
+void
+base64Free(void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#include "util_random.h"
+
+#ifdef WIN32
+#include <random>
+#endif
+#ifdef HAVE_OPENSSL
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#endif
+
+
+bool randGenPseudoRandom(unsigned char *buffer, size_t len)
+{
+#ifdef WIN32
+ std::random_device rd; // slow; use to seed only!
+ std::mt19937 gen(rd()); // seed mersenne twister.
+ std::uniform_int_distribution<> dist(0,UCHAR_MAX);
+ for (int i=0; i<len; i++)
+ buffer[i] = dist(gen);
+ return true;
+#elif defined(HAVE_OPENSSL)
+ int osslReturn = 0;
+ bool existingErrors = false;
+
+ /* Error checking */
+ // See if there are any queued OpenSSL errors already.
+ existingErrors = ( 0 == ERR_peek_error() );
+
+ /* Setup */
+ /* Main */
+ // Generate random byte string
+ osslReturn = RAND_pseudo_bytes(buffer, len);
+
+ // Discard the error message if there weren't any OpenSSL errors to begin with.
+ if (osslReturn == 1 && !existingErrors)
+ {
+ while (0 != ERR_get_error() );
+ return(false);
+ }
+ return true;
+#else
+ #error no pseudo random generator available
+#endif
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ *
+ * For license details, see the LICENSE file in the root of this project.
+ *
+ */
+
+#include <stddef.h>
+
+bool randGenPseudoRandom(unsigned char *buffer, size_t len);
command_mocks/MockImportName.cpp
test_run.cpp
../src/commands/GSSInitSecContext.cpp
+ ../src/util_base64.cpp
../src/util_json.cpp
+ ../src/util_random.cpp
../src/commands/GSSImportName.cpp
../src/GSSException.cpp
../src/commands/GSSGetMic.cpp
# install(TARGETS test RUNTIME DESTINATION bin)
add_subdirectory(datamodel)
-add_subdirectory(command_mocks)
\ No newline at end of file
+add_subdirectory(command_mocks)
#include <cache/GSSContextCache.h>
#include <cache/GSSNameCache.h>
#include <datamodel/GSSContext.h>
-#include <utils/base64.h>
+#include <util_base64.h>
// Registers the fixture into the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION( GSSCreateSecContextTest );
- unsigned int len;
std::string str = (*result)["output_token"].string();
- unsigned char *decoded = base64_decode(str, &len);
+ size_t len;
+ void *decoded = base64Decode(str.c_str(), &len);
+ CPPUNIT_ASSERT_MESSAGE(
+ "The decoded token size is incorrect",
+ ( len == InitSecContextMock::output_token.length )
+ );
CPPUNIT_ASSERT_MESSAGE(
"The output_token value was reported incorrectly",
- ( strcmp((const char *)(InitSecContextMock::output_token.value),
- (const char *)decoded ) == 0 )
+ ( memcmp(InitSecContextMock::output_token.value,
+ decoded, len ) == 0 )
);
+ base64Free(decoded);
CPPUNIT_ASSERT_EQUAL_MESSAGE(
"The minor_status value was reported incorrectly",