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 /*
229e765c33SHuie-Ying Lee  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237711facfSdinak  * Use is subject to license terms.
2433f5ff17SMilan Jurik  * Copyright 2012 Milan Jurik. All rights reserved.
257711facfSdinak  */
267711facfSdinak 
277711facfSdinak /*
287711facfSdinak  * This file implements the import operation for this tool.
297711facfSdinak  * The basic flow of the process is to decrypt the PKCS#12
307711facfSdinak  * input file if it has a password, parse the elements in
317711facfSdinak  * the file, find the soft token, log into it, import the
327711facfSdinak  * PKCS#11 objects into the soft token, and log out.
337711facfSdinak  */
347711facfSdinak 
357711facfSdinak #include <stdio.h>
367711facfSdinak #include <stdlib.h>
377711facfSdinak #include <string.h>
3899ebb4caSwyllys #include <ctype.h>
397711facfSdinak #include <errno.h>
407711facfSdinak #include <fcntl.h>
417711facfSdinak #include <sys/types.h>
427711facfSdinak #include <sys/stat.h>
437711facfSdinak #include "common.h"
447711facfSdinak 
4599ebb4caSwyllys #include <kmfapi.h>
4699ebb4caSwyllys 
475b3e1433Swyllys #define	NEW_ATTRLIST(a, n) \
485b3e1433Swyllys { \
495b3e1433Swyllys 	a = (KMF_ATTRIBUTE *)malloc(n * sizeof (KMF_ATTRIBUTE)); \
505b3e1433Swyllys 	if (a == NULL) { \
515b3e1433Swyllys 		rv = KMF_ERR_MEMORY; \
525b3e1433Swyllys 		goto end; \
535b3e1433Swyllys 	} \
545b3e1433Swyllys 	(void) memset(a, 0, n * sizeof (KMF_ATTRIBUTE));  \
555b3e1433Swyllys }
565b3e1433Swyllys 
5799ebb4caSwyllys static KMF_RETURN
pk_import_pk12_files(KMF_HANDLE_T kmfhandle,KMF_CREDENTIAL * cred,char * outfile,char * certfile,char * keyfile,KMF_ENCODE_FORMAT outformat)5899ebb4caSwyllys pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred,
5999ebb4caSwyllys 	char *outfile, char *certfile, char *keyfile,
60448b8615Swyllys 	KMF_ENCODE_FORMAT outformat)
617711facfSdinak {
6299ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
635b3e1433Swyllys 	KMF_X509_DER_CERT *certs = NULL;
6499ebb4caSwyllys 	KMF_RAW_KEY_DATA *keys = NULL;
6599ebb4caSwyllys 	int ncerts = 0;
6699ebb4caSwyllys 	int nkeys = 0;
6799ebb4caSwyllys 	int i;
6830a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
695b3e1433Swyllys 	KMF_ATTRIBUTE *attrlist = NULL;
7030a5e8faSwyllys 	int numattr = 0;
7199ebb4caSwyllys 
7230a5e8faSwyllys 	rv = kmf_import_objects(kmfhandle, outfile, cred,
7330a5e8faSwyllys 	    &certs, &ncerts, &keys, &nkeys);
7499ebb4caSwyllys 
7599ebb4caSwyllys 	if (rv == KMF_OK) {
7699ebb4caSwyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
7730a5e8faSwyllys 		    "key(s) in %s\n"), ncerts, nkeys, outfile);
7899ebb4caSwyllys 	}
7999ebb4caSwyllys 
8099ebb4caSwyllys 	if (rv == KMF_OK && ncerts > 0) {
8199ebb4caSwyllys 		char newcertfile[MAXPATHLEN];
8299ebb4caSwyllys 
835b3e1433Swyllys 		NEW_ATTRLIST(attrlist,  (3 + (3 * ncerts)));
845b3e1433Swyllys 
8530a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
8630a5e8faSwyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
8730a5e8faSwyllys 		numattr++;
8830a5e8faSwyllys 
8930a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
9030a5e8faSwyllys 		    KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat));
9130a5e8faSwyllys 		numattr++;
9299ebb4caSwyllys 
9399ebb4caSwyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
9430a5e8faSwyllys 			int num = numattr;
9530a5e8faSwyllys 
9699ebb4caSwyllys 			/*
9799ebb4caSwyllys 			 * If storing more than 1 cert, gotta change
9899ebb4caSwyllys 			 * the name so we don't overwrite the previous one.
9999ebb4caSwyllys 			 * Just append a _# to the name.
10099ebb4caSwyllys 			 */
10199ebb4caSwyllys 			if (i > 0) {
10299ebb4caSwyllys 				(void) snprintf(newcertfile,
10330a5e8faSwyllys 				    sizeof (newcertfile), "%s_%d", certfile, i);
10430a5e8faSwyllys 
10530a5e8faSwyllys 				kmf_set_attr_at_index(attrlist, num,
10630a5e8faSwyllys 				    KMF_CERT_FILENAME_ATTR, newcertfile,
10730a5e8faSwyllys 				    strlen(newcertfile));
10830a5e8faSwyllys 				num++;
10999ebb4caSwyllys 			} else {
11030a5e8faSwyllys 				kmf_set_attr_at_index(attrlist, num,
11130a5e8faSwyllys 				    KMF_CERT_FILENAME_ATTR, certfile,
11230a5e8faSwyllys 				    strlen(certfile));
11330a5e8faSwyllys 				num++;
11499ebb4caSwyllys 			}
11530a5e8faSwyllys 
1165b3e1433Swyllys 			if (certs[i].kmf_private.label != NULL) {
1175b3e1433Swyllys 				kmf_set_attr_at_index(attrlist, num,
1185b3e1433Swyllys 				    KMF_CERT_LABEL_ATTR,
1195b3e1433Swyllys 				    certs[i].kmf_private.label,
1205b3e1433Swyllys 				    strlen(certs[i].kmf_private.label));
1215b3e1433Swyllys 				num++;
1225b3e1433Swyllys 			}
12330a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, num,
1245b3e1433Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i].certificate,
1255b3e1433Swyllys 			    sizeof (KMF_DATA));
12630a5e8faSwyllys 			num++;
12730a5e8faSwyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
12899ebb4caSwyllys 		}
1295b3e1433Swyllys 		free(attrlist);
1307711facfSdinak 	}
13199ebb4caSwyllys 	if (rv == KMF_OK && nkeys > 0) {
13299ebb4caSwyllys 		char newkeyfile[MAXPATHLEN];
13330a5e8faSwyllys 		numattr = 0;
1345b3e1433Swyllys 		NEW_ATTRLIST(attrlist, (4 + (4 * nkeys)));
13530a5e8faSwyllys 
13630a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
13730a5e8faSwyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
13830a5e8faSwyllys 		    sizeof (kstype));
13930a5e8faSwyllys 		numattr++;
14030a5e8faSwyllys 
14130a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
14230a5e8faSwyllys 		    KMF_ENCODE_FORMAT_ATTR, &outformat,
14330a5e8faSwyllys 		    sizeof (outformat));
14430a5e8faSwyllys 		numattr++;
14530a5e8faSwyllys 
14630a5e8faSwyllys 		if (cred != NULL && cred->credlen > 0) {
14730a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
14830a5e8faSwyllys 			    KMF_CREDENTIAL_ATTR, cred,
14930a5e8faSwyllys 			    sizeof (KMF_CREDENTIAL));
15030a5e8faSwyllys 			numattr++;
15130a5e8faSwyllys 		}
15299ebb4caSwyllys 
15399ebb4caSwyllys 		/* The order of certificates and keys should match */
15499ebb4caSwyllys 		for (i = 0; rv == KMF_OK && i < nkeys; i++) {
15530a5e8faSwyllys 			int num = numattr;
15699ebb4caSwyllys 
15799ebb4caSwyllys 			if (i > 0) {
15899ebb4caSwyllys 				(void) snprintf(newkeyfile,
15930a5e8faSwyllys 				    sizeof (newkeyfile), "%s_%d", keyfile, i);
16030a5e8faSwyllys 
16130a5e8faSwyllys 				kmf_set_attr_at_index(attrlist, num,
16230a5e8faSwyllys 				    KMF_KEY_FILENAME_ATTR, newkeyfile,
16330a5e8faSwyllys 				    strlen(newkeyfile));
16430a5e8faSwyllys 				num++;
16599ebb4caSwyllys 			} else {
16630a5e8faSwyllys 				kmf_set_attr_at_index(attrlist, num,
16730a5e8faSwyllys 				    KMF_KEY_FILENAME_ATTR, keyfile,
16830a5e8faSwyllys 				    strlen(keyfile));
16930a5e8faSwyllys 				num++;
17099ebb4caSwyllys 			}
17199ebb4caSwyllys 
1725b3e1433Swyllys 			if (i < ncerts) {
1735b3e1433Swyllys 				kmf_set_attr_at_index(attrlist, num,
1745b3e1433Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i],
1755b3e1433Swyllys 				    sizeof (KMF_CERT_DATA_ATTR));
1765b3e1433Swyllys 				num++;
1775b3e1433Swyllys 			}
17830a5e8faSwyllys 
17930a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, num,
18030a5e8faSwyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
18130a5e8faSwyllys 			    sizeof (KMF_RAW_KEY_DATA));
18230a5e8faSwyllys 			num++;
18330a5e8faSwyllys 
18430a5e8faSwyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
18599ebb4caSwyllys 		}
1865b3e1433Swyllys 		free(attrlist);
1877711facfSdinak 	}
1885b3e1433Swyllys end:
18999ebb4caSwyllys 	/*
19099ebb4caSwyllys 	 * Cleanup memory.
19199ebb4caSwyllys 	 */
19299ebb4caSwyllys 	if (certs) {
19399ebb4caSwyllys 		for (i = 0; i < ncerts; i++)
1945b3e1433Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
19599ebb4caSwyllys 		free(certs);
19699ebb4caSwyllys 	}
19799ebb4caSwyllys 	if (keys) {
19899ebb4caSwyllys 		for (i = 0; i < nkeys; i++)
19930a5e8faSwyllys 			kmf_free_raw_key(&keys[i]);
20099ebb4caSwyllys 		free(keys);
2017711facfSdinak 	}
2027711facfSdinak 
2037711facfSdinak 
20499ebb4caSwyllys 	return (rv);
2057711facfSdinak }
2067711facfSdinak 
20799ebb4caSwyllys 
20899ebb4caSwyllys 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)20999ebb4caSwyllys pk_import_pk12_nss(
21099ebb4caSwyllys 	KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred,
21199ebb4caSwyllys 	KMF_CREDENTIAL *tokencred,
21299ebb4caSwyllys 	char *token_spec, char *dir, char *prefix,
21399ebb4caSwyllys 	char *nickname, char *trustflags, char *filename)
2147711facfSdinak {
21599ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
2165b3e1433Swyllys 	KMF_X509_DER_CERT *certs = NULL;
21799ebb4caSwyllys 	KMF_RAW_KEY_DATA *keys = NULL;
21899ebb4caSwyllys 	int ncerts = 0;
21999ebb4caSwyllys 	int nkeys = 0;
22099ebb4caSwyllys 	int i;
22130a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
2225b3e1433Swyllys 	KMF_ATTRIBUTE *attrlist = NULL;
22330a5e8faSwyllys 	int numattr = 0;
22499ebb4caSwyllys 
22599ebb4caSwyllys 	rv = configure_nss(kmfhandle, dir, prefix);
22699ebb4caSwyllys 	if (rv != KMF_OK)
22799ebb4caSwyllys 		return (rv);
2287711facfSdinak 
22930a5e8faSwyllys 	rv = kmf_import_objects(kmfhandle, filename, kmfcred,
23030a5e8faSwyllys 	    &certs, &ncerts, &keys, &nkeys);
2317711facfSdinak 
23299ebb4caSwyllys 	if (rv == KMF_OK)
23399ebb4caSwyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
23430a5e8faSwyllys 		    "key(s) in %s\n"), ncerts, nkeys, filename);
2357711facfSdinak 
23699ebb4caSwyllys 	if (rv == KMF_OK) {
23764012b18Swyllys 		numattr = 0;
23864012b18Swyllys 		NEW_ATTRLIST(attrlist, (4 + (2 * nkeys)));
2395b3e1433Swyllys 
24030a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
24164012b18Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
24264012b18Swyllys 		    sizeof (kstype));
24330a5e8faSwyllys 		numattr++;
24430a5e8faSwyllys 
24530a5e8faSwyllys 		if (token_spec != NULL) {
24630a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
24730a5e8faSwyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
24830a5e8faSwyllys 			    strlen(token_spec));
24930a5e8faSwyllys 			numattr++;
25030a5e8faSwyllys 		}
2517711facfSdinak 
25264012b18Swyllys 		if (nickname != NULL) {
25330a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
25464012b18Swyllys 			    KMF_KEYLABEL_ATTR, nickname,
25564012b18Swyllys 			    strlen(nickname));
25630a5e8faSwyllys 			numattr++;
25730a5e8faSwyllys 		}
2587711facfSdinak 
25964012b18Swyllys 		if (tokencred->credlen > 0) {
26064012b18Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
26164012b18Swyllys 			    KMF_CREDENTIAL_ATTR, tokencred,
26264012b18Swyllys 			    sizeof (KMF_CREDENTIAL));
26364012b18Swyllys 			numattr++;
26464012b18Swyllys 		}
26564012b18Swyllys 
26664012b18Swyllys 		/* The order of certificates and keys should match */
26764012b18Swyllys 		for (i = 0; i < nkeys; i++) {
26830a5e8faSwyllys 			int num = numattr;
2697711facfSdinak 
27064012b18Swyllys 			if (i < ncerts) {
27130a5e8faSwyllys 				kmf_set_attr_at_index(attrlist, num,
27264012b18Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i],
27364012b18Swyllys 				    sizeof (KMF_DATA));
27430a5e8faSwyllys 				num++;
27530a5e8faSwyllys 			}
27630a5e8faSwyllys 
27730a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, num,
27864012b18Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
27964012b18Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
28030a5e8faSwyllys 			num++;
28164012b18Swyllys 
28264012b18Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
2837711facfSdinak 		}
2845b3e1433Swyllys 		free(attrlist);
2855b3e1433Swyllys 		attrlist = NULL;
2867711facfSdinak 	}
2877711facfSdinak 
28899ebb4caSwyllys 	if (rv == KMF_OK) {
2899e765c33SHuie-Ying Lee 		numattr = 0;
29064012b18Swyllys 		NEW_ATTRLIST(attrlist, (3 + (2 * ncerts)));
29130a5e8faSwyllys 
29230a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
29364012b18Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
29430a5e8faSwyllys 		numattr++;
29530a5e8faSwyllys 
29630a5e8faSwyllys 		if (token_spec != NULL) {
29730a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
29830a5e8faSwyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
29930a5e8faSwyllys 			    strlen(token_spec));
30030a5e8faSwyllys 			numattr++;
30130a5e8faSwyllys 		}
30230a5e8faSwyllys 
30364012b18Swyllys 		if (trustflags != NULL) {
30430a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
30564012b18Swyllys 			    KMF_TRUSTFLAG_ATTR, trustflags,
30664012b18Swyllys 			    strlen(trustflags));
30730a5e8faSwyllys 			numattr++;
30830a5e8faSwyllys 		}
3097711facfSdinak 
31064012b18Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
31130a5e8faSwyllys 			int num = numattr;
31230a5e8faSwyllys 
31364012b18Swyllys 			if (certs[i].kmf_private.label != NULL) {
3145b3e1433Swyllys 				kmf_set_attr_at_index(attrlist, num,
31564012b18Swyllys 				    KMF_CERT_LABEL_ATTR,
31664012b18Swyllys 				    certs[i].kmf_private.label,
31764012b18Swyllys 				    strlen(certs[i].kmf_private.label));
31864012b18Swyllys 				num++;
31964012b18Swyllys 			} else if (i == 0 && nickname != NULL) {
32064012b18Swyllys 				kmf_set_attr_at_index(attrlist, num,
32164012b18Swyllys 				    KMF_CERT_LABEL_ATTR, nickname,
32264012b18Swyllys 				    strlen(nickname));
3235b3e1433Swyllys 				num++;
3245b3e1433Swyllys 			}
32530a5e8faSwyllys 
32630a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, num,
32764012b18Swyllys 			    KMF_CERT_DATA_ATTR,
32864012b18Swyllys 			    &certs[i].certificate, sizeof (KMF_DATA));
32930a5e8faSwyllys 			num++;
33064012b18Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
33199ebb4caSwyllys 		}
3325b3e1433Swyllys 		free(attrlist);
33364012b18Swyllys 		attrlist = NULL;
33464012b18Swyllys 		if (rv != KMF_OK) {
33564012b18Swyllys 			display_error(kmfhandle, rv,
33664012b18Swyllys 			    gettext("Error storing certificate in NSS token"));
33764012b18Swyllys 		}
3387711facfSdinak 	}
3397711facfSdinak 
3405b3e1433Swyllys end:
34199ebb4caSwyllys 	/*
34299ebb4caSwyllys 	 * Cleanup memory.
34399ebb4caSwyllys 	 */
34499ebb4caSwyllys 	if (certs) {
34599ebb4caSwyllys 		for (i = 0; i < ncerts; i++)
3465b3e1433Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
34799ebb4caSwyllys 		free(certs);
3487711facfSdinak 	}
34999ebb4caSwyllys 	if (keys) {
35099ebb4caSwyllys 		for (i = 0; i < nkeys; i++)
35130a5e8faSwyllys 			kmf_free_raw_key(&keys[i]);
35299ebb4caSwyllys 		free(keys);
3537711facfSdinak 	}
3547711facfSdinak 
35599ebb4caSwyllys 	return (rv);
35699ebb4caSwyllys }
3577711facfSdinak 
35899ebb4caSwyllys 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)35999ebb4caSwyllys pk_import_cert(
36099ebb4caSwyllys 	KMF_HANDLE_T kmfhandle,
36199ebb4caSwyllys 	KMF_KEYSTORE_TYPE kstype,
36299ebb4caSwyllys 	char *label, char *token_spec, char *filename,
36399ebb4caSwyllys 	char *dir, char *prefix, char *trustflags)
36499ebb4caSwyllys {
36599ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
36630a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[32];
367fa60c371Swyllys 	KMF_CREDENTIAL tokencred;
36830a5e8faSwyllys 	int i = 0;
3697711facfSdinak 
37099ebb4caSwyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
37199ebb4caSwyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
37230a5e8faSwyllys 	} else if (kstype == KMF_KEYSTORE_NSS) {
37330a5e8faSwyllys 		rv = configure_nss(kmfhandle, dir, prefix);
3747711facfSdinak 	}
37530a5e8faSwyllys 	if (rv != KMF_OK)
37630a5e8faSwyllys 		return (rv);
3777711facfSdinak 
37830a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, i,
37930a5e8faSwyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE));
38030a5e8faSwyllys 	i++;
3817711facfSdinak 
38230a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR,
38330a5e8faSwyllys 	    filename, strlen(filename));
38430a5e8faSwyllys 	i++;
38530a5e8faSwyllys 
38630a5e8faSwyllys 	if (label != NULL) {
38730a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR,
38830a5e8faSwyllys 		    label, strlen(label));
38930a5e8faSwyllys 		i++;
3907711facfSdinak 	}
3917711facfSdinak 
39230a5e8faSwyllys 	if (kstype == KMF_KEYSTORE_NSS) {
39330a5e8faSwyllys 		if (trustflags != NULL) {
39430a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR,
39530a5e8faSwyllys 			    trustflags, strlen(trustflags));
39630a5e8faSwyllys 			i++;
39730a5e8faSwyllys 		}
3987711facfSdinak 
39930a5e8faSwyllys 		if (token_spec != NULL) {
40030a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, i,
40130a5e8faSwyllys 			    KMF_TOKEN_LABEL_ATTR,
40230a5e8faSwyllys 			    token_spec, strlen(token_spec));
40330a5e8faSwyllys 			i++;
40430a5e8faSwyllys 		}
40530a5e8faSwyllys 	}
40630a5e8faSwyllys 
40730a5e8faSwyllys 	rv = kmf_import_cert(kmfhandle, i, attrlist);
408fa60c371Swyllys 	if (rv == KMF_ERR_AUTH_FAILED) {
409fa60c371Swyllys 		/*
410fa60c371Swyllys 		 * The token requires a credential, prompt and try again.
411fa60c371Swyllys 		 */
412fa60c371Swyllys 		(void) get_token_password(kstype, token_spec, &tokencred);
413fa60c371Swyllys 		kmf_set_attr_at_index(attrlist, i, KMF_CREDENTIAL_ATTR,
414fa60c371Swyllys 		    &tokencred, sizeof (KMF_CREDENTIAL));
415fa60c371Swyllys 		i++;
416fa60c371Swyllys 
417fa60c371Swyllys 		rv = kmf_import_cert(kmfhandle, i, attrlist);
418fa60c371Swyllys 
419fa60c371Swyllys 	}
42099ebb4caSwyllys 	return (rv);
4217711facfSdinak }
4227711facfSdinak 
42399ebb4caSwyllys static KMF_RETURN
pk_import_file_crl(void * kmfhandle,char * infile,char * outfile,KMF_ENCODE_FORMAT outfmt)42499ebb4caSwyllys pk_import_file_crl(void *kmfhandle,
42599ebb4caSwyllys 	char *infile,
42699ebb4caSwyllys 	char *outfile,
42799ebb4caSwyllys 	KMF_ENCODE_FORMAT outfmt)
4287711facfSdinak {
42930a5e8faSwyllys 	int numattr = 0;
43030a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[8];
43130a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
43230a5e8faSwyllys 
43330a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
43430a5e8faSwyllys 	    &kstype, sizeof (kstype));
43530a5e8faSwyllys 	numattr++;
43630a5e8faSwyllys 	if (infile) {
43730a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
43830a5e8faSwyllys 		    KMF_CRL_FILENAME_ATTR, infile, strlen(infile));
43930a5e8faSwyllys 		numattr++;
44030a5e8faSwyllys 	}
44130a5e8faSwyllys 	if (outfile) {
44230a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
44330a5e8faSwyllys 		    KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile));
44430a5e8faSwyllys 		numattr++;
44530a5e8faSwyllys 	}
44630a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
44730a5e8faSwyllys 	    KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt));
44830a5e8faSwyllys 	numattr++;
4497711facfSdinak 
45030a5e8faSwyllys 	return (kmf_import_crl(kmfhandle, numattr, attrlist));
45199ebb4caSwyllys }
4527711facfSdinak 
45399ebb4caSwyllys static KMF_RETURN
pk_import_nss_crl(void * kmfhandle,boolean_t verify_crl_flag,char * infile,char * outdir,char * prefix)45499ebb4caSwyllys pk_import_nss_crl(void *kmfhandle,
45599ebb4caSwyllys 	boolean_t verify_crl_flag,
45699ebb4caSwyllys 	char *infile,
45799ebb4caSwyllys 	char *outdir,
45899ebb4caSwyllys 	char *prefix)
45999ebb4caSwyllys {
46099ebb4caSwyllys 	KMF_RETURN rv;
46130a5e8faSwyllys 	int numattr = 0;
46230a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[4];
46330a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
46499ebb4caSwyllys 
46599ebb4caSwyllys 	rv = configure_nss(kmfhandle, outdir, prefix);
46699ebb4caSwyllys 	if (rv != KMF_OK)
4677711facfSdinak 		return (rv);
4687711facfSdinak 
46930a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
47030a5e8faSwyllys 	    &kstype, sizeof (kstype));
47130a5e8faSwyllys 	numattr++;
47230a5e8faSwyllys 	if (infile) {
47330a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR,
47430a5e8faSwyllys 		    infile, strlen(infile));
47530a5e8faSwyllys 		numattr++;
47630a5e8faSwyllys 	}
47730a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR,
47830a5e8faSwyllys 	    &verify_crl_flag, sizeof (verify_crl_flag));
47930a5e8faSwyllys 	numattr++;
4807711facfSdinak 
48130a5e8faSwyllys 	return (kmf_import_crl(kmfhandle, numattr, attrlist));
4827711facfSdinak 
4837711facfSdinak }
4847711facfSdinak 
48599ebb4caSwyllys static KMF_RETURN
pk_import_pk12_pk11(KMF_HANDLE_T kmfhandle,KMF_CREDENTIAL * p12cred,KMF_CREDENTIAL * tokencred,char * label,char * token_spec,char * filename)48699ebb4caSwyllys pk_import_pk12_pk11(
48799ebb4caSwyllys 	KMF_HANDLE_T kmfhandle,
48899ebb4caSwyllys 	KMF_CREDENTIAL *p12cred,
48999ebb4caSwyllys 	KMF_CREDENTIAL *tokencred,
49099ebb4caSwyllys 	char *label, char *token_spec,
49199ebb4caSwyllys 	char *filename)
4927711facfSdinak {
49399ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
4945b3e1433Swyllys 	KMF_X509_DER_CERT *certs = NULL;
49599ebb4caSwyllys 	KMF_RAW_KEY_DATA *keys = NULL;
49699ebb4caSwyllys 	int ncerts = 0;
49799ebb4caSwyllys 	int nkeys = 0;
49899ebb4caSwyllys 	int i;
49930a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
5005b3e1433Swyllys 	KMF_ATTRIBUTE *attrlist = NULL;
50130a5e8faSwyllys 	int numattr = 0;
5027711facfSdinak 
50399ebb4caSwyllys 	rv = select_token(kmfhandle, token_spec, FALSE);
5047711facfSdinak 
50599ebb4caSwyllys 	if (rv != KMF_OK) {
50699ebb4caSwyllys 		return (rv);
5077711facfSdinak 	}
5087711facfSdinak 
50930a5e8faSwyllys 	rv = kmf_import_objects(kmfhandle, filename, p12cred,
51030a5e8faSwyllys 	    &certs, &ncerts, &keys, &nkeys);
5117711facfSdinak 
51299ebb4caSwyllys 	if (rv == KMF_OK) {
5135b3e1433Swyllys 		NEW_ATTRLIST(attrlist, (3 + (2 * nkeys)));
51430a5e8faSwyllys 
51530a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
51630a5e8faSwyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
51730a5e8faSwyllys 		    sizeof (kstype));
51830a5e8faSwyllys 		numattr++;
51930a5e8faSwyllys 
52030a5e8faSwyllys 		if (label != NULL) {
52130a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
52230a5e8faSwyllys 			    KMF_KEYLABEL_ATTR, label,
52330a5e8faSwyllys 			    strlen(label));
52430a5e8faSwyllys 			numattr++;
52530a5e8faSwyllys 		}
52630a5e8faSwyllys 
52730a5e8faSwyllys 		if (tokencred != NULL && tokencred->credlen > 0) {
52830a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
52930a5e8faSwyllys 			    KMF_CREDENTIAL_ATTR, tokencred,
53030a5e8faSwyllys 			    sizeof (KMF_CREDENTIAL));
53130a5e8faSwyllys 			numattr++;
53230a5e8faSwyllys 		}
5337711facfSdinak 
53499ebb4caSwyllys 		/* The order of certificates and keys should match */
53599ebb4caSwyllys 		for (i = 0; i < nkeys; i++) {
53630a5e8faSwyllys 			int num = numattr;
53730a5e8faSwyllys 
5385b3e1433Swyllys 			if (i < ncerts) {
5395b3e1433Swyllys 				kmf_set_attr_at_index(attrlist, num,
5405b3e1433Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i].certificate,
5415b3e1433Swyllys 				    sizeof (KMF_DATA));
5425b3e1433Swyllys 				num++;
5435b3e1433Swyllys 			}
54430a5e8faSwyllys 
54530a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, num,
54630a5e8faSwyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
54730a5e8faSwyllys 			    sizeof (KMF_RAW_KEY_DATA));
54830a5e8faSwyllys 			num++;
54930a5e8faSwyllys 
55030a5e8faSwyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
5517711facfSdinak 
55299ebb4caSwyllys 		}
5535b3e1433Swyllys 		free(attrlist);
5547711facfSdinak 	}
5557711facfSdinak 
55699ebb4caSwyllys 	if (rv == KMF_OK) {
5575b3e1433Swyllys 		numattr = 0;
5585b3e1433Swyllys 		NEW_ATTRLIST(attrlist, (1 + (2 * ncerts)));
5597711facfSdinak 
56099ebb4caSwyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
56130a5e8faSwyllys 		    "key(s) in %s\n"), ncerts, nkeys, filename);
5625b3e1433Swyllys 
56330a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
56430a5e8faSwyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
56530a5e8faSwyllys 		numattr++;
5667711facfSdinak 
56799ebb4caSwyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
56830a5e8faSwyllys 			int num = numattr;
5695b3e1433Swyllys 			if (certs[i].kmf_private.label != NULL) {
5705b3e1433Swyllys 				kmf_set_attr_at_index(attrlist, num,
5715b3e1433Swyllys 				    KMF_CERT_LABEL_ATTR,
5725b3e1433Swyllys 				    certs[i].kmf_private.label,
5735b3e1433Swyllys 				    strlen(certs[i].kmf_private.label));
5745b3e1433Swyllys 				num++;
5755b3e1433Swyllys 			} else if (i == 0 && label != NULL) {
57630a5e8faSwyllys 				kmf_set_attr_at_index(attrlist, num,
57730a5e8faSwyllys 				    KMF_CERT_LABEL_ATTR, label, strlen(label));
57830a5e8faSwyllys 				num++;
57930a5e8faSwyllys 			}
5807711facfSdinak 
58130a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, num,
5825b3e1433Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i].certificate,
5835b3e1433Swyllys 			    sizeof (KMF_DATA));
58430a5e8faSwyllys 			num++;
58530a5e8faSwyllys 
58630a5e8faSwyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
58799ebb4caSwyllys 		}
5885b3e1433Swyllys 		free(attrlist);
5897711facfSdinak 	}
5907711facfSdinak 
5915b3e1433Swyllys end:
59299ebb4caSwyllys 	/*
59399ebb4caSwyllys 	 * Cleanup memory.
59499ebb4caSwyllys 	 */
59599ebb4caSwyllys 	if (certs) {
59699ebb4caSwyllys 		for (i = 0; i < ncerts; i++)
5975b3e1433Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
59899ebb4caSwyllys 		free(certs);
59999ebb4caSwyllys 	}
60099ebb4caSwyllys 	if (keys) {
60199ebb4caSwyllys 		for (i = 0; i < nkeys; i++)
60230a5e8faSwyllys 			kmf_free_raw_key(&keys[i]);
60399ebb4caSwyllys 		free(keys);
6047711facfSdinak 	}
6057711facfSdinak 
60699ebb4caSwyllys 	return (rv);
6077711facfSdinak }
6087711facfSdinak 
60946d33f7eSwyllys /*ARGSUSED*/
61030a5e8faSwyllys 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)61130a5e8faSwyllys pk_import_keys(KMF_HANDLE_T kmfhandle,
61230a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype, char *token_spec,
61330a5e8faSwyllys 	KMF_CREDENTIAL *cred, char *filename,
61430a5e8faSwyllys 	char *label, char *senstr, char *extstr)
61530a5e8faSwyllys {
61630a5e8faSwyllys 	KMF_RETURN rv = KMF_OK;
61730a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[16];
61830a5e8faSwyllys 	KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL;
61930a5e8faSwyllys 	int numattr = 0;
62030a5e8faSwyllys 	KMF_KEY_HANDLE key;
62130a5e8faSwyllys 	KMF_RAW_KEY_DATA rawkey;
62230a5e8faSwyllys 	KMF_KEY_CLASS class = KMF_ASYM_PRI;
62330a5e8faSwyllys 	int numkeys = 1;
62430a5e8faSwyllys 
62530a5e8faSwyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
62630a5e8faSwyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
62730a5e8faSwyllys 	}
62830a5e8faSwyllys 	if (rv != KMF_OK)
62930a5e8faSwyllys 		return (rv);
63030a5e8faSwyllys 	/*
63130a5e8fa