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 * 2199ebb4caSwyllys * 22*592106a2SWyllys Ingersoll * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237711facfSdinak * Use is subject to license terms. 247711facfSdinak */ 257711facfSdinak 267711facfSdinak /* 277711facfSdinak * This file implements the export operation for this tool. 287711facfSdinak * The basic flow of the process is to find the soft token, 297711facfSdinak * log into it, find the PKCS#11 objects in the soft token 307711facfSdinak * to be exported matching keys with their certificates, export 317711facfSdinak * them to the PKCS#12 file encrypting them with a file password 327711facfSdinak * if desired, and log out. 337711facfSdinak */ 347711facfSdinak 357711facfSdinak #include <stdio.h> 367711facfSdinak #include <stdlib.h> 377711facfSdinak #include <string.h> 387711facfSdinak #include <errno.h> 3999ebb4caSwyllys #include <fcntl.h> 407711facfSdinak #include "common.h" 417711facfSdinak 4299ebb4caSwyllys #include <kmfapi.h> 4399ebb4caSwyllys 4499ebb4caSwyllys static KMF_RETURN 4530a5e8faSwyllys pk_find_export_cert(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attrlist, 4630a5e8faSwyllys int numattr, KMF_X509_DER_CERT *cert) 477711facfSdinak { 4899ebb4caSwyllys KMF_RETURN rv = KMF_OK; 4999ebb4caSwyllys uint32_t numcerts = 0; 507711facfSdinak 5199ebb4caSwyllys numcerts = 0; 5299ebb4caSwyllys (void) memset(cert, 0, sizeof (KMF_X509_DER_CERT)); 5330a5e8faSwyllys 5430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 5530a5e8faSwyllys &numcerts, sizeof (uint32_t)); 5630a5e8faSwyllys numattr++; 5730a5e8faSwyllys 5830a5e8faSwyllys rv = kmf_find_cert(kmfhandle, numattr, attrlist); 5999ebb4caSwyllys if (rv != KMF_OK) { 6099ebb4caSwyllys return (rv); 6199ebb4caSwyllys } 6299ebb4caSwyllys if (numcerts == 0) { 6399ebb4caSwyllys cryptoerror(LOG_STDERR, 6499ebb4caSwyllys gettext("No matching certificates found.")); 6599ebb4caSwyllys return (KMF_ERR_CERT_NOT_FOUND); 667711facfSdinak 6799ebb4caSwyllys } else if (numcerts == 1) { 6830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 6930a5e8faSwyllys KMF_X509_DER_CERT_ATTR, cert, 7030a5e8faSwyllys sizeof (KMF_X509_DER_CERT)); 7130a5e8faSwyllys numattr++; 7230a5e8faSwyllys rv = kmf_find_cert(kmfhandle, numattr, attrlist); 737711facfSdinak 7499ebb4caSwyllys } else if (numcerts > 1) { 7599ebb4caSwyllys cryptoerror(LOG_STDERR, 7699ebb4caSwyllys gettext("%d certificates found, refine the " 7799ebb4caSwyllys "search parameters to eliminate ambiguity\n"), 7899ebb4caSwyllys numcerts); 7999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 8099ebb4caSwyllys } 8199ebb4caSwyllys return (rv); 827711facfSdinak } 837711facfSdinak 8499ebb4caSwyllys static KMF_RETURN 8599ebb4caSwyllys pk_export_file_objects(KMF_HANDLE_T kmfhandle, int oclass, 8699ebb4caSwyllys char *issuer, char *subject, KMF_BIGINT *serial, 87448b8615Swyllys char *infile, char *filename) 887711facfSdinak { 8999ebb4caSwyllys KMF_RETURN rv = KMF_OK; 9099ebb4caSwyllys KMF_X509_DER_CERT kmfcert; 9130a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 9230a5e8faSwyllys int numattr = 0; 9330a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 947711facfSdinak 9599ebb4caSwyllys /* If searching for public objects or certificates, find certs now */ 9699ebb4caSwyllys if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) { 9730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 9830a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 9930a5e8faSwyllys sizeof (kstype)); 10030a5e8faSwyllys numattr++; 1017711facfSdinak 10230a5e8faSwyllys if (issuer != NULL) { 10330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 10430a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, 10530a5e8faSwyllys strlen(issuer)); 10630a5e8faSwyllys numattr++; 10730a5e8faSwyllys } 10899ebb4caSwyllys 10930a5e8faSwyllys if (subject != NULL) { 11030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 11130a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, 11230a5e8faSwyllys strlen(subject)); 11330a5e8faSwyllys numattr++; 11430a5e8faSwyllys } 11530a5e8faSwyllys 11630a5e8faSwyllys if (serial != NULL) { 11730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 11830a5e8faSwyllys KMF_BIGINT_ATTR, serial, 11930a5e8faSwyllys sizeof (KMF_BIGINT)); 12030a5e8faSwyllys numattr++; 12130a5e8faSwyllys } 12230a5e8faSwyllys 12330a5e8faSwyllys if (infile != NULL) { 12430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 12530a5e8faSwyllys KMF_CERT_FILENAME_ATTR, infile, 12630a5e8faSwyllys strlen(infile)); 12730a5e8faSwyllys numattr++; 12830a5e8faSwyllys } 12930a5e8faSwyllys 13030a5e8faSwyllys rv = pk_find_export_cert(kmfhandle, attrlist, numattr, 13130a5e8faSwyllys &kmfcert); 13299ebb4caSwyllys if (rv == KMF_OK) { 13330a5e8faSwyllys kstype = KMF_KEYSTORE_OPENSSL; 13430a5e8faSwyllys numattr = 0; 13599ebb4caSwyllys 13630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 13730a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 13830a5e8faSwyllys numattr++; 13930a5e8faSwyllys 14030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 14130a5e8faSwyllys KMF_CERT_DATA_ATTR, &kmfcert.certificate, 14230a5e8faSwyllys sizeof (KMF_DATA)); 14330a5e8faSwyllys numattr++; 14430a5e8faSwyllys 14530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 14630a5e8faSwyllys KMF_CERT_FILENAME_ATTR, filename, 14730a5e8faSwyllys strlen(filename)); 14830a5e8faSwyllys numattr++; 14930a5e8faSwyllys 15030a5e8faSwyllys rv = kmf_store_cert(kmfhandle, numattr, 15130a5e8faSwyllys attrlist); 15230a5e8faSwyllys 15330a5e8faSwyllys kmf_free_kmf_cert(kmfhandle, &kmfcert); 15499ebb4caSwyllys } 15599ebb4caSwyllys } 1567711facfSdinak return (rv); 1577711facfSdinak } 1587711facfSdinak 15999ebb4caSwyllys static KMF_RETURN 16099ebb4caSwyllys pk_export_pk12_nss(KMF_HANDLE_T kmfhandle, 16199ebb4caSwyllys char *token_spec, char *dir, char *prefix, 16299ebb4caSwyllys char *certlabel, char *issuer, char *subject, 16399ebb4caSwyllys KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, 16499ebb4caSwyllys char *filename) 1657711facfSdinak { 16699ebb4caSwyllys KMF_RETURN rv = KMF_OK; 16730a5e8faSwyllys KMF_KEYSTORE_TYPE kstype; 16830a5e8faSwyllys KMF_CREDENTIAL p12cred = { NULL, 0}; 16930a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 17030a5e8faSwyllys int numattr = 0; 1717711facfSdinak 17299ebb4caSwyllys rv = configure_nss(kmfhandle, dir, prefix); 17399ebb4caSwyllys if (rv != KMF_OK) 17499ebb4caSwyllys return (rv); 1757711facfSdinak 17699ebb4caSwyllys if (token_spec == NULL) 17799ebb4caSwyllys token_spec = DEFAULT_NSS_TOKEN; 1787711facfSdinak 17930a5e8faSwyllys kstype = KMF_KEYSTORE_NSS; 18030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 18130a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 18230a5e8faSwyllys numattr++; 1837711facfSdinak 18430a5e8faSwyllys if (certlabel != NULL) { 18530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 18630a5e8faSwyllys KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); 18730a5e8faSwyllys numattr++; 18830a5e8faSwyllys } 18999ebb4caSwyllys 19030a5e8faSwyllys if (issuer != NULL) { 19130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 19230a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); 19330a5e8faSwyllys numattr++; 19430a5e8faSwyllys } 19530a5e8faSwyllys 19630a5e8faSwyllys if (subject != NULL) { 19730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 19830a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); 19930a5e8faSwyllys numattr++; 20030a5e8faSwyllys } 20130a5e8faSwyllys 20230a5e8faSwyllys if (serial != NULL) { 20330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 20430a5e8faSwyllys KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); 20530a5e8faSwyllys numattr++; 20630a5e8faSwyllys } 20730a5e8faSwyllys 20830a5e8faSwyllys if (tokencred != NULL) { 20930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 21030a5e8faSwyllys KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); 21130a5e8faSwyllys numattr++; 21230a5e8faSwyllys } 21330a5e8faSwyllys 21430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 21530a5e8faSwyllys token_spec, strlen(token_spec)); 21630a5e8faSwyllys numattr++; 21730a5e8faSwyllys 21830a5e8faSwyllys (void) get_pk12_password(&p12cred); 21930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 22030a5e8faSwyllys KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); 22130a5e8faSwyllys numattr++; 22230a5e8faSwyllys 22330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 22430a5e8faSwyllys KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename)); 22530a5e8faSwyllys numattr++; 22630a5e8faSwyllys 22730a5e8faSwyllys rv = kmf_export_pk12(kmfhandle, numattr, attrlist); 22830a5e8faSwyllys 22930a5e8faSwyllys if (p12cred.cred) 23030a5e8faSwyllys free(p12cred.cred); 23199ebb4caSwyllys 23299ebb4caSwyllys return (rv); 2337711facfSdinak } 2347711facfSdinak 23599ebb4caSwyllys static KMF_RETURN 23699ebb4caSwyllys pk_export_pk12_files(KMF_HANDLE_T kmfhandle, 237448b8615Swyllys char *certfile, char *keyfile, 23899ebb4caSwyllys char *outfile) 2397711facfSdinak { 24099ebb4caSwyllys KMF_RETURN rv; 24130a5e8faSwyllys KMF_KEYSTORE_TYPE kstype; 24230a5e8faSwyllys KMF_CREDENTIAL p12cred = { NULL, 0}; 24330a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 24430a5e8faSwyllys int numattr = 0; 2457711facfSdinak 24630a5e8faSwyllys kstype = KMF_KEYSTORE_OPENSSL; 24730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 24830a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 24930a5e8faSwyllys numattr++; 2507711facfSdinak 25130a5e8faSwyllys if (certfile != NULL) { 25230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 25330a5e8faSwyllys KMF_CERT_FILENAME_ATTR, certfile, strlen(certfile)); 25430a5e8faSwyllys numattr++; 25530a5e8faSwyllys } 25699ebb4caSwyllys 25730a5e8faSwyllys if (keyfile != NULL) { 25830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 25930a5e8faSwyllys KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile)); 26030a5e8faSwyllys numattr++; 26130a5e8faSwyllys } 26299ebb4caSwyllys 26330a5e8faSwyllys (void) get_pk12_password(&p12cred); 26430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 26530a5e8faSwyllys KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); 26630a5e8faSwyllys numattr++; 26730a5e8faSwyllys 26830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 26930a5e8faSwyllys KMF_OUTPUT_FILENAME_ATTR, outfile, strlen(outfile)); 27030a5e8faSwyllys numattr++; 27130a5e8faSwyllys 27230a5e8faSwyllys rv = kmf_export_pk12(kmfhandle, numattr, attrlist); 27330a5e8faSwyllys 27430a5e8faSwyllys if (p12cred.cred) 27530a5e8faSwyllys free(p12cred.cred); 27699ebb4caSwyllys 2777711facfSdinak return (rv); 2787711facfSdinak } 2797711facfSdinak 28099ebb4caSwyllys static KMF_RETURN 28199ebb4caSwyllys pk_export_nss_objects(KMF_HANDLE_T kmfhandle, char *token_spec, 28299ebb4caSwyllys int oclass, char *certlabel, char *issuer, char *subject, 28399ebb4caSwyllys KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, char *dir, 28499ebb4caSwyllys char *prefix, char *filename) 2857711facfSdinak { 28699ebb4caSwyllys KMF_RETURN rv = KMF_OK; 28799ebb4caSwyllys KMF_X509_DER_CERT kmfcert; 28830a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 28930a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 29030a5e8faSwyllys int numattr = 0; 2917711facfSdinak 29299ebb4caSwyllys rv = configure_nss(kmfhandle, dir, prefix); 29399ebb4caSwyllys if (rv != KMF_OK) 29499ebb4caSwyllys return (rv); 2957711facfSdinak 29699ebb4caSwyllys /* If searching for public objects or certificates, find certs now */ 29799ebb4caSwyllys if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) { 29830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 29930a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 30030a5e8faSwyllys sizeof (kstype)); 30130a5e8faSwyllys numattr++; 30299ebb4caSwyllys 30330a5e8faSwyllys if (certlabel != NULL) { 30430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 30530a5e8faSwyllys KMF_CERT_LABEL_ATTR, certlabel, 30630a5e8faSwyllys strlen(certlabel)); 30730a5e8faSwyllys numattr++; 30830a5e8faSwyllys } 30999ebb4caSwyllys 31030a5e8faSwyllys if (issuer != NULL) { 31130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 31230a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, 31330a5e8faSwyllys strlen(issuer)); 31430a5e8faSwyllys numattr++; 31530a5e8faSwyllys } 31630a5e8faSwyllys 31730a5e8faSwyllys if (subject != NULL) { 31830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 31930a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, 32030a5e8faSwyllys strlen(subject)); 32130a5e8faSwyllys numattr++; 32230a5e8faSwyllys } 32330a5e8faSwyllys 32430a5e8faSwyllys if (serial != NULL) { 32530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 32630a5e8faSwyllys KMF_BIGINT_ATTR, serial, 32730a5e8faSwyllys sizeof (KMF_BIGINT)); 32830a5e8faSwyllys numattr++; 32930a5e8faSwyllys } 33030a5e8faSwyllys 33130a5e8faSwyllys if (token_spec != NULL) { 33230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 33330a5e8faSwyllys KMF_TOKEN_LABEL_ATTR, token_spec, 33430a5e8faSwyllys strlen(token_spec)); 33530a5e8faSwyllys numattr++; 33630a5e8faSwyllys } 33730a5e8faSwyllys 33830a5e8faSwyllys rv = pk_find_export_cert(kmfhandle, attrlist, numattr, 33930a5e8faSwyllys &kmfcert); 34099ebb4caSwyllys if (rv == KMF_OK) { 34130a5e8faSwyllys kstype = KMF_KEYSTORE_OPENSSL; 34230a5e8faSwyllys numattr = 0; 34399ebb4caSwyllys 34430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 34530a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 34630a5e8faSwyllys numattr++; 34799ebb4caSwyllys 34830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 34930a5e8faSwyllys KMF_CERT_DATA_ATTR, &kmfcert.certificate, 35030a5e8faSwyllys sizeof (KMF_DATA)); 35130a5e8faSwyllys numattr++; 35230a5e8faSwyllys 35330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 35430a5e8faSwyllys KMF_CERT_FILENAME_ATTR, filename, 35530a5e8faSwyllys strlen(filename)); 35630a5e8faSwyllys numattr++; 35730a5e8faSwyllys 35830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 35930a5e8faSwyllys KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt)); 36030a5e8faSwyllys numattr++; 36130a5e8faSwyllys 36230a5e8faSwyllys rv = kmf_store_cert(kmfhandle, numattr, attrlist); 36330a5e8faSwyllys 36430a5e8faSwyllys kmf_free_kmf_cert(kmfhandle, &kmfcert); 3657711facfSdinak } 36699ebb4caSwyllys } 3677711facfSdinak return (rv); 3687711facfSdinak } 3697711facfSdinak 37099ebb4caSwyllys static KMF_RETURN 37199ebb4caSwyllys pk_export_pk12_pk11(KMF_HANDLE_T kmfhandle, char *token_spec, 37299ebb4caSwyllys char *certlabel, char *issuer, char *subject, 37399ebb4caSwyllys KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, char *filename) 3747711facfSdinak { 37599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 37630a5e8faSwyllys KMF_KEYSTORE_TYPE kstype; 37730a5e8faSwyllys KMF_CREDENTIAL p12cred = { NULL, 0}; 37830a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 37930a5e8faSwyllys int numattr = 0; 3807711facfSdinak 38199ebb4caSwyllys rv = select_token(kmfhandle, token_spec, TRUE); 38299ebb4caSwyllys if (rv != KMF_OK) { 3837711facfSdinak return (rv); 3847711facfSdinak } 3857711facfSdinak 38630a5e8faSwyllys kstype = KMF_KEYSTORE_PK11TOKEN; 38730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 38830a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 38930a5e8faSwyllys numattr++; 3907711facfSdinak 39130a5e8faSwyllys if (certlabel != NULL) { 39230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 39330a5e8faSwyllys KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); 39430a5e8faSwyllys numattr++; 39530a5e8faSwyllys } 39699ebb4caSwyllys 39730a5e8faSwyllys if (issuer != NULL) { 39830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 39930a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); 40030a5e8faSwyllys numattr++; 40130a5e8faSwyllys } 40299ebb4caSwyllys 40330a5e8faSwyllys if (subject != NULL) { 40430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 40530a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); 40630a5e8faSwyllys numattr++; 40730a5e8faSwyllys } 40830a5e8faSwyllys 40930a5e8faSwyllys if (serial != NULL) { 41030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 41130a5e8faSwyllys KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); 41230a5e8faSwyllys numattr++; 41330a5e8faSwyllys } 41430a5e8faSwyllys 41530a5e8faSwyllys if (tokencred != NULL) { 41630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 41730a5e8faSwyllys KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); 41830a5e8faSwyllys numattr++; 41930a5e8faSwyllys } 42030a5e8faSwyllys 42130a5e8faSwyllys (void) get_pk12_password(&p12cred); 42230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 42330a5e8faSwyllys KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); 42430a5e8faSwyllys numattr++; 42530a5e8faSwyllys 42630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 42730a5e8faSwyllys KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename)); 42830a5e8faSwyllys numattr++; 42930a5e8faSwyllys 43030a5e8faSwyllys rv = kmf_export_pk12(kmfhandle, numattr, attrlist); 43130a5e8faSwyllys 43230a5e8faSwyllys if (p12cred.cred) 43330a5e8faSwyllys free(p12cred.cred); 43430a5e8faSwyllys 43530a5e8faSwyllys return (rv); 43630a5e8faSwyllys } 43730a5e8faSwyllys 43830a5e8faSwyllys static KMF_RETURN 43930a5e8faSwyllys pk_export_pk11_keys(KMF_HANDLE_T kmfhandle, char *token, 44030a5e8faSwyllys KMF_CREDENTIAL *cred, KMF_ENCODE_FORMAT format, 44173cc0e02Swyllys char *label, char *filename, int oclass) 44230a5e8faSwyllys { 44330a5e8faSwyllys KMF_RETURN rv = KMF_OK; 44430a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 44573cc0e02Swyllys KMF_KEY_CLASS kclass = KMF_KEYCLASS_NONE; 44630a5e8faSwyllys int numattr = 0; 44730a5e8faSwyllys uint32_t numkeys = 1; 44830a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 44930a5e8faSwyllys KMF_KEY_HANDLE key; 45030a5e8faSwyllys boolean_t is_token = B_TRUE; 45130a5e8faSwyllys 45230a5e8faSwyllys if (EMPTYSTRING(label)) { 45330a5e8faSwyllys cryptoerror(LOG_STDERR, gettext("A label " 45430a5e8faSwyllys "must be specified to export a key.")); 45530a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 45630a5e8faSwyllys } 45730a5e8faSwyllys 45830a5e8faSwyllys rv = select_token(kmfhandle, token, TRUE); 45930a5e8faSwyllys if (rv != KMF_OK) { 46030a5e8faSwyllys return (rv); 46130a5e8faSwyllys } 46230a5e8faSwyllys 46330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 46430a5e8faSwyllys &kstype, sizeof (kstype)); 46530a5e8faSwyllys numattr++; 46630a5e8faSwyllys 46730a5e8faSwyllys if (cred != NULL) { 46830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 46930a5e8faSwyllys cred, sizeof (KMF_CREDENTIAL)); 47030a5e8faSwyllys numattr++; 47130a5e8faSwyllys } 47230a5e8faSwyllys 47330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, 47430a5e8faSwyllys label, strlen(label)); 47530a5e8faSwyllys numattr++; 47630a5e8faSwyllys 47730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 47830a5e8faSwyllys &numkeys, sizeof (numkeys)); 47930a5e8faSwyllys numattr++; 48030a5e8faSwyllys 48130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 48230a5e8faSwyllys &key, sizeof (key)); 48330a5e8faSwyllys numattr++; 48430a5e8faSwyllys 48530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR, 48630a5e8faSwyllys &is_token, sizeof (is_token)); 48730a5e8faSwyllys numattr++; 48830a5e8faSwyllys 48930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 49030a5e8faSwyllys &format, sizeof (format)); 49130a5e8faSwyllys numattr++; 49230a5e8faSwyllys 49373cc0e02Swyllys /* Check to see if we are exporting private or public only */ 49473cc0e02Swyllys if ((oclass & PK_KEY_OBJ) == PK_PRIKEY_OBJ) 49573cc0e02Swyllys kclass = KMF_ASYM_PRI; 49673cc0e02Swyllys else if ((oclass & PK_KEY_OBJ) == PK_PUBKEY_OBJ) 49773cc0e02Swyllys kclass = KMF_ASYM_PUB; 49873cc0e02Swyllys else if ((oclass & PK_KEY_OBJ) == PK_SYMKEY_OBJ) 49973cc0e02Swyllys kclass = KMF_SYMMETRIC; 50073cc0e02Swyllys else /* only 1 key at a time can be exported here, so default to pri */ 50173cc0e02Swyllys kclass = KMF_ASYM_PRI; 50273cc0e02Swyllys 50373cc0e02Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, 50473cc0e02Swyllys &kclass, sizeof (kclass)); 50573cc0e02Swyllys numattr++; 50673cc0e02Swyllys 50730a5e8faSwyllys rv = kmf_find_key(kmfhandle, numattr, attrlist); 50871a79fe7Swyllys /* 50971a79fe7Swyllys * If nothing found but caller wanted ALL keys, try symmetric 51071a79fe7Swyllys * this time. 51171a79fe7Swyllys */ 51271a79fe7Swyllys if (rv == KMF_ERR_KEY_NOT_FOUND && (oclass == PK_KEY_OBJ)) { 51371a79fe7Swyllys kclass = KMF_SYMMETRIC; 51471a79fe7Swyllys rv = kmf_find_key(kmfhandle, numattr, attrlist); 51571a79fe7Swyllys } 51671a79fe7Swyllys /* 51771a79fe7Swyllys * If nothing found but caller wanted ALL keys, try asymmetric 51871a79fe7Swyllys * public this time. 51971a79fe7Swyllys */ 52071a79fe7Swyllys if (rv == KMF_ERR_KEY_NOT_FOUND && (oclass == PK_KEY_OBJ)) { 52171a79fe7Swyllys kclass = KMF_ASYM_PUB; 52271a79fe7Swyllys rv = kmf_find_key(kmfhandle, numattr, attrlist); 52371a79fe7Swyllys } 52430a5e8faSwyllys if (rv == KMF_OK && key.keyclass == KMF_SYMMETRIC) { 52530a5e8faSwyllys KMF_RAW_SYM_KEY rkey; 52630a5e8faSwyllys 52730a5e8faSwyllys (void) memset(&rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 52830a5e8faSwyllys rv = kmf_get_sym_key_value(kmfhandle, &key, &rkey); 52930a5e8faSwyllys if (rv == KMF_OK) { 53030a5e8faSwyllys int fd, n, total = 0; 53130a5e8faSwyllys 53230a5e8faSwyllys fd = open(filename, O_CREAT | O_RDWR |O_TRUNC, 0600); 53330a5e8faSwyllys if (fd == -1) { 53430a5e8faSwyllys rv = KMF_ERR_OPEN_FILE; 53530a5e8faSwyllys goto done; 53630a5e8faSwyllys } 53730a5e8faSwyllys do { 53830a5e8faSwyllys n = write(fd, rkey.keydata.val + total, 53930a5e8faSwyllys rkey.keydata.len - total); 54030a5e8faSwyllys if (n < 0) { 54130a5e8faSwyllys if (errno == EINTR) 54230a5e8faSwyllys continue; 54346d33f7eSwyllys (void) close(fd); 54430a5e8faSwyllys rv = KMF_ERR_WRITE_FILE; 54530a5e8faSwyllys goto done; 54630a5e8faSwyllys } 54730a5e8faSwyllys total += n; 54830a5e8faSwyllys 54930a5e8faSwyllys } while (total < rkey.keydata.len); 55046d33f7eSwyllys (void) close(fd); 55130a5e8faSwyllys } 55230a5e8faSwyllys done: 55330a5e8faSwyllys kmf_free_bigint(&rkey.keydata); 55430a5e8faSwyllys kmf_free_kmf_key(kmfhandle, &key); 55530a5e8faSwyllys } else if (rv == KMF_OK) { 55630a5e8faSwyllys KMF_KEYSTORE_TYPE sslks = KMF_KEYSTORE_OPENSSL; 55746d33f7eSwyllys (void) printf(gettext("Found %d asymmetric keys\n"), numkeys); 55830a5e8faSwyllys 55930a5e8faSwyllys numattr = 0; 56030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 56130a5e8faSwyllys &sslks, sizeof (sslks)); 56230a5e8faSwyllys numattr++; 56330a5e8faSwyllys 56430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR, 56530a5e8faSwyllys key.keyp, sizeof (KMF_RAW_KEY_DATA)); 56630a5e8faSwyllys numattr++; 56730a5e8faSwyllys 56830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 56930a5e8faSwyllys &format, sizeof (format)); 57030a5e8faSwyllys numattr++; 57130a5e8faSwyllys 57230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, 57330a5e8faSwyllys filename, strlen(filename)); 57430a5e8faSwyllys numattr++; 57530a5e8faSwyllys 57673cc0e02Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, 57773cc0e02Swyllys &key.keyclass, sizeof (KMF_KEY_CLASS)); 57873cc0e02Swyllys numattr++; 57973cc0e02Swyllys 58030a5e8faSwyllys rv = kmf_store_key(kmfhandle, numattr, attrlist); 58130a5e8faSwyllys kmf_free_kmf_key(kmfhandle, &key); 58230a5e8faSwyllys } 58399ebb4caSwyllys 5847711facfSdinak return (rv); 5857711facfSdinak } 5867711facfSdinak 58799ebb4caSwyllys static KMF_RETURN 58899ebb4caSwyllys pk_export_pk11_objects(KMF_HANDLE_T kmfhandle, char *token_spec, 589*592106a2SWyllys Ingersoll KMF_CREDENTIAL *cred, char *certlabel, char *issuer, char *subject, 59099ebb4caSwyllys KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, 59199ebb4caSwyllys char *filename) 5927711facfSdinak { 59399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 59499ebb4caSwyllys KMF_X509_DER_CERT kmfcert; 59530a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 59630a5e8faSwyllys int numattr = 0; 59730a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 5987711facfSdinak 59999ebb4caSwyllys rv = select_token(kmfhandle, token_spec, TRUE); 6007711facfSdinak 601*592106a2SWyllys Ingersoll if (rv != KMF_OK) 6027711facfSdinak return (rv); 6037711facfSdinak 60430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 60530a5e8faSwyllys &kstype, sizeof (kstype)); 60630a5e8faSwyllys numattr++; 6077711facfSdinak 608*592106a2SWyllys Ingersoll if (cred != NULL) { 609*592106a2SWyllys Ingersoll kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 610*592106a2SWyllys Ingersoll cred, sizeof (KMF_CREDENTIAL)); 611*592106a2SWyllys Ingersoll numattr++; 612*592106a2SWyllys Ingersoll } 61330a5e8faSwyllys if (certlabel != NULL) { 61430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 61530a5e8faSwyllys KMF_CERT_LABEL_ATTR, certlabel, 61630a5e8faSwyllys strlen(certlabel)); 61730a5e8faSwyllys numattr++; 61830a5e8faSwyllys } 61930a5e8faSwyllys 62030a5e8faSwyllys if (issuer != NULL) { 62130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 62230a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, 62330a5e8faSwyllys strlen(issuer)); 62430a5e8faSwyllys numattr++; 62530a5e8faSwyllys } 62630a5e8faSwyllys 62730a5e8faSwyllys if (subject != NULL) { 62830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 62930a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, 63030a5e8faSwyllys strlen(subject)); 63130a5e8faSwyllys numattr++; 63230a5e8faSwyllys } 63330a5e8faSwyllys 63430a5e8faSwyllys if (serial != NULL) { 63530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 63630a5e8faSwyllys KMF_BIGINT_ATTR, serial, 63730a5e8faSwyllys sizeof (KMF_BIGINT)); 63830a5e8faSwyllys numattr++; 63930a5e8faSwyllys } 64030a5e8faSwyllys 64130a5e8faSwyllys rv = pk_find_export_cert(kmfhandle, attrlist, numattr, &kmfcert); 6427711facfSdinak 64399ebb4caSwyllys if (rv == KMF_OK) { 64430a5e8faSwyllys kstype = KMF_KEYSTORE_OPENSSL; 64530a5e8faSwyllys numattr = 0; 6467711facfSdinak 64730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 64830a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 64930a5e8faSwyllys numattr++; 6507711facfSdinak 65130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 65230a5e8faSwyllys KMF_CERT_DATA_ATTR, &kmfcert.certificate, 65330a5e8faSwyllys sizeof (KMF_DATA)); 65430a5e8faSwyllys numattr++; 65530a5e8faSwyllys 65630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 65730a5e8faSwyllys KMF_CERT_FILENAME_ATTR, filename, strlen(filename)); 65830a5e8faSwyllys numattr++; 65930a5e8faSwyllys 66030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 66130a5e8faSwyllys KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt)); 66230a5e8faSwyllys numattr++; 66330a5e8faSwyllys 66430a5e8faSwyllys rv = kmf_store_cert(kmfhandle, numattr, attrlist); 66530a5e8faSwyllys 66630a5e8faSwyllys kmf_free_kmf_cert(kmfhandle, &kmfcert); 6677711facfSdinak } 6687711facfSdinak return (rv); 6697711facfSdinak } 6707711facfSdinak 6717711facfSdinak /* 67299ebb4caSwyllys * Export objects from one keystore to a file. 6737711facfSdinak */ 6747711facfSdinak int 6757711facfSdinak pk_export(int argc, char *argv[]) 6767711facfSdinak { 67749e21299Sdinak int opt; 67849e21299Sdinak extern int optind_av; 67949e21299Sdinak extern char *optarg_av; 68049e21299Sdinak char *token_spec = NULL; 6817711facfSdinak char *filename = NULL; 68299ebb4caSwyllys char *dir = NULL; 68399ebb4caSwyllys char *prefix = NULL; 68499ebb4caSwyllys char *certlabel = NULL; 68599ebb4caSwyllys char *subject = NULL; 68699ebb4caSwyllys char *issuer = NULL; 68799ebb4caSwyllys char *infile = NULL; 68899ebb4caSwyllys char *keyfile = NULL; 68999ebb4caSwyllys char *certfile = NULL; 69099ebb4caSwyllys char *serstr = NULL; 69199ebb4caSwyllys KMF_KEYSTORE_TYPE kstype = 0; 69299ebb4caSwyllys KMF_ENCODE_FORMAT kfmt = KMF_FORMAT_PKCS12; 69399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 69499ebb4caSwyllys int oclass = PK_CERT_OBJ; 69599ebb4caSwyllys KMF_BIGINT serial = { NULL, 0 }; 69699ebb4caSwyllys KMF_HANDLE_T kmfhandle = NULL; 69799ebb4caSwyllys KMF_CREDENTIAL tokencred = {NULL, 0}; 6987711facfSdinak 69949e21299Sdinak /* Parse command line options. Do NOT i18n/l10n. */ 70099ebb4caSwyllys while ((opt = getopt_av(argc, argv, 70199ebb4caSwyllys "k:(keystore)y:(objtype)T:(token)" 70299ebb4caSwyllys "d:(dir)p:(prefix)" 70399ebb4caSwyllys "l:(label)n:(nickname)s:(subject)" 70499ebb4caSwyllys "i:(issuer)S:(serial)" 70599ebb4caSwyllys "K:(keyfile)c:(certfile)" 70699ebb4caSwyllys "F:(outformat)" 70799ebb4caSwyllys "I:(infile)o:(outfile)")) != EOF) { 70899ebb4caSwyllys if (EMPTYSTRING(optarg_av)) 70999ebb4caSwyllys return (PK_ERR_USAGE); 71049e21299Sdinak switch (opt) { 71199ebb4caSwyllys case 'k': 71299ebb4caSwyllys kstype = KS2Int(optarg_av); 71399ebb4caSwyllys if (kstype == 0) 71499ebb4caSwyllys return (PK_ERR_USAGE); 71599ebb4caSwyllys break; 71699ebb4caSwyllys case 'y': 71799ebb4caSwyllys oclass = OT2Int(optarg_av); 71899ebb4caSwyllys if (oclass == -1) 71999ebb4caSwyllys return (PK_ERR_USAGE); 72099ebb4caSwyllys break; 72149e21299Sdinak case 'T': /* token specifier */ 72249e21299Sdinak if (token_spec) 72349e21299Sdinak return (PK_ERR_USAGE); 72449e21299Sdinak token_spec = optarg_av; 72549e21299Sdinak break; 72699ebb4caSwyllys case 'd': 72799ebb4caSwyllys if (dir) 72899ebb4caSwyllys return (PK_ERR_USAGE); 72999ebb4caSwyllys dir = optarg_av; 73099ebb4caSwyllys break; 73199ebb4caSwyllys case 'p': 73299ebb4caSwyllys if (prefix) 73399ebb4caSwyllys return (PK_ERR_USAGE); 73499ebb4caSwyllys prefix = optarg_av; 73599ebb4caSwyllys break; 73699ebb4caSwyllys case 'n': 73799ebb4caSwyllys case 'l': 73899ebb4caSwyllys if (certlabel) 73999ebb4caSwyllys return (PK_ERR_USAGE); 74099ebb4caSwyllys certlabel = optarg_av; 74199ebb4caSwyllys break; 74299ebb4caSwyllys case 's': 74399ebb4caSwyllys if (subject) 74499ebb4caSwyllys return (PK_ERR_USAGE); 74599ebb4caSwyllys subject = optarg_av; 74699ebb4caSwyllys break; 74799ebb4caSwyllys case 'i': 74899ebb4caSwyllys if (issuer) 74999ebb4caSwyllys return (PK_ERR_USAGE); 75099ebb4caSwyllys issuer = optarg_av; 75199ebb4caSwyllys break; 75299ebb4caSwyllys case 'S': 75399ebb4caSwyllys serstr = optarg_av; 75499ebb4caSwyllys break; 75599ebb4caSwyllys case 'F': 75699ebb4caSwyllys kfmt = Str2Format(optarg_av); 75799ebb4caSwyllys if (kfmt == KMF_FORMAT_UNDEF) 75899ebb4caSwyllys return (PK_ERR_USAGE); 75999ebb4caSwyllys break; 76099ebb4caSwyllys case 'I': /* output file name */ 76199ebb4caSwyllys if (infile) 76299ebb4caSwyllys return (PK_ERR_USAGE); 76399ebb4caSwyllys infile = optarg_av; 76499ebb4caSwyllys break; 76549e21299Sdinak case 'o': /* output file name */ 76649e21299Sdinak if (filename) 76749e21299Sdinak return (PK_ERR_USAGE); 76849e21299Sdinak filename = optarg_av; 76949e21299Sdinak break; 77099ebb4caSwyllys case 'c': /* input cert file name */ 77199ebb4caSwyllys if (certfile) 77299ebb4caSwyllys return (PK_ERR_USAGE); 77399ebb4caSwyllys certfile = optarg_av; 77499ebb4caSwyllys break; 77599ebb4caSwyllys case 'K': /* input key file name */ 77699ebb4caSwyllys if (keyfile) 77799ebb4caSwyllys return (PK_ERR_USAGE); 77899ebb4caSwyllys keyfile = optarg_av; 77999ebb4caSwyllys break; 78049e21299Sdinak default: 78149e21299Sdinak return (PK_ERR_USAGE); 78249e21299Sdinak break; 78349e21299Sdinak } 78449e21299Sdinak } 7857711facfSdinak 78699ebb4caSwyllys /* Assume keystore = PKCS#11 if not specified */ 78799ebb4caSwyllys if (kstype == 0) 78899ebb4caSwyllys kstype = KMF_KEYSTORE_PK11TOKEN; 78949e21299Sdinak 79049e21299Sdinak /* Filename arg is required. */ 79199ebb4caSwyllys if (EMPTYSTRING(filename)) { 79299ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("You must specify " 79399ebb4caSwyllys "an 'outfile' parameter when exporting.\n")); 7947711facfSdinak return (PK_ERR_USAGE); 79599ebb4caSwyllys } 7967711facfSdinak 79749e21299Sdinak /* No additional args allowed. */ 79849e21299Sdinak argc -= optind_av; 79949e21299Sdinak argv += optind_av; 80049e21299Sdinak if (argc) 80149e21299Sdinak return (PK_ERR_USAGE); 80299ebb4caSwyllys 803577f4726Swyllys DIR_OPTION_CHECK(kstype, dir); 804577f4726Swyllys 80599ebb4caSwyllys /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ 80699ebb4caSwyllys if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && 80799ebb4caSwyllys kstype != KMF_KEYSTORE_PK11TOKEN) { 80899ebb4caSwyllys 80999ebb4caSwyllys (void) fprintf(stderr, gettext("The objtype parameter " 81099ebb4caSwyllys "is only relevant if keystore=pkcs11\n")); 81199ebb4caSwyllys return (PK_ERR_USAGE); 81299ebb4caSwyllys } 81399ebb4caSwyllys 81499ebb4caSwyllys if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) 81599ebb4caSwyllys token_spec = PK_DEFAULT_PK11TOKEN; 81699ebb4caSwyllys else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) 81799ebb4caSwyllys token_spec = DEFAULT_NSS_TOKEN; 81899ebb4caSwyllys 81999ebb4caSwyllys if (kstype == KMF_KEYSTORE_OPENSSL) { 82099ebb4caSwyllys if (kfmt != KMF_FORMAT_PKCS12) { 82199ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("PKCS12 " 82299ebb4caSwyllys "is the only export format " 82399ebb4caSwyllys "supported for the 'file' " 82499ebb4caSwyllys "keystore.\n")); 82599ebb4caSwyllys return (PK_ERR_USAGE); 82699ebb4caSwyllys } 82799ebb4caSwyllys if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { 82899ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("A cert file" 82999ebb4caSwyllys "and a key file must be specified " 83099ebb4caSwyllys "when exporting to PKCS12 from the " 83199ebb4caSwyllys "'file' keystore.\n")); 83299ebb4caSwyllys return (PK_ERR_USAGE); 83399ebb4caSwyllys } 83499ebb4caSwyllys } 8357711facfSdinak 8367711facfSdinak /* Check if the file exists and might be overwritten. */ 8377711facfSdinak if (access(filename, F_OK) == 0) { 83899ebb4caSwyllys cryptoerror(LOG_STDERR, 83999ebb4caSwyllys gettext("Warning: file \"%s\" exists, " 8407711facfSdinak "will be overwritten."), filename); 8417711facfSdinak if (yesno(gettext("Continue with export? "), 8427711facfSdinak gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) { 8437711facfSdinak return (0); 84473cc0e02Swyllys } else { 84573cc0e02Swyllys /* remove the file */ 84673cc0e02Swyllys (void) unlink(filename); 8477711facfSdinak } 84899ebb4caSwyllys } else { 84999ebb4caSwyllys rv = verify_file(filename); 85099ebb4caSwyllys if (rv != KMF_OK) { 85199ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("The file (%s) " 85299ebb4caSwyllys "cannot be created.\n"), filename); 85399ebb4caSwyllys return (PK_ERR_USAGE); 85499ebb4caSwyllys } 8557711facfSdinak } 8567711facfSdinak 85799ebb4caSwyllys if (serstr != NULL) { 85899ebb4caSwyllys uchar_t *bytes = NULL; 85999ebb4caSwyllys size_t bytelen; 8607711facfSdinak 86130a5e8faSwyllys rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); 86299ebb4caSwyllys if (rv != KMF_OK || bytes == NULL) { 86399ebb4caSwyllys (void) fprintf(stderr, gettext("serial number " 86499ebb4caSwyllys "must be specified as a hex number " 86599ebb4caSwyllys "(ex: 0x0102030405ffeeddee)\n")); 86699ebb4caSwyllys return (PK_ERR_USAGE); 86799ebb4caSwyllys } 86899ebb4caSwyllys serial.val = bytes; 86999ebb4caSwyllys serial.len = bytelen; 8707711facfSdinak } 8717711facfSdinak 872*592106a2SWyllys Ingersoll if (kstype == KMF_KEYSTORE_PK11TOKEN || 873*592106a2SWyllys Ingersoll ((kstype == KMF_KEYSTORE_NSS) && 874*592106a2SWyllys Ingersoll (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ))) || 875*592106a2SWyllys Ingersoll kfmt == KMF_FORMAT_PKCS12) { 87699ebb4caSwyllys (void) get_token_password(kstype, token_spec, 87799ebb4caSwyllys &tokencred); 8787711facfSdinak } 8797711facfSdinak 88030a5e8faSwyllys if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 88199ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Error initializing " 88299ebb4caSwyllys "KMF: 0x%02x\n"), rv); 88399ebb4caSwyllys return (rv); 8847711facfSdinak } 8857711facfSdinak 88699ebb4caSwyllys switch (kstype) { 88799ebb4caSwyllys case KMF_KEYSTORE_PK11TOKEN: 88899ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 88930a5e8faSwyllys rv = pk_export_pk12_pk11(kmfhandle, 89030a5e8faSwyllys token_spec, certlabel, 89199ebb4caSwyllys issuer, subject, 89299ebb4caSwyllys &serial, &tokencred, 89399ebb4caSwyllys filename); 89430a5e8faSwyllys else if ((oclass & PK_KEY_OBJ) || 89530a5e8faSwyllys kfmt == KMF_FORMAT_RAWKEY) 89630a5e8faSwyllys rv = pk_export_pk11_keys(kmfhandle, 89730a5e8faSwyllys token_spec, &tokencred, kfmt, 89873cc0e02Swyllys certlabel, filename, oclass); 8997711facfSdinak else 90099ebb4caSwyllys rv = pk_export_pk11_objects(kmfhandle, 901*592106a2SWyllys Ingersoll token_spec, &tokencred, certlabel, 90230a5e8faSwyllys issuer, subject, &serial, kfmt, 90399ebb4caSwyllys filename); 90499ebb4caSwyllys break; 90599ebb4caSwyllys case KMF_KEYSTORE_NSS: 90699ebb4caSwyllys if (dir == NULL) 90799ebb4caSwyllys dir = PK_DEFAULT_DIRECTORY; 90899ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 90999ebb4caSwyllys rv = pk_export_pk12_nss(kmfhandle, 91099ebb4caSwyllys token_spec, dir, prefix, 91199ebb4caSwyllys certlabel, issuer, 91299ebb4caSwyllys subject, &serial, 91399ebb4caSwyllys &tokencred, filename); 91499ebb4caSwyllys else 91599ebb4caSwyllys rv = pk_export_nss_objects(kmfhandle, 91699ebb4caSwyllys token_spec, 91799ebb4caSwyllys oclass, certlabel, issuer, subject, 91899ebb4caSwyllys &serial, kfmt, dir, prefix, filename); 91999ebb4caSwyllys break; 92099ebb4caSwyllys case KMF_KEYSTORE_OPENSSL: 92199ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 92299ebb4caSwyllys rv = pk_export_pk12_files(kmfhandle, 923448b8615Swyllys certfile, keyfile, filename); 92499ebb4caSwyllys else 92599ebb4caSwyllys rv = pk_export_file_objects(kmfhandle, oclass, 92630a5e8faSwyllys issuer, subject, &serial, 927448b8615Swyllys infile, filename); 92899ebb4caSwyllys break; 92999ebb4caSwyllys default: 93099ebb4caSwyllys rv = PK_ERR_USAGE; 93199ebb4caSwyllys break; 9327711facfSdinak } 9337711facfSdinak 93499ebb4caSwyllys if (rv != KMF_OK) { 93599ebb4caSwyllys display_error(kmfhandle, rv, 93699ebb4caSwyllys gettext("Error exporting objects")); 9377711facfSdinak } 9387711facfSdinak 93999ebb4caSwyllys if (serial.val != NULL) 94099ebb4caSwyllys free(serial.val); 9417711facfSdinak 94230a5e8faSwyllys (void) kmf_finalize(kmfhandle); 9437711facfSdinak 94499ebb4caSwyllys return (rv); 9457711facfSdinak } 946