mirror of
https://github.com/amnezia-vpn/openvpn3.git
synced 2026-05-17 08:26:28 +03:00
introduce base types for strong and weak RNGs
The need of having to call the assert_crypto() member function to ensure that a cryptographically strong RNG is used where needed, was reported as potentially insecure, since calling it manually can easily be missed. In the commit the two new classes StrongRandomAPI and WeakRandomAPI are introduced. They are to be used instead of just RandomAPI, unless it doesn't matter what strength the RNG is. All the places the assert_crypto() was called were converted to using StrongRandomAPI instead. Also the RNGs for which assert_crypto() was not throwing are now inheriting from StrongRandomAPI. Variable names, which have the StrongRandomAPI type, but were called prng, are changed to rng instead to follow the source code convention. Signed-off-by: Heiko Hund <heiko@openvpn.net>
This commit is contained in:
@@ -480,13 +480,12 @@ Here is a brief set of guidelines:
|
||||
|
||||
* When grabbing random entropy that is to be used
|
||||
for cryptographic purposes (i.e. for keys, tokens, etc.),
|
||||
always ensure that the RNG is crypto-grade by calling
|
||||
:code:`assert_crypto()` on the RNG. This will throw
|
||||
an exception if the RNG is not crypto-grade:
|
||||
always ensure that the RNG is crypto-grade by using
|
||||
:code:`class StrongRandomAPI` as the RNG type:
|
||||
::
|
||||
|
||||
void set_rng(RandomAPI::Ptr rng_arg) {
|
||||
rng_arg->assert_crypto();
|
||||
StrongRandomAPI::Ptr rng;
|
||||
void set_rng(StrongRandomAPI::Ptr rng_arg) {
|
||||
rng = std::move(rng_arg);
|
||||
}
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ class AppleSSLContext : public SSLFactoryAPI
|
||||
return not_implemented("set_enable_renegotiation");
|
||||
}
|
||||
|
||||
virtual void set_rng(const RandomAPI::Ptr &rng_arg)
|
||||
virtual void set_rng(const StrongRandomAPI::Ptr &rng_arg)
|
||||
{
|
||||
return not_implemented("set_rng");
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <openvpn/random/randapi.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
class AppleRandom : public RandomAPI
|
||||
class AppleRandom : public StrongRandomAPI
|
||||
{
|
||||
public:
|
||||
OPENVPN_EXCEPTION(rand_error_apple);
|
||||
@@ -47,12 +47,6 @@ class AppleRandom : public RandomAPI
|
||||
return "AppleRandom";
|
||||
}
|
||||
|
||||
// Return true if algorithm is crypto-strength
|
||||
virtual bool is_crypto() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fill buffer with random bytes
|
||||
virtual void rand_bytes(unsigned char *buf, size_t size)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace AWS {
|
||||
class HTTPContext
|
||||
{
|
||||
public:
|
||||
HTTPContext(RandomAPI::Ptr rng,
|
||||
HTTPContext(StrongRandomAPI::Ptr rng,
|
||||
const int debug_level)
|
||||
: frame_(frame_init_simple(2048)),
|
||||
digest_factory_(new CryptoDigestFactory<SSLLib::CryptoAPI>()),
|
||||
@@ -49,7 +49,7 @@ class HTTPContext
|
||||
}
|
||||
|
||||
#ifdef VPN_BINDING_PROFILES
|
||||
HTTPContext(RandomAPI::Ptr rng,
|
||||
HTTPContext(StrongRandomAPI::Ptr rng,
|
||||
const int debug_level,
|
||||
const OptionList &opt) // for VPN binding profile
|
||||
: HTTPContext(rng, debug_level)
|
||||
@@ -84,7 +84,7 @@ class HTTPContext
|
||||
return *digest_factory_;
|
||||
}
|
||||
|
||||
RandomAPI *rng() const
|
||||
StrongRandomAPI *rng() const
|
||||
{
|
||||
return rng_.get();
|
||||
}
|
||||
@@ -120,7 +120,7 @@ class HTTPContext
|
||||
|
||||
Frame::Ptr frame_;
|
||||
DigestFactory::Ptr digest_factory_;
|
||||
RandomAPI::Ptr rng_;
|
||||
StrongRandomAPI::Ptr rng_;
|
||||
WS::Client::Config::Ptr http_config_;
|
||||
#ifdef VPN_BINDING_PROFILES
|
||||
WS::ViaVPN::Ptr via_vpn_;
|
||||
|
||||
@@ -516,7 +516,6 @@ class PCQuery : public RC<thread_unsafe_refcount>
|
||||
std::string nonce() const
|
||||
{
|
||||
unsigned char data[16];
|
||||
rng->assert_crypto();
|
||||
rng->rand_fill(data);
|
||||
return render_hex(data, sizeof(data));
|
||||
}
|
||||
@@ -598,7 +597,7 @@ class PCQuery : public RC<thread_unsafe_refcount>
|
||||
}
|
||||
|
||||
WS::ClientSet::Ptr cs;
|
||||
RandomAPI::Ptr rng;
|
||||
StrongRandomAPI::Ptr rng;
|
||||
Frame::Ptr frame;
|
||||
const bool lookup_product_code;
|
||||
const int debug_level;
|
||||
|
||||
@@ -1255,7 +1255,7 @@ class ClientOptions : public RC<thread_unsafe_refcount>
|
||||
Client::ProtoConfig::Ptr cp(new Client::ProtoConfig());
|
||||
cp->ssl_factory = cc->new_factory();
|
||||
cp->relay_mode = relay_mode;
|
||||
cp->dc.set_factory(new CryptoDCSelect<SSLLib::CryptoAPI>(cp->ssl_factory->libctx(), frame, cli_stats, prng));
|
||||
cp->dc.set_factory(new CryptoDCSelect<SSLLib::CryptoAPI>(cp->ssl_factory->libctx(), frame, cli_stats, rng));
|
||||
cp->dc_deferred = true; // defer data channel setup until after options pull
|
||||
cp->tls_auth_factory.reset(new CryptoOvpnHMACFactory<SSLLib::CryptoAPI>());
|
||||
cp->tls_crypt_factory.reset(new CryptoTLSCryptFactory<SSLLib::CryptoAPI>());
|
||||
@@ -1388,7 +1388,7 @@ class ClientOptions : public RC<thread_unsafe_refcount>
|
||||
ClientConfigParsed clientconf;
|
||||
|
||||
Time now_; // current time
|
||||
RandomAPI::Ptr rng;
|
||||
StrongRandomAPI::Ptr rng;
|
||||
RandomAPI::Ptr prng;
|
||||
Frame::Ptr frame;
|
||||
Layer layer;
|
||||
|
||||
@@ -55,10 +55,8 @@ class SessionIDType
|
||||
}
|
||||
|
||||
// Create a random Session ID.
|
||||
explicit SessionIDType(RandomAPI &rng, const bool allow_noncrypto_rng = false)
|
||||
explicit SessionIDType(RandomAPI &rng)
|
||||
{
|
||||
if (!allow_noncrypto_rng)
|
||||
rng.assert_crypto();
|
||||
rng.rand_bytes(u.data, sizeof(u.data));
|
||||
}
|
||||
|
||||
|
||||
@@ -44,17 +44,17 @@ class CryptoCHM : public CryptoDCInstance
|
||||
const CryptoAlgs::Type digest_arg,
|
||||
const Frame::Ptr &frame_arg,
|
||||
const SessionStats::Ptr &stats_arg,
|
||||
const RandomAPI::Ptr &prng_arg)
|
||||
const StrongRandomAPI::Ptr &rng_arg)
|
||||
: cipher(cipher_arg),
|
||||
digest(digest_arg),
|
||||
frame(frame_arg),
|
||||
stats(stats_arg),
|
||||
prng(prng_arg),
|
||||
rng(rng_arg),
|
||||
libctx(libctx_arg)
|
||||
{
|
||||
encrypt_.frame = frame;
|
||||
decrypt_.frame = frame;
|
||||
encrypt_.set_prng(prng);
|
||||
encrypt_.set_rng(rng);
|
||||
}
|
||||
|
||||
// Encrypt/Decrypt
|
||||
@@ -126,7 +126,7 @@ class CryptoCHM : public CryptoDCInstance
|
||||
CryptoAlgs::Type digest;
|
||||
Frame::Ptr frame;
|
||||
SessionStats::Ptr stats;
|
||||
RandomAPI::Ptr prng;
|
||||
StrongRandomAPI::Ptr rng;
|
||||
SSLLib::Ctx libctx;
|
||||
|
||||
EncryptCHM<CRYPTO_API> encrypt_;
|
||||
@@ -146,13 +146,13 @@ class CryptoContextCHM : public CryptoDCContext
|
||||
const CryptoAlgs::KeyDerivation key_method,
|
||||
const Frame::Ptr &frame_arg,
|
||||
const SessionStats::Ptr &stats_arg,
|
||||
const RandomAPI::Ptr &prng_arg)
|
||||
const StrongRandomAPI::Ptr &rng_arg)
|
||||
: CryptoDCContext(key_method),
|
||||
cipher(CryptoAlgs::dc_cbc_cipher(cipher_arg)),
|
||||
digest(CryptoAlgs::dc_cbc_hash(digest_arg)),
|
||||
frame(frame_arg),
|
||||
stats(stats_arg),
|
||||
prng(prng_arg),
|
||||
rng(rng_arg),
|
||||
libctx(libctx_arg)
|
||||
{
|
||||
}
|
||||
@@ -167,7 +167,7 @@ class CryptoContextCHM : public CryptoDCContext
|
||||
CryptoAlgs::legal_dc_digest(digest),
|
||||
frame,
|
||||
stats,
|
||||
prng);
|
||||
rng);
|
||||
}
|
||||
|
||||
// cipher/HMAC/key info
|
||||
@@ -194,7 +194,7 @@ class CryptoContextCHM : public CryptoDCContext
|
||||
CryptoAlgs::Type digest;
|
||||
Frame::Ptr frame;
|
||||
SessionStats::Ptr stats;
|
||||
RandomAPI::Ptr prng;
|
||||
StrongRandomAPI::Ptr rng;
|
||||
SSLLib::Ctx libctx;
|
||||
};
|
||||
} // namespace openvpn
|
||||
|
||||
@@ -43,10 +43,10 @@ class CryptoDCSelect : public CryptoDCFactory
|
||||
CryptoDCSelect(SSLLib::Ctx libctx_arg,
|
||||
const Frame::Ptr &frame_arg,
|
||||
const SessionStats::Ptr &stats_arg,
|
||||
const RandomAPI::Ptr &prng_arg)
|
||||
const StrongRandomAPI::Ptr &rng_arg)
|
||||
: frame(frame_arg),
|
||||
stats(stats_arg),
|
||||
prng(prng_arg),
|
||||
rng(rng_arg),
|
||||
libctx(libctx_arg)
|
||||
{
|
||||
}
|
||||
@@ -57,7 +57,7 @@ class CryptoDCSelect : public CryptoDCFactory
|
||||
{
|
||||
const CryptoAlgs::Alg &alg = CryptoAlgs::get(cipher);
|
||||
if (alg.flags() & CryptoAlgs::CBC_HMAC)
|
||||
return new CryptoContextCHM<CRYPTO_API>(libctx, cipher, digest, method, frame, stats, prng);
|
||||
return new CryptoContextCHM<CRYPTO_API>(libctx, cipher, digest, method, frame, stats, rng);
|
||||
else if (alg.flags() & CryptoAlgs::AEAD)
|
||||
return new AEAD::CryptoContext<CRYPTO_API>(libctx, cipher, method, frame, stats);
|
||||
else
|
||||
@@ -67,7 +67,7 @@ class CryptoDCSelect : public CryptoDCFactory
|
||||
private:
|
||||
Frame::Ptr frame;
|
||||
SessionStats::Ptr stats;
|
||||
RandomAPI::Ptr prng;
|
||||
StrongRandomAPI::Ptr rng;
|
||||
SSLLib::Ctx libctx;
|
||||
};
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ class EncryptCHM
|
||||
if (cipher_mode == CRYPTO_API::CipherContext::CIPH_CBC_MODE)
|
||||
{
|
||||
// in CBC mode, use an explicit, random IV
|
||||
prng->rand_bytes(iv_buf, iv_length);
|
||||
rng->rand_bytes(iv_buf, iv_length);
|
||||
|
||||
// generate fresh outgoing packet ID and prepend to cleartext buffer
|
||||
pid_send.write_next(buf, true, now);
|
||||
@@ -102,10 +102,9 @@ class EncryptCHM
|
||||
}
|
||||
}
|
||||
|
||||
void set_prng(RandomAPI::Ptr prng_arg)
|
||||
void set_rng(StrongRandomAPI::Ptr rng_arg)
|
||||
{
|
||||
prng_arg->assert_crypto();
|
||||
prng = std::move(prng_arg);
|
||||
rng = std::move(rng_arg);
|
||||
}
|
||||
|
||||
Frame::Ptr frame;
|
||||
@@ -129,7 +128,7 @@ class EncryptCHM
|
||||
}
|
||||
|
||||
BufferAllocated work;
|
||||
RandomAPI::Ptr prng;
|
||||
StrongRandomAPI::Ptr rng;
|
||||
};
|
||||
|
||||
} // namespace openvpn
|
||||
|
||||
@@ -80,9 +80,8 @@ class StaticKey
|
||||
return base64->encode(key_data_);
|
||||
}
|
||||
|
||||
void init_from_rng(RandomAPI &rng, const size_t key_size)
|
||||
void init_from_rng(StrongRandomAPI &rng, const size_t key_size)
|
||||
{
|
||||
rng.assert_crypto();
|
||||
key_data_.init(key_size, key_t::DESTRUCT_ZERO);
|
||||
rng.rand_bytes(key_data_.data(), key_size);
|
||||
key_data_.set_size(key_size);
|
||||
|
||||
@@ -445,9 +445,8 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
x509_track_config = std::move(x509_track_config_arg);
|
||||
}
|
||||
|
||||
virtual void set_rng(const RandomAPI::Ptr &rng_arg)
|
||||
virtual void set_rng(const StrongRandomAPI::Ptr &rng_arg)
|
||||
{
|
||||
rng_arg->assert_crypto();
|
||||
rng = rng_arg;
|
||||
}
|
||||
|
||||
@@ -643,7 +642,7 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
std::string tls_groups;
|
||||
X509Track::ConfigSet x509_track_config;
|
||||
bool local_cert_enabled;
|
||||
RandomAPI::Ptr rng; // random data source
|
||||
StrongRandomAPI::Ptr rng; // random data source
|
||||
};
|
||||
|
||||
// Represents an actual SSL session.
|
||||
|
||||
@@ -35,14 +35,14 @@
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
class MbedTLSRandom : public RandomAPI
|
||||
class MbedTLSRandom : public StrongRandomAPI
|
||||
{
|
||||
public:
|
||||
OPENVPN_EXCEPTION(rand_error_mbedtls);
|
||||
|
||||
typedef RCPtr<MbedTLSRandom> Ptr;
|
||||
|
||||
MbedTLSRandom(const bool prng, RandomAPI::Ptr entropy_source)
|
||||
MbedTLSRandom(const bool prng, StrongRandomAPI::Ptr entropy_source)
|
||||
: entropy(std::move(entropy_source))
|
||||
{
|
||||
// Init RNG context
|
||||
@@ -60,7 +60,7 @@ class MbedTLSRandom : public RandomAPI
|
||||
}
|
||||
|
||||
MbedTLSRandom(const bool prng)
|
||||
: MbedTLSRandom(prng, RandomAPI::Ptr())
|
||||
: MbedTLSRandom(prng, StrongRandomAPI::Ptr())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -80,12 +80,6 @@ class MbedTLSRandom : public RandomAPI
|
||||
return n;
|
||||
}
|
||||
|
||||
// Return true if algorithm is crypto-strength
|
||||
virtual bool is_crypto() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fill buffer with random bytes
|
||||
virtual void rand_bytes(unsigned char *buf, size_t size)
|
||||
{
|
||||
|
||||
@@ -346,11 +346,9 @@ class OpenSSLContext : public SSLFactoryAPI
|
||||
x509_track_config = std::move(x509_track_config_arg);
|
||||
}
|
||||
|
||||
void set_rng(const RandomAPI::Ptr &rng_arg) override
|
||||
void set_rng(const StrongRandomAPI::Ptr &rng_arg) override
|
||||
{
|
||||
// Not implemented (other than assert_crypto check)
|
||||
// because OpenSSL is hardcoded to use its own RNG.
|
||||
rng_arg->assert_crypto();
|
||||
// Not implemented because OpenSSL is hardcoded to use its own RNG.
|
||||
}
|
||||
|
||||
std::string validate_cert(const std::string &cert_txt) const override
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <openvpn/common/numeric_util.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
class OpenSSLRandom : public RandomAPI
|
||||
class OpenSSLRandom : public StrongRandomAPI
|
||||
{
|
||||
public:
|
||||
OPENVPN_EXCEPTION(rand_error_openssl);
|
||||
@@ -48,12 +48,6 @@ class OpenSSLRandom : public RandomAPI
|
||||
return "OpenSSLRandom";
|
||||
}
|
||||
|
||||
// Return true if algorithm is crypto-strength
|
||||
virtual bool is_crypto() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fill buffer with random bytes
|
||||
virtual void rand_bytes(unsigned char *buf, size_t size)
|
||||
{
|
||||
|
||||
@@ -46,9 +46,8 @@ class TokenEncrypt
|
||||
public:
|
||||
static constexpr size_t SIZE = 16;
|
||||
|
||||
Key(RandomAPI &rng)
|
||||
Key(StrongRandomAPI &rng)
|
||||
{
|
||||
rng.assert_crypto();
|
||||
rng.rand_bytes(data, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ class NTLM
|
||||
const std::string &phase_2_response,
|
||||
const std::string &dom_username,
|
||||
const std::string &password,
|
||||
RandomAPI &rng)
|
||||
StrongRandomAPI &rng)
|
||||
{
|
||||
// sanity checks
|
||||
if (dom_username.empty())
|
||||
@@ -72,9 +72,6 @@ class NTLM
|
||||
if (phase_2_response.size() < 32)
|
||||
throw Exception("phase2 response from server too short (" + std::to_string(phase_2_response.size()) + ")");
|
||||
|
||||
// ensure that RNG is crypto-strength
|
||||
rng.assert_crypto();
|
||||
|
||||
// split domain\username
|
||||
std::string domain;
|
||||
std::string username;
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
class DevURand : public RandomAPI
|
||||
class DevURand : public StrongRandomAPI
|
||||
{
|
||||
public:
|
||||
OPENVPN_EXCEPTION(dev_urand_error);
|
||||
@@ -53,12 +53,6 @@ class DevURand : public RandomAPI
|
||||
return "DevURand";
|
||||
}
|
||||
|
||||
// Return true if algorithm is crypto-strength
|
||||
virtual bool is_crypto() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fill buffer with random bytes
|
||||
virtual void rand_bytes(unsigned char *buf, size_t size)
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
class MTRand : public RandomAPI
|
||||
class MTRand : public WeakRandomAPI
|
||||
{
|
||||
public:
|
||||
OPENVPN_EXCEPTION(mtrand_error);
|
||||
@@ -61,12 +61,6 @@ class MTRand : public RandomAPI
|
||||
return "MTRand";
|
||||
}
|
||||
|
||||
// Return true if algorithm is crypto-strength
|
||||
virtual bool is_crypto() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fill buffer with random bytes
|
||||
virtual void rand_bytes(unsigned char *buf, size_t size)
|
||||
{
|
||||
|
||||
@@ -27,24 +27,21 @@
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
// By convention, rng is crypto-strength while prng is
|
||||
// not. Be sure to always call RandomAPI::assert_crypto()
|
||||
// before using an rng for crypto purposes, to verify that
|
||||
// it is crypto-capable.
|
||||
// By convention, rng is crypto-strength while prng is not.
|
||||
struct Rand2
|
||||
{
|
||||
Rand2()
|
||||
{
|
||||
}
|
||||
|
||||
Rand2(RandomAPI::Ptr rng_arg,
|
||||
Rand2(StrongRandomAPI::Ptr rng_arg,
|
||||
RandomAPI::Ptr prng_arg)
|
||||
: rng(std::move(rng_arg)),
|
||||
prng(std::move(prng_arg))
|
||||
{
|
||||
}
|
||||
|
||||
Rand2(RandomAPI::Ptr rng_arg)
|
||||
Rand2(StrongRandomAPI::Ptr rng_arg)
|
||||
: rng(rng_arg),
|
||||
prng(rng_arg)
|
||||
{
|
||||
@@ -55,7 +52,7 @@ struct Rand2
|
||||
return rng && prng;
|
||||
}
|
||||
|
||||
RandomAPI::Ptr rng;
|
||||
StrongRandomAPI::Ptr rng;
|
||||
RandomAPI::Ptr prng;
|
||||
};
|
||||
|
||||
|
||||
@@ -136,15 +136,6 @@ class RandomAPI : public RC<thread_unsafe_refcount>
|
||||
return bool(randbyte() & 1);
|
||||
}
|
||||
|
||||
// Throw an exception if algorithm is not crypto-strength.
|
||||
// Be sure to always call this method before using an rng
|
||||
// for crypto purposes.
|
||||
void assert_crypto() const
|
||||
{
|
||||
if (!is_crypto())
|
||||
throw Exception("RandomAPI: " + name() + " algorithm is not crypto-strength");
|
||||
}
|
||||
|
||||
// UniformRandomBitGenerator for std::shuffle
|
||||
typedef unsigned int result_type;
|
||||
static constexpr result_type min()
|
||||
@@ -159,6 +150,33 @@ class RandomAPI : public RC<thread_unsafe_refcount>
|
||||
{
|
||||
return rand_get<result_type>();
|
||||
}
|
||||
|
||||
private:
|
||||
friend class StrongRandomAPI;
|
||||
friend class WeakRandomAPI;
|
||||
RandomAPI() = default;
|
||||
};
|
||||
|
||||
class StrongRandomAPI : public RandomAPI
|
||||
{
|
||||
bool is_crypto() const final override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
typedef RCPtr<StrongRandomAPI> Ptr;
|
||||
};
|
||||
|
||||
class WeakRandomAPI : public RandomAPI
|
||||
{
|
||||
bool is_crypto() const final override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
typedef RCPtr<WeakRandomAPI> Ptr;
|
||||
};
|
||||
|
||||
} // namespace openvpn
|
||||
|
||||
@@ -307,7 +307,7 @@ class ProtoContext
|
||||
// Random number generator.
|
||||
// Use-cases demand highest cryptographic strength
|
||||
// such as key generation.
|
||||
RandomAPI::Ptr rng;
|
||||
StrongRandomAPI::Ptr rng;
|
||||
|
||||
// Pseudo-random number generator.
|
||||
// Use-cases demand cryptographic strength
|
||||
@@ -3768,7 +3768,7 @@ class ProtoContext
|
||||
if (cookie_psid.defined())
|
||||
psid_self = cookie_psid;
|
||||
else
|
||||
psid_self.randomize(*c.prng);
|
||||
psid_self.randomize(*c.rng);
|
||||
psid_peer.reset();
|
||||
|
||||
// initialize key contexts
|
||||
|
||||
@@ -59,11 +59,9 @@ class ProtoSessionID
|
||||
defined_ = true;
|
||||
}
|
||||
|
||||
template <typename PRNG_TYPE>
|
||||
void randomize(PRNG_TYPE &prng)
|
||||
void randomize(StrongRandomAPI &rng)
|
||||
{
|
||||
prng.assert_crypto();
|
||||
prng.rand_bytes(id_, SIZE);
|
||||
rng.rand_bytes(id_, SIZE);
|
||||
defined_ = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -264,7 +264,7 @@ class PsidCookieImpl : public PsidCookie
|
||||
// key must be common to all threads
|
||||
static StaticKey create_key()
|
||||
{
|
||||
RandomAPI::Ptr rng(new SSLLib::RandomAPI(false));
|
||||
StrongRandomAPI::Ptr rng(new SSLLib::RandomAPI(false));
|
||||
const CryptoAlgs::Alg &alg = CryptoAlgs::get(digest_);
|
||||
|
||||
// guarantee that the key is large enough
|
||||
|
||||
@@ -130,9 +130,8 @@ class TLSSessionTicketBase
|
||||
static constexpr size_t CIPHER_KEY_SIZE = 32;
|
||||
static constexpr size_t HMAC_KEY_SIZE = 16;
|
||||
|
||||
explicit Key(RandomAPI &rng)
|
||||
explicit Key(StrongRandomAPI &rng)
|
||||
{
|
||||
rng.assert_crypto();
|
||||
rng.rand_bytes(cipher_value_, CIPHER_KEY_SIZE);
|
||||
rng.rand_bytes(hmac_value_, HMAC_KEY_SIZE);
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ class SSLConfigAPI : public RC<thread_unsafe_refcount>
|
||||
virtual void set_tls_cert_profile_override(const std::string &override) = 0;
|
||||
virtual void set_local_cert_enabled(const bool v) = 0;
|
||||
virtual void set_x509_track(X509Track::ConfigSet x509_track_config_arg) = 0;
|
||||
virtual void set_rng(const RandomAPI::Ptr &rng_arg) = 0;
|
||||
virtual void set_rng(const StrongRandomAPI::Ptr &rng_arg) = 0;
|
||||
virtual void load(const OptionList &opt, const unsigned int lflags) = 0;
|
||||
|
||||
#ifdef OPENVPN_JSON_INTERNAL
|
||||
|
||||
@@ -55,9 +55,8 @@ class TLSPRF
|
||||
{
|
||||
}
|
||||
|
||||
void randomize(RandomAPI &rng)
|
||||
void randomize(StrongRandomAPI &rng)
|
||||
{
|
||||
rng.assert_crypto();
|
||||
if (!server_)
|
||||
rng.rand_bytes(pre_master, sizeof(pre_master));
|
||||
rng.rand_bytes(random1, sizeof(random1));
|
||||
@@ -234,7 +233,7 @@ class TLSPRFInstance : public RC<thread_unsafe_refcount>
|
||||
public:
|
||||
typedef RCPtr<TLSPRFInstance> Ptr;
|
||||
|
||||
virtual void self_randomize(RandomAPI &rng) = 0;
|
||||
virtual void self_randomize(StrongRandomAPI &rng) = 0;
|
||||
virtual void self_write(Buffer &buf) = 0;
|
||||
virtual void peer_read(Buffer &buf) = 0;
|
||||
virtual bool peer_read_complete(BufferComplete &bc) = 0;
|
||||
@@ -267,7 +266,7 @@ class CryptoTLSPRFInstance : public TLSPRFInstance
|
||||
{
|
||||
}
|
||||
|
||||
virtual void self_randomize(RandomAPI &rng)
|
||||
virtual void self_randomize(StrongRandomAPI &rng)
|
||||
{
|
||||
self.randomize(rng);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ struct AltProxy : public RC<thread_unsafe_refcount>
|
||||
Frame::Ptr frame;
|
||||
SessionStats::Ptr stats;
|
||||
|
||||
RandomAPI::Ptr rng;
|
||||
StrongRandomAPI::Ptr rng;
|
||||
DigestFactory::Ptr digest_factory;
|
||||
|
||||
SocketProtect *socket_protect;
|
||||
|
||||
@@ -219,7 +219,7 @@ class ClientConfig : public TransportClientFactory
|
||||
|
||||
Options::Ptr http_proxy_options;
|
||||
|
||||
RandomAPI::Ptr rng; // random data source
|
||||
StrongRandomAPI::Ptr rng; // random data source
|
||||
|
||||
DigestFactory::Ptr digest_factory; // needed by proxy auth methods
|
||||
|
||||
@@ -733,7 +733,6 @@ class Client : public TransportClient, AsyncResolvableTCP
|
||||
|
||||
// generate a client nonce
|
||||
unsigned char cnonce_raw[8];
|
||||
config->rng->assert_crypto();
|
||||
config->rng->rand_bytes(cnonce_raw, sizeof(cnonce_raw));
|
||||
const std::string cnonce = render_hex(cnonce_raw, sizeof(cnonce_raw));
|
||||
|
||||
|
||||
@@ -197,11 +197,9 @@ class Status
|
||||
class Sender
|
||||
{
|
||||
public:
|
||||
Sender(RandomAPI::Ptr cli_rng_arg) // only provide rng on client side
|
||||
Sender(StrongRandomAPI::Ptr cli_rng_arg) // only provide rng on client side
|
||||
: cli_rng(std::move(cli_rng_arg))
|
||||
{
|
||||
if (cli_rng)
|
||||
cli_rng->assert_crypto();
|
||||
}
|
||||
|
||||
void frame(Buffer &buf, const Status &s) const
|
||||
@@ -254,7 +252,7 @@ class Sender
|
||||
buf.prepend(&len8, sizeof(len8));
|
||||
}
|
||||
|
||||
RandomAPI::Ptr cli_rng;
|
||||
StrongRandomAPI::Ptr cli_rng;
|
||||
};
|
||||
|
||||
class Receiver
|
||||
@@ -434,7 +432,7 @@ struct Config : public RC<thread_unsafe_refcount>
|
||||
|
||||
std::string origin;
|
||||
std::string protocol;
|
||||
RandomAPI::Ptr rng;
|
||||
StrongRandomAPI::Ptr rng;
|
||||
DigestFactory::Ptr digest_factory;
|
||||
|
||||
// compression
|
||||
@@ -483,7 +481,6 @@ class PerRequest : public RC<thread_unsafe_refcount>
|
||||
{
|
||||
if (!conf)
|
||||
throw websocket_error("no config");
|
||||
conf->rng->assert_crypto();
|
||||
if (!conf->digest_factory)
|
||||
throw websocket_error("no digest factory in config");
|
||||
return conf;
|
||||
@@ -521,7 +518,7 @@ class PerRequest : public RC<thread_unsafe_refcount>
|
||||
|
||||
PerRequest(Config::Ptr conf_arg)
|
||||
: conf(validate_conf(std::move(conf_arg))),
|
||||
sender(RandomAPI::Ptr()),
|
||||
sender(StrongRandomAPI::Ptr()),
|
||||
receiver(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -658,7 +658,6 @@ class Client : public ClientBase
|
||||
if (!self->rng)
|
||||
{
|
||||
self->rng.reset(new SSLLib::RandomAPI(false));
|
||||
self->rng->assert_crypto();
|
||||
}
|
||||
return self->rng->rand_bytes_noexcept(data, len) ? 0 : -1; // using -1 as a general-purpose mbed TLS error code
|
||||
}
|
||||
@@ -708,7 +707,7 @@ class Client : public ClientBase
|
||||
|
||||
std::mutex log_mutex;
|
||||
std::string dc_cookie;
|
||||
RandomAPI::Ptr rng; // random data source for epki
|
||||
StrongRandomAPI::Ptr rng; // random data source for epki
|
||||
volatile ClockTickAction clock_tick_action = CT_UNDEF;
|
||||
|
||||
#ifdef OPENVPN_REMOTE_OVERRIDE
|
||||
|
||||
@@ -339,7 +339,7 @@ class FakeAsyncResolvable : public RESOLVABLE
|
||||
* its maximum range is [0x03020100, 0xfffefdfc]. Especially the lower
|
||||
* bound makes the std::shuffle implementation in libc++ loop endlessly.
|
||||
*/
|
||||
class FakeSecureRand : public openvpn::RandomAPI
|
||||
class FakeSecureRand : public openvpn::StrongRandomAPI
|
||||
{
|
||||
public:
|
||||
FakeSecureRand(const unsigned char initial = 0)
|
||||
@@ -352,11 +352,6 @@ class FakeSecureRand : public openvpn::RandomAPI
|
||||
return "FakeRNG";
|
||||
}
|
||||
|
||||
virtual bool is_crypto() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void rand_bytes(unsigned char *buf, size_t size) override
|
||||
{
|
||||
rand_bytes_(buf, size);
|
||||
|
||||
@@ -85,6 +85,7 @@ class PsidCookieTest : public testing::Test
|
||||
pcfg->now = &now;
|
||||
pcfg->handshake_window = Time::Duration::seconds(60);
|
||||
pcfg->key_direction = 0;
|
||||
pcfg->rng.reset(new SSLLib::RandomAPI(false));
|
||||
pcfg->prng.reset(new SSLLib::RandomAPI(true));
|
||||
|
||||
spf.reset(new ServerProto::Factory(dummy_io_context, *pcfg));
|
||||
@@ -141,7 +142,7 @@ TEST_F(PsidCookieTest, valid_time)
|
||||
uint64_t interval = (pci_dut.pcfg_.handshake_window.raw() + 1) / 2;
|
||||
bool hmac_ok;
|
||||
|
||||
cli_psid.randomize(*pci_dut.pcfg_.prng);
|
||||
cli_psid.randomize(*pci_dut.pcfg_.rng);
|
||||
|
||||
set_clock(Time::now());
|
||||
srv_psid = pci_dut.calculate_session_id_hmac(cli_psid, cli_addr, 0);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
using namespace openvpn;
|
||||
|
||||
template <typename IntegralT>
|
||||
class IntegralMin : public RandomAPI
|
||||
class IntegralMin : public WeakRandomAPI
|
||||
{
|
||||
public:
|
||||
OPENVPN_EXCEPTION(s_min_error);
|
||||
@@ -19,12 +19,6 @@ class IntegralMin : public RandomAPI
|
||||
return "IntegralMin";
|
||||
}
|
||||
|
||||
// Return true if algorithm is crypto-strength
|
||||
bool is_crypto() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fill buffer with minimum value
|
||||
void rand_bytes(unsigned char *buf, size_t size) override
|
||||
{
|
||||
|
||||
@@ -118,7 +118,7 @@ struct SessionID : public SessionID128
|
||||
}
|
||||
|
||||
SessionID(RandomAPI &rng)
|
||||
: SessionID128(rng, true)
|
||||
: SessionID128(rng)
|
||||
{
|
||||
// dump("rng");
|
||||
}
|
||||
@@ -184,7 +184,7 @@ static void tryit(RandomAPI &rng, TokenEncryptDecrypt &encdec)
|
||||
|
||||
TEST(sessid, tokenEncrypt)
|
||||
{
|
||||
RandomAPI::Ptr rng(new SSLLib::RandomAPI(false));
|
||||
StrongRandomAPI::Ptr rng(new SSLLib::RandomAPI(false));
|
||||
const TokenEncrypt::Key key(*rng);
|
||||
TokenEncryptDecrypt encdec(key);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ TEST(ssl, sslciphersuites)
|
||||
|
||||
TEST(ssl, sslciphers)
|
||||
{
|
||||
RandomAPI::Ptr rng(new FakeSecureRand);
|
||||
StrongRandomAPI::Ptr rng(new FakeSecureRand);
|
||||
|
||||
bool previousLogOutput = testLog->isStdoutEnabled();
|
||||
testLog->setPrintOutput(false);
|
||||
@@ -71,7 +71,7 @@ TEST(ssl, sslciphers)
|
||||
|
||||
TEST(ssl, tls_groups)
|
||||
{
|
||||
RandomAPI::Ptr rng(new FakeSecureRand);
|
||||
StrongRandomAPI::Ptr rng(new FakeSecureRand);
|
||||
|
||||
SSLFactoryAPI::Ptr sslfact;
|
||||
|
||||
@@ -116,7 +116,7 @@ TEST(ssl, translate_ciphers_openssl)
|
||||
#if defined(USE_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
TEST(ssl, enablelegacyProvider)
|
||||
{
|
||||
RandomAPI::Ptr rng(new FakeSecureRand);
|
||||
StrongRandomAPI::Ptr rng(new FakeSecureRand);
|
||||
|
||||
SSLLib::SSLAPI::Config::Ptr sslcfg(new SSLLib::SSLAPI::Config);
|
||||
sslcfg->set_local_cert_enabled(false);
|
||||
|
||||
@@ -37,7 +37,7 @@ TEST(statickey, key1)
|
||||
|
||||
TEST(statickey, key2)
|
||||
{
|
||||
RandomAPI::Ptr rng(new SSLLib::RandomAPI(false));
|
||||
StrongRandomAPI::Ptr rng(new SSLLib::RandomAPI(false));
|
||||
const size_t key_len = 16;
|
||||
StaticKey sk1;
|
||||
sk1.init_from_rng(*rng, key_len);
|
||||
|
||||
Reference in New Issue
Block a user