@@ -101,10 +101,18 @@ 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>\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 " );
108
116
printf (" --init-token Initialize the token at a given slot.\n " );
109
117
printf (" Use with --slot or --token or --serial or --free,\n " );
110
118
printf (" --label, --so-pin, and --pin.\n " );
@@ -114,6 +122,7 @@ void usage()
114
122
printf (" --version Show version info.\n " );
115
123
printf (" Options:\n " );
116
124
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 " );
117
126
printf (" --file-pin <PIN> Supply a PIN if the file is encrypted.\n " );
118
127
printf (" --force Used to override a warning.\n " );
119
128
printf (" --free Use the first free/uninitialized token.\n " );
@@ -130,6 +139,13 @@ void usage()
130
139
printf (" --token <label> Will use the token with a matching token label.\n " );
131
140
}
132
141
142
+ // Enumeration of import types
143
+ enum {
144
+ IMPORT_TYPE_KEYPAIR,
145
+ IMPORT_TYPE_AES,
146
+ IMPORT_TYPE_CERT
147
+ };
148
+
133
149
// Enumeration of the long options
134
150
enum {
135
151
OPT_DELETE_TOKEN = 0x100 ,
@@ -139,6 +155,7 @@ enum {
139
155
OPT_HELP,
140
156
OPT_ID,
141
157
OPT_IMPORT,
158
+ OPT_IMPORT_TYPE,
142
159
OPT_INIT_TOKEN,
143
160
OPT_LABEL,
144
161
OPT_MODULE,
@@ -162,6 +179,7 @@ static const struct option long_options[] = {
162
179
{ " help" , 0 , NULL , OPT_HELP },
163
180
{ " id" , 1 , NULL , OPT_ID },
164
181
{ " import" , 1 , NULL , OPT_IMPORT },
182
+ { " import-type" , 1 , NULL , OPT_IMPORT_TYPE },
165
183
{ " init-token" , 0 , NULL , OPT_INIT_TOKEN },
166
184
{ " label" , 1 , NULL , OPT_LABEL },
167
185
{ " module" , 1 , NULL , OPT_MODULE },
@@ -199,7 +217,7 @@ int main(int argc, char* argv[])
199
217
int forceExec = 0 ;
200
218
bool freeToken = false ;
201
219
int noPublicKey = 0 ;
202
- bool importAES = false ;
220
+ int importType = IMPORT_TYPE_KEYPAIR ;
203
221
204
222
int doInitToken = 0 ;
205
223
int doShowSlots = 0 ;
@@ -233,8 +251,20 @@ int main(int argc, char* argv[])
233
251
inPath = optarg ;
234
252
needP11 = true ;
235
253
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 ;
236
266
case OPT_AES:
237
- importAES = true ;
267
+ importType = IMPORT_TYPE_AES ;
238
268
break ;
239
269
case OPT_DELETE_TOKEN:
240
270
doDeleteToken = 1 ;
@@ -352,8 +382,17 @@ int main(int argc, char* argv[])
352
382
rv = findSlot (slot, serial, token, slotID);
353
383
if (!rv)
354
384
{
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
+ }
357
396
}
358
397
}
359
398
@@ -1099,7 +1138,7 @@ int importKeyPair
1099
1138
return 1 ;
1100
1139
}
1101
1140
1102
- CK_OBJECT_HANDLE oHandle = searchObject (hSession, objID, objIDLen);
1141
+ CK_OBJECT_HANDLE oHandle = searchObject (hSession, CKO_PRIVATE_KEY, objID, objIDLen);
1103
1142
if (oHandle != CK_INVALID_HANDLE && forceExec == 0 )
1104
1143
{
1105
1144
free (objID);
@@ -1187,6 +1226,98 @@ int importSecretKey(char* filePath, CK_SLOT_ID slotID, char* userPIN, char* labe
1187
1226
return result;
1188
1227
}
1189
1228
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
+
1190
1321
// Convert a char array of hexadecimal characters into a binary representation
1191
1322
char * hexStrToBin (char * objectID, int idLength, size_t * newLen)
1192
1323
{
@@ -1273,14 +1404,13 @@ int hexdigit_to_int(char ch)
1273
1404
}
1274
1405
1275
1406
// 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)
1277
1408
{
1278
1409
if (objID == NULL )
1279
1410
{
1280
1411
return CK_INVALID_HANDLE;
1281
1412
}
1282
1413
1283
- CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY;
1284
1414
CK_OBJECT_HANDLE hObject = CK_INVALID_HANDLE;
1285
1415
CK_ULONG objectCount = 0 ;
1286
1416
0 commit comments