1 /*
2  * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 /*****************************************************************************
28  library.cpp
29 
30  Support function for handling PKCS#11 libraries
31  *****************************************************************************/
32 
33 #include <config.h>
34 #include "library.h"
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 #if defined(HAVE_DLOPEN)
39 #include <dlfcn.h>
40 #endif
41 
42 // Load the PKCS#11 library
loadLibrary(char * module,void ** moduleHandle,char ** pErrMsg)43 CK_C_GetFunctionList loadLibrary(char* module, void** moduleHandle,
44 				char **pErrMsg)
45 {
46 	CK_C_GetFunctionList pGetFunctionList = NULL;
47 
48 #if defined(HAVE_LOADLIBRARY)
49 	HINSTANCE hDLL = NULL;
50 	DWORD dw = NULL;
51 	static char errMsg[100];
52 
53 	// Load PKCS #11 library
54 	if (module)
55 	{
56 		hDLL = LoadLibraryA(module);
57 	}
58 	else
59 	{
60 		hDLL = LoadLibraryA(DEFAULT_PKCS11_LIB);
61 	}
62 
63 	if (hDLL == NULL)
64 	{
65 		// Failed to load the PKCS #11 library
66 		dw = GetLastError();
67 		snprintf((char*)errMsg, sizeof(errMsg), "LoadLibraryA failed: 0x%08X", dw);
68 		*pErrMsg = errMsg;
69 		return NULL;
70 	}
71 	else
72 	{
73 		*pErrMsg = NULL;
74 	}
75 
76 	// Retrieve the entry point for C_GetFunctionList
77 	pGetFunctionList = (CK_C_GetFunctionList) GetProcAddress(hDLL, "C_GetFunctionList");
78 	if (pGetFunctionList == NULL)
79 	{
80 		dw = GetLastError();
81 		snprintf((char*)errMsg, sizeof(errMsg), "getProcAddress failed: 0x%08X", dw);
82 		*pErrMsg = errMsg;
83 		FreeLibrary(hDLL);
84 		return NULL;
85 	}
86 
87 	// Store the handle so we can FreeLibrary it later
88 	*moduleHandle = hDLL;
89 
90 #elif defined(HAVE_DLOPEN)
91 	void* pDynLib = NULL;
92 
93 	// Load PKCS #11 library
94 	if (module)
95 	{
96 		pDynLib = dlopen(module, RTLD_NOW | RTLD_LOCAL);
97 	}
98 	else
99 	{
100 		pDynLib = dlopen(DEFAULT_PKCS11_LIB, RTLD_NOW | RTLD_LOCAL);
101 	}
102 
103 	*pErrMsg = dlerror();
104 	if (pDynLib == NULL || *pErrMsg != NULL)
105 	{
106 		if (pDynLib != NULL) dlclose(pDynLib);
107 
108 		// Failed to load the PKCS #11 library
109 		return NULL;
110 	}
111 
112 	// Retrieve the entry point for C_GetFunctionList
113 	pGetFunctionList = (CK_C_GetFunctionList) dlsym(pDynLib, "C_GetFunctionList");
114 
115 	// Store the handle so we can dlclose it later
116 	*pErrMsg = dlerror();
117 	if (*pErrMsg != NULL)
118 	{
119 		dlclose(pDynLib);
120 
121 		// An error occured during dlsym()
122 		return NULL;
123 	}
124 
125 	*moduleHandle = pDynLib;
126 #else
127 	fprintf(stderr, "ERROR: Not compiled with library support.\n");
128 
129 	return NULL;
130 #endif
131 
132 	return pGetFunctionList;
133 }
134 
unloadLibrary(void * moduleHandle)135 void unloadLibrary(void* moduleHandle)
136 {
137 	if (moduleHandle)
138 	{
139 #if defined(HAVE_LOADLIBRARY)
140 		FreeLibrary((HMODULE) moduleHandle);
141 #elif defined(HAVE_DLOPEN)
142 		dlclose(moduleHandle);
143 #endif
144 	}
145 }
146