Product Documentation

FairCom Callbacks Tutorials

Previous Topic

Next Topic

Master Key Library Tutorial

drivers/ctree.callbacks/encrypted.data.masterkey/bin/libmaskeylib.so

FairCom DB provides advanced AES encryption at rest when enabled. Encryption requires defining a master key which should be kept as secure as possible. The master key must be presented at FairCom DB startup allowing access to encrypted data. A challenge is in securely presenting this key to a server for the best of unattended operation. FairCom DB includes functionality to make this as flexible as possible. One method is storing keys in an external mechanism such as Amazon AWS Secrets Manager.® However, application providers may want direct control over key management. FairCom DB provides a callback mechanism allowing access to any external key store as defined by the application vendor.

With the FairCom DB PRO SDK you can implement a custom way to retrieve the Advanced Encryption master key at server startup, see Advanced Encryption Configuration. This document describes how to write a generic master key library functionality.

How to Configure

To use this feature, the server must have Advanced Encryption turned on. To do that, follow the steps shown on Advanced Data Encryption before launching the FairCom DB server. Here is a summary:

  1. Generate a master password file by using the following command:

    tools/ctcpvf -s

    This will prompt you to type in a master password of your choosing. Copy the resulting ctsrvr.pvf file in the server folder.

  2. Add the following line to the configuration file:

    ADVANCED_ENCRYPTION YES

  3. If needed, update the FAIRCOM.FCS file as discussed in Enabling Advanced Encryption Support.

To instruct the server to call the custom library rather than using the regular prompt to obtain the master key, you need to add the MASTER_KEY_LIB configuration keyword to ctsrvr.cfg.

As a parameter, MASTER_KEY_LIB takes a string value indicating the library to be loaded to return the master key.

Windows:

MASTER_KEY_LIB masterkeylib.dll

Linux/Unix:

MASTER_KEY_LIB libmasterkey.so

Note: 64-bit servers require a 64-bit shared library and 32-bit servers require a 32-bit shared library. The servers and libraries cannot be mixed and matched.

How to Build It

To build and hook up the password key plug-in file (both Windows and Linux):

  1. Open drivers\ctree.callbacks\encrypted.data.masterkey\src\maskeylib.c with a text editor.
  2. Find the following line in the file and change ADMIN to the master password you specified with the ctcpvf tool.

    char myKey[] = "ADMIN";

  3. Save your changes.

Now perform additional steps for Windows or Linux:

The following steps are for Windows only:

  1. Open Visual Studio developer command prompt.
  2. Change directories:

    cd drivers\ctree.callbacks\encrypted.data.masterkey

  3. Execute BuildCallback.bat.

    This creates a DLL in the bin folder:

    drivers\ctree.callbacks\encrypted.data.masterkey\bin\maskeylib.dll

  4. Copy this DLL into the FairCom server folder.
  5. Verify that the following line is in your ctsrvr.cfg file:

    MASTER_KEY_LIB maskeylib.dll

The following steps are for Linux only:

  1. Open a shell prompt.
  2. Change directories:

    cd drivers/ctree.callbacks/encrypted.data.masterkey

  3. Execute make.

    This creates a shared library file in the bin folder:

    drivers/ctree.callbacks/encrypted.data.masterkey/bin/libmaskeylib.so

  4. Copy this library file into the FairCom server folder.
  5. Verify that the following line is in your ctsrvr.cfg file:

    MASTER_KEY_LIB libmaskeylib.so

At this point, you should be able to start the FairCom server, using one of the methods described in How to Start the Server, and the server should start without asking for the master password. If the server does not start, check the CTSTATUS.FCS log file for error messages.

Note that this is just a simple tutorial which shows how to hook up and use a library to provide the master password to the FairCom server at server start-up time. To properly (and safely!) configure your FairCom server for Advanced Encryption, follow the procedures in Advanced Data Encryption.

Master Key Library Information

The master key library is a shared library that must export at least the following two functions:

int ctGetSecretVersion(void)

int ctGetSecret(ctGetSecretParams_t * GetSecretParams)

If the server is properly configured at startup, it loads the specified library and first checks if the master key library SDK version is compatible with the server by calling ctGetSecretVersion(). It then obtains the master key by calling ctGetSecret().

If the version is compatible and ctGetSecret() returns with a value of 0, the master key passed back in the GetSecretParams struct is evaluated. If it matches with the master key stored in the server ctsrvr.pvf file, the server starts up correctly, otherwise the server is stopped with error BMPW_ERR (932).

To prevent malicious users from writing a simple program that calls ctGetSecret() to obtain the advanced encryption master key before sending back the master key to the server, the master key must be encrypted by calling the master key library SDK function ctSecureMasterKey(). This function encrypts the master key in a fashion that only the requesting server is able to decipher: the encryption and decryption features are implemented using OpenSSL features.

How to Implement Your Custom Master Key Library

To ease the process of writing a custom master key library, FairCom provides a simple SDK to write your library. The SDK is composed of two files:

  • ctmsklib.c (in the source area of your c-tree package)
  • ctmsklib.h (in the include area of your c-tree package)

ctmsklib.c contains the logic to encrypt the master key and must be part of your library. ctmsklib.h contains all the required definitions and includes, ctmsklib.h must be included in your library implementation.

Your master key library implementation must implement two functions defined as:

CTMASLIB_DLL_EXPORT int ctGetSecretVersion(void)

CTMASLIB_DLL_EXPORT int ctGetSecret(ctGetSecretParams_t * GetSecretParams)

Your master key library must also be linked with the OpenSSL libraries provided in the c-tree License.Lib area to resolve the OpenSSL encryption calls.

Function Descriptions

ctGetSecretVersion

CTMASLIB_DLL_EXPORT int ctGetSecretVersion(void)

This function is expected to return only the version of the master key library as defined in ctmsklib.h. For example:

CTMASLIB_DLL_EXPORT int ctGetSecretVersion(void)

{

return(GET_SECRET_PARAMS_VER1);

}

ctGetSecret

CTMASLIB_DLL_EXPORT int ctGetSecret(ctGetSecretParams_t * GetSecretParams)

This function is the one expected to return the master key as a member of the _ctGetSecretParams_t structure received from the server.

The _ctGetSecretParams_t structure is defined as follows:

typedef struct _ctGetSecretParams_t {

int Version; /* [IN] version of this structure */

char SaltValue[GET_SECRET_SALT_LENGTH]; /* [IN] salt value */

char *OutputBuffer; /* [OUT] output buffer */

size_t OutputBufferLength; /* [IN] size of output buffer */

char *ErrorBuffer; /* [OUT] optional error buffer */

size_t ErrorBufferLength; /* [IN] size of the optional error buffer */

} ctGetSecretParams_t;

Particularly the master key must be returned in the OutputBuffer member.

Please note that for security reasons the contents of OutputBuffer must be encrypted by using the ctSecureMasterKey() function described later.

The second member of this structure, SaltValue sent by the server, must be passed to the ctSecureMasterKey() function to be used during the encryption of the master key.

Please also note that an error buffer is passed where a textual error can be stored to be written in CTSTATUS.FCS in case ctGetSecret() returns a value different than 0.

As discussed above, if the ctGetSecret() returns a value different than 0 the server will not continue the evaluation of the master key and will shut down.

An example of ctGetSecret() can be found in the maskeylib.c file of your FairCom DB package.

CTMASLIB_DLL_EXPORT int ctGetSecret(ctGetSecretParams_t * GetSecretParams)

{

int returnValue;

ctSecureMasterKeyParams_t SecureMasterKeyParams;

char myKey[] = "ADMIN";

memset(&SecureMasterKeyParams, 0, sizeof(SecureMasterKeyParams));

SecureMasterKeyParams.MasterKey = myKey;

memcpy(SecureMasterKeyParams.SaltValue, GetSecretParams->SaltValue, sizeof(SecureMasterKeyParams.SaltValue));

SecureMasterKeyParams.OutputBufferLength = GetSecretParams->OutputBufferLength;

SecureMasterKeyParams.OutputBuffer = GetSecretParams->OutputBuffer;

if (GetSecretParams->ErrorBuffer != NULL && GetSecretParams->ErrorBufferLength > 0)

{

SecureMasterKeyParams.ErrorBuffer = GetSecretParams->ErrorBuffer;

SecureMasterKeyParams.ErrorBufferLength = GetSecretParams->ErrorBufferLength;

}

returnValue = ctSecureMasterKey(&SecureMasterKeyParams);

return(returnValue);

}

Note how the SaltValue is passed to ctSecureMasterKey() using the proper structure.

int ctSecureMasterKey(ctSecureMasterKeyParams_t *SecureMasterKeyParams)

This function is already implemented in ctmsklib.c and must be compiled within your master key library to provide the required encryption methods.

The call to this function to encrypt the master key is mandatory because the server always expects the master key encrypted. If a clear text master key is passed, the decryption will fail and the server will shut down.

The ctSecureMasterKey function takes a ctSecureMasterKeyParams_t structure as only parameter. This structure is defined as follows:

typedef struct _ctSecureMasterKeyParams_t {

char *MasterKey; /* [IN] the master key as a null-terminated string */

char SaltValue[GET_SECRET_SALT_LENGTH]; /* [IN] salt value */

char *OutputBuffer; /* [OUT] output buffer */

size_t OutputBufferLength; /* [IN] size of output buffer */

char *ErrorBuffer; /* [OUT] optional error buffer */

size_t ErrorBufferLength; /* [IN] size of the optional error buffer */

} ctSecureMasterKeyParams_t;

Please note the first member which is your designated master key in clear text that needs to be encrypted to be passed back to the server.

To have an encryption that the server is able to complete the SaltValue must be the same received by the ctGetSecret() function.

Because ctSecureMasterKey() may write textual error messages in case the encryption fails it accepts an error buffer where these error messages are stored: ideally it could be worth to use the same record buffer as received by ctGetSecret() to be passed back to the server, however an arbitrary buffer defined in the master key library could be used.

How to Build the Master Key Library

Once the master key library logic is implemented it must be built by linking with the OpenSSL libraries provided by the c-tree package. You can use the makefiles provided in your c-tree package in the drivers\ctree.callbacks\encrypted.data.masterkey folder to build your maskeylib.c and to link it with the included OpenSSL libraries. See the makefile for details.

Note the output of the makefile will be placed in the drivers\ctree.callbacks\encrypted.data.masterkey\bin folder and will be called maskeylib.dll (.so on Linux/Unix platforms). Be sure to copy this shared library (.DLL or .so) into the server folder, so the FairCom server can locate the library as it starts up.

How to Use the Master Key Lib with Standalone Applications

To provide the master password to standalone applications (ctrdmp, ctfdmp) using the master key library (e.g.: to use ctrdmp to extract a backup containing encrypted files) the master key library can be pointed with the use of the environment variable CTREE_MASTER_KEY_LIB.

For example, when ctrdmp detects that the backup contains encrypted files, it asks for the master password to be verified with the server’s pvf file. If CTREE_MASTER_KEY_LIB is properly set and the indicated master key library is correctly loadable, the master key will be retrieved from the library.

TOCIndex