[cpp-sp] branch main updated: Add CSPRNG impl, dummy sessio store.
Scott Cantor
cantor.2 at osu.edu
Tue Jun 3 14:18:44 UTC 2025
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository cpp-sp.
View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=f0ffb3d2f074761475e5c0d0c574d146a2f2a3a8
The following commit(s) were added to refs/heads/main by this push:
new f0ffb3d2 Add CSPRNG impl, dummy sessio store.
f0ffb3d2 is described below
commit f0ffb3d2f074761475e5c0d0c574d146a2f2a3a8
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Jun 3 10:18:40 2025 -0400
Add CSPRNG impl, dummy sessio store.
---
Projects/vc22/shibsp.vcxproj | 6 +-
doc/CSPRNG.LICENSE | 23 ++++
doc/Makefile.am | 1 +
shibsp/Makefile.am | 4 +
shibsp/csprng/csprng.h | 50 +++++++
shibsp/csprng/csprng.hpp | 195 +++++++++++++++++++++++++++
shibsp/csprng/impl/csprng.cpp | 137 +++++++++++++++++++
shibsp/csprng/is_iterable.hpp | 46 +++++++
shibsp/session/impl/AbstractSessionCache.cpp | 1 +
shibsp/session/impl/MemorySessionCache.cpp | 14 +-
10 files changed, 471 insertions(+), 6 deletions(-)
diff --git a/Projects/vc22/shibsp.vcxproj b/Projects/vc22/shibsp.vcxproj
index 2bcab0c8..04ee38b3 100644
--- a/Projects/vc22/shibsp.vcxproj
+++ b/Projects/vc22/shibsp.vcxproj
@@ -32,10 +32,13 @@
<ClInclude Include="..\..\shibsp\AccessControl.h" />
<ClInclude Include="..\..\shibsp\Agent.h" />
<ClInclude Include="..\..\shibsp\AgentConfig.h" />
- <ClInclude Include="..\..\shibsp\attribute\AttributeConfiguration.h" />
<ClInclude Include="..\..\shibsp\base.h" />
<ClInclude Include="..\..\shibsp\config_pub_win32.h" />
<ClInclude Include="..\..\shibsp\exceptions.h" />
+ <ClInclude Include="..\..\shibsp\attribute\AttributeConfiguration.h" />
+ <ClInclude Include="..\..\shibsp\csprng\csprng.h" />
+ <ClInclude Include="..\..\shibsp\csprng\csprng.hpp" />
+ <ClInclude Include="..\..\shibsp\csprng\is_iterable.hpp" />
<ClInclude Include="..\..\shibsp\handler\AbstractHandler.h" />
<ClInclude Include="..\..\shibsp\handler\AssertionConsumerService.h" />
<ClInclude Include="..\..\shibsp\handler\Handler.h" />
@@ -84,6 +87,7 @@
<ClCompile Include="..\..\shibsp\AbstractSPRequest.cpp" />
<ClCompile Include="..\..\shibsp\Agent.cpp" />
<ClCompile Include="..\..\shibsp\attribute\impl\DefaultAttributeConfiguration.cpp" />
+ <ClCompile Include="..\..\shibsp\csprng\impl\csprng.cpp" />
<ClCompile Include="..\..\shibsp\exceptions.cpp" />
<ClCompile Include="..\..\shibsp\handler\impl\AbstractHandler.cpp">
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4296;%(DisableSpecificWarnings)</DisableSpecificWarnings>
diff --git a/doc/CSPRNG.LICENSE b/doc/CSPRNG.LICENSE
new file mode 100644
index 00000000..1dad8e93
--- /dev/null
+++ b/doc/CSPRNG.LICENSE
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/doc/Makefile.am b/doc/Makefile.am
index e13fca4c..567b602c 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -13,6 +13,7 @@ docfiles = \
NOTICE.txt \
README.txt \
RELEASE.txt \
+ CSPRNG.LICENSE \
FASTCGI.LICENSE
pkgdoc_DATA = $(docfiles)
diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am
index 15fb425d..5608a9c4 100644
--- a/shibsp/Makefile.am
+++ b/shibsp/Makefile.am
@@ -87,6 +87,9 @@ utilinclude_HEADERS = \
noinst_HEADERS = \
internal.h \
+ csprng/csprng.h \
+ csprng/csprng.hpp \
+ csprng/is_iterable.hpp \
logging/impl/AbstractLoggingService.h \
logging/impl/LoggingServiceSPI.h \
logging/impl/StringUtil.h \
@@ -101,6 +104,7 @@ libshibsp_la_SOURCES = \
exceptions.cpp \
version.cpp \
attribute/impl/DefaultAttributeConfiguration.cpp \
+ csprng/impl/csprng.cpp \
handler/impl/AbstractHandler.cpp \
handler/impl/AdminLogoutInitiator.cpp \
handler/impl/AttributeCheckerHandler.cpp \
diff --git a/shibsp/csprng/csprng.h b/shibsp/csprng/csprng.h
new file mode 100644
index 00000000..b49f338d
--- /dev/null
+++ b/shibsp/csprng/csprng.h
@@ -0,0 +1,50 @@
+/*
+// Interface to the OS Cryptographically-Secure Pseudo-Random Number Generator
+
+// Copyright 2017 Michael Thomas Greer
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file ../../LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt )
+*/
+
+#pragma once
+#ifndef DUTHOMHAS_CSPRNG_H
+#define DUTHOMHAS_CSPRNG_H
+
+/* ------------------------------------------------------------------------------------------------
+ * CSPRNG
+ */
+typedef void* CSPRNG;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+CSPRNG csprng_create();
+/* Returns a new CSPRNG object, 0 on error.
+ */
+
+int csprng_get( CSPRNG, void* dest, unsigned long long size );
+/* Fills $dest with $size bytes worth of random data.
+ * Returns 1 on succes, 0 on failure.
+ */
+
+long csprng_get_int( CSPRNG );
+/* Return a random value
+ * There is no way to know if it failed.
+ * (If it did fail, the result will be 0, which is fairly unlikely
+ * to occur multiple times in sequence.
+ * It is also unlikely to fail at all if csprng_create() succeeded.)
+ */
+
+CSPRNG csprng_destroy( CSPRNG );
+/* Destroy an existing CSPRNG object. Returns 0.
+ * Use it as:
+ * v = csprng_destroy( v );
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/shibsp/csprng/csprng.hpp b/shibsp/csprng/csprng.hpp
new file mode 100644
index 00000000..9e3dc1eb
--- /dev/null
+++ b/shibsp/csprng/csprng.hpp
@@ -0,0 +1,195 @@
+// Interface to the OS Cryptographically-Secure Pseudo-Random Number Generator
+
+// Copyright 2017 Michael Thomas Greer
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file ../../LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt )
+
+#ifndef DUTHOMHAS_CSPRNG_HPP
+#define DUTHOMHAS_CSPRNG_HPP
+
+#include <shibsp/base.h>
+#include <shibsp/csprng/csprng.h>
+#include <shibsp/csprng/is_iterable.hpp>
+
+#include <initializer_list>
+#include <iterator>
+#include <limits>
+#include <stdexcept>
+#include <string>
+#include <type_traits>
+
+//-------------------------------------------------------------------------------------------------
+namespace duthomhas
+{
+ struct csprng
+ {
+ // Standard C++ Library PRNG boilerplate . . . . . . . . . . . . . . . . . . . . . .
+ typedef unsigned long result_type;
+
+ static constexpr result_type min() { return std::numeric_limits <result_type> ::min(); }
+ static constexpr result_type max() { return std::numeric_limits <result_type> ::max(); }
+
+ template <typename Sseq>
+ void seed( Sseq& ) { }
+ void seed( result_type ) { }
+ void discard( unsigned long long ) { }
+
+ public:
+ // Standard C++ std::seed_seq boilerplate . . . . . . . . . . . . . . . . . . . . . .
+ template <typename Iterator>
+ csprng( Iterator begin, Iterator end ):
+ internal( csprng_create() ),
+ sseq( internal, std::distance( begin, end ) )
+ { }
+
+ template <typename T>
+ csprng( std::initializer_list <T> xs ):
+ internal( csprng_create() ),
+ sseq( internal, xs.size() )
+ { }
+
+ struct sseq_type
+ {
+ // ( This is separated out like this otherwise objects that take a SeedSeq
+ // object may get confused by the conversion operators in the main class. )
+
+ template <typename Iterator>
+ void generate( Iterator begin, Iterator end )
+ {
+ while (begin != end)
+ *begin++ = csprng_get_int( internal );
+ }
+
+ std::size_t size() const { return seed_seq_size; }
+
+ template <typename Iterator>
+ void param( Iterator dest ) const
+ {
+ for (auto n = seed_seq_size; n--; )
+ *dest++ = csprng_get_int( internal );
+ }
+
+ CSPRNG& internal;
+ std::size_t seed_seq_size;
+
+ sseq_type( CSPRNG& internal, std::size_t seed_seq_size ):
+ internal( internal ),
+ seed_seq_size( seed_seq_size )
+ { }
+ };
+
+ public:
+ // Runtime errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+ struct exception: public std::runtime_error
+ {
+ exception( const char* message ): std::runtime_error( message ) { }
+ exception( const std::string& message ): std::runtime_error( message ) { }
+ };
+
+ // Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+ csprng(): internal( csprng_create() ), sseq( internal, 0 )
+ {
+ if (!internal)
+ throw exception( "duthomhas::CSPRNG: Failed to initialize the OS CSPRNG" );
+ }
+
+ csprng( const csprng& that ):
+ internal( csprng_create() ),
+ sseq( internal, that.sseq.seed_seq_size )
+ {
+ if (!internal)
+ throw exception( "duthomhas::CSPRNG: Failed to initialize the OS CSPRNG" );
+ }
+
+ // Destructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+ ~csprng()
+ {
+ internal = csprng_destroy( internal );
+ }
+
+ // Typed buffer fill . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+ // int* xs = rng( new int[ 5 ], 5 );
+ template <typename T>
+ T* operator () ( T* buffer, std::size_t n )
+ {
+ if (!csprng_get( internal, (void*)buffer, n * sizeof(T) ))
+ throw exception( "duthomhas::CSPRNG: Failed to read the OS CSPRNG" );
+ return buffer;
+ }
+
+ // Untyped buffer fill . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+ // void* p = get_some_unknown_with_known_size_in_bytes();
+ // rng( p, size_in_bytes );
+// template <typename T>
+ void* operator () ( void* buffer, std::size_t n )
+ {
+ return operator () <unsigned char> ( (unsigned char*)buffer, n );
+ }
+
+ // Typed assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+ // int x = rng();
+ template <typename T>
+ operator T ()
+ {
+ T result;
+ return operator () ( result );
+ }
+
+ // Untyped function --> unsigned long . . . . . . . . . . . . . . . . . . . . . . . .
+ // rng()
+ result_type operator () ()
+ {
+ result_type result;
+ return *operator () ( &result, 1 );
+ }
+
+ // Fundamental / assignable from fundamental types function . . . . . . . . . . . . .
+ // rng( int() )
+ //
+ // int x;
+ // rng( x )
+ template <typename T>
+ typename std::enable_if <std::is_fundamental <typename std::remove_reference <T> ::type> ::value, T&> ::type
+ operator () ( T&& value )
+ {
+ operator () ( &value, 1 );
+ return value;
+ }
+
+ // Iterable types function . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+ // auto s = rng( std::string( 20, 0 ) );
+ // auto v = rng( std::vector <int> ( 20 ) );
+ template <typename Iterable>
+ typename std::enable_if <is_iterable <Iterable> ::value, Iterable&> ::type
+ operator () ( Iterable&& value )
+ {
+ for (auto& v : value)
+ operator () ( v );
+ return value;
+ }
+
+ // Array types function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+ // int xs[ 20 ];
+ // rng( xs )
+ template <typename T, std::size_t N>
+ T* operator () ( T* (&array)[ N ] )
+ {
+ for (auto& v : array)
+ operator () ( v );
+ return &(array[0]);
+ }
+
+ private:
+ // Internal state is hidden from user . . . . . . . . . . . . . . . . . . . . . . . .
+ CSPRNG internal;
+
+ public:
+ // This thing is public, though . . . . . . . . . . . . . . . . . . . . . . . . . . .
+ sseq_type sseq;
+
+ };
+
+}
+
+#endif
diff --git a/shibsp/csprng/impl/csprng.cpp b/shibsp/csprng/impl/csprng.cpp
new file mode 100644
index 00000000..e06dd099
--- /dev/null
+++ b/shibsp/csprng/impl/csprng.cpp
@@ -0,0 +1,137 @@
+/*
+// Source for the OS Cryptographically-Secure Pseudo-Random Number Generator
+
+// Copyright 2017 Michael Thomas Greer
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file ../LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt )
+*/
+
+#include "csprng/csprng.h"
+
+/* ///////////////////////////////////////////////////////////////////////////////////////////// */
+#ifdef _WIN32
+/* ///////////////////////////////////////////////////////////////////////////////////////////// */
+
+ #include <windows.h>
+ #include <wincrypt.h>
+
+ #ifdef _MSC_VER
+ #pragma comment(lib, "advapi32.lib")
+ #endif
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ /* ------------------------------------------------------------------------------------------- */
+ typedef union
+ {
+ CSPRNG object;
+ HCRYPTPROV hCryptProv;
+ }
+ CSPRNG_TYPE;
+
+ /* ------------------------------------------------------------------------------------------- */
+ CSPRNG csprng_create()
+ {
+ CSPRNG_TYPE csprng;
+ if (!CryptAcquireContextA( &csprng.hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT ))
+ csprng.hCryptProv = 0;
+ return csprng.object;
+ }
+
+ /* ------------------------------------------------------------------------------------------- */
+ int csprng_get( CSPRNG object, void* dest, unsigned long long size )
+ {
+ // Alas, we have to be pedantic here. csprng_get().size is a 64-bit entity.
+ // However, CryptGenRandom().size is only a 32-bit DWORD. So we have to make sure failure
+ // isn't from providing less random data than requested, even if absurd.
+ unsigned long long n;
+
+ CSPRNG_TYPE csprng;
+ csprng.object = object;
+ if (!csprng.hCryptProv) return 0;
+
+ n = size >> 30;
+ while (n--)
+ if (!CryptGenRandom( csprng.hCryptProv, 1UL << 30, (BYTE*)dest )) return 0;
+
+ return !!CryptGenRandom( csprng.hCryptProv, size & ((1ULL << 30) - 1), (BYTE*)dest );
+ }
+
+ /* ------------------------------------------------------------------------------------------- */
+ long csprng_get_int( CSPRNG object )
+ {
+ long result;
+ return csprng_get( object, &result, sizeof(result) ) ? result : 0;
+ }
+
+ /* ------------------------------------------------------------------------------------------- */
+ CSPRNG csprng_destroy( CSPRNG object )
+ {
+ CSPRNG_TYPE csprng;
+ csprng.object = object;
+ if (csprng.hCryptProv) CryptReleaseContext( csprng.hCryptProv, 0 );
+ return 0;
+ }
+
+ #ifdef __cplusplus
+ }
+ #endif
+
+/* ///////////////////////////////////////////////////////////////////////////////////////////// */
+#else /* Using /dev/urandom */
+/* ///////////////////////////////////////////////////////////////////////////////////////////// */
+
+ #include <stdio.h>
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ /* ------------------------------------------------------------------------------------------- */
+ typedef union
+ {
+ CSPRNG object;
+ FILE* urandom;
+ }
+ CSPRNG_TYPE;
+
+ /* ------------------------------------------------------------------------------------------- */
+ CSPRNG csprng_create()
+ {
+ CSPRNG_TYPE csprng;
+ csprng.urandom = fopen( "/dev/urandom", "rb" );
+ return csprng.object;
+ }
+
+ /* ------------------------------------------------------------------------------------------- */
+ int csprng_get( CSPRNG object, void* dest, unsigned long long size )
+ {
+ CSPRNG_TYPE csprng;
+ csprng.object = object;
+ return (csprng.urandom) && (fread( (char*)dest, 1, size, csprng.urandom ) == size);
+ }
+
+ /* ------------------------------------------------------------------------------------------- */
+ long csprng_get_int( CSPRNG object )
+ {
+ long result;
+ return csprng_get( object, &result, sizeof(result) ) ? result : 0;
+ }
+
+ /* ------------------------------------------------------------------------------------------- */
+ CSPRNG csprng_destroy( CSPRNG object )
+ {
+ CSPRNG_TYPE csprng;
+ csprng.object = object;
+ if (csprng.urandom) fclose( csprng.urandom );
+ return 0;
+ }
+
+ #ifdef __cplusplus
+ }
+ #endif
+
+#endif
diff --git a/shibsp/csprng/is_iterable.hpp b/shibsp/csprng/is_iterable.hpp
new file mode 100644
index 00000000..cb991909
--- /dev/null
+++ b/shibsp/csprng/is_iterable.hpp
@@ -0,0 +1,46 @@
+// is_iterable.hpp
+
+// Copyright 2017 Michael Thomas Greer
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file ../../LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt )
+
+#ifndef DUTHOMHAS_IS_ITERABLE_HPP
+#define DUTHOMHAS_IS_ITERABLE_HPP
+
+namespace duthomhas
+{
+
+ // The basis for this code was found at
+ // https://stackoverflow.com/a/29634934/2706707
+ using std::begin;
+ using std::end;
+
+ template <typename T>
+ class is_iterable
+ {
+ template <typename U>
+ static constexpr auto is_iterable_impl( int )
+ -> decltype(
+ begin( std::declval <U&> () ) != end( std::declval <U&> () ), // begin/end and operator !=
+ void(), // Handle evil operator ,
+ ++std::declval <decltype( begin( std::declval <U&> () ) )&> (), // operator ++
+ void( *begin( std::declval <U&> () ) ), // operator*
+ std::true_type {}
+ )
+ { return std::true_type {}; }
+
+ template <typename U>
+ static constexpr std::false_type is_iterable_impl(...)
+ { return std::false_type {}; }
+
+ typedef decltype( is_iterable_impl <T> ( 0 ) ) type;
+
+ public:
+ //static constexpr bool value = type::value;
+ enum : bool { value = type::value };
+ };
+
+}
+
+#endif
diff --git a/shibsp/session/impl/AbstractSessionCache.cpp b/shibsp/session/impl/AbstractSessionCache.cpp
index 6b41c3aa..e9f686e7 100644
--- a/shibsp/session/impl/AbstractSessionCache.cpp
+++ b/shibsp/session/impl/AbstractSessionCache.cpp
@@ -171,6 +171,7 @@ string AbstractSessionCache::create(SPRequest& request, DDF& session)
return string();
}
+ session.name(key.c_str());
unique_ptr<BasicSession> sessionObject(new BasicSession(*this, session));
const char* issuer = nullptr;
diff --git a/shibsp/session/impl/MemorySessionCache.cpp b/shibsp/session/impl/MemorySessionCache.cpp
index 2d33605f..1352bc6e 100644
--- a/shibsp/session/impl/MemorySessionCache.cpp
+++ b/shibsp/session/impl/MemorySessionCache.cpp
@@ -17,13 +17,14 @@
*
* SessionCache implementation using non-shared memory.
*
- * <p>This is a more or less degenerate implementation of the SessionCacheSPI interface
- * for testing and perhaps very constrained use cases in which only a single agent process
- * can exist.</p>
+ * <p>This is a degenerate implementation for testing and perhaps very constrained use cases
+ * in which only a single agent process can exist. It essentially no-ops all the operations
+ * such that the base class in-process cache is the only store.</p>
*/
#include "internal.h"
#include "exceptions.h"
+#include "csprng/csprng.hpp"
#include "session/AbstractSessionCache.h"
#include "logging/Category.h"
@@ -49,6 +50,9 @@ namespace {
) const;
bool cache_touch(const char* key, unsigned int timeout=0) const;
void cache_remove(const char* key);
+
+ private:
+ duthomhas::csprng m_rng;
};
};
@@ -68,7 +72,7 @@ MemorySessionCache::~MemorySessionCache()
string MemorySessionCache::cache_create(DDF& sessionData)
{
- return string();
+ return m_rng(string(16,0));
}
DDF MemorySessionCache::cache_read(
@@ -84,7 +88,7 @@ DDF MemorySessionCache::cache_read(
bool MemorySessionCache::cache_touch(const char* key, unsigned int timeout) const
{
- return false;
+ return true;
}
void MemorySessionCache::cache_remove(const char* key)
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list