17711facfSdinak /*
27711facfSdinak  * CDDL HEADER START
37711facfSdinak  *
47711facfSdinak  * The contents of this file are subject to the terms of the
599ebb4caSwyllys  * Common Development and Distribution License (the "License").
699ebb4caSwyllys  * You may not use this file except in compliance with the License.
77711facfSdinak  *
87711facfSdinak  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97711facfSdinak  * or http://www.opensolaris.org/os/licensing.
107711facfSdinak  * See the License for the specific language governing permissions
117711facfSdinak  * and limitations under the License.
127711facfSdinak  *
137711facfSdinak  * When distributing Covered Code, include this CDDL HEADER in each
147711facfSdinak  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157711facfSdinak  * If applicable, add the following below this CDDL HEADER, with the
167711facfSdinak  * fields enclosed by brackets "[]" replaced with your own identifying
177711facfSdinak  * information: Portions Copyright [yyyy] [name of copyright owner]
187711facfSdinak  *
197711facfSdinak  * CDDL HEADER END
207711facfSdinak  */
217711facfSdinak /*
22*9e765c33SHuie-Ying Lee  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237711facfSdinak  * Use is subject to license terms.
247711facfSdinak  */
257711facfSdinak 
267711facfSdinak /*
277711facfSdinak  * This file implements the import operation for this tool.
287711facfSdinak  * The basic flow of the process is to decrypt the PKCS#12
297711facfSdinak  * input file if it has a password, parse the elements in
307711facfSdinak  * the file, find the soft token, log into it, import the
317711facfSdinak  * PKCS#11 objects into the soft token, and log out.
327711facfSdinak  */
337711facfSdinak 
347711facfSdinak #include <stdio.h>
357711facfSdinak #include <stdlib.h>
367711facfSdinak #include <string.h>
3799ebb4caSwyllys #include <ctype.h>
387711facfSdinak #include <errno.h>
397711facfSdinak #include <fcntl.h>
407711facfSdinak #include <sys/types.h>
417711facfSdinak #include <sys/stat.h>
427711facfSdinak #include "common.h"
437711facfSdinak 
4499ebb4caSwyllys #include <kmfapi.h>
4599ebb4caSwyllys 
465b3e1433Swyllys #define	NEW_ATTRLIST(a, n) \
475b3e1433Swyllys { \
485b3e1433Swyllys 	a = (KMF_ATTRIBUTE *)malloc(n * sizeof (KMF_ATTRIBUTE)); \
495b3e1433Swyllys 	if (a == NULL) { \
505b3e1433Swyllys 		rv = KMF_ERR_MEMORY; \
515b3e1433Swyllys 		goto end; \
525b3e1433Swyllys 	} \
535b3e1433Swyllys 	(void) memset(a, 0, n * sizeof (KMF_ATTRIBUTE));  \
545b3e1433Swyllys }
555b3e1433Swyllys 
5699ebb4caSwyllys static KMF_RETURN
5799ebb4caSwyllys pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred,
5899ebb4caSwyllys 	char *outfile, char *certfile, char *keyfile,
59448b8615Swyllys 	KMF_ENCODE_FORMAT outformat)
607711facfSdinak {
6199ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
625b3e1433Swyllys 	KMF_X509_DER_CERT *certs = NULL;
6399ebb4caSwyllys 	KMF_RAW_KEY_DATA *keys = NULL;
6499ebb4caSwyllys 	int ncerts = 0;
6599ebb4caSwyllys 	int nkeys = 0;
6699ebb4caSwyllys 	int i;
6730a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
685b3e1433Swyllys 	KMF_ATTRIBUTE *attrlist = NULL;
6930a5e8faSwyllys 	int numattr = 0;
7099ebb4caSwyllys 
7130a5e8faSwyllys 	rv = kmf_import_objects(kmfhandle, outfile, cred,
7230a5e8faSwyllys 	    &certs, &ncerts, &keys, &nkeys);
7399ebb4caSwyllys 
7499ebb4caSwyllys 	if (rv == KMF_OK) {
7599ebb4caSwyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
7630a5e8faSwyllys 		    "key(s) in %s\n"), ncerts, nkeys, outfile);
7799ebb4caSwyllys 	}
7899ebb4caSwyllys 
7999ebb4caSwyllys 	if (rv == KMF_OK && ncerts > 0) {
8099ebb4caSwyllys 		char newcertfile[MAXPATHLEN];
8199ebb4caSwyllys 
825b3e1433Swyllys 		NEW_ATTRLIST(attrlist,  (3 + (3 * ncerts)));
835b3e1433Swyllys 
8430a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
8530a5e8faSwyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
8630a5e8faSwyllys 		numattr++;
8730a5e8faSwyllys 
8830a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
8930a5e8faSwyllys 		    KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat));
9030a5e8faSwyllys 		numattr++;
9199ebb4caSwyllys 
9299ebb4caSwyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
9330a5e8faSwyllys 			int num = numattr;
9430a5e8faSwyllys 
9599ebb4caSwyllys 			/*
9699ebb4caSwyllys 			 * If storing more than 1 cert, gotta change
9799ebb4caSwyllys 			 * the name so we don't overwrite the previous one.
9899ebb4caSwyllys 			 * Just append a _# to the name.
9999ebb4caSwyllys 			 */
10099ebb4caSwyllys 			if (i > 0) {
10199ebb4caSwyllys 				(void) snprintf(newcertfile,
10230a5e8faSwyllys 				    sizeof (newcertfile), "%s_%d", certfile, i);
10330a5e8faSwyllys 
10430a5e8faSwyllys 				kmf_set_attr_at_index(attrlist, num,
10530a5e8faSwyllys 				    KMF_CERT_FILENAME_ATTR, newcertfile,
10630a5e8faSwyllys 				    strlen(newcertfile));
10730a5e8faSwyllys 				num++;
10899ebb4caSwyllys 			} else {
10930a5e8faSwyllys 				kmf_set_attr_at_index(attrlist, num,
11030a5e8faSwyllys 				    KMF_CERT_FILENAME_ATTR, certfile,
11130a5e8faSwyllys 				    strlen(certfile));
11230a5e8faSwyllys 				num++;
11399ebb4caSwyllys 			}
11430a5e8faSwyllys 
1155b3e1433Swyllys 			if (certs[i].kmf_private.label != NULL) {
1165b3e1433Swyllys 				kmf_set_attr_at_index(attrlist, num,
1175b3e1433Swyllys 				    KMF_CERT_LABEL_ATTR,
1185b3e1433Swyllys 				    certs[i].kmf_private.label,
1195b3e1433Swyllys 				    strlen(certs[i].kmf_private.label));
1205b3e1433Swyllys 				num++;
1215b3e1433Swyllys 			}
12230a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, num,
1235b3e1433Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i].certificate,
1245b3e1433Swyllys 			    sizeof (KMF_DATA));
12530a5e8faSwyllys 			num++;
12630a5e8faSwyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
12799ebb4caSwyllys 		}
1285b3e1433Swyllys 		free(attrlist);
1297711facfSdinak 	}
13099ebb4caSwyllys 	if (rv == KMF_OK && nkeys > 0) {
13199ebb4caSwyllys 		char newkeyfile[MAXPATHLEN];
13230a5e8faSwyllys 		numattr = 0;
1335b3e1433Swyllys 		NEW_ATTRLIST(attrlist, (4 + (4 * nkeys)));
13430a5e8faSwyllys 
13530a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
13630a5e8faSwyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
13730a5e8faSwyllys 		    sizeof (kstype));
13830a5e8faSwyllys 		numattr++;
13930a5e8faSwyllys 
14030a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
14130a5e8faSwyllys 		    KMF_ENCODE_FORMAT_ATTR, &outformat,
14230a5e8faSwyllys 		    sizeof (outformat));
14330a5e8faSwyllys 		numattr++;
14430a5e8faSwyllys 
14530a5e8faSwyllys 		if (cred != NULL && cred->credlen > 0) {
14630a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
14730a5e8faSwyllys 			    KMF_CREDENTIAL_ATTR, cred,
14830a5e8faSwyllys 			    sizeof (KMF_CREDENTIAL));
14930a5e8faSwyllys 			numattr++;
15030a5e8faSwyllys 		}
15199ebb4caSwyllys 
15299ebb4caSwyllys 		/* The order of certificates and keys should match */
15399ebb4caSwyllys 		for (i = 0; rv == KMF_OK && i < nkeys; i++) {
15430a5e8faSwyllys 			int num = numattr;
15599ebb4caSwyllys 
15699ebb4caSwyllys 			if (i > 0) {
15799ebb4caSwyllys 				(void) snprintf(newkeyfile,
15830a5e8faSwyllys 				    sizeof (newkeyfile), "%s_%d", keyfile, i);
15930a5e8faSwyllys 
16030a5e8faSwyllys 				kmf_set_attr_at_index(attrlist, num,
16130a5e8faSwyllys 				    KMF_KEY_FILENAME_ATTR, newkeyfile,
16230a5e8faSwyllys 				    strlen(newkeyfile));
16330a5e8faSwyllys 				num++;
16499ebb4caSwyllys 			} else {
16530a5e8faSwyllys 				kmf_set_attr_at_index(attrlist, num,
16630a5e8faSwyllys 				    KMF_KEY_FILENAME_ATTR, keyfile,
16730a5e8faSwyllys 				    strlen(keyfile));
16830a5e8faSwyllys 				num++;
16999ebb4caSwyllys 			}
17099ebb4caSwyllys 
1715b3e1433Swyllys 			if (i < ncerts) {
1725b3e1433Swyllys 				kmf_set_attr_at_index(attrlist, num,
1735b3e1433Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i],
1745b3e1433Swyllys 				    sizeof (KMF_CERT_DATA_ATTR));
1755b3e1433Swyllys 				num++;
1765b3e1433Swyllys 			}
17730a5e8faSwyllys 
17830a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, num,
17930a5e8faSwyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
18030a5e8faSwyllys 			    sizeof (KMF_RAW_KEY_DATA));
18130a5e8faSwyllys 			num++;
18230a5e8faSwyllys 
18330a5e8faSwyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
18499ebb4caSwyllys 		}
1855b3e1433Swyllys 		free(attrlist);
1867711facfSdinak 	}
1875b3e1433Swyllys end:
18899ebb4caSwyllys 	/*
18999ebb4caSwyllys 	 * Cleanup memory.
19099ebb4caSwyllys 	 */
19199ebb4caSwyllys 	if (certs) {
19299ebb4caSwyllys 		for (i = 0; i < ncerts; i++)
1935b3e1433Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
19499ebb4caSwyllys 		free(certs);
19599ebb4caSwyllys 	}
19699ebb4caSwyllys 	if (keys) {
19799ebb4caSwyllys 		for (i = 0; i < nkeys; i++)
19830a5e8faSwyllys 			kmf_free_raw_key(&keys[i]);
19999ebb4caSwyllys 		free(keys);
2007711facfSdinak 	}
2017711facfSdinak 
2027711facfSdinak 
20399ebb4caSwyllys 	return (rv);
2047711facfSdinak }
2057711facfSdinak 
20699ebb4caSwyllys 
20799ebb4caSwyllys static KMF_RETURN
20899ebb4caSwyllys pk_import_pk12_nss(
20999ebb4caSwyllys 	KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred,
21099ebb4caSwyllys 	KMF_CREDENTIAL *tokencred,
21199ebb4caSwyllys 	char *token_spec, char *dir, char *prefix,
21299ebb4caSwyllys 	char *nickname, char *trustflags, char *filename)
2137711facfSdinak {
21499ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
2155b3e1433Swyllys 	KMF_X509_DER_CERT *certs = NULL;
21699ebb4caSwyllys 	KMF_RAW_KEY_DATA *keys = NULL;
21799ebb4caSwyllys 	int ncerts = 0;
21899ebb4caSwyllys 	int nkeys = 0;
21999ebb4caSwyllys 	int i;
22030a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
2215b3e1433Swyllys 	KMF_ATTRIBUTE *attrlist = NULL;
22230a5e8faSwyllys 	int numattr = 0;
22399ebb4caSwyllys 
22499ebb4caSwyllys 	rv = configure_nss(kmfhandle, dir, prefix);
22599ebb4caSwyllys 	if (rv != KMF_OK)
22699ebb4caSwyllys 		return (rv);
2277711facfSdinak 
22830a5e8faSwyllys 	rv = kmf_import_objects(kmfhandle, filename, kmfcred,
22930a5e8faSwyllys 	    &certs, &ncerts, &keys, &nkeys);
2307711facfSdinak 
23199ebb4caSwyllys 	if (rv == KMF_OK)
23299ebb4caSwyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
23330a5e8faSwyllys 		    "key(s) in %s\n"), ncerts, nkeys, filename);
2347711facfSdinak 
23599ebb4caSwyllys 	if (rv == KMF_OK) {
23664012b18Swyllys 		numattr = 0;
23764012b18Swyllys 		NEW_ATTRLIST(attrlist, (4 + (2 * nkeys)));
2385b3e1433Swyllys 
23930a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
24064012b18Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
24164012b18Swyllys 		    sizeof (kstype));
24230a5e8faSwyllys 		numattr++;
24330a5e8faSwyllys 
24430a5e8faSwyllys 		if (token_spec != NULL) {
24530a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
24630a5e8faSwyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
24730a5e8faSwyllys 			    strlen(token_spec));
24830a5e8faSwyllys 			numattr++;
24930a5e8faSwyllys 		}
2507711facfSdinak 
25164012b18Swyllys 		if (nickname != NULL) {
25230a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
25364012b18Swyllys 			    KMF_KEYLABEL_ATTR, nickname,
25464012b18Swyllys 			    strlen(nickname));
25530a5e8faSwyllys 			numattr++;
25630a5e8faSwyllys 		}
2577711facfSdinak 
25864012b18Swyllys 		if (tokencred->credlen > 0) {
25964012b18Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
26064012b18Swyllys 			    KMF_CREDENTIAL_ATTR, tokencred,
26164012b18Swyllys 			    sizeof (KMF_CREDENTIAL));
26264012b18Swyllys 			numattr++;
26364012b18Swyllys 		}
26464012b18Swyllys 
26564012b18Swyllys 		/* The order of certificates and keys should match */
26664012b18Swyllys 		for (i = 0; i < nkeys; i++) {
26730a5e8faSwyllys 			int num = numattr;
2687711facfSdinak 
26964012b18Swyllys 			if (i < ncerts) {
27030a5e8faSwyllys 				kmf_set_attr_at_index(attrlist, num,
27164012b18Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i],
27264012b18Swyllys 				    sizeof (KMF_DATA));
27330a5e8faSwyllys 				num++;
27430a5e8faSwyllys 			}
27530a5e8faSwyllys 
27630a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, num,
27764012b18Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
27864012b18Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
27930a5e8faSwyllys 			num++;
28064012b18Swyllys 
28164012b18Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
2827711facfSdinak 		}
2835b3e1433Swyllys 		free(attrlist);
2845b3e1433Swyllys 		attrlist = NULL;
2857711facfSdinak 	}
2867711facfSdinak 
28799ebb4caSwyllys 	if (rv == KMF_OK) {
288*9e765c33SHuie-Ying Lee 		numattr = 0;
28964012b18Swyllys 		NEW_ATTRLIST(attrlist, (3 + (2 * ncerts)));
29030a5e8faSwyllys 
29130a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
29264012b18Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
29330a5e8faSwyllys 		numattr++;
29430a5e8faSwyllys 
29530a5e8faSwyllys 		if (token_spec != NULL) {
29630a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
29730a5e8faSwyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
29830a5e8faSwyllys 			    strlen(token_spec));
29930a5e8faSwyllys 			numattr++;
30030a5e8faSwyllys 		}
30130a5e8faSwyllys 
30264012b18Swyllys 		if (trustflags != NULL) {
30330a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
30464012b18Swyllys 			    KMF_TRUSTFLAG_ATTR, trustflags,
30564012b18Swyllys 			    strlen(trustflags));
30630a5e8faSwyllys 			numattr++;
30730a5e8faSwyllys 		}
3087711facfSdinak 
30964012b18Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
31030a5e8faSwyllys 			int num = numattr;
31130a5e8faSwyllys 
31264012b18Swyllys 			if (certs[i].kmf_private.label != NULL) {
3135b3e1433Swyllys 				kmf_set_attr_at_index(attrlist, num,
31464012b18Swyllys 				    KMF_CERT_LABEL_ATTR,
31564012b18Swyllys 				    certs[i].kmf_private.label,
31664012b18Swyllys 				    strlen(certs[i].kmf_private.label));
31764012b18Swyllys 				num++;
31864012b18Swyllys 			} else if (i == 0 && nickname != NULL) {
31964012b18Swyllys 				kmf_set_attr_at_index(attrlist, num,
32064012b18Swyllys 				    KMF_CERT_LABEL_ATTR, nickname,
32164012b18Swyllys 				    strlen(nickname));
3225b3e1433Swyllys 				num++;
3235b3e1433Swyllys 			}
32430a5e8faSwyllys 
32530a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, num,
32664012b18Swyllys 			    KMF_CERT_DATA_ATTR,
32764012b18Swyllys 			    &certs[i].certificate, sizeof (KMF_DATA));
32830a5e8faSwyllys 			num++;
32964012b18Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
33099ebb4caSwyllys 		}
3315b3e1433Swyllys 		free(attrlist);
33264012b18Swyllys 		attrlist = NULL;
33364012b18Swyllys 		if (rv != KMF_OK) {
33464012b18Swyllys 			display_error(kmfhandle, rv,
33564012b18Swyllys 			    gettext("Error storing certificate in NSS token"));
33664012b18Swyllys 		}
3377711facfSdinak 	}
3387711facfSdinak 
3395b3e1433Swyllys end:
34099ebb4caSwyllys 	/*
34199ebb4caSwyllys 	 * Cleanup memory.
34299ebb4caSwyllys 	 */
34399ebb4caSwyllys 	if (certs) {
34499ebb4caSwyllys 		for (i = 0; i < ncerts; i++)
3455b3e1433Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
34699ebb4caSwyllys 		free(certs);
3477711facfSdinak 	}
34899ebb4caSwyllys 	if (keys) {
34999ebb4caSwyllys 		for (i = 0; i < nkeys; i++)
35030a5e8faSwyllys 			kmf_free_raw_key(&keys[i]);
35199ebb4caSwyllys 		free(keys);
3527711facfSdinak 	}
3537711facfSdinak 
35499ebb4caSwyllys 	return (rv);
35599ebb4caSwyllys }
3567711facfSdinak 
35799ebb4caSwyllys static KMF_RETURN
35899ebb4caSwyllys pk_import_cert(
35999ebb4caSwyllys 	KMF_HANDLE_T kmfhandle,
36099ebb4caSwyllys 	KMF_KEYSTORE_TYPE kstype,
36199ebb4caSwyllys 	char *label, char *token_spec, char *filename,
36299ebb4caSwyllys 	char *dir, char *prefix, char *trustflags)
36399ebb4caSwyllys {
36499ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
36530a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[32];
366fa60c371Swyllys 	KMF_CREDENTIAL tokencred;
36730a5e8faSwyllys 	int i = 0;
3687711facfSdinak 
36999ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
37099ebb4caSwyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
37130a5e8faSwyllys 	} else if (kstype == KMF_KEYSTORE_NSS) {
37230a5e8faSwyllys 		rv = configure_nss(kmfhandle, dir, prefix);
3737711facfSdinak 	}
37430a5e8faSwyllys 	if (rv != KMF_OK)
37530a5e8faSwyllys 		return (rv);
3767711facfSdinak 
37730a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, i,
37830a5e8faSwyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE));
37930a5e8faSwyllys 	i++;
3807711facfSdinak 
38130a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR,
38230a5e8faSwyllys 	    filename, strlen(filename));
38330a5e8faSwyllys 	i++;
38430a5e8faSwyllys 
38530a5e8faSwyllys 	if (label != NULL) {
38630a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR,
38730a5e8faSwyllys 		    label, strlen(label));
38830a5e8faSwyllys 		i++;
3897711facfSdinak 	}
3907711facfSdinak 
39130a5e8faSwyllys 	if (kstype == KMF_KEYSTORE_NSS) {
39230a5e8faSwyllys 		if (trustflags != NULL) {
39330a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR,
39430a5e8faSwyllys 			    trustflags, strlen(trustflags));
39530a5e8faSwyllys 			i++;
39630a5e8faSwyllys 		}
3977711facfSdinak 
39830a5e8faSwyllys 		if (token_spec != NULL) {
39930a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, i,
40030a5e8faSwyllys 			    KMF_TOKEN_LABEL_ATTR,
40130a5e8faSwyllys 			    token_spec, strlen(token_spec));
40230a5e8faSwyllys 			i++;
40330a5e8faSwyllys 		}
40430a5e8faSwyllys 	}
40530a5e8faSwyllys 
40630a5e8faSwyllys 	rv = kmf_import_cert(kmfhandle, i, attrlist);
407fa60c371Swyllys 	if (rv == KMF_ERR_AUTH_FAILED) {
408fa60c371Swyllys 		/*
409fa60c371Swyllys 		 * The token requires a credential, prompt and try again.
410fa60c371Swyllys 		 */
411fa60c371Swyllys 		(void) get_token_password(kstype, token_spec, &tokencred);
412fa60c371Swyllys 		kmf_set_attr_at_index(attrlist, i, KMF_CREDENTIAL_ATTR,
413fa60c371Swyllys 		    &tokencred, sizeof (KMF_CREDENTIAL));
414fa60c371Swyllys 		i++;
415fa60c371Swyllys 
416fa60c371Swyllys 		rv = kmf_import_cert(kmfhandle, i, attrlist);
417fa60c371Swyllys 
418fa60c371Swyllys 	}
41999ebb4caSwyllys 	return (rv);
4207711facfSdinak }
4217711facfSdinak 
42299ebb4caSwyllys static KMF_RETURN
42399ebb4caSwyllys pk_import_file_crl(void *kmfhandle,
42499ebb4caSwyllys 	char *infile,
42599ebb4caSwyllys 	char *outfile,
42699ebb4caSwyllys 	KMF_ENCODE_FORMAT outfmt)
4277711facfSdinak {
42830a5e8faSwyllys 	int numattr = 0;
42930a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[8];
43030a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
43130a5e8faSwyllys 
43230a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
43330a5e8faSwyllys 	    &kstype, sizeof (kstype));
43430a5e8faSwyllys 	numattr++;
43530a5e8faSwyllys 	if (infile) {
43630a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
43730a5e8faSwyllys 		    KMF_CRL_FILENAME_ATTR, infile, strlen(infile));
43830a5e8faSwyllys 		numattr++;
43930a5e8faSwyllys 	}
44030a5e8faSwyllys 	if (outfile) {
44130a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
44230a5e8faSwyllys 		    KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile));
44330a5e8faSwyllys 		numattr++;
44430a5e8faSwyllys 	}
44530a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
44630a5e8faSwyllys 	    KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt));
44730a5e8faSwyllys 	numattr++;
4487711facfSdinak 
44930a5e8faSwyllys 	return (kmf_import_crl(kmfhandle, numattr, attrlist));
45099ebb4caSwyllys }
4517711facfSdinak 
45299ebb4caSwyllys static KMF_RETURN
45399ebb4caSwyllys pk_import_nss_crl(void *kmfhandle,
45499ebb4caSwyllys 	boolean_t verify_crl_flag,
45599ebb4caSwyllys 	char *infile,
45699ebb4caSwyllys 	char *outdir,
45799ebb4caSwyllys 	char *prefix)
45899ebb4caSwyllys {
45999ebb4caSwyllys 	KMF_RETURN rv;
46030a5e8faSwyllys 	int numattr = 0;
46130a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[4];
46230a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
46399ebb4caSwyllys 
46499ebb4caSwyllys 	rv = configure_nss(kmfhandle, outdir, prefix);
46599ebb4caSwyllys 	if (rv != KMF_OK)
4667711facfSdinak 		return (rv);
4677711facfSdinak 
46830a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
46930a5e8faSwyllys 	    &kstype, sizeof (kstype));
47030a5e8faSwyllys 	numattr++;
47130a5e8faSwyllys 	if (infile) {
47230a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR,
47330a5e8faSwyllys 		    infile, strlen(infile));
47430a5e8faSwyllys 		numattr++;
47530a5e8faSwyllys 	}
47630a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR,
47730a5e8faSwyllys 	    &verify_crl_flag, sizeof (verify_crl_flag));
47830a5e8faSwyllys 	numattr++;
4797711facfSdinak 
48030a5e8faSwyllys 	return (kmf_import_crl(kmfhandle, numattr, attrlist));
4817711facfSdinak 
4827711facfSdinak }
4837711facfSdinak 
48499ebb4caSwyllys static KMF_RETURN
48599ebb4caSwyllys pk_import_pk12_pk11(
48699ebb4caSwyllys 	KMF_HANDLE_T kmfhandle,
48799ebb4caSwyllys 	KMF_CREDENTIAL *p12cred,
48899ebb4caSwyllys 	KMF_CREDENTIAL *tokencred,
48999ebb4caSwyllys 	char *label, char *token_spec,
49099ebb4caSwyllys 	char *filename)
4917711facfSdinak {
49299ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
4935b3e1433Swyllys 	KMF_X509_DER_CERT *certs = NULL;
49499ebb4caSwyllys 	KMF_RAW_KEY_DATA *keys = NULL;
49599ebb4caSwyllys 	int ncerts = 0;
49699ebb4caSwyllys 	int nkeys = 0;
49799ebb4caSwyllys 	int i;
49830a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
4995b3e1433Swyllys 	KMF_ATTRIBUTE *attrlist = NULL;
50030a5e8faSwyllys 	int numattr = 0;
5017711facfSdinak 
50299ebb4caSwyllys 	rv = select_token(kmfhandle, token_spec, FALSE);
5037711facfSdinak 
50499ebb4caSwyllys 	if (rv != KMF_OK) {
50599ebb4caSwyllys 		return (rv);
5067711facfSdinak 	}
5077711facfSdinak 
50830a5e8faSwyllys 	rv = kmf_import_objects(kmfhandle, filename, p12cred,
50930a5e8faSwyllys 	    &certs, &ncerts, &keys, &nkeys);
5107711facfSdinak 
51199ebb4caSwyllys 	if (rv == KMF_OK) {
5125b3e1433Swyllys 		NEW_ATTRLIST(attrlist, (3 + (2 * nkeys)));
51330a5e8faSwyllys 
51430a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
51530a5e8faSwyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
51630a5e8faSwyllys 		    sizeof (kstype));
51730a5e8faSwyllys 		numattr++;
51830a5e8faSwyllys 
51930a5e8faSwyllys 		if (label != NULL) {
52030a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
52130a5e8faSwyllys 			    KMF_KEYLABEL_ATTR, label,
52230a5e8faSwyllys 			    strlen(label));
52330a5e8faSwyllys 			numattr++;
52430a5e8faSwyllys 		}
52530a5e8faSwyllys 
52630a5e8faSwyllys 		if (tokencred != NULL && tokencred->credlen > 0) {
52730a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
52830a5e8faSwyllys 			    KMF_CREDENTIAL_ATTR, tokencred,
52930a5e8faSwyllys 			    sizeof (KMF_CREDENTIAL));
53030a5e8faSwyllys 			numattr++;
53130a5e8faSwyllys 		}
5327711facfSdinak 
53399ebb4caSwyllys 		/* The order of certificates and keys should match */
53499ebb4caSwyllys 		for (i = 0; i < nkeys; i++) {
53530a5e8faSwyllys 			int num = numattr;
53630a5e8faSwyllys 
5375b3e1433Swyllys 			if (i < ncerts) {
5385b3e1433Swyllys 				kmf_set_attr_at_index(attrlist, num,
5395b3e1433Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i].certificate,
5405b3e1433Swyllys 				    sizeof (KMF_DATA));
5415b3e1433Swyllys 				num++;
5425b3e1433Swyllys 			}
54330a5e8faSwyllys 
54430a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, num,
54530a5e8faSwyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
54630a5e8faSwyllys 			    sizeof (KMF_RAW_KEY_DATA));
54730a5e8faSwyllys 			num++;
54830a5e8faSwyllys 
54930a5e8faSwyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
5507711facfSdinak 
55199ebb4caSwyllys 		}
5525b3e1433Swyllys 		free(attrlist);
5537711facfSdinak 	}
5547711facfSdinak 
55599ebb4caSwyllys 	if (rv == KMF_OK) {
5565b3e1433Swyllys 		numattr = 0;
5575b3e1433Swyllys 		NEW_ATTRLIST(attrlist, (1 + (2 * ncerts)));
5587711facfSdinak 
55999ebb4caSwyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
56030a5e8faSwyllys 		    "key(s) in %s\n"), ncerts, nkeys, filename);
5615b3e1433Swyllys 
56230a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
56330a5e8faSwyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
56430a5e8faSwyllys 		numattr++;
5657711facfSdinak 
56699ebb4caSwyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
56730a5e8faSwyllys 			int num = numattr;
5685b3e1433Swyllys 			if (certs[i].kmf_private.label != NULL) {
5695b3e1433Swyllys 				kmf_set_attr_at_index(attrlist, num,
5705b3e1433Swyllys 				    KMF_CERT_LABEL_ATTR,
5715b3e1433Swyllys 				    certs[i].kmf_private.label,
5725b3e1433Swyllys 				    strlen(certs[i].kmf_private.label));
5735b3e1433Swyllys 				num++;
5745b3e1433Swyllys 			} else if (i == 0 && label != NULL) {
57530a5e8faSwyllys 				kmf_set_attr_at_index(attrlist, num,
57630a5e8faSwyllys 				    KMF_CERT_LABEL_ATTR, label, strlen(label));
57730a5e8faSwyllys 				num++;
57830a5e8faSwyllys 			}
5797711facfSdinak 
58030a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, num,
5815b3e1433Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i].certificate,
5825b3e1433Swyllys 			    sizeof (KMF_DATA));
58330a5e8faSwyllys 			num++;
58430a5e8faSwyllys 
58530a5e8faSwyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
58699ebb4caSwyllys 		}
5875b3e1433Swyllys 		free(attrlist);
5887711facfSdinak 	}
5897711facfSdinak 
5905b3e1433Swyllys end:
59199ebb4caSwyllys 	/*
59299ebb4caSwyllys 	 * Cleanup memory.
59399ebb4caSwyllys 	 */
59499ebb4caSwyllys 	if (certs) {
59599ebb4caSwyllys 		for (i = 0; i < ncerts; i++)
5965b3e1433Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
59799ebb4caSwyllys 		free(certs);
59899ebb4caSwyllys 	}
59999ebb4caSwyllys 	if (keys) {
60099ebb4caSwyllys 		for (i = 0; i < nkeys; i++)
60130a5e8faSwyllys 			kmf_free_raw_key(&keys[i]);
60299ebb4caSwyllys 		free(keys);
6037711facfSdinak 	}
6047711facfSdinak 
60599ebb4caSwyllys 	return (rv);
6067711facfSdinak }
6077711facfSdinak 
60846d33f7eSwyllys /*ARGSUSED*/
60930a5e8faSwyllys static KMF_RETURN
61030a5e8faSwyllys pk_import_keys(KMF_HANDLE_T kmfhandle,
61130a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype, char *token_spec,
61230a5e8faSwyllys 	KMF_CREDENTIAL *cred, char *filename,
61330a5e8faSwyllys 	char *label, char *senstr, char *extstr)
61430a5e8faSwyllys {
61530a5e8faSwyllys 	KMF_RETURN rv = KMF_OK;
61630a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[16];
61730a5e8faSwyllys 	KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL;
61830a5e8faSwyllys 	int numattr = 0;
61930a5e8faSwyllys 	KMF_KEY_HANDLE key;
62030a5e8faSwyllys 	KMF_RAW_KEY_DATA rawkey;
62130a5e8faSwyllys 	KMF_KEY_CLASS class = KMF_ASYM_PRI;
62230a5e8faSwyllys 	int numkeys = 1;
62330a5e8faSwyllys 
62430a5e8faSwyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
62530a5e8faSwyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
62630a5e8faSwyllys 	}
62730a5e8faSwyllys 	if (rv != KMF_OK)
62830a5e8faSwyllys 		return (rv);
62930a5e8faSwyllys 	/*
63030a5e8faSwyllys 	 * First, set up to read the keyfile using the FILE plugin
63130a5e8faSwyllys 	 * mechanisms.
63230a5e8faSwyllys 	 */
63330a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
63430a5e8faSwyllys 	    &fileks, sizeof (fileks));
63530a5e8faSwyllys 	numattr++;
63630a5e8faSwyllys 
63730a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
63830a5e8faSwyllys 	    &numkeys, sizeof (numkeys));
63930a5e8faSwyllys 	numattr++;
64030a5e8faSwyllys 
64130a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
64230a5e8faSwyllys 	    &key, sizeof (key));
64330a5e8faSwyllys 	numattr++;
64430a5e8faSwyllys 
64530a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
64630a5e8faSwyllys 	    &rawkey, sizeof (rawkey));
64730a5e8faSwyllys 	numattr++;
64830a5e8faSwyllys 
64930a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
65030a5e8faSwyllys 	    &class, sizeof (class));
65130a5e8faSwyllys 	numattr++;
65230a5e8faSwyllys 
65330a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
65430a5e8faSwyllys 	    filename, strlen(filename));
65530a5e8faSwyllys 	numattr++;
65630a5e8faSwyllys 
65730a5e8faSwyllys 	rv = kmf_find_key(kmfhandle, numattr, attrlist);
65830a5e8faSwyllys 	if (rv == KMF_OK) {
65930a5e8faSwyllys 		numattr = 0;
66030a5e8faSwyllys 
66130a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
66230a5e8faSwyllys 		    &kstype, sizeof (kstype));
66330a5e8faSwyllys 		numattr++;
66430a5e8faSwyllys 
66530a5e8faSwyllys 		if (cred != NULL && cred->credlen > 0) {
66630a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
66730a5e8faSwyllys 			    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
66830a5e8faSwyllys 			numattr++;
66930a5e8faSwyllys 		}
67030a5e8faSwyllys 
67130a5e8faSwyllys 		if (label != NULL) {
67230a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
67330a5e8faSwyllys 			    KMF_KEYLABEL_ATTR, label, strlen(label));
67430a5e8faSwyllys 			numattr++;
67530a5e8faSwyllys 		}
67630a5e8faSwyllys 
67730a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
67830a5e8faSwyllys 		    KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey));
67930a5e8faSwyllys 		numattr++;
68030a5e8faSwyllys 
68130a5e8faSwyllys 		rv = kmf_store_key(kmfhandle, numattr, attrlist);
68230a5e8faSwyllys 		if (rv == KMF_OK) {
68346d33f7eSwyllys 			(void) printf(gettext("Importing %d keys\n"), numkeys);
68430a5e8faSwyllys 		}
68530a5e8faSwyllys 
68630a5e8faSwyllys 		kmf_free_kmf_key(kmfhandle, &key);
68730a5e8faSwyllys 		kmf_free_raw_key(&rawkey);
68830a5e8faSwyllys 	} else {
68930a5e8faSwyllys 		cryptoerror(LOG_STDERR,
69030a5e8faSwyllys 		    gettext("Failed to load key from file (%s)\n"),
69130a5e8faSwyllys 		    filename);
69230a5e8faSwyllys 	}
69330a5e8faSwyllys 	return (rv);
69430a5e8faSwyllys }
69530a5e8faSwyllys 
69630a5e8faSwyllys static KMF_RETURN
69730a5e8faSwyllys pk_import_rawkey(KMF_HANDLE_T kmfhandle,
69830a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype, char *token,
69930a5e8faSwyllys 	KMF_CREDENTIAL *cred,
70030a5e8faSwyllys 	char *filename, char *label, KMF_KEY_ALG keyAlg,
70130a5e8faSwyllys 	char *senstr, char *extstr)
70230a5e8faSwyllys {
70330a5e8faSwyllys 	KMF_RETURN rv = KMF_OK;
70430a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[16];
70530a5e8faSwyllys 	int numattr = 0;
70630a5e8faSwyllys 	uint32_t keylen;
70730a5e8faSwyllys 	boolean_t sensitive = B_FALSE;
70830a5e8faSwyllys 	boolean_t not_extractable = B_FALSE;
70930a5e8faSwyllys 	KMF_DATA keydata = {NULL, 0};
71030a5e8faSwyllys 	KMF_KEY_HANDLE rawkey;
71130a5e8faSwyllys 
71230a5e8faSwyllys 	rv = kmf_read_input_file(kmfhandle, filename, &keydata);
71330a5e8faSwyllys 	if (rv != KMF_OK)
71430a5e8faSwyllys 		return (rv);
71530a5e8faSwyllys 
71630a5e8faSwyllys 	rv = select_token(kmfhandle, token, FALSE);
71730a5e8faSwyllys 
71830a5e8faSwyllys 	if (rv != KMF_OK) {
71930a5e8faSwyllys 		return (rv);
72030a5e8faSwyllys 	}
72130a5e8faSwyllys 	if (senstr != NULL) {
72230a5e8faSwyllys 		if (tolower(senstr[0]) == 'y')
72330a5e8faSwyllys 			sensitive = B_TRUE;
72430a5e8faSwyllys 		else if (tolower(senstr[0]) == 'n')
72530a5e8faSwyllys 			sensitive = B_FALSE;
72630a5e8faSwyllys 		else {
72730a5e8faSwyllys 			cryptoerror(LOG_STDERR,
72830a5e8faSwyllys 			    gettext("Incorrect sensitive option value.\n"));
72930a5e8faSwyllys 			return (KMF_ERR_BAD_PARAMETER);
73030a5e8faSwyllys 		}
73130a5e8faSwyllys 	}
73230a5e8faSwyllys 
73330a5e8faSwyllys 	if (extstr != NULL) {
73430a5e8faSwyllys 		if (tolower(extstr[0]) == 'y')
73530a5e8faSwyllys 			not_extractable = B_FALSE;
73630a5e8faSwyllys 		else if (tolower(extstr[0]) == 'n')
73730a5e8faSwyllys 			not_extractable = B_TRUE;
73830a5e8faSwyllys 		else {
73930a5e8faSwyllys 			cryptoerror(LOG_STDERR,
74030a5e8faSwyllys 			    gettext("Incorrect extractable option value.\n"));
74130a5e8faSwyllys 			return (KMF_ERR_BAD_PARAMETER);
74230a5e8faSwyllys 		}
74330a5e8faSwyllys 	}
74430a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
74530a5e8faSwyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
74630a5e8faSwyllys 	numattr++;
74730a5e8faSwyllys 
74830a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
74930a5e8faSwyllys 	    KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey));
75030a5e8faSwyllys 	numattr++;
75130a5e8faSwyllys 
75230a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
75330a5e8faSwyllys 	    KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG));
75430a5e8faSwyllys 	numattr++;
75530a5e8faSwyllys 
75630a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
75730a5e8faSwyllys 	    KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length);
75830a5e8faSwyllys 	numattr++;
75930a5e8faSwyllys 
76030a5e8faSwyllys 	/* Key length is given in bits not bytes */
76130a5e8faSwyllys 	keylen = keydata.Length * 8;
76230a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
76330a5e8faSwyllys 	    KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length));
76430a5e8faSwyllys 	numattr++;
76530a5e8faSwyllys 
76630a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
76730a5e8faSwyllys 	    KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive));
76830a5e8faSwyllys 	numattr++;
76930a5e8faSwyllys 
77030a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
77130a5e8faSwyllys 	    KMF_NON_EXTRACTABLE_BOOL_ATTR, &not_extractable,
77230a5e8faSwyllys 	    sizeof (not_extractable));
77330a5e8faSwyllys 	numattr++;
77430a5e8faSwyllys 
77530a5e8faSwyllys 	if (label != NULL) {
77630a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
77730a5e8faSwyllys 		    KMF_KEYLABEL_ATTR, label, strlen(label));
77830a5e8faSwyllys 		numattr++;
77930a5e8faSwyllys 	}
78030a5e8faSwyllys 	if (cred != NULL && cred->credlen > 0) {
78130a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
78230a5e8faSwyllys 		    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
78330a5e8faSwyllys 		numattr++;
78430a5e8faSwyllys 	}
78530a5e8faSwyllys 	rv = kmf_create_sym_key(kmfhandle, numattr, attrlist);
78630a5e8faSwyllys 
78730a5e8faSwyllys 	return (rv);
78830a5e8faSwyllys }
78930a5e8faSwyllys 
7907711facfSdinak /*
79199ebb4caSwyllys  * Import objects from into KMF repositories.
7927711facfSdinak  */
7937711facfSdinak int
7947711facfSdinak pk_import(int argc, char *argv[])
7957711facfSdinak {
79649e21299Sdinak 	int		opt;
79749e21299Sdinak 	extern int	optind_av;
79849e21299Sdinak 	extern char	*optarg_av;
79949e21299Sdinak 	char		*token_spec = NULL;
8007711facfSdinak 	char		*filename = NULL;
80199ebb4caSwyllys 	char		*keyfile = NULL;
80299ebb4caSwyllys 	char		*certfile = NULL;
80399ebb4caSwyllys 	char		*crlfile = NULL;
80430a5e8faSwyllys 	char		*label = NULL;
80599ebb4caSwyllys 	char		*dir = NULL;
80699ebb4caSwyllys 	char		*prefix = NULL;
80799ebb4caSwyllys 	char		*trustflags = NULL;
80899ebb4caSwyllys 	char		*verify_crl = NULL;
80930a5e8faSwyllys 	char		*keytype = "generic";
81030a5e8faSwyllys 	char		*senstr = NULL;
81130a5e8faSwyllys 	char		*extstr = NULL;
81299ebb4caSwyllys 	boolean_t	verify_crl_flag = B_FALSE;
81399ebb4caSwyllys 	int		oclass = 0;
81499ebb4caSwyllys 	KMF_KEYSTORE_TYPE	kstype = 0;
81599ebb4caSwyllys 	KMF_ENCODE_FORMAT	kfmt = 0;
81699ebb4caSwyllys 	KMF_ENCODE_FORMAT	okfmt = KMF_FORMAT_ASN1;
81799ebb4caSwyllys 	KMF_RETURN		rv = KMF_OK;
81899ebb4caSwyllys 	KMF_CREDENTIAL	pk12cred = { NULL, 0 };
81999ebb4caSwyllys 	KMF_CREDENTIAL	tokencred = { NULL, 0 };
82099ebb4caSwyllys 	KMF_HANDLE_T	kmfhandle = NULL;
82130a5e8faSwyllys 	KMF_KEY_ALG	keyAlg = KMF_GENERIC_SECRET;
8227711facfSdinak 
82349e21299Sdinak 	/* Parse command line options.  Do NOT i18n/l10n. */
82499ebb4caSwyllys 	while ((opt = getopt_av(argc, argv,
82530a5e8faSwyllys 	    "T:(token)i:(infile)"
82630a5e8faSwyllys 	    "k:(keystore)y:(objtype)"
82730a5e8faSwyllys 	    "d:(dir)p:(prefix)"
82830a5e8faSwyllys 	    "n:(certlabel)N:(label)"
82930a5e8faSwyllys 	    "K:(outkey)c:(outcert)"
83030a5e8faSwyllys 	    "v:(verifycrl)l:(outcrl)"
83130a5e8faSwyllys 	    "E:(keytype)s:(sensitive)x:(extractable)"
832448b8615Swyllys 	    "t:(trust)F:(outformat)")) != EOF) {
83399ebb4caSwyllys 		if (EMPTYSTRING(optarg_av))
83499ebb4caSwyllys 			return (PK_ERR_USAGE);
83549e21299Sdinak 		switch (opt) {
83649e21299Sdinak 		case 'T':	/* token specifier */
83749e21299Sdinak 			if (token_spec)
83849e21299Sdinak 				return (PK_ERR_USAGE);
83949e21299Sdinak 			token_spec = optarg_av;
84049e21299Sdinak 			break;
84199ebb4caSwyllys 		case 'c':	/* output cert file name */
84299ebb4caSwyllys 			if (certfile)
84399ebb4caSwyllys 				return (PK_ERR_USAGE);
84499ebb4caSwyllys 			certfile = optarg_av;
84599ebb4caSwyllys 			break;
84699ebb4caSwyllys 		case 'l':	/* output CRL file name */
84799ebb4caSwyllys 			if (crlfile)
84899ebb4caSwyllys 				return (PK_ERR_USAGE);
84999ebb4caSwyllys 			crlfile = optarg_av;
85099ebb4caSwyllys 			break;
85199ebb4caSwyllys 		case 'K':	/* output key file name */
85299ebb4caSwyllys 			if (keyfile)
85399ebb4caSwyllys 				return (PK_ERR_USAGE);
85499ebb4caSwyllys 			keyfile = optarg_av;
85599ebb4caSwyllys 			break;
85649e21299Sdinak 		case 'i':	/* input file name */
85749e21299Sdinak 			if (filename)
85849e21299Sdinak 				return (PK_ERR_USAGE);
85949e21299Sdinak 			filename = optarg_av;
86049e21299Sdinak 			break;
86199ebb4caSwyllys 		case 'k':
86299ebb4caSwyllys 			kstype = KS2Int(optarg_av);
86399ebb4caSwyllys 			if (kstype == 0)
86499ebb4caSwyllys 				return (PK_ERR_USAGE);
86599ebb4caSwyllys 			break;
86699ebb4caSwyllys 		case 'y':
86799ebb4caSwyllys 			oclass = OT2Int(optarg_av);
86899ebb4caSwyllys 			if (oclass == -1)
86999ebb4caSwyllys 				return (PK_ERR_USAGE);
87099ebb4caSwyllys 			break;
87199ebb4caSwyllys 		case 'd':
87299ebb4caSwyllys 			dir = optarg_av;
87399ebb4caSwyllys 			break;
87499ebb4caSwyllys 		case 'p':
87599ebb4caSwyllys 			if (prefix)
87699ebb4caSwyllys 				return (PK_ERR_USAGE);
87799ebb4caSwyllys 			prefix = optarg_av;
87899ebb4caSwyllys 			break;
87999ebb4caSwyllys 		case 'n':
88099ebb4caSwyllys 		case 'N':
88130a5e8faSwyllys 			if (label)
88299ebb4caSwyllys 				return (PK_ERR_USAGE);
88330a5e8faSwyllys 			label = optarg_av;
88499ebb4caSwyllys 			break;
88599ebb4caSwyllys 		case 'F':
88699ebb4caSwyllys 			okfmt = Str2Format(optarg_av);
88799ebb4caSwyllys 			if (okfmt == KMF_FORMAT_UNDEF)
88899ebb4caSwyllys 				return (PK_ERR_USAGE);
88999ebb4caSwyllys 			break;
89099ebb4caSwyllys 		case 't':
89199ebb4caSwyllys 			if (trustflags)
89299ebb4caSwyllys 				return (PK_ERR_USAGE);
89399ebb4caSwyllys 			trustflags = optarg_av;
89499ebb4caSwyllys 			break;
89599ebb4caSwyllys 		case 'v':
89699ebb4caSwyllys 			verify_crl = optarg_av;
89799ebb4caSwyllys 			if (tolower(verify_crl[0]) == 'y')
89899ebb4caSwyllys 				verify_crl_flag = B_TRUE;
89999ebb4caSwyllys 			else if (tolower(verify_crl[0]) == 'n')
90099ebb4caSwyllys 				verify_crl_flag = B_FALSE;
90199ebb4caSwyllys 			else
90299ebb4caSwyllys 				return (PK_ERR_USAGE);
90399ebb4caSwyllys 			break;
90430a5e8faSwyllys 		case 'E':
90530a5e8faSwyllys 			keytype = optarg_av;
90630a5e8faSwyllys 			break;
90730a5e8faSwyllys 		case 's':
90830a5e8faSwyllys 			if (senstr)
90930a5e8faSwyllys 				return (PK_ERR_USAGE);
91030a5e8faSwyllys 			senstr = optarg_av;
91130a5e8faSwyllys 			break;
91230a5e8faSwyllys 		case 'x':
91330a5e8faSwyllys 			if (extstr)
91430a5e8faSwyllys 				return (PK_ERR_USAGE);
91530a5e8faSwyllys 			extstr = optarg_av;
91630a5e8faSwyllys 			break;
91749e21299Sdinak 		default:
91849e21299Sdinak 			return (PK_ERR_USAGE);
91949e21299Sdinak 			break;
92049e21299Sdinak 		}
92149e21299Sdinak 	}
92249e21299Sdinak 
92399ebb4caSwyllys 	/* Assume keystore = PKCS#11 if not specified */
92499ebb4caSwyllys 	if (kstype == 0)
92599ebb4caSwyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
9267711facfSdinak 
92749e21299Sdinak 	/* Filename arg is required. */
92899ebb4caSwyllys 	if (EMPTYSTRING(filename)) {
92999ebb4caSwyllys 		cryptoerror(LOG_STDERR, gettext("The 'infile' parameter"
93030a5e8faSwyllys 		    "is required for the import operation.\n"));
9317711facfSdinak 		return (PK_ERR_USAGE);
93299ebb4caSwyllys 	}
9337711facfSdinak 
93449e21299Sdinak 	/* No additional args allowed. */
93549e21299Sdinak 	argc -= optind_av;
93649e21299Sdinak 	argv += optind_av;
93749e21299Sdinak 	if (argc)
93849e21299Sdinak 		return (PK_ERR_USAGE);
9397711facfSdinak 
940577f4726Swyllys 	DIR_OPTION_CHECK(kstype, dir);
941577f4726Swyllys 
94299ebb4caSwyllys 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
94399ebb4caSwyllys 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
94430a5e8faSwyllys 	    kstype != KMF_KEYSTORE_PK11TOKEN) {
9457711facfSdinak 
94699ebb4caSwyllys 		(void) fprintf(stderr, gettext("The objtype parameter "
94730a5e8faSwyllys 		    "is only relevant if keystore=pkcs11\n"));
94899ebb4caSwyllys 		return (PK_ERR_USAGE);
94999ebb4caSwyllys 	}
9507711facfSdinak 
95199ebb4caSwyllys 	/*
95299ebb4caSwyllys 	 * You must specify a certlabel (cert label) when importing
95399ebb4caSwyllys 	 * into NSS or PKCS#11.
95499ebb4caSwyllys 	 */
95599ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_NSS &&
95630a5e8faSwyllys 	    (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) {
95799ebb4caSwyllys 		cryptoerror(LOG_STDERR, gettext("The 'label' argument "
95830a5e8faSwyllys 		    "is required for this operation\n"));
95999ebb4caSwyllys 		return (PK_ERR_USAGE);
9607711facfSdinak 	}
9617711facfSdinak 
96230a5e8faSwyllys 	if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) {
96330a5e8faSwyllys 		/*
96430a5e8faSwyllys 		 * Allow for raw key data to be imported.
96530a5e8faSwyllys 		 */
96630a5e8faSwyllys 		if (rv == KMF_ERR_ENCODING) {
96730a5e8faSwyllys 			rv = KMF_OK;
96830a5e8faSwyllys 			kfmt = KMF_FORMAT_RAWKEY;
96930a5e8faSwyllys 			/*
97030a5e8faSwyllys 			 * Set the object class only if it was not
97130a5e8faSwyllys 			 * given on the command line or if it was
97230a5e8faSwyllys 			 * specified as a symmetric key object.
97330a5e8faSwyllys 			 */
97430a5e8faSwyllys 			if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) {
97530a5e8faSwyllys 				oclass = PK_SYMKEY_OBJ;
97630a5e8faSwyllys 			} else {
97730a5e8faSwyllys 				cryptoerror(LOG_STDERR, gettext(
97830a5e8faSwyllys 				    "The input file does not contain the "
97930a5e8faSwyllys 				    "object type indicated on command "
98030a5e8faSwyllys 				    "line."));
98130a5e8faSwyllys 				return (KMF_ERR_BAD_PARAMETER);
98230a5e8faSwyllys 			}
98330a5e8faSwyllys 		} else {
98430a5e8faSwyllys 			cryptoerror(LOG_STDERR,
98530a5e8faSwyllys 			    gettext("File format not recognized."));
98630a5e8faSwyllys 			return (rv);
98799ebb4caSwyllys 		}
9887711facfSdinak 	}
9897711facfSdinak 
99030a5e8faSwyllys 	/* Check parameters for raw key import operation */
99130a5e8faSwyllys 	if (kfmt == KMF_FORMAT_RAWKEY) {
99230a5e8faSwyllys 		if (keytype != NULL &&
99330a5e8faSwyllys 		    Str2SymKeyType(keytype, &keyAlg) != 0) {
99430a5e8faSwyllys 			cryptoerror(LOG_STDERR,
99530a5e8faSwyllys 			    gettext("Unrecognized keytype(%s).\n"), keytype);
99630a5e8faSwyllys 			return (PK_ERR_USAGE);
99730a5e8faSwyllys 		}
99830a5e8faSwyllys 		if (senstr != NULL && extstr != NULL &&
99930a5e8faSwyllys 		    kstype != KMF_KEYSTORE_PK11TOKEN) {
100030a5e8faSwyllys 			cryptoerror(LOG_STDERR,
100130a5e8faSwyllys 			    gettext("The sensitive or extractable option "
100230a5e8faSwyllys 			    "applies only when importing a key from a file "
100330a5e8faSwyllys 			    "into a PKCS#11 keystore.\n"));
100430a5e8faSwyllys 			return (PK_ERR_USAGE);
100530a5e8faSwyllys 		}
10067711facfSdinak 	}
100730a5e8faSwyllys 
100830a5e8faSwyllys 	/* If no objtype was given, treat it as a certificate */
100999ebb4caSwyllys 	if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 ||
101030a5e8faSwyllys 	    kfmt == KMF_FORMAT_PEM))
101199ebb4caSwyllys 		oclass = PK_CERT_OBJ;
10127711facfSdinak 
101399ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_NSS) {
101499ebb4caSwyllys 		if (oclass == PK_CRL_OBJ &&
101530a5e8faSwyllys 		    (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
101699ebb4caSwyllys 			cryptoerror(LOG_STDERR, gettext(
101730a5e8faSwyllys 			    "CRL data can only be imported as DER or "
101830a5e8faSwyllys 			    "PEM format"));
101999ebb4caSwyllys 			return (PK_ERR_USAGE);
102099ebb4caSwyllys 		}
10217711facfSdinak 
102299ebb4caSwyllys 		if (oclass == PK_CERT_OBJ &&
102330a5e8faSwyllys 		    (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
102499ebb4caSwyllys 			cryptoerror(LOG_STDERR, gettext(
102530a5e8faSwyllys 			    "Certificates can only be imported as DER or "
102630a5e8faSwyllys 			    "PEM format"));
102799ebb4caSwyllys 			return (PK_ERR_USAGE);
102899ebb4caSwyllys 		}
10297711facfSdinak 
103099ebb4caSwyllys 		/* we do not import private keys except in PKCS12 bundles */
103199ebb4caSwyllys 		if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
103299ebb4caSwyllys 			cryptoerror(LOG_STDERR, gettext(
103330a5e8faSwyllys 			    "Private key data can only be imported as part "
103430a5e8faSwyllys 			    "of a PKCS12 file.\n"));
103599ebb4caSwyllys 			return (PK_ERR_USAGE);
103699ebb4caSwyllys 		}
10377711facfSdinak 	}
10387711facfSdinak 
103999ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) {
104099ebb4caSwyllys 		if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
10417711facfSdinak 			cryptoerror(LOG_STDERR, gettext(
104230a5e8faSwyllys 			    "The 'outkey' and 'outcert' parameters "
104330a5e8faSwyllys 			    "are required for the import operation "
104430a5e8faSwyllys 			    "when the 'file' keystore is used.\n"));
104599ebb4caSwyllys 			return (PK_ERR_USAGE);
10467711facfSdinak 		}
104799ebb4caSwyllys 	}
10487711facfSdinak 
104999ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
105099ebb4caSwyllys 		token_spec = PK_DEFAULT_PK11TOKEN;
105199ebb4caSwyllys 	else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
105299ebb4caSwyllys 		token_spec = DEFAULT_NSS_TOKEN;
105399ebb4caSwyllys 
105499ebb4caSwyllys 	if (kfmt == KMF_FORMAT_PKCS12) {
105599ebb4caSwyllys 		(void) get_pk12_password(&pk12cred);
105630a5e8faSwyllys 	}
105799ebb4caSwyllys 
105830a5e8faSwyllys 	if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY ||
105930a5e8faSwyllys 	    (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) &&
106030a5e8faSwyllys 	    (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) {
106130a5e8faSwyllys 		(void) get_token_password(kstype, token_spec, &tokencred);
106299ebb4caSwyllys 	}
106399ebb4caSwyllys 
106430a5e8faSwyllys 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
106599ebb4caSwyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing "
106630a5e8faSwyllys 		    "KMF: 0x%02x\n"), rv);
106799ebb4caSwyllys 		goto end;
106899ebb4caSwyllys 	}
106999ebb4caSwyllys 
107099ebb4caSwyllys 	switch (kstype) {
107199ebb4caSwyllys 		case KMF_KEYSTORE_PK11TOKEN:
107299ebb4caSwyllys 			if (kfmt == KMF_FORMAT_PKCS12)
107399ebb4caSwyllys 				rv = pk_import_pk12_pk11(
107430a5e8faSwyllys 				    kmfhandle, &pk12cred,
107530a5e8faSwyllys 				    &tokencred, label,
107630a5e8faSwyllys 				    token_spec, filename);
107799ebb4caSwyllys 			else if (oclass == PK_CERT_OBJ)
107899ebb4caSwyllys 				rv = pk_import_cert(
107930a5e8faSwyllys 				    kmfhandle, kstype,
108030a5e8faSwyllys 				    label, token_spec,
108130a5e8faSwyllys 				    filename,
108230a5e8faSwyllys 				    NULL, NULL, NULL);
108399ebb4caSwyllys 			else if (oclass == PK_CRL_OBJ)
108499ebb4caSwyllys 				rv = pk_import_file_crl(
108530a5e8faSwyllys 				    kmfhandle, filename,
1086448b8615Swyllys 				    crlfile, okfmt);
108730a5e8faSwyllys 			else if (kfmt == KMF_FORMAT_RAWKEY &&
108830a5e8faSwyllys 			    oclass == PK_SYMKEY_OBJ) {
108930a5e8faSwyllys 				rv = pk_import_rawkey(kmfhandle,
109030a5e8faSwyllys 				    kstype, token_spec, &tokencred,
109130a5e8faSwyllys 				    filename, label,
109230a5e8faSwyllys 				    keyAlg, senstr, extstr);
109330a5e8faSwyllys 			} else if (kfmt == KMF_FORMAT_PEM ||
109430a5e8faSwyllys 			    kfmt == KMF_FORMAT_PEM_KEYPAIR) {
109530a5e8faSwyllys 				rv = pk_import_keys(kmfhandle,
109630a5e8faSwyllys 				    kstype, token_spec, &tokencred,
109730a5e8faSwyllys 				    filename, label, senstr, extstr);
109830a5e8faSwyllys 			} else {
109930a5e8faSwyllys 				rv = PK_ERR_USAGE;
110030a5e8faSwyllys 			}
11017711facfSdinak 			break;
110299ebb4caSwyllys 		case KMF_KEYSTORE_NSS:
110399ebb4caSwyllys 			if (dir == NULL)
110499ebb4caSwyllys 				dir = PK_DEFAULT_DIRECTORY;
110599ebb4caSwyllys 			if (kfmt == KMF_FORMAT_PKCS12)
110699ebb4caSwyllys 				rv = pk_import_pk12_nss(
110730a5e8faSwyllys 				    kmfhandle, &pk12cred,
110830a5e8faSwyllys 				    &tokencred,
110930a5e8faSwyllys 				    token_spec, dir, prefix,
111030a5e8faSwyllys 				    label, trustflags, filename);
111199ebb4caSwyllys 			else if (oclass == PK_CERT_OBJ) {
111299ebb4caSwyllys 				rv = pk_import_cert(
111330a5e8faSwyllys 				    kmfhandle, kstype,
111430a5e8faSwyllys 				    label, token_spec,
111530a5e8faSwyllys 				    filename, dir, prefix, trustflags);
111699ebb4caSwyllys 			} else if (oclass == PK_CRL_OBJ) {
111799ebb4caSwyllys 				rv = pk_import_nss_crl(
111830a5e8faSwyllys 				    kmfhandle, verify_crl_flag,
111930a5e8faSwyllys 				    filename, dir, prefix);
112099ebb4caSwyllys 			}
112199ebb4caSwyllys 			break;
112299ebb4caSwyllys 		case KMF_KEYSTORE_OPENSSL:
112399ebb4caSwyllys 			if (kfmt == KMF_FORMAT_PKCS12)
112499ebb4caSwyllys 				rv = pk_import_pk12_files(
112530a5e8faSwyllys 				    kmfhandle, &pk12cred,
112630a5e8faSwyllys 				    filename, certfile, keyfile,
1127448b8615Swyllys 				    okfmt);
112899ebb4caSwyllys 			else if (oclass == PK_CRL_OBJ) {
112999ebb4caSwyllys 				rv = pk_import_file_crl(
113030a5e8faSwyllys 				    kmfhandle, filename,
1131448b8615Swyllys 				    crlfile, okfmt);
113299ebb4caSwyllys 			} else
113399ebb4caSwyllys 				/*
113499ebb4caSwyllys 				 * It doesn't make sense to import anything
113599ebb4caSwyllys 				 * else for the files plugin.
113699ebb4caSwyllys 				 */
113799ebb4caSwyllys 				return (PK_ERR_USAGE);
113899ebb4caSwyllys 			break;
113999ebb4caSwyllys 		default:
114099ebb4caSwyllys 			rv = PK_ERR_USAGE;
114199ebb4caSwyllys 			break;
114299ebb4caSwyllys 	}
11437711facfSdinak 
114499ebb4caSwyllys end:
114599ebb4caSwyllys 	if (rv != KMF_OK)
114699ebb4caSwyllys 		display_error(kmfhandle, rv,
114730a5e8faSwyllys 		    gettext("Error importing objects"));
11487711facfSdinak 
114999ebb4caSwyllys 	if (tokencred.cred != NULL)
115099ebb4caSwyllys 		free(tokencred.cred);
11517711facfSdinak 
115299ebb4caSwyllys 	if (pk12cred.cred != NULL)
115399ebb4caSwyllys 		free(pk12cred.cred);
11547711facfSdinak 
115530a5e8faSwyllys 	(void) kmf_finalize(kmfhandle);
115699ebb4caSwyllys 
115799ebb4caSwyllys 	if (rv != KMF_OK)
115899ebb4caSwyllys 		return (PK_ERR_USAGE);
11597711facfSdinak 
11607711facfSdinak 	return (0);
11617711facfSdinak }
1162