xref: /onnv-gate/usr/src/cmd/cmd-crypto/pktool/export.c (revision 5069:a114332ed71c)
117Sdinak /*
217Sdinak  * CDDL HEADER START
317Sdinak  *
417Sdinak  * The contents of this file are subject to the terms of the
51837Sdinak  * Common Development and Distribution License (the "License").
61837Sdinak  * You may not use this file except in compliance with the License.
717Sdinak  *
817Sdinak  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
917Sdinak  * or http://www.opensolaris.org/os/licensing.
1017Sdinak  * See the License for the specific language governing permissions
1117Sdinak  * and limitations under the License.
1217Sdinak  *
1317Sdinak  * When distributing Covered Code, include this CDDL HEADER in each
1417Sdinak  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1517Sdinak  * If applicable, add the following below this CDDL HEADER, with the
1617Sdinak  * fields enclosed by brackets "[]" replaced with your own identifying
1717Sdinak  * information: Portions Copyright [yyyy] [name of copyright owner]
1817Sdinak  *
1917Sdinak  * CDDL HEADER END
203089Swyllys  *
213089Swyllys  *
225051Swyllys  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2317Sdinak  * Use is subject to license terms.
2417Sdinak  */
2517Sdinak 
2617Sdinak #pragma ident	"%Z%%M%	%I%	%E% SMI"
2717Sdinak 
2817Sdinak /*
2917Sdinak  * This file implements the export operation for this tool.
3017Sdinak  * The basic flow of the process is to find the soft token,
3117Sdinak  * log into it, find the PKCS#11 objects in the soft token
3217Sdinak  * to be exported matching keys with their certificates, export
3317Sdinak  * them to the PKCS#12 file encrypting them with a file password
3417Sdinak  * if desired, and log out.
3517Sdinak  */
3617Sdinak 
3717Sdinak #include <stdio.h>
3817Sdinak #include <stdlib.h>
3917Sdinak #include <string.h>
4017Sdinak #include <errno.h>
413089Swyllys #include <fcntl.h>
4217Sdinak #include "common.h"
433089Swyllys 
443089Swyllys #include <kmfapi.h>
4517Sdinak 
463089Swyllys static KMF_RETURN
475051Swyllys pk_find_export_cert(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attrlist,
485051Swyllys 	int numattr, KMF_X509_DER_CERT *cert)
4917Sdinak {
503089Swyllys 	KMF_RETURN rv = KMF_OK;
513089Swyllys 	uint32_t numcerts = 0;
5217Sdinak 
533089Swyllys 	numcerts = 0;
543089Swyllys 	(void) memset(cert, 0, sizeof (KMF_X509_DER_CERT));
555051Swyllys 
565051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
575051Swyllys 	    &numcerts, sizeof (uint32_t));
585051Swyllys 	numattr++;
595051Swyllys 
605051Swyllys 	rv = kmf_find_cert(kmfhandle, numattr, attrlist);
613089Swyllys 	if (rv != KMF_OK) {
623089Swyllys 		return (rv);
6317Sdinak 	}
643089Swyllys 	if (numcerts == 0) {
653089Swyllys 		cryptoerror(LOG_STDERR,
665051Swyllys 		    gettext("No matching certificates found."));
673089Swyllys 		return (KMF_ERR_CERT_NOT_FOUND);
6817Sdinak 
693089Swyllys 	} else if (numcerts == 1) {
705051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
715051Swyllys 		    KMF_X509_DER_CERT_ATTR, cert,
725051Swyllys 		    sizeof (KMF_X509_DER_CERT));
735051Swyllys 		numattr++;
745051Swyllys 		rv = kmf_find_cert(kmfhandle, numattr, attrlist);
7517Sdinak 
763089Swyllys 	} else if (numcerts > 1) {
773089Swyllys 		cryptoerror(LOG_STDERR,
785051Swyllys 		    gettext("%d certificates found, refine the "
795051Swyllys 		    "search parameters to eliminate ambiguity\n"),
805051Swyllys 		    numcerts);
813089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
823089Swyllys 	}
833089Swyllys 	return (rv);
843089Swyllys }
8517Sdinak 
863089Swyllys static KMF_RETURN
873089Swyllys pk_export_file_objects(KMF_HANDLE_T kmfhandle, int oclass,
883089Swyllys 	char *issuer, char *subject, KMF_BIGINT *serial,
893089Swyllys 	char *dir, char *infile, char *filename)
903089Swyllys {
913089Swyllys 	KMF_RETURN rv = KMF_OK;
923089Swyllys 	KMF_X509_DER_CERT kmfcert;
935051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
945051Swyllys 	int numattr = 0;
955051Swyllys 	KMF_ATTRIBUTE attrlist[16];
9617Sdinak 
973089Swyllys 	/* If searching for public objects or certificates, find certs now */
983089Swyllys 	if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
995051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
1005051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
1015051Swyllys 		    sizeof (kstype));
1025051Swyllys 		numattr++;
1035051Swyllys 
1045051Swyllys 		if (issuer != NULL) {
1055051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1065051Swyllys 			    KMF_ISSUER_NAME_ATTR, issuer,
1075051Swyllys 			    strlen(issuer));
1085051Swyllys 			numattr++;
1095051Swyllys 		}
1105051Swyllys 
1115051Swyllys 		if (subject != NULL) {
1125051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1135051Swyllys 			    KMF_SUBJECT_NAME_ATTR, subject,
1145051Swyllys 			    strlen(subject));
1155051Swyllys 			numattr++;
1165051Swyllys 		}
1175051Swyllys 
1185051Swyllys 		if (serial != NULL) {
1195051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1205051Swyllys 			    KMF_BIGINT_ATTR, serial,
1215051Swyllys 			    sizeof (KMF_BIGINT));
1225051Swyllys 			numattr++;
1235051Swyllys 		}
12417Sdinak 
1255051Swyllys 		if (dir != NULL) {
1265051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1275051Swyllys 			    KMF_DIRPATH_ATTR, dir,
1285051Swyllys 			    strlen(dir));
1295051Swyllys 			numattr++;
1305051Swyllys 		}
1315051Swyllys 
1325051Swyllys 		if (infile != NULL) {
1335051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1345051Swyllys 			    KMF_CERT_FILENAME_ATTR, infile,
1355051Swyllys 			    strlen(infile));
1365051Swyllys 			numattr++;
1375051Swyllys 		}
13817Sdinak 
1395051Swyllys 		rv = pk_find_export_cert(kmfhandle, attrlist, numattr,
1405051Swyllys 		    &kmfcert);
1413089Swyllys 		if (rv == KMF_OK) {
1425051Swyllys 			kstype = KMF_KEYSTORE_OPENSSL;
1435051Swyllys 			numattr = 0;
1445051Swyllys 
1455051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1465051Swyllys 			    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
1475051Swyllys 			numattr++;
14817Sdinak 
1495051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1505051Swyllys 			    KMF_CERT_DATA_ATTR, &kmfcert.certificate,
1515051Swyllys 			    sizeof (KMF_DATA));
1525051Swyllys 			numattr++;
1535051Swyllys 
1545051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1555051Swyllys 			    KMF_CERT_FILENAME_ATTR, filename,
1565051Swyllys 			    strlen(filename));
1575051Swyllys 			numattr++;
1585051Swyllys 
1595051Swyllys 			rv = kmf_store_cert(kmfhandle, numattr,
1605051Swyllys 			    attrlist);
1615051Swyllys 
1625051Swyllys 			kmf_free_kmf_cert(kmfhandle, &kmfcert);
16317Sdinak 		}
16417Sdinak 	}
1653089Swyllys 	return (rv);
1663089Swyllys }
16717Sdinak 
1683089Swyllys static KMF_RETURN
1693089Swyllys pk_export_pk12_nss(KMF_HANDLE_T kmfhandle,
1703089Swyllys 	char *token_spec, char *dir, char *prefix,
1713089Swyllys 	char *certlabel, char *issuer, char *subject,
1723089Swyllys 	KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred,
1733089Swyllys 	char *filename)
1743089Swyllys {
1753089Swyllys 	KMF_RETURN rv = KMF_OK;
1765051Swyllys 	KMF_KEYSTORE_TYPE kstype;
1775051Swyllys 	KMF_CREDENTIAL p12cred = { NULL, 0};
1785051Swyllys 	KMF_ATTRIBUTE attrlist[16];
1795051Swyllys 	int numattr = 0;
18017Sdinak 
1813089Swyllys 	rv = configure_nss(kmfhandle, dir, prefix);
1823089Swyllys 	if (rv != KMF_OK)
1833089Swyllys 		return (rv);
18417Sdinak 
1853089Swyllys 	if (token_spec == NULL)
1863089Swyllys 		token_spec = DEFAULT_NSS_TOKEN;
18717Sdinak 
1885051Swyllys 	kstype = KMF_KEYSTORE_NSS;
1895051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
1905051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
1915051Swyllys 	numattr++;
1925051Swyllys 
1935051Swyllys 	if (certlabel != NULL) {
1945051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
1955051Swyllys 		    KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
1965051Swyllys 		numattr++;
1975051Swyllys 	}
1985051Swyllys 
1995051Swyllys 	if (issuer != NULL) {
2005051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2015051Swyllys 		    KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
2025051Swyllys 		numattr++;
2035051Swyllys 	}
2045051Swyllys 
2055051Swyllys 	if (subject != NULL) {
2065051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2075051Swyllys 		    KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
2085051Swyllys 		numattr++;
2095051Swyllys 	}
21017Sdinak 
2115051Swyllys 	if (serial != NULL) {
2125051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2135051Swyllys 		    KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
2145051Swyllys 		numattr++;
2155051Swyllys 	}
2165051Swyllys 
2175051Swyllys 	if (tokencred != NULL) {
2185051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2195051Swyllys 		    KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL));
2205051Swyllys 		numattr++;
2215051Swyllys 	}
22217Sdinak 
2235051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
2245051Swyllys 	    token_spec, strlen(token_spec));
2255051Swyllys 	numattr++;
2265051Swyllys 
2275051Swyllys 	(void) get_pk12_password(&p12cred);
2285051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
2295051Swyllys 	    KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
2305051Swyllys 	numattr++;
2315051Swyllys 
2325051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
2335051Swyllys 	    KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename));
2345051Swyllys 	numattr++;
2355051Swyllys 
2365051Swyllys 	rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
2375051Swyllys 
2385051Swyllys 	if (p12cred.cred)
2395051Swyllys 		free(p12cred.cred);
24017Sdinak 
2413089Swyllys 	return (rv);
24217Sdinak }
24317Sdinak 
2443089Swyllys static KMF_RETURN
2453089Swyllys pk_export_pk12_files(KMF_HANDLE_T kmfhandle,
2463089Swyllys 	char *certfile, char *keyfile, char *dir,
2473089Swyllys 	char *outfile)
24817Sdinak {
2493089Swyllys 	KMF_RETURN rv;
2505051Swyllys 	KMF_KEYSTORE_TYPE kstype;
2515051Swyllys 	KMF_CREDENTIAL p12cred = { NULL, 0};
2525051Swyllys 	KMF_ATTRIBUTE attrlist[16];
2535051Swyllys 	int numattr = 0;
25417Sdinak 
2555051Swyllys 	kstype = KMF_KEYSTORE_OPENSSL;
2565051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
2575051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2585051Swyllys 	numattr++;
2595051Swyllys 
2605051Swyllys 	if (dir != NULL) {
2615051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2625051Swyllys 		    KMF_DIRPATH_ATTR, dir, strlen(dir));
2635051Swyllys 		numattr++;
2645051Swyllys 	}
26517Sdinak 
2665051Swyllys 	if (certfile != NULL) {
2675051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2685051Swyllys 		    KMF_CERT_FILENAME_ATTR, certfile, strlen(certfile));
2695051Swyllys 		numattr++;
2705051Swyllys 	}
2715051Swyllys 
2725051Swyllys 	if (keyfile != NULL) {
2735051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2745051Swyllys 		    KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
2755051Swyllys 		numattr++;
2765051Swyllys 	}
27717Sdinak 
2785051Swyllys 	(void) get_pk12_password(&p12cred);
2795051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
2805051Swyllys 	    KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
2815051Swyllys 	numattr++;
28217Sdinak 
2835051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
2845051Swyllys 	    KMF_OUTPUT_FILENAME_ATTR, outfile, strlen(outfile));
2855051Swyllys 	numattr++;
28617Sdinak 
2875051Swyllys 	rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
2885051Swyllys 
2895051Swyllys 	if (p12cred.cred)
2905051Swyllys 		free(p12cred.cred);
29117Sdinak 
2923089Swyllys 	return (rv);
29317Sdinak }
29417Sdinak 
2953089Swyllys static KMF_RETURN
2963089Swyllys pk_export_nss_objects(KMF_HANDLE_T kmfhandle, char *token_spec,
2973089Swyllys 	int oclass, char *certlabel, char *issuer, char *subject,
2983089Swyllys 	KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, char *dir,
2993089Swyllys 	char *prefix, char *filename)
30017Sdinak {
3013089Swyllys 	KMF_RETURN rv = KMF_OK;
3023089Swyllys 	KMF_X509_DER_CERT kmfcert;
3035051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
3045051Swyllys 	KMF_ATTRIBUTE attrlist[16];
3055051Swyllys 	int numattr = 0;
3063089Swyllys 
3073089Swyllys 	rv = configure_nss(kmfhandle, dir, prefix);
3083089Swyllys 	if (rv != KMF_OK)
3093089Swyllys 		return (rv);
3103089Swyllys 
3113089Swyllys 	/* If searching for public objects or certificates, find certs now */
3123089Swyllys 	if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
3135051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
3145051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
3155051Swyllys 		    sizeof (kstype));
3165051Swyllys 		numattr++;
3175051Swyllys 
3185051Swyllys 		if (certlabel != NULL) {
3195051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3205051Swyllys 			    KMF_CERT_LABEL_ATTR, certlabel,
3215051Swyllys 			    strlen(certlabel));
3225051Swyllys 			numattr++;
3235051Swyllys 		}
32417Sdinak 
3255051Swyllys 		if (issuer != NULL) {
3265051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3275051Swyllys 			    KMF_ISSUER_NAME_ATTR, issuer,
3285051Swyllys 			    strlen(issuer));
3295051Swyllys 			numattr++;
3305051Swyllys 		}
3315051Swyllys 
3325051Swyllys 		if (subject != NULL) {
3335051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3345051Swyllys 			    KMF_SUBJECT_NAME_ATTR, subject,
3355051Swyllys 			    strlen(subject));
3365051Swyllys 			numattr++;
3375051Swyllys 		}
3385051Swyllys 
3395051Swyllys 		if (serial != NULL) {
3405051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3415051Swyllys 			    KMF_BIGINT_ATTR, serial,
3425051Swyllys 			    sizeof (KMF_BIGINT));
3435051Swyllys 			numattr++;
3445051Swyllys 		}
34517Sdinak 
3465051Swyllys 		if (token_spec != NULL) {
3475051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3485051Swyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
3495051Swyllys 			    strlen(token_spec));
3505051Swyllys 			numattr++;
3515051Swyllys 		}
3525051Swyllys 
3535051Swyllys 		rv = pk_find_export_cert(kmfhandle, attrlist, numattr,
3545051Swyllys 		    &kmfcert);
3553089Swyllys 		if (rv == KMF_OK) {
3565051Swyllys 			kstype = KMF_KEYSTORE_OPENSSL;
3575051Swyllys 			numattr = 0;
3585051Swyllys 
3595051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3605051Swyllys 			    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
3615051Swyllys 			numattr++;
3625051Swyllys 
3635051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3645051Swyllys 			    KMF_CERT_DATA_ATTR, &kmfcert.certificate,
3655051Swyllys 			    sizeof (KMF_DATA));
3665051Swyllys 			numattr++;
36717Sdinak 
3685051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3695051Swyllys 			    KMF_CERT_FILENAME_ATTR, filename,
3705051Swyllys 			    strlen(filename));
3715051Swyllys 			numattr++;
3723089Swyllys 
3735051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3745051Swyllys 			    KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt));
3755051Swyllys 			numattr++;
3765051Swyllys 
3775051Swyllys 			rv = kmf_store_cert(kmfhandle, numattr, attrlist);
3785051Swyllys 
3795051Swyllys 			kmf_free_kmf_cert(kmfhandle, &kmfcert);
3803089Swyllys 		}
3813089Swyllys 	}
3823089Swyllys 	return (rv);
38317Sdinak }
38417Sdinak 
3853089Swyllys static KMF_RETURN
3863089Swyllys pk_export_pk12_pk11(KMF_HANDLE_T kmfhandle, char *token_spec,
3873089Swyllys 	char *certlabel, char *issuer, char *subject,
3883089Swyllys 	KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, char *filename)
38917Sdinak {
3903089Swyllys 	KMF_RETURN rv = KMF_OK;
3915051Swyllys 	KMF_KEYSTORE_TYPE kstype;
3925051Swyllys 	KMF_CREDENTIAL p12cred = { NULL, 0};
3935051Swyllys 	KMF_ATTRIBUTE attrlist[16];
3945051Swyllys 	int numattr = 0;
39517Sdinak 
3963089Swyllys 	rv = select_token(kmfhandle, token_spec, TRUE);
3973089Swyllys 	if (rv != KMF_OK) {
39817Sdinak 		return (rv);
39917Sdinak 	}
40017Sdinak 
4015051Swyllys 	kstype = KMF_KEYSTORE_PK11TOKEN;
4025051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
4035051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
4045051Swyllys 	numattr++;
4055051Swyllys 
4065051Swyllys 	if (certlabel != NULL) {
4075051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4085051Swyllys 		    KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
4095051Swyllys 		numattr++;
4105051Swyllys 	}
4115051Swyllys 
4125051Swyllys 	if (issuer != NULL) {
4135051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4145051Swyllys 		    KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
4155051Swyllys 		numattr++;
4165051Swyllys 	}
4175051Swyllys 
4185051Swyllys 	if (subject != NULL) {
4195051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4205051Swyllys 		    KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
4215051Swyllys 		numattr++;
4225051Swyllys 	}
4235051Swyllys 
4245051Swyllys 	if (serial != NULL) {
4255051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4265051Swyllys 		    KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
4275051Swyllys 		numattr++;
4285051Swyllys 	}
4295051Swyllys 
4305051Swyllys 	if (tokencred != NULL) {
4315051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4325051Swyllys 		    KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL));
4335051Swyllys 		numattr++;
4345051Swyllys 	}
4355051Swyllys 
4365051Swyllys 	(void) get_pk12_password(&p12cred);
4375051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
4385051Swyllys 	    KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
4395051Swyllys 	numattr++;
4405051Swyllys 
4415051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
4425051Swyllys 	    KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename));
4435051Swyllys 	numattr++;
4445051Swyllys 
4455051Swyllys 	rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
4465051Swyllys 
4475051Swyllys 	if (p12cred.cred)
4485051Swyllys 		free(p12cred.cred);
4495051Swyllys 
4505051Swyllys 	return (rv);
4515051Swyllys }
4525051Swyllys 
4535051Swyllys static KMF_RETURN
4545051Swyllys pk_export_pk11_keys(KMF_HANDLE_T kmfhandle, char *token,
4555051Swyllys 	KMF_CREDENTIAL *cred, KMF_ENCODE_FORMAT format,
4565051Swyllys 	char *label, char *filename)
4575051Swyllys {
4585051Swyllys 	KMF_RETURN rv = KMF_OK;
4595051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
4605051Swyllys 	int numattr = 0;
4615051Swyllys 	uint32_t numkeys = 1;
4625051Swyllys 	KMF_ATTRIBUTE attrlist[16];
4635051Swyllys 	KMF_KEY_HANDLE key;
4645051Swyllys 	boolean_t is_token = B_TRUE;
4655051Swyllys 
4665051Swyllys 	if (EMPTYSTRING(label)) {
4675051Swyllys 		cryptoerror(LOG_STDERR, gettext("A label "
4685051Swyllys 		    "must be specified to export a key."));
4695051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
4705051Swyllys 	}
4715051Swyllys 
4725051Swyllys 	rv = select_token(kmfhandle, token, TRUE);
4735051Swyllys 	if (rv != KMF_OK) {
4745051Swyllys 		return (rv);
4755051Swyllys 	}
4765051Swyllys 
4775051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
4785051Swyllys 	    &kstype, sizeof (kstype));
4795051Swyllys 	numattr++;
48017Sdinak 
4815051Swyllys 	if (cred != NULL) {
4825051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
4835051Swyllys 		    cred, sizeof (KMF_CREDENTIAL));
4845051Swyllys 		numattr++;
4855051Swyllys 	}
4865051Swyllys 
4875051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
4885051Swyllys 	    label, strlen(label));
4895051Swyllys 	numattr++;
4905051Swyllys 
4915051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
4925051Swyllys 	    &numkeys, sizeof (numkeys));
4935051Swyllys 	numattr++;
4945051Swyllys 
4955051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
4965051Swyllys 	    &key, sizeof (key));
4975051Swyllys 	numattr++;
4985051Swyllys 
4995051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR,
5005051Swyllys 	    &is_token, sizeof (is_token));
5015051Swyllys 	numattr++;
5025051Swyllys 
5035051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
5045051Swyllys 	    &format, sizeof (format));
5055051Swyllys 	numattr++;
5065051Swyllys 
5075051Swyllys 	rv = kmf_find_key(kmfhandle, numattr, attrlist);
5085051Swyllys 	if (rv == KMF_OK && key.keyclass == KMF_SYMMETRIC) {
5095051Swyllys 		KMF_RAW_SYM_KEY rkey;
5105051Swyllys 
5115051Swyllys 		(void) memset(&rkey, 0, sizeof (KMF_RAW_SYM_KEY));
5125051Swyllys 		rv = kmf_get_sym_key_value(kmfhandle, &key, &rkey);
5135051Swyllys 		if (rv == KMF_OK) {
5145051Swyllys 			int fd, n, total = 0;
51517Sdinak 
5165051Swyllys 			fd = open(filename, O_CREAT | O_RDWR |O_TRUNC, 0600);
5175051Swyllys 			if (fd == -1) {
5185051Swyllys 				rv = KMF_ERR_OPEN_FILE;
5195051Swyllys 				goto done;
5205051Swyllys 			}
5215051Swyllys 			do {
5225051Swyllys 				n = write(fd, rkey.keydata.val + total,
5235051Swyllys 				    rkey.keydata.len - total);
5245051Swyllys 				if (n < 0) {
5255051Swyllys 					if (errno == EINTR)
5265051Swyllys 						continue;
527*5069Swyllys 					(void) close(fd);
5285051Swyllys 					rv = KMF_ERR_WRITE_FILE;
5295051Swyllys 					goto done;
5305051Swyllys 				}
5315051Swyllys 				total += n;
53217Sdinak 
5335051Swyllys 			} while (total < rkey.keydata.len);
534*5069Swyllys 			(void) close(fd);
5355051Swyllys 		}
5365051Swyllys done:
5375051Swyllys 		kmf_free_bigint(&rkey.keydata);
5385051Swyllys 		kmf_free_kmf_key(kmfhandle, &key);
5395051Swyllys 	} else if (rv == KMF_OK) {
5405051Swyllys 		KMF_KEYSTORE_TYPE sslks = KMF_KEYSTORE_OPENSSL;
541*5069Swyllys 		(void) printf(gettext("Found %d asymmetric keys\n"), numkeys);
5425051Swyllys 
5435051Swyllys 		numattr = 0;
5445051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
5455051Swyllys 		    &sslks, sizeof (sslks));
5465051Swyllys 		numattr++;
5475051Swyllys 
5485051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
5495051Swyllys 		    key.keyp, sizeof (KMF_RAW_KEY_DATA));
5505051Swyllys 		numattr++;
5515051Swyllys 
5525051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
5535051Swyllys 		    &format, sizeof (format));
5545051Swyllys 		numattr++;
5555051Swyllys 
5565051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
5575051Swyllys 		    filename, strlen(filename));
5585051Swyllys 		numattr++;
5595051Swyllys 
5605051Swyllys 		rv = kmf_store_key(kmfhandle, numattr, attrlist);
5615051Swyllys 		kmf_free_kmf_key(kmfhandle, &key);
5625051Swyllys 	}
56317Sdinak 
5643089Swyllys 	return (rv);
56517Sdinak }
56617Sdinak 
5673089Swyllys static KMF_RETURN
5683089Swyllys pk_export_pk11_objects(KMF_HANDLE_T kmfhandle, char *token_spec,
5693089Swyllys 	char *certlabel, char *issuer, char *subject,
5703089Swyllys 	KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt,
5713089Swyllys 	char *filename)
57217Sdinak {
5733089Swyllys 	KMF_RETURN rv = KMF_OK;
5743089Swyllys 	KMF_X509_DER_CERT kmfcert;
5755051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
5765051Swyllys 	int numattr = 0;
5775051Swyllys 	KMF_ATTRIBUTE attrlist[16];
57817Sdinak 
5793089Swyllys 	rv = select_token(kmfhandle, token_spec, TRUE);
58017Sdinak 
5813089Swyllys 	if (rv != KMF_OK) {
58217Sdinak 		return (rv);
58317Sdinak 	}
58417Sdinak 
5855051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
5865051Swyllys 	    &kstype, sizeof (kstype));
5875051Swyllys 	numattr++;
5885051Swyllys 
5895051Swyllys 	if (certlabel != NULL) {
5905051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
5915051Swyllys 		    KMF_CERT_LABEL_ATTR, certlabel,
5925051Swyllys 		    strlen(certlabel));
5935051Swyllys 		numattr++;
5945051Swyllys 	}
59517Sdinak 
5965051Swyllys 	if (issuer != NULL) {
5975051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
5985051Swyllys 		    KMF_ISSUER_NAME_ATTR, issuer,
5995051Swyllys 		    strlen(issuer));
6005051Swyllys 		numattr++;
6015051Swyllys 	}
6025051Swyllys 
6035051Swyllys 	if (subject != NULL) {
6045051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6055051Swyllys 		    KMF_SUBJECT_NAME_ATTR, subject,
6065051Swyllys 		    strlen(subject));
6075051Swyllys 		numattr++;
6085051Swyllys 	}
6095051Swyllys 
6105051Swyllys 	if (serial != NULL) {
6115051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6125051Swyllys 		    KMF_BIGINT_ATTR, serial,
6135051Swyllys 		    sizeof (KMF_BIGINT));
6145051Swyllys 		numattr++;
6155051Swyllys 	}
6165051Swyllys 
6175051Swyllys 	rv = pk_find_export_cert(kmfhandle, attrlist, numattr, &kmfcert);
61817Sdinak 
6193089Swyllys 	if (rv == KMF_OK) {
6205051Swyllys 		kstype = KMF_KEYSTORE_OPENSSL;
6215051Swyllys 		numattr = 0;
6225051Swyllys 
6235051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6245051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
6255051Swyllys 		numattr++;
6265051Swyllys 
6275051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6285051Swyllys 		    KMF_CERT_DATA_ATTR, &kmfcert.certificate,
6295051Swyllys 		    sizeof (KMF_DATA));
6305051Swyllys 		numattr++;
63117Sdinak 
6325051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6335051Swyllys 		    KMF_CERT_FILENAME_ATTR, filename, strlen(filename));
6345051Swyllys 		numattr++;
63517Sdinak 
6365051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6375051Swyllys 		    KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt));
6385051Swyllys 		numattr++;
6395051Swyllys 
6405051Swyllys 		rv = kmf_store_cert(kmfhandle, numattr, attrlist);
6415051Swyllys 
6425051Swyllys 		kmf_free_kmf_cert(kmfhandle, &kmfcert);
64317Sdinak 	}
6443089Swyllys 	return (rv);
64517Sdinak }
64617Sdinak 
64717Sdinak /*
6483089Swyllys  * Export objects from one keystore to a file.
64917Sdinak  */
65017Sdinak int
65117Sdinak pk_export(int argc, char *argv[])
65217Sdinak {
653864Sdinak 	int		opt;
654864Sdinak 	extern int	optind_av;
655864Sdinak 	extern char	*optarg_av;
656864Sdinak 	char		*token_spec = NULL;
65717Sdinak 	char		*filename = NULL;
6583089Swyllys 	char		*dir = NULL;
6593089Swyllys 	char		*prefix = NULL;
6603089Swyllys 	char		*certlabel = NULL;
6613089Swyllys 	char		*subject = NULL;
6623089Swyllys 	char		*issuer = NULL;
6633089Swyllys 	char		*infile = NULL;
6643089Swyllys 	char		*keyfile = NULL;
6653089Swyllys 	char		*certfile = NULL;
6663089Swyllys 	char		*serstr = NULL;
6673089Swyllys 	KMF_KEYSTORE_TYPE	kstype = 0;
6683089Swyllys 	KMF_ENCODE_FORMAT	kfmt = KMF_FORMAT_PKCS12;
6693089Swyllys 	KMF_RETURN		rv = KMF_OK;
6703089Swyllys 	int		oclass = PK_CERT_OBJ;
6713089Swyllys 	KMF_BIGINT	serial = { NULL, 0 };
6723089Swyllys 	KMF_HANDLE_T	kmfhandle = NULL;
6733089Swyllys 	KMF_CREDENTIAL	tokencred = {NULL, 0};
67417Sdinak 
675864Sdinak 	/* Parse command line options.  Do NOT i18n/l10n. */
6763089Swyllys 	while ((opt = getopt_av(argc, argv,
6775051Swyllys 	    "k:(keystore)y:(objtype)T:(token)"
6785051Swyllys 	    "d:(dir)p:(prefix)"
6795051Swyllys 	    "l:(label)n:(nickname)s:(subject)"
6805051Swyllys 	    "i:(issuer)S:(serial)"
6815051Swyllys 	    "K:(keyfile)c:(certfile)"
6825051Swyllys 	    "F:(outformat)"
6835051Swyllys 	    "I:(infile)o:(outfile)")) != EOF) {
6843089Swyllys 		if (EMPTYSTRING(optarg_av))
6853089Swyllys 			return (PK_ERR_USAGE);
686864Sdinak 		switch (opt) {
6873089Swyllys 		case 'k':
6883089Swyllys 			kstype = KS2Int(optarg_av);
6893089Swyllys 			if (kstype == 0)
6903089Swyllys 				return (PK_ERR_USAGE);
6913089Swyllys 			break;
6923089Swyllys 		case 'y':
6933089Swyllys 			oclass = OT2Int(optarg_av);
6943089Swyllys 			if (oclass == -1)
6953089Swyllys 				return (PK_ERR_USAGE);
6963089Swyllys 			break;
697864Sdinak 		case 'T':	/* token specifier */
698864Sdinak 			if (token_spec)
699864Sdinak 				return (PK_ERR_USAGE);
700864Sdinak 			token_spec = optarg_av;
701864Sdinak 			break;
7023089Swyllys 		case 'd':
7033089Swyllys 			if (dir)
7043089Swyllys 				return (PK_ERR_USAGE);
7053089Swyllys 			dir = optarg_av;
7063089Swyllys 			break;
7073089Swyllys 		case 'p':
7083089Swyllys 			if (prefix)
7093089Swyllys 				return (PK_ERR_USAGE);
7103089Swyllys 			prefix = optarg_av;
7113089Swyllys 			break;
7123089Swyllys 		case 'n':
7133089Swyllys 		case 'l':
7143089Swyllys 			if (certlabel)
7153089Swyllys 				return (PK_ERR_USAGE);
7163089Swyllys 			certlabel = optarg_av;
7173089Swyllys 			break;
7183089Swyllys 		case 's':
7193089Swyllys 			if (subject)
7203089Swyllys 				return (PK_ERR_USAGE);
7213089Swyllys 			subject = optarg_av;
7223089Swyllys 			break;
7233089Swyllys 		case 'i':
7243089Swyllys 			if (issuer)
7253089Swyllys 				return (PK_ERR_USAGE);
7263089Swyllys 			issuer = optarg_av;
7273089Swyllys 			break;
7283089Swyllys 		case 'S':
7293089Swyllys 			serstr = optarg_av;
7303089Swyllys 			break;
7313089Swyllys 		case 'F':
7323089Swyllys 			kfmt = Str2Format(optarg_av);
7333089Swyllys 			if (kfmt == KMF_FORMAT_UNDEF)
7343089Swyllys 				return (PK_ERR_USAGE);
7353089Swyllys 			break;
7363089Swyllys 		case 'I':	/* output file name */
7373089Swyllys 			if (infile)
7383089Swyllys 				return (PK_ERR_USAGE);
7393089Swyllys 			infile = optarg_av;
7403089Swyllys 			break;
741864Sdinak 		case 'o':	/* output file name */
742864Sdinak 			if (filename)
743864Sdinak 				return (PK_ERR_USAGE);
744864Sdinak 			filename = optarg_av;
745864Sdinak 			break;
7463089Swyllys 		case 'c':	/* input cert file name */
7473089Swyllys 			if (certfile)
7483089Swyllys 				return (PK_ERR_USAGE);
7493089Swyllys 			certfile = optarg_av;
7503089Swyllys 			break;
7513089Swyllys 		case 'K':	/* input key file name */
7523089Swyllys 			if (keyfile)
7533089Swyllys 				return (PK_ERR_USAGE);
7543089Swyllys 			keyfile = optarg_av;
7553089Swyllys 			break;
756864Sdinak 		default:
757864Sdinak 			return (PK_ERR_USAGE);
758864Sdinak 			break;
759864Sdinak 		}
760864Sdinak 	}
76117Sdinak 
7623089Swyllys 	/* Assume keystore = PKCS#11 if not specified */
7633089Swyllys 	if (kstype == 0)
7643089Swyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
765864Sdinak 
766864Sdinak 	/* Filename arg is required. */
7673089Swyllys 	if (EMPTYSTRING(filename)) {
7683089Swyllys 		cryptoerror(LOG_STDERR, gettext("You must specify "
7695051Swyllys 		    "an 'outfile' parameter when exporting.\n"));
77017Sdinak 		return (PK_ERR_USAGE);
7713089Swyllys 	}
77217Sdinak 
773864Sdinak 	/* No additional args allowed. */
774864Sdinak 	argc -= optind_av;
775864Sdinak 	argv += optind_av;
776864Sdinak 	if (argc)
777864Sdinak 		return (PK_ERR_USAGE);
7783089Swyllys 
7793089Swyllys 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
7803089Swyllys 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
7815051Swyllys 	    kstype != KMF_KEYSTORE_PK11TOKEN) {
7823089Swyllys 
7833089Swyllys 		(void) fprintf(stderr, gettext("The objtype parameter "
7845051Swyllys 		    "is only relevant if keystore=pkcs11\n"));
7853089Swyllys 		return (PK_ERR_USAGE);
7863089Swyllys 	}
7873089Swyllys 
7883089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
7893089Swyllys 		token_spec = PK_DEFAULT_PK11TOKEN;
7903089Swyllys 	else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
7913089Swyllys 		token_spec = DEFAULT_NSS_TOKEN;
7923089Swyllys 
7933089Swyllys 	if (kstype == KMF_KEYSTORE_OPENSSL) {
7943089Swyllys 		if (kfmt != KMF_FORMAT_PKCS12) {
7953089Swyllys 			cryptoerror(LOG_STDERR, gettext("PKCS12 "
7965051Swyllys 			    "is the only export format "
7975051Swyllys 			    "supported for the 'file' "
7985051Swyllys 			    "keystore.\n"));
7993089Swyllys 			return (PK_ERR_USAGE);
8003089Swyllys 		}
8013089Swyllys 		if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
8023089Swyllys 			cryptoerror(LOG_STDERR, gettext("A cert file"
8035051Swyllys 			    "and a key file must be specified "
8045051Swyllys 			    "when exporting to PKCS12 from the "
8055051Swyllys 			    "'file' keystore.\n"));
8063089Swyllys 			return (PK_ERR_USAGE);
8073089Swyllys 		}
8083089Swyllys 	}
80917Sdinak 
81017Sdinak 	/* Check if the file exists and might be overwritten. */
81117Sdinak 	if (access(filename, F_OK) == 0) {
8123089Swyllys 		cryptoerror(LOG_STDERR,
8135051Swyllys 		    gettext("Warning: file \"%s\" exists, "
8145051Swyllys 		    "will be overwritten."), filename);
81517Sdinak 		if (yesno(gettext("Continue with export? "),
81617Sdinak 		    gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) {
81717Sdinak 			return (0);
81817Sdinak 		}
8193089Swyllys 	} else {
8203089Swyllys 		rv = verify_file(filename);
8213089Swyllys 		if (rv != KMF_OK) {
8223089Swyllys 			cryptoerror(LOG_STDERR, gettext("The file (%s) "
8235051Swyllys 			    "cannot be created.\n"), filename);
8243089Swyllys 			return (PK_ERR_USAGE);
8253089Swyllys 		}
82617Sdinak 	}
82717Sdinak 
8283089Swyllys 	if (serstr != NULL) {
8293089Swyllys 		uchar_t *bytes = NULL;
8303089Swyllys 		size_t bytelen;
83117Sdinak 
8325051Swyllys 		rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
8333089Swyllys 		if (rv != KMF_OK || bytes == NULL) {
8343089Swyllys 			(void) fprintf(stderr, gettext("serial number "
8355051Swyllys 			    "must be specified as a hex number "
8365051Swyllys 			    "(ex: 0x0102030405ffeeddee)\n"));
8373089Swyllys 			return (PK_ERR_USAGE);
8383089Swyllys 		}
8393089Swyllys 		serial.val = bytes;
8403089Swyllys 		serial.len = bytelen;
84117Sdinak 	}
84217Sdinak 
8433089Swyllys 	if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
8445051Swyllys 	    kstype == KMF_KEYSTORE_NSS) &&
8455051Swyllys 	    (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ) ||
8465051Swyllys 	    kfmt == KMF_FORMAT_PKCS12)) {
8473089Swyllys 			(void) get_token_password(kstype, token_spec,
8485051Swyllys 			    &tokencred);
84917Sdinak 	}
85017Sdinak 
8515051Swyllys 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
8523089Swyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing "
8535051Swyllys 		    "KMF: 0x%02x\n"), rv);
8543089Swyllys 		return (rv);
85517Sdinak 	}
85617Sdinak 
8573089Swyllys 	switch (kstype) {
8583089Swyllys 		case KMF_KEYSTORE_PK11TOKEN:
8593089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
8605051Swyllys 				rv = pk_export_pk12_pk11(kmfhandle,
8615051Swyllys 				    token_spec, certlabel,
8625051Swyllys 				    issuer, subject,
8635051Swyllys 				    &serial, &tokencred,
8645051Swyllys 				    filename);
8655051Swyllys 			else if ((oclass & PK_KEY_OBJ) ||
8665051Swyllys 			    kfmt == KMF_FORMAT_RAWKEY)
8675051Swyllys 				rv = pk_export_pk11_keys(kmfhandle,
8685051Swyllys 				    token_spec, &tokencred, kfmt,
8695051Swyllys 				    certlabel, filename);
8703089Swyllys 			else
8713089Swyllys 				rv = pk_export_pk11_objects(kmfhandle,
8725051Swyllys 				    token_spec, certlabel,
8735051Swyllys 				    issuer, subject, &serial, kfmt,
8745051Swyllys 				    filename);
8753089Swyllys 			break;
8763089Swyllys 		case KMF_KEYSTORE_NSS:
8773089Swyllys 			if (dir == NULL)
8783089Swyllys 				dir = PK_DEFAULT_DIRECTORY;
8793089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
8803089Swyllys 				rv = pk_export_pk12_nss(kmfhandle,
8815051Swyllys 				    token_spec, dir, prefix,
8825051Swyllys 				    certlabel, issuer,
8835051Swyllys 				    subject, &serial,
8845051Swyllys 				    &tokencred, filename);
8853089Swyllys 			else
8863089Swyllys 				rv = pk_export_nss_objects(kmfhandle,
8875051Swyllys 				    token_spec,
8885051Swyllys 				    oclass, certlabel, issuer, subject,
8895051Swyllys 				    &serial, kfmt, dir, prefix, filename);
8903089Swyllys 			break;
8913089Swyllys 		case KMF_KEYSTORE_OPENSSL:
8923089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
8933089Swyllys 				rv = pk_export_pk12_files(kmfhandle,
8945051Swyllys 				    certfile, keyfile, dir,
8955051Swyllys 				    filename);
8963089Swyllys 			else
8973089Swyllys 				rv = pk_export_file_objects(kmfhandle, oclass,
8985051Swyllys 				    issuer, subject, &serial,
8995051Swyllys 				    dir, infile, filename);
9003089Swyllys 			break;
9013089Swyllys 		default:
9023089Swyllys 			rv = PK_ERR_USAGE;
9033089Swyllys 			break;
90417Sdinak 	}
90517Sdinak 
9063089Swyllys 	if (rv != KMF_OK) {
9073089Swyllys 		display_error(kmfhandle, rv,
9085051Swyllys 		    gettext("Error exporting objects"));
9093089Swyllys 	}
91017Sdinak 
9113089Swyllys 	if (serial.val != NULL)
9123089Swyllys 		free(serial.val);
91317Sdinak 
9145051Swyllys 	(void) kmf_finalize(kmfhandle);
9153089Swyllys 
9163089Swyllys 	return (rv);
91717Sdinak }
918