@@ -101,10 +101,17 @@ void usage()
101
101
printf (" WARNING: Any content in token will be erased.\n " );
102
102
printf (" -h Shows this help screen.\n " );
103
103
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> Import an object from the given path.\n " );
105
+ printf (" Use with --import-type, --slot or --token or --serial,\n " );
106
+ printf (" --file-pin, --label, --id, --no-public-key, and --pin.\n " );
107
+ printf (" --import-type <type>\n " );
108
+ printf (" Import object type, type may be one of:\n " );
109
+ printf (" keypair [default]\n " );
110
+ printf (" The file must be in PKCS#8 PEM format.\n " );
111
+ printf (" aes\n " );
112
+ printf (" The file must be in binary format.\n " );
113
+ printf (" cert\n " );
114
+ printf (" The file must be in X509 PEM format.\n " );
108
115
printf (" --init-token Initialize the token at a given slot.\n " );
109
116
printf (" Use with --slot or --token or --serial or --free,\n " );
110
117
printf (" --label, --so-pin, and --pin.\n " );
@@ -118,6 +125,7 @@ void usage()
118
125
printf (" --version Show version info.\n " );
119
126
printf (" Options:\n " );
120
127
printf (" --aes Used to tell import to use file as is and import it as AES.\n " );
128
+ printf (" Deprecated, use '--import-type aes'.\n " );
121
129
printf (" --file-pin <PIN> Supply a PIN if the file is encrypted.\n " );
122
130
printf (" --force Used to override a warning.\n " );
123
131
printf (" --free Use the first free/uninitialized token.\n " );
@@ -134,6 +142,13 @@ void usage()
134
142
printf (" --token <label> Will use the token with a matching token label.\n " );
135
143
}
136
144
145
+ // Enumeration of import types
146
+ enum {
147
+ IMPORT_TYPE_KEYPAIR,
148
+ IMPORT_TYPE_AES,
149
+ IMPORT_TYPE_CERT
150
+ };
151
+
137
152
// Enumeration of the long options
138
153
enum {
139
154
OPT_DELETE_TOKEN = 0x100 ,
@@ -143,6 +158,7 @@ enum {
143
158
OPT_HELP,
144
159
OPT_ID,
145
160
OPT_IMPORT,
161
+ OPT_IMPORT_TYPE,
146
162
OPT_INIT_TOKEN,
147
163
OPT_LABEL,
148
164
OPT_MODULE,
@@ -167,6 +183,7 @@ static const struct option long_options[] = {
167
183
{ " help" , 0 , NULL , OPT_HELP },
168
184
{ " id" , 1 , NULL , OPT_ID },
169
185
{ " import" , 1 , NULL , OPT_IMPORT },
186
+ { " import-type" , 1 , NULL , OPT_IMPORT_TYPE },
170
187
{ " init-token" , 0 , NULL , OPT_INIT_TOKEN },
171
188
{ " label" , 1 , NULL , OPT_LABEL },
172
189
{ " module" , 1 , NULL , OPT_MODULE },
@@ -205,7 +222,7 @@ int main(int argc, char* argv[])
205
222
int forceExec = 0 ;
206
223
bool freeToken = false ;
207
224
int noPublicKey = 0 ;
208
- bool importAES = false ;
225
+ int importType = IMPORT_TYPE_KEYPAIR ;
209
226
210
227
int doInitToken = 0 ;
211
228
int doShowSlots = 0 ;
@@ -251,8 +268,20 @@ int main(int argc, char* argv[])
251
268
inPath = optarg ;
252
269
needP11 = true ;
253
270
break ;
271
+ case OPT_IMPORT_TYPE:
272
+ if (!strcmp (optarg , " keypair" ))
273
+ importType = IMPORT_TYPE_KEYPAIR;
274
+ else if (!strcmp (optarg , " aes" ))
275
+ importType = IMPORT_TYPE_AES;
276
+ else if (!strcmp (optarg , " cert" ))
277
+ importType = IMPORT_TYPE_CERT;
278
+ else
279
+ {
280
+ fprintf (stderr, " ERROR: Invalid import type '%s'\n " , optarg );
281
+ }
282
+ break ;
254
283
case OPT_AES:
255
- importAES = true ;
284
+ importType = IMPORT_TYPE_AES ;
256
285
break ;
257
286
case OPT_DELETE_TOKEN:
258
287
doDeleteToken = 1 ;
@@ -370,8 +399,22 @@ int main(int argc, char* argv[])
370
399
rv = findSlot (slot, serial, token, slotID);
371
400
if (!rv)
372
401
{
373
- rv = importAES ? importSecretKey (inPath, slotID, userPIN, label, objectID)
374
- : importKeyPair (inPath, filePIN, slotID, userPIN, label, objectID, forceExec, noPublicKey);
402
+ switch (importType)
403
+ {
404
+ case IMPORT_TYPE_KEYPAIR:
405
+ rv = importKeyPair (inPath, filePIN, slotID, userPIN, label, objectID, forceExec, noPublicKey);
406
+ break ;
407
+ case IMPORT_TYPE_AES:
408
+ rv = importSecretKey (inPath, slotID, userPIN, label, objectID);
409
+ break ;
410
+ case IMPORT_TYPE_CERT:
411
+ rv = importCertificate (inPath, slotID, userPIN, label, objectID, forceExec);
412
+ break ;
413
+ default :
414
+ fprintf (stderr, " Invalid importType %d.\n " , importType);
415
+ rv = 1 ;
416
+ break ;
417
+ }
375
418
}
376
419
}
377
420
@@ -1117,7 +1160,7 @@ int importKeyPair
1117
1160
return 1 ;
1118
1161
}
1119
1162
1120
- CK_OBJECT_HANDLE oHandle = searchObject (hSession, objID, objIDLen);
1163
+ CK_OBJECT_HANDLE oHandle = searchObject (hSession, CKO_PRIVATE_KEY, objID, objIDLen);
1121
1164
if (oHandle != CK_INVALID_HANDLE && forceExec == 0 )
1122
1165
{
1123
1166
free (objID);
@@ -1205,6 +1248,98 @@ int importSecretKey(char* filePath, CK_SLOT_ID slotID, char* userPIN, char* labe
1205
1248
return result;
1206
1249
}
1207
1250
1251
+ // Import a certificate from given path
1252
+ int importCertificate
1253
+ (
1254
+ char * filePath,
1255
+ CK_SLOT_ID slotID,
1256
+ char * userPIN,
1257
+ char * label,
1258
+ char * objectID,
1259
+ int forceExec
1260
+ )
1261
+ {
1262
+ char user_pin_copy[MAX_PIN_LEN+1 ] = {0 };
1263
+
1264
+ if (label == NULL )
1265
+ {
1266
+ fprintf (stderr, " ERROR: A label for the object must be supplied. "
1267
+ " Use --label <text>\n " );
1268
+ return 1 ;
1269
+ }
1270
+
1271
+ if (objectID == NULL )
1272
+ {
1273
+ fprintf (stderr, " ERROR: An ID for the object must be supplied. "
1274
+ " Use --id <hex>\n " );
1275
+ return 1 ;
1276
+ }
1277
+
1278
+ size_t objIDLen = 0 ;
1279
+ char * objID = hexStrToBin (objectID, strlen (objectID), &objIDLen);
1280
+ if (objID == NULL )
1281
+ {
1282
+ fprintf (stderr, " Please edit --id <hex> to correct error.\n " );
1283
+ return 1 ;
1284
+ }
1285
+
1286
+ CK_SESSION_HANDLE hSession;
1287
+ CK_RV rv = p11->C_OpenSession (slotID, CKF_SERIAL_SESSION | CKF_RW_SESSION,
1288
+ NULL_PTR, NULL_PTR, &hSession);
1289
+ if (rv != CKR_OK)
1290
+ {
1291
+ if (rv == CKR_SLOT_ID_INVALID)
1292
+ {
1293
+ fprintf (stderr, " ERROR: The given slot does not exist.\n " );
1294
+ }
1295
+ else
1296
+ {
1297
+ fprintf (stderr, " ERROR: Could not open a session on the given slot.\n " );
1298
+ }
1299
+ free (objID);
1300
+ return 1 ;
1301
+ }
1302
+
1303
+ // Get the password
1304
+ if (getPW (userPIN, user_pin_copy, CKU_USER) != 0 )
1305
+ {
1306
+ fprintf (stderr, " ERROR: Could not get user PIN\n " );
1307
+ free (objID);
1308
+ return 1 ;
1309
+ }
1310
+
1311
+ rv = p11->C_Login (hSession, CKU_USER, (CK_UTF8CHAR_PTR)user_pin_copy, strlen (user_pin_copy));
1312
+ if (rv != CKR_OK)
1313
+ {
1314
+ if (rv == CKR_PIN_INCORRECT) {
1315
+ fprintf (stderr, " ERROR: The given user PIN does not match the one in the token.\n " );
1316
+ }
1317
+ else
1318
+ {
1319
+ fprintf (stderr, " ERROR: Could not log in on the token.\n " );
1320
+ }
1321
+ free (objID);
1322
+ return 1 ;
1323
+ }
1324
+
1325
+ CK_OBJECT_HANDLE oHandle = searchObject (hSession, CKO_CERTIFICATE, objID, objIDLen);
1326
+ if (oHandle != CK_INVALID_HANDLE && forceExec == 0 )
1327
+ {
1328
+ free (objID);
1329
+ fprintf (stderr, " ERROR: The ID is already assigned to another object. "
1330
+ " Use --force to override this message.\n " );
1331
+ return 1 ;
1332
+ }
1333
+
1334
+ crypto_init ();
1335
+ int result = crypto_import_certificate (hSession, filePath, label, objID, objIDLen);
1336
+ crypto_final ();
1337
+
1338
+ free (objID);
1339
+
1340
+ return result;
1341
+ }
1342
+
1208
1343
// Convert a char array of hexadecimal characters into a binary representation
1209
1344
char * hexStrToBin (char * objectID, int idLength, size_t * newLen)
1210
1345
{
@@ -1291,14 +1426,13 @@ int hexdigit_to_int(char ch)
1291
1426
}
1292
1427
1293
1428
// Search for an object
1294
- CK_OBJECT_HANDLE searchObject (CK_SESSION_HANDLE hSession, char * objID, size_t objIDLen)
1429
+ CK_OBJECT_HANDLE searchObject (CK_SESSION_HANDLE hSession, CK_OBJECT_CLASS oClass, char * objID, size_t objIDLen)
1295
1430
{
1296
1431
if (objID == NULL )
1297
1432
{
1298
1433
return CK_INVALID_HANDLE;
1299
1434
}
1300
1435
1301
- CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY;
1302
1436
CK_OBJECT_HANDLE hObject = CK_INVALID_HANDLE;
1303
1437
CK_ULONG objectCount = 0 ;
1304
1438
0 commit comments