mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 09:20:39 +01:00
Postfix for #7065: Connection hangs after delivery of 256 Gb; reworked according to java requirements
This commit is contained in:
parent
98e1f406ca
commit
c7f10bf221
@ -514,14 +514,14 @@
|
||||
#TracePlugin = fbtrace
|
||||
|
||||
# Wire crypt plugins are used to crypt data transferred over the wire.
|
||||
# In default case wire is encrypted using ChaCha#20 or Alleged RC4.
|
||||
# Key must be generated by auth plugin.
|
||||
# In default case wire is encrypted using ChaCha#20 (32/64 bit counter variants)
|
||||
# or Alleged RC4. Key must be generated by auth plugin.
|
||||
# For chacha we are using 16 or 32 bytes key (depends upon what is provided
|
||||
# by auth plugin), 12 bytes nonce and 4 bytes counter, 20 (10 + 10) rounds are made.
|
||||
# by auth plugin), 12 (8) bytes nonce and 4 (8) bytes counter, 20 (10 + 10) rounds are made.
|
||||
#
|
||||
# Per-connection configurable.
|
||||
#
|
||||
#WireCryptPlugin = ChaCha, Arc4
|
||||
#WireCryptPlugin = ChaCha64, ChaCha, Arc4
|
||||
|
||||
# Key holder is a kind of temp storage for DB crypt keys.
|
||||
# There is no default for this kind of plugins.
|
||||
|
@ -6,3 +6,7 @@ Plugin = UDR {
|
||||
Config = UDR_config {
|
||||
path = $(dir_plugins)/udr
|
||||
}
|
||||
|
||||
Plugin = ChaCha64 {
|
||||
Module = $(dir_plugins)/ChaCha
|
||||
}
|
||||
|
@ -275,7 +275,7 @@ constexpr ConfigEntry entries[MAX_CONFIG_KEY] =
|
||||
{TYPE_STRING, "SecurityDatabase", false, nullptr}, // sec/db alias - rely on ConfigManager::getDefaultSecurityDb(
|
||||
{TYPE_STRING, "ServerMode", true, nullptr}, // actual value differs in boot/regular cases and set at setupDefaultConfig(
|
||||
{TYPE_STRING, "WireCrypt", false, nullptr},
|
||||
{TYPE_STRING, "WireCryptPlugin", false, "ChaCha, Arc4"},
|
||||
{TYPE_STRING, "WireCryptPlugin", false, "ChaCha64, ChaCha, Arc4"},
|
||||
{TYPE_STRING, "KeyHolderPlugin", false, ""},
|
||||
{TYPE_BOOLEAN, "RemoteAccess", false, true},
|
||||
{TYPE_BOOLEAN, "IPv6V6Only", false, false},
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include <tomcrypt.h>
|
||||
#include <../common/os/guid.h>
|
||||
|
||||
#include "../remote/remot_proto.h"
|
||||
|
||||
using namespace Firebird;
|
||||
|
||||
namespace
|
||||
@ -84,105 +86,94 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class ChaCha FB_FINAL : public StdPlugin<IWireCryptPluginImpl<ChaCha, CheckStatusWrapper> >
|
||||
template <unsigned IV_SIZE>
|
||||
class ChaCha FB_FINAL : public StdPlugin<IWireCryptPluginImpl<ChaCha<IV_SIZE>, CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
explicit ChaCha(IPluginConfig* cfg)
|
||||
: en(NULL), de(NULL), iv(getPool()), pluginConfig(cfg)
|
||||
{ }
|
||||
explicit ChaCha(IPluginConfig*)
|
||||
: en(NULL), de(NULL), iv(this->getPool())
|
||||
{
|
||||
if (IV_SIZE == 16)
|
||||
{
|
||||
GenerateRandomBytes(iv.getBuffer(16), 12);
|
||||
iv[12] = iv[13] = iv[14] = iv[15] = 0;
|
||||
}
|
||||
else
|
||||
GenerateRandomBytes(iv.getBuffer(8), 8);
|
||||
}
|
||||
|
||||
// ICryptPlugin implementation
|
||||
const char* getKnownTypes(CheckStatusWrapper* status);
|
||||
void setKey(CheckStatusWrapper* status, ICryptKey* key);
|
||||
void encrypt(CheckStatusWrapper* status, unsigned int length, const void* from, void* to);
|
||||
void decrypt(CheckStatusWrapper* status, unsigned int length, const void* from, void* to);
|
||||
const unsigned char* getSpecificData(CheckStatusWrapper* status, const char* type, unsigned* len);
|
||||
void setSpecificData(CheckStatusWrapper* status, const char* type, unsigned len, const unsigned char* data);
|
||||
const char* getKnownTypes(CheckStatusWrapper* status)
|
||||
{
|
||||
status->init();
|
||||
return "Symmetric";
|
||||
}
|
||||
|
||||
void setKey(CheckStatusWrapper* status, ICryptKey* key)
|
||||
{
|
||||
status->init();
|
||||
try
|
||||
{
|
||||
unsigned int l;
|
||||
const void* k = key->getEncryptKey(&l);
|
||||
en = createCypher(l, k);
|
||||
|
||||
k = key->getDecryptKey(&l);
|
||||
de = createCypher(l, k);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
}
|
||||
|
||||
void encrypt(CheckStatusWrapper* status, unsigned int length, const void* from, void* to)
|
||||
{
|
||||
status->init();
|
||||
en->transform(length, from, to);
|
||||
}
|
||||
|
||||
void decrypt(CheckStatusWrapper* status, unsigned int length, const void* from, void* to)
|
||||
{
|
||||
status->init();
|
||||
de->transform(length, from, to);
|
||||
}
|
||||
|
||||
const unsigned char* getSpecificData(CheckStatusWrapper* status, const char* type, unsigned* len)
|
||||
{
|
||||
*len = IV_SIZE;
|
||||
|
||||
WIRECRYPT_DEBUG(fprintf(stderr, "getSpecificData %d\n", *len));
|
||||
return iv.begin();
|
||||
}
|
||||
|
||||
void setSpecificData(CheckStatusWrapper* status, const char* type, unsigned len, const unsigned char* data)
|
||||
{
|
||||
WIRECRYPT_DEBUG(fprintf(stderr, "setSpecificData %d\n", len));
|
||||
memcpy(iv.getBuffer(len), data, len);
|
||||
}
|
||||
|
||||
private:
|
||||
Cipher* createCypher(unsigned int l, const void* key);
|
||||
Cipher* createCypher(unsigned int l, const void* key)
|
||||
{
|
||||
if (l < 16)
|
||||
(Arg::Gds(isc_random) << "Key too short").raise();
|
||||
|
||||
hash_state md;
|
||||
tomCheck(sha256_init(&md), "initializing sha256");
|
||||
tomCheck(sha256_process(&md, static_cast<const unsigned char*>(key), l), "processing original key in sha256");
|
||||
unsigned char stretched[32];
|
||||
tomCheck(sha256_done(&md, stretched), "getting stretched key from sha256");
|
||||
|
||||
return FB_NEW Cipher(stretched, iv.getCount(), iv.begin());
|
||||
}
|
||||
|
||||
AutoPtr<Cipher> en, de;
|
||||
UCharBuffer iv;
|
||||
RefPtr<IPluginConfig> pluginConfig;
|
||||
};
|
||||
|
||||
void ChaCha::setKey(CheckStatusWrapper* status, ICryptKey* key)
|
||||
{
|
||||
status->init();
|
||||
try
|
||||
{
|
||||
unsigned int l;
|
||||
const void* k = key->getEncryptKey(&l);
|
||||
en = createCypher(l, k);
|
||||
|
||||
k = key->getDecryptKey(&l);
|
||||
de = createCypher(l, k);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(status);
|
||||
}
|
||||
}
|
||||
|
||||
void ChaCha::encrypt(CheckStatusWrapper* status, unsigned int length, const void* from, void* to)
|
||||
{
|
||||
status->init();
|
||||
en->transform(length, from, to);
|
||||
}
|
||||
|
||||
void ChaCha::decrypt(CheckStatusWrapper* status, unsigned int length, const void* from, void* to)
|
||||
{
|
||||
status->init();
|
||||
de->transform(length, from, to);
|
||||
}
|
||||
|
||||
Cipher* ChaCha::createCypher(unsigned int l, const void* key)
|
||||
{
|
||||
if (l < 16)
|
||||
(Arg::Gds(isc_random) << "Key too short").raise();
|
||||
|
||||
hash_state md;
|
||||
tomCheck(sha256_init(&md), "initializing sha256");
|
||||
tomCheck(sha256_process(&md, static_cast<const unsigned char*>(key), l), "processing original key in sha256");
|
||||
unsigned char stretched[32];
|
||||
tomCheck(sha256_done(&md, stretched), "getting stretched key from sha256");
|
||||
|
||||
return FB_NEW Cipher(stretched, iv.getCount(), iv.begin());
|
||||
}
|
||||
|
||||
const char* ChaCha::getKnownTypes(CheckStatusWrapper* status)
|
||||
{
|
||||
status->init();
|
||||
return "Symmetric";
|
||||
}
|
||||
|
||||
const unsigned char* ChaCha::getSpecificData(CheckStatusWrapper* status, const char*, unsigned* len)
|
||||
{
|
||||
RefPtr<IConfig> config(pluginConfig->getDefaultConfig(status));
|
||||
check(status);
|
||||
RefPtr<IConfigEntry> entry(config->find(status, "CounterSize"));
|
||||
check(status);
|
||||
if (entry.hasData())
|
||||
*len = entry->getIntValue() == 64 ? 8 : 16;
|
||||
else
|
||||
*len = 16;
|
||||
|
||||
if (*len == 16)
|
||||
{
|
||||
GenerateRandomBytes(iv.getBuffer(16), 12);
|
||||
iv[12] = iv[13] = iv[14] = iv[15] = 0;
|
||||
}
|
||||
else
|
||||
GenerateRandomBytes(iv.getBuffer(8), 8);
|
||||
return iv.begin();
|
||||
}
|
||||
|
||||
void ChaCha::setSpecificData(CheckStatusWrapper* status, const char*, unsigned len, const unsigned char* data)
|
||||
{
|
||||
memcpy(iv.getBuffer(len), data, len);
|
||||
}
|
||||
|
||||
SimpleFactory<ChaCha> factory;
|
||||
SimpleFactory<ChaCha<16> > factory;
|
||||
SimpleFactory<ChaCha<8> > factory64;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
@ -190,5 +181,6 @@ extern "C" void FB_EXPORTED FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master)
|
||||
{
|
||||
CachedMasterInterface::set(master);
|
||||
PluginManagerInterfacePtr()->registerPluginFactory(IPluginManager::TYPE_WIRE_CRYPT, "ChaCha", &factory);
|
||||
PluginManagerInterfacePtr()->registerPluginFactory(IPluginManager::TYPE_WIRE_CRYPT, "ChaCha64", &factory64);
|
||||
getUnloadDetector()->registerMe();
|
||||
}
|
||||
|
@ -1215,12 +1215,15 @@ bool rem_port::tryKeyType(const KnownServerKey& srvKey, InternalCryptKey* cryptK
|
||||
for (unsigned n = 0; n < clientPlugins.getCount(); ++n)
|
||||
{
|
||||
Firebird::PathName p(clientPlugins[n]);
|
||||
WIRECRYPT_DEBUG(fprintf(stderr, "tryKeyType, client plugin %s\n", p.c_str()));
|
||||
if (srvKey.plugins.find(" " + p + " ") != Firebird::PathName::npos)
|
||||
{
|
||||
WIRECRYPT_DEBUG(fprintf(stderr, "tryKeyType, server listed plugin %s\n", p.c_str()));
|
||||
Firebird::GetPlugins<Firebird::IWireCryptPlugin>
|
||||
cp(Firebird::IPluginManager::TYPE_WIRE_CRYPT, p.c_str());
|
||||
if (cp.hasData())
|
||||
{
|
||||
WIRECRYPT_DEBUG(fprintf(stderr, "tryKeyType, client loaded plugin %s\n", p.c_str()));
|
||||
Firebird::LocalStatus st;
|
||||
Firebird::CheckStatusWrapper statusWrapper(&st);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user