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 * 2230a5e8faSwyllys * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 237711facfSdinak * Use is subject to license terms. 247711facfSdinak */ 257711facfSdinak 267711facfSdinak #pragma ident "%Z%%M% %I% %E% SMI" 277711facfSdinak 287711facfSdinak /* 297711facfSdinak * This file implements the export operation for this tool. 307711facfSdinak * The basic flow of the process is to find the soft token, 317711facfSdinak * log into it, find the PKCS#11 objects in the soft token 327711facfSdinak * to be exported matching keys with their certificates, export 337711facfSdinak * them to the PKCS#12 file encrypting them with a file password 347711facfSdinak * if desired, and log out. 357711facfSdinak */ 367711facfSdinak 377711facfSdinak #include <stdio.h> 387711facfSdinak #include <stdlib.h> 397711facfSdinak #include <string.h> 407711facfSdinak #include <errno.h> 4199ebb4caSwyllys #include <fcntl.h> 427711facfSdinak #include "common.h" 437711facfSdinak 4499ebb4caSwyllys #include <kmfapi.h> 457711facfSdinak 4699ebb4caSwyllys static KMF_RETURN 4730a5e8faSwyllys pk_find_export_cert(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attrlist, 4830a5e8faSwyllys int numattr, KMF_X509_DER_CERT *cert) 497711facfSdinak { 5099ebb4caSwyllys KMF_RETURN rv = KMF_OK; 5199ebb4caSwyllys uint32_t numcerts = 0; 527711facfSdinak 5399ebb4caSwyllys numcerts = 0; 5499ebb4caSwyllys (void) memset(cert, 0, sizeof (KMF_X509_DER_CERT)); 5530a5e8faSwyllys 5630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 5730a5e8faSwyllys &numcerts, sizeof (uint32_t)); 5830a5e8faSwyllys numattr++; 5930a5e8faSwyllys 6030a5e8faSwyllys rv = kmf_find_cert(kmfhandle, numattr, attrlist); 6199ebb4caSwyllys if (rv != KMF_OK) { 627711facfSdinak return (rv); 637711facfSdinak } 6499ebb4caSwyllys if (numcerts == 0) { 6599ebb4caSwyllys cryptoerror(LOG_STDERR, 6630a5e8faSwyllys gettext("No matching certificates found.")); 6799ebb4caSwyllys return (KMF_ERR_CERT_NOT_FOUND); 687711facfSdinak 6999ebb4caSwyllys } else if (numcerts == 1) { 7030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 7130a5e8faSwyllys KMF_X509_DER_CERT_ATTR, cert, 7230a5e8faSwyllys sizeof (KMF_X509_DER_CERT)); 7330a5e8faSwyllys numattr++; 7430a5e8faSwyllys rv = kmf_find_cert(kmfhandle, numattr, attrlist); 757711facfSdinak 7699ebb4caSwyllys } else if (numcerts > 1) { 7799ebb4caSwyllys cryptoerror(LOG_STDERR, 7830a5e8faSwyllys gettext("%d certificates found, refine the " 7930a5e8faSwyllys "search parameters to eliminate ambiguity\n"), 8030a5e8faSwyllys numcerts); 8199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 827711facfSdinak } 8399ebb4caSwyllys return (rv); 847711facfSdinak } 857711facfSdinak 8699ebb4caSwyllys static KMF_RETURN 8799ebb4caSwyllys pk_export_file_objects(KMF_HANDLE_T kmfhandle, int oclass, 8899ebb4caSwyllys char *issuer, char *subject, KMF_BIGINT *serial, 8999ebb4caSwyllys char *dir, char *infile, char *filename) 907711facfSdinak { 9199ebb4caSwyllys KMF_RETURN rv = KMF_OK; 9299ebb4caSwyllys KMF_X509_DER_CERT kmfcert; 9330a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 9430a5e8faSwyllys int numattr = 0; 9530a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 9699ebb4caSwyllys 9799ebb4caSwyllys /* If searching for public objects or certificates, find certs now */ 9899ebb4caSwyllys if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) { 9930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 10030a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 10130a5e8faSwyllys sizeof (kstype)); 10230a5e8faSwyllys numattr++; 10330a5e8faSwyllys 10430a5e8faSwyllys if (issuer != NULL) { 10530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 10630a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, 10730a5e8faSwyllys strlen(issuer)); 10830a5e8faSwyllys numattr++; 10930a5e8faSwyllys } 11030a5e8faSwyllys 11130a5e8faSwyllys if (subject != NULL) { 11230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 11330a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, 11430a5e8faSwyllys strlen(subject)); 11530a5e8faSwyllys numattr++; 11630a5e8faSwyllys } 11730a5e8faSwyllys 11830a5e8faSwyllys if (serial != NULL) { 11930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 12030a5e8faSwyllys KMF_BIGINT_ATTR, serial, 12130a5e8faSwyllys sizeof (KMF_BIGINT)); 12230a5e8faSwyllys numattr++; 12330a5e8faSwyllys } 12430a5e8faSwyllys 12530a5e8faSwyllys if (dir != NULL) { 12630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 12730a5e8faSwyllys KMF_DIRPATH_ATTR, dir, 12830a5e8faSwyllys strlen(dir)); 12930a5e8faSwyllys numattr++; 13030a5e8faSwyllys } 13130a5e8faSwyllys 13230a5e8faSwyllys if (infile != NULL) { 13330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 13430a5e8faSwyllys KMF_CERT_FILENAME_ATTR, infile, 13530a5e8faSwyllys strlen(infile)); 13630a5e8faSwyllys numattr++; 13730a5e8faSwyllys } 13830a5e8faSwyllys 13930a5e8faSwyllys rv = pk_find_export_cert(kmfhandle, attrlist, numattr, 14030a5e8faSwyllys &kmfcert); 14199ebb4caSwyllys if (rv == KMF_OK) { 14230a5e8faSwyllys kstype = KMF_KEYSTORE_OPENSSL; 14330a5e8faSwyllys numattr = 0; 14499ebb4caSwyllys 14530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 14630a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 14730a5e8faSwyllys numattr++; 14830a5e8faSwyllys 14930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 15030a5e8faSwyllys KMF_CERT_DATA_ATTR, &kmfcert.certificate, 15130a5e8faSwyllys sizeof (KMF_DATA)); 15230a5e8faSwyllys numattr++; 15330a5e8faSwyllys 15430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 15530a5e8faSwyllys KMF_CERT_FILENAME_ATTR, filename, 15630a5e8faSwyllys strlen(filename)); 15730a5e8faSwyllys numattr++; 15830a5e8faSwyllys 15930a5e8faSwyllys rv = kmf_store_cert(kmfhandle, numattr, 16030a5e8faSwyllys attrlist); 16130a5e8faSwyllys 16230a5e8faSwyllys kmf_free_kmf_cert(kmfhandle, &kmfcert); 16399ebb4caSwyllys } 16499ebb4caSwyllys } 16599ebb4caSwyllys return (rv); 1667711facfSdinak } 1677711facfSdinak 16899ebb4caSwyllys static KMF_RETURN 16999ebb4caSwyllys pk_export_pk12_nss(KMF_HANDLE_T kmfhandle, 17099ebb4caSwyllys char *token_spec, char *dir, char *prefix, 17199ebb4caSwyllys char *certlabel, char *issuer, char *subject, 17299ebb4caSwyllys KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, 17399ebb4caSwyllys char *filename) 1747711facfSdinak { 17599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 17630a5e8faSwyllys KMF_KEYSTORE_TYPE kstype; 17730a5e8faSwyllys KMF_CREDENTIAL p12cred = { NULL, 0}; 17830a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 17930a5e8faSwyllys int numattr = 0; 1807711facfSdinak 18199ebb4caSwyllys rv = configure_nss(kmfhandle, dir, prefix); 18299ebb4caSwyllys if (rv != KMF_OK) 1837711facfSdinak return (rv); 1847711facfSdinak 18599ebb4caSwyllys if (token_spec == NULL) 18699ebb4caSwyllys token_spec = DEFAULT_NSS_TOKEN; 1877711facfSdinak 18830a5e8faSwyllys kstype = KMF_KEYSTORE_NSS; 18930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 19030a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 19130a5e8faSwyllys numattr++; 19230a5e8faSwyllys 19330a5e8faSwyllys if (certlabel != NULL) { 19430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 19530a5e8faSwyllys KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); 19630a5e8faSwyllys numattr++; 19730a5e8faSwyllys } 19830a5e8faSwyllys 19930a5e8faSwyllys if (issuer != NULL) { 20030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 20130a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); 20230a5e8faSwyllys numattr++; 20330a5e8faSwyllys } 20430a5e8faSwyllys 20530a5e8faSwyllys if (subject != NULL) { 20630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 20730a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); 20830a5e8faSwyllys numattr++; 20930a5e8faSwyllys } 2107711facfSdinak 21130a5e8faSwyllys if (serial != NULL) { 21230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 21330a5e8faSwyllys KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); 21430a5e8faSwyllys numattr++; 21530a5e8faSwyllys } 2167711facfSdinak 21730a5e8faSwyllys if (tokencred != NULL) { 21830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 21930a5e8faSwyllys KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); 22030a5e8faSwyllys numattr++; 22130a5e8faSwyllys } 22230a5e8faSwyllys 22330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 22430a5e8faSwyllys token_spec, strlen(token_spec)); 22530a5e8faSwyllys numattr++; 22630a5e8faSwyllys 22730a5e8faSwyllys (void) get_pk12_password(&p12cred); 22830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 22930a5e8faSwyllys KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); 23030a5e8faSwyllys numattr++; 23130a5e8faSwyllys 23230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 23330a5e8faSwyllys KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename)); 23430a5e8faSwyllys numattr++; 23530a5e8faSwyllys 23630a5e8faSwyllys rv = kmf_export_pk12(kmfhandle, numattr, attrlist); 23730a5e8faSwyllys 23830a5e8faSwyllys if (p12cred.cred) 23930a5e8faSwyllys free(p12cred.cred); 2407711facfSdinak 24199ebb4caSwyllys return (rv); 2427711facfSdinak } 2437711facfSdinak 24499ebb4caSwyllys static KMF_RETURN 24599ebb4caSwyllys pk_export_pk12_files(KMF_HANDLE_T kmfhandle, 24699ebb4caSwyllys char *certfile, char *keyfile, char *dir, 24799ebb4caSwyllys char *outfile) 2487711facfSdinak { 24999ebb4caSwyllys KMF_RETURN rv; 25030a5e8faSwyllys KMF_KEYSTORE_TYPE kstype; 25130a5e8faSwyllys KMF_CREDENTIAL p12cred = { NULL, 0}; 25230a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 25330a5e8faSwyllys int numattr = 0; 25430a5e8faSwyllys 25530a5e8faSwyllys kstype = KMF_KEYSTORE_OPENSSL; 25630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 25730a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 25830a5e8faSwyllys numattr++; 25930a5e8faSwyllys 26030a5e8faSwyllys if (dir != NULL) { 26130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 26230a5e8faSwyllys KMF_DIRPATH_ATTR, dir, strlen(dir)); 26330a5e8faSwyllys numattr++; 26430a5e8faSwyllys } 2657711facfSdinak 26630a5e8faSwyllys if (certfile != NULL) { 26730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 26830a5e8faSwyllys KMF_CERT_FILENAME_ATTR, certfile, strlen(certfile)); 26930a5e8faSwyllys numattr++; 27030a5e8faSwyllys } 27130a5e8faSwyllys 27230a5e8faSwyllys if (keyfile != NULL) { 27330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 27430a5e8faSwyllys KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile)); 27530a5e8faSwyllys numattr++; 27630a5e8faSwyllys } 2777711facfSdinak 27830a5e8faSwyllys (void) get_pk12_password(&p12cred); 27930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 28030a5e8faSwyllys KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); 28130a5e8faSwyllys numattr++; 2827711facfSdinak 28330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 28430a5e8faSwyllys KMF_OUTPUT_FILENAME_ATTR, outfile, strlen(outfile)); 28530a5e8faSwyllys numattr++; 2867711facfSdinak 28730a5e8faSwyllys rv = kmf_export_pk12(kmfhandle, numattr, attrlist); 2887711facfSdinak 28930a5e8faSwyllys if (p12cred.cred) 29030a5e8faSwyllys free(p12cred.cred); 2917711facfSdinak 29299ebb4caSwyllys return (rv); 2937711facfSdinak } 2947711facfSdinak 29599ebb4caSwyllys static KMF_RETURN 29699ebb4caSwyllys pk_export_nss_objects(KMF_HANDLE_T kmfhandle, char *token_spec, 29799ebb4caSwyllys int oclass, char *certlabel, char *issuer, char *subject, 29899ebb4caSwyllys KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, char *dir, 29999ebb4caSwyllys char *prefix, char *filename) 3007711facfSdinak { 30199ebb4caSwyllys KMF_RETURN rv = KMF_OK; 30299ebb4caSwyllys KMF_X509_DER_CERT kmfcert; 30330a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 30430a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 30530a5e8faSwyllys int numattr = 0; 3067711facfSdinak 30799ebb4caSwyllys rv = configure_nss(kmfhandle, dir, prefix); 30899ebb4caSwyllys if (rv != KMF_OK) 3097711facfSdinak return (rv); 3107711facfSdinak 31199ebb4caSwyllys /* If searching for public objects or certificates, find certs now */ 31299ebb4caSwyllys if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) { 31330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 31430a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 31530a5e8faSwyllys sizeof (kstype)); 31630a5e8faSwyllys numattr++; 31730a5e8faSwyllys 31830a5e8faSwyllys if (certlabel != NULL) { 31930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 32030a5e8faSwyllys KMF_CERT_LABEL_ATTR, certlabel, 32130a5e8faSwyllys strlen(certlabel)); 32230a5e8faSwyllys numattr++; 32330a5e8faSwyllys } 32499ebb4caSwyllys 32530a5e8faSwyllys if (issuer != NULL) { 32630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 32730a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, 32830a5e8faSwyllys strlen(issuer)); 32930a5e8faSwyllys numattr++; 33030a5e8faSwyllys } 33199ebb4caSwyllys 33230a5e8faSwyllys if (subject != NULL) { 33330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 33430a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, 33530a5e8faSwyllys strlen(subject)); 33630a5e8faSwyllys numattr++; 33730a5e8faSwyllys } 33830a5e8faSwyllys 33930a5e8faSwyllys if (serial != NULL) { 34030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 34130a5e8faSwyllys KMF_BIGINT_ATTR, serial, 34230a5e8faSwyllys sizeof (KMF_BIGINT)); 34330a5e8faSwyllys numattr++; 34430a5e8faSwyllys } 34530a5e8faSwyllys 34630a5e8faSwyllys if (token_spec != NULL) { 34730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 34830a5e8faSwyllys KMF_TOKEN_LABEL_ATTR, token_spec, 34930a5e8faSwyllys strlen(token_spec)); 35030a5e8faSwyllys numattr++; 35130a5e8faSwyllys } 35230a5e8faSwyllys 35330a5e8faSwyllys rv = pk_find_export_cert(kmfhandle, attrlist, numattr, 35430a5e8faSwyllys &kmfcert); 35599ebb4caSwyllys if (rv == KMF_OK) { 35630a5e8faSwyllys kstype = KMF_KEYSTORE_OPENSSL; 35730a5e8faSwyllys numattr = 0; 35830a5e8faSwyllys 35930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 36030a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 36130a5e8faSwyllys numattr++; 36299ebb4caSwyllys 36330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 36430a5e8faSwyllys KMF_CERT_DATA_ATTR, &kmfcert.certificate, 36530a5e8faSwyllys sizeof (KMF_DATA)); 36630a5e8faSwyllys numattr++; 36799ebb4caSwyllys 36830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 36930a5e8faSwyllys KMF_CERT_FILENAME_ATTR, filename, 37030a5e8faSwyllys strlen(filename)); 37130a5e8faSwyllys numattr++; 37230a5e8faSwyllys 37330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 37430a5e8faSwyllys KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt)); 37530a5e8faSwyllys numattr++; 37630a5e8faSwyllys 37730a5e8faSwyllys rv = kmf_store_cert(kmfhandle, numattr, attrlist); 37830a5e8faSwyllys 37930a5e8faSwyllys kmf_free_kmf_cert(kmfhandle, &kmfcert); 3807711facfSdinak } 3817711facfSdinak } 38299ebb4caSwyllys return (rv); 38399ebb4caSwyllys } 3847711facfSdinak 38599ebb4caSwyllys static KMF_RETURN 38699ebb4caSwyllys pk_export_pk12_pk11(KMF_HANDLE_T kmfhandle, char *token_spec, 38799ebb4caSwyllys char *certlabel, char *issuer, char *subject, 38899ebb4caSwyllys KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, char *filename) 38999ebb4caSwyllys { 39099ebb4caSwyllys KMF_RETURN rv = KMF_OK; 39130a5e8faSwyllys KMF_KEYSTORE_TYPE kstype; 39230a5e8faSwyllys KMF_CREDENTIAL p12cred = { NULL, 0}; 39330a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 39430a5e8faSwyllys int numattr = 0; 3957711facfSdinak 39699ebb4caSwyllys rv = select_token(kmfhandle, token_spec, TRUE); 39799ebb4caSwyllys if (rv != KMF_OK) { 39899ebb4caSwyllys return (rv); 3997711facfSdinak } 4007711facfSdinak 40130a5e8faSwyllys kstype = KMF_KEYSTORE_PK11TOKEN; 40230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 40330a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 40430a5e8faSwyllys numattr++; 40530a5e8faSwyllys 40630a5e8faSwyllys if (certlabel != NULL) { 40730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 40830a5e8faSwyllys KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); 40930a5e8faSwyllys numattr++; 41030a5e8faSwyllys } 41130a5e8faSwyllys 41230a5e8faSwyllys if (issuer != NULL) { 41330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 41430a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); 41530a5e8faSwyllys numattr++; 41630a5e8faSwyllys } 41730a5e8faSwyllys 41830a5e8faSwyllys if (subject != NULL) { 41930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 42030a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); 42130a5e8faSwyllys numattr++; 42230a5e8faSwyllys } 42330a5e8faSwyllys 42430a5e8faSwyllys if (serial != NULL) { 42530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 42630a5e8faSwyllys KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); 42730a5e8faSwyllys numattr++; 42830a5e8faSwyllys } 42930a5e8faSwyllys 43030a5e8faSwyllys if (tokencred != NULL) { 43130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 43230a5e8faSwyllys KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); 43330a5e8faSwyllys numattr++; 43430a5e8faSwyllys } 43530a5e8faSwyllys 43630a5e8faSwyllys (void) get_pk12_password(&p12cred); 43730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 43830a5e8faSwyllys KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); 43930a5e8faSwyllys numattr++; 44030a5e8faSwyllys 44130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 44230a5e8faSwyllys KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename)); 44330a5e8faSwyllys numattr++; 44430a5e8faSwyllys 44530a5e8faSwyllys rv = kmf_export_pk12(kmfhandle, numattr, attrlist); 44630a5e8faSwyllys 44730a5e8faSwyllys if (p12cred.cred) 44830a5e8faSwyllys free(p12cred.cred); 44930a5e8faSwyllys 45030a5e8faSwyllys return (rv); 45130a5e8faSwyllys } 45230a5e8faSwyllys 45330a5e8faSwyllys static KMF_RETURN 45430a5e8faSwyllys pk_export_pk11_keys(KMF_HANDLE_T kmfhandle, char *token, 45530a5e8faSwyllys KMF_CREDENTIAL *cred, KMF_ENCODE_FORMAT format, 45673cc0e02Swyllys char *label, char *filename, int oclass) 45730a5e8faSwyllys { 45830a5e8faSwyllys KMF_RETURN rv = KMF_OK; 45930a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 46073cc0e02Swyllys KMF_KEY_CLASS kclass = KMF_KEYCLASS_NONE; 46130a5e8faSwyllys int numattr = 0; 46230a5e8faSwyllys uint32_t numkeys = 1; 46330a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 46430a5e8faSwyllys KMF_KEY_HANDLE key; 46530a5e8faSwyllys boolean_t is_token = B_TRUE; 46630a5e8faSwyllys 46730a5e8faSwyllys if (EMPTYSTRING(label)) { 46830a5e8faSwyllys cryptoerror(LOG_STDERR, gettext("A label " 46930a5e8faSwyllys "must be specified to export a key.")); 47030a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 47130a5e8faSwyllys } 47230a5e8faSwyllys 47330a5e8faSwyllys rv = select_token(kmfhandle, token, TRUE); 47430a5e8faSwyllys if (rv != KMF_OK) { 47530a5e8faSwyllys return (rv); 47630a5e8faSwyllys } 47730a5e8faSwyllys 47830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 47930a5e8faSwyllys &kstype, sizeof (kstype)); 48030a5e8faSwyllys numattr++; 48130a5e8faSwyllys 48230a5e8faSwyllys if (cred != NULL) { 48330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 48430a5e8faSwyllys cred, sizeof (KMF_CREDENTIAL)); 48530a5e8faSwyllys numattr++; 48630a5e8faSwyllys } 48730a5e8faSwyllys 48830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, 48930a5e8faSwyllys label, strlen(label)); 49030a5e8faSwyllys numattr++; 49130a5e8faSwyllys 49230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 49330a5e8faSwyllys &numkeys, sizeof (numkeys)); 49430a5e8faSwyllys numattr++; 4957711facfSdinak 49630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 49730a5e8faSwyllys &key, sizeof (key)); 49830a5e8faSwyllys numattr++; 4997711facfSdinak 50030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR, 50130a5e8faSwyllys &is_token, sizeof (is_token)); 50230a5e8faSwyllys numattr++; 5037711facfSdinak 50430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 50530a5e8faSwyllys &format, sizeof (format)); 50630a5e8faSwyllys numattr++; 50730a5e8faSwyllys 50873cc0e02Swyllys /* Check to see if we are exporting private or public only */ 50973cc0e02Swyllys if ((oclass & PK_KEY_OBJ) == PK_PRIKEY_OBJ) 51073cc0e02Swyllys kclass = KMF_ASYM_PRI; 51173cc0e02Swyllys else if ((oclass & PK_KEY_OBJ) == PK_PUBKEY_OBJ) 51273cc0e02Swyllys kclass = KMF_ASYM_PUB; 51373cc0e02Swyllys else if ((oclass & PK_KEY_OBJ) == PK_SYMKEY_OBJ) 51473cc0e02Swyllys kclass = KMF_SYMMETRIC; 51573cc0e02Swyllys else /* only 1 key at a time can be exported here, so default to pri */ 51673cc0e02Swyllys kclass = KMF_ASYM_PRI; 51773cc0e02Swyllys 51873cc0e02Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, 51973cc0e02Swyllys &kclass, sizeof (kclass)); 52073cc0e02Swyllys numattr++; 52173cc0e02Swyllys 52230a5e8faSwyllys rv = kmf_find_key(kmfhandle, numattr, attrlist); 523*71a79fe7Swyllys /* 524*71a79fe7Swyllys * If nothing found but caller wanted ALL keys, try symmetric 525*71a79fe7Swyllys * this time. 526*71a79fe7Swyllys */ 527*71a79fe7Swyllys if (rv == KMF_ERR_KEY_NOT_FOUND && (oclass == PK_KEY_OBJ)) { 528*71a79fe7Swyllys kclass = KMF_SYMMETRIC; 529*71a79fe7Swyllys rv = kmf_find_key(kmfhandle, numattr, attrlist); 530*71a79fe7Swyllys } 531*71a79fe7Swyllys /* 532*71a79fe7Swyllys * If nothing found but caller wanted ALL keys, try asymmetric 533*71a79fe7Swyllys * public this time. 534*71a79fe7Swyllys */ 535*71a79fe7Swyllys if (rv == KMF_ERR_KEY_NOT_FOUND && (oclass == PK_KEY_OBJ)) { 536*71a79fe7Swyllys kclass = KMF_ASYM_PUB; 537*71a79fe7Swyllys rv = kmf_find_key(kmfhandle, numattr, attrlist); 538*71a79fe7Swyllys } 53930a5e8faSwyllys if (rv == KMF_OK && key.keyclass == KMF_SYMMETRIC) { 54030a5e8faSwyllys KMF_RAW_SYM_KEY rkey; 54130a5e8faSwyllys 54230a5e8faSwyllys (void) memset(&rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 54330a5e8faSwyllys rv = kmf_get_sym_key_value(kmfhandle, &key, &rkey); 54430a5e8faSwyllys if (rv == KMF_OK) { 54530a5e8faSwyllys int fd, n, total = 0; 54630a5e8faSwyllys 54730a5e8faSwyllys fd = open(filename, O_CREAT | O_RDWR |O_TRUNC, 0600); 54830a5e8faSwyllys if (fd == -1) { 54930a5e8faSwyllys rv = KMF_ERR_OPEN_FILE; 55030a5e8faSwyllys goto done; 55130a5e8faSwyllys } 55230a5e8faSwyllys do { 55330a5e8faSwyllys n = write(fd, rkey.keydata.val + total, 55430a5e8faSwyllys rkey.keydata.len - total); 55530a5e8faSwyllys if (n < 0) { 55630a5e8faSwyllys if (errno == EINTR) 55730a5e8faSwyllys continue; 55846d33f7eSwyllys (void) close(fd); 55930a5e8faSwyllys rv = KMF_ERR_WRITE_FILE; 56030a5e8faSwyllys goto done; 56130a5e8faSwyllys } 56230a5e8faSwyllys total += n; 56330a5e8faSwyllys 56430a5e8faSwyllys } while (total < rkey.keydata.len); 56546d33f7eSwyllys (void) close(fd); 56630a5e8faSwyllys } 56730a5e8faSwyllys done: 56830a5e8faSwyllys kmf_free_bigint(&rkey.keydata); 56930a5e8faSwyllys kmf_free_kmf_key(kmfhandle, &key); 57030a5e8faSwyllys } else if (rv == KMF_OK) { 57130a5e8faSwyllys KMF_KEYSTORE_TYPE sslks = KMF_KEYSTORE_OPENSSL; 57246d33f7eSwyllys (void) printf(gettext("Found %d asymmetric keys\n"), numkeys); 57330a5e8faSwyllys 57430a5e8faSwyllys numattr = 0; 57530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 57630a5e8faSwyllys &sslks, sizeof (sslks)); 57730a5e8faSwyllys numattr++; 57830a5e8faSwyllys 57930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR, 58030a5e8faSwyllys key.keyp, sizeof (KMF_RAW_KEY_DATA)); 58130a5e8faSwyllys numattr++; 58230a5e8faSwyllys 58330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 58430a5e8faSwyllys &format, sizeof (format)); 58530a5e8faSwyllys numattr++; 58630a5e8faSwyllys 58730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, 58830a5e8faSwyllys filename, strlen(filename)); 58930a5e8faSwyllys numattr++; 59030a5e8faSwyllys 59173cc0e02Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, 59273cc0e02Swyllys &key.keyclass, sizeof (KMF_KEY_CLASS)); 59373cc0e02Swyllys numattr++; 59473cc0e02Swyllys 59530a5e8faSwyllys rv = kmf_store_key(kmfhandle, numattr, attrlist); 59630a5e8faSwyllys kmf_free_kmf_key(kmfhandle, &key); 59730a5e8faSwyllys } 5987711facfSdinak 59999ebb4caSwyllys return (rv); 6007711facfSdinak } 6017711facfSdinak 60299ebb4caSwyllys static KMF_RETURN 60399ebb4caSwyllys pk_export_pk11_objects(KMF_HANDLE_T kmfhandle, char *token_spec, 60499ebb4caSwyllys char *certlabel, char *issuer, char *subject, 60599ebb4caSwyllys KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, 60699ebb4caSwyllys char *filename) 6077711facfSdinak { 60899ebb4caSwyllys KMF_RETURN rv = KMF_OK; 60999ebb4caSwyllys KMF_X509_DER_CERT kmfcert; 61030a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 61130a5e8faSwyllys int numattr = 0; 61230a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 6137711facfSdinak 61499ebb4caSwyllys rv = select_token(kmfhandle, token_spec, TRUE); 6157711facfSdinak 61699ebb4caSwyllys if (rv != KMF_OK) { 6177711facfSdinak return (rv); 6187711facfSdinak } 6197711facfSdinak 62030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 62130a5e8faSwyllys &kstype, sizeof (kstype)); 62230a5e8faSwyllys numattr++; 6237711facfSdinak 62430a5e8faSwyllys if (certlabel != NULL) { 62530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 62630a5e8faSwyllys KMF_CERT_LABEL_ATTR, certlabel, 62730a5e8faSwyllys strlen(certlabel)); 62830a5e8faSwyllys numattr++; 62930a5e8faSwyllys } 63030a5e8faSwyllys 63130a5e8faSwyllys if (issuer != NULL) { 63230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 63330a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, 63430a5e8faSwyllys strlen(issuer)); 63530a5e8faSwyllys numattr++; 63630a5e8faSwyllys } 63730a5e8faSwyllys 63830a5e8faSwyllys if (subject != NULL) { 63930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 64030a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, 64130a5e8faSwyllys strlen(subject)); 64230a5e8faSwyllys numattr++; 64330a5e8faSwyllys } 64430a5e8faSwyllys 64530a5e8faSwyllys if (serial != NULL) { 64630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 64730a5e8faSwyllys KMF_BIGINT_ATTR, serial, 64830a5e8faSwyllys sizeof (KMF_BIGINT)); 64930a5e8faSwyllys numattr++; 65030a5e8faSwyllys } 65130a5e8faSwyllys 65230a5e8faSwyllys rv = pk_find_export_cert(kmfhandle, attrlist, numattr, &kmfcert); 6537711facfSdinak 65499ebb4caSwyllys if (rv == KMF_OK) { 65530a5e8faSwyllys kstype = KMF_KEYSTORE_OPENSSL; 65630a5e8faSwyllys numattr = 0; 65730a5e8faSwyllys 65830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 65930a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 66030a5e8faSwyllys numattr++; 66130a5e8faSwyllys 66230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 66330a5e8faSwyllys KMF_CERT_DATA_ATTR, &kmfcert.certificate, 66430a5e8faSwyllys sizeof (KMF_DATA)); 66530a5e8faSwyllys numattr++; 66630a5e8faSwyllys 66730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 66830a5e8faSwyllys KMF_CERT_FILENAME_ATTR, filename, strlen(filename)); 66930a5e8faSwyllys numattr++; 67030a5e8faSwyllys 67130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 67230a5e8faSwyllys KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt)); 67330a5e8faSwyllys numattr++; 6747711facfSdinak 67530a5e8faSwyllys rv = kmf_store_cert(kmfhandle, numattr, attrlist); 6767711facfSdinak 67730a5e8faSwyllys kmf_free_kmf_cert(kmfhandle, &kmfcert); 6787711facfSdinak } 67999ebb4caSwyllys return (rv); 6807711facfSdinak } 6817711facfSdinak 6827711facfSdinak /* 68399ebb4caSwyllys * Export objects from one keystore to a file. 6847711facfSdinak */ 6857711facfSdinak int 6867711facfSdinak pk_export(int argc, char *argv[]) 6877711facfSdinak { 68849e21299Sdinak int opt; 68949e21299Sdinak extern int optind_av; 69049e21299Sdinak extern char *optarg_av; 69149e21299Sdinak char *token_spec = NULL; 6927711facfSdinak char *filename = NULL; 69399ebb4caSwyllys char *dir = NULL; 69499ebb4caSwyllys char *prefix = NULL; 69599ebb4caSwyllys char *certlabel = NULL; 69699ebb4caSwyllys char *subject = NULL; 69799ebb4caSwyllys char *issuer = NULL; 69899ebb4caSwyllys char *infile = NULL; 69999ebb4caSwyllys char *keyfile = NULL; 70099ebb4caSwyllys char *certfile = NULL; 70199ebb4caSwyllys char *serstr = NULL; 70299ebb4caSwyllys KMF_KEYSTORE_TYPE kstype = 0; 70399ebb4caSwyllys KMF_ENCODE_FORMAT kfmt = KMF_FORMAT_PKCS12; 70499ebb4caSwyllys KMF_RETURN rv = KMF_OK; 70599ebb4caSwyllys int oclass = PK_CERT_OBJ; 70699ebb4caSwyllys KMF_BIGINT serial = { NULL, 0 }; 70799ebb4caSwyllys KMF_HANDLE_T kmfhandle = NULL; 70899ebb4caSwyllys KMF_CREDENTIAL tokencred = {NULL, 0}; 7097711facfSdinak 71049e21299Sdinak /* Parse command line options. Do NOT i18n/l10n. */ 71199ebb4caSwyllys while ((opt = getopt_av(argc, argv, 71230a5e8faSwyllys "k:(keystore)y:(objtype)T:(token)" 71330a5e8faSwyllys "d:(dir)p:(prefix)" 71430a5e8faSwyllys "l:(label)n:(nickname)s:(subject)" 71530a5e8faSwyllys "i:(issuer)S:(serial)" 71630a5e8faSwyllys "K:(keyfile)c:(certfile)" 71730a5e8faSwyllys "F:(outformat)" 71830a5e8faSwyllys "I:(infile)o:(outfile)")) != EOF) { 71999ebb4caSwyllys if (EMPTYSTRING(optarg_av)) 72099ebb4caSwyllys return (PK_ERR_USAGE); 72149e21299Sdinak switch (opt) { 72299ebb4caSwyllys case 'k': 72399ebb4caSwyllys kstype = KS2Int(optarg_av); 72499ebb4caSwyllys if (kstype == 0) 72599ebb4caSwyllys return (PK_ERR_USAGE); 72699ebb4caSwyllys break; 72799ebb4caSwyllys case 'y': 72899ebb4caSwyllys oclass = OT2Int(optarg_av); 72999ebb4caSwyllys if (oclass == -1) 73099ebb4caSwyllys return (PK_ERR_USAGE); 73199ebb4caSwyllys break; 73249e21299Sdinak case 'T': /* token specifier */ 73349e21299Sdinak if (token_spec) 73449e21299Sdinak return (PK_ERR_USAGE); 73549e21299Sdinak token_spec = optarg_av; 73649e21299Sdinak break; 73799ebb4caSwyllys case 'd': 73899ebb4caSwyllys if (dir) 73999ebb4caSwyllys return (PK_ERR_USAGE); 74099ebb4caSwyllys dir = optarg_av; 74199ebb4caSwyllys break; 74299ebb4caSwyllys case 'p': 74399ebb4caSwyllys if (prefix) 74499ebb4caSwyllys return (PK_ERR_USAGE); 74599ebb4caSwyllys prefix = optarg_av; 74699ebb4caSwyllys break; 74799ebb4caSwyllys case 'n': 74899ebb4caSwyllys case 'l': 74999ebb4caSwyllys if (certlabel) 75099ebb4caSwyllys return (PK_ERR_USAGE); 75199ebb4caSwyllys certlabel = optarg_av; 75299ebb4caSwyllys break; 75399ebb4caSwyllys case 's': 75499ebb4caSwyllys if (subject) 75599ebb4caSwyllys return (PK_ERR_USAGE); 75699ebb4caSwyllys subject = optarg_av; 75799ebb4caSwyllys break; 75899ebb4caSwyllys case 'i': 75999ebb4caSwyllys if (issuer) 76099ebb4caSwyllys return (PK_ERR_USAGE); 76199ebb4caSwyllys issuer = optarg_av; 76299ebb4caSwyllys break; 76399ebb4caSwyllys case 'S': 76499ebb4caSwyllys serstr = optarg_av; 76599ebb4caSwyllys break; 76699ebb4caSwyllys case 'F': 76799ebb4caSwyllys kfmt = Str2Format(optarg_av); 76899ebb4caSwyllys if (kfmt == KMF_FORMAT_UNDEF) 76999ebb4caSwyllys return (PK_ERR_USAGE); 77099ebb4caSwyllys break; 77199ebb4caSwyllys case 'I': /* output file name */ 77299ebb4caSwyllys if (infile) 77399ebb4caSwyllys return (PK_ERR_USAGE); 77499ebb4caSwyllys infile = optarg_av; 77599ebb4caSwyllys break; 77649e21299Sdinak case 'o': /* output file name */ 77749e21299Sdinak if (filename) 77849e21299Sdinak return (PK_ERR_USAGE); 77949e21299Sdinak filename = optarg_av; 78049e21299Sdinak break; 78199ebb4caSwyllys case 'c': /* input cert file name */ 78299ebb4caSwyllys if (certfile) 78399ebb4caSwyllys return (PK_ERR_USAGE); 78499ebb4caSwyllys certfile = optarg_av; 78599ebb4caSwyllys break; 78699ebb4caSwyllys case 'K': /* input key file name */ 78799ebb4caSwyllys if (keyfile) 78899ebb4caSwyllys return (PK_ERR_USAGE); 78999ebb4caSwyllys keyfile = optarg_av; 79099ebb4caSwyllys break; 79149e21299Sdinak default: 79249e21299Sdinak return (PK_ERR_USAGE); 79349e21299Sdinak break; 79449e21299Sdinak } 79549e21299Sdinak } 7967711facfSdinak 79799ebb4caSwyllys /* Assume keystore = PKCS#11 if not specified */ 79899ebb4caSwyllys if (kstype == 0) 79999ebb4caSwyllys kstype = KMF_KEYSTORE_PK11TOKEN; 80049e21299Sdinak 80149e21299Sdinak /* Filename arg is required. */ 80299ebb4caSwyllys if (EMPTYSTRING(filename)) { 80399ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("You must specify " 80430a5e8faSwyllys "an 'outfile' parameter when exporting.\n")); 8057711facfSdinak return (PK_ERR_USAGE); 80699ebb4caSwyllys } 8077711facfSdinak 80849e21299Sdinak /* No additional args allowed. */ 80949e21299Sdinak argc -= optind_av; 81049e21299Sdinak argv += optind_av; 81149e21299Sdinak if (argc) 81249e21299Sdinak return (PK_ERR_USAGE); 81399ebb4caSwyllys 81499ebb4caSwyllys /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ 81599ebb4caSwyllys if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && 81630a5e8faSwyllys kstype != KMF_KEYSTORE_PK11TOKEN) { 81799ebb4caSwyllys 81899ebb4caSwyllys (void) fprintf(stderr, gettext("The objtype parameter " 81930a5e8faSwyllys "is only relevant if keystore=pkcs11\n")); 82099ebb4caSwyllys return (PK_ERR_USAGE); 82199ebb4caSwyllys } 82299ebb4caSwyllys 82399ebb4caSwyllys if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) 82499ebb4caSwyllys token_spec = PK_DEFAULT_PK11TOKEN; 82599ebb4caSwyllys else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) 82699ebb4caSwyllys token_spec = DEFAULT_NSS_TOKEN; 82799ebb4caSwyllys 82899ebb4caSwyllys if (kstype == KMF_KEYSTORE_OPENSSL) { 82999ebb4caSwyllys if (kfmt != KMF_FORMAT_PKCS12) { 83099ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("PKCS12 " 83130a5e8faSwyllys "is the only export format " 83230a5e8faSwyllys "supported for the 'file' " 83330a5e8faSwyllys "keystore.\n")); 83499ebb4caSwyllys return (PK_ERR_USAGE); 83599ebb4caSwyllys } 83699ebb4caSwyllys if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { 83799ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("A cert file" 83830a5e8faSwyllys "and a key file must be specified " 83930a5e8faSwyllys "when exporting to PKCS12 from the " 84030a5e8faSwyllys "'file' keystore.\n")); 84199ebb4caSwyllys return (PK_ERR_USAGE); 84299ebb4caSwyllys } 84399ebb4caSwyllys } 8447711facfSdinak 8457711facfSdinak /* Check if the file exists and might be overwritten. */ 8467711facfSdinak if (access(filename, F_OK) == 0) { 84799ebb4caSwyllys cryptoerror(LOG_STDERR, 84830a5e8faSwyllys gettext("Warning: file \"%s\" exists, " 84930a5e8faSwyllys "will be overwritten."), filename); 8507711facfSdinak if (yesno(gettext("Continue with export? "), 8517711facfSdinak gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) { 8527711facfSdinak return (0); 85373cc0e02Swyllys } else { 85473cc0e02Swyllys /* remove the file */ 85573cc0e02Swyllys (void) unlink(filename); 8567711facfSdinak } 85799ebb4caSwyllys } else { 85899ebb4caSwyllys rv = verify_file(filename); 85999ebb4caSwyllys if (rv != KMF_OK) { 86099ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("The file (%s) " 86130a5e8faSwyllys "cannot be created.\n"), filename); 86299ebb4caSwyllys return (PK_ERR_USAGE); 86399ebb4caSwyllys } 8647711facfSdinak } 8657711facfSdinak 86699ebb4caSwyllys if (serstr != NULL) { 86799ebb4caSwyllys uchar_t *bytes = NULL; 86899ebb4caSwyllys size_t bytelen; 8697711facfSdinak 87030a5e8faSwyllys rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); 87199ebb4caSwyllys if (rv != KMF_OK || bytes == NULL) { 87299ebb4caSwyllys (void) fprintf(stderr, gettext("serial number " 87330a5e8faSwyllys "must be specified as a hex number " 87430a5e8faSwyllys "(ex: 0x0102030405ffeeddee)\n")); 87599ebb4caSwyllys return (PK_ERR_USAGE); 87699ebb4caSwyllys } 87799ebb4caSwyllys serial.val = bytes; 87899ebb4caSwyllys serial.len = bytelen; 8797711facfSdinak } 8807711facfSdinak 88199ebb4caSwyllys if ((kstype == KMF_KEYSTORE_PK11TOKEN || 88230a5e8faSwyllys kstype == KMF_KEYSTORE_NSS) && 88330a5e8faSwyllys (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ) || 88430a5e8faSwyllys kfmt == KMF_FORMAT_PKCS12)) { 88599ebb4caSwyllys (void) get_token_password(kstype, token_spec, 88630a5e8faSwyllys &tokencred); 8877711facfSdinak } 8887711facfSdinak 88930a5e8faSwyllys if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 89099ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Error initializing " 89130a5e8faSwyllys "KMF: 0x%02x\n"), rv); 89299ebb4caSwyllys return (rv); 8937711facfSdinak } 8947711facfSdinak 89599ebb4caSwyllys switch (kstype) { 89699ebb4caSwyllys case KMF_KEYSTORE_PK11TOKEN: 89799ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 89830a5e8faSwyllys rv = pk_export_pk12_pk11(kmfhandle, 89930a5e8faSwyllys token_spec, certlabel, 90030a5e8faSwyllys issuer, subject, 90130a5e8faSwyllys &serial, &tokencred, 90230a5e8faSwyllys filename); 90330a5e8faSwyllys else if ((oclass & PK_KEY_OBJ) || 90430a5e8faSwyllys kfmt == KMF_FORMAT_RAWKEY) 90530a5e8faSwyllys rv = pk_export_pk11_keys(kmfhandle, 90630a5e8faSwyllys token_spec, &tokencred, kfmt, 90773cc0e02Swyllys certlabel, filename, oclass); 90899ebb4caSwyllys else 90999ebb4caSwyllys rv = pk_export_pk11_objects(kmfhandle, 91030a5e8faSwyllys token_spec, certlabel, 91130a5e8faSwyllys issuer, subject, &serial, kfmt, 91230a5e8faSwyllys filename); 91399ebb4caSwyllys break; 91499ebb4caSwyllys case KMF_KEYSTORE_NSS: 91599ebb4caSwyllys if (dir == NULL) 91699ebb4caSwyllys dir = PK_DEFAULT_DIRECTORY; 91799ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 91899ebb4caSwyllys rv = pk_export_pk12_nss(kmfhandle, 91930a5e8faSwyllys token_spec, dir, prefix, 92030a5e8faSwyllys certlabel, issuer, 92130a5e8faSwyllys subject, &serial, 92230a5e8faSwyllys &tokencred, filename); 92399ebb4caSwyllys else 92499ebb4caSwyllys rv = pk_export_nss_objects(kmfhandle, 92530a5e8faSwyllys token_spec, 92630a5e8faSwyllys oclass, certlabel, issuer, subject, 92730a5e8faSwyllys &serial, kfmt, dir, prefix, filename); 92899ebb4caSwyllys break; 92999ebb4caSwyllys case KMF_KEYSTORE_OPENSSL: 93099ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 93199ebb4caSwyllys rv = pk_export_pk12_files(kmfhandle, 93230a5e8faSwyllys certfile, keyfile, dir, 93330a5e8faSwyllys filename); 93499ebb4caSwyllys else 93599ebb4caSwyllys rv = pk_export_file_objects(kmfhandle, oclass, 93630a5e8faSwyllys issuer, subject, &serial, 93730a5e8faSwyllys dir, infile, filename); 93899ebb4caSwyllys break; 93999ebb4caSwyllys default: 94099ebb4caSwyllys rv = PK_ERR_USAGE; 94199ebb4caSwyllys break; 9427711facfSdinak } 9437711facfSdinak 94499ebb4caSwyllys if (rv != KMF_OK) { 94599ebb4caSwyllys display_error(kmfhandle, rv, 94630a5e8faSwyllys gettext("Error exporting objects")); 9477711facfSdinak } 9487711facfSdinak 94999ebb4caSwyllys if (serial.val != NULL) 95099ebb4caSwyllys free(serial.val); 9517711facfSdinak 95230a5e8faSwyllys (void) kmf_finalize(kmfhandle); 9537711facfSdinak 95499ebb4caSwyllys return (rv); 9557711facfSdinak } 956