Adding New Encryption Libraries to Distrix for Android
This document describes how to add support for a new encryption library to Distrix for the Android platform. Any encryption library that is to be interface to Distrix must support at least:
- The ability to use the library from C
- DTLS server and client modes
- Performing DTLS actions on memory buffers (i.e. not directly on a socket)
- One or more of the following three identification/authentication mechanisms:
- Pre-shared keys
- Public Key Infrastructure (PKI) keys and certificates stored in memory
- PKI keys and certificates stored in PEM format on the local filesystem
Here it is assumed that the target platform is Distrix running on Android and that the development is being done on Windows, however the source files and implementation process would be the same for all non-embedded platforms. The main difference between platforms is the build environment in which the code is compiled.
Encryption.h
Defines the API which DTLS/encryption libraries must comply with in order to be used by Distrix.
/**
* File: Encryption.h
* Defines the API which DTLS/encryption libraries must comply with in
* order to be used by Distrix.
**/
#ifndef COMMON_ENCRYPTION_ENCRYPTION_H
#define COMMON_ENCRYPTION_ENCRYPTION_H
#include "Distrix/Abstractions/Datatypes/BasicTypes.h"
#include "Distrix/Abstractions/Datatypes/Vector.h"
#include "Distrix/Abstractions/Datatypes/List.h"
#include "Distrix/Abstractions/Utils/Compiler/Export.h"
// Forward declarations
struct DX_Dataset;
struct DX_EncryptionData;
/**
* Structure: DX_Encryption
* The encryption interface into Distrix
**/
typedef struct DX_Encryption
{
/**
* Variable: m_data
* Pointer to arbitrary application-specific data; opaque to the
* encryption module implementation; initialized by Distrix
**/
void *m_data;
/**
* Callback: sendf
* The function to call to pass encrypted datasets to Distrix so that
* they can be sent; initialized by Distrix
*
* Parameters:
* p_encryption - The encryption instance that sendf() is being
* called on
* p_reliable - Whether the dataset is to be sent reliably or
* not
* p_dataset - The encrypted Distrix dataset to send
**/
void (*sendf)(struct DX_Encryption *p_encryption, int p_reliable, struct DX_Dataset *p_dataset);
/**
* Callback: onError
* The function to call to inform Distrix that an error has occured
* with the encrypted connection; initialized by Distrix
*
* Parameters:
* p_encryption - The encryption instance that onError() is being
* called on
* p_disconnected - Indicates if the connection has been disconnected as a
* result of the error
**/
void (*onError)(struct DX_Encryption *p_encryption, int p_disconnected);
/**
* Callback: onConnect
* The function to call to inform Distrix that an encrypted connection
* has been established; initialized by Distrix
*
* Parameters:
* p_encryption - The encryption instance that onConnect() is
* being called on
**/
void (*onConnect)(struct DX_Encryption *p_encryption);
/**
* Callback: onReceive
* The function to call to pass decrypted received datasets to
* Distrix; initialized by Distrix
*
* Parameters:
* p_encryption - The encryption instance that onReceive() is
* being called on
* p_decrypted - The decrypted data; this may or may not be a
* complete Distrix dataset depending on how much
* data was decrypted
* p_size - The size of the decrypted data
**/
void (*onReceive)(struct DX_Encryption *p_encryption, void *p_decrypted, uint32_t p_size);
/**
* Variable: m_sendBuffer
* Buffer for assembling the current outgoing encrypted dataset
**/
DX_Vector m_sendBuffer;
/**
* Variable: m_sendQueue
* Queue for outgoing encrypted datasets
**/
DX_List m_sendQueue;
/**
* Variable: m_timeout
* Absolute connection establishment timeout time in ms
**/
uint64_t m_timeout;
/**
* Variable: m_connected
* Flag indicating if the encrypted connection is currently
* established or not
**/
int m_connected;
/**
* Variable: m_error
* Flag indicating if an error has occured in the encrypted connection
* or not
**/
int m_error;
/**
* Variable: m_mutex
* A mutex instance used to protect accesses to the send queue and
* buffer
**/
void *m_mutex;
/**
* Variable: m_impl
* Implementation-specific data
**/
struct DX_EncryptionData *m_impl;
} DX_Encryption;
/**
* Structure: DX_Credential
* Base type representing a generic credential to be used for encryption;
* see , , and
* for the actual available implementations
**/
typedef struct DX_Credential
{
/**
* Variable: m_type
* One of the type values from
**/
int m_type;
// ... other fields as determined by m_type.
} DX_Credential;
/**
* Enumeration: DX_CredentialTypes
* The possible credential types, corresponding to the structures defined
* below
*
* Note:
* Not every type is supported by every implementation, but every
* implementation must support at least one type
**/
enum DX_CredentialTypes
{
e_DX_pskCredential,
e_DX_certCredential,
e_DX_certFileCredential
};
/**
* Structure: DX_PskCredential
* Represents a pre-shared key
**/
typedef struct DX_PskCredential
{
int m_type;
/**
* Variable: m_identity
* The identity or common name associated with the pre-shared key
**/
char *m_identity;
/**
* Variable: m_key
* The pre-shared key data
**/
void *m_key;
/**
* Variable: m_keyLength
* The length of the pre-shared key data in bytes
**/
unsigned int m_keyLength;
} DX_PskCredential;
/**
* Structure: DX_CertCredential
* Represents a PEM-encoded certificate and key located in memory
**/
typedef struct DX_CertCredential
{
int m_type;
/**
* Variable: m_certData
* The PEM-encoded certificate data
**/
void *m_certData;
/**
* Variable: m_certLength
* The length of the certificate data in bytes
**/
unsigned int m_certLength;
/**
* Variable: m_keyData
* The PEM-encoded key data
**/
void *m_keyData;
/**
* Variable: m_keyLength
* The length of the key data in bytes
**/
unsigned int m_keyLength;
} DX_CertCredential;
/**
* Structure: DX_CertFileCredential
* Represents a PEM-encoded certificate and key located in the filesystem
**/
typedef struct DX_CertFileCredential
{
int m_type;
/**
* Variable: m_certPath
* The path to the PEM-encoded certificate file
**/
char *m_certPath;
/**
* Variable: m_keyPath
* The path to the PEM-encoded key file
**/
char *m_keyPath;
} DX_CertFileCredential;
#ifdef __cplusplus
extern "C"
{
#endif
/**
* Section: Encryption API
* Unless otherwise noted, these functions are called internally by
* Distrix or the generated client code, and not directly by end users
**/
/**
* Function: DX_dtlsInitClient
* Initializes the encryption system as a DTLS client
*
* Parameters:
* p_clientCredential - The credential used to identify this client
*
* Returns:
* 1 on success, 0 on failure
**/
EXPORT_DL int DX_dtlsInitClient(DX_Credential *p_clientCredential);
/**
* Function: DX_dtlsInitClient
* Initializes the encryption system as a DTLS server and client (so that
* it can both initiate and accept connections)
*
* Parameters:
* p_serverCredential - The credential used to identify this server/client
*
* Returns:
* 1 on success, 0 on failure
**/
int DX_dtlsInitServer(DX_Credential *p_serverCredential);
/**
* Function: DX_dtlsDestroy
* Shuts down the encryption system, and performs any necessary cleanup
**/
void DX_dtlsDestroy(void);
/**
* Function: DX_addTrustedCredential
* Adds a trusted credential to the encryption system (a CA certificate
* for example)
*
* Parameters:
* p_credential - The trusted credential
*
* Returns:
* 1 on success, 0 on failure
**/
EXPORT_DL int DX_addTrustedCredential(DX_Credential *p_credential);
/**
* Function: DX_dtlsSetCRLs
* Sets the Certificate Revocation Lists to use with the encryption
* system; this function is not implemented for all encryption systems
*
* Parameters:
* p_paths - An array of strings, each of which is the path to a
* PEM-encoded CRL file
* p_count - The number of paths in the array
*
* Returns:
* 1 on success, 0 on failure
**/
int DX_dtlsSetCRLs(const char **p_paths, unsigned int p_count);
/**
* Function: DX_encryptedInit
* Initializes an encryption instance
*
* Parameters:
* p_encryption - The encryption instance to initialize; some members
* are already initialized before it is passed in here
* (see )
**/
void DX_encryptedInit(DX_Encryption *p_encryption);
/**
* Function: DX_encryptedDestroy
* Destroys an encryption instance
*
* Parameters:
* p_encryption - The encryption instance to clean up; only the
* members that were initialized in DX_encryptedInit()
* are destroyed up here
**/
void DX_encryptedDestroy(DX_Encryption *p_encryption);
/**
* Function: DX_encryptedAccept
* Accepts a new encrypted connection
*
* Parameters:
* p_encryption - The encryption instance
* p_timeout - The connection timeout in ms
*
* Returns:
* 1 on success, 0 on failure
**/
int DX_encryptedAccept(DX_Encryption *p_encryption, uint32_t p_timeout);
/**
* Function: DX_encryptedConnect
* Initiates a new encrypted connection
*
* Parameters:
* p_encryption - The encryption instance
* p_timeout - The connection timeout in ms
*
* Returns:
* 1 on success, 0 on failure
**/
int DX_encryptedConnect(DX_Encryption *p_encryption, uint32_t p_timeout);
/**
* Function: DX_encryptedDisconnect
* Closes an encrypted connection
*
* Parameters:
* p_encryption - The encryption instance
**/
void DX_encryptedDisconnect(DX_Encryption *p_encryption);
/**
* Function: DX_encryptedPeriodicTask
* Called periodically so that the encryption implementation can perform
* periodic tasks such as checking timeouts or sending buffered data
*
* Parameters:
* p_encryption - The encryption instance
**/
void DX_encryptedPeriodicTask(DX_Encryption *p_encryption);
/**
* Function: DX_encryptedSendReliable
* Encrypts and sends a dataset reliably
*
* Parameters:
* p_encryption - The encryption instance
* p_dataset - The unencrypted dataset to encrypt and send
**/
void DX_encryptedSendReliable(DX_Encryption *p_encryption, struct DX_Dataset *p_dataset);
/**
* Function: DX_encryptedSendUnreliable
* Encrypts and sends a dataset unreliably
*
* Parameters:
* p_encryption - The encryption instance
* p_dataset - The unencrypted dataset to encrypt and send
**/
void DX_encryptedSendUnreliable(DX_Encryption *p_encryption, struct DX_Dataset *p_dataset);
/**
* Function: DX_encryptedReceive
* Receives and decrypts a dataset
*
* Parameters:
* p_encryption - The encryption instance
* p_dataset - The dataset buffer to receive the decrypted dataset
* into
*
* Returns:
* 1 on success, 0 on failure
**/
int DX_encryptedReceive(DX_Encryption *p_encryption, struct DX_Dataset *p_dataset);
/**
* Function: DX_getCommonName
* Gets the Common Name of the client or server
*
* Parameters:
* p_encryption - The encryption instance
* p_buffer - The buffer to write the Common Name into
* p_size - The size of the buffer
**/
void DX_getCommonName(DX_Encryption *p_encryption, char *p_buffer, unsigned int p_size);
/**
* Function: DX_getCommonNameFromCert
* Gets the Common Name from a given credential
*
* Parameters:
* p_cert - The credential
* p_buffer - The buffer to write the Common Name into
* p_size - The size of the buffer
**/
void DX_getCommonNameFromCert(DX_Credential *p_cert, char *p_buffer, unsigned int p_size);
#ifdef __cplusplus
} // end of extern "C"
#endif
#endif
Encryption.c
Distrix encryption interface template. "Template" is a placeholder for the actual name used by the implementation.
The internal structure of this file may be changed as needed to support the specific implementation, so long as the external interface is maintained.
/**
* File: Encryption.c
* Distrix encryption interface template. "Template" is a placeholder for
* the actual name used by the implementation.
*
* The internal structure of this file may be changed as needed to support
* the specific implementation, so long as the external interface is
* maintained.
**/
#include "Distrix/Common/Encryption/Encryption.h"
#include "Distrix/Common/Dataset.h"
#include "Distrix/Abstractions/Threads/Mutex.h"
#include "Distrix/Abstractions/Threads/Thread.h"
#include "Distrix/Abstractions/Memory/Alloc.h"
#include "Distrix/Abstractions/Time/Time.h"
#include "Distrix/Abstractions/Log/Log.h"
// Include any necessary encryption library headers...
#include <string.h>
/**
* Constant: IMPL_NAME
* Encryption implementation name
**/
#define IMPL_NAME "Template"
static DX_Logger gs_templateLog = DX_LOGGER_INIT(DX_LOG, "?" IMPL_NAME ": ", DX_LOG_INHERIT_LEVEL, DX_LOG_INHERIT_OUTPUT);
/**
* Variable: TEMPLATE_LOG
* The logger to use for all messages from this module
**/
static DX_LogHandle TEMPLATE_LOG = &gs_templateLog;
// Change the typedef to the DTLS context type for the library...
/**
* Type: DX_DTLSContext
* The type of DTLS contexts for this library
**/
typedef int DX_DTLSContext;
/**
* Structure: DX_EncryptionData
* Implementation-specific state information
**/
typedef struct DX_EncryptionData
{
// Add necessary members...
} DX_EncryptionData;
// Declare the global client and server contexts
static DX_DTLSContext *gs_serverCtx = NULL;
static DX_DTLSContext *gs_clientCtx = NULL;
static int dtlsInitClient(void)
{
// Create a new global DTLS client context...
//> gs_clientCtx = ...
return 1;
}
static int dtlsInitServer(void)
{
// Create a new global DTLS server context...
//> gs_serverCtx = ...
return 1;
}
static int credentialSetup(DX_DTLSContext *p_ctx, DX_Credential *p_credential)
{
switch (p_credential->m_type)
{
case e_DX_pskCredential:
// Configure context with pre-shared key...
break;
case e_DX_certCredential:
// Configure context with certificate and key...
break;
case e_DX_certFileCredential:
// Configure context with certificate and key from files...
break;
};
return 1;
}
int DX_dtlsInitClient(DX_Credential *p_clientCredential)
{
static int ls_inited = 0;
if (ls_inited)
{
return 1;
}
ls_inited = 1;
// Initialize DTLS/crypto library...
return (dtlsInitClient() && credentialSetup(gs_clientCtx, p_clientCredential));
}
int DX_dtlsInitServer(DX_Credential *p_serverCredential)
{
static int ls_inited = 0;
if (ls_inited)
{
return 1;
}
ls_inited = 1;
// Initialize DTLS/crypto library...
if (!dtlsInitClient() || !credentialSetup(gs_clientCtx, p_serverCredential))
{
return 0;
}
return (dtlsInitServer() && credentialSetup(gs_serverCtx, p_serverCredential));
}
void DX_dtlsDestroy(void)
{
// Clean up client and server contexts, as applicable...
// Clean up DTLS/crypto library...
}
int DX_addTrustedCredential(DX_Credential *p_credential)
{
switch (p_credential->m_type)
{
case e_DX_pskCredential:
// Add client and server contexts trusted credential from pre-shared key, as applicable...
break;
case e_DX_certCredential:
// Add client and server contexts trusted credential from certificate and key, as applicable...
break;
case e_DX_certFileCredential:
// Add client and server contexts trusted credential from certificate and key files, as applicable...
break;
};
return 1;
}
int DX_dtlsSetCRLs(const char **p_paths, unsigned int p_count)
{
if (p_count == 1 && p_paths[0][0] == '\0')
{
// Handle case where there is a list of paths containing one empty
// string, as generated by the System Manager if no CRL is specified
return 1;
}
// Add CRLs to client and server contexts, as applicable...
return 1;
}
void DX_encryptedInit(DX_Encryption *p_encryption)
{
DX_listInit(&p_encryption->m_sendQueue);
DX_vectorInit(&p_encryption->m_sendBuffer, uint8_t, NULL, NULL);
p_encryption->m_connected = 0;
p_encryption->m_error = 0;
p_encryption->m_mutex = DX_mutexCreate();
p_encryption->m_impl = DX_alloc(sizeof(DX_EncryptionData));
// Initialize p_encryption->m_impl as appropriate...
}
static void emptySendQueue(DX_Encryption *p_encryption)
{
DX_ListIterator it;
for (DX_listBegin(&p_encryption->m_sendQueue, &it); DX_listHasNext(&it); DX_listNext(&it))
{
struct DX_Dataset *l_dataset = it.m_value;
DX_free(l_dataset);
}
DX_listClear(&p_encryption->m_sendQueue);
}
void DX_encryptedDestroy(DX_Encryption *p_encryption)
{
emptySendQueue(p_encryption);
DX_listDestroy(&p_encryption->m_sendQueue);
DX_vectorDestroy(&p_encryption->m_sendBuffer);
DX_mutexDelete(p_encryption->m_mutex);
DX_free(p_encryption->m_impl);
}
static int encryptedSetup(DX_DTLSContext *p_ctx, DX_Encryption *p_encryption, uint32_t p_timeout)
{
if (p_ctx == NULL || p_encryption == NULL)
{
DX_logError(TEMPLATE_LOG, "An setup parameter was NULL\n");
return 0;
}
p_encryption->m_connected = 0;
p_encryption->m_error = 0;
// Create a new DTLS connection instance and store it somewhere in m_impl...
DX_vectorClear(&p_encryption->m_sendBuffer);
DX_vectorResizeFast(&p_encryption->m_sendBuffer, sizeof(DX_Dataset));
// Set up connection memory buffers, etc...
p_encryption->m_timeout = DX_getTimeMs() + p_timeout;
return 1;
}
int DX_encryptedAccept(DX_Encryption *p_encryption, uint32_t p_timeout)
{
if(!encryptedSetup(gs_serverCtx, p_encryption, p_timeout))
{
return 0;
}
// Tell connection instance that the connection has been accepted...
return 1;
}
// The implementation of this function is largely dependent on the specifics of
// the DTLS/crypto library, and in some cases it may only be used to send
// reliable control data (such as handshakes) rather than all data
static void sendBufferedData(DX_Encryption *p_encryption, int p_reliable)
{
// Copy the encrypted data out of the implementation's own buffer and into
// m_sendBuffer, leaving enough room to prepend a DX_Dataset (in some cases
// m_sendBuffer may be used directly as the implementation's buffer, in
// which case the extra copying is unnecessary)...
// If the size of the data to send is greater than the size of a dataset header,
// then fill the dataset header and send it...
//> DX_Dataset *l_hdr = DX_vectorArray(&p_encryption->m_sendBuffer, DX_Dataset);
//> DX_fillDatasetHeader(l_hdr, l_dataSize, e_DX_dsType_encrypted, (p_reliable ? c_DX_dsFlag_reliable : 0));
//> p_encryption->sendf(p_encryption, p_reliable, l_hdr);
}
int DX_encryptedConnect(DX_Encryption *p_encryption, uint32_t p_timeout)
{
if (!encryptedSetup(gs_clientCtx, p_encryption, p_timeout))
{
return 0;
}
// Tell connection instance that it is connected...
// Send any generated handshaking traffic over Distrix
sendBufferedData(p_encryption, 1);
return 1;
}
void DX_encryptedDisconnect(DX_Encryption *p_encryption)
{
if (p_encryption == NULL)
{
return;
}
emptySendQueue(p_encryption);
// Shut down the DTLS connection...
// Send any generated shutdown traffic
sendBufferedData(p_encryption, 1);
// Clean up connection state...
p_encryption->m_connected = 0;
}
// p_encryption->m_mutex must be locked
static void onError(DX_Encryption *p_encryption, int p_disconnected)
{
emptySendQueue(p_encryption);
p_encryption->m_error = 1;
// Shut down the connection, if one exists...
p_encryption->m_connected = 0;
DX_mutexUnlock(p_encryption->m_mutex);
p_encryption->onError(p_encryption, p_disconnected);
}
void DX_encryptedPeriodicTask(DX_Encryption *p_encryption)
{
uint64_t l_time;
if (p_encryption == NULL)
{
return;
}
l_time = DX_getTimeMs();
DX_mutexLock(p_encryption->m_mutex);
if (p_encryption->m_error)
{
DX_mutexUnlock(p_encryption->m_mutex);
return;
}
if (p_encryption->m_timeout != 0 && l_time > p_encryption->m_timeout)
{
DX_logError(TEMPLATE_LOG, "DTLS timeout at %llu\n", (unsigned long long) l_time);
onError(p_encryption, 0);
}
else
{
sendBufferedData(p_encryption, 1);
DX_mutexUnlock(p_encryption->m_mutex);
}
}
// p_encryption->m_mutex must be locked
static int sendData(DX_Encryption *p_encryption, int p_reliable, void *p_data, uint32_t p_size, int *p_doOnConnect)
{
uint32_t l_sizeLeft = p_size; // Decrement this value as data is processed...
// Potentially send any previously buffered data, then write the current data to the DTLS context to encrypt it...
// Send the newly encrypted data to Distrix using sendBufferedData(), or some other mechanism if it is more efficient...
if (l_sizeLeft == 0)
{
if (p_encryption->m_timeout != 0 && p_encryption->onConnect)
{
*p_doOnConnect = 1;
}
p_encryption->m_timeout = 0;
return 1;
}
else if (l_sizeLeft != p_size)
{
DX_logError(TEMPLATE_LOG, "Partially sent a dataset!\n");
onError(p_encryption, 0);
return 0;
}
return 0;
}
// p_encryption->m_mutex must be locked
static int sendQueue(DX_Encryption *p_encryption)
{
int l_doOnConnect = 0;
DX_ListIterator it;
// Add any other checks needed to this if statement to ensure that the handshaking is complete...
if (DX_listEmpty(&p_encryption->m_sendQueue) && p_encryption->m_timeout != 0 && p_encryption->onConnect)
{
p_encryption->m_timeout = 0;
return 1;
}
for (DX_listBegin(&p_encryption->m_sendQueue, &it); DX_listHasNext(&it);)
{
struct DX_Dataset *l_dataset = it.m_value;
if (sendData(p_encryption, 1, l_dataset, l_dataset->m_size, &l_doOnConnect))
{
DX_free(l_dataset);
DX_listErase(&it);
}
else
{
break;
}
}
return l_doOnConnect;
}
// p_encryption->m_mutex must be locked
static void addToQueue(DX_Encryption *p_encryption, struct DX_Dataset *p_dataset)
{
struct DX_Dataset *l_copy;
if (p_encryption->m_error)
{
return;
}
l_copy = DX_alloc(p_dataset->m_size);
memcpy(l_copy, p_dataset, p_dataset->m_size);
DX_listPushBack(&p_encryption->m_sendQueue, l_copy);
}
static void sendImpl(DX_Encryption *p_encryption, int p_reliable, struct DX_Dataset *p_dataset)
{
int l_doOnConnect = 0;
DX_mutexLock(p_encryption->m_mutex);
if (p_encryption->m_error)
{
DX_mutexUnlock(p_encryption->m_mutex);
return;
}
if (!DX_listEmpty(&p_encryption->m_sendQueue))
{
if (p_reliable)
{
addToQueue(p_encryption, p_dataset);
}
if (sendQueue(p_encryption))
{
l_doOnConnect = 1;
}
}
else if (!sendData(p_encryption, p_reliable, p_dataset, p_dataset->m_size, &l_doOnConnect) && p_reliable)
{
addToQueue(p_encryption, p_dataset);
}
if (!p_encryption->m_error)
{
DX_mutexUnlock(p_encryption->m_mutex);
}
// otherwise it has already been unlocked by onError()
if (l_doOnConnect)
{
p_encryption->m_connected = 1;
p_encryption->onConnect(p_encryption);
}
}
void DX_encryptedSendReliable(DX_Encryption *p_encryption, struct DX_Dataset *p_dataset)
{
sendImpl(p_encryption, 1, p_dataset);
}
void DX_encryptedSendUnreliable(DX_Encryption *p_encryption, struct DX_Dataset *p_dataset)
{
sendImpl(p_encryption, 0, p_dataset);
}
int DX_encryptedReceive(DX_Encryption *p_encryption, struct DX_Dataset *p_dataset)
{
char *l_data = ((char *)p_dataset) + sizeof(DX_Dataset);
uint32_t l_size = p_dataset->m_size - sizeof(DX_Dataset);
int l_doOnConnect = 0;
uint32_t l_recvSize = 0; // Populate this with the amount of data
// received from the DTLS conenction
DX_mutexLock(p_encryption->m_mutex);
if (p_encryption->m_error)
{
DX_mutexUnlock(p_encryption->m_mutex);
return 0;
}
// Check that there is no pending data in the DTLS buffer (since the buffer
// should have been emptied the last time DX_encryptedReceive() was
// called)...
// Copy the body of the encrypted dataset into the DTLS implementation's
// receive buffer and perform a read to obtain the decrypted content...
// Send any resulting handshaking data
sendBufferedData(p_encryption, 1);
if (sendQueue(p_encryption))
{
l_doOnConnect = 1;
}
if (l_recvSize == 0)
{
DX_mutexUnlock(p_encryption->m_mutex);
if (l_doOnConnect)
{
p_encryption->m_connected = 1;
p_encryption->onConnect(p_encryption);
}
return 0;
}
if (l_recvSize < sizeof(DX_Dataset) && !p_encryption->onReceive)
{
DX_logError(TEMPLATE_LOG, "Received dataset was invalid!\n");
onError(p_encryption, 0);
return 0;
}
if (p_encryption->m_timeout != 0 && p_encryption->onConnect)
{
l_doOnConnect = 1;
}
p_encryption->m_timeout = 0;
DX_mutexUnlock(p_encryption->m_mutex);
if (l_doOnConnect)
{
p_encryption->m_connected = 1;
p_encryption->onConnect(p_encryption);
}
if (p_encryption->onReceive)
{
p_encryption->onReceive(p_encryption, p_dataset, l_recvSize);
}
return 1;
}
void DX_getCommonName(DX_Encryption *p_encryption, char *p_buffer, unsigned int p_size)
{
if (p_buffer == NULL || p_size == 0)
{
return;
}
*p_buffer = '\0';
// Read the Common Name out of the credentials used by the current
// server/client and populate p_buffer...
}
void DX_getCommonNameFromCert(DX_Credential *p_cert, char *p_buffer, unsigned int p_size)
{
if (p_buffer == NULL || p_size == 0)
{
return;
}
*p_buffer = '\0';
// Read the Common Name out of the provided credential and populate
// p_buffer...
}
Encryption.h
This file is simply for exposing the function that is used to load the service.
/**
* File: Encryption.h
* Exposes the hook for loading the Distrix encryption service.
**/
#ifndef DX_SERVER_WRAPPERS_SERVICES_ENCRYPTION_STATIC_ENCRYPTION_H
#define DX_SERVER_WRAPPERS_SERVICES_ENCRYPTION_STATIC_ENCRYPTION_H
#include "Distrix/Server/Services/Service.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* Function: DX_Server_getEncryptionService
* Called to instanitate the encryption service. For the non-embedded
* version of the server this would be called from the getService()
* function of the service module.
*
* Returns:
* The encryption service instance.
**/
DX_Server_Service *DX_Server_getEncryptionService(void);
#ifdef __cplusplus
} // end of extern "C"
#endif
#endif /* DX_SERVER_WRAPPERS_SERVICES_ENCRYPTION_STATIC_ENCRYPTION_H */
Entry.cpp
Public shared library interface for loading the Encryption service.
/**
* File: Entry.cpp
* Public shared library interface for loading the Encryption service.
**/
#include "Distrix/Server/Wrappers/Services/Encryption/Static/Encryption.h"
#include "Distrix/Abstractions/Utils/Compiler/Export.h"
/**
* Function: getService
* The public entry point for the service module, this function is called
* by the Distrix server to obtain a handle to the service.
*
* Returns:
* The service instance
**/
EXPORT DX_Server_Service *getService(void)
{
return DX_Server_getEncryptionService();
}


