Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 77 additions & 11 deletions src/jrd/CryptoManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ namespace Jrd {

// tdbb w/o attachment comes when database is shutting down in the end of detachDatabase()
// the only needed here page is header, i.e. we can live w/o cryptPlugin
if ((crypt || process) && (!cryptPlugin) && tdbb->getAttachment())
if ((crypt || process) && tdbb->getAttachment())
{
ClumpletWriter hc(ClumpletWriter::UnTagged, hdr->hdr_page_size);
hdr.getClumplets(hc);
Expand All @@ -377,18 +377,55 @@ namespace Jrd {
else
keyName = "";

loadPlugin(tdbb, hdr->hdr_crypt_plugin);

string valid;
calcValidation(valid, cryptPlugin);
if (hc.find(Ods::HDR_crypt_hash))
if (!cryptPlugin)
{
hc.getString(hash);
if (hash != valid)
(Arg::Gds(isc_bad_crypt_key) << keyName).raise();
loadPlugin(tdbb, hdr->hdr_crypt_plugin);
string valid;
calcValidation(valid, cryptPlugin);
if (hc.find(Ods::HDR_crypt_hash))
{
hc.getString(hash);
if (hash != valid)
(Arg::Gds(isc_bad_crypt_key) << keyName).raise();
}
else
hash = valid;
}
else
hash = valid;
{
for (GetPlugins<IKeyHolderPlugin> keyControl(IPluginManager::TYPE_KEY_HOLDER, dbb.dbb_config);
keyControl.hasData(); keyControl.next())
{
// check does keyHolder want to provide a key for us
IKeyHolderPlugin* keyHolder = keyControl.plugin();

FbLocalStatus st;
int keyCallbackRc = keyHolder->keyCallback(&st, tdbb->getAttachment()->att_crypt_callback);
st.check();
if (!keyCallbackRc)
continue;

// validate a key
AutoPlugin<IDbCryptPlugin> crypt(checkFactory->makeInstance());
setDbInfo(crypt);
crypt->setKey(&st, 1, &keyHolder, keyName.c_str());


string valid;
calcValidation(valid, crypt);
if (hc.find(Ods::HDR_crypt_hash))
{
hc.getString(hash);
if (hash == valid)
{
// unload old plugin and set new one
PluginManagerInterfacePtr()->releasePlugin(cryptPlugin);
cryptPlugin = NULL;
cryptPlugin = crypt.release();
}
}
}
}
}

if (cryptPlugin && (flags & CRYPT_HDR_INIT))
Expand Down Expand Up @@ -495,7 +532,7 @@ namespace Jrd {
checkFactory = NULL;

// store new one
if (dbb.dbb_config->getServerMode() == MODE_SUPER && !holderLess)
if (!holderLess)
checkFactory = cryptControl.release();
}

Expand Down Expand Up @@ -670,7 +707,36 @@ namespace Jrd {
}
}
else
{
for (GetPlugins<IKeyHolderPlugin> keyControl(IPluginManager::TYPE_KEY_HOLDER, dbb.dbb_config);
keyControl.hasData(); keyControl.next())
{
// check does keyHolder want to provide a key for us
IKeyHolderPlugin* keyHolder = keyControl.plugin();

FbLocalStatus st;
int keyCallbackRc = keyHolder->keyCallback(&st, tdbb->getAttachment()->att_crypt_callback);
st.check();
if (!keyCallbackRc)
continue;

// validate a key
AutoPlugin<IDbCryptPlugin> crypt(checkFactory->makeInstance());
setDbInfo(crypt);
crypt->setKey(&st, 1, &keyHolder, keyName.c_str());


string valid;
calcValidation(valid, crypt);
if (hc.find(Ods::HDR_crypt_hash))
{
hc.getString(hash);
if (hash != valid)
(Arg::Gds(isc_bad_crypt_key) << keyName).raise();
}
}
header->hdr_flags &= ~Ods::hdr_encrypted;
}

hdr.setClumplets(hc);

Expand Down