17711facfSdinak /*
27711facfSdinak  * CDDL HEADER START
37711facfSdinak  *
47711facfSdinak  * The contents of this file are subject to the terms of the
59e860378Sdinak  * Common Development and Distribution License (the "License").
69e860378Sdinak  * 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
2099ebb4caSwyllys  *
212c9a247fSWyllys Ingersoll  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2233f5ff17SMilan Jurik  * Copyright 2012 Milan Jurik. All rights reserved.
237711facfSdinak  */
247711facfSdinak 
257711facfSdinak /*
267711facfSdinak  * This file implements the export operation for this tool.
277711facfSdinak  * The basic flow of the process is to find the soft token,
287711facfSdinak  * log into it, find the PKCS#11 objects in the soft token
297711facfSdinak  * to be exported matching keys with their certificates, export
307711facfSdinak  * them to the PKCS#12 file encrypting them with a file password
317711facfSdinak  * if desired, and log out.
327711facfSdinak  */
337711facfSdinak 
347711facfSdinak #include <stdio.h>
357711facfSdinak #include <stdlib.h>
367711facfSdinak #include <string.h>
377711facfSdinak #include <errno.h>
3899ebb4caSwyllys #include <fcntl.h>
397711facfSdinak #include "common.h"
407711facfSdinak 
4199ebb4caSwyllys #include <kmfapi.h>
427711facfSdinak 
4399ebb4caSwyllys static KMF_RETURN
pk_find_export_cert(KMF_HANDLE_T kmfhandle,KMF_ATTRIBUTE * attrlist,int numattr,KMF_X509_DER_CERT * cert)4430a5e8faSwyllys pk_find_export_cert(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attrlist,
4530a5e8faSwyllys 	int numattr, KMF_X509_DER_CERT *cert)
467711facfSdinak {
4799ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
4899ebb4caSwyllys 	uint32_t numcerts = 0;
497711facfSdinak 
5099ebb4caSwyllys 	numcerts = 0;
5199ebb4caSwyllys 	(void) memset(cert, 0, sizeof (KMF_X509_DER_CERT));
5230a5e8faSwyllys 
5330a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
5430a5e8faSwyllys 	    &numcerts, sizeof (uint32_t));
5530a5e8faSwyllys 	numattr++;
5630a5e8faSwyllys 
5730a5e8faSwyllys 	rv = kmf_find_cert(kmfhandle, numattr, attrlist);
5899ebb4caSwyllys 	if (rv != KMF_OK) {
597711facfSdinak 		return (rv);
607711facfSdinak 	}
6199ebb4caSwyllys 	if (numcerts == 0) {
6299ebb4caSwyllys 		cryptoerror(LOG_STDERR,
6330a5e8faSwyllys 		    gettext("No matching certificates found."));
6499ebb4caSwyllys 		return (KMF_ERR_CERT_NOT_FOUND);
657711facfSdinak 
6699ebb4caSwyllys 	} else if (numcerts == 1) {
6730a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
6830a5e8faSwyllys 		    KMF_X509_DER_CERT_ATTR, cert,
6930a5e8faSwyllys 		    sizeof (KMF_X509_DER_CERT));
7030a5e8faSwyllys 		numattr++;
7130a5e8faSwyllys 		rv = kmf_find_cert(kmfhandle, numattr, attrlist);
727711facfSdinak 
7399ebb4caSwyllys 	} else if (numcerts > 1) {
7499ebb4caSwyllys 		cryptoerror(LOG_STDERR,
7530a5e8faSwyllys 		    gettext("%d certificates found, refine the "
7630a5e8faSwyllys 		    "search parameters to eliminate ambiguity\n"),
7730a5e8faSwyllys 		    numcerts);
7899ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
797711facfSdinak 	}
8099ebb4caSwyllys 	return (rv);
817711facfSdinak }
827711facfSdinak 
8399ebb4caSwyllys static KMF_RETURN
pk_export_file_objects(KMF_HANDLE_T kmfhandle,int oclass,char * issuer,char * subject,KMF_BIGINT * serial,char * infile,char * filename)8499ebb4caSwyllys pk_export_file_objects(KMF_HANDLE_T kmfhandle, int oclass,
8599ebb4caSwyllys 	char *issuer, char *subject, KMF_BIGINT *serial,
86448b8615Swyllys 	char *infile, char *filename)
877711facfSdinak {
8899ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
8999ebb4caSwyllys 	KMF_X509_DER_CERT kmfcert;
9030a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
9130a5e8faSwyllys 	int numattr = 0;
9230a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[16];
9399ebb4caSwyllys 
9499ebb4caSwyllys 	/* If searching for public objects or certificates, find certs now */
9599ebb4caSwyllys 	if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
9630a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
9730a5e8faSwyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
9830a5e8faSwyllys 		    sizeof (kstype));
9930a5e8faSwyllys 		numattr++;
10030a5e8faSwyllys 
10130a5e8faSwyllys 		if (issuer != NULL) {
10230a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
10330a5e8faSwyllys 			    KMF_ISSUER_NAME_ATTR, issuer,
10430a5e8faSwyllys 			    strlen(issuer));
10530a5e8faSwyllys 			numattr++;
10630a5e8faSwyllys 		}
10730a5e8faSwyllys 
10830a5e8faSwyllys 		if (subject != NULL) {
10930a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
11030a5e8faSwyllys 			    KMF_SUBJECT_NAME_ATTR, subject,
11130a5e8faSwyllys 			    strlen(subject));
11230a5e8faSwyllys 			numattr++;
11330a5e8faSwyllys 		}
11430a5e8faSwyllys 
11530a5e8faSwyllys 		if (serial != NULL) {
11630a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
11730a5e8faSwyllys 			    KMF_BIGINT_ATTR, serial,
11830a5e8faSwyllys 			    sizeof (KMF_BIGINT));
11930a5e8faSwyllys 			numattr++;
12030a5e8faSwyllys 		}
12130a5e8faSwyllys 
12230a5e8faSwyllys 		if (infile != NULL) {
12330a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
12430a5e8faSwyllys 			    KMF_CERT_FILENAME_ATTR, infile,
12530a5e8faSwyllys 			    strlen(infile));
12630a5e8faSwyllys 			numattr++;
12730a5e8faSwyllys 		}
12830a5e8faSwyllys 
12930a5e8faSwyllys 		rv = pk_find_export_cert(kmfhandle, attrlist, numattr,
13030a5e8faSwyllys 		    &kmfcert);
13199ebb4caSwyllys 		if (rv == KMF_OK) {
13230a5e8faSwyllys 			kstype = KMF_KEYSTORE_OPENSSL;
13330a5e8faSwyllys 			numattr = 0;
13499ebb4caSwyllys 
13530a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
13630a5e8faSwyllys 			    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
13730a5e8faSwyllys 			numattr++;
13830a5e8faSwyllys 
13930a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
14030a5e8faSwyllys 			    KMF_CERT_DATA_ATTR, &kmfcert.certificate,
14130a5e8faSwyllys 			    sizeof (KMF_DATA));
14230a5e8faSwyllys 			numattr++;
14330a5e8faSwyllys 
14430a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
14530a5e8faSwyllys 			    KMF_CERT_FILENAME_ATTR, filename,
14630a5e8faSwyllys 			    strlen(filename));
14730a5e8faSwyllys 			numattr++;
14830a5e8faSwyllys 
14930a5e8faSwyllys 			rv = kmf_store_cert(kmfhandle, numattr,
15030a5e8faSwyllys 			    attrlist);
15130a5e8faSwyllys 
15230a5e8faSwyllys 			kmf_free_kmf_cert(kmfhandle, &kmfcert);
15399ebb4caSwyllys 		}
15499ebb4caSwyllys 	}
15599ebb4caSwyllys 	return (rv);
1567711facfSdinak }
1577711facfSdinak 
15899ebb4caSwyllys 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)15999ebb4caSwyllys pk_export_pk12_nss(KMF_HANDLE_T kmfhandle,
16099ebb4caSwyllys 	char *token_spec, char *dir, char *prefix,
16199ebb4caSwyllys 	char *certlabel, char *issuer, char *subject,
16299ebb4caSwyllys 	KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred,
16399ebb4caSwyllys 	char *filename)
1647711facfSdinak {
16599ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
16630a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype;
167*6b35cb3cSRichard PALO 	KMF_CREDENTIAL p12cred = { NULL, 0 };
16830a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[16];
16930a5e8faSwyllys 	int numattr = 0;
1707711facfSdinak 
17199ebb4caSwyllys 	rv = configure_nss(kmfhandle, dir, prefix);
17299ebb4caSwyllys 	if (rv != KMF_OK)
1737711facfSdinak 		return (rv);
1747711facfSdinak 
17599ebb4caSwyllys 	if (token_spec == NULL)
17699ebb4caSwyllys 		token_spec = DEFAULT_NSS_TOKEN;
1777711facfSdinak 
17830a5e8faSwyllys 	kstype = KMF_KEYSTORE_NSS;
17930a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
18030a5e8faSwyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
18130a5e8faSwyllys 	numattr++;
18230a5e8faSwyllys 
18330a5e8faSwyllys 	if (certlabel != NULL) {
18430a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
18530a5e8faSwyllys 		    KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
18630a5e8faSwyllys 		numattr++;
18730a5e8faSwyllys 	}
18830a5e8faSwyllys 
18930a5e8faSwyllys 	if (issuer != NULL) {
19030a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
19130a5e8faSwyllys 		    KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
19230a5e8faSwyllys 		numattr++;
19330a5e8faSwyllys 	}
19430a5e8faSwyllys 
19530a5e8faSwyllys 	if (subject != NULL) {
19630a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
19730a5e8faSwyllys 		    KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
19830a5e8faSwyllys 		numattr++;
19930a5e8faSwyllys 	}
2007711facfSdinak 
20130a5e8faSwyllys 	if (serial != NULL) {
20230a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
20330a5e8faSwyllys 		    KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
20430a5e8faSwyllys 		numattr++;
20530a5e8faSwyllys 	}
2067711facfSdinak 
20730a5e8faSwyllys 	if (tokencred != NULL) {
20830a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
20930a5e8faSwyllys 		    KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL));
21030a5e8faSwyllys 		numattr++;
21130a5e8faSwyllys 	}
21230a5e8faSwyllys 
21330a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
21430a5e8faSwyllys 	    token_spec, strlen(token_spec));
21530a5e8faSwyllys 	numattr++;
21630a5e8faSwyllys 
21730a5e8faSwyllys 	(void) get_pk12_password(&p12cred);
21830a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
21930a5e8faSwyllys 	    KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
22030a5e8faSwyllys 	numattr++;
22130a5e8faSwyllys 
22230a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
22330a5e8faSwyllys 	    KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename));
22430a5e8faSwyllys 	numattr++;
22530a5e8faSwyllys 
22630a5e8faSwyllys 	rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
22730a5e8faSwyllys 
22830a5e8faSwyllys 	if (p12cred.cred)
22930a5e8faSwyllys 		free(p12cred.cred);
2307711facfSdinak 
23199ebb4caSwyllys 	return (rv);
2327711facfSdinak }
2337711facfSdinak 
23499ebb4caSwyllys static KMF_RETURN
pk_export_pk12_files(KMF_HANDLE_T kmfhandle,char * certfile,char * keyfile,char * outfile)23599ebb4caSwyllys pk_export_pk12_files(KMF_HANDLE_T kmfhandle,
236448b8615Swyllys 	char *certfile, char *keyfile,
23799ebb4caSwyllys 	char *outfile)
2387711facfSdinak {
23999ebb4caSwyllys 	KMF_RETURN rv;
24030a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype;
241*6b35cb3cSRichard PALO 	KMF_CREDENTIAL p12cred = { NULL, 0 };
24230a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[16];
24330a5e8faSwyllys 	int numattr = 0;
24430a5e8faSwyllys 
24530a5e8faSwyllys 	kstype = KMF_KEYSTORE_OPENSSL;
24630a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
24730a5e8faSwyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
24830a5e8faSwyllys 	numattr++;
24930a5e8faSwyllys 
25030a5e8faSwyllys 	if (certfile != NULL) {
25130a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
25230a5e8faSwyllys 		    KMF_CERT_FILENAME_ATTR, certfile, strlen(certfile));
25330a5e8faSwyllys 		numattr++;
25430a5e8faSwyllys 	}
25530a5e8faSwyllys 
25630a5e8faSwyllys 	if (keyfile != NULL) {
25730a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
25830a5e8faSwyllys 		    KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
25930a5e8faSwyllys 		numattr++;
26030a5e8faSwyllys 	}
2617711facfSdinak 
26230a5e8faSwyllys 	(void) get_pk12_password(&p12cred);
26330a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
26430a5e8faSwyllys 	    KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
26530a5e8faSwyllys 	numattr++;
2667711facfSdinak 
26730a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
26830a5e8faSwyllys 	    KMF_OUTPUT_FILENAME_ATTR, outfile, strlen(outfile));
26930a5e8faSwyllys 	numattr++;
2707711facfSdinak 
27130a5e8faSwyllys 	rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
2727711facfSdinak 
27330a5e8faSwyllys 	if (p12cred.cred)
27430a5e8faSwyllys 		free(p12cred.cred);
2757711facfSdinak 
27699ebb4caSwyllys 	return (rv);
2777711facfSdinak }
2787711facfSdinak 
27999ebb4caSwyllys 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)28099ebb4caSwyllys pk_export_nss_objects(KMF_HANDLE_T kmfhandle, char *token_spec,
28199ebb4caSwyllys 	int oclass, char *certlabel, char *issuer, char *subject,
28299ebb4caSwyllys 	KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, char *dir,
28399ebb4caSwyllys 	char *prefix, char *filename)
2847711facfSdinak {
28599ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
28699ebb4caSwyllys 	KMF_X509_DER_CERT kmfcert;
28730a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
28830a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[16];
28930a5e8faSwyllys 	int numattr = 0;
2907711facfSdinak 
29199ebb4caSwyllys 	rv = configure_nss(kmfhandle, dir, prefix);
29299ebb4caSwyllys 	if (rv != KMF_OK)
2937711facfSdinak 		return (rv);
2947711facfSdinak 
29599ebb4caSwyllys 	/* If searching for public objects or certificates, find certs now */
29699ebb4caSwyllys 	if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
29730a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
29830a5e8faSwyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
29930a5e8faSwyllys 		    sizeof (kstype));
30030a5e8faSwyllys 		numattr++;
30130a5e8faSwyllys 
30230a5e8faSwyllys 		if (certlabel != NULL) {
30330a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
30430a5e8faSwyllys 			    KMF_CERT_LABEL_ATTR, certlabel,
30530a5e8faSwyllys 			    strlen(certlabel));
30630a5e8faSwyllys 			numattr++;
30730a5e8faSwyllys 		}
30899ebb4caSwyllys 
30930a5e8faSwyllys 		if (issuer != NULL) {
31030a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
31130a5e8faSwyllys 			    KMF_ISSUER_NAME_ATTR, issuer,
31230a5e8faSwyllys 			    strlen(issuer));
31330a5e8faSwyllys 			numattr++;
31430a5e8faSwyllys 		}
31599ebb4caSwyllys 
31630a5e8faSwyllys 		if (subject != NULL) {
31730a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
31830a5e8faSwyllys 			    KMF_SUBJECT_NAME_ATTR, subject,
31930a5e8faSwyllys 			    strlen(subject));
32030a5e8faSwyllys 			numattr++;
32130a5e8faSwyllys 		}
32230a5e8faSwyllys 
32330a5e8faSwyllys 		if (serial != NULL) {
32430a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
32530a5e8faSwyllys 			    KMF_BIGINT_ATTR, serial,
32630a5e8faSwyllys 			    sizeof (KMF_BIGINT));
32730a5e8faSwyllys 			numattr++;
32830a5e8faSwyllys 		}
32930a5e8faSwyllys 
33030a5e8faSwyllys 		if (token_spec != NULL) {
33130a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
33230a5e8faSwyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
33330a5e8faSwyllys 			    strlen(token_spec));
33430a5e8faSwyllys 			numattr++;
33530a5e8faSwyllys 		}
33630a5e8faSwyllys 
33730a5e8faSwyllys 		rv = pk_find_export_cert(kmfhandle, attrlist, numattr,
33830a5e8faSwyllys 		    &kmfcert);
33999ebb4caSwyllys 		if (rv == KMF_OK) {
34030a5e8faSwyllys 			kstype = KMF_KEYSTORE_OPENSSL;
34130a5e8faSwyllys 			numattr = 0;
34230a5e8faSwyllys 
34330a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
34430a5e8faSwyllys 			    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
34530a5e8faSwyllys 			numattr++;
34699ebb4caSwyllys 
34730a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
34830a5e8faSwyllys 			    KMF_CERT_DATA_ATTR, &kmfcert.certificate,
34930a5e8faSwyllys 			    sizeof (KMF_DATA));
35030a5e8faSwyllys 			numattr++;
35199ebb4caSwyllys 
35230a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
35330a5e8faSwyllys 			    KMF_CERT_FILENAME_ATTR, filename,
35430a5e8faSwyllys 			    strlen(filename));
35530a5e8faSwyllys 			numattr++;
35630a5e8faSwyllys 
35730a5e8faSwyllys 			kmf_set_attr_at_index(attrlist, numattr,
35830a5e8faSwyllys 			    KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt));
35930a5e8faSwyllys 			numattr++;
36030a5e8faSwyllys 
36130a5e8faSwyllys 			rv = kmf_store_cert(kmfhandle, numattr, attrlist);
36230a5e8faSwyllys 
36330a5e8faSwyllys 			kmf_free_kmf_cert(kmfhandle, &kmfcert);
3647711facfSdinak 		}
3657711facfSdinak 	}
36699ebb4caSwyllys 	return (rv);
36799ebb4caSwyllys }
3687711facfSdinak 
36999ebb4caSwyllys 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)37099ebb4caSwyllys pk_export_pk12_pk11(KMF_HANDLE_T kmfhandle, char *token_spec,
37199ebb4caSwyllys 	char *certlabel, char *issuer, char *subject,
37299ebb4caSwyllys 	KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, char *filename)
37399ebb4caSwyllys {
37499ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
37530a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype;
376*6b35cb3cSRichard PALO 	KMF_CREDENTIAL p12cred = { NULL, 0 };
37730a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[16];
37830a5e8faSwyllys 	int numattr = 0;
3797711facfSdinak 
38099ebb4caSwyllys 	rv = select_token(kmfhandle, token_spec, TRUE);
38199ebb4caSwyllys 	if (rv != KMF_OK) {
38299ebb4caSwyllys 		return (rv);
3837711facfSdinak 	}
3847711facfSdinak 
38530a5e8faSwyllys 	kstype = KMF_KEYSTORE_PK11TOKEN;
38630a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
38730a5e8faSwyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
38830a5e8faSwyllys 	numattr++;
38930a5e8faSwyllys 
39030a5e8faSwyllys 	if (certlabel != NULL) {
39130a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
39230a5e8faSwyllys 		    KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
39330a5e8faSwyllys 		numattr++;
39430a5e8faSwyllys 	}
39530a5e8faSwyllys 
39630a5e8faSwyllys 	if (issuer != NULL) {
39730a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
39830a5e8faSwyllys 		    KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
39930a5e8faSwyllys 		numattr++;
40030a5e8faSwyllys 	}
40130a5e8faSwyllys 
40230a5e8faSwyllys 	if (subject != NULL) {
40330a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
40430a5e8faSwyllys 		    KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
40530a5e8faSwyllys 		numattr++;
40630a5e8faSwyllys 	}
40730a5e8faSwyllys 
40830a5e8faSwyllys 	if (serial != NULL) {
40930a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
41030a5e8faSwyllys 		    KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
41130a5e8faSwyllys 		numattr++;
41230a5e8faSwyllys 	}
41330a5e8faSwyllys 
41430a5e8faSwyllys 	if (tokencred != NULL) {
41530a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
41630a5e8faSwyllys 		    KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL));
41730a5e8faSwyllys 		numattr++;
41830a5e8faSwyllys 	}
41930a5e8faSwyllys 
42030a5e8faSwyllys 	(void) get_pk12_password(&p12cred);
42130a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
42230a5e8faSwyllys 	    KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
42330a5e8faSwyllys 	numattr++;
42430a5e8faSwyllys 
42530a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr,
42630a5e8faSwyllys 	    KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename));
42730a5e8faSwyllys 	numattr++;
42830a5e8faSwyllys 
42930a5e8faSwyllys 	rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
43030a5e8faSwyllys 
43130a5e8faSwyllys 	if (p12cred.cred)
43230a5e8faSwyllys 		free(p12cred.cred);
43330a5e8faSwyllys 
43430a5e8faSwyllys 	return (rv);
43530a5e8faSwyllys }
43630a5e8faSwyllys 
43730a5e8faSwyllys 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)43830a5e8faSwyllys pk_export_pk11_keys(KMF_HANDLE_T kmfhandle, char *token,
43930a5e8faSwyllys 	KMF_CREDENTIAL *cred, KMF_ENCODE_FORMAT format,
44073cc0e02Swyllys 	char *label, char *filename, int oclass)
44130a5e8faSwyllys {
44230a5e8faSwyllys 	KMF_RETURN rv = KMF_OK;
44330a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
44473cc0e02Swyllys 	KMF_KEY_CLASS kclass = KMF_KEYCLASS_NONE;
44530a5e8faSwyllys 	int numattr = 0;
44630a5e8faSwyllys 	uint32_t numkeys = 1;
44730a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[16];
44830a5e8faSwyllys 	KMF_KEY_HANDLE key;
44930a5e8faSwyllys 	boolean_t is_token = B_TRUE;
45030a5e8faSwyllys 
45130a5e8faSwyllys 	if (EMPTYSTRING(label)) {
45230a5e8faSwyllys 		cryptoerror(LOG_STDERR, gettext("A label "
45330a5e8faSwyllys 		    "must be specified to export a key."));
45430a5e8faSwyllys 		return (KMF_ERR_BAD_PARAMETER);
45530a5e8faSwyllys 	}
45630a5e8faSwyllys 
45730a5e8faSwyllys 	rv = select_token(kmfhandle, token, TRUE);
45830a5e8faSwyllys 	if (rv != KMF_OK) {
45930a5e8faSwyllys 		return (rv);
46030a5e8faSwyllys 	}
46130a5e8faSwyllys 
46230a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
46330a5e8faSwyllys 	    &kstype, sizeof (kstype));
46430a5e8faSwyllys 	numattr++;
46530a5e8faSwyllys 
46630a5e8faSwyllys 	if (cred != NULL) {
46730a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
46830a5e8faSwyllys 		    cred, sizeof (KMF_CREDENTIAL));
46930a5e8faSwyllys 		numattr++;
47030a5e8faSwyllys 	}
47130a5e8faSwyllys 
47230a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
47330a5e8faSwyllys 	    label, strlen(label));
47430a5e8faSwyllys 	numattr++;
47530a5e8faSwyllys 
47630a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
47730a5e8faSwyllys 	    &numkeys, sizeof (numkeys));
47830a5e8faSwyllys 	numattr++;
4797711facfSdinak 
48030a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
48130a5e8faSwyllys 	    &key, sizeof (key));
48230a5e8faSwyllys 	numattr++;
4837711facfSdinak 
48430a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR,
48530a5e8faSwyllys 	    &is_token, sizeof (is_token));
48630a5e8faSwyllys 	numattr++;
4877711facfSdinak 
48830a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
48930a5e8faSwyllys 	    &format, sizeof (format));
49030a5e8faSwyllys 	numattr++;
49130a5e8faSwyllys 
49273cc0e02Swyllys 	/* Check to see if we are exporting private or public only */
49373cc0e02Swyllys 	if ((oclass & PK_KEY_OBJ) == PK_PRIKEY_OBJ)
49473cc0e02Swyllys 		kclass = KMF_ASYM_PRI;
49573cc0e02Swyllys 	else if ((oclass & PK_KEY_OBJ) == PK_PUBKEY_OBJ)
49673cc0e02Swyllys 		kclass = KMF_ASYM_PUB;
49773cc0e02Swyllys 	else if ((oclass & PK_KEY_OBJ) == PK_SYMKEY_OBJ)
49873cc0e02Swyllys 		kclass = KMF_SYMMETRIC;
49973cc0e02Swyllys 	else /* only 1 key at a time can be exported here, so default to pri */
50073cc0e02Swyllys 		kclass = KMF_ASYM_PRI;
50173cc0e02Swyllys 
50273cc0e02Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
50373cc0e02Swyllys 	    &kclass, sizeof (kclass));
50473cc0e02Swyllys 	numattr++;
50573cc0e02Swyllys 
50630a5e8faSwyllys 	rv = kmf_find_key(kmfhandle, numattr, attrlist);
50771a79fe7Swyllys 	/*
50871a79fe7Swyllys 	 * If nothing found but caller wanted ALL keys, try symmetric
50971a79fe7Swyllys 	 * this time.
51071a79fe7Swyllys 	 */
51171a79fe7Swyllys 	if (rv == KMF_ERR_KEY_NOT_FOUND && (oclass == PK_KEY_OBJ)) {
51271a79fe7Swyllys 		kclass = KMF_SYMMETRIC;
51371a79fe7Swyllys 		rv = kmf_find_key(kmfhandle, numattr, attrlist);
51471a79fe7Swyllys 	}
51571a79fe7Swyllys 	/*
51671a79fe7Swyllys 	 * If nothing found but caller wanted ALL keys, try asymmetric
51771a79fe7Swyllys 	 * public this time.
51871a79fe7Swyllys 	 */
51971a79fe7Swyllys 	if (rv == KMF_ERR_KEY_NOT_FOUND && (oclass == PK_KEY_OBJ)) {
52071a79fe7Swyllys 		kclass = KMF_ASYM_PUB;
52171a79fe7Swyllys 		rv = kmf_find_key(kmfhandle, numattr, attrlist);
52271a79fe7Swyllys 	}
52330a5e8faSwyllys 	if (rv == KMF_OK && key.keyclass == KMF_SYMMETRIC) {
52430a5e8faSwyllys 		KMF_RAW_SYM_KEY rkey;
52530a5e8faSwyllys 
52630a5e8faSwyllys 		(void) memset(&rkey, 0, sizeof (KMF_RAW_SYM_KEY));
52730a5e8faSwyllys 		rv = kmf_get_sym_key_value(kmfhandle, &key, &rkey);
52830a5e8faSwyllys 		if (rv == KMF_OK) {
52930a5e8faSwyllys 			int fd, n, total = 0;
53030a5e8faSwyllys 
53130a5e8faSwyllys 			fd = open(filename, O_CREAT | O_RDWR |O_TRUNC, 0600);
53230a5e8faSwyllys 			if (fd == -1) {
53330a5e8faSwyllys 				rv = KMF_ERR_OPEN_FILE;
53430a5e8faSwyllys 				goto done;
53530a5e8faSwyllys 			}
53630a5e8faSwyllys 			do {
53730a5e8faSwyllys 				n = write(fd, rkey.keydata.val + total,
53830a5e8faSwyllys 				    rkey.keydata.len - total);
53930a5e8faSwyllys 				if (n < 0) {
54030a5e8faSwyllys 					if (errno == EINTR)
54130a5e8faSwyllys 						continue;
54246d33f7eSwyllys 					(void) close(fd);
54330a5e8faSwyllys 					rv = KMF_ERR_WRITE_FILE;
54430a5e8faSwyllys 					goto done;
54530a5e8faSwyllys 				}
54630a5e8faSwyllys 				total += n;
54730a5e8faSwyllys 
54830a5e8faSwyllys 			} while (total < rkey.keydata.len);
54946d33f7eSwyllys 			(void) close(fd);
55030a5e8faSwyllys 		}
55130a5e8faSwyllys done:
55230a5e8faSwyllys 		kmf_free_bigint(&rkey.keydata);
55330a5e8faSwyllys 		kmf_free_kmf_key(kmfhandle, &key);
55430a5e8faSwyllys 	} else if (rv == KMF_OK) {
55530a5e8faSwyllys 		KMF_KEYSTORE_TYPE sslks = KMF_KEYSTORE_OPENSSL;
55646d33f7eSwyllys 		(void) printf(gettext("Found %d asymmetric keys\n"), numkeys);
55730a5e8faSwyllys 
55830a5e8faSwyllys 		numattr = 0;
55930a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
56030a5e8faSwyllys 		    &sslks, sizeof (sslks));
56130a5e8faSwyllys 		numattr++;
56230a5e8faSwyllys 
56330a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
56430a5e8faSwyllys 		    key.keyp, sizeof (KMF_RAW_KEY_DATA));
56530a5e8faSwyllys 		numattr++;
56630a5e8faSwyllys 
56730a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
56830a5e8faSwyllys 		    &format, sizeof (format));
56930a5e8faSwyllys 		numattr++;
57030a5e8faSwyllys 
57130a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
57230a5e8faSwyllys 		    filename, strlen(filename));
57330a5e8faSwyllys 		numattr++;
57430a5e8faSwyllys 
57573cc0e02Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
57673cc0e02Swyllys 		    &key.keyclass, sizeof (KMF_KEY_CLASS));
57773cc0e02Swyllys 		numattr++;
57873cc0e02Swyllys 
57930a5e8faSwyllys 		rv = kmf_store_key(kmfhandle, numattr, attrlist);
58030a5e8faSwyllys 		kmf_free_kmf_key(kmfhandle, &key);
58130a5e8faSwyllys 	}
5827711facfSdinak 
58399ebb4caSwyllys 	return (rv);
5847711facfSdinak }
5857711facfSdinak 
58699ebb4caSwyllys 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)58799ebb4caSwyllys pk_export_pk11_objects(KMF_HANDLE_T kmfhandle, char *token_spec,
588592106a2SWyllys Ingersoll 	KMF_CREDENTIAL *cred, char *certlabel, char *issuer, char *subject,
58999ebb4caSwyllys 	KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt,
59099ebb4caSwyllys 	char *filename)
5917711facfSdinak {
59299ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
59399ebb4caSwyllys 	KMF_X509_DER_CERT kmfcert;
59430a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
59530a5e8faSwyllys 	int numattr = 0;
59630a5e8faSwyllys 	KMF_ATTRIBUTE attrlist[16];
5977711facfSdinak 
59899ebb4caSwyllys 	rv = select_token(kmfhandle, token_spec, TRUE);
5997711facfSdinak 
600592106a2SWyllys Ingersoll 	if (rv != KMF_OK)
6017711facfSdinak 		return (rv);
6027711facfSdinak 
60330a5e8faSwyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
60430a5e8faSwyllys 	    &kstype, sizeof (kstype));
60530a5e8faSwyllys 	numattr++;
6067711facfSdinak 
607592106a2SWyllys Ingersoll 	if (cred != NULL) {
608592106a2SWyllys Ingersoll 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
609592106a2SWyllys Ingersoll 		    cred, sizeof (KMF_CREDENTIAL));
610592106a2SWyllys Ingersoll 		numattr++;
611592106a2SWyllys Ingersoll 	}
61230a5e8faSwyllys 	if (certlabel != NULL) {
61330a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
61430a5e8faSwyllys 		    KMF_CERT_LABEL_ATTR, certlabel,
61530a5e8faSwyllys 		    strlen(certlabel));
61630a5e8faSwyllys 		numattr++;
61730a5e8faSwyllys 	}
61830a5e8faSwyllys 
61930a5e8faSwyllys 	if (issuer != NULL) {
62030a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
62130a5e8faSwyllys 		    KMF_ISSUER_NAME_ATTR, issuer,
62230a5e8faSwyllys 		    strlen(issuer));
62330a5e8faSwyllys 		numattr++;
62430a5e8faSwyllys 	}
62530a5e8faSwyllys 
62630a5e8faSwyllys 	if (subject != NULL) {
62730a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
62830a5e8faSwyllys 		    KMF_SUBJECT_NAME_ATTR, subject,
62930a5e8faSwyllys 		    strlen(subject));
63030a5e8faSwyllys 		numattr++;
63130a5e8faSwyllys 	}
63230a5e8faSwyllys 
63330a5e8faSwyllys 	if (serial != NULL) {
63430a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
63530a5e8faSwyllys 		    KMF_BIGINT_ATTR, serial,
63630a5e8faSwyllys 		    sizeof (KMF_BIGINT));
63730a5e8faSwyllys 		numattr++;
63830a5e8faSwyllys 	}
63930a5e8faSwyllys 
64030a5e8faSwyllys 	rv = pk_find_export_cert(kmfhandle, attrlist, numattr, &kmfcert);
6417711facfSdinak 
64299ebb4caSwyllys 	if (rv == KMF_OK) {
64330a5e8faSwyllys 		kstype = KMF_KEYSTORE_OPENSSL;
64430a5e8faSwyllys 		numattr = 0;
64530a5e8faSwyllys 
64630a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
64730a5e8faSwyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
64830a5e8faSwyllys 		numattr++;
64930a5e8faSwyllys 
65030a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
65130a5e8faSwyllys 		    KMF_CERT_DATA_ATTR, &kmfcert.certificate,
65230a5e8faSwyllys 		    sizeof (KMF_DATA));
65330a5e8faSwyllys 		numattr++;
65430a5e8faSwyllys 
65530a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
65630a5e8faSwyllys 		    KMF_CERT_FILENAME_ATTR, filename, strlen(filename));
65730a5e8faSwyllys 		numattr++;
65830a5e8faSwyllys 
65930a5e8faSwyllys 		kmf_set_attr_at_index(attrlist, numattr,
66030a5e8faSwyllys 		    KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt));
66130a5e8faSwyllys 		numattr++;
6627711facfSdinak 
66330a5e8faSwyllys 		rv = kmf_store_cert(kmfhandle, numattr, attrlist);
6647711facfSdinak 
66530a5e8faSwyllys 		kmf_free_kmf_cert(kmfhandle, &kmfcert);
6667711facfSdinak 	}
66799ebb4caSwyllys 	return (rv);
6687711facfSdinak }
6697711facfSdinak 
6707711facfSdinak /*
67199ebb4caSwyllys  * Export objects from one keystore to a file.
672