2 * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
27 /*****************************************************************************
30 This program can be used for migrating SoftHSM v1 databases to any
31 PKCS#11 library. The default library is the libsofthsm2.so
32 *****************************************************************************/
35 #include "softhsm2-migrate.h"
52 #define sched_yield() SleepEx(0, 0)
58 printf("SoftHSM migration tool. From SoftHSM v1 database to PKCS#11.\n");
59 printf("Usage: softhsm2-migrate [OPTIONS]\n");
61 printf(" -h Shows this help screen.\n");
62 printf(" --help Shows this help screen.\n");
63 printf(" --db <path> The SoftHSM v1 database that is going to be migrated.\n");
64 printf(" --module <path> Use another PKCS#11 library than SoftHSM.\n");
65 printf(" --no-public-key Do not migrate the public key.\n");
66 printf(" --pin <PIN> The PIN for the normal user.\n");
67 printf(" --serial <number> Will use the token with a matching serial number.\n");
68 printf(" --slot <number> The slot where the token is located.\n");
69 printf(" --token <label> Will use the token with a matching token label.\n");
70 printf(" -v Show version info.\n");
71 printf(" --version Show version info.\n");
74 // Enumeration of the long options
87 // Text representation of the long options
88 static const struct option long_options[] = {
89 { "help", 0, NULL, OPT_HELP },
90 { "db", 1, NULL, OPT_DB },
91 { "module", 1, NULL, OPT_MODULE },
92 { "no-public-key", 0, NULL, OPT_NO_PUBLIC_KEY },
93 { "pin", 1, NULL, OPT_PIN },
94 { "serial", 1, NULL, OPT_SERIAL },
95 { "slot", 1, NULL, OPT_SLOT },
96 { "token" , 1, NULL, OPT_TOKEN },
97 { "version", 0, NULL, OPT_VERSION },
101 CK_FUNCTION_LIST_PTR p11;
103 // Prepared statements
104 sqlite3_stmt* select_an_attribute_sql = NULL;
105 sqlite3_stmt* select_object_ids_sql = NULL;
106 sqlite3_stmt* count_object_id_sql = NULL;
110 int main(int argc, char* argv[])
112 int option_index = 0;
116 char* userPIN = NULL;
129 CK_SLOT_ID slotID = 0;
137 while ((opt = getopt_long(argc, argv, "hv", long_options, &option_index)) != -1)
156 case OPT_NO_PUBLIC_KEY:
164 printf("%s\n", PACKAGE_VERSION);
176 // Get a pointer to the function list for PKCS#11 library
177 CK_C_GetFunctionList pGetFunctionList = loadLibrary(module, &moduleHandle, &errMsg);
178 if (pGetFunctionList == NULL)
180 fprintf(stderr, "ERROR: Could not load the PKCS#11 library/module: %s\n", errMsg);
181 fprintf(stderr, "ERROR: Please check log files for additional information.\n");
185 // Load the function list
186 (*pGetFunctionList)(&p11);
188 // Initialize the library
189 rv = p11->C_Initialize(NULL_PTR);
192 fprintf(stderr, "ERROR: Could not initialize the PKCS#11 library/module: %s\n", module ? module : DEFAULT_PKCS11_LIB);
193 fprintf(stderr, "ERROR: Please check log files for additional information.\n");
198 result = findSlot(slot, serial, token, slotID);
202 // Migrate the database
203 result = migrate(dbPath, slotID, userPIN, noPublicKey);
206 // Finalize the library
207 p11->C_Finalize(NULL_PTR);
208 unloadLibrary(moduleHandle);
213 // Migrate the database
214 int migrate(char* dbPath, CK_SLOT_ID slotID, char* userPIN, int noPublicKey)
216 CK_SESSION_HANDLE hSession;
222 fprintf(stderr, "ERROR: A path to the database must be supplied. "
223 "Use --db <path>\n");
234 // Connect to the PKCS#11 library
235 result = openP11(slotID, userPIN, &hSession);
242 // Prepare the statements
243 if (prepStatements(db))
245 fprintf(stderr, "ERROR: Could not prepare the statements\n");
251 // Start the migration
252 result = db2session(db, hSession, noPublicKey);
254 // Finalize the statements
261 fprintf(stderr, "ERROR: Unable to migrate all of the objects.\n");
265 printf("The database has been migrated to the new HSM\n");
271 // Prepare the statements
272 int prepStatements(sqlite3* db)
274 select_an_attribute_sql = NULL;
275 select_object_ids_sql = NULL;
276 count_object_id_sql = NULL;
278 const char select_an_attribute_str[] = "SELECT value,length FROM Attributes WHERE objectID = ? AND type = ?;";
279 const char select_object_ids_str[] = "SELECT objectID FROM Objects;";
280 const char count_object_id_str[] = "SELECT COUNT(objectID) FROM Objects;";
284 sqlite3_prepare_v2(db, select_an_attribute_str, -1, &select_an_attribute_sql, NULL) ||
285 sqlite3_prepare_v2(db, select_object_ids_str, -1, &select_object_ids_sql, NULL) ||
286 sqlite3_prepare_v2(db, count_object_id_str, -1, &count_object_id_sql, NULL)
295 // Finalize the statements
296 void finalStatements()
298 if (select_an_attribute_sql) sqlite3_finalize(select_an_attribute_sql);
299 if (select_object_ids_sql) sqlite3_finalize(select_object_ids_sql);
300 if (count_object_id_sql) sqlite3_finalize(count_object_id_sql);
303 // Open a connection to a valid SoftHSM v1 database
304 sqlite3* openDB(char* dbPath)
308 sqlite3_stmt* pragStatem = NULL;
312 result = sqlite3_open(dbPath, &db);
315 fprintf(stderr, "ERROR: Could not open token database. "
316 "Probably wrong path or privileges: %s\n", dbPath);
320 // Check the schema version
321 if (sqlite3_prepare_v2(db, "PRAGMA user_version;", -1, &pragStatem, NULL))
323 fprintf(stderr, "ERROR: Could not prepare a SQL statement\n");
327 if (sqlite3_step(pragStatem) == SQLITE_ROW)
329 dbVersion = sqlite3_column_int(pragStatem, 0);
330 sqlite3_finalize(pragStatem);
332 if (dbVersion != 100)
334 fprintf(stderr, "ERROR: Wrong database schema version: %s\n", dbPath);
341 fprintf(stderr, "ERROR: The token database has not been initialized by SoftHSM\n");
342 sqlite3_finalize(pragStatem);
347 // Check that the Token table exist
348 result = sqlite3_exec(db, "SELECT COUNT(variableID) FROM Token;", NULL, NULL, NULL);
351 fprintf(stderr, "ERROR: The Token table is missing the in database\n");
356 // Check that the Objects table exist
357 result = sqlite3_exec(db, "SELECT COUNT(objectID) FROM Objects;", NULL, NULL, NULL);
360 fprintf(stderr, "ERROR: The Objects table is missing the in database\n");
365 // Check that the Attributes table exist
366 result = sqlite3_exec(db, "SELECT COUNT(attributeID) FROM Attributes;", NULL, NULL, NULL);
369 fprintf(stderr, "ERROR: The Attributes table is missing in the database\n");
377 // Connect and login to the token
378 int openP11(CK_SLOT_ID slotID, char* userPIN, CK_SESSION_HANDLE* hSession)
380 char user_pin_copy[MAX_PIN_LEN+1];
383 rv = p11->C_OpenSession(slotID, CKF_SERIAL_SESSION | CKF_RW_SESSION,
384 NULL_PTR, NULL_PTR, hSession);
387 if (rv == CKR_SLOT_ID_INVALID)
389 fprintf(stderr, "ERROR: The given slot does not exist.\n");
393 fprintf(stderr, "ERROR: Could not open a session on the given slot.\n");
399 if (getPW(userPIN, user_pin_copy, CKU_USER) != 0)
401 fprintf(stderr, "ERROR: Could not get user PIN\n");
405 rv = p11->C_Login(*hSession, CKU_USER, (CK_UTF8CHAR_PTR)user_pin_copy, strlen(user_pin_copy));
408 if (rv == CKR_PIN_INCORRECT) {
409 fprintf(stderr, "ERROR: The given user PIN does not match the one in the token.\n");
413 fprintf(stderr, "ERROR: Could not log in on the token.\n");
421 // Migrate the database to the session
422 int db2session(sqlite3* db, CK_SESSION_HANDLE hSession, int noPublicKey)
424 CK_ULONG objectCount;
426 CK_OBJECT_HANDLE* objects = NULL;
427 CK_OBJECT_CLASS ckClass;
430 objects = getObjects(db, &objectCount);
433 fprintf(stderr, "ERROR: Could not find any objects in the database.\n");
437 // Loop over all objects
438 for (unsigned i = 0; i < objectCount; i++)
440 ckClass = getObjectClass(objects[i]);
445 if (noPublicKey) continue;
446 if (getKeyType(objects[i]) != CKK_RSA)
448 fprintf(stderr, "ERROR: Cannot export object %lu. Only supporting RSA keys. "
449 "Continuing.\n", objects[i]);
453 rv = dbRSAPub2session(db, objects[i], hSession);
456 case CKO_PRIVATE_KEY:
457 if (getKeyType(objects[i]) != CKK_RSA)
459 fprintf(stderr, "ERROR: Cannot export object %lu. Only supporting RSA keys. "
460 "Continuing.\n", objects[i]);
464 rv = dbRSAPriv2session(db, objects[i], hSession);
467 case CKO_VENDOR_DEFINED:
468 fprintf(stderr, "ERROR: Could not get the class of object %lu. "
469 "Continuing.\n", objects[i]);
473 fprintf(stderr, "ERROR: Not supporting class %lu in object %lu. "
474 "Continuing.\n", ckClass, objects[i]);
485 // Get the key type from key objects
486 CK_KEY_TYPE getKeyType(CK_OBJECT_HANDLE objectRef)
489 CK_KEY_TYPE retVal = CKK_VENDOR_DEFINED;
491 sqlite3_bind_int(select_an_attribute_sql, 1, objectRef);
492 sqlite3_bind_int(select_an_attribute_sql, 2, CKA_KEY_TYPE);
495 while ((retSQL = sqlite3_step(select_an_attribute_sql)) == SQLITE_BUSY)
501 if (retSQL == SQLITE_ROW)
503 CK_VOID_PTR pValue = (CK_VOID_PTR)sqlite3_column_blob(select_an_attribute_sql, 0);
504 CK_ULONG length = sqlite3_column_int(select_an_attribute_sql, 1);
506 if (pValue != NULL_PTR)
508 // 32/64-bit DB on 32/64-bit system
509 if (length == sizeof(CK_KEY_TYPE))
511 retVal = *(CK_KEY_TYPE*)pValue;
513 // 32-bit DB on 64-bit system (LP64)
514 else if (length == sizeof(unsigned int))
516 retVal = *(unsigned int*)pValue;
521 sqlite3_reset(select_an_attribute_sql);
526 // Get the class of the object
527 CK_OBJECT_CLASS getObjectClass(CK_OBJECT_HANDLE objectRef)
530 CK_OBJECT_CLASS retVal = CKO_VENDOR_DEFINED;
532 sqlite3_bind_int(select_an_attribute_sql, 1, objectRef);
533 sqlite3_bind_int(select_an_attribute_sql, 2, CKA_CLASS);
536 while ((retSQL = sqlite3_step(select_an_attribute_sql)) == SQLITE_BUSY)
542 if (retSQL == SQLITE_ROW)
544 CK_VOID_PTR pValue = (CK_VOID_PTR)sqlite3_column_blob(select_an_attribute_sql, 0);
545 CK_ULONG length = sqlite3_column_int(select_an_attribute_sql, 1);
547 if (pValue != NULL_PTR)
549 // 32/64-bit DB on 32/64-bit system
550 if (length == sizeof(CK_OBJECT_CLASS))
552 retVal = *(CK_OBJECT_CLASS*)pValue;
554 // 32-bit DB on 64-bit system (LP64)
555 else if (length == sizeof(unsigned int))
557 retVal = *(unsigned int*)pValue;
562 sqlite3_reset(select_an_attribute_sql);
567 // Get all object IDs
568 CK_OBJECT_HANDLE* getObjects(sqlite3* /*db*/, CK_ULONG* objectCount)
570 CK_ULONG objectsInDB;
571 CK_ULONG counter = 0;
572 CK_OBJECT_HANDLE* objectRefs = NULL;
577 // Find out how many objects we have.
578 while ((retSQL = sqlite3_step(count_object_id_sql)) == SQLITE_BUSY)
583 if (retSQL != SQLITE_ROW)
585 fprintf(stderr, "ERROR: Could not count the number of objects in the database\n");
586 sqlite3_reset(count_object_id_sql);
590 // Get the number of objects
591 objectsInDB = sqlite3_column_int(count_object_id_sql, 0);
592 sqlite3_reset(count_object_id_sql);
596 fprintf(stderr, "ERROR: There are not objects in the database\n");
600 // Create the object-reference buffer
601 objectRefs = (CK_OBJECT_HANDLE*)malloc(objectsInDB * sizeof(CK_OBJECT_HANDLE));
602 if (objectRefs == NULL)
604 fprintf(stderr, "ERROR: Could not allocate memory\n");
608 // Get all the object ids
611 ((retSQL = sqlite3_step(select_object_ids_sql)) == SQLITE_BUSY || retSQL == SQLITE_ROW) &&
612 counter < objectsInDB
615 if(retSQL == SQLITE_BUSY)
621 objectRefs[counter++] = sqlite3_column_int(select_object_ids_sql, 0);
624 *objectCount = counter;
626 sqlite3_reset(select_object_ids_sql);
631 // Extract the information about the public RSA key and save it in the token
632 int dbRSAPub2session(sqlite3* /*db*/, CK_OBJECT_HANDLE objectID, CK_SESSION_HANDLE hSession)
636 CK_OBJECT_HANDLE hKey;
638 CK_OBJECT_CLASS ckClass = CKO_PUBLIC_KEY;
639 CK_KEY_TYPE ckType = CKK_RSA;
641 // All required CK_ULONG attributes have known/fixed values.
642 // So no need read them from the DB and no need to handle
643 // convertion from 32-bit to 64-bit.
644 CK_ATTRIBUTE pubTemplate[] = {
645 { CKA_CLASS, &ckClass, sizeof(ckClass) },
646 { CKA_KEY_TYPE, &ckType, sizeof(ckType) },
647 { CKA_TOKEN, NULL, 0 },
648 { CKA_PRIVATE, NULL, 0 },
649 { CKA_MODIFIABLE, NULL, 0 },
650 { CKA_LABEL, NULL, 0 },
652 { CKA_START_DATE, NULL, 0 },
653 { CKA_END_DATE, NULL, 0 },
654 { CKA_DERIVE, NULL, 0 },
655 { CKA_SUBJECT, NULL, 0 },
656 { CKA_ENCRYPT, NULL, 0 },
657 { CKA_VERIFY, NULL, 0 },
658 { CKA_VERIFY_RECOVER, NULL, 0 },
659 { CKA_WRAP, NULL, 0 },
660 { CKA_MODULUS, NULL, 0 },
661 { CKA_PUBLIC_EXPONENT, NULL, 0 }
664 for (i = 2; i < 17; i++)
666 result = getAttribute(objectID, &pubTemplate[i]);
669 freeTemplate(pubTemplate, 2, 17);
674 rv = p11->C_CreateObject(hSession, pubTemplate, 17, &hKey);
677 fprintf(stderr, "ERROR %X: Could not save the public key in the token. "
678 "Skipping object %lu\n", (unsigned int)rv, objectID);
683 printf("Object %lu has been migrated\n", objectID);
686 freeTemplate(pubTemplate, 2, 17);
691 // Extract the information about the private RSA key and save it in the token
692 int dbRSAPriv2session(sqlite3* /*db*/, CK_OBJECT_HANDLE objectID, CK_SESSION_HANDLE hSession)
696 CK_OBJECT_HANDLE hKey;
698 CK_OBJECT_CLASS ckClass = CKO_PRIVATE_KEY;
700 // All required CK_ULONG attributes have known/fixed values.
701 // So no need read them from the DB and no need to handle
702 // convertion from 32-bit to 64-bit.
703 CK_ATTRIBUTE privTemplate[] = {
704 { CKA_CLASS, &ckClass, sizeof(ckClass) },
705 { CKA_TOKEN, NULL, 0 },
706 { CKA_PRIVATE, NULL, 0 },
707 { CKA_MODIFIABLE, NULL, 0 },
708 { CKA_LABEL, NULL, 0 },
709 { CKA_KEY_TYPE, NULL, 0 },
711 { CKA_START_DATE, NULL, 0 },
712 { CKA_END_DATE, NULL, 0 },
713 { CKA_DERIVE, NULL, 0 },
714 { CKA_SUBJECT, NULL, 0 },
715 { CKA_SENSITIVE, NULL, 0 },
716 { CKA_DECRYPT, NULL, 0 },
717 { CKA_SIGN, NULL, 0 },
718 { CKA_SIGN_RECOVER, NULL, 0 },
719 { CKA_UNWRAP, NULL, 0 },
720 { CKA_EXTRACTABLE, NULL, 0 },
721 { CKA_WRAP_WITH_TRUSTED, NULL, 0 },
722 { CKA_MODULUS, NULL, 0 },
723 { CKA_PUBLIC_EXPONENT, NULL, 0 },
724 { CKA_PRIVATE_EXPONENT, NULL, 0 },
725 { CKA_PRIME_1, NULL, 0 },
726 { CKA_PRIME_2, NULL, 0 }
727 // SoftHSM v1 did not store these values
728 // { CKA_EXPONENT_1, NULL, 0 },
729 // { CKA_EXPONENT_2, NULL, 0 },
730 // { CKA_COEFFICIENT, NULL, 0 }
733 for (i = 1; i < 23; i++)
735 result = getAttribute(objectID, &privTemplate[i]);
738 freeTemplate(privTemplate, 1, 23);
743 rv = p11->C_CreateObject(hSession, privTemplate, 23, &hKey);
746 fprintf(stderr, "ERROR %X: Could not save the private key in the token. "
747 "Skipping object %lu\n", (unsigned int)rv, objectID);
752 printf("Object %lu has been migrated\n", objectID);
755 freeTemplate(privTemplate, 1, 23);
760 // Get the value of the given attribute
761 int getAttribute(CK_OBJECT_HANDLE objectRef, CK_ATTRIBUTE* attTemplate)
766 sqlite3_bind_int(select_an_attribute_sql, 1, objectRef);
767 sqlite3_bind_int(select_an_attribute_sql, 2, attTemplate->type);
770 while ((retSQL = sqlite3_step(select_an_attribute_sql)) == SQLITE_BUSY)
776 if (retSQL == SQLITE_ROW)
778 CK_VOID_PTR pValue = (CK_VOID_PTR)sqlite3_column_blob(select_an_attribute_sql, 0);
779 CK_ULONG length = sqlite3_column_int(select_an_attribute_sql, 1);
783 attTemplate->pValue = malloc(length);
784 if (!attTemplate->pValue)
786 fprintf(stderr, "ERROR: Could not allocate memory. "
787 "Skipping object %lu\n", objectRef);
793 memcpy(attTemplate->pValue, pValue, length);
797 attTemplate->ulValueLen = length;
801 fprintf(stderr, "ERROR: Do not have attribute %lu. "
802 "Skipping object %lu\n", attTemplate->type, objectRef);
806 sqlite3_reset(select_an_attribute_sql);
811 // Free allocated memory in the template
812 void freeTemplate(CK_ATTRIBUTE* attTemplate, int startIndex, int size)
816 if (!attTemplate) return;
818 for (i = startIndex; i < size; i++)
820 if(attTemplate[i].pValue)
822 free(attTemplate[i].pValue);