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 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 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 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 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 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 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 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 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 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