@@ -101,10 +101,18 @@ void usage()
101101 printf (" WARNING: Any content in token will be erased.\n " );
102102 printf (" -h Shows this help screen.\n " );
103103 printf (" --help Shows this help screen.\n " );
104- printf (" --import <path> Import a key pair from the given path.\n " );
105- printf (" The file must be in PKCS#8-format.\n " );
106- printf (" Use with --slot or --token or --serial, --file-pin,\n " );
107- printf (" --label, --id, --no-public-key, and --pin.\n " );
104+ printf (" --import <path>\n " );
105+ printf (" Import an object from the given path.\n " );
106+ printf (" Use with --import-type, --slot or --token or --serial,\n " );
107+ printf (" --file-pin, --label, --id, --no-public-key, and --pin.\n " );
108+ printf (" --import-type <type>\n " );
109+ printf (" Import object type, may be one of:\n " );
110+ printf (" keypair [default]\n " );
111+ printf (" The file must be in PKCS#8 PEM format.\n " );
112+ printf (" aes\n " );
113+ printf (" The file must be in binary format.\n " );
114+ printf (" cert\n " );
115+ printf (" The file must be in X509 PEM format.\n " );
108116 printf (" --init-token Initialize the token at a given slot.\n " );
109117 printf (" Use with --slot or --token or --serial or --free,\n " );
110118 printf (" --label, --so-pin, and --pin.\n " );
@@ -114,6 +122,7 @@ void usage()
114122 printf (" --version Show version info.\n " );
115123 printf (" Options:\n " );
116124 printf (" --aes Used to tell import to use file as is and import it as AES.\n " );
125+ printf (" Deprecated, use '--import-type aes'.\n " );
117126 printf (" --file-pin <PIN> Supply a PIN if the file is encrypted.\n " );
118127 printf (" --force Used to override a warning.\n " );
119128 printf (" --free Use the first free/uninitialized token.\n " );
@@ -130,6 +139,13 @@ void usage()
130139 printf (" --token <label> Will use the token with a matching token label.\n " );
131140}
132141
142+ // Enumeration of import types
143+ enum {
144+ IMPORT_TYPE_KEYPAIR,
145+ IMPORT_TYPE_AES,
146+ IMPORT_TYPE_CERT
147+ };
148+
133149// Enumeration of the long options
134150enum {
135151 OPT_DELETE_TOKEN = 0x100 ,
@@ -139,6 +155,7 @@ enum {
139155 OPT_HELP,
140156 OPT_ID,
141157 OPT_IMPORT,
158+ OPT_IMPORT_TYPE,
142159 OPT_INIT_TOKEN,
143160 OPT_LABEL,
144161 OPT_MODULE,
@@ -162,6 +179,7 @@ static const struct option long_options[] = {
162179 { " help" , 0 , NULL , OPT_HELP },
163180 { " id" , 1 , NULL , OPT_ID },
164181 { " import" , 1 , NULL , OPT_IMPORT },
182+ { " import-type" , 1 , NULL , OPT_IMPORT_TYPE },
165183 { " init-token" , 0 , NULL , OPT_INIT_TOKEN },
166184 { " label" , 1 , NULL , OPT_LABEL },
167185 { " module" , 1 , NULL , OPT_MODULE },
@@ -199,7 +217,7 @@ int main(int argc, char* argv[])
199217 int forceExec = 0 ;
200218 bool freeToken = false ;
201219 int noPublicKey = 0 ;
202- bool importAES = false ;
220+ int importType = IMPORT_TYPE_KEYPAIR ;
203221
204222 int doInitToken = 0 ;
205223 int doShowSlots = 0 ;
@@ -233,8 +251,20 @@ int main(int argc, char* argv[])
233251 inPath = optarg;
234252 needP11 = true ;
235253 break ;
254+ case OPT_IMPORT_TYPE:
255+ if (!strcmp (optarg, " keypair" ))
256+ importType = IMPORT_TYPE_KEYPAIR;
257+ else if (!strcmp (optarg, " aes" ))
258+ importType = IMPORT_TYPE_AES;
259+ else if (!strcmp (optarg, " cert" ))
260+ importType = IMPORT_TYPE_CERT;
261+ else
262+ {
263+ fprintf (stderr, " ERROR: Invalid import type '%s'\n " , optarg);
264+ }
265+ break ;
236266 case OPT_AES:
237- importAES = true ;
267+ importType = IMPORT_TYPE_AES ;
238268 break ;
239269 case OPT_DELETE_TOKEN:
240270 doDeleteToken = 1 ;
@@ -352,8 +382,17 @@ int main(int argc, char* argv[])
352382 rv = findSlot (slot, serial, token, slotID);
353383 if (!rv)
354384 {
355- rv = importAES ? importSecretKey (inPath, slotID, userPIN, label, objectID)
356- : importKeyPair (inPath, filePIN, slotID, userPIN, label, objectID, forceExec, noPublicKey);
385+ switch (importType)
386+ {
387+ case IMPORT_TYPE_KEYPAIR:
388+ rv = importKeyPair (inPath, filePIN, slotID, userPIN, label, objectID, forceExec, noPublicKey);
389+ break ;
390+ case IMPORT_TYPE_AES:
391+ rv = importSecretKey (inPath, slotID, userPIN, label, objectID);
392+ break ;
393+ case IMPORT_TYPE_CERT:
394+ rv = importCertificate (inPath, slotID, userPIN, label, objectID, forceExec);
395+ }
357396 }
358397 }
359398
@@ -1099,7 +1138,7 @@ int importKeyPair
10991138 return 1 ;
11001139 }
11011140
1102- CK_OBJECT_HANDLE oHandle = searchObject (hSession, objID, objIDLen);
1141+ CK_OBJECT_HANDLE oHandle = searchObject (hSession, CKO_PRIVATE_KEY, objID, objIDLen);
11031142 if (oHandle != CK_INVALID_HANDLE && forceExec == 0 )
11041143 {
11051144 free (objID);
@@ -1187,6 +1226,98 @@ int importSecretKey(char* filePath, CK_SLOT_ID slotID, char* userPIN, char* labe
11871226 return result;
11881227}
11891228
1229+ // Import a certificate from given path
1230+ int importCertificate
1231+ (
1232+ char * filePath,
1233+ CK_SLOT_ID slotID,
1234+ char * userPIN,
1235+ char * label,
1236+ char * objectID,
1237+ int forceExec
1238+ )
1239+ {
1240+ char user_pin_copy[MAX_PIN_LEN+1 ];
1241+
1242+ if (label == NULL )
1243+ {
1244+ fprintf (stderr, " ERROR: A label for the object must be supplied. "
1245+ " Use --label <text>\n " );
1246+ return 1 ;
1247+ }
1248+
1249+ if (objectID == NULL )
1250+ {
1251+ fprintf (stderr, " ERROR: An ID for the object must be supplied. "
1252+ " Use --id <hex>\n " );
1253+ return 1 ;
1254+ }
1255+
1256+ size_t objIDLen = 0 ;
1257+ char * objID = hexStrToBin (objectID, strlen (objectID), &objIDLen);
1258+ if (objID == NULL )
1259+ {
1260+ fprintf (stderr, " Please edit --id <hex> to correct error.\n " );
1261+ return 1 ;
1262+ }
1263+
1264+ CK_SESSION_HANDLE hSession;
1265+ CK_RV rv = p11->C_OpenSession (slotID, CKF_SERIAL_SESSION | CKF_RW_SESSION,
1266+ NULL_PTR, NULL_PTR, &hSession);
1267+ if (rv != CKR_OK)
1268+ {
1269+ if (rv == CKR_SLOT_ID_INVALID)
1270+ {
1271+ fprintf (stderr, " ERROR: The given slot does not exist.\n " );
1272+ }
1273+ else
1274+ {
1275+ fprintf (stderr, " ERROR: Could not open a session on the given slot.\n " );
1276+ }
1277+ free (objID);
1278+ return 1 ;
1279+ }
1280+
1281+ // Get the password
1282+ if (getPW (userPIN, user_pin_copy, CKU_USER) != 0 )
1283+ {
1284+ fprintf (stderr, " ERROR: Could not get user PIN\n " );
1285+ free (objID);
1286+ return 1 ;
1287+ }
1288+
1289+ rv = p11->C_Login (hSession, CKU_USER, (CK_UTF8CHAR_PTR)user_pin_copy, strlen (user_pin_copy));
1290+ if (rv != CKR_OK)
1291+ {
1292+ if (rv == CKR_PIN_INCORRECT) {
1293+ fprintf (stderr, " ERROR: The given user PIN does not match the one in the token.\n " );
1294+ }
1295+ else
1296+ {
1297+ fprintf (stderr, " ERROR: Could not log in on the token.\n " );
1298+ }
1299+ free (objID);
1300+ return 1 ;
1301+ }
1302+
1303+ CK_OBJECT_HANDLE oHandle = searchObject (hSession, CKO_CERTIFICATE, objID, objIDLen);
1304+ if (oHandle != CK_INVALID_HANDLE && forceExec == 0 )
1305+ {
1306+ free (objID);
1307+ fprintf (stderr, " ERROR: The ID is already assigned to another object. "
1308+ " Use --force to override this message.\n " );
1309+ return 1 ;
1310+ }
1311+
1312+ crypto_init ();
1313+ int result = crypto_import_certificate (hSession, filePath, label, objID, objIDLen);
1314+ crypto_final ();
1315+
1316+ free (objID);
1317+
1318+ return result;
1319+ }
1320+
11901321// Convert a char array of hexadecimal characters into a binary representation
11911322char * hexStrToBin (char * objectID, int idLength, size_t * newLen)
11921323{
@@ -1273,14 +1404,13 @@ int hexdigit_to_int(char ch)
12731404}
12741405
12751406// Search for an object
1276- CK_OBJECT_HANDLE searchObject (CK_SESSION_HANDLE hSession, char * objID, size_t objIDLen)
1407+ CK_OBJECT_HANDLE searchObject (CK_SESSION_HANDLE hSession, CK_OBJECT_CLASS oClass, char * objID, size_t objIDLen)
12771408{
12781409 if (objID == NULL )
12791410 {
12801411 return CK_INVALID_HANDLE;
12811412 }
12821413
1283- CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY;
12841414 CK_OBJECT_HANDLE hObject = CK_INVALID_HANDLE;
12851415 CK_ULONG objectCount = 0 ;
12861416
0 commit comments