1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 Milan Jurik. All rights reserved.
25 */
26
27 /*
28 * This file implements the import operation for this tool.
29 * The basic flow of the process is to decrypt the PKCS#12
30 * input file if it has a password, parse the elements in
31 * the file, find the soft token, log into it, import the
32 * PKCS#11 objects into the soft token, and log out.
33 */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <ctype.h>
39 #include <errno.h>
40 #include <fcntl.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include "common.h"
44
45 #include <kmfapi.h>
46
47 #define NEW_ATTRLIST(a, n) \
48 { \
49 a = (KMF_ATTRIBUTE *)malloc(n * sizeof (KMF_ATTRIBUTE)); \
50 if (a == NULL) { \
51 rv = KMF_ERR_MEMORY; \
52 goto end; \
53 } \
54 (void) memset(a, 0, n * sizeof (KMF_ATTRIBUTE)); \
55 }
56
57 static KMF_RETURN
pk_import_pk12_files(KMF_HANDLE_T kmfhandle,KMF_CREDENTIAL * cred,char * outfile,char * certfile,char * keyfile,KMF_ENCODE_FORMAT outformat)58 pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred,
59 char *outfile, char *certfile, char *keyfile,
60 KMF_ENCODE_FORMAT outformat)
61 {
62 KMF_RETURN rv = KMF_OK;
63 KMF_X509_DER_CERT *certs = NULL;
64 KMF_RAW_KEY_DATA *keys = NULL;
65 int ncerts = 0;
66 int nkeys = 0;
67 int i;
68 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
69 KMF_ATTRIBUTE *attrlist = NULL;
70 int numattr = 0;
71
72 rv = kmf_import_objects(kmfhandle, outfile, cred,
73 &certs, &ncerts, &keys, &nkeys);
74
75 if (rv == KMF_OK) {
76 (void) printf(gettext("Found %d certificate(s) and %d "
77 "key(s) in %s\n"), ncerts, nkeys, outfile);
78 }
79
80 if (rv == KMF_OK && ncerts > 0) {
81 char newcertfile[MAXPATHLEN];
82
83 NEW_ATTRLIST(attrlist, (3 + (3 * ncerts)));
84
85 kmf_set_attr_at_index(attrlist, numattr,
86 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
87 numattr++;
88
89 kmf_set_attr_at_index(attrlist, numattr,
90 KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat));
91 numattr++;
92
93 for (i = 0; rv == KMF_OK && i < ncerts; i++) {
94 int num = numattr;
95
96 /*
97 * If storing more than 1 cert, gotta change
98 * the name so we don't overwrite the previous one.
99 * Just append a _# to the name.
100 */
101 if (i > 0) {
102 (void) snprintf(newcertfile,
103 sizeof (newcertfile), "%s_%d", certfile, i);
104
105 kmf_set_attr_at_index(attrlist, num,
106 KMF_CERT_FILENAME_ATTR, newcertfile,
107 strlen(newcertfile));
108 num++;
109 } else {
110 kmf_set_attr_at_index(attrlist, num,
111 KMF_CERT_FILENAME_ATTR, certfile,
112 strlen(certfile));
113 num++;
114 }
115
116 if (certs[i].kmf_private.label != NULL) {
117 kmf_set_attr_at_index(attrlist, num,
118 KMF_CERT_LABEL_ATTR,
119 certs[i].kmf_private.label,
120 strlen(certs[i].kmf_private.label));
121 num++;
122 }
123 kmf_set_attr_at_index(attrlist, num,
124 KMF_CERT_DATA_ATTR, &certs[i].certificate,
125 sizeof (KMF_DATA));
126 num++;
127 rv = kmf_store_cert(kmfhandle, num, attrlist);
128 }
129 free(attrlist);
130 }
131 if (rv == KMF_OK && nkeys > 0) {
132 char newkeyfile[MAXPATHLEN];
133 numattr = 0;
134 NEW_ATTRLIST(attrlist, (4 + (4 * nkeys)));
135
136 kmf_set_attr_at_index(attrlist, numattr,
137 KMF_KEYSTORE_TYPE_ATTR, &kstype,
138 sizeof (kstype));
139 numattr++;
140
141 kmf_set_attr_at_index(attrlist, numattr,
142 KMF_ENCODE_FORMAT_ATTR, &outformat,
143 sizeof (outformat));
144 numattr++;
145
146 if (cred != NULL && cred->credlen > 0) {
147 kmf_set_attr_at_index(attrlist, numattr,
148 KMF_CREDENTIAL_ATTR, cred,
149 sizeof (KMF_CREDENTIAL));
150 numattr++;
151 }
152
153 /* The order of certificates and keys should match */
154 for (i = 0; rv == KMF_OK && i < nkeys; i++) {
155 int num = numattr;
156
157 if (i > 0) {
158 (void) snprintf(newkeyfile,
159 sizeof (newkeyfile), "%s_%d", keyfile, i);
160
161 kmf_set_attr_at_index(attrlist, num,
162 KMF_KEY_FILENAME_ATTR, newkeyfile,
163 strlen(newkeyfile));
164 num++;
165 } else {
166 kmf_set_attr_at_index(attrlist, num,
167 KMF_KEY_FILENAME_ATTR, keyfile,
168 strlen(keyfile));
169 num++;
170 }
171
172 if (i < ncerts) {
173 kmf_set_attr_at_index(attrlist, num,
174 KMF_CERT_DATA_ATTR, &certs[i],
175 sizeof (KMF_CERT_DATA_ATTR));
176 num++;
177 }
178
179 kmf_set_attr_at_index(attrlist, num,
180 KMF_RAW_KEY_ATTR, &keys[i],
181 sizeof (KMF_RAW_KEY_DATA));
182 num++;
183
184 rv = kmf_store_key(kmfhandle, num, attrlist);
185 }
186 free(attrlist);
187 }
188 end:
189 /*
190 * Cleanup memory.
191 */
192 if (certs) {
193 for (i = 0; i < ncerts; i++)
194 kmf_free_kmf_cert(kmfhandle, &certs[i]);
195 free(certs);
196 }
197 if (keys) {
198 for (i = 0; i < nkeys; i++)
199 kmf_free_raw_key(&keys[i]);
200 free(keys);
201 }
202
203
204 return (rv);
205 }
206
207
208 static KMF_RETURN
pk_import_pk12_nss(KMF_HANDLE_T kmfhandle,KMF_CREDENTIAL * kmfcred,KMF_CREDENTIAL * tokencred,char * token_spec,char * dir,char * prefix,char * nickname,char * trustflags,char * filename)209 pk_import_pk12_nss(
210 KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred,
211 KMF_CREDENTIAL *tokencred,
212 char *token_spec, char *dir, char *prefix,
213 char *nickname, char *trustflags, char *filename)
214 {
215 KMF_RETURN rv = KMF_OK;
216 KMF_X509_DER_CERT *certs = NULL;
217 KMF_RAW_KEY_DATA *keys = NULL;
218 int ncerts = 0;
219 int nkeys = 0;
220 int i;
221 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
222 KMF_ATTRIBUTE *attrlist = NULL;
223 int numattr = 0;
224
225 rv = configure_nss(kmfhandle, dir, prefix);
226 if (rv != KMF_OK)
227 return (rv);
228
229 rv = kmf_import_objects(kmfhandle, filename, kmfcred,
230 &certs, &ncerts, &keys, &nkeys);
231
232 if (rv == KMF_OK)
233 (void) printf(gettext("Found %d certificate(s) and %d "
234 "key(s) in %s\n"), ncerts, nkeys, filename);
235
236 if (rv == KMF_OK) {
237 numattr = 0;
238 NEW_ATTRLIST(attrlist, (4 + (2 * nkeys)));
239
240 kmf_set_attr_at_index(attrlist, numattr,
241 KMF_KEYSTORE_TYPE_ATTR, &kstype,
242 sizeof (kstype));
243 numattr++;
244
245 if (token_spec != NULL) {
246 kmf_set_attr_at_index(attrlist, numattr,
247 KMF_TOKEN_LABEL_ATTR, token_spec,
248 strlen(token_spec));
249 numattr++;
250 }
251
252 if (nickname != NULL) {
253 kmf_set_attr_at_index(attrlist, numattr,
254 KMF_KEYLABEL_ATTR, nickname,
255 strlen(nickname));
256 numattr++;
257 }
258
259 if (tokencred->credlen > 0) {
260 kmf_set_attr_at_index(attrlist, numattr,
261 KMF_CREDENTIAL_ATTR, tokencred,
262 sizeof (KMF_CREDENTIAL));
263 numattr++;
264 }
265
266 /* The order of certificates and keys should match */
267 for (i = 0; i < nkeys; i++) {
268 int num = numattr;
269
270 if (i < ncerts) {
271 kmf_set_attr_at_index(attrlist, num,
272 KMF_CERT_DATA_ATTR, &certs[i],
273 sizeof (KMF_DATA));
274 num++;
275 }
276
277 kmf_set_attr_at_index(attrlist, num,
278 KMF_RAW_KEY_ATTR, &keys[i],
279 sizeof (KMF_RAW_KEY_DATA));
280 num++;
281
282 rv = kmf_store_key(kmfhandle, num, attrlist);
283 }
284 free(attrlist);
285 attrlist = NULL;
286 }
287
288 if (rv == KMF_OK) {
289 numattr = 0;
290 NEW_ATTRLIST(attrlist, (3 + (2 * ncerts)));
291
292 kmf_set_attr_at_index(attrlist, numattr,
293 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
294 numattr++;
295
296 if (token_spec != NULL) {
297 kmf_set_attr_at_index(attrlist, numattr,
298 KMF_TOKEN_LABEL_ATTR, token_spec,
299 strlen(token_spec));
300 numattr++;
301 }
302
303 if (trustflags != NULL) {
304 kmf_set_attr_at_index(attrlist, numattr,
305 KMF_TRUSTFLAG_ATTR, trustflags,
306 strlen(trustflags));
307 numattr++;
308 }
309
310 for (i = 0; rv == KMF_OK && i < ncerts; i++) {
311 int num = numattr;
312
313 if (certs[i].kmf_private.label != NULL) {
314 kmf_set_attr_at_index(attrlist, num,
315 KMF_CERT_LABEL_ATTR,
316 certs[i].kmf_private.label,
317 strlen(certs[i].kmf_private.label));
318 num++;
319 } else if (i == 0 && nickname != NULL) {
320 kmf_set_attr_at_index(attrlist, num,
321 KMF_CERT_LABEL_ATTR, nickname,
322 strlen(nickname));
323 num++;
324 }
325
326 kmf_set_attr_at_index(attrlist, num,
327 KMF_CERT_DATA_ATTR,
328 &certs[i].certificate, sizeof (KMF_DATA));
329 num++;
330 rv = kmf_store_cert(kmfhandle, num, attrlist);
331 }
332 free(attrlist);
333 attrlist = NULL;
334 if (rv != KMF_OK) {
335 display_error(kmfhandle, rv,
336 gettext("Error storing certificate in NSS token"));
337 }
338 }
339
340 end:
341 /*
342 * Cleanup memory.
343 */
344 if (certs) {
345 for (i = 0; i < ncerts; i++)
346 kmf_free_kmf_cert(kmfhandle, &certs[i]);
347 free(certs);
348 }
349 if (keys) {
350 for (i = 0; i < nkeys; i++)
351 kmf_free_raw_key(&keys[i]);
352 free(keys);
353 }
354
355 return (rv);
356 }
357
358 static KMF_RETURN
pk_import_cert(KMF_HANDLE_T kmfhandle,KMF_KEYSTORE_TYPE kstype,char * label,char * token_spec,char * filename,char * dir,char * prefix,char * trustflags)359 pk_import_cert(
360 KMF_HANDLE_T kmfhandle,
361 KMF_KEYSTORE_TYPE kstype,
362 char *label, char *token_spec, char *filename,
363 char *dir, char *prefix, char *trustflags)
364 {
365 KMF_RETURN rv = KMF_OK;
366 KMF_ATTRIBUTE attrlist[32];
367 KMF_CREDENTIAL tokencred;
368 int i = 0;
369
370 if (kstype == KMF_KEYSTORE_PK11TOKEN) {
371 rv = select_token(kmfhandle, token_spec, FALSE);
372 } else if (kstype == KMF_KEYSTORE_NSS) {
373 rv = configure_nss(kmfhandle, dir, prefix);
374 }
375 if (rv != KMF_OK)
376 return (rv);
377
378 kmf_set_attr_at_index(attrlist, i,
379 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE));
380 i++;
381
382 kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR,
383 filename, strlen(filename));
384 i++;
385
386 if (label != NULL) {
387 kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR,
388 label, strlen(label));
389 i++;
390 }
391
392 if (kstype == KMF_KEYSTORE_NSS) {
393 if (trustflags != NULL) {
394 kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR,
395 trustflags, strlen(trustflags));
396 i++;
397 }
398
399 if (token_spec != NULL) {
400 kmf_set_attr_at_index(attrlist, i,
401 KMF_TOKEN_LABEL_ATTR,
402 token_spec, strlen(token_spec));
403 i++;
404 }
405 }
406
407 rv = kmf_import_cert(kmfhandle, i, attrlist);
408 if (rv == KMF_ERR_AUTH_FAILED) {
409 /*
410 * The token requires a credential, prompt and try again.
411 */
412 (void) get_token_password(kstype, token_spec, &tokencred);
413 kmf_set_attr_at_index(attrlist, i, KMF_CREDENTIAL_ATTR,
414 &tokencred, sizeof (KMF_CREDENTIAL));
415 i++;
416
417 rv = kmf_import_cert(kmfhandle, i, attrlist);
418
419 }
420 return (rv);
421 }
422
423 static KMF_RETURN
pk_import_file_crl(void * kmfhandle,char * infile,char * outfile,KMF_ENCODE_FORMAT outfmt)424 pk_import_file_crl(void *kmfhandle,
425 char *infile,
426 char *outfile,
427 KMF_ENCODE_FORMAT outfmt)
428 {
429 int numattr = 0;
430 KMF_ATTRIBUTE attrlist[8];
431 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
432
433 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
434 &kstype, sizeof (kstype));
435 numattr++;
436 if (infile) {
437 kmf_set_attr_at_index(attrlist, numattr,
438 KMF_CRL_FILENAME_ATTR, infile, strlen(infile));
439 numattr++;
440 }
441 if (outfile) {
442 kmf_set_attr_at_index(attrlist, numattr,
443 KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile));
444 numattr++;
445 }
446 kmf_set_attr_at_index(attrlist, numattr,
447 KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt));
448 numattr++;
449
450 return (kmf_import_crl(kmfhandle, numattr, attrlist));
451 }
452
453 static KMF_RETURN
pk_import_nss_crl(void * kmfhandle,boolean_t verify_crl_flag,char * infile,char * outdir,char * prefix)454 pk_import_nss_crl(void *kmfhandle,
455 boolean_t verify_crl_flag,
456 char *infile,
457 char *outdir,
458 char *prefix)
459 {
460 KMF_RETURN rv;
461 int numattr = 0;
462 KMF_ATTRIBUTE attrlist[4];
463 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
464
465 rv = configure_nss(kmfhandle, outdir, prefix);
466 if (rv != KMF_OK)
467 return (rv);
468
469 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
470 &kstype, sizeof (kstype));
471 numattr++;
472 if (infile) {
473 kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR,
474 infile, strlen(infile));
475 numattr++;
476 }
477 kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR,
478 &verify_crl_flag, sizeof (verify_crl_flag));
479 numattr++;
480
481 return (kmf_import_crl(kmfhandle, numattr, attrlist));
482
483 }
484
485 static KMF_RETURN
pk_import_pk12_pk11(KMF_HANDLE_T kmfhandle,KMF_CREDENTIAL * p12cred,KMF_CREDENTIAL * tokencred,char * label,char * token_spec,char * filename)486 pk_import_pk12_pk11(
487 KMF_HANDLE_T kmfhandle,
488 KMF_CREDENTIAL *p12cred,
489 KMF_CREDENTIAL *tokencred,
490 char *label, char *token_spec,
491 char *filename)
492 {
493 KMF_RETURN rv = KMF_OK;
494 KMF_X509_DER_CERT *certs = NULL;
495 KMF_RAW_KEY_DATA *keys = NULL;
496 int ncerts = 0;
497 int nkeys = 0;
498 int i;
499 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
500 KMF_ATTRIBUTE *attrlist = NULL;
501 int numattr = 0;
502
503 rv = select_token(kmfhandle, token_spec, FALSE);
504
505 if (rv != KMF_OK) {
506 return (rv);
507 }
508
509 rv = kmf_import_objects(kmfhandle, filename, p12cred,
510 &certs, &ncerts, &keys, &nkeys);
511
512 if (rv == KMF_OK) {
513 NEW_ATTRLIST(attrlist, (3 + (2 * nkeys)));
514
515 kmf_set_attr_at_index(attrlist, numattr,
516 KMF_KEYSTORE_TYPE_ATTR, &kstype,
517 sizeof (kstype));
518 numattr++;
519
520 if (label != NULL) {
521 kmf_set_attr_at_index(attrlist, numattr,
522 KMF_KEYLABEL_ATTR, label,
523 strlen(label));
524 numattr++;
525 }
526
527 if (tokencred != NULL && tokencred->credlen > 0) {
528 kmf_set_attr_at_index(attrlist, numattr,
529 KMF_CREDENTIAL_ATTR, tokencred,
530 sizeof (KMF_CREDENTIAL));
531 numattr++;
532 }
533
534 /* The order of certificates and keys should match */
535 for (i = 0; i < nkeys; i++) {
536 int num = numattr;
537
538 if (i < ncerts) {
539 kmf_set_attr_at_index(attrlist, num,
540 KMF_CERT_DATA_ATTR, &certs[i].certificate,
541 sizeof (KMF_DATA));
542 num++;
543 }
544
545 kmf_set_attr_at_index(attrlist, num,
546 KMF_RAW_KEY_ATTR, &keys[i],
547 sizeof (KMF_RAW_KEY_DATA));
548 num++;
549
550 rv = kmf_store_key(kmfhandle, num, attrlist);
551
552 }
553 free(attrlist);
554 }
555
556 if (rv == KMF_OK) {
557 numattr = 0;
558 NEW_ATTRLIST(attrlist, (1 + (2 * ncerts)));
559
560 (void) printf(gettext("Found %d certificate(s) and %d "
561 "key(s) in %s\n"), ncerts, nkeys, filename);
562
563 kmf_set_attr_at_index(attrlist, numattr,
564 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
565 numattr++;
566
567 for (i = 0; rv == KMF_OK && i < ncerts; i++) {
568 int num = numattr;
569 if (certs[i].kmf_private.label != NULL) {
570 kmf_set_attr_at_index(attrlist, num,
571 KMF_CERT_LABEL_ATTR,
572 certs[i].kmf_private.label,
573 strlen(certs[i].kmf_private.label));
574 num++;
575 } else if (i == 0 && label != NULL) {
576 kmf_set_attr_at_index(attrlist, num,
577 KMF_CERT_LABEL_ATTR, label, strlen(label));
578 num++;
579 }
580
581 kmf_set_attr_at_index(attrlist, num,
582 KMF_CERT_DATA_ATTR, &certs[i].certificate,
583 sizeof (KMF_DATA));
584 num++;
585
586 rv = kmf_store_cert(kmfhandle, num, attrlist);
587 }
588 free(attrlist);
589 }
590
591 end:
592 /*
593 * Cleanup memory.
594 */
595 if (certs) {
596 for (i = 0; i < ncerts; i++)
597 kmf_free_kmf_cert(kmfhandle, &certs[i]);
598 free(certs);
599 }
600 if (keys) {
601 for (i = 0; i < nkeys; i++)
602 kmf_free_raw_key(&keys[i]);
603 free(keys);
604 }
605
606 return (rv);
607 }
608
609 /*ARGSUSED*/
610 static KMF_RETURN
pk_import_keys(KMF_HANDLE_T kmfhandle,KMF_KEYSTORE_TYPE kstype,char * token_spec,KMF_CREDENTIAL * cred,char * filename,char * label,char * senstr,char * extstr)611 pk_import_keys(KMF_HANDLE_T kmfhandle,
612 KMF_KEYSTORE_TYPE kstype, char *token_spec,
613 KMF_CREDENTIAL *cred, char *filename,
614 char *label, char *senstr, char *extstr)
615 {
616 KMF_RETURN rv = KMF_OK;
617 KMF_ATTRIBUTE attrlist[16];
618 KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL;
619 int numattr = 0;
620 KMF_KEY_HANDLE key;
621 KMF_RAW_KEY_DATA rawkey;
622 KMF_KEY_CLASS class = KMF_ASYM_PRI;
623 int numkeys = 1;
624
625 if (kstype == KMF_KEYSTORE_PK11TOKEN) {
626 rv = select_token(kmfhandle, token_spec, FALSE);
627 }
628 if (rv != KMF_OK)
629 return (rv);
630 /*
631 * First, set up to read the keyfile using the FILE plugin
632 * mechanisms.
633 */
634 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
635 &fileks, sizeof (fileks));
636 numattr++;
637
638 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
639 &numkeys, sizeof (numkeys));
640 numattr++;
641
642 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
643 &key, sizeof (key));
644 numattr++;
645
646 kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
647 &rawkey, sizeof (rawkey));
648 numattr++;
649
650 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
651 &class, sizeof (class));
652 numattr++;
653
654 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
655 filename, strlen(filename));
656 numattr++;
657
658 rv = kmf_find_key(kmfhandle, numattr, attrlist);
659 if (rv == KMF_OK) {
660 numattr = 0;
661
662 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
663 &kstype, sizeof (kstype));
664 numattr++;
665
666 if (cred != NULL && cred->credlen > 0) {
667 kmf_set_attr_at_index(attrlist, numattr,
668 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
669 numattr++;
670 }
671
672 if (label != NULL) {
673 kmf_set_attr_at_index(attrlist, numattr,
674 KMF_KEYLABEL_ATTR, label, strlen(label));
675 numattr++;
676 }
677
678 kmf_set_attr_at_index(attrlist, numattr,
679 KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey));
680 numattr++;
681
682 rv = kmf_store_key(kmfhandle, numattr, attrlist);
683 if (rv == KMF_OK) {
684 (void) printf(gettext("Importing %d keys\n"), numkeys);
685 }
686
687 kmf_free_kmf_key(kmfhandle, &key);
688 kmf_free_raw_key(&rawkey);
689 } else {
690 cryptoerror(LOG_STDERR,
691 gettext("Failed to load key from file (%s)\n"),
692 filename);
693 }
694 return (rv);
695 }
696
697 static KMF_RETURN
pk_import_rawkey(KMF_HANDLE_T kmfhandle,KMF_KEYSTORE_TYPE kstype,char * token,KMF_CREDENTIAL * cred,char * filename,char * label,KMF_KEY_ALG keyAlg,char * senstr,char * extstr)698 pk_import_rawkey(KMF_HANDLE_T kmfhandle,
699 KMF_KEYSTORE_TYPE kstype, char *token,
700 KMF_CREDENTIAL *cred,
701 char *filename, char *label, KMF_KEY_ALG keyAlg,
702 char *senstr, char *extstr)
703 {
704 KMF_RETURN rv = KMF_OK;
705 KMF_ATTRIBUTE attrlist[16];
706 int numattr = 0;
707 uint32_t keylen;
708 boolean_t sensitive = B_FALSE;
709 boolean_t not_extractable = B_FALSE;
710 KMF_DATA keydata = { 0, NULL };
711 KMF_KEY_HANDLE rawkey;
712
713 rv = kmf_read_input_file(kmfhandle, filename, &keydata);
714 if (rv != KMF_OK)
715 return (rv);
716
717 rv = select_token(kmfhandle, token, FALSE);
718
719 if (rv != KMF_OK) {
720 return (rv);
721 }
722 if (senstr != NULL) {
723 if (tolower(senstr[0]) == 'y')
724 sensitive = B_TRUE;
725 else if (tolower(senstr[0]) == 'n')
726 sensitive = B_FALSE;
727 else {
728 cryptoerror(LOG_STDERR,
729 gettext("Incorrect sensitive option value.\n"));
730 return (KMF_ERR_BAD_PARAMETER);
731 }
732 }
733
734 if (extstr != NULL) {
735 if (tolower(extstr[0]) == 'y')
736 not_extractable = B_FALSE;
737 else if (tolower(extstr[0]) == 'n')
738 not_extractable = B_TRUE;
739 else {
740 cryptoerror(LOG_STDERR,
741 gettext("Incorrect extractable option value.\n"));
742 return (KMF_ERR_BAD_PARAMETER);
743 }
744 }
745 kmf_set_attr_at_index(attrlist, numattr,
746 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
747 numattr++;
748
749 kmf_set_attr_at_index(attrlist, numattr,
750 KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey));
751 numattr++;
752
753 kmf_set_attr_at_index(attrlist, numattr,
754 KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG));
755 numattr++;
756
757 kmf_set_attr_at_index(attrlist, numattr,
758 KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length);
759 numattr++;
760
761 /* Key length is given in bits not bytes */
762 keylen = keydata.Length * 8;
763 kmf_set_attr_at_index(attrlist, numattr,
764 KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length));
765 numattr++;
766
767 kmf_set_attr_at_index(attrlist, numattr,
768 KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive));
769 numattr++;
770
771 kmf_set_attr_at_index(attrlist, numattr,
772 KMF_NON_EXTRACTABLE_BOOL_ATTR, ¬_extractable,
773 sizeof (not_extractable));
774 numattr++;
775
776 if (label != NULL) {
777 kmf_set_attr_at_index(attrlist, numattr,
778 KMF_KEYLABEL_ATTR, label, strlen(label));
779 numattr++;
780 }
781 if (cred != NULL && cred->credlen > 0) {
782 kmf_set_attr_at_index(attrlist, numattr,
783 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
784 numattr++;
785 }
786 rv = kmf_create_sym_key(kmfhandle, numattr, attrlist);
787
788 return (rv);
789 }
790
791 /*
792 * Import objects from into KMF repositories.
793 */
794 int
pk_import(int argc,char * argv[])795 pk_import(int argc, char *argv[])
796 {
797 int opt;
798 extern int optind_av;
799 extern char *optarg_av;
800 char *token_spec = NULL;
801 char *filename = NULL;
802 char *keyfile = NULL;
803 char *certfile = NULL;
804 char *crlfile = NULL;
805 char *label = NULL;
806 char *dir = NULL;
807 char *prefix = NULL;
808 char *trustflags = NULL;
809 char *verify_crl = NULL;
810 char *keytype = "generic";
811 char *senstr = NULL;
812 char *extstr = NULL;
813 boolean_t verify_crl_flag = B_FALSE;
814 int oclass = 0;
815 KMF_KEYSTORE_TYPE kstype = 0;
816 KMF_ENCODE_FORMAT kfmt = 0;
817 KMF_ENCODE_FORMAT okfmt = KMF_FORMAT_ASN1;
818 KMF_RETURN rv = KMF_OK;
819 KMF_CREDENTIAL pk12cred = { NULL, 0 };
820 KMF_CREDENTIAL tokencred = { NULL, 0 };
821 KMF_HANDLE_T kmfhandle = NULL;
822 KMF_KEY_ALG keyAlg = KMF_GENERIC_SECRET;
823
824 /* Parse command line options. Do NOT i18n/l10n. */
825 while ((opt = getopt_av(argc, argv,
826 "T:(token)i:(infile)"
827 "k:(keystore)y:(objtype)"
828 "d:(dir)p:(prefix)"
829 "n:(certlabel)N:(label)"
830 "K:(outkey)c:(outcert)"
831 "v:(verifycrl)l:(outcrl)"
832 "E:(keytype)s:(sensitive)x:(extractable)"
833 "t:(trust)F:(outformat)")) != EOF) {
834 if (EMPTYSTRING(optarg_av))
835 return (PK_ERR_USAGE);
836 switch (opt) {
837 case 'T': /* token specifier */
838 if (token_spec)
839 return (PK_ERR_USAGE);
840 token_spec = optarg_av;
841 break;
842 case 'c': /* output cert file name */
843 if (certfile)
844 return (PK_ERR_USAGE);
845 certfile = optarg_av;
846 break;
847 case 'l': /* output CRL file name */
848 if (crlfile)
849 return (PK_ERR_USAGE);
850 crlfile = optarg_av;
851 break;
852 case 'K': /* output key file name */
853 if (keyfile)
854 return (PK_ERR_USAGE);
855 keyfile = optarg_av;
856 break;
857 case 'i': /* input file name */
858 if (filename)
859 return (PK_ERR_USAGE);
860 filename = optarg_av;
861 break;
862 case 'k':
863 kstype = KS2Int(optarg_av);
864 if (kstype == 0)
865 return (PK_ERR_USAGE);
866 break;
867 case 'y':
868 oclass = OT2Int(optarg_av);
869 if (oclass == -1)
870 return (PK_ERR_USAGE);
871 break;
872 case 'd':
873 dir = optarg_av;
874 break;
875 case 'p':
876 if (prefix)
877 return (PK_ERR_USAGE);
878 prefix = optarg_av;
879 break;
880 case 'n':
881 case 'N':
882 if (label)
883 return (PK_ERR_USAGE);
884 label = optarg_av;
885 break;
886 case 'F':
887 okfmt = Str2Format(optarg_av);
888 if (okfmt == KMF_FORMAT_UNDEF)
889 return (PK_ERR_USAGE);
890 break;
891 case 't':
892 if (trustflags)
893 return (PK_ERR_USAGE);
894 trustflags = optarg_av;
895 break;
896 case 'v':
897 verify_crl = optarg_av;
898 if (tolower(verify_crl[0]) == 'y')
899 verify_crl_flag = B_TRUE;
900 else if (tolower(verify_crl[0]) == 'n')
901 verify_crl_flag = B_FALSE;
902 else
903 return (PK_ERR_USAGE);
904 break;
905 case 'E':
906 keytype = optarg_av;
907 break;
908 case 's':
909 if (senstr)
910 return (PK_ERR_USAGE);
911 senstr = optarg_av;
912 break;
913 case 'x':
914 if (extstr)
915 return (PK_ERR_USAGE);
916 extstr = optarg_av;
917 break;
918 default:
919 return (PK_ERR_USAGE);
920 }
921 }
922
923 /* Assume keystore = PKCS#11 if not specified */
924 if (kstype == 0)
925 kstype = KMF_KEYSTORE_PK11TOKEN;
926
927 /* Filename arg is required. */
928 if (EMPTYSTRING(filename)) {
929 cryptoerror(LOG_STDERR, gettext("The 'infile' parameter"
930 "is required for the import operation.\n"));
931 return (PK_ERR_USAGE);
932 }
933
934 /* No additional args allowed. */
935 argc -= optind_av;
936 argv += optind_av;
937 if (argc)
938 return (PK_ERR_USAGE);
939
940 DIR_OPTION_CHECK(kstype, dir);
941
942 /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
943 if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
944 kstype != KMF_KEYSTORE_PK11TOKEN) {
945
946 (void) fprintf(stderr, gettext("The objtype parameter "
947 "is only relevant if keystore=pkcs11\n"));
948 return (PK_ERR_USAGE);
949 }
950
951 /*
952 * You must specify a certlabel (cert label) when importing
953 * into NSS or PKCS#11.
954 */
955 if (kstype == KMF_KEYSTORE_NSS &&
956 (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) {
957 cryptoerror(LOG_STDERR, gettext("The 'label' argument "
958 "is required for this operation\n"));
959 return (PK_ERR_USAGE);
960 }
961
962 if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) {
963 char *kmferrstr = NULL;
964 KMF_RETURN rv2;
965 /*
966 * Allow for raw key data to be imported.
967 */
968 if (rv == KMF_ERR_ENCODING) {
969 rv = KMF_OK;
970 kfmt = KMF_FORMAT_RAWKEY;
971 /*
972 * Set the object class only if it was not
973 * given on the command line or if it was
974 * specified as a symmetric key object.
975 */
976 if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) {
977 oclass = PK_SYMKEY_OBJ;
978 } else {
979 cryptoerror(LOG_STDERR, gettext(
980 "The input file does not contain the "
981 "object type indicated on command "
982 "line."));
983 return (KMF_ERR_BAD_PARAMETER);
984 }
985 } else {
986 if (rv == KMF_ERR_OPEN_FILE) {
987 cryptoerror(LOG_STDERR,
988 gettext("Cannot open file (%s)\n."),
989 filename);
990 } else {
991 rv2 = kmf_get_kmf_error_str(rv, &kmferrstr);
992 if (rv2 == KMF_OK && kmferrstr) {
993 cryptoerror(LOG_STDERR,
994 gettext("libkmf error: %s"),
995 kmferrstr);
996 kmf_free_str(kmferrstr);
997 }
998 }
999 return (rv);
1000 }
1001 }
1002
1003 /* Check parameters for raw key import operation */
1004 if (kfmt == KMF_FORMAT_RAWKEY) {
1005 if (keytype != NULL &&
1006 Str2SymKeyType(keytype, &keyAlg) != 0) {
1007 cryptoerror(LOG_STDERR,
1008 gettext("Unrecognized keytype(%s).\n"), keytype);
1009 return (PK_ERR_USAGE);
1010 }
1011 if (senstr != NULL && extstr != NULL &&
1012 kstype != KMF_KEYSTORE_PK11TOKEN) {
1013 cryptoerror(LOG_STDERR,
1014 gettext("The sensitive or extractable option "
1015 "applies only when importing a key from a file "
1016 "into a PKCS#11 keystore.\n"));
1017 return (PK_ERR_USAGE);
1018 }
1019 }
1020
1021 /* If no objtype was given, treat it as a certificate */
1022 if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 ||
1023 kfmt == KMF_FORMAT_PEM))
1024 oclass = PK_CERT_OBJ;
1025
1026 if (kstype == KMF_KEYSTORE_NSS) {
1027 if (oclass == PK_CRL_OBJ &&
1028 (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
1029 cryptoerror(LOG_STDERR, gettext(
1030 "CRL data can only be imported as DER or "
1031 "PEM format"));
1032 return (PK_ERR_USAGE);
1033 }
1034
1035 if (oclass == PK_CERT_OBJ &&
1036 (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
1037 cryptoerror(LOG_STDERR, gettext(
1038 "Certificates can only be imported as DER or "
1039 "PEM format"));
1040 return (PK_ERR_USAGE);
1041 }
1042
1043 /* we do not import private keys except in PKCS12 bundles */
1044 if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
1045 cryptoerror(LOG_STDERR, gettext(
1046 "Private key data can only be imported as part "
1047 "of a PKCS12 file.\n"));
1048 return (PK_ERR_USAGE);
1049 }
1050 }
1051
1052 if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) {
1053 if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
1054 cryptoerror(LOG_STDERR, gettext(
1055 "The 'outkey' and 'outcert' parameters "
1056 "are required for the import operation "
1057 "when the 'file' keystore is used.\n"));
1058 return (PK_ERR_USAGE);
1059 }
1060 }
1061
1062 if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
1063 token_spec = PK_DEFAULT_PK11TOKEN;
1064 else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
1065 token_spec = DEFAULT_NSS_TOKEN;
1066
1067 if (kfmt == KMF_FORMAT_PKCS12) {
1068 (void) get_pk12_password(&pk12cred);
1069 }
1070
1071 if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY ||
1072 (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) &&
1073 (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) {
1074 (void) get_token_password(kstype, token_spec, &tokencred);
1075 }
1076
1077 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
1078 cryptoerror(LOG_STDERR, gettext("Error initializing "
1079 "KMF: 0x%02x\n"), rv);
1080 goto end;
1081 }
1082
1083 switch (kstype) {
1084 case KMF_KEYSTORE_PK11TOKEN:
1085 if (kfmt == KMF_FORMAT_PKCS12)
1086 rv = pk_import_pk12_pk11(
1087 kmfhandle, &pk12cred,
1088 &tokencred, label,
1089 token_spec, filename);
1090 else if (oclass == PK_CERT_OBJ)
1091 rv = pk_import_cert(
1092 kmfhandle, kstype,
1093 label, token_spec,
1094 filename,
1095 NULL, NULL, NULL);
1096 else if (oclass == PK_CRL_OBJ)
1097 rv = pk_import_file_crl(
1098 kmfhandle, filename,
1099 crlfile, okfmt);
1100 else if (kfmt == KMF_FORMAT_RAWKEY &&
1101 oclass == PK_SYMKEY_OBJ) {
1102 rv = pk_import_rawkey(kmfhandle,
1103 kstype, token_spec, &tokencred,
1104 filename, label,
1105 keyAlg, senstr, extstr);
1106 } else if (kfmt == KMF_FORMAT_PEM ||
1107 kfmt == KMF_FORMAT_PEM_KEYPAIR) {
1108 rv = pk_import_keys(kmfhandle,
1109 kstype, token_spec, &tokencred,
1110 filename, label, senstr, extstr);
1111 } else {
1112 rv = PK_ERR_USAGE;
1113 }
1114 break;
1115 case KMF_KEYSTORE_NSS:
1116 if (dir == NULL)
1117 dir = PK_DEFAULT_DIRECTORY;
1118 if (kfmt == KMF_FORMAT_PKCS12)
1119 rv = pk_import_pk12_nss(
1120 kmfhandle, &pk12cred,
1121 &tokencred,
1122 token_spec, dir, prefix,
1123 label, trustflags, filename);
1124 else if (oclass == PK_CERT_OBJ) {
1125 rv = pk_import_cert(
1126 kmfhandle, kstype,
1127 label, token_spec,
1128 filename, dir, prefix, trustflags);
1129 } else if (oclass == PK_CRL_OBJ) {
1130 rv = pk_import_nss_crl(
1131 kmfhandle, verify_crl_flag,
1132 filename, dir, prefix);
1133 }
1134 break;
1135 case KMF_KEYSTORE_OPENSSL:
1136 if (kfmt == KMF_FORMAT_PKCS12)
1137 rv = pk_import_pk12_files(
1138 kmfhandle, &pk12cred,
1139 filename, certfile, keyfile,
1140 okfmt);
1141 else if (oclass == PK_CRL_OBJ) {
1142 rv = pk_import_file_crl(
1143 kmfhandle, filename,
1144 crlfile, okfmt);
1145 } else
1146 /*
1147 * It doesn't make sense to import anything
1148 * else for the files plugin.
1149 */
1150 return (PK_ERR_USAGE);
1151 break;
1152 default:
1153 rv = PK_ERR_USAGE;
1154 break;
1155 }
1156
1157 end:
1158 if (rv != KMF_OK)
1159 display_error(kmfhandle, rv,
1160 gettext("Error importing objects"));
1161
1162 if (tokencred.cred != NULL)
1163 free(tokencred.cred);
1164
1165 if (pk12cred.cred != NULL)
1166 free(pk12cred.cred);
1167
1168 (void) kmf_finalize(kmfhandle);
1169
1170 if (rv != KMF_OK)
1171 return (PK_ERR_USAGE);
1172
1173 return (0);
1174 }
1175