8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / cmd-crypto / pktool / import.c
blob7c52c427d0ef1175553e17b176107a67c7b3d884
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 Milan Jurik. All rights reserved.
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.
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"
45 #include <kmfapi.h>
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)); \
57 static KMF_RETURN
58 pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred,
59 char *outfile, char *certfile, char *keyfile,
60 KMF_ENCODE_FORMAT outformat)
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;
72 rv = kmf_import_objects(kmfhandle, outfile, cred,
73 &certs, &ncerts, &keys, &nkeys);
75 if (rv == KMF_OK) {
76 (void) printf(gettext("Found %d certificate(s) and %d "
77 "key(s) in %s\n"), ncerts, nkeys, outfile);
80 if (rv == KMF_OK && ncerts > 0) {
81 char newcertfile[MAXPATHLEN];
83 NEW_ATTRLIST(attrlist, (3 + (3 * ncerts)));
85 kmf_set_attr_at_index(attrlist, numattr,
86 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
87 numattr++;
89 kmf_set_attr_at_index(attrlist, numattr,
90 KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat));
91 numattr++;
93 for (i = 0; rv == KMF_OK && i < ncerts; i++) {
94 int num = numattr;
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.
101 if (i > 0) {
102 (void) snprintf(newcertfile,
103 sizeof (newcertfile), "%s_%d", certfile, i);
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++;
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++;
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);
129 free(attrlist);
131 if (rv == KMF_OK && nkeys > 0) {
132 char newkeyfile[MAXPATHLEN];
133 numattr = 0;
134 NEW_ATTRLIST(attrlist, (4 + (4 * nkeys)));
136 kmf_set_attr_at_index(attrlist, numattr,
137 KMF_KEYSTORE_TYPE_ATTR, &kstype,
138 sizeof (kstype));
139 numattr++;
141 kmf_set_attr_at_index(attrlist, numattr,
142 KMF_ENCODE_FORMAT_ATTR, &outformat,
143 sizeof (outformat));
144 numattr++;
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++;
153 /* The order of certificates and keys should match */
154 for (i = 0; rv == KMF_OK && i < nkeys; i++) {
155 int num = numattr;
157 if (i > 0) {
158 (void) snprintf(newkeyfile,
159 sizeof (newkeyfile), "%s_%d", keyfile, i);
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++;
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++;
179 kmf_set_attr_at_index(attrlist, num,
180 KMF_RAW_KEY_ATTR, &keys[i],
181 sizeof (KMF_RAW_KEY_DATA));
182 num++;
184 rv = kmf_store_key(kmfhandle, num, attrlist);
186 free(attrlist);
188 end:
190 * Cleanup memory.
192 if (certs) {
193 for (i = 0; i < ncerts; i++)
194 kmf_free_kmf_cert(kmfhandle, &certs[i]);
195 free(certs);
197 if (keys) {
198 for (i = 0; i < nkeys; i++)
199 kmf_free_raw_key(&keys[i]);
200 free(keys);
204 return (rv);
208 static KMF_RETURN
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)
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;
225 rv = configure_nss(kmfhandle, dir, prefix);
226 if (rv != KMF_OK)
227 return (rv);
229 rv = kmf_import_objects(kmfhandle, filename, kmfcred,
230 &certs, &ncerts, &keys, &nkeys);
232 if (rv == KMF_OK)
233 (void) printf(gettext("Found %d certificate(s) and %d "
234 "key(s) in %s\n"), ncerts, nkeys, filename);
236 if (rv == KMF_OK) {
237 numattr = 0;
238 NEW_ATTRLIST(attrlist, (4 + (2 * nkeys)));
240 kmf_set_attr_at_index(attrlist, numattr,
241 KMF_KEYSTORE_TYPE_ATTR, &kstype,
242 sizeof (kstype));
243 numattr++;
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++;
252 if (nickname != NULL) {
253 kmf_set_attr_at_index(attrlist, numattr,
254 KMF_KEYLABEL_ATTR, nickname,
255 strlen(nickname));
256 numattr++;
259 if (tokencred->credlen > 0) {
260 kmf_set_attr_at_index(attrlist, numattr,
261 KMF_CREDENTIAL_ATTR, tokencred,
262 sizeof (KMF_CREDENTIAL));
263 numattr++;
266 /* The order of certificates and keys should match */
267 for (i = 0; i < nkeys; i++) {
268 int num = numattr;
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++;
277 kmf_set_attr_at_index(attrlist, num,
278 KMF_RAW_KEY_ATTR, &keys[i],
279 sizeof (KMF_RAW_KEY_DATA));
280 num++;
282 rv = kmf_store_key(kmfhandle, num, attrlist);
284 free(attrlist);
285 attrlist = NULL;
288 if (rv == KMF_OK) {
289 numattr = 0;
290 NEW_ATTRLIST(attrlist, (3 + (2 * ncerts)));
292 kmf_set_attr_at_index(attrlist, numattr,
293 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
294 numattr++;
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++;
303 if (trustflags != NULL) {
304 kmf_set_attr_at_index(attrlist, numattr,
305 KMF_TRUSTFLAG_ATTR, trustflags,
306 strlen(trustflags));
307 numattr++;
310 for (i = 0; rv == KMF_OK && i < ncerts; i++) {
311 int num = numattr;
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++;
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);
332 free(attrlist);
333 attrlist = NULL;
334 if (rv != KMF_OK) {
335 display_error(kmfhandle, rv,
336 gettext("Error storing certificate in NSS token"));
340 end:
342 * Cleanup memory.
344 if (certs) {
345 for (i = 0; i < ncerts; i++)
346 kmf_free_kmf_cert(kmfhandle, &certs[i]);
347 free(certs);
349 if (keys) {
350 for (i = 0; i < nkeys; i++)
351 kmf_free_raw_key(&keys[i]);
352 free(keys);
355 return (rv);
358 static KMF_RETURN
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)
365 KMF_RETURN rv = KMF_OK;
366 KMF_ATTRIBUTE attrlist[32];
367 KMF_CREDENTIAL tokencred;
368 int i = 0;
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);
375 if (rv != KMF_OK)
376 return (rv);
378 kmf_set_attr_at_index(attrlist, i,
379 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE));
380 i++;
382 kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR,
383 filename, strlen(filename));
384 i++;
386 if (label != NULL) {
387 kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR,
388 label, strlen(label));
389 i++;
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++;
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++;
407 rv = kmf_import_cert(kmfhandle, i, attrlist);
408 if (rv == KMF_ERR_AUTH_FAILED) {
410 * The token requires a credential, prompt and try again.
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++;
417 rv = kmf_import_cert(kmfhandle, i, attrlist);
420 return (rv);
423 static KMF_RETURN
424 pk_import_file_crl(void *kmfhandle,
425 char *infile,
426 char *outfile,
427 KMF_ENCODE_FORMAT outfmt)
429 int numattr = 0;
430 KMF_ATTRIBUTE attrlist[8];
431 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
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++;
441 if (outfile) {
442 kmf_set_attr_at_index(attrlist, numattr,
443 KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile));
444 numattr++;
446 kmf_set_attr_at_index(attrlist, numattr,
447 KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt));
448 numattr++;
450 return (kmf_import_crl(kmfhandle, numattr, attrlist));
453 static KMF_RETURN
454 pk_import_nss_crl(void *kmfhandle,
455 boolean_t verify_crl_flag,
456 char *infile,
457 char *outdir,
458 char *prefix)
460 KMF_RETURN rv;
461 int numattr = 0;
462 KMF_ATTRIBUTE attrlist[4];
463 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
465 rv = configure_nss(kmfhandle, outdir, prefix);
466 if (rv != KMF_OK)
467 return (rv);
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++;
477 kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR,
478 &verify_crl_flag, sizeof (verify_crl_flag));
479 numattr++;
481 return (kmf_import_crl(kmfhandle, numattr, attrlist));
485 static KMF_RETURN
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)
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;
503 rv = select_token(kmfhandle, token_spec, FALSE);
505 if (rv != KMF_OK) {
506 return (rv);
509 rv = kmf_import_objects(kmfhandle, filename, p12cred,
510 &certs, &ncerts, &keys, &nkeys);
512 if (rv == KMF_OK) {
513 NEW_ATTRLIST(attrlist, (3 + (2 * nkeys)));
515 kmf_set_attr_at_index(attrlist, numattr,
516 KMF_KEYSTORE_TYPE_ATTR, &kstype,
517 sizeof (kstype));
518 numattr++;
520 if (label != NULL) {
521 kmf_set_attr_at_index(attrlist, numattr,
522 KMF_KEYLABEL_ATTR, label,
523 strlen(label));
524 numattr++;
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++;
534 /* The order of certificates and keys should match */
535 for (i = 0; i < nkeys; i++) {
536 int num = numattr;
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++;
545 kmf_set_attr_at_index(attrlist, num,
546 KMF_RAW_KEY_ATTR, &keys[i],
547 sizeof (KMF_RAW_KEY_DATA));
548 num++;
550 rv = kmf_store_key(kmfhandle, num, attrlist);
553 free(attrlist);
556 if (rv == KMF_OK) {
557 numattr = 0;
558 NEW_ATTRLIST(attrlist, (1 + (2 * ncerts)));
560 (void) printf(gettext("Found %d certificate(s) and %d "
561 "key(s) in %s\n"), ncerts, nkeys, filename);
563 kmf_set_attr_at_index(attrlist, numattr,
564 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
565 numattr++;
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++;
581 kmf_set_attr_at_index(attrlist, num,
582 KMF_CERT_DATA_ATTR, &certs[i].certificate,
583 sizeof (KMF_DATA));
584 num++;
586 rv = kmf_store_cert(kmfhandle, num, attrlist);
588 free(attrlist);
591 end:
593 * Cleanup memory.
595 if (certs) {
596 for (i = 0; i < ncerts; i++)
597 kmf_free_kmf_cert(kmfhandle, &certs[i]);
598 free(certs);
600 if (keys) {
601 for (i = 0; i < nkeys; i++)
602 kmf_free_raw_key(&keys[i]);
603 free(keys);
606 return (rv);
609 /*ARGSUSED*/
610 static KMF_RETURN
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)
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;
625 if (kstype == KMF_KEYSTORE_PK11TOKEN) {
626 rv = select_token(kmfhandle, token_spec, FALSE);
628 if (rv != KMF_OK)
629 return (rv);
631 * First, set up to read the keyfile using the FILE plugin
632 * mechanisms.
634 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
635 &fileks, sizeof (fileks));
636 numattr++;
638 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
639 &numkeys, sizeof (numkeys));
640 numattr++;
642 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
643 &key, sizeof (key));
644 numattr++;
646 kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
647 &rawkey, sizeof (rawkey));
648 numattr++;
650 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
651 &class, sizeof (class));
652 numattr++;
654 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
655 filename, strlen(filename));
656 numattr++;
658 rv = kmf_find_key(kmfhandle, numattr, attrlist);
659 if (rv == KMF_OK) {
660 numattr = 0;
662 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
663 &kstype, sizeof (kstype));
664 numattr++;
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++;
672 if (label != NULL) {
673 kmf_set_attr_at_index(attrlist, numattr,
674 KMF_KEYLABEL_ATTR, label, strlen(label));
675 numattr++;
678 kmf_set_attr_at_index(attrlist, numattr,
679 KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey));
680 numattr++;
682 rv = kmf_store_key(kmfhandle, numattr, attrlist);
683 if (rv == KMF_OK) {
684 (void) printf(gettext("Importing %d keys\n"), numkeys);
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);
694 return (rv);
697 static KMF_RETURN
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)
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;
713 rv = kmf_read_input_file(kmfhandle, filename, &keydata);
714 if (rv != KMF_OK)
715 return (rv);
717 rv = select_token(kmfhandle, token, FALSE);
719 if (rv != KMF_OK) {
720 return (rv);
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);
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);
745 kmf_set_attr_at_index(attrlist, numattr,
746 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
747 numattr++;
749 kmf_set_attr_at_index(attrlist, numattr,
750 KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey));
751 numattr++;
753 kmf_set_attr_at_index(attrlist, numattr,
754 KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG));
755 numattr++;
757 kmf_set_attr_at_index(attrlist, numattr,
758 KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length);
759 numattr++;
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++;
767 kmf_set_attr_at_index(attrlist, numattr,
768 KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive));
769 numattr++;
771 kmf_set_attr_at_index(attrlist, numattr,
772 KMF_NON_EXTRACTABLE_BOOL_ATTR, &not_extractable,
773 sizeof (not_extractable));
774 numattr++;
776 if (label != NULL) {
777 kmf_set_attr_at_index(attrlist, numattr,
778 KMF_KEYLABEL_ATTR, label, strlen(label));
779 numattr++;
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++;
786 rv = kmf_create_sym_key(kmfhandle, numattr, attrlist);
788 return (rv);
792 * Import objects from into KMF repositories.
795 pk_import(int argc, char *argv[])
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;
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);
923 /* Assume keystore = PKCS#11 if not specified */
924 if (kstype == 0)
925 kstype = KMF_KEYSTORE_PK11TOKEN;
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);
934 /* No additional args allowed. */
935 argc -= optind_av;
936 argv += optind_av;
937 if (argc)
938 return (PK_ERR_USAGE);
940 DIR_OPTION_CHECK(kstype, dir);
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) {
946 (void) fprintf(stderr, gettext("The objtype parameter "
947 "is only relevant if keystore=pkcs11\n"));
948 return (PK_ERR_USAGE);
952 * You must specify a certlabel (cert label) when importing
953 * into NSS or PKCS#11.
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);
962 if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) {
963 char *kmferrstr = NULL;
964 KMF_RETURN rv2;
966 * Allow for raw key data to be imported.
968 if (rv == KMF_ERR_ENCODING) {
969 rv = KMF_OK;
970 kfmt = KMF_FORMAT_RAWKEY;
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.
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);
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);
999 return (rv);
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);
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);
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;
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);
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);
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);
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);
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;
1067 if (kfmt == KMF_FORMAT_PKCS12) {
1068 (void) get_pk12_password(&pk12cred);
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);
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;
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;
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);
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
1147 * It doesn't make sense to import anything
1148 * else for the files plugin.
1150 return (PK_ERR_USAGE);
1151 break;
1152 default:
1153 rv = PK_ERR_USAGE;
1154 break;
1157 end:
1158 if (rv != KMF_OK)
1159 display_error(kmfhandle, rv,
1160 gettext("Error importing objects"));
1162 if (tokencred.cred != NULL)
1163 free(tokencred.cred);
1165 if (pk12cred.cred != NULL)
1166 free(pk12cred.cred);
1168 (void) kmf_finalize(kmfhandle);
1170 if (rv != KMF_OK)
1171 return (PK_ERR_USAGE);
1173 return (0);