000026129 - How to ensure that RSA BSAFE SSL-C based application is thread safe

Document created by RSA Customer Support Employee on Jun 16, 2016Last modified by RSA Customer Support Employee on Apr 21, 2017
Version 2Show Document
  • View in full screen mode

Article Content

Article Number000026129
Applies ToRSA BSAFE SSL-C 1.3
RSA BSAFE SSL-C 1.1
RSA BSAFE SSL-C 2.0
Operating in a multi-threaded environment
IssueHow to ensure that RSA BSAFE SSL-C based application is thread safe
Unexplained errors are reported by the RSA BSAFE SSL-C library, including SSL_ERROR_SYSCALL
CauseProper locking in a multi-threaded environment is not occurring
ResolutionRSA BSAFE SSL-C allows for platform specific locking callbacks.  These callbacks provide a method for application programmers to specify platform specific locking mechanisms to the SSL-C library.  When these callbacks are set, the SSL-C library will use them to assure that only one thread will access certain data structures and areas of code at a time.

SSL-C requires that two user-defined callback functions to be registered.  The first is a function that returns the current thread (or process) ID.  The second is a function that will obtain (or release) a lock (as defined by the operating system) on a particular object.  If these two functions are registered, SSL-C will lock necessary sections of code when appropriate.  All locking after this point is transparent to the application and application programmer.

Note:  The following examples demonstrate how to implement the callbacks for a Win32 based system.  The SSL-C sample code provides sample implementations for Solaris, Win32, VxWorks, and pthreads based applications.  The sample code can be found in the samples/cb directory on the product CD.

The following function demonstrates how one might implement the thread ID callback.  This function simply calls the appropriate Win32 function to obtain the current thread ID, and returns that value.

unsigned long APPCB_thread_id(void) {
 unsigned long ret;

 ret=(unsigned long)GetCurrentThreadId();
 return(ret);
}

This callback function is then registered by a call to CRYPTO_set_id_cb:

CRYPTO_set_id_cb((unsigned long (*)(void))APPCB_thread_id);

The other callback function that needs to be registered is the function that will actually obtain or release a lock.  Because the SSL-C library performs many different operations, there are several different reasons to lock a particular section of code.  It is unwise to lock entire functions, and it is not necessary to obtain a generic lock on an SSL_CTX structure when only part of it is being updated.  SSL-C meets these needs by having several locks.  In the case of Win32, we'll establish several Mutex objects.

The CRYPTO_get_num_locks() function returns an integer value that is one less than the number of Mutexes (locks) required.  To satisfy SSL-C's needs, we'll declare a series of Mutexes:

int numLocks = CRYPTO_get_num_locks()+1;
HANDLE *locks = malloc (sizeof(HANDLE*) * numLocks);
int i = 0;
for ( i = 0 ; i < numLocks ; i++) {
 locks[i] = CreateMutex (NULL, FALSE, NULL);
}

Once the series of locks has been created, a function that will obtain or release the lock is required:
int APPCB_locking_cb(int mode,int lockid,char *file,int line) {

 if (mode & CRYPTO_LOCK) {
   WaitForSingleObject(locks[lockid],INFINITE);
 }
 else {
   ReleaseMutex(locks[lockid]);
 }

 return (1);
}

This function is then registered by calling CRYPTO_set_locking_cb:

CRYPTO_set_locking_cb((int (*)(int,int,char *,int))APPCB_locking_cb);
Legacy Article IDa594

Attachments

    Outcomes