From 2df9f4f6d3288f8966ef9069dc92d1eee7b531d9 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Thu, 2 Feb 2017 17:05:46 +0300 Subject: [PATCH] Postfix (mostly comments & documentation) for core-5472 --- doc/Using_OO_API.html | 36 +++++++++++++++++------ examples/dbcrypt/CryptApplication.cpp | 6 ++++ examples/dbcrypt/ReadMe.txt | 41 +++++++++++++++++++++++++-- src/jrd/extds/IscDS.cpp | 26 +++++++++++------ 4 files changed, 89 insertions(+), 20 deletions(-) diff --git a/doc/Using_OO_API.html b/doc/Using_OO_API.html index ce36b2e0095..2c01816baf8 100644 --- a/doc/Using_OO_API.html +++ b/doc/Using_OO_API.html @@ -5,8 +5,10 @@ - - + + + + @@ -3161,8 +3163,7 @@

Database encryption when network access to the server is used. All this job should be done in plugin (and application working with it) i.e. database block encryption algorithm by itself may happen to be easiest part of db -crypt plugin, specially -when some standard library is used for it.

+crypt plugin, specially when some standard library is used for it.


@@ -3180,6 +3181,19 @@

Database encryption


+

+

DbCryptInfo +interface is passed to DbCryptPlugin by engine. Plugin may save this +interface and use when needed to obtain additional informatio about +database.

+
    +
  1. +

    const + char* getDatabaseFullPath(StatusType* status) – returns full + (including path) name of primary database file.

    +
+


+

DbCryptPlugin interface is main interface of database crypt plugin.

@@ -3202,6 +3216,10 @@

Database encryption

void decrypt(StatusType* status, unsigned length, const void* from, void* to) – decrypts data after reading block from database file.

+
  • +

    void + setInfo(StatusType* status, IDbCryptInfo* info) – in this method + crypt plugin typically saves informational interface for future use.


    @@ -3251,11 +3269,11 @@

    Key holder for database letting it to work with database.

  • ICryptKeyCallback* - chainHandle(StatusType* status) – support of a chain of key holders. In - some cases key has to pass through more than single key holder - before it reaches db crypt plugin. This is needed (for example) to - support execute statement in encrypted database. This is just a - sample – chains are also used in some other cases. Callback + chainHandle(StatusType* status) – support of a chain of key + holders. In some cases key has to pass through more than single key + holder before it reaches db crypt plugin. This is needed (for + example) to support execute statement in encrypted database. This is + just a sample – chains are also used in some other cases. Callback interface, returned by this method, may differ from one returned by keyHandle() function (see above). Typically is should be able to duplicate one-to-one keys, received by KeyHolderPlugin when diff --git a/examples/dbcrypt/CryptApplication.cpp b/examples/dbcrypt/CryptApplication.cpp index 16fff91c83c..ad6d385e65f 100644 --- a/examples/dbcrypt/CryptApplication.cpp +++ b/examples/dbcrypt/CryptApplication.cpp @@ -81,6 +81,12 @@ class App } enum Action {NONE, ENC, DEC, EX_LCL, EX_RMT}; + // Switches/actions have the following meanings: + // ENC(-e) - encrypt database + // DEC(-d) - decrypt database + // EX_LCL(-l) - execute some predefined select command (demonstrates that database can respond to select request) + // EX_RMT(-r) - execute select using execute statement in remote datasource (demonstrates that dbcrypt key is + // passed to target database when using execute statement) void execute(const char* dbName, const Action a) { diff --git a/examples/dbcrypt/ReadMe.txt b/examples/dbcrypt/ReadMe.txt index c6c3deeadee..90ad08f808d 100644 --- a/examples/dbcrypt/ReadMe.txt +++ b/examples/dbcrypt/ReadMe.txt @@ -1,2 +1,39 @@ -All files in this directory are trivial samples. -They do not perform any real data encryption and should not be used in production! +************************************************************************************** +* All files in this directory are trivial samples. * +* They do not perform any real data encryption and should not be used in production! * +************************************************************************************** + +Brief description of the sample. + +Sample contains 3 components - DbCrypt plugin, KeyHolder plugin and application, which can pass +crypt key to server. Plugins do not perform any real encryption (XOR with single byte hardly can +be treated as encryption though makes database useless without crypt plugin), key is sent between +components in plain form - they just demonstrate what calls in plugins should be done and what +methods should be implemented in order for plugin to start to work. + +Depending upon settings in configuration file plugins may use different ways to manage encryption +key. DbCrypt's configuration file may contain following parameters: +Auto - boolean value, when FALSE plugin queries KeyHolder plugin for key value (this is default), + when TRUE get key value from "Value" configuration parameter. +Value - integer value (lower byte is actually used), used in "Auto" mode as key value (default 90). + +CryptKeyHolder's configuration file may contain following parameters: +Auto - boolean value, when FALSE plugin queries client application for key value (this is default), + when TRUE get key value from configuration file by name or use default (90) for unnamed key. +Key{Name} - integer value, a key with name "Name" (i.e. when one issues "ALTER DATABASE ENCRYPT ... + KEY Doggy" configuration parameter KeyDoggy should be present). +OnlyOwnKey - boolean value, enables/disables use of a key from another key holder in SuperServer. + Default value is TRUE (i.e. only key, owned by this KeyHolder, can be used by related + attachment). + +Crypt application has a few parameters making it possible to demonstrate different operations. +-e - Encrypt database (use gstat to monitor crypt progress). +-d - Decrypt database. +-l - Locally execute SELECT statement returning name of currently attached user. +-r - Execute same statement using remote datasource 'localhost:employee'. To make it work + user "test" with password "test" should be created in employee database. If employee was + encrypted in advance this demonstrates passing database crypt key through the chain of + key holders. + +cryptDb.pas is a minimum (XOR using fixed key hardcoded in plugin body) sample of database crypt +plugin written on Pascal. Was tested with both FreePascal and Delphi. diff --git a/src/jrd/extds/IscDS.cpp b/src/jrd/extds/IscDS.cpp index b98bc170ac9..b1b9e73d114 100644 --- a/src/jrd/extds/IscDS.cpp +++ b/src/jrd/extds/IscDS.cpp @@ -126,16 +126,24 @@ void IscConnection::attach(thread_db* tdbb, const PathName& dbName, const MetaNa EngineCallbackGuard guard(tdbb, *this, FB_FUNCTION); ICryptKeyCallback* cb = tdbb->getAttachment()->att_crypt_callback; - m_iscProvider.fb_database_crypt_callback(&status, cb); - if (status->getState() & IStatus::STATE_ERRORS) { - raise(&status, tdbb, "crypt_callback"); - } + try + { + m_iscProvider.fb_database_crypt_callback(&status, cb); + if (status->getState() & IStatus::STATE_ERRORS) { + raise(&status, tdbb, "crypt_callback"); + } - m_iscProvider.isc_attach_database(&status, m_dbName.length(), m_dbName.c_str(), - &m_handle, newDpb.getBufferLength(), - reinterpret_cast(newDpb.getBuffer())); - if (status->getState() & IStatus::STATE_ERRORS) { - raise(&status, tdbb, "attach"); + m_iscProvider.isc_attach_database(&status, m_dbName.length(), m_dbName.c_str(), + &m_handle, newDpb.getBufferLength(), + reinterpret_cast(newDpb.getBuffer())); + if (status->getState() & IStatus::STATE_ERRORS) { + raise(&status, tdbb, "attach"); + } + } + catch(const Exception&) + { + m_iscProvider.fb_database_crypt_callback(&status, NULL); + throw; } m_iscProvider.fb_database_crypt_callback(&status, NULL);