Initial sshsm project structure

Issue-ID: AAF-94
Change-Id: I5e82fff418e7567b161acf9b98013a9b85ffc5b4
Signed-off-by: NingSun <ning.sun@intel.com>
diff --git a/SoftHSMv2/src/bin/common/Makefile.am b/SoftHSMv2/src/bin/common/Makefile.am
new file mode 100644
index 0000000..e3a2b24
--- /dev/null
+++ b/SoftHSMv2/src/bin/common/Makefile.am
@@ -0,0 +1,3 @@
+MAINTAINERCLEANFILES =	$(srcdir)/Makefile.in
+
+EXTRA_DIST =		$(srcdir)/*.h
diff --git a/SoftHSMv2/src/bin/common/findslot.cpp b/SoftHSMv2/src/bin/common/findslot.cpp
new file mode 100644
index 0000000..5936db7
--- /dev/null
+++ b/SoftHSMv2/src/bin/common/findslot.cpp
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2016 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ findslot.cpp
+
+ Helper function to find the slot
+ *****************************************************************************/
+
+#include <config.h>
+#include "findslot.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern CK_FUNCTION_LIST_PTR p11;
+
+// Find the slot/token
+int findSlot(char* slot, char* serial, char* token, bool freeToken, CK_SLOT_ID& slotID)
+{
+	if (slot != NULL)
+	{
+		int slotNumber = atoi(slot);
+		if (slotNumber < 0)
+		{
+			fprintf(stderr, "ERROR: The slot number is negative.\n");
+			return 1;
+		}
+
+		slotID = slotNumber;
+		return 0;
+	}
+
+	if (serial == NULL && token == NULL && freeToken == false)
+ 	{
+		fprintf(stderr, "ERROR: A slot/token must be supplied. "
+				"Use --slot <number>, --serial <serial>, "
+				"--token <label>, or --free\n");
+		return 1;
+	}
+
+	// Load the variables
+	CK_UTF8CHAR paddedSerial[16];
+	CK_UTF8CHAR paddedToken[32];
+	if (serial != NULL)
+	{
+		size_t inSize = strlen(serial);
+		size_t outSize = sizeof(paddedSerial);
+		if (inSize > outSize)
+		{
+			fprintf(stderr, "ERROR: --serial is too long.\n");
+			return 1;
+		}
+		memset(paddedSerial, ' ', outSize);
+		memcpy(paddedSerial, serial, inSize);
+	}
+	if (token != NULL)
+	{
+		size_t inSize = strlen(token);
+		size_t outSize = sizeof(paddedToken);
+		if (inSize > outSize)
+		{
+			fprintf(stderr, "ERROR: --token is too long.\n");
+			return 1;
+		}
+		memset(paddedToken, ' ', outSize);
+		memcpy(paddedToken, token, inSize);
+	}
+
+	CK_ULONG ulSlotCount;
+	CK_RV rv = p11->C_GetSlotList(CK_TRUE, NULL_PTR, &ulSlotCount);
+	if (rv != CKR_OK)
+	{
+		fprintf(stderr, "ERROR: Could not get the number of slots.\n");
+		return 1;
+	}
+
+	CK_SLOT_ID_PTR pSlotList = (CK_SLOT_ID_PTR) malloc(ulSlotCount*sizeof(CK_SLOT_ID));
+	if (pSlotList == NULL)
+	{
+		fprintf(stderr, "ERROR: Could not allocate memory.\n");
+		return 1;
+	}
+
+	rv = p11->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
+	if (rv != CKR_OK)
+	{
+		fprintf(stderr, "ERROR: Could not get the slot list.\n");
+		free(pSlotList);
+		return 1;
+	}
+
+	size_t counter = 0;
+	for (CK_ULONG i = 0; i < ulSlotCount; i++)
+	{
+		CK_TOKEN_INFO tokenInfo;
+
+		rv = p11->C_GetTokenInfo(pSlotList[i], &tokenInfo);
+		if (rv != CKR_OK)
+		{
+			fprintf(stderr, "ERROR: Could not get info about the token in slot %lu.\n",
+				pSlotList[i]);
+			free(pSlotList);
+			return 1;
+		}
+
+		if (freeToken)
+		{
+			if ((tokenInfo.flags & CKF_TOKEN_INITIALIZED) == 0)
+			{
+				printf("Slot %lu has a free/uninitialized token.\n", pSlotList[i]);
+				slotID = pSlotList[i];
+				free(pSlotList);
+				return 0;
+			}
+		}
+		else
+		{
+			if (serial != NULL && token == NULL &&
+				memcmp(tokenInfo.serialNumber, paddedSerial, sizeof(paddedSerial)) == 0)
+			{
+				printf("Found slot %lu with matching serial.\n",
+				       pSlotList[i]);
+				slotID = pSlotList[i];
+				counter++;
+			}
+			if (serial == NULL && token != NULL &&
+				memcmp(tokenInfo.label, paddedToken, sizeof(paddedToken)) == 0)
+			{
+				printf("Found slot %lu with matching token label.\n",
+				       pSlotList[i]);
+				slotID = pSlotList[i];
+				counter++;
+			}
+			if (serial != NULL && token != NULL &&
+				memcmp(tokenInfo.serialNumber, paddedSerial, sizeof(paddedSerial)) == 0 &&
+				memcmp(tokenInfo.label, paddedToken, sizeof(paddedToken)) == 0)
+			{
+				printf("Found slot %lu with matching serial and token label.\n",
+				       pSlotList[i]);
+				slotID = pSlotList[i];
+				counter++;
+			}
+		}
+	}
+
+	free(pSlotList);
+
+	if (counter == 1) return 0;
+	if (counter > 1)
+	{
+		fprintf(stderr, "ERROR: Found multiple matching slots/tokens.\n");
+		return 1;
+	}
+
+	fprintf(stderr, "ERROR: Could not find a slot/token using --serial, --token, or --free.\n");
+	return 1;
+}
+
+// Find the slot/token
+int findSlot(char* slot, char* serial, char* token, CK_SLOT_ID& slotID)
+{
+	if (slot != NULL)
+	{
+		int slotNumber = atoi(slot);
+		if (slotNumber < 0)
+		{
+			fprintf(stderr, "ERROR: The slot number is negative.\n");
+			return 1;
+		}
+
+		slotID = slotNumber;
+		return 0;
+	}
+
+	if (serial == NULL && token == NULL)
+ 	{
+		fprintf(stderr, "ERROR: A slot/token must be supplied. "
+				"Use --slot <number>, --serial <serial>, "
+				"or --token <label>\n");
+		return 1;
+	}
+
+	// Load the variables
+	CK_UTF8CHAR paddedSerial[16];
+	CK_UTF8CHAR paddedToken[32];
+	if (serial != NULL)
+	{
+		size_t inSize = strlen(serial);
+		size_t outSize = sizeof(paddedSerial);
+		if (inSize > outSize)
+		{
+			fprintf(stderr, "ERROR: --serial is too long.\n");
+			return 1;
+		}
+		memset(paddedSerial, ' ', outSize);
+		memcpy(paddedSerial, serial, inSize);
+	}
+	if (token != NULL)
+	{
+		size_t inSize = strlen(token);
+		size_t outSize = sizeof(paddedToken);
+		if (inSize > outSize)
+		{
+			fprintf(stderr, "ERROR: --token is too long.\n");
+			return 1;
+		}
+		memset(paddedToken, ' ', outSize);
+		memcpy(paddedToken, token, inSize);
+	}
+
+	CK_ULONG ulSlotCount;
+	CK_RV rv = p11->C_GetSlotList(CK_TRUE, NULL_PTR, &ulSlotCount);
+	if (rv != CKR_OK)
+	{
+		fprintf(stderr, "ERROR: Could not get the number of slots.\n");
+		return 1;
+	}
+
+	CK_SLOT_ID_PTR pSlotList = (CK_SLOT_ID_PTR) malloc(ulSlotCount*sizeof(CK_SLOT_ID));
+	if (pSlotList == NULL)
+	{
+		fprintf(stderr, "ERROR: Could not allocate memory.\n");
+		return 1;
+	}
+
+	rv = p11->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
+	if (rv != CKR_OK)
+	{
+		fprintf(stderr, "ERROR: Could not get the slot list.\n");
+		free(pSlotList);
+		return 1;
+	}
+
+	size_t counter = 0;
+	for (CK_ULONG i = 0; i < ulSlotCount; i++)
+	{
+		CK_TOKEN_INFO tokenInfo;
+
+		rv = p11->C_GetTokenInfo(pSlotList[i], &tokenInfo);
+		if (rv != CKR_OK)
+		{
+			fprintf(stderr, "ERROR: Could not get info about the token in slot %lu.\n",
+				pSlotList[i]);
+			free(pSlotList);
+			return 1;
+		}
+
+		if (serial != NULL && token == NULL &&
+			memcmp(tokenInfo.serialNumber, paddedSerial, sizeof(paddedSerial)) == 0)
+		{
+			printf("Found slot %lu with matching serial.\n",
+			       pSlotList[i]);
+			slotID = pSlotList[i];
+			counter++;
+		}
+		if (serial == NULL && token != NULL &&
+			memcmp(tokenInfo.label, paddedToken, sizeof(paddedToken)) == 0)
+		{
+			printf("Found slot %lu with matching token label.\n",
+			       pSlotList[i]);
+			slotID = pSlotList[i];
+			counter++;
+		}
+		if (serial != NULL && token != NULL &&
+			memcmp(tokenInfo.serialNumber, paddedSerial, sizeof(paddedSerial)) == 0 &&
+			memcmp(tokenInfo.label, paddedToken, sizeof(paddedToken)) == 0)
+		{
+			printf("Found slot %lu with matching serial and token label.\n",
+			       pSlotList[i]);
+			slotID = pSlotList[i];
+			counter++;
+		}
+	}
+
+	free(pSlotList);
+
+	if (counter == 1) return 0;
+	if (counter > 1)
+	{
+		fprintf(stderr, "ERROR: Found multiple matching slots/tokens.\n");
+		return 1;
+	}
+
+	fprintf(stderr, "ERROR: Could not find a slot/token using --serial, or --token\n");
+	return 1;
+}
+
+// Find the slot/token
+int findSlot(CK_TOKEN_INFO tokenInfo, CK_SLOT_ID& slotID)
+{
+	CK_ULONG ulSlotCount;
+	CK_RV rv = p11->C_GetSlotList(CK_TRUE, NULL_PTR, &ulSlotCount);
+	if (rv != CKR_OK)
+	{
+		fprintf(stderr, "ERROR: Could not get the number of slots.\n");
+		return 1;
+	}
+
+	CK_SLOT_ID_PTR pSlotList = (CK_SLOT_ID_PTR) malloc(ulSlotCount*sizeof(CK_SLOT_ID));
+	if (pSlotList == NULL)
+	{
+		fprintf(stderr, "ERROR: Could not allocate memory.\n");
+		return 1;
+	}
+
+	rv = p11->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
+	if (rv != CKR_OK)
+	{
+		fprintf(stderr, "ERROR: Could not get the slot list.\n");
+		free(pSlotList);
+		return 1;
+	}
+
+	size_t counter = 0;
+	for (CK_ULONG i = 0; i < ulSlotCount; i++)
+	{
+		CK_TOKEN_INFO currentTokenInfo;
+
+		rv = p11->C_GetTokenInfo(pSlotList[i], &currentTokenInfo);
+		if (rv != CKR_OK)
+		{
+			fprintf(stderr, "ERROR: Could not get info about the token in slot %lu.\n",
+				pSlotList[i]);
+			free(pSlotList);
+			return 1;
+		}
+
+		if (memcmp(currentTokenInfo.serialNumber, tokenInfo.serialNumber, sizeof(tokenInfo.serialNumber)) == 0 &&
+		    memcmp(currentTokenInfo.label, tokenInfo.label, sizeof(tokenInfo.label)) == 0)
+		{
+			slotID = pSlotList[i];
+			counter++;
+		}
+	}
+
+	free(pSlotList);
+
+	if (counter == 1) return 0;
+	if (counter > 1)
+	{
+		fprintf(stderr, "ERROR: Found multiple matching slots/tokens.\n");
+		return 1;
+	}
+
+	fprintf(stderr, "ERROR: Could not find a slot/token using --serial, or --token\n");
+	return 1;
+}
diff --git a/SoftHSMv2/src/bin/common/findslot.h b/SoftHSMv2/src/bin/common/findslot.h
new file mode 100644
index 0000000..f8a7ba6
--- /dev/null
+++ b/SoftHSMv2/src/bin/common/findslot.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ findslot.h
+
+ Helper function to find the slot number
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BIN_FINDSLOT_H
+#define _SOFTHSM_V2_BIN_FINDSLOT_H
+
+#include "cryptoki.h"
+
+int findSlot(char* slot, char* serial, char* token, bool freeToken, CK_SLOT_ID& slotID);
+int findSlot(char* slot, char* serial, char* token, CK_SLOT_ID& slotID);
+int findSlot(CK_TOKEN_INFO tokenInfo, CK_SLOT_ID& slotID);
+
+#endif // !_SOFTHSM_V2_BIN_FINDSLOT_H
diff --git a/SoftHSMv2/src/bin/common/getpw.cpp b/SoftHSMv2/src/bin/common/getpw.cpp
new file mode 100644
index 0000000..938abd5
--- /dev/null
+++ b/SoftHSMv2/src/bin/common/getpw.cpp
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ getpw.cpp
+
+ Helper function to get a password from the user
+ *****************************************************************************/
+
+#include <config.h>
+#include "getpw.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <termios.h>
+#include <signal.h>
+#endif
+
+#ifndef _WIN32
+// Remember the signal number
+static volatile sig_atomic_t signo;
+
+void sighandler(int s)
+{
+	signo = s;
+}
+#endif
+
+int getpin(const char* prompt, char* buffer, size_t size)
+{
+	if (prompt == NULL || buffer == NULL || size < 1)
+		return -1;
+
+	printf("%s", prompt);
+
+#ifdef _WIN32
+	HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE);
+	DWORD mode;
+
+	// Save current console mode
+	if (!GetConsoleMode(hstdin, &mode))
+		return -1;
+
+	// Update the console mode
+	if (hstdin == INVALID_HANDLE_VALUE || !(SetConsoleMode(hstdin, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT)))
+		return -1;
+#else
+	struct termios new_attr, old_attr;
+
+	// Get current terminal attributes
+	if (tcgetattr(STDIN_FILENO, &old_attr) < 0)
+		return -1;
+
+	// Save the mode flags
+	new_attr = old_attr;
+
+	// Update the mode flags
+	new_attr.c_lflag &= ~ICANON;
+	new_attr.c_lflag &= ~ECHO;
+
+	// Handle the SIGINT signal
+	signo = 0;
+	struct sigaction osa, sa;
+	sigaction(SIGINT, NULL, &osa);
+	if (osa.sa_handler != SIG_IGN)
+	{
+		sigemptyset(&sa.sa_mask);
+		sa.sa_flags = 0;
+		sa.sa_handler = sighandler;
+		sigaction(SIGINT, &sa, &osa);
+        }
+
+	// Set the new terminal attributes
+	if (tcsetattr(STDIN_FILENO, 0, &new_attr) < 0)
+		return -1;
+#endif
+
+	size_t nread = 0;
+	int ch = 0;
+	while ((ch = getchar()) != '\n' && ch != EOF)
+	{
+		// Check buffer size
+		if ((nread+2) > size)
+			continue;
+
+		putchar('*');
+		buffer[nread] = ch;
+		nread++;
+	}
+
+	putchar('\n');
+	buffer[nread] = '\0';
+
+#ifdef _WIN32
+	// Restore the console mode
+	if (!SetConsoleMode(hstdin, mode))
+		return -1;
+#else
+	// Restore terminal
+	if (tcsetattr(STDIN_FILENO, 0, &old_attr) < 0)
+		return -1;
+
+	// Restore the signal
+	sigaction(SIGINT, &osa, NULL);
+	if (signo)
+		raise(signo);
+#endif
+
+	return nread;
+}
+
+// Get a password from the user
+int getPW(char* pin, char* newPIN, CK_ULONG userType)
+{
+	char password1[MAX_PIN_LEN+1];
+	char password2[MAX_PIN_LEN+1];
+	size_t size = MAX_PIN_LEN+1;
+	int length = 0;
+
+	// Check if the user has provided a password
+	if (pin)
+	{
+		length = strlen(pin);
+		// Save the PIN if it has the correct length
+		if (length >= MIN_PIN_LEN && length <= MAX_PIN_LEN)
+			memcpy(password1, pin, length+1);
+	}
+
+	while (length < MIN_PIN_LEN || length > MAX_PIN_LEN)
+	{
+		if (userType == CKU_SO)
+		{
+			printf("=== SO PIN (%i-%i characters) ===\n",
+				MIN_PIN_LEN, MAX_PIN_LEN);
+			length = getpin("Please enter SO PIN: ",
+					password1, size);
+		}
+		else
+		{
+			printf("=== User PIN (%i-%i characters) ===\n",
+				MIN_PIN_LEN, MAX_PIN_LEN);
+			length = getpin("Please enter user PIN: ",
+					password1, size);
+		}
+
+		if (length < 0)
+			return 1;
+		if (length < MIN_PIN_LEN || length > MAX_PIN_LEN)
+		{
+			fprintf(stderr, "ERROR: The length of the PIN is out of range.\n");
+			length = 0;
+			continue;
+		}
+
+		if (userType == CKU_SO)
+		{
+			length = getpin("Please reenter SO PIN: ",
+					password2, size);
+		}
+		else
+		{
+			length = getpin("Please reenter user PIN: ",
+					password2, size);
+		}
+
+		if (length < 0)
+			return 1;
+		if (strcmp(password1, password2))
+		{
+			fprintf(stderr, "ERROR: The entered PINs are not equal.\n");
+			length = 0;
+			continue;
+		}
+	}
+
+	memcpy(newPIN, password1, length+1);
+	return 0;
+}
diff --git a/SoftHSMv2/src/bin/common/getpw.h b/SoftHSMv2/src/bin/common/getpw.h
new file mode 100644
index 0000000..1ca15a5
--- /dev/null
+++ b/SoftHSMv2/src/bin/common/getpw.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ getpw.h
+
+ Helper function to get a password from the user
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BIN_GETPW_H
+#define _SOFTHSM_V2_BIN_GETPW_H
+
+#include "cryptoki.h"
+
+int getPW(char* pin, char* newPIN, CK_ULONG userType);
+
+#endif // !_SOFTHSM_V2_BIN_GETPW_H
diff --git a/SoftHSMv2/src/bin/common/library.cpp b/SoftHSMv2/src/bin/common/library.cpp
new file mode 100644
index 0000000..af0dd93
--- /dev/null
+++ b/SoftHSMv2/src/bin/common/library.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ library.cpp
+
+ Support function for handling PKCS#11 libraries
+ *****************************************************************************/
+
+#include <config.h>
+#include "library.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#if defined(HAVE_DLOPEN)
+#include <dlfcn.h>
+#endif
+
+// Load the PKCS#11 library
+CK_C_GetFunctionList loadLibrary(char* module, void** moduleHandle,
+				char **pErrMsg)
+{
+	CK_C_GetFunctionList pGetFunctionList = NULL;
+
+#if defined(HAVE_LOADLIBRARY)
+	HINSTANCE hDLL = NULL;
+	DWORD dw = NULL;
+	static char errMsg[100];
+
+	// Load PKCS #11 library
+	if (module)
+	{
+		hDLL = LoadLibraryA(module);
+	}
+	else
+	{
+		hDLL = LoadLibraryA(DEFAULT_PKCS11_LIB);
+	}
+
+	if (hDLL == NULL)
+	{
+		// Failed to load the PKCS #11 library
+		dw = GetLastError();
+		snprintf((char*)errMsg, sizeof(errMsg), "LoadLibraryA failed: 0x%08X", dw);
+		*pErrMsg = errMsg;
+		return NULL;
+	}
+	else
+	{
+		*pErrMsg = NULL;
+	}
+
+	// Retrieve the entry point for C_GetFunctionList
+	pGetFunctionList = (CK_C_GetFunctionList) GetProcAddress(hDLL, "C_GetFunctionList");
+	if (pGetFunctionList == NULL)
+	{
+		dw = GetLastError();
+		snprintf((char*)errMsg, sizeof(errMsg), "getProcAddress failed: 0x%08X", dw);
+		*pErrMsg = errMsg;
+		FreeLibrary(hDLL);
+		return NULL;
+	}
+
+	// Store the handle so we can FreeLibrary it later
+	*moduleHandle = hDLL;
+
+#elif defined(HAVE_DLOPEN)
+	void* pDynLib = NULL;
+
+	// Load PKCS #11 library
+	if (module)
+	{
+		pDynLib = dlopen(module, RTLD_NOW | RTLD_LOCAL);
+	}
+	else
+	{
+		pDynLib = dlopen(DEFAULT_PKCS11_LIB, RTLD_NOW | RTLD_LOCAL);
+	}
+
+	*pErrMsg = dlerror();
+	if (pDynLib == NULL || *pErrMsg != NULL)
+	{
+		if (pDynLib != NULL) dlclose(pDynLib);
+
+		// Failed to load the PKCS #11 library
+		return NULL;
+	}
+
+	// Retrieve the entry point for C_GetFunctionList
+	pGetFunctionList = (CK_C_GetFunctionList) dlsym(pDynLib, "C_GetFunctionList");
+
+	// Store the handle so we can dlclose it later
+	*pErrMsg = dlerror();
+	if (*pErrMsg != NULL)
+	{
+		dlclose(pDynLib);
+
+		// An error occured during dlsym()
+		return NULL;
+	}
+
+	*moduleHandle = pDynLib;
+#else
+	fprintf(stderr, "ERROR: Not compiled with library support.\n");
+
+	return NULL;
+#endif
+
+	return pGetFunctionList;
+}
+
+void unloadLibrary(void* moduleHandle)
+{
+	if (moduleHandle)
+	{
+#if defined(HAVE_LOADLIBRARY)
+		FreeLibrary((HMODULE) moduleHandle);
+#elif defined(HAVE_DLOPEN)
+		dlclose(moduleHandle);
+#endif
+	}
+}
diff --git a/SoftHSMv2/src/bin/common/library.h b/SoftHSMv2/src/bin/common/library.h
new file mode 100644
index 0000000..6c6b3e4
--- /dev/null
+++ b/SoftHSMv2/src/bin/common/library.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ library.h
+
+ Support function for handling PKCS#11 libraries
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BIN_LIBRARY_H
+#define _SOFTHSM_V2_BIN_LIBRARY_H
+
+#include "cryptoki.h"
+
+CK_C_GetFunctionList loadLibrary(char* module, void** moduleHandle,
+				char **pErrMsg);
+void unloadLibrary(void* moduleHandle);
+
+#endif // !_SOFTHSM_V2_BIN_LIBRARY_H