From ae5b681bd7c3ea3ffa02e20ff5956fdca425ba1b Mon Sep 17 00:00:00 2001 From: Mark Donnelly Date: Mon, 18 Aug 2014 17:12:21 -0400 Subject: [PATCH] Adding GSS Pseudo Random --- json_gssapi/CMakeLists.txt | 1 + json_gssapi/src/GSSPseudoRandom.cpp | 150 +++++++++++ json_gssapi/src/GSSPseudoRandom.h | 59 +++++ json_gssapi/test/CMakeLists.txt | 5 +- json_gssapi/test/GSSAcquireCredTest.cpp | 6 +- json_gssapi/test/GSSPseudoRandomTest.cpp | 291 +++++++++++++++++++++ json_gssapi/test/GSSPseudoRandomTest.h | 32 +++ .../test/command_mocks/MockPseudoRandom.cpp | 43 +++ json_gssapi/test/command_mocks/MockPseudoRandom.h | 29 ++ 9 files changed, 612 insertions(+), 4 deletions(-) create mode 100644 json_gssapi/src/GSSPseudoRandom.cpp create mode 100644 json_gssapi/src/GSSPseudoRandom.h create mode 100644 json_gssapi/test/GSSPseudoRandomTest.cpp create mode 100644 json_gssapi/test/GSSPseudoRandomTest.h create mode 100644 json_gssapi/test/command_mocks/MockPseudoRandom.cpp create mode 100644 json_gssapi/test/command_mocks/MockPseudoRandom.h diff --git a/json_gssapi/CMakeLists.txt b/json_gssapi/CMakeLists.txt index 16b7441..da009af 100644 --- a/json_gssapi/CMakeLists.txt +++ b/json_gssapi/CMakeLists.txt @@ -13,6 +13,7 @@ add_executable(json_gssapi src/datamodel/GSSName.cpp src/GSSCommand.cpp src/GSSImportName.cpp src/GSSAcquireCred.cpp + src/GSSPseudoRandom.cpp src/GSSWrap.cpp src/GSSUnwrap.cpp src/util_json.cpp diff --git a/json_gssapi/src/GSSPseudoRandom.cpp b/json_gssapi/src/GSSPseudoRandom.cpp new file mode 100644 index 0000000..fbb111b --- /dev/null +++ b/json_gssapi/src/GSSPseudoRandom.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2014 + * + * For license details, see the LICENSE file in the root of this project. + * + */ + +#include + +#include "GSSPseudoRandom.h" + +GSSPseudoRandom::GSSPseudoRandom(JSONObject *params, + gss_pseudo_random_type fn) : GSSCommand(params) +{ + /* Variables */ + /* Error checking */ + /* Setup */ + /* Main */ + loadParameters(params); + function = fn; + /* Cleanup */ + /* Return */ + +} + +/* JSON input + * + * {"method": "gss_pseudo_random", + * "arguments": + * { + * "context_handle": "########", + * "prf_key": ###, + * "prf_in": "la la la input message", + * "desired_output_len": #### + * } + * + */ +bool GSSPseudoRandom::loadParameters ( JSONObject* params ) +{ + /* Variables */ + std::string sInputMessage; + + /* Error checking */ + /* Setup */ + /* Main */ + + /*********** + * prf_key * + ***********/ + if ( ! params->get("arguments").get("prf_key").isNull() ) + { + if (params->get("arguments").get("prf_key").isInteger()) + this->key = params->get("arguments").get("prf_key").integer(); + else + throw std::invalid_argument( "Unrecognized argument type for prf_key." ); + } + + + /********************** + * desired_output_len * + **********************/ + if ( ! params->get("arguments").get("desired_output_len").isNull() ) + { + if (params->get("arguments").get("desired_output_len").isInteger()) + this->desiredOutputLength = params->get("arguments").get("desired_output_len").integer(); + else + throw std::invalid_argument( "Unrecognized argument type for desired_output_len." ); + } + + + /********** + * prf_in * + **********/ + if ( ! params->get("arguments").get("prf_in").isNull() ) + { + if (params->get("arguments").get("prf_in").isString()) + { + sInputMessage = params->get("arguments").get("prf_in").string(); + this->inputMessage.setValue(sInputMessage); + } + } + + /* Cleanup */ + /* Return */ + return true; +} + + +void GSSPseudoRandom::execute() +{ + /* Variables */ + gss_buffer_desc output_buf; + OM_uint32 minor = 0; + + retVal = function( + &minor, + this->context, + this->key, + this->inputMessage.toGss(), + this->desiredOutputLength, + &output_buf + ); + + this->minor_status = minor; + this->outputMessage.setValue( (char *)output_buf.value, output_buf.length ); +} + +/* Desired JSON output: + * + * { + * "command": "gss_pseudo_random", + * "return_values": + * { + * "major_status": 0, + * "minor_status": 0, + * "random_bytes": "asdf" + * } + * } + */ +JSONObject* GSSPseudoRandom::toJSON() +{ + /* Variables */ + JSONObject *ret = new JSONObject(); + JSONObject *values = new JSONObject(); + + /* Error checking */ + + /* Setup */ + + /* Main */ + // Return Values + // Easy stuff + values->set("major_status", this->retVal); + values->set("minor_status", this->minor_status); + + values->set( + "random_bytes", + this->outputMessage.toString().c_str() + ); + + // Put it all together. + ret->set("command", "gss_pseudo_random"); + ret->set("return_values", *values); + + /* Cleanup */ + + /* Return */ + return(ret); +} + diff --git a/json_gssapi/src/GSSPseudoRandom.h b/json_gssapi/src/GSSPseudoRandom.h new file mode 100644 index 0000000..11d06df --- /dev/null +++ b/json_gssapi/src/GSSPseudoRandom.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014 + * + * For license details, see the LICENSE file in the root of this project. + * + */ + +#ifndef GSSPSEUDORANDOMCOMMAND_H +#define GSSPSEUDORANDOMCOMMAND_H + +#include +#include + +#include "datamodel/GSSBuffer.h" +#include "GSSCommand.h" + +typedef OM_uint32 (*gss_pseudo_random_type) ( + OM_uint32 *, /* minor_status */ + gss_ctx_id_t, /* context */ + int, /* prf_key */ + const gss_buffer_t, /* prf_in */ + ssize_t, /* desired_output_len */ + gss_buffer_t); /* prf_out */ + +class GSSPseudoRandom : public GSSCommand +{ +public: + GSSPseudoRandom(gss_pseudo_random_type fn = &gss_pseudo_random) : function(fn) {}; + GSSPseudoRandom(JSONObject *params, + gss_pseudo_random_type fn = &gss_pseudo_random); + void execute(); + JSONObject* toJSON(); + bool loadParameters(JSONObject *params); + + /* Setters */ + void setContextHandle ( gss_ctx_id_t desiredContext ) { context = (desiredContext); }; + void setKey ( int prf_in ) { key = (prf_in); }; + void setInputMessage ( const GSSBuffer prf_in ) { inputMessage.setValue(prf_in.toString()); }; + void setDesiredOutputLength ( int desired_output_len ) { desiredOutputLength =desired_output_len; }; + + /* Getters */ + GSSBuffer getInputMessage() { return inputMessage; } + GSSBuffer getOutputMessage() { return outputMessage; } + OM_uint32 getRetVal() { return(retVal); } + OM_uint32 getMinorStatus() { return(minor_status); } + int getKey() { return(key); } + int getDesiredOutputLength() { return(desiredOutputLength); } + gss_pseudo_random_type getGSSFunction() { return function; }; + +private: + OM_uint32 retVal, minor_status; + gss_pseudo_random_type function; + gss_ctx_id_t context; + int key, desiredOutputLength; + GSSBuffer inputMessage; + GSSBuffer outputMessage; +}; + +#endif // GSSPSEUDORANDOMCOMMAND_H diff --git a/json_gssapi/test/CMakeLists.txt b/json_gssapi/test/CMakeLists.txt index 6098aa8..e262b50 100644 --- a/json_gssapi/test/CMakeLists.txt +++ b/json_gssapi/test/CMakeLists.txt @@ -3,11 +3,13 @@ include_directories(${CMAKE_SOURCE_DIR}/src) add_executable(test GSSExceptionTest.cpp GSSAcquireCredTest.cpp GSSGetMicTest.cpp + GSSPseudoRandomTest.cpp GSSWrapTest.cpp GSSUnwrapTest.cpp command_mocks/InitSecContextMock.cpp command_mocks/MockAcquireCred.cpp command_mocks/MockGetMic.cpp + command_mocks/MockPseudoRandom.cpp command_mocks/MockUnwrap.cpp command_mocks/MockWrap.cpp GSSCreateSecContextTest.cpp @@ -20,6 +22,7 @@ add_executable(test GSSExceptionTest.cpp ../src/GSSException.cpp ../src/GSSGetMic.cpp ../src/GSSAcquireCred.cpp + ../src/GSSPseudoRandom.cpp ../src/GSSUnwrap.cpp ../src/GSSWrap.cpp ../src/datamodel/GSSBuffer.cpp @@ -31,7 +34,7 @@ add_executable(test GSSExceptionTest.cpp datamodel/GSSOIDSetTest.cpp ) -target_link_libraries(test cppunit gssapi_krb5 jansson) +target_link_libraries(test cppunit gssapi_krb5 jansson crypto) # install(TARGETS test RUNTIME DESTINATION bin) diff --git a/json_gssapi/test/GSSAcquireCredTest.cpp b/json_gssapi/test/GSSAcquireCredTest.cpp index f5d1f5d..b4b552d 100644 --- a/json_gssapi/test/GSSAcquireCredTest.cpp +++ b/json_gssapi/test/GSSAcquireCredTest.cpp @@ -221,7 +221,7 @@ void GSSAcquireCredTest::testEmptyCall() * "cred_handle": "###########", * "actual_mechs": [ * "{ 1 2 3 4 }", - * "{ 5 6 7 8 }" + * "{ 1 5 6 7 8 }" * ], * "time_rec": 0 * } @@ -237,7 +237,7 @@ void GSSAcquireCredTest::testJSONMarshal() /* Error checking */ /* Setup */ actualMechs.addOID( GSSOID( (char *)"{ 1 2 3 4 }" ) ); - actualMechs.addOID( GSSOID( (char *)"{ 5 6 7 8 }" ) ); + actualMechs.addOID( GSSOID( (char *)"{ 1 5 6 7 8 }" ) ); MockAcquireCred::reset(); MockAcquireCred::retVal = 0; MockAcquireCred::minor_status = 0; @@ -278,7 +278,7 @@ void GSSAcquireCredTest::testJSONMarshal() CPPUNIT_ASSERT_EQUAL_MESSAGE( "The gss_name was reported incorrectly", - std::string("{ 5 6 7 8 }"), + std::string("{ 1 5 6 7 8 }"), std::string( (*result)["return_values"]["actual_mechs"][(size_t)1].string() ) ); diff --git a/json_gssapi/test/GSSPseudoRandomTest.cpp b/json_gssapi/test/GSSPseudoRandomTest.cpp new file mode 100644 index 0000000..12693ad --- /dev/null +++ b/json_gssapi/test/GSSPseudoRandomTest.cpp @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2014 + * + * For license details, see the LICENSE file in the root of this project. + * + */ + +#include + +//#include +//#include +#include + +#include "GSSPseudoRandom.h" +#include "GSSPseudoRandomTest.h" +#include "command_mocks/MockPseudoRandom.h" + +// Registers the fixture into the 'registry' +CPPUNIT_TEST_SUITE_REGISTRATION( GSSPseudoRandomTest ); + + +// typedef OM_uint32 (*gss_pseudo_random_type) ( +// OM_uint32 *, /* minor_status */ +// gss_ctx_id_t, /* context */ +// int, /* prf_key */ +// const gss_buffer_t, /* prf_in */ +// ssize_t, /* desired_output_len */ +// gss_buffer_t); /* prf_out */ +OM_uint32 mock_gss_pseudo_random( + OM_uint32 *minor_status, + gss_ctx_id_t context, + int prf_key, + const gss_buffer_t prf_in, + ssize_t desired_output_len, + gss_buffer_t prf_out) +{ + /* Variables */ + std::string buffer; + /* Error checking */ + /* Setup */ + /* Main */ + MockPseudoRandom::context_handle = context; + MockPseudoRandom::key = prf_key; + MockPseudoRandom::inputMessageBuffer.setValue(prf_in); + MockPseudoRandom::desiredOutputLength = desired_output_len; + + buffer = MockPseudoRandom::outputMessageBuffer.toString(); + prf_out->length = buffer.length(); + prf_out->value = (void *)buffer.c_str(); + + /* Cleanup */ + /* Return */ + return 0; +} + + +void GSSPseudoRandomTest::setUp() +{ + CppUnit::TestFixture::setUp(); + MockPseudoRandom::reset(); +} + + +void GSSPseudoRandomTest::testConstructor() +{ + /* Variables */ + GSSPseudoRandom cmd = GSSPseudoRandom(); + + /* Error checking */ + /* Setup */ + /* Main */ + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "The GSSPseudoRandom object has the wrong GSS function", + (void *)&gss_pseudo_random, + (void *)cmd.getGSSFunction() + ); + + /* Cleanup */ + /* Return */ +} + +/* + * Test that the command calls into gss_pseudo_random with + * all of the correct values, and that the command reads + * all of the appropriate values back out of it. + */ +void GSSPseudoRandomTest::testEmptyCall() +{ + /* Variables */ + GSSPseudoRandom cmd = GSSPseudoRandom(&mock_gss_pseudo_random); + gss_ctx_id_t desiredContext; + int prf_key; + ssize_t desired_output_len; + GSSBuffer prf_in((char *)"Input message"); + + /* Error Checking */ + /* Setup */ + + // Populate cmd with what will be used to call into gss_pseudo_random + // taking the address of prf_key should be plenty random for testing the empty call. + desiredContext = (gss_ctx_id_t)&prf_key; + prf_key = rand(); + desired_output_len = (ssize_t)(rand() + 50); // Must be at least fifty bytes long + + cmd.setContextHandle(desiredContext); + cmd.setKey(prf_key); + cmd.setInputMessage( prf_in ); + cmd.setDesiredOutputLength(desired_output_len); + + + // Populate the mock with what will be returned from gss_pseudo_random + MockPseudoRandom::minor_status = 0; + MockPseudoRandom::retVal = 0; + MockPseudoRandom::outputMessageBuffer.setValue((char *)"Output message"); + + + /* Main */ + cmd.execute(); + + // Do we populate the call to gss_pseudo_random correctly? + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "The requested GSS context handle is not correct", + desiredContext, + MockPseudoRandom::context_handle + ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "The requested pseudo random function key is not correct", + prf_key, + MockPseudoRandom::key + ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "The requested desired output length is not correct", + desired_output_len, + MockPseudoRandom::desiredOutputLength + ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "The requested input message is not correct", + prf_in.toString(), + MockPseudoRandom::inputMessageBuffer.toString() + ); + + // Do we read the results of gss_pseudo_random correctly? + + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "The requested output message is not correct", + MockPseudoRandom::outputMessageBuffer.toString(), + cmd.getOutputMessage().toString() + ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "The return value is not correct", + MockPseudoRandom::retVal, + cmd.getRetVal() + ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "The minor status value is not correct", + MockPseudoRandom::minor_status, + cmd.getMinorStatus() + ); + + + + /* Cleanup */ + /* Return */ +} + +/* JSON input + * + * {"method": "gss_pseudo_random", + * "arguments": + * { + * "context_handle": "########", + * "prf_key": ###, + * "prf_in": "la la la input message", + * "desired_output_len": #### + * } + * + */ +void GSSPseudoRandomTest::testConstructorWithJSONObject() +{ + /* Variables */ + const char* input = "{\"method\": \"gss_pseudo_random\", \ + \"arguments\": \ + { \ + \"context_handle\": \"#######\", \ + \"prf_key\": 1234567890, \ + \"prf_in\": \"mary had a little lamb\", \ + \"desired_output_len\": 256 \ + }\ + }"; + json_error_t jsonErr; + JSONObject json = JSONObject::load(input, 0, &jsonErr); + + GSSPseudoRandom cmd = GSSPseudoRandom(&json, &mock_gss_pseudo_random); + + /* Error Checking */ + /* Setup */ + /* Main */ + + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "GSSPseudoRandom did not parse the prf_key argument correctly.", + 1234567890, + cmd.getKey() + ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "GSSPseudoRandom did not parse the prf_in argument correctly.", + std::string("mary had a little lamb"), + cmd.getInputMessage().toString() + ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "GSSPseudoRandom did not parse the desired_output_len argument correctly.", + 256, + cmd.getDesiredOutputLength() + ); + + /* Cleanup */ + /* Return */ +} + +/* Desired JSON output: + * + * { + * "command": "gss_pseudo_random", + * "return_values": + * { + * "major_status": 0, + * "minor_status": 0, + * "random_bytes": "asdf" + * } + * } + */ +void GSSPseudoRandomTest::testJSONMarshal() +{ + + /* Variables */ + std::string output("dns@google.com"); + JSONObject *result; + GSSPseudoRandom cmd = GSSPseudoRandom(&mock_gss_pseudo_random); + + /* Error checking */ + /* Setup */ + MockPseudoRandom::minor_status = 0; + MockPseudoRandom::retVal = 0; + MockPseudoRandom::outputMessageBuffer.setValue(output); + + /* Main */ + cmd.execute(); + result = cmd.toJSON(); +// std::cout << "\nGSSWrap JSON: \n" << result->dump() << "\n"; + + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "The command name is incorrect", + std::string("gss_pseudo_random"), + std::string( (*result)["command"].string() ) + ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "The return value was reported incorrectly", + (int)MockPseudoRandom::retVal, + (int)( (*result)["return_values"]["major_status"].integer() ) + ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "The minor_status value was reported incorrectly", + (int)MockPseudoRandom::minor_status, + (int)( (*result)["return_values"]["minor_status"].integer() ) + ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "The random bytes were reported incorrectly", + MockPseudoRandom::outputMessageBuffer.toString(), + std::string( (*result)["return_values"]["random_bytes"].string() ) + ); + + + /* Cleanup */ + /* Return */ +} + + /* Variables */ + /* Error Checking */ + /* Setup */ + /* Main */ + /* Cleanup */ + /* Return */ diff --git a/json_gssapi/test/GSSPseudoRandomTest.h b/json_gssapi/test/GSSPseudoRandomTest.h new file mode 100644 index 0000000..f2d9a11 --- /dev/null +++ b/json_gssapi/test/GSSPseudoRandomTest.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2014 + * + * For license details, see the LICENSE file in the root of this project. + * + */ + +#ifndef GSSPSEUDORANDOMTEST_H +#define GSSPSEUDORANDOMTEST_H + +#include +#include + +class GSSPseudoRandomTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( GSSPseudoRandomTest ); + CPPUNIT_TEST( testConstructor ); + CPPUNIT_TEST( testEmptyCall ); + CPPUNIT_TEST( testConstructorWithJSONObject ); + CPPUNIT_TEST( testJSONMarshal ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + + void testJSONMarshal(); + void testEmptyCall(); + void testConstructor(); + void testConstructorWithJSONObject(); +}; + +#endif // GSSPSEUDORANDOMTEST_H diff --git a/json_gssapi/test/command_mocks/MockPseudoRandom.cpp b/json_gssapi/test/command_mocks/MockPseudoRandom.cpp new file mode 100644 index 0000000..8dcdc7e --- /dev/null +++ b/json_gssapi/test/command_mocks/MockPseudoRandom.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014 + * + * For license details, see the LICENSE file in the root of this project. + * + */ + +#include "MockPseudoRandom.h" + +/* + * static OM_uint32 retVal; + * static OM_uint32 minor_status; + * + * static gss_ctx_id_t context_handle; + * static int key; + * static GSSBuffer inputMessageBuffer; + * static ssize_t desiredOutputLength; + * static GSSBuffer outputMessageBuffer; + * + * static void reset(); + */ + +OM_uint32 MockPseudoRandom::retVal; +OM_uint32 MockPseudoRandom::minor_status; +gss_ctx_id_t MockPseudoRandom::context_handle; +int MockPseudoRandom::key; +GSSBuffer MockPseudoRandom::inputMessageBuffer; +ssize_t MockPseudoRandom::desiredOutputLength; +GSSBuffer MockPseudoRandom::outputMessageBuffer; + +void MockPseudoRandom::reset() +{ + retVal = 0; + minor_status = 0; + context_handle = GSS_C_NO_CONTEXT; + key = 0; + inputMessageBuffer.setValue(std::string()); + desiredOutputLength = 0; + outputMessageBuffer.setValue(std::string()); + + return; +} + diff --git a/json_gssapi/test/command_mocks/MockPseudoRandom.h b/json_gssapi/test/command_mocks/MockPseudoRandom.h new file mode 100644 index 0000000..02e6e03 --- /dev/null +++ b/json_gssapi/test/command_mocks/MockPseudoRandom.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2014 + * + * For license details, see the LICENSE file in the root of this project. + * + */ + +#ifndef MOCKPSEUDORANDOM_H +#define MOCKPSEUDORANDOM_H + +#include +#include + +class MockPseudoRandom +{ +public: + static OM_uint32 retVal; + static OM_uint32 minor_status; + + static gss_ctx_id_t context_handle; + static int key; + static GSSBuffer inputMessageBuffer; + static ssize_t desiredOutputLength; + static GSSBuffer outputMessageBuffer; + + static void reset(); +}; + +#endif // MOCKPSEUDORANDOM_H -- 2.1.4