@@ -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,22 @@ 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
+ break ;
396
+ default :
397
+ fprintf (stderr, " Invalid importType %d.\n " , importType);
398
+ rv = 1 ;
399
+ break ;
400
+ }
357
401
}
358
402
}
359
403
@@ -1099,7 +1143,7 @@ int importKeyPair
1099
1143
return 1 ;
1100
1144
}
1101
1145
1102
- CK_OBJECT_HANDLE oHandle = searchObject (hSession, objID, objIDLen);
1146
+ CK_OBJECT_HANDLE oHandle = searchObject (hSession, CKO_PRIVATE_KEY, objID, objIDLen);
1103
1147
if (oHandle != CK_INVALID_HANDLE && forceExec == 0 )
1104
1148
{
1105
1149
free (objID);
@@ -1187,6 +1231,98 @@ int importSecretKey(char* filePath, CK_SLOT_ID slotID, char* userPIN, char* labe
1187
1231
return result;
1188
1232
}
1189
1233
1234
+ // Import a certificate from given path
1235
+ int importCertificate
1236
+ (
1237
+ char * filePath,
1238
+ CK_SLOT_ID slotID,
1239
+ char * userPIN,
1240
+ char * label,
1241
+ char * objectID,
1242
+ int forceExec
1243
+ )
1244
+ {
1245
+ char user_pin_copy[MAX_PIN_LEN+1 ];
1246
+
1247
+ if (label == NULL )
1248
+ {
1249
+ fprintf (stderr, " ERROR: A label for the object must be supplied. "
1250
+ " Use --label <text>\n " );
1251
+ return 1 ;
1252
+ }
1253
+
1254
+ if (objectID == NULL )
1255
+ {
1256
+ fprintf (stderr, " ERROR: An ID for the object must be supplied. "
1257
+ " Use --id <hex>\n " );
1258
+ return 1 ;
1259
+ }
1260
+
1261
+ size_t objIDLen = 0 ;
1262
+ char * objID = hexStrToBin (objectID, strlen (objectID), &objIDLen);
1263
+ if (objID == NULL )
1264
+ {
1265
+ fprintf (stderr, " Please edit --id <hex> to correct error.\n " );
1266
+ return 1 ;
1267
+ }
1268
+
1269
+ CK_SESSION_HANDLE hSession;
1270
+ CK_RV rv = p11->C_OpenSession (slotID, CKF_SERIAL_SESSION | CKF_RW_SESSION,
1271
+ NULL_PTR, NULL_PTR, &hSession);
1272
+ if (rv != CKR_OK)
1273
+ {
1274
+ if (rv == CKR_SLOT_ID_INVALID)
1275
+ {
1276
+ fprintf (stderr, " ERROR: The given slot does not exist.\n " );
1277
+ }
1278
+ else
1279
+ {
1280
+ fprintf (stderr, " ERROR: Could not open a session on the given slot.\n " );
1281
+ }
1282
+ free (objID);
1283
+ return 1 ;
1284
+ }
1285
+
1286
+ // Get the password
1287
+ if (getPW (userPIN, user_pin_copy, CKU_USER) != 0 )
1288
+ {
1289
+ fprintf (stderr, " ERROR: Could not get user PIN\n " );
1290
+ free (objID);
1291
+ return 1 ;
1292
+ }
1293
+
1294
+ rv = p11->C_Login (hSession, CKU_USER, (CK_UTF8CHAR_PTR)user_pin_copy, strlen (user_pin_copy));
1295
+ if (rv != CKR_OK)
1296
+ {
1297
+ if (rv == CKR_PIN_INCORRECT) {
1298
+ fprintf (stderr, " ERROR: The given user PIN does not match the one in the token.\n " );
1299
+ }
1300
+ else
1301
+ {
1302
+ fprintf (stderr, " ERROR: Could not log in on the token.\n " );
1303
+ }
1304
+ free (objID);
1305
+ return 1 ;
1306
+ }
1307
+
1308
+ CK_OBJECT_HANDLE oHandle = searchObject (hSession, CKO_CERTIFICATE, objID, objIDLen);
1309
+ if (oHandle != CK_INVALID_HANDLE && forceExec == 0 )
1310
+ {
1311
+ free (objID);
1312
+ fprintf (stderr, " ERROR: The ID is already assigned to another object. "
1313
+ " Use --force to override this message.\n " );
1314
+ return 1 ;
1315
+ }
1316
+
1317
+ crypto_init ();
1318
+ int result = crypto_import_certificate (hSession, filePath, label, objID, objIDLen);
1319
+ crypto_final ();
1320
+
1321
+ free (objID);
1322
+
1323
+ return result;
1324
+ }
1325
+
1190
1326
// Convert a char array of hexadecimal characters into a binary representation
1191
1327
char * hexStrToBin (char * objectID, int idLength, size_t * newLen)
1192
1328
{
@@ -1273,14 +1409,13 @@ int hexdigit_to_int(char ch)
1273
1409
}
1274
1410
1275
1411
// Search for an object
1276
- CK_OBJECT_HANDLE searchObject (CK_SESSION_HANDLE hSession, char * objID, size_t objIDLen)
1412
+ CK_OBJECT_HANDLE searchObject (CK_SESSION_HANDLE hSession, CK_OBJECT_CLASS oClass, char * objID, size_t objIDLen)
1277
1413
{
1278
1414
if (objID == NULL )
1279
1415
{
1280
1416
return CK_INVALID_HANDLE;
1281
1417
}
1282
1418
1283
- CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY;
1284
1419
CK_OBJECT_HANDLE hObject = CK_INVALID_HANDLE;
1285
1420
CK_ULONG objectCount = 0 ;
1286
1421
0 commit comments