Update SoftHSM v2.0 to the latest version
[aaf/sshsm.git] / SoftHSMv2 / src / bin / migrate / softhsm2-migrate.cpp
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  softhsm2-migrate.cpp
29
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  *****************************************************************************/
33
34 #include <config.h>
35 #include "softhsm2-migrate.h"
36 #include "findslot.h"
37 #include "getpw.h"
38 #include "library.h"
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <getopt.h>
43 #include <string.h>
44 #ifndef _WIN32
45 #include <unistd.h>
46 #endif
47 #include <iostream>
48 #include <fstream>
49 #include <sched.h>
50
51 #ifdef _WIN32
52 #define sched_yield() SleepEx(0, 0)
53 #endif
54
55 // Display the usage
56 void usage()
57 {
58         printf("SoftHSM migration tool. From SoftHSM v1 database to PKCS#11.\n");
59         printf("Usage: softhsm2-migrate [OPTIONS]\n");
60         printf("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");
72 }
73
74 // Enumeration of the long options
75 enum {
76         OPT_HELP = 0x100,
77         OPT_DB,
78         OPT_MODULE,
79         OPT_NO_PUBLIC_KEY,
80         OPT_PIN,
81         OPT_SERIAL,
82         OPT_SLOT,
83         OPT_TOKEN,
84         OPT_VERSION
85 };
86
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 },
98         { NULL,              0, NULL, 0 }
99 };
100
101 CK_FUNCTION_LIST_PTR p11;
102
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;
107
108
109 // The main function
110 int main(int argc, char* argv[])
111 {
112         int option_index = 0;
113         int opt;
114
115         char* dbPath = NULL;
116         char* userPIN = NULL;
117         char* module = NULL;
118         char* slot = NULL;
119         char* serial = NULL;
120         char* token = NULL;
121         char *errMsg = NULL;
122         int noPublicKey = 0;
123
124         int result = 0;
125         CK_RV rv;
126
127         moduleHandle = NULL;
128         p11 = NULL;
129         CK_SLOT_ID slotID = 0;
130
131         if (argc == 1)
132         {
133                 usage();
134                 exit(0);
135         }
136
137         while ((opt = getopt_long(argc, argv, "hv", long_options, &option_index)) != -1)
138         {
139                 switch (opt)
140                 {
141                         case OPT_DB:
142                                 dbPath = optarg;
143                                 break;
144                         case OPT_SLOT:
145                                 slot = optarg;
146                                 break;
147                         case OPT_SERIAL:
148                                 serial = optarg;
149                                 break;
150                         case OPT_TOKEN:
151                                 token = optarg;
152                                 break;
153                         case OPT_MODULE:
154                                 module = optarg;
155                                 break;
156                         case OPT_NO_PUBLIC_KEY:
157                                 noPublicKey = 1;
158                                 break;
159                         case OPT_PIN:
160                                 userPIN = optarg;
161                                 break;
162                         case OPT_VERSION:
163                         case 'v':
164                                 printf("%s\n", PACKAGE_VERSION);
165                                 exit(0);
166                                 break;
167                         case OPT_HELP:
168                         case 'h':
169                         default:
170                                 usage();
171                                 exit(0);
172                                 break;
173                 }
174         }
175
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)
179         {
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");
182                 exit(1);
183         }
184
185         // Load the function list
186         (*pGetFunctionList)(&p11);
187
188         // Initialize the library
189         rv = p11->C_Initialize(NULL_PTR);
190         if (rv != CKR_OK)
191         {
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");
194                 exit(1);
195         }
196
197         // Get the slotID
198         result = findSlot(slot, serial, token, slotID);
199
200         if (!result)
201         {
202                 // Migrate the database
203                 result = migrate(dbPath, slotID, userPIN, noPublicKey);
204         }
205
206         // Finalize the library
207         p11->C_Finalize(NULL_PTR);
208         unloadLibrary(moduleHandle);
209
210         return result;
211 }
212
213 // Migrate the database
214 int migrate(char* dbPath, CK_SLOT_ID slotID, char* userPIN, int noPublicKey)
215 {
216         CK_SESSION_HANDLE hSession;
217         sqlite3* db = NULL;
218         int result;
219
220         if (dbPath == NULL)
221         {
222                 fprintf(stderr, "ERROR: A path to the database must be supplied. "
223                                 "Use --db <path>\n");
224                 return 1;
225         }
226
227         // Open the database
228         db = openDB(dbPath);
229         if (db == NULL)
230         {
231                 return 1;
232         }
233
234         // Connect to the PKCS#11 library
235         result = openP11(slotID, userPIN, &hSession);
236         if (result)
237         {
238                 sqlite3_close(db);
239                 return result;
240         }
241
242         // Prepare the statements
243         if (prepStatements(db))
244         {
245                 fprintf(stderr, "ERROR: Could not prepare the statements\n");
246                 finalStatements();
247                 sqlite3_close(db);
248                 return 1;
249         }
250
251         // Start the migration
252         result = db2session(db, hSession, noPublicKey);
253
254         // Finalize the statements
255         finalStatements();
256
257         sqlite3_close(db);
258
259         if (result)
260         {
261                 fprintf(stderr, "ERROR: Unable to migrate all of the objects.\n");
262         }
263         else
264         {
265                 printf("The database has been migrated to the new HSM\n");
266         }
267
268         return result;
269 }
270
271 // Prepare the statements
272 int prepStatements(sqlite3* db)
273 {
274         select_an_attribute_sql = NULL;
275         select_object_ids_sql = NULL;
276         count_object_id_sql = NULL;
277
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;";
281
282         if
283         (
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)
287         )
288         {
289                 return 1;
290         }
291
292         return 0;
293 }
294
295 // Finalize the statements
296 void finalStatements()
297 {
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);
301 }
302
303 // Open a connection to a valid SoftHSM v1 database
304 sqlite3* openDB(char* dbPath)
305 {
306         int result;
307         sqlite3* db = NULL;
308         sqlite3_stmt* pragStatem = NULL;
309         int dbVersion;
310
311         // Open the database
312         result = sqlite3_open(dbPath, &db);
313         if (result)
314         {
315                 fprintf(stderr, "ERROR: Could not open token database. "
316                                 "Probably wrong path or privileges: %s\n", dbPath);
317                 return NULL;
318         }
319
320         // Check the schema version
321         if (sqlite3_prepare_v2(db, "PRAGMA user_version;", -1, &pragStatem, NULL))
322         {
323                 fprintf(stderr, "ERROR: Could not prepare a SQL statement\n");
324                 sqlite3_close(db);
325                 return NULL;
326         }
327         if (sqlite3_step(pragStatem) == SQLITE_ROW)
328         {
329                 dbVersion = sqlite3_column_int(pragStatem, 0);
330                 sqlite3_finalize(pragStatem);
331
332                 if (dbVersion != 100)
333                 {
334                         fprintf(stderr, "ERROR: Wrong database schema version: %s\n", dbPath);
335                         sqlite3_close(db);
336                         return NULL;
337                 }
338         }
339         else
340         {
341                 fprintf(stderr, "ERROR: The token database has not been initialized by SoftHSM\n");
342                 sqlite3_finalize(pragStatem);
343                 sqlite3_close(db);
344                 return NULL;
345         }
346
347         // Check that the Token table exist
348         result = sqlite3_exec(db, "SELECT COUNT(variableID) FROM Token;", NULL, NULL, NULL);
349         if (result)
350         {
351                 fprintf(stderr, "ERROR: The Token table is missing the in database\n");
352                 sqlite3_close(db);
353                 return NULL;
354         }
355
356         // Check that the Objects table exist
357         result = sqlite3_exec(db, "SELECT COUNT(objectID) FROM Objects;", NULL, NULL, NULL);
358         if (result)
359         {
360                 fprintf(stderr, "ERROR: The Objects table is missing the in database\n");
361                 sqlite3_close(db);
362                 return NULL;
363         }
364
365         // Check that the Attributes table exist
366         result = sqlite3_exec(db, "SELECT COUNT(attributeID) FROM Attributes;", NULL, NULL, NULL);
367         if (result)
368         {
369                 fprintf(stderr, "ERROR: The Attributes table is missing in the database\n");
370                 sqlite3_close(db);
371                 return NULL;
372         }
373
374         return db;
375 }
376
377 // Connect and login to the token
378 int openP11(CK_SLOT_ID slotID, char* userPIN, CK_SESSION_HANDLE* hSession)
379 {
380         char user_pin_copy[MAX_PIN_LEN+1];
381         CK_RV rv;
382
383         rv = p11->C_OpenSession(slotID, CKF_SERIAL_SESSION | CKF_RW_SESSION,
384                                         NULL_PTR, NULL_PTR, hSession);
385         if (rv != CKR_OK)
386         {
387                 if (rv == CKR_SLOT_ID_INVALID)
388                 {
389                         fprintf(stderr, "ERROR: The given slot does not exist.\n");
390                 }
391                 else
392                 {
393                         fprintf(stderr, "ERROR: Could not open a session on the given slot.\n");
394                 }
395                 return 1;
396         }
397
398         // Get the password
399         if (getPW(userPIN, user_pin_copy, CKU_USER) != 0)
400         {
401                 fprintf(stderr, "ERROR: Could not get user PIN\n");
402                 return 1;
403         }
404
405         rv = p11->C_Login(*hSession, CKU_USER, (CK_UTF8CHAR_PTR)user_pin_copy, strlen(user_pin_copy));
406         if (rv != CKR_OK)
407         {
408                 if (rv == CKR_PIN_INCORRECT) {
409                         fprintf(stderr, "ERROR: The given user PIN does not match the one in the token.\n");
410                 }
411                 else
412                 {
413                         fprintf(stderr, "ERROR: Could not log in on the token.\n");
414                 }
415                 return 1;
416         }
417
418         return 0;
419 }
420
421 // Migrate the database to the session
422 int db2session(sqlite3* db, CK_SESSION_HANDLE hSession, int noPublicKey)
423 {
424         CK_ULONG objectCount;
425         int result = 0, rv;
426         CK_OBJECT_HANDLE* objects = NULL;
427         CK_OBJECT_CLASS ckClass;
428
429         // Get all objects
430         objects = getObjects(db, &objectCount);
431         if (objects == NULL)
432         {
433                 fprintf(stderr, "ERROR: Could not find any objects in the database.\n");
434                 return 1;
435         }
436
437         // Loop over all objects
438         for (unsigned i = 0; i < objectCount; i++)
439         {
440                 ckClass = getObjectClass(objects[i]);
441
442                 switch (ckClass)
443                 {
444                         case CKO_PUBLIC_KEY:
445                                 if (noPublicKey) continue;
446                                 if (getKeyType(objects[i]) != CKK_RSA)
447                                 {
448                                         fprintf(stderr, "ERROR: Cannot export object %lu. Only supporting RSA keys. "
449                                                 "Continuing.\n", objects[i]);
450                                         result = 1;
451                                         break;
452                                 }
453                                 rv = dbRSAPub2session(db, objects[i], hSession);
454                                 if (rv) result = 1;
455                                 break;
456                         case CKO_PRIVATE_KEY:
457                                 if (getKeyType(objects[i]) != CKK_RSA)
458                                 {
459                                         fprintf(stderr, "ERROR: Cannot export object %lu. Only supporting RSA keys. "
460                                                 "Continuing.\n", objects[i]);
461                                         result = 1;
462                                         break;
463                                 }
464                                 rv = dbRSAPriv2session(db, objects[i], hSession);
465                                 if (rv) result = 1;
466                                 break;
467                         case CKO_VENDOR_DEFINED:
468                                 fprintf(stderr, "ERROR: Could not get the class of object %lu. "
469                                                 "Continuing.\n", objects[i]);
470                                 result = 1;
471                                 break;
472                         default:
473                                 fprintf(stderr, "ERROR: Not supporting class %lu in object %lu. "
474                                                 "Continuing.\n", ckClass, objects[i]);
475                                 result = 1;
476                                 break;
477                 }
478         }
479
480         free(objects);
481
482         return result;
483 }
484
485 // Get the key type from key objects
486 CK_KEY_TYPE getKeyType(CK_OBJECT_HANDLE objectRef)
487 {
488         int retSQL = 0;
489         CK_KEY_TYPE retVal = CKK_VENDOR_DEFINED;
490
491         sqlite3_bind_int(select_an_attribute_sql, 1, objectRef);
492         sqlite3_bind_int(select_an_attribute_sql, 2, CKA_KEY_TYPE);
493
494         // Get result
495         while ((retSQL = sqlite3_step(select_an_attribute_sql)) == SQLITE_BUSY)
496         {
497                 sched_yield();
498         }
499
500         // Get attribute
501         if (retSQL == SQLITE_ROW)
502         {
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);
505
506                 if (pValue != NULL_PTR)
507                 {
508                         // 32/64-bit DB on 32/64-bit system
509                         if (length == sizeof(CK_KEY_TYPE))
510                         {
511                                 retVal = *(CK_KEY_TYPE*)pValue;
512                         }
513                         // 32-bit DB on 64-bit system (LP64)
514                         else if (length == sizeof(unsigned int))
515                         {
516                                 retVal = *(unsigned int*)pValue;
517                         }
518                 }
519         }
520
521         sqlite3_reset(select_an_attribute_sql);
522
523         return retVal;
524 }
525
526 // Get the class of the object
527 CK_OBJECT_CLASS getObjectClass(CK_OBJECT_HANDLE objectRef)
528 {
529         int retSQL = 0;
530         CK_OBJECT_CLASS retVal = CKO_VENDOR_DEFINED;
531
532         sqlite3_bind_int(select_an_attribute_sql, 1, objectRef);
533         sqlite3_bind_int(select_an_attribute_sql, 2, CKA_CLASS);
534
535         // Get the result
536         while ((retSQL = sqlite3_step(select_an_attribute_sql)) == SQLITE_BUSY)
537         {
538                 sched_yield();
539         }
540
541         // Get attribute
542         if (retSQL == SQLITE_ROW)
543         {
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);
546
547                 if (pValue != NULL_PTR)
548                 {
549                         // 32/64-bit DB on 32/64-bit system
550                         if (length == sizeof(CK_OBJECT_CLASS))
551                         {
552                                 retVal = *(CK_OBJECT_CLASS*)pValue;
553                         }
554                         // 32-bit DB on 64-bit system (LP64)
555                         else if (length == sizeof(unsigned int))
556                         {
557                                 retVal = *(unsigned int*)pValue;
558                         }
559                 }
560         }
561
562         sqlite3_reset(select_an_attribute_sql);
563
564         return retVal;
565 }
566
567 // Get all object IDs
568 CK_OBJECT_HANDLE* getObjects(sqlite3* /*db*/, CK_ULONG* objectCount)
569 {
570         CK_ULONG objectsInDB;
571         CK_ULONG counter = 0;
572         CK_OBJECT_HANDLE* objectRefs = NULL;
573         int retSQL = 0;
574
575         *objectCount = 0;
576
577         // Find out how many objects we have.
578         while ((retSQL = sqlite3_step(count_object_id_sql)) == SQLITE_BUSY)
579         {
580                 sched_yield();
581         }
582
583         if (retSQL != SQLITE_ROW)
584         {
585                 fprintf(stderr, "ERROR: Could not count the number of objects in the database\n");
586                 sqlite3_reset(count_object_id_sql);
587                 return NULL;
588         }
589
590         // Get the number of objects
591         objectsInDB = sqlite3_column_int(count_object_id_sql, 0);
592         sqlite3_reset(count_object_id_sql);
593
594         if (!objectsInDB)
595         {
596                 fprintf(stderr, "ERROR: There are not objects in the database\n");
597                 return NULL;
598         }
599
600         // Create the object-reference buffer
601         objectRefs = (CK_OBJECT_HANDLE*)malloc(objectsInDB * sizeof(CK_OBJECT_HANDLE));
602         if (objectRefs == NULL)
603         {
604                 fprintf(stderr, "ERROR: Could not allocate memory\n");
605                 return NULL;
606         }
607
608         // Get all the object ids
609         while
610         (
611                 ((retSQL = sqlite3_step(select_object_ids_sql)) == SQLITE_BUSY || retSQL == SQLITE_ROW) &&
612                 counter < objectsInDB
613         )
614         {
615                 if(retSQL == SQLITE_BUSY)
616                 {
617                         sched_yield();
618                         continue;
619                 }
620
621                 objectRefs[counter++] = sqlite3_column_int(select_object_ids_sql, 0);
622         }
623
624         *objectCount = counter;
625
626         sqlite3_reset(select_object_ids_sql);
627
628         return objectRefs;
629 }
630
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)
633 {
634         int result = 0;
635         int i;
636         CK_OBJECT_HANDLE hKey;
637         CK_RV rv;
638         CK_OBJECT_CLASS ckClass = CKO_PUBLIC_KEY;
639         CK_KEY_TYPE ckType = CKK_RSA;
640
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 },
651                 { CKA_ID,               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 }
662         };
663
664         for (i = 2; i < 17; i++)
665         {
666                 result = getAttribute(objectID, &pubTemplate[i]);
667                 if (result)
668                 {
669                         freeTemplate(pubTemplate, 2, 17);
670                         return 1;
671                 }
672         }
673
674         rv = p11->C_CreateObject(hSession, pubTemplate, 17, &hKey);
675         if (rv != CKR_OK)
676         {
677                 fprintf(stderr, "ERROR %X: Could not save the public key in the token. "
678                                 "Skipping object %lu\n", (unsigned int)rv, objectID);
679                 result = 1;
680         }
681         else
682         {
683                 printf("Object %lu has been migrated\n", objectID);
684         }
685
686         freeTemplate(pubTemplate, 2, 17);
687
688         return result;
689 }
690
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)
693 {
694         int result = 0;
695         int i;
696         CK_OBJECT_HANDLE hKey;
697         CK_RV rv;
698         CK_OBJECT_CLASS ckClass = CKO_PRIVATE_KEY;
699
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 },
710                 { CKA_ID,                       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 }
731         };
732
733         for (i = 1; i < 23; i++)
734         {
735                 result = getAttribute(objectID, &privTemplate[i]);
736                 if (result)
737                 {
738                         freeTemplate(privTemplate, 1, 23);
739                         return 1;
740                 }
741         }
742
743         rv = p11->C_CreateObject(hSession, privTemplate, 23, &hKey);
744         if (rv != CKR_OK)
745         {
746                 fprintf(stderr, "ERROR %X: Could not save the private key in the token. "
747                                 "Skipping object %lu\n", (unsigned int)rv, objectID);
748                 result = 1;
749         }
750         else
751         {
752                 printf("Object %lu has been migrated\n", objectID);
753         }
754
755         freeTemplate(privTemplate, 1, 23);
756
757         return result;
758 }
759
760 // Get the value of the given attribute
761 int getAttribute(CK_OBJECT_HANDLE objectRef, CK_ATTRIBUTE* attTemplate)
762 {
763         int retSQL = 0;
764         int retVal = 0;
765
766         sqlite3_bind_int(select_an_attribute_sql, 1, objectRef);
767         sqlite3_bind_int(select_an_attribute_sql, 2, attTemplate->type);
768
769         // Get result
770         while ((retSQL = sqlite3_step(select_an_attribute_sql)) == SQLITE_BUSY)
771         {
772                 sched_yield();
773         }
774
775         // Get the attribute
776         if (retSQL == SQLITE_ROW)
777         {
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);
780
781                 if (length)
782                 {
783                         attTemplate->pValue = malloc(length);
784                         if (!attTemplate->pValue)
785                         {
786                                 fprintf(stderr, "ERROR: Could not allocate memory. "
787                                                 "Skipping object %lu\n", objectRef);
788                                 retVal = 1;
789                         }
790                         else
791                         {
792                                 // Copy data
793                                 memcpy(attTemplate->pValue, pValue, length);
794                         }
795                 }
796
797                 attTemplate->ulValueLen = length;
798         }
799         else
800         {
801                 fprintf(stderr, "ERROR: Do not have attribute %lu. "
802                                 "Skipping object %lu\n", attTemplate->type, objectRef);
803                 retVal = 1;
804         }
805
806         sqlite3_reset(select_an_attribute_sql);
807
808         return retVal;
809 }
810
811 // Free allocated memory in the template
812 void freeTemplate(CK_ATTRIBUTE* attTemplate, int startIndex, int size)
813 {
814         int i;
815
816         if (!attTemplate) return;
817
818         for (i = startIndex; i < size; i++)
819         {
820                 if(attTemplate[i].pValue)
821                 {
822                         free(attTemplate[i].pValue);
823                 }
824         }
825 }