[cpp-sp] branch main updated: Switch RNG to C++ impl.
Codeberg
noreply at shibboleth.net
Mon Sep 7 18:16:42 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch main
in repository cpp-sp.
View the commit online:
https://codeberg.org/Shibboleth/cpp-sp/commit/b23526331f556b99dfb550ace585b562b3956d3a
The following commit(s) were added to refs/heads/main by this push:
new b2352633 Switch RNG to C++ impl.
b2352633 is described below
commit b23526331f556b99dfb550ace585b562b3956d3a
Author: Scott Cantor <scott at restingparrotsoftware.com>
AuthorDate: Mon Sep 7 14:16:27 2026 -0400
Switch RNG to C++ impl.
---
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/impl/AgentConfig.cpp | 45 +++++++++-
6 files changed, 42 insertions(+), 435 deletions(-)
diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am
index e8d0c61f..d11aae09 100644
--- a/shibsp/Makefile.am
+++ b/shibsp/Makefile.am
@@ -83,9 +83,6 @@ 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 \
@@ -102,7 +99,6 @@ libshibsp_la_SOURCES = \
exceptions.cpp \
version.cpp \
attribute/impl/DefaultAttributeConfiguration.cpp \
- csprng/impl/csprng.cpp \
handler/impl/AbstractHandler.cpp \
handler/impl/AttributeCheckerHandler.cpp \
handler/impl/DefaultHandlerConfiguration.cpp \
diff --git a/shibsp/csprng/csprng.h b/shibsp/csprng/csprng.h
deleted file mode 100644
index b49f338d..00000000
--- a/shibsp/csprng/csprng.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-// 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
deleted file mode 100644
index 9e3dc1eb..00000000
--- a/shibsp/csprng/csprng.hpp
+++ /dev/null
@@ -1,195 +0,0 @@
-// 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
deleted file mode 100644
index e06dd099..00000000
--- a/shibsp/csprng/impl/csprng.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
-// 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
deleted file mode 100644
index cb991909..00000000
--- a/shibsp/csprng/is_iterable.hpp
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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/impl/AgentConfig.cpp b/shibsp/impl/AgentConfig.cpp
index 8389c871..bc9432d5 100644
--- a/shibsp/impl/AgentConfig.cpp
+++ b/shibsp/impl/AgentConfig.cpp
@@ -26,7 +26,6 @@
#include "Agent.h"
#include "AgentConfig.h"
#include "RequestMapper.h"
-#include "csprng/csprng.hpp"
#include "handler/Handler.h"
#include "io/HTTPResponse.h"
#include "logging/LoggingService.h"
@@ -39,6 +38,7 @@
#include <climits>
#include <ctime>
+#include <random>
#include <stdexcept>
#include <thread>
#include <mutex>
@@ -108,7 +108,7 @@ namespace shibsp {
vector<void*> m_libhandles;
unique_ptr<LoggingService> m_logging;
unique_ptr<Agent> m_agent;
- mutable duthomhas::csprng m_rng;
+ mutable mt19937_64 m_rng;
};
static AgentInternalConfig g_agentConfig;
@@ -166,7 +166,23 @@ Agent& AgentInternalConfig::getAgent() const
string AgentInternalConfig::generateRandom(unsigned int len) const
{
- return hex_encode(m_rng(string(len, 0)));
+ string s;
+
+ while (len > 0) {
+ uint_fast64_t val = m_rng();
+ size_t randlen = sizeof(uint_fast64_t);
+ for (int i = 0; i < randlen; ++i) {
+ s += (char) (val & 0xFF);
+ val = val >> 8;
+ }
+ if (len > randlen) {
+ len -= randlen;
+ } else {
+ len = 0;
+ }
+ }
+
+ return hex_encode(s);
}
bool AgentInternalConfig::init(const char* inst_prefix, const char* config_file, bool rethrow)
@@ -193,8 +209,31 @@ bool AgentInternalConfig::init(const char* inst_prefix, const char* config_file,
return true;
}
+static unsigned long long my_entropy()
+{
+ // Gather many potential forms of entropy and XOR them
+ const uint64_t my_seed = 0xc587acf84d9d5a64;
+ static uint64_t i = 0;
+ static std::random_device rd;
+ const auto hrclock = std::chrono::high_resolution_clock::now().time_since_epoch().count();
+ const auto sclock = std::chrono::system_clock::now().time_since_epoch().count();
+ auto *heap = malloc(1);
+ const auto mash = my_seed + rd() + hrclock + sclock + (i++) +
+ reinterpret_cast<intptr_t>(heap) + reinterpret_cast<intptr_t>(&hrclock) +
+ reinterpret_cast<intptr_t>(&i) + reinterpret_cast<intptr_t>(&malloc) +
+ reinterpret_cast<intptr_t>(&my_entropy);
+ free(heap);
+ return mash;
+}
+
bool AgentInternalConfig::_init(const char* inst_prefix, const char* config_file, bool rethrow)
{
+ // Attempt to seed the PRNG.
+ uint_least64_t seed_data[mt19937_64::state_size];
+ generate_n(seed_data, mt19937_64::state_size, ref(my_entropy));
+ seed_seq q(begin(seed_data), end(seed_data));
+ m_rng.seed(q);
+
// Establish prefix and replace backward slashes in path.
if (!inst_prefix)
inst_prefix = getenv("SHIBSP_PREFIX");
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list