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