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.
22*33f5ff17SMilan 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>
4299ebb4caSwyllys
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) {
5999ebb4caSwyllys return (rv);
6099ebb4caSwyllys }
6199ebb4caSwyllys if (numcerts == 0) {
6299ebb4caSwyllys cryptoerror(LOG_STDERR,
6399ebb4caSwyllys 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,
7599ebb4caSwyllys gettext("%d certificates found, refine the "
7699ebb4caSwyllys "search parameters to eliminate ambiguity\n"),
7799ebb4caSwyllys numcerts);
7899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER);
7999ebb4caSwyllys }
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];
937711facfSdinak
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++;
1007711facfSdinak
10130a5e8faSwyllys if (issuer != NULL) {
10230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr,
10330a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer,
10430a5e8faSwyllys strlen(issuer));
10530a5e8faSwyllys numattr++;
10630a5e8faSwyllys }
10799ebb4caSwyllys
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 }
1557711facfSdinak 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;
16730a5e8faSwyllys 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)
17399ebb4caSwyllys 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++;
1827711facfSdinak
18330a5e8faSwyllys if (certlabel != NULL) {
18430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr,
18530a5e8faSwyllys KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
18630a5e8faSwyllys numattr++;
18730a5e8faSwyllys }
18899ebb4caSwyllys
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 }
20030a5e8faSwyllys
20130a5e8faSwyllys if (serial != NULL) {
20230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr,
20330a5e8faSwyllys KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
20430a5e8faSwyllys numattr++;
20530a5e8faSwyllys }
20630a5e8faSwyllys
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);
23099ebb4caSwyllys
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;
24130a5e8faSwyllys KMF_CREDENTIAL p12cred = { NULL, 0 };
24230a5e8faSwyllys KMF_ATTRIBUTE attrlist[16];
24330a5e8faSwyllys int numattr = 0;
2447711facfSdinak
24530a5e8faSwyllys kstype = KMF_KEYSTORE_OPENSSL;
24630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr,
24730a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
24830a5e8faSwyllys numattr++;
2497711facfSdinak
25030a5e8faSwyllys if (certfile != NULL) {
25130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr,
25230a5e8faSwyllys KMF_CERT_FILENAME_ATTR, certfile, strlen(certfile));
25330a5e8faSwyllys numattr++;
25430a5e8faSwyllys }
25599ebb4caSwyllys
25630a5e8faSwyllys if (keyfile != NULL) {
25730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr,
25830a5e8faSwyllys KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
25930a5e8faSwyllys numattr++;
26030a5e8faSwyllys }
26199ebb4caSwyllys
26230a5e8faSwyllys (void) get_pk12_password(&p12cred);
26330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr,
26430a5e8faSwyllys KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
26530a5e8faSwyllys numattr++;
26630a5e8faSwyllys
26730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr,
26830a5e8faSwyllys KMF_OUTPUT_FILENAME_ATTR, outfile, strlen(outfile));
26930a5e8faSwyllys numattr++;
27030a5e8faSwyllys
27130a5e8faSwyllys rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
27230a5e8faSwyllys
27330a5e8faSwyllys if (p12cred.cred)
27430a5e8faSwyllys free(p12cred.cred);
27599ebb4caSwyllys
2767711facfSdinak 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)
29399ebb4caSwyllys 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++;
30199ebb4caSwyllys
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 }
31530a5e8faSwyllys
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;
34299ebb4caSwyllys
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++;
35130a5e8faSwyllys
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 }
36599ebb4caSwyllys }
3667711facfSdinak return (rv);
3677711facfSdinak }
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)
3737711facfSdinak {
37499ebb4caSwyllys KMF_RETURN rv = KMF_OK;
37530a5e8faSwyllys KMF_KEYSTORE_TYPE kstype;
37630a5e8faSwyllys 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) {
3827711facfSdinak 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++;
3897711facfSdinak
39030a5e8faSwyllys if (certlabel != NULL) {
39130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr,
39230a5e8faSwyllys KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
39330a5e8faSwyllys numattr++;
39430a5e8faSwyllys }
39599ebb4caSwyllys
39630a5e8faSwyllys if (issuer != NULL) {
39730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr,
39830a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
39930a5e8faSwyllys numattr++;
40030a5e8faSwyllys }
40199ebb4caSwyllys
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++;
47930a5e8faSwyllys
48030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
48130a5e8faSwyllys &key, sizeof (key));
48230a5e8faSwyllys numattr++;
48330a5e8faSwyllys
48430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR,
48530a5e8faSwyllys &is_token, sizeof (is_token));
48630a5e8faSwyllys numattr++;
48730a5e8faSwyllys
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 }
58299ebb4caSwyllys
5837711facfSdinak 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;
6457711facfSdinak
64630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr,
64730a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
64830a5e8faSwyllys numattr++;
6497711facfSdinak
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++;
66230a5e8faSwyllys
66330a5e8faSwyllys rv = kmf_store_cert(kmfhandle, numattr, attrlist);
66430a5e8faSwyllys
66530a5e8faSwyllys kmf_free_kmf_cert(kmfhandle, &kmfcert);
6667711facfSdinak }
6677711facfSdinak return (rv);
6687711facfSdinak }
6697711facfSdinak
6707711facfSdinak /*
67199ebb4caSwyllys * Export objects from one keystore to a file.
6727711facfSdinak */
6737711facfSdinak int
pk_export(int argc,char * argv[])6747711facfSdinak pk_export(int argc, char *argv[])
6757711facfSdinak {
67649e21299Sdinak int opt;
67749e21299Sdinak extern int optind_av;
67849e21299Sdinak extern char *optarg_av;
67949e21299Sdinak char *token_spec = NULL;
6807711facfSdinak char *filename = NULL;
68199ebb4caSwyllys char *dir = NULL;
68299ebb4caSwyllys char *prefix = NULL;
68399ebb4caSwyllys char *certlabel = NULL;
68499ebb4caSwyllys char *subject = NULL;
68599ebb4caSwyllys char *issuer = NULL;
68699ebb4caSwyllys char *infile = NULL;
68799ebb4caSwyllys char *keyfile = NULL;
68899ebb4caSwyllys char *certfile = NULL;
68999ebb4caSwyllys char *serstr = NULL;
69099ebb4caSwyllys KMF_KEYSTORE_TYPE kstype = 0;
69199ebb4caSwyllys KMF_ENCODE_FORMAT kfmt = KMF_FORMAT_PKCS12;
69299ebb4caSwyllys KMF_RETURN rv = KMF_OK;
69399ebb4caSwyllys int oclass = PK_CERT_OBJ;
69499ebb4caSwyllys KMF_BIGINT serial = { NULL, 0 };
69599ebb4caSwyllys KMF_HANDLE_T kmfhandle = NULL;
69699ebb4caSwyllys KMF_CREDENTIAL tokencred = { NULL, 0 };
6977711facfSdinak
69849e21299Sdinak /* Parse command line options. Do NOT i18n/l10n. */
69999ebb4caSwyllys while ((opt = getopt_av(argc, argv,
70099ebb4caSwyllys "k:(keystore)y:(objtype)T:(token)"
70199ebb4caSwyllys "d:(dir)p:(prefix)"
70299ebb4caSwyllys "l:(label)n:(nickname)s:(subject)"
70399ebb4caSwyllys "i:(issuer)S:(serial)"
70499ebb4caSwyllys "K:(keyfile)c:(certfile)"
70599ebb4caSwyllys "F:(outformat)"
70699ebb4caSwyllys "I:(infile)o:(outfile)")) != EOF) {
70799ebb4caSwyllys if (EMPTYSTRING(optarg_av))
70899ebb4caSwyllys return (PK_ERR_USAGE);
70949e21299Sdinak switch (opt) {
71099ebb4caSwyllys case 'k':
71199ebb4caSwyllys kstype = KS2Int(optarg_av);
71299ebb4caSwyllys if (kstype == 0)
71399ebb4caSwyllys return (PK_ERR_USAGE);
71499ebb4caSwyllys break;
71599ebb4caSwyllys case 'y':
71699ebb4caSwyllys oclass = OT2Int(optarg_av);
71799ebb4caSwyllys if (oclass == -1)
71899ebb4caSwyllys return (PK_ERR_USAGE);
71999ebb4caSwyllys break;
72049e21299Sdinak case 'T': /* token specifier */
72149e21299Sdinak if (token_spec)
72249e21299Sdinak return (PK_ERR_USAGE);
72349e21299Sdinak token_spec = optarg_av;
72449e21299Sdinak break;
72599ebb4caSwyllys case 'd':
72699ebb4caSwyllys if (dir)
72799ebb4caSwyllys return (PK_ERR_USAGE);
72899ebb4caSwyllys dir = optarg_av;
72999ebb4caSwyllys break;
73099ebb4caSwyllys case 'p':
73199ebb4caSwyllys if (prefix)
73299ebb4caSwyllys return (PK_ERR_USAGE);
73399ebb4caSwyllys prefix = optarg_av;
73499ebb4caSwyllys break;
73599ebb4caSwyllys case 'n':
73699ebb4caSwyllys case 'l':
73799ebb4caSwyllys if (certlabel)
73899ebb4caSwyllys return (PK_ERR_USAGE);
73999ebb4caSwyllys certlabel = optarg_av;
74099ebb4caSwyllys break;
74199ebb4caSwyllys case 's':
74299ebb4caSwyllys if (subject)
74399ebb4caSwyllys return (PK_ERR_USAGE);
74499ebb4caSwyllys subject = optarg_av;
74599ebb4caSwyllys break;
74699ebb4caSwyllys case 'i':
74799ebb4caSwyllys if (issuer)
74899ebb4caSwyllys return (PK_ERR_USAGE);
74999ebb4caSwyllys issuer = optarg_av;
75099ebb4caSwyllys break;
75199ebb4caSwyllys case 'S':
75299ebb4caSwyllys serstr = optarg_av;
75399ebb4caSwyllys break;
75499ebb4caSwyllys case 'F':
75599ebb4caSwyllys kfmt = Str2Format(optarg_av);
75699ebb4caSwyllys if (kfmt == KMF_FORMAT_UNDEF)
75799ebb4caSwyllys return (PK_ERR_USAGE);
75899ebb4caSwyllys break;
75999ebb4caSwyllys case 'I': /* output file name */
76099ebb4caSwyllys if (infile)
76199ebb4caSwyllys return (PK_ERR_USAGE);
76299ebb4caSwyllys infile = optarg_av;
76399ebb4caSwyllys break;
76449e21299Sdinak case 'o': /* output file name */
76549e21299Sdinak if (filename)
76649e21299Sdinak return (PK_ERR_USAGE);
76749e21299Sdinak filename = optarg_av;
76849e21299Sdinak break;
76999ebb4caSwyllys case 'c': /* input cert file name */
77099ebb4caSwyllys if (certfile)
77199ebb4caSwyllys return (PK_ERR_USAGE);
77299ebb4caSwyllys certfile = optarg_av;
77399ebb4caSwyllys break;
77499ebb4caSwyllys case 'K': /* input key file name */
77599ebb4caSwyllys if (keyfile)
77699ebb4caSwyllys return (PK_ERR_USAGE);
77799ebb4caSwyllys keyfile = optarg_av;
77899ebb4caSwyllys break;
77949e21299Sdinak default:
78049e21299Sdinak return (PK_ERR_USAGE);
78149e21299Sdinak }
78249e21299Sdinak }
7837711facfSdinak
78499ebb4caSwyllys /* Assume keystore = PKCS#11 if not specified */
78599ebb4caSwyllys if (kstype == 0)
78699ebb4caSwyllys kstype = KMF_KEYSTORE_PK11TOKEN;
78749e21299Sdinak
78849e21299Sdinak /* Filename arg is required. */
78999ebb4caSwyllys if (EMPTYSTRING(filename)) {
79099ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("You must specify "
79199ebb4caSwyllys "an 'outfile' parameter when exporting.\n"));
7927711facfSdinak return (PK_ERR_USAGE);
79399ebb4caSwyllys }
7947711facfSdinak
79549e21299Sdinak /* No additional args allowed. */
79649e21299Sdinak argc -= optind_av;
79749e21299Sdinak argv += optind_av;
79849e21299Sdinak if (argc)
79949e21299Sdinak return (PK_ERR_USAGE);
80099ebb4caSwyllys
801577f4726Swyllys DIR_OPTION_CHECK(kstype, dir);
802577f4726Swyllys
80399ebb4caSwyllys /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
80499ebb4caSwyllys if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
80599ebb4caSwyllys kstype != KMF_KEYSTORE_PK11TOKEN) {
80699ebb4caSwyllys
80799ebb4caSwyllys (void) fprintf(stderr, gettext("The objtype parameter "
80899ebb4caSwyllys "is only relevant if keystore=pkcs11\n"));
80999ebb4caSwyllys return (PK_ERR_USAGE);
81099ebb4caSwyllys }
81199ebb4caSwyllys
81299ebb4caSwyllys if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
81399ebb4caSwyllys token_spec = PK_DEFAULT_PK11TOKEN;
81499ebb4caSwyllys else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
81599ebb4caSwyllys token_spec = DEFAULT_NSS_TOKEN;
81699ebb4caSwyllys
81799ebb4caSwyllys if (kstype == KMF_KEYSTORE_OPENSSL) {
81899ebb4caSwyllys if (kfmt != KMF_FORMAT_PKCS12) {
81999ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("PKCS12 "
82099ebb4caSwyllys "is the only export format "
82199ebb4caSwyllys "supported for the 'file' "
82299ebb4caSwyllys "keystore.\n"));
82399ebb4caSwyllys return (PK_ERR_USAGE);
82499ebb4caSwyllys }
82599ebb4caSwyllys if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
82699ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("A cert file"
82799ebb4caSwyllys "and a key file must be specified "
82899ebb4caSwyllys "when exporting to PKCS12 from the "
82999ebb4caSwyllys "'file' keystore.\n"));
83099ebb4caSwyllys return (PK_ERR_USAGE);
83199ebb4caSwyllys }
83299ebb4caSwyllys }
8337711facfSdinak
8342c9a247fSWyllys Ingersoll /* Check if the file exists */
8352c9a247fSWyllys Ingersoll if (verify_file(filename) != KMF_OK) {
83699ebb4caSwyllys cryptoerror(LOG_STDERR,
83799ebb4caSwyllys gettext("Warning: file \"%s\" exists, "
8387711facfSdinak "will be overwritten."), filename);
8397711facfSdinak if (yesno(gettext("Continue with export? "),
8407711facfSdinak gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) {
8417711facfSdinak return (0);
84273cc0e02Swyllys } else {
84373cc0e02Swyllys /* remove the file */
84473cc0e02Swyllys (void) unlink(filename);
8457711facfSdinak }
8467711facfSdinak }
8477711facfSdinak
84899ebb4caSwyllys if (serstr != NULL) {
84999ebb4caSwyllys uchar_t *bytes = NULL;
85099ebb4caSwyllys size_t bytelen;
8517711facfSdinak
85230a5e8faSwyllys rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
85399ebb4caSwyllys if (rv != KMF_OK || bytes == NULL) {
85499ebb4caSwyllys (void) fprintf(stderr, gettext("serial number "
85599ebb4caSwyllys "must be specified as a hex number "
85699ebb4caSwyllys "(ex: 0x0102030405ffeeddee)\n"));
85799ebb4caSwyllys return (PK_ERR_USAGE);
85899ebb4caSwyllys }
85999ebb4caSwyllys serial.val = bytes;
86099ebb4caSwyllys serial.len = bytelen;
8617711facfSdinak }
8627711facfSdinak
863ab8b4e5cSWyllys Ingersoll /*
864ab8b4e5cSWyllys Ingersoll * We need a password in the following situations:
865ab8b4e5cSWyllys Ingersoll * 1. When accessing PKCS11 token
866ab8b4e5cSWyllys Ingersoll * 2. If NSS keystore, when making a PKCS12 file or when
867ab8b4e5cSWyllys Ingersoll * accessing any private object or key.
868ab8b4e5cSWyllys Ingersoll */
869592106a2SWyllys Ingersoll if (kstype == KMF_KEYSTORE_PK11TOKEN ||
870592106a2SWyllys Ingersoll ((kstype == KMF_KEYSTORE_NSS) &&
871ab8b4e5cSWyllys Ingersoll ((oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ)) ||
872ab8b4e5cSWyllys Ingersoll (kfmt == KMF_FORMAT_PKCS12)))) {
87399ebb4caSwyllys (void) get_token_password(kstype, token_spec,
87499ebb4caSwyllys &tokencred);
8757711facfSdinak }
8767711facfSdinak
87730a5e8faSwyllys if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
87899ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Error initializing "
87999ebb4caSwyllys "KMF: 0x%02x\n"), rv);
88099ebb4caSwyllys return (rv);
8817711facfSdinak }
8827711facfSdinak
88399ebb4caSwyllys switch (kstype) {
88499ebb4caSwyllys case KMF_KEYSTORE_PK11TOKEN:
88599ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12)
88630a5e8faSwyllys rv = pk_export_pk12_pk11(kmfhandle,
88730a5e8faSwyllys token_spec, certlabel,
88899ebb4caSwyllys issuer, subject,
88999ebb4caSwyllys &serial, &tokencred,
89099ebb4caSwyllys filename);
89130a5e8faSwyllys else if ((oclass & PK_KEY_OBJ) ||
89230a5e8faSwyllys kfmt == KMF_FORMAT_RAWKEY)
89330a5e8faSwyllys rv = pk_export_pk11_keys(kmfhandle,
89430a5e8faSwyllys token_spec, &tokencred, kfmt,
89573cc0e02Swyllys certlabel, filename, oclass);
8967711facfSdinak else
89799ebb4caSwyllys rv = pk_export_pk11_objects(kmfhandle,
898592106a2SWyllys Ingersoll token_spec, &tokencred, certlabel,
89930a5e8faSwyllys issuer, subject, &serial, kfmt,
90099ebb4caSwyllys filename);
90199ebb4caSwyllys break;
90299ebb4caSwyllys case KMF_KEYSTORE_NSS:
90399ebb4caSwyllys if (dir == NULL)
90499ebb4caSwyllys dir = PK_DEFAULT_DIRECTORY;
90599ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12)
90699ebb4caSwyllys rv = pk_export_pk12_nss(kmfhandle,
90799ebb4caSwyllys token_spec, dir, prefix,
90899ebb4caSwyllys certlabel, issuer,
90999ebb4caSwyllys subject, &serial,
91099ebb4caSwyllys &tokencred, filename);
91199ebb4caSwyllys else
91299ebb4caSwyllys rv = pk_export_nss_objects(kmfhandle,
91399ebb4caSwyllys token_spec,
91499ebb4caSwyllys oclass, certlabel, issuer, subject,
91599ebb4caSwyllys &serial, kfmt, dir, prefix, filename);
91699ebb4caSwyllys break;
91799ebb4caSwyllys case KMF_KEYSTORE_OPENSSL:
91899ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12)
91999ebb4caSwyllys rv = pk_export_pk12_files(kmfhandle,
920448b8615Swyllys certfile, keyfile, filename);
92199ebb4caSwyllys else
92299ebb4caSwyllys rv = pk_export_file_objects(kmfhandle, oclass,
92330a5e8faSwyllys issuer, subject, &serial,
924448b8615Swyllys infile, filename);
92599ebb4caSwyllys break;
92699ebb4caSwyllys default:
92799ebb4caSwyllys rv = PK_ERR_USAGE;
92899ebb4caSwyllys break;
9297711facfSdinak }
9307711facfSdinak
93199ebb4caSwyllys if (rv != KMF_OK) {
93299ebb4caSwyllys display_error(kmfhandle, rv,
93399ebb4caSwyllys gettext("Error exporting objects"));
9347711facfSdinak }
9357711facfSdinak
93699ebb4caSwyllys if (serial.val != NULL)
93799ebb4caSwyllys free(serial.val);
9387711facfSdinak
93930a5e8faSwyllys (void) kmf_finalize(kmfhandle);
9407711facfSdinak
94199ebb4caSwyllys return (rv);
9427711facfSdinak }
943