xref: /onnv-gate/usr/src/cmd/cmd-crypto/pktool/export.c (revision 12234:cd6642d6b7dd)
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  *
21*12234Swyllys.ingersoll@sun.com  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2217Sdinak  */
2317Sdinak 
2417Sdinak /*
2517Sdinak  * This file implements the export operation for this tool.
2617Sdinak  * The basic flow of the process is to find the soft token,
2717Sdinak  * log into it, find the PKCS#11 objects in the soft token
2817Sdinak  * to be exported matching keys with their certificates, export
2917Sdinak  * them to the PKCS#12 file encrypting them with a file password
3017Sdinak  * if desired, and log out.
3117Sdinak  */
3217Sdinak 
3317Sdinak #include <stdio.h>
3417Sdinak #include <stdlib.h>
3517Sdinak #include <string.h>
3617Sdinak #include <errno.h>
373089Swyllys #include <fcntl.h>
3817Sdinak #include "common.h"
393089Swyllys 
403089Swyllys #include <kmfapi.h>
4117Sdinak 
423089Swyllys static KMF_RETURN
pk_find_export_cert(KMF_HANDLE_T kmfhandle,KMF_ATTRIBUTE * attrlist,int numattr,KMF_X509_DER_CERT * cert)435051Swyllys pk_find_export_cert(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attrlist,
445051Swyllys 	int numattr, KMF_X509_DER_CERT *cert)
4517Sdinak {
463089Swyllys 	KMF_RETURN rv = KMF_OK;
473089Swyllys 	uint32_t numcerts = 0;
4817Sdinak 
493089Swyllys 	numcerts = 0;
503089Swyllys 	(void) memset(cert, 0, sizeof (KMF_X509_DER_CERT));
515051Swyllys 
525051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
535051Swyllys 	    &numcerts, sizeof (uint32_t));
545051Swyllys 	numattr++;
555051Swyllys 
565051Swyllys 	rv = kmf_find_cert(kmfhandle, numattr, attrlist);
573089Swyllys 	if (rv != KMF_OK) {
583089Swyllys 		return (rv);
5917Sdinak 	}
603089Swyllys 	if (numcerts == 0) {
613089Swyllys 		cryptoerror(LOG_STDERR,
625051Swyllys 		    gettext("No matching certificates found."));
633089Swyllys 		return (KMF_ERR_CERT_NOT_FOUND);
6417Sdinak 
653089Swyllys 	} else if (numcerts == 1) {
665051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
675051Swyllys 		    KMF_X509_DER_CERT_ATTR, cert,
685051Swyllys 		    sizeof (KMF_X509_DER_CERT));
695051Swyllys 		numattr++;
705051Swyllys 		rv = kmf_find_cert(kmfhandle, numattr, attrlist);
7117Sdinak 
723089Swyllys 	} else if (numcerts > 1) {
733089Swyllys 		cryptoerror(LOG_STDERR,
745051Swyllys 		    gettext("%d certificates found, refine the "
755051Swyllys 		    "search parameters to eliminate ambiguity\n"),
765051Swyllys 		    numcerts);
773089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
783089Swyllys 	}
793089Swyllys 	return (rv);
803089Swyllys }
8117Sdinak 
823089Swyllys static KMF_RETURN
pk_export_file_objects(KMF_HANDLE_T kmfhandle,int oclass,char * issuer,char * subject,KMF_BIGINT * serial,char * infile,char * filename)833089Swyllys pk_export_file_objects(KMF_HANDLE_T kmfhandle, int oclass,
843089Swyllys 	char *issuer, char *subject, KMF_BIGINT *serial,
856669Swyllys 	char *infile, char *filename)
863089Swyllys {
873089Swyllys 	KMF_RETURN rv = KMF_OK;
883089Swyllys 	KMF_X509_DER_CERT kmfcert;
895051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
905051Swyllys 	int numattr = 0;
915051Swyllys 	KMF_ATTRIBUTE attrlist[16];
9217Sdinak 
933089Swyllys 	/* If searching for public objects or certificates, find certs now */
943089Swyllys 	if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
955051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
965051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
975051Swyllys 		    sizeof (kstype));
985051Swyllys 		numattr++;
995051Swyllys 
1005051Swyllys 		if (issuer != NULL) {
1015051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1025051Swyllys 			    KMF_ISSUER_NAME_ATTR, issuer,
1035051Swyllys 			    strlen(issuer));
1045051Swyllys 			numattr++;
1055051Swyllys 		}
1065051Swyllys 
1075051Swyllys 		if (subject != NULL) {
1085051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1095051Swyllys 			    KMF_SUBJECT_NAME_ATTR, subject,
1105051Swyllys 			    strlen(subject));
1115051Swyllys 			numattr++;
1125051Swyllys 		}
1135051Swyllys 
1145051Swyllys 		if (serial != NULL) {
1155051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1165051Swyllys 			    KMF_BIGINT_ATTR, serial,
1175051Swyllys 			    sizeof (KMF_BIGINT));
1185051Swyllys 			numattr++;
1195051Swyllys 		}
12017Sdinak 
1215051Swyllys 		if (infile != NULL) {
1225051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1235051Swyllys 			    KMF_CERT_FILENAME_ATTR, infile,
1245051Swyllys 			    strlen(infile));
1255051Swyllys 			numattr++;
1265051Swyllys 		}
12717Sdinak 
1285051Swyllys 		rv = pk_find_export_cert(kmfhandle, attrlist, numattr,
1295051Swyllys 		    &kmfcert);
1303089Swyllys 		if (rv == KMF_OK) {
1315051Swyllys 			kstype = KMF_KEYSTORE_OPENSSL;
1325051Swyllys 			numattr = 0;
1335051Swyllys 
1345051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1355051Swyllys 			    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
1365051Swyllys 			numattr++;
13717Sdinak 
1385051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1395051Swyllys 			    KMF_CERT_DATA_ATTR, &kmfcert.certificate,
1405051Swyllys 			    sizeof (KMF_DATA));
1415051Swyllys 			numattr++;
1425051Swyllys 
1435051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1445051Swyllys 			    KMF_CERT_FILENAME_ATTR, filename,
1455051Swyllys 			    strlen(filename));
1465051Swyllys 			numattr++;
1475051Swyllys 
1485051Swyllys 			rv = kmf_store_cert(kmfhandle, numattr,
1495051Swyllys 			    attrlist);
1505051Swyllys 
1515051Swyllys 			kmf_free_kmf_cert(kmfhandle, &kmfcert);
15217Sdinak 		}
15317Sdinak 	}
1543089Swyllys 	return (rv);
1553089Swyllys }
15617Sdinak 
1573089Swyllys static KMF_RETURN
pk_export_pk12_nss(KMF_HANDLE_T kmfhandle,char * token_spec,char * dir,char * prefix,char * certlabel,char * issuer,char * subject,KMF_BIGINT * serial,KMF_CREDENTIAL * tokencred,char * filename)1583089Swyllys pk_export_pk12_nss(KMF_HANDLE_T kmfhandle,
1593089Swyllys 	char *token_spec, char *dir, char *prefix,
1603089Swyllys 	char *certlabel, char *issuer, char *subject,
1613089Swyllys 	KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred,
1623089Swyllys 	char *filename)
1633089Swyllys {
1643089Swyllys 	KMF_RETURN rv = KMF_OK;
1655051Swyllys 	KMF_KEYSTORE_TYPE kstype;
1665051Swyllys 	KMF_CREDENTIAL p12cred = { NULL, 0};
1675051Swyllys 	KMF_ATTRIBUTE attrlist[16];
1685051Swyllys 	int numattr = 0;
16917Sdinak 
1703089Swyllys 	rv = configure_nss(kmfhandle, dir, prefix);
1713089Swyllys 	if (rv != KMF_OK)
1723089Swyllys 		return (rv);
17317Sdinak 
1743089Swyllys 	if (token_spec == NULL)
1753089Swyllys 		token_spec = DEFAULT_NSS_TOKEN;
17617Sdinak 
1775051Swyllys 	kstype = KMF_KEYSTORE_NSS;
1785051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
1795051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
1805051Swyllys 	numattr++;
1815051Swyllys 
1825051Swyllys 	if (certlabel != NULL) {
1835051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
1845051Swyllys 		    KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
1855051Swyllys 		numattr++;
1865051Swyllys 	}
1875051Swyllys 
1885051Swyllys 	if (issuer != NULL) {
1895051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
1905051Swyllys 		    KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
1915051Swyllys 		numattr++;
1925051Swyllys 	}
1935051Swyllys 
1945051Swyllys 	if (subject != NULL) {
1955051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
1965051Swyllys 		    KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
1975051Swyllys 		numattr++;
1985051Swyllys 	}
19917Sdinak 
2005051Swyllys 	if (serial != NULL) {
2015051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2025051Swyllys 		    KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
2035051Swyllys 		numattr++;
2045051Swyllys 	}
2055051Swyllys 
2065051Swyllys 	if (tokencred != NULL) {
2075051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2085051Swyllys 		    KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL));
2095051Swyllys 		numattr++;
2105051Swyllys 	}
21117Sdinak 
2125051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
2135051Swyllys 	    token_spec, strlen(token_spec));
2145051Swyllys 	numattr++;
2155051Swyllys 
2165051Swyllys 	(void) get_pk12_password(&p12cred);
2175051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
2185051Swyllys 	    KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
2195051Swyllys 	numattr++;
2205051Swyllys 
2215051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
2225051Swyllys 	    KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename));
2235051Swyllys 	numattr++;
2245051Swyllys 
2255051Swyllys 	rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
2265051Swyllys 
2275051Swyllys 	if (p12cred.cred)
2285051Swyllys 		free(p12cred.cred);
22917Sdinak 
2303089Swyllys 	return (rv);
23117Sdinak }
23217Sdinak 
2333089Swyllys static KMF_RETURN
pk_export_pk12_files(KMF_HANDLE_T kmfhandle,char * certfile,char * keyfile,char * outfile)2343089Swyllys pk_export_pk12_files(KMF_HANDLE_T kmfhandle,
2356669Swyllys 	char *certfile, char *keyfile,
2363089Swyllys 	char *outfile)
23717Sdinak {
2383089Swyllys 	KMF_RETURN rv;
2395051Swyllys 	KMF_KEYSTORE_TYPE kstype;
2405051Swyllys 	KMF_CREDENTIAL p12cred = { NULL, 0};
2415051Swyllys 	KMF_ATTRIBUTE attrlist[16];
2425051Swyllys 	int numattr = 0;
24317Sdinak 
2445051Swyllys 	kstype = KMF_KEYSTORE_OPENSSL;
2455051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
2465051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2475051Swyllys 	numattr++;
2485051Swyllys 
2495051Swyllys 	if (certfile != NULL) {
2505051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2515051Swyllys 		    KMF_CERT_FILENAME_ATTR, certfile, strlen(certfile));
2525051Swyllys 		numattr++;
2535051Swyllys 	}
2545051Swyllys 
2555051Swyllys 	if (keyfile != NULL) {
2565051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2575051Swyllys 		    KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
2585051Swyllys 		numattr++;
2595051Swyllys 	}
26017Sdinak 
2615051Swyllys 	(void) get_pk12_password(&p12cred);
2625051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
2635051Swyllys 	    KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
2645051Swyllys 	numattr++;
26517Sdinak 
2665051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
2675051Swyllys 	    KMF_OUTPUT_FILENAME_ATTR, outfile, strlen(outfile));
2685051Swyllys 	numattr++;
26917Sdinak 
2705051Swyllys 	rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
2715051Swyllys 
2725051Swyllys 	if (p12cred.cred)
2735051Swyllys 		free(p12cred.cred);
27417Sdinak 
2753089Swyllys 	return (rv);
27617Sdinak }
27717Sdinak 
2783089Swyllys static KMF_RETURN
pk_export_nss_objects(KMF_HANDLE_T kmfhandle,char * token_spec,int oclass,char * certlabel,char * issuer,char * subject,KMF_BIGINT * serial,KMF_ENCODE_FORMAT kfmt,char * dir,char * prefix,char * filename)2793089Swyllys pk_export_nss_objects(KMF_HANDLE_T kmfhandle, char *token_spec,
2803089Swyllys 	int oclass, char *certlabel, char *issuer, char *subject,
2813089Swyllys 	KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, char *dir,
2823089Swyllys 	char *prefix, char *filename)
28317Sdinak {
2843089Swyllys 	KMF_RETURN rv = KMF_OK;
2853089Swyllys 	KMF_X509_DER_CERT kmfcert;
2865051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
2875051Swyllys 	KMF_ATTRIBUTE attrlist[16];
2885051Swyllys 	int numattr = 0;
2893089Swyllys 
2903089Swyllys 	rv = configure_nss(kmfhandle, dir, prefix);
2913089Swyllys 	if (rv != KMF_OK)
2923089Swyllys 		return (rv);
2933089Swyllys 
2943089Swyllys 	/* If searching for public objects or certificates, find certs now */
2953089Swyllys 	if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
2965051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2975051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
2985051Swyllys 		    sizeof (kstype));
2995051Swyllys 		numattr++;
3005051Swyllys 
3015051Swyllys 		if (certlabel != NULL) {
3025051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3035051Swyllys 			    KMF_CERT_LABEL_ATTR, certlabel,
3045051Swyllys 			    strlen(certlabel));
3055051Swyllys 			numattr++;
3065051Swyllys 		}
30717Sdinak 
3085051Swyllys 		if (issuer != NULL) {
3095051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3105051Swyllys 			    KMF_ISSUER_NAME_ATTR, issuer,
3115051Swyllys 			    strlen(issuer));
3125051Swyllys 			numattr++;
3135051Swyllys 		}
3145051Swyllys 
3155051Swyllys 		if (subject != NULL) {
3165051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3175051Swyllys 			    KMF_SUBJECT_NAME_ATTR, subject,
3185051Swyllys 			    strlen(subject));
3195051Swyllys 			numattr++;
3205051Swyllys 		}
3215051Swyllys 
3225051Swyllys 		if (serial != NULL) {
3235051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3245051Swyllys 			    KMF_BIGINT_ATTR, serial,
3255051Swyllys 			    sizeof (KMF_BIGINT));
3265051Swyllys 			numattr++;
3275051Swyllys 		}
32817Sdinak 
3295051Swyllys 		if (token_spec != NULL) {
3305051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3315051Swyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
3325051Swyllys 			    strlen(token_spec));
3335051Swyllys 			numattr++;
3345051Swyllys 		}
3355051Swyllys 
3365051Swyllys 		rv = pk_find_export_cert(kmfhandle, attrlist, numattr,
3375051Swyllys 		    &kmfcert);
3383089Swyllys 		if (rv == KMF_OK) {
3395051Swyllys 			kstype = KMF_KEYSTORE_OPENSSL;
3405051Swyllys 			numattr = 0;
3415051Swyllys 
3425051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3435051Swyllys 			    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
3445051Swyllys 			numattr++;
3455051Swyllys 
3465051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3475051Swyllys 			    KMF_CERT_DATA_ATTR, &kmfcert.certificate,
3485051Swyllys 			    sizeof (KMF_DATA));
3495051Swyllys 			numattr++;
35017Sdinak 
3515051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3525051Swyllys 			    KMF_CERT_FILENAME_ATTR, filename,
3535051Swyllys 			    strlen(filename));
3545051Swyllys 			numattr++;
3553089Swyllys 
3565051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3575051Swyllys 			    KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt));
3585051Swyllys 			numattr++;
3595051Swyllys 
3605051Swyllys 			rv = kmf_store_cert(kmfhandle, numattr, attrlist);
3615051Swyllys 
3625051Swyllys 			kmf_free_kmf_cert(kmfhandle, &kmfcert);
3633089Swyllys 		}
3643089Swyllys 	}
3653089Swyllys 	return (rv);
36617Sdinak }
36717Sdinak 
3683089Swyllys static KMF_RETURN
pk_export_pk12_pk11(KMF_HANDLE_T kmfhandle,char * token_spec,char * certlabel,char * issuer,char * subject,KMF_BIGINT * serial,KMF_CREDENTIAL * tokencred,char * filename)3693089Swyllys pk_export_pk12_pk11(KMF_HANDLE_T kmfhandle, char *token_spec,
3703089Swyllys 	char *certlabel, char *issuer, char *subject,
3713089Swyllys 	KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, char *filename)
37217Sdinak {
3733089Swyllys 	KMF_RETURN rv = KMF_OK;
3745051Swyllys 	KMF_KEYSTORE_TYPE kstype;
3755051Swyllys 	KMF_CREDENTIAL p12cred = { NULL, 0};
3765051Swyllys 	KMF_ATTRIBUTE attrlist[16];
3775051Swyllys 	int numattr = 0;
37817Sdinak 
3793089Swyllys 	rv = select_token(kmfhandle, token_spec, TRUE);
3803089Swyllys 	if (rv != KMF_OK) {
38117Sdinak 		return (rv);
38217Sdinak 	}
38317Sdinak 
3845051Swyllys 	kstype = KMF_KEYSTORE_PK11TOKEN;
3855051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
3865051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
3875051Swyllys 	numattr++;
3885051Swyllys 
3895051Swyllys 	if (certlabel != NULL) {
3905051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
3915051Swyllys 		    KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
3925051Swyllys 		numattr++;
3935051Swyllys 	}
3945051Swyllys 
3955051Swyllys 	if (issuer != NULL) {
3965051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
3975051Swyllys 		    KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
3985051Swyllys 		numattr++;
3995051Swyllys 	}
4005051Swyllys 
4015051Swyllys 	if (subject != NULL) {
4025051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4035051Swyllys 		    KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
4045051Swyllys 		numattr++;
4055051Swyllys 	}
4065051Swyllys 
4075051Swyllys 	if (serial != NULL) {
4085051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4095051Swyllys 		    KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
4105051Swyllys 		numattr++;
4115051Swyllys 	}
4125051Swyllys 
4135051Swyllys 	if (tokencred != NULL) {
4145051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4155051Swyllys 		    KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL));
4165051Swyllys 		numattr++;
4175051Swyllys 	}
4185051Swyllys 
4195051Swyllys 	(void) get_pk12_password(&p12cred);
4205051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
4215051Swyllys 	    KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
4225051Swyllys 	numattr++;
4235051Swyllys 
4245051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
4255051Swyllys 	    KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename));
4265051Swyllys 	numattr++;
4275051Swyllys 
4285051Swyllys 	rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
4295051Swyllys 
4305051Swyllys 	if (p12cred.cred)
4315051Swyllys 		free(p12cred.cred);
4325051Swyllys 
4335051Swyllys 	return (rv);
4345051Swyllys }
4355051Swyllys 
4365051Swyllys static KMF_RETURN
pk_export_pk11_keys(KMF_HANDLE_T kmfhandle,char * token,KMF_CREDENTIAL * cred,KMF_ENCODE_FORMAT format,char * label,char * filename,int oclass)4375051Swyllys pk_export_pk11_keys(KMF_HANDLE_T kmfhandle, char *token,
4385051Swyllys 	KMF_CREDENTIAL *cred, KMF_ENCODE_FORMAT format,
4395637Swyllys 	char *label, char *filename, int oclass)
4405051Swyllys {
4415051Swyllys 	KMF_RETURN rv = KMF_OK;
4425051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
4435637Swyllys 	KMF_KEY_CLASS kclass = KMF_KEYCLASS_NONE;
4445051Swyllys 	int numattr = 0;
4455051Swyllys 	uint32_t numkeys = 1;
4465051Swyllys 	KMF_ATTRIBUTE attrlist[16];
4475051Swyllys 	KMF_KEY_HANDLE key;
4485051Swyllys 	boolean_t is_token = B_TRUE;
4495051Swyllys 
4505051Swyllys 	if (EMPTYSTRING(label)) {
4515051Swyllys 		cryptoerror(LOG_STDERR, gettext("A label "
4525051Swyllys 		    "must be specified to export a key."));
4535051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
4545051Swyllys 	}
4555051Swyllys 
4565051Swyllys 	rv = select_token(kmfhandle, token, TRUE);
4575051Swyllys 	if (rv != KMF_OK) {
4585051Swyllys 		return (rv);
4595051Swyllys 	}
4605051Swyllys 
4615051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
4625051Swyllys 	    &kstype, sizeof (kstype));
4635051Swyllys 	numattr++;
46417Sdinak 
4655051Swyllys 	if (cred != NULL) {
4665051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
4675051Swyllys 		    cred, sizeof (KMF_CREDENTIAL));
4685051Swyllys 		numattr++;
4695051Swyllys 	}
4705051Swyllys 
4715051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
4725051Swyllys 	    label, strlen(label));
4735051Swyllys 	numattr++;
4745051Swyllys 
4755051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
4765051Swyllys 	    &numkeys, sizeof (numkeys));
4775051Swyllys 	numattr++;
4785051Swyllys 
4795051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
4805051Swyllys 	    &key, sizeof (key));
4815051Swyllys 	numattr++;
4825051Swyllys 
4835051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR,
4845051Swyllys 	    &is_token, sizeof (is_token));
4855051Swyllys 	numattr++;
4865051Swyllys 
4875051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
4885051Swyllys 	    &format, sizeof (format));
4895051Swyllys 	numattr++;
4905051Swyllys 
4915637Swyllys 	/* Check to see if we are exporting private or public only */
4925637Swyllys 	if ((oclass & PK_KEY_OBJ) == PK_PRIKEY_OBJ)
4935637Swyllys 		kclass = KMF_ASYM_PRI;
4945637Swyllys 	else if ((oclass & PK_KEY_OBJ) == PK_PUBKEY_OBJ)
4955637Swyllys 		kclass = KMF_ASYM_PUB;
4965637Swyllys 	else if ((oclass & PK_KEY_OBJ) == PK_SYMKEY_OBJ)
4975637Swyllys 		kclass = KMF_SYMMETRIC;
4985637Swyllys 	else /* only 1 key at a time can be exported here, so default to pri */
4995637Swyllys 		kclass = KMF_ASYM_PRI;
5005637Swyllys 
5015637Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
5025637Swyllys 	    &kclass, sizeof (kclass));
5035637Swyllys 	numattr++;
5045637Swyllys 
5055051Swyllys 	rv = kmf_find_key(kmfhandle, numattr, attrlist);
5065740Swyllys 	/*
5075740Swyllys 	 * If nothing found but caller wanted ALL keys, try symmetric
5085740Swyllys 	 * this time.
5095740Swyllys 	 */
5105740Swyllys 	if (rv == KMF_ERR_KEY_NOT_FOUND && (oclass == PK_KEY_OBJ)) {
5115740Swyllys 		kclass = KMF_SYMMETRIC;
5125740Swyllys 		rv = kmf_find_key(kmfhandle, numattr, attrlist);
5135740Swyllys 	}
5145740Swyllys 	/*
5155740Swyllys 	 * If nothing found but caller wanted ALL keys, try asymmetric
5165740Swyllys 	 * public this time.
5175740Swyllys 	 */
5185740Swyllys 	if (rv == KMF_ERR_KEY_NOT_FOUND && (oclass == PK_KEY_OBJ)) {
5195740Swyllys 		kclass = KMF_ASYM_PUB;
5205740Swyllys 		rv = kmf_find_key(kmfhandle, numattr, attrlist);
5215740Swyllys 	}
5225051Swyllys 	if (rv == KMF_OK && key.keyclass == KMF_SYMMETRIC) {
5235051Swyllys 		KMF_RAW_SYM_KEY rkey;
5245051Swyllys 
5255051Swyllys 		(void) memset(&rkey, 0, sizeof (KMF_RAW_SYM_KEY));
5265051Swyllys 		rv = kmf_get_sym_key_value(kmfhandle, &key, &rkey);
5275051Swyllys 		if (rv == KMF_OK) {
5285051Swyllys 			int fd, n, total = 0;
52917Sdinak 
5305051Swyllys 			fd = open(filename, O_CREAT | O_RDWR |O_TRUNC, 0600);
5315051Swyllys 			if (fd == -1) {
5325051Swyllys 				rv = KMF_ERR_OPEN_FILE;
5335051Swyllys 				goto done;
5345051Swyllys 			}
5355051Swyllys 			do {
5365051Swyllys 				n = write(fd, rkey.keydata.val + total,
5375051Swyllys 				    rkey.keydata.len - total);
5385051Swyllys 				if (n < 0) {
5395051Swyllys 					if (errno == EINTR)
5405051Swyllys 						continue;
5415069Swyllys 					(void) close(fd);
5425051Swyllys 					rv = KMF_ERR_WRITE_FILE;
5435051Swyllys 					goto done;
5445051Swyllys 				}
5455051Swyllys 				total += n;
54617Sdinak 
5475051Swyllys 			} while (total < rkey.keydata.len);
5485069Swyllys 			(void) close(fd);
5495051Swyllys 		}
5505051Swyllys done:
5515051Swyllys 		kmf_free_bigint(&rkey.keydata);
5525051Swyllys 		kmf_free_kmf_key(kmfhandle, &key);
5535051Swyllys 	} else if (rv == KMF_OK) {
5545051Swyllys 		KMF_KEYSTORE_TYPE sslks = KMF_KEYSTORE_OPENSSL;
5555069Swyllys 		(void) printf(gettext("Found %d asymmetric keys\n"), numkeys);
5565051Swyllys 
5575051Swyllys 		numattr = 0;
5585051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
5595051Swyllys 		    &sslks, sizeof (sslks));
5605051Swyllys 		numattr++;
5615051Swyllys 
5625051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
5635051Swyllys 		    key.keyp, sizeof (KMF_RAW_KEY_DATA));
5645051Swyllys 		numattr++;
5655051Swyllys 
5665051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
5675051Swyllys 		    &format, sizeof (format));
5685051Swyllys 		numattr++;
5695051Swyllys 
5705051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
5715051Swyllys 		    filename, strlen(filename));
5725051Swyllys 		numattr++;
5735051Swyllys 
5745637Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
5755637Swyllys 		    &key.keyclass, sizeof (KMF_KEY_CLASS));
5765637Swyllys 		numattr++;
5775637Swyllys 
5785051Swyllys 		rv = kmf_store_key(kmfhandle, numattr, attrlist);
5795051Swyllys 		kmf_free_kmf_key(kmfhandle, &key);
5805051Swyllys 	}
58117Sdinak 
5823089Swyllys 	return (rv);
58317Sdinak }
58417Sdinak 
5853089Swyllys static KMF_RETURN
pk_export_pk11_objects(KMF_HANDLE_T kmfhandle,char * token_spec,KMF_CREDENTIAL * cred,char * certlabel,char * issuer,char * subject,KMF_BIGINT * serial,KMF_ENCODE_FORMAT kfmt,char * filename)5863089Swyllys pk_export_pk11_objects(KMF_HANDLE_T kmfhandle, char *token_spec,
58710241Swyllys.ingersoll@sun.com 	KMF_CREDENTIAL *cred, char *certlabel, char *issuer, char *subject,
5883089Swyllys 	KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt,
5893089Swyllys 	char *filename)
59017Sdinak {
5913089Swyllys 	KMF_RETURN rv = KMF_OK;
5923089Swyllys 	KMF_X509_DER_CERT kmfcert;
5935051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
5945051Swyllys 	int numattr = 0;
5955051Swyllys 	KMF_ATTRIBUTE attrlist[16];
59617Sdinak 
5973089Swyllys 	rv = select_token(kmfhandle, token_spec, TRUE);
59817Sdinak 
59910241Swyllys.ingersoll@sun.com 	if (rv != KMF_OK)
60017Sdinak 		return (rv);
60117Sdinak 
6025051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
6035051Swyllys 	    &kstype, sizeof (kstype));
6045051Swyllys 	numattr++;
6055051Swyllys 
60610241Swyllys.ingersoll@sun.com 	if (cred != NULL) {
60710241Swyllys.ingersoll@sun.com 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
60810241Swyllys.ingersoll@sun.com 		    cred, sizeof (KMF_CREDENTIAL));
60910241Swyllys.ingersoll@sun.com 		numattr++;
61010241Swyllys.ingersoll@sun.com 	}
6115051Swyllys 	if (certlabel != NULL) {
6125051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6135051Swyllys 		    KMF_CERT_LABEL_ATTR, certlabel,
6145051Swyllys 		    strlen(certlabel));
6155051Swyllys 		numattr++;
6165051Swyllys 	}
61717Sdinak 
6185051Swyllys 	if (issuer != NULL) {
6195051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6205051Swyllys 		    KMF_ISSUER_NAME_ATTR, issuer,
6215051Swyllys 		    strlen(issuer));
6225051Swyllys 		numattr++;
6235051Swyllys 	}
6245051Swyllys 
6255051Swyllys 	if (subject != NULL) {
6265051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6275051Swyllys 		    KMF_SUBJECT_NAME_ATTR, subject,
6285051Swyllys 		    strlen(subject));
6295051Swyllys 		numattr++;
6305051Swyllys 	}
6315051Swyllys 
6325051Swyllys 	if (serial != NULL) {
6335051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6345051Swyllys 		    KMF_BIGINT_ATTR, serial,
6355051Swyllys 		    sizeof (KMF_BIGINT));
6365051Swyllys 		numattr++;
6375051Swyllys 	}
6385051Swyllys 
6395051Swyllys 	rv = pk_find_export_cert(kmfhandle, attrlist, numattr, &kmfcert);
64017Sdinak 
6413089Swyllys 	if (rv == KMF_OK) {
6425051Swyllys 		kstype = KMF_KEYSTORE_OPENSSL;
6435051Swyllys 		numattr = 0;
6445051Swyllys 
6455051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6465051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
6475051Swyllys 		numattr++;
6485051Swyllys 
6495051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6505051Swyllys 		    KMF_CERT_DATA_ATTR, &kmfcert.certificate,
6515051Swyllys 		    sizeof (KMF_DATA));
6525051Swyllys 		numattr++;
65317Sdinak 
6545051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6555051Swyllys 		    KMF_CERT_FILENAME_ATTR, filename, strlen(filename));
6565051Swyllys 		numattr++;
65717Sdinak 
6585051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6595051Swyllys 		    KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt));
6605051Swyllys 		numattr++;
6615051Swyllys 
6625051Swyllys 		rv = kmf_store_cert(kmfhandle, numattr, attrlist);
6635051Swyllys 
6645051Swyllys 		kmf_free_kmf_cert(kmfhandle, &kmfcert);
66517Sdinak 	}
6663089Swyllys 	return (rv);
66717Sdinak }
66817Sdinak 
66917Sdinak /*
6703089Swyllys  * Export objects from one keystore to a file.
67117Sdinak  */
67217Sdinak int
pk_export(int argc,char * argv[])67317Sdinak pk_export(int argc, char *argv[])
67417Sdinak {
675864Sdinak 	int		opt;
676864Sdinak 	extern int	optind_av;
677864Sdinak 	extern char	*optarg_av;
678864Sdinak 	char		*token_spec = NULL;
67917Sdinak 	char		*filename = NULL;
6803089Swyllys 	char		*dir = NULL;
6813089Swyllys 	char		*prefix = NULL;
6823089Swyllys 	char		*certlabel = NULL;
6833089Swyllys 	char		*subject = NULL;
6843089Swyllys 	char		*issuer = NULL;
6853089Swyllys 	char		*infile = NULL;
6863089Swyllys 	char		*keyfile = NULL;
6873089Swyllys 	char		*certfile = NULL;
6883089Swyllys 	char		*serstr = NULL;
6893089Swyllys 	KMF_KEYSTORE_TYPE	kstype = 0;
6903089Swyllys 	KMF_ENCODE_FORMAT	kfmt = KMF_FORMAT_PKCS12;
6913089Swyllys 	KMF_RETURN		rv = KMF_OK;
6923089Swyllys 	int		oclass = PK_CERT_OBJ;
6933089Swyllys 	KMF_BIGINT	serial = { NULL, 0 };
6943089Swyllys 	KMF_HANDLE_T	kmfhandle = NULL;
6953089Swyllys 	KMF_CREDENTIAL	tokencred = {NULL, 0};
69617Sdinak 
697864Sdinak 	/* Parse command line options.  Do NOT i18n/l10n. */
6983089Swyllys 	while ((opt = getopt_av(argc, argv,
6995051Swyllys 	    "k:(keystore)y:(objtype)T:(token)"
7005051Swyllys 	    "d:(dir)p:(prefix)"
7015051Swyllys 	    "l:(label)n:(nickname)s:(subject)"
7025051Swyllys 	    "i:(issuer)S:(serial)"
7035051Swyllys 	    "K:(keyfile)c:(certfile)"
7045051Swyllys 	    "F:(outformat)"
7055051Swyllys 	    "I:(infile)o:(outfile)")) != EOF) {
7063089Swyllys 		if (EMPTYSTRING(optarg_av))
7073089Swyllys 			return (PK_ERR_USAGE);
708864Sdinak 		switch (opt) {
7093089Swyllys 		case 'k':
7103089Swyllys 			kstype = KS2Int(optarg_av);
7113089Swyllys 			if (kstype == 0)
7123089Swyllys 				return (PK_ERR_USAGE);
7133089Swyllys 			break;
7143089Swyllys 		case 'y':
7153089Swyllys 			oclass = OT2Int(optarg_av);
7163089Swyllys 			if (oclass == -1)
7173089Swyllys 				return (PK_ERR_USAGE);
7183089Swyllys 			break;
719864Sdinak 		case 'T':	/* token specifier */
720864Sdinak 			if (token_spec)
721864Sdinak 				return (PK_ERR_USAGE);
722864Sdinak 			token_spec = optarg_av;
723864Sdinak 			break;
7243089Swyllys 		case 'd':
7253089Swyllys 			if (dir)
7263089Swyllys 				return (PK_ERR_USAGE);
7273089Swyllys 			dir = optarg_av;
7283089Swyllys 			break;
7293089Swyllys 		case 'p':
7303089Swyllys 			if (prefix)
7313089Swyllys 				return (PK_ERR_USAGE);
7323089Swyllys 			prefix = optarg_av;
7333089Swyllys 			break;
7343089Swyllys 		case 'n':
7353089Swyllys 		case 'l':
7363089Swyllys 			if (certlabel)
7373089Swyllys 				return (PK_ERR_USAGE);
7383089Swyllys 			certlabel = optarg_av;
7393089Swyllys 			break;
7403089Swyllys 		case 's':
7413089Swyllys 			if (subject)
7423089Swyllys 				return (PK_ERR_USAGE);
7433089Swyllys 			subject = optarg_av;
7443089Swyllys 			break;
7453089Swyllys 		case 'i':
7463089Swyllys 			if (issuer)
7473089Swyllys 				return (PK_ERR_USAGE);
7483089Swyllys 			issuer = optarg_av;
7493089Swyllys 			break;
7503089Swyllys 		case 'S':
7513089Swyllys 			serstr = optarg_av;
7523089Swyllys 			break;
7533089Swyllys 		case 'F':
7543089Swyllys 			kfmt = Str2Format(optarg_av);
7553089Swyllys 			if (kfmt == KMF_FORMAT_UNDEF)
7563089Swyllys 				return (PK_ERR_USAGE);
7573089Swyllys 			break;
7583089Swyllys 		case 'I':	/* output file name */
7593089Swyllys 			if (infile)
7603089Swyllys 				return (PK_ERR_USAGE);
7613089Swyllys 			infile = optarg_av;
7623089Swyllys 			break;
763864Sdinak 		case 'o':	/* output file name */
764864Sdinak 			if (filename)
765864Sdinak 				return (PK_ERR_USAGE);
766864Sdinak 			filename = optarg_av;
767864Sdinak 			break;
7683089Swyllys 		case 'c':	/* input cert file name */
7693089Swyllys 			if (certfile)
7703089Swyllys 				return (PK_ERR_USAGE);
7713089Swyllys 			certfile = optarg_av;
7723089Swyllys 			break;
7733089Swyllys 		case 'K':	/* input key file name */
7743089Swyllys 			if (keyfile)
7753089Swyllys 				return (PK_ERR_USAGE);
7763089Swyllys 			keyfile = optarg_av;
7773089Swyllys 			break;
778864Sdinak 		default:
779864Sdinak 			return (PK_ERR_USAGE);
780864Sdinak 			break;
781864Sdinak 		}
782864Sdinak 	}
78317Sdinak 
7843089Swyllys 	/* Assume keystore = PKCS#11 if not specified */
7853089Swyllys 	if (kstype == 0)
7863089Swyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
787864Sdinak 
788864Sdinak 	/* Filename arg is required. */
7893089Swyllys 	if (EMPTYSTRING(filename)) {
7903089Swyllys 		cryptoerror(LOG_STDERR, gettext("You must specify "
7915051Swyllys 		    "an 'outfile' parameter when exporting.\n"));
79217Sdinak 		return (PK_ERR_USAGE);
7933089Swyllys 	}
79417Sdinak 
795864Sdinak 	/* No additional args allowed. */
796864Sdinak 	argc -= optind_av;
797864Sdinak 	argv += optind_av;
798864Sdinak 	if (argc)
799864Sdinak 		return (PK_ERR_USAGE);
8003089Swyllys 
8016884Swyllys 	DIR_OPTION_CHECK(kstype, dir);
8026884Swyllys 
8033089Swyllys 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
8043089Swyllys 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
8055051Swyllys 	    kstype != KMF_KEYSTORE_PK11TOKEN) {
8063089Swyllys 
8073089Swyllys 		(void) fprintf(stderr, gettext("The objtype parameter "
8085051Swyllys 		    "is only relevant if keystore=pkcs11\n"));
8093089Swyllys 		return (PK_ERR_USAGE);
8103089Swyllys 	}
8113089Swyllys 
8123089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
8133089Swyllys 		token_spec = PK_DEFAULT_PK11TOKEN;
8143089Swyllys 	else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
8153089Swyllys 		token_spec = DEFAULT_NSS_TOKEN;
8163089Swyllys 
8173089Swyllys 	if (kstype == KMF_KEYSTORE_OPENSSL) {
8183089Swyllys 		if (kfmt != KMF_FORMAT_PKCS12) {
8193089Swyllys 			cryptoerror(LOG_STDERR, gettext("PKCS12 "
8205051Swyllys 			    "is the only export format "
8215051Swyllys 			    "supported for the 'file' "
8225051Swyllys 			    "keystore.\n"));
8233089Swyllys 			return (PK_ERR_USAGE);
8243089Swyllys 		}
8253089Swyllys 		if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
8263089Swyllys 			cryptoerror(LOG_STDERR, gettext("A cert file"
8275051Swyllys 			    "and a key file must be specified "
8285051Swyllys 			    "when exporting to PKCS12 from the "
8295051Swyllys 			    "'file' keystore.\n"));
8303089Swyllys 			return (PK_ERR_USAGE);
8313089Swyllys 		}
8323089Swyllys 	}
83317Sdinak 
834*12234Swyllys.ingersoll@sun.com 	/* Check if the file exists */
835*12234Swyllys.ingersoll@sun.com 	if (verify_file(filename) != KMF_OK) {
8363089Swyllys 		cryptoerror(LOG_STDERR,
8375051Swyllys 		    gettext("Warning: file \"%s\" exists, "
8385051Swyllys 		    "will be overwritten."), filename);
83917Sdinak 		if (yesno(gettext("Continue with export? "),
84017Sdinak 		    gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) {
84117Sdinak 			return (0);
8425637Swyllys 		} else {
8435637Swyllys 			/* remove the file */
8445637Swyllys 			(void) unlink(filename);
84517Sdinak 		}
84617Sdinak 	}
84717Sdinak 
8483089Swyllys 	if (serstr != NULL) {
8493089Swyllys 		uchar_t *bytes = NULL;
8503089Swyllys 		size_t bytelen;
85117Sdinak 
8525051Swyllys 		rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
8533089Swyllys 		if (rv != KMF_OK || bytes == NULL) {
8543089Swyllys 			(void) fprintf(stderr, gettext("serial number "
8555051Swyllys 			    "must be specified as a hex number "
8565051Swyllys 			    "(ex: 0x0102030405ffeeddee)\n"));
8573089Swyllys 			return (PK_ERR_USAGE);
8583089Swyllys 		}
8593089Swyllys 		serial.val = bytes;
8603089Swyllys 		serial.len = bytelen;
86117Sdinak 	}
86217Sdinak 
86310442Swyllys.ingersoll@sun.com 	/*
86410442Swyllys.ingersoll@sun.com 	 * We need a password in the following situations:
86510442Swyllys.ingersoll@sun.com 	 * 1.  When accessing PKCS11 token
86610442Swyllys.ingersoll@sun.com 	 * 2.  If NSS keystore, when making a PKCS12 file or when
86710442Swyllys.ingersoll@sun.com 	 * accessing any private object or key.
86810442Swyllys.ingersoll@sun.com 	 */
86910241Swyllys.ingersoll@sun.com 	if (kstype == KMF_KEYSTORE_PK11TOKEN ||
87010241Swyllys.ingersoll@sun.com 	    ((kstype == KMF_KEYSTORE_NSS) &&
87110442Swyllys.ingersoll@sun.com 	    ((oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ)) ||
87210442Swyllys.ingersoll@sun.com 	    (kfmt == KMF_FORMAT_PKCS12)))) {
8733089Swyllys 			(void) get_token_password(kstype, token_spec,
8745051Swyllys 			    &tokencred);
87517Sdinak 	}
87617Sdinak 
8775051Swyllys 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
8783089Swyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing "
8795051Swyllys 		    "KMF: 0x%02x\n"), rv);
8803089Swyllys 		return (rv);
88117Sdinak 	}
88217Sdinak 
8833089Swyllys 	switch (kstype) {
8843089Swyllys 		case KMF_KEYSTORE_PK11TOKEN:
8853089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
8865051Swyllys 				rv = pk_export_pk12_pk11(kmfhandle,
8875051Swyllys 				    token_spec, certlabel,
8885051Swyllys 				    issuer, subject,
8895051Swyllys 				    &serial, &tokencred,
8905051Swyllys 				    filename);
8915051Swyllys 			else if ((oclass & PK_KEY_OBJ) ||
8925051Swyllys 			    kfmt == KMF_FORMAT_RAWKEY)
8935051Swyllys 				rv = pk_export_pk11_keys(kmfhandle,
8945051Swyllys 				    token_spec, &tokencred, kfmt,
8955637Swyllys 				    certlabel, filename, oclass);
8963089Swyllys 			else
8973089Swyllys 				rv = pk_export_pk11_objects(kmfhandle,
89810241Swyllys.ingersoll@sun.com 				    token_spec, &tokencred, certlabel,
8995051Swyllys 				    issuer, subject, &serial, kfmt,
9005051Swyllys 				    filename);
9013089Swyllys 			break;
9023089Swyllys 		case KMF_KEYSTORE_NSS:
9033089Swyllys 			if (dir == NULL)
9043089Swyllys 				dir = PK_DEFAULT_DIRECTORY;
9053089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
9063089Swyllys 				rv = pk_export_pk12_nss(kmfhandle,
9075051Swyllys 				    token_spec, dir, prefix,
9085051Swyllys 				    certlabel, issuer,
9095051Swyllys 				    subject, &serial,
9105051Swyllys 				    &tokencred, filename);
9113089Swyllys 			else
9123089Swyllys 				rv = pk_export_nss_objects(kmfhandle,
9135051Swyllys 				    token_spec,
9145051Swyllys 				    oclass, certlabel, issuer, subject,
9155051Swyllys 				    &serial, kfmt, dir, prefix, filename);
9163089Swyllys 			break;
9173089Swyllys 		case KMF_KEYSTORE_OPENSSL:
9183089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
9193089Swyllys 				rv = pk_export_pk12_files(kmfhandle,
9206669Swyllys 				    certfile, keyfile, filename);
9213089Swyllys 			else
9223089Swyllys 				rv = pk_export_file_objects(kmfhandle, oclass,
9235051Swyllys 				    issuer, subject, &serial,
9246669Swyllys 				    infile, filename);
9253089Swyllys 			break;
9263089Swyllys 		default:
9273089Swyllys 			rv = PK_ERR_USAGE;
9283089Swyllys 			break;
92917Sdinak 	}
93017Sdinak 
9313089Swyllys 	if (rv != KMF_OK) {
9323089Swyllys 		display_error(kmfhandle, rv,
9335051Swyllys 		    gettext("Error exporting objects"));
9343089Swyllys 	}
93517Sdinak 
9363089Swyllys 	if (serial.val != NULL)
9373089Swyllys 		free(serial.val);
93817Sdinak 
9395051Swyllys 	(void) kmf_finalize(kmfhandle);
9403089Swyllys 
9413089Swyllys 	return (rv);
94217Sdinak }
943