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*30a5e8faSwyllys * 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 47*30a5e8faSwyllys pk_find_export_cert(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attrlist, 48*30a5e8faSwyllys 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)); 55*30a5e8faSwyllys 56*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 57*30a5e8faSwyllys &numcerts, sizeof (uint32_t)); 58*30a5e8faSwyllys numattr++; 59*30a5e8faSwyllys 60*30a5e8faSwyllys rv = kmf_find_cert(kmfhandle, numattr, attrlist); 6199ebb4caSwyllys if (rv != KMF_OK) { 627711facfSdinak return (rv); 637711facfSdinak } 6499ebb4caSwyllys if (numcerts == 0) { 6599ebb4caSwyllys cryptoerror(LOG_STDERR, 66*30a5e8faSwyllys gettext("No matching certificates found.")); 6799ebb4caSwyllys return (KMF_ERR_CERT_NOT_FOUND); 687711facfSdinak 6999ebb4caSwyllys } else if (numcerts == 1) { 70*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 71*30a5e8faSwyllys KMF_X509_DER_CERT_ATTR, cert, 72*30a5e8faSwyllys sizeof (KMF_X509_DER_CERT)); 73*30a5e8faSwyllys numattr++; 74*30a5e8faSwyllys rv = kmf_find_cert(kmfhandle, numattr, attrlist); 757711facfSdinak 7699ebb4caSwyllys } else if (numcerts > 1) { 7799ebb4caSwyllys cryptoerror(LOG_STDERR, 78*30a5e8faSwyllys gettext("%d certificates found, refine the " 79*30a5e8faSwyllys "search parameters to eliminate ambiguity\n"), 80*30a5e8faSwyllys 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; 93*30a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 94*30a5e8faSwyllys int numattr = 0; 95*30a5e8faSwyllys 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)) { 99*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 100*30a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 101*30a5e8faSwyllys sizeof (kstype)); 102*30a5e8faSwyllys numattr++; 103*30a5e8faSwyllys 104*30a5e8faSwyllys if (issuer != NULL) { 105*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 106*30a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, 107*30a5e8faSwyllys strlen(issuer)); 108*30a5e8faSwyllys numattr++; 109*30a5e8faSwyllys } 110*30a5e8faSwyllys 111*30a5e8faSwyllys if (subject != NULL) { 112*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 113*30a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, 114*30a5e8faSwyllys strlen(subject)); 115*30a5e8faSwyllys numattr++; 116*30a5e8faSwyllys } 117*30a5e8faSwyllys 118*30a5e8faSwyllys if (serial != NULL) { 119*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 120*30a5e8faSwyllys KMF_BIGINT_ATTR, serial, 121*30a5e8faSwyllys sizeof (KMF_BIGINT)); 122*30a5e8faSwyllys numattr++; 123*30a5e8faSwyllys } 124*30a5e8faSwyllys 125*30a5e8faSwyllys if (dir != NULL) { 126*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 127*30a5e8faSwyllys KMF_DIRPATH_ATTR, dir, 128*30a5e8faSwyllys strlen(dir)); 129*30a5e8faSwyllys numattr++; 130*30a5e8faSwyllys } 131*30a5e8faSwyllys 132*30a5e8faSwyllys if (infile != NULL) { 133*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 134*30a5e8faSwyllys KMF_CERT_FILENAME_ATTR, infile, 135*30a5e8faSwyllys strlen(infile)); 136*30a5e8faSwyllys numattr++; 137*30a5e8faSwyllys } 138*30a5e8faSwyllys 139*30a5e8faSwyllys rv = pk_find_export_cert(kmfhandle, attrlist, numattr, 140*30a5e8faSwyllys &kmfcert); 14199ebb4caSwyllys if (rv == KMF_OK) { 142*30a5e8faSwyllys kstype = KMF_KEYSTORE_OPENSSL; 143*30a5e8faSwyllys numattr = 0; 14499ebb4caSwyllys 145*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 146*30a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 147*30a5e8faSwyllys numattr++; 148*30a5e8faSwyllys 149*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 150*30a5e8faSwyllys KMF_CERT_DATA_ATTR, &kmfcert.certificate, 151*30a5e8faSwyllys sizeof (KMF_DATA)); 152*30a5e8faSwyllys numattr++; 153*30a5e8faSwyllys 154*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 155*30a5e8faSwyllys KMF_CERT_FILENAME_ATTR, filename, 156*30a5e8faSwyllys strlen(filename)); 157*30a5e8faSwyllys numattr++; 158*30a5e8faSwyllys 159*30a5e8faSwyllys rv = kmf_store_cert(kmfhandle, numattr, 160*30a5e8faSwyllys attrlist); 161*30a5e8faSwyllys 162*30a5e8faSwyllys 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; 176*30a5e8faSwyllys KMF_KEYSTORE_TYPE kstype; 177*30a5e8faSwyllys KMF_CREDENTIAL p12cred = { NULL, 0}; 178*30a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 179*30a5e8faSwyllys 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 188*30a5e8faSwyllys kstype = KMF_KEYSTORE_NSS; 189*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 190*30a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 191*30a5e8faSwyllys numattr++; 192*30a5e8faSwyllys 193*30a5e8faSwyllys if (certlabel != NULL) { 194*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 195*30a5e8faSwyllys KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); 196*30a5e8faSwyllys numattr++; 197*30a5e8faSwyllys } 198*30a5e8faSwyllys 199*30a5e8faSwyllys if (issuer != NULL) { 200*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 201*30a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); 202*30a5e8faSwyllys numattr++; 203*30a5e8faSwyllys } 204*30a5e8faSwyllys 205*30a5e8faSwyllys if (subject != NULL) { 206*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 207*30a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); 208*30a5e8faSwyllys numattr++; 209*30a5e8faSwyllys } 2107711facfSdinak 211*30a5e8faSwyllys if (serial != NULL) { 212*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 213*30a5e8faSwyllys KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); 214*30a5e8faSwyllys numattr++; 215*30a5e8faSwyllys } 2167711facfSdinak 217*30a5e8faSwyllys if (tokencred != NULL) { 218*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 219*30a5e8faSwyllys KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); 220*30a5e8faSwyllys numattr++; 221*30a5e8faSwyllys } 222*30a5e8faSwyllys 223*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 224*30a5e8faSwyllys token_spec, strlen(token_spec)); 225*30a5e8faSwyllys numattr++; 226*30a5e8faSwyllys 227*30a5e8faSwyllys (void) get_pk12_password(&p12cred); 228*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 229*30a5e8faSwyllys KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); 230*30a5e8faSwyllys numattr++; 231*30a5e8faSwyllys 232*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 233*30a5e8faSwyllys KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename)); 234*30a5e8faSwyllys numattr++; 235*30a5e8faSwyllys 236*30a5e8faSwyllys rv = kmf_export_pk12(kmfhandle, numattr, attrlist); 237*30a5e8faSwyllys 238*30a5e8faSwyllys if (p12cred.cred) 239*30a5e8faSwyllys 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; 250*30a5e8faSwyllys KMF_KEYSTORE_TYPE kstype; 251*30a5e8faSwyllys KMF_CREDENTIAL p12cred = { NULL, 0}; 252*30a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 253*30a5e8faSwyllys int numattr = 0; 254*30a5e8faSwyllys 255*30a5e8faSwyllys kstype = KMF_KEYSTORE_OPENSSL; 256*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 257*30a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 258*30a5e8faSwyllys numattr++; 259*30a5e8faSwyllys 260*30a5e8faSwyllys if (dir != NULL) { 261*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 262*30a5e8faSwyllys KMF_DIRPATH_ATTR, dir, strlen(dir)); 263*30a5e8faSwyllys numattr++; 264*30a5e8faSwyllys } 2657711facfSdinak 266*30a5e8faSwyllys if (certfile != NULL) { 267*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 268*30a5e8faSwyllys KMF_CERT_FILENAME_ATTR, certfile, strlen(certfile)); 269*30a5e8faSwyllys numattr++; 270*30a5e8faSwyllys } 271*30a5e8faSwyllys 272*30a5e8faSwyllys if (keyfile != NULL) { 273*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 274*30a5e8faSwyllys KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile)); 275*30a5e8faSwyllys numattr++; 276*30a5e8faSwyllys } 2777711facfSdinak 278*30a5e8faSwyllys (void) get_pk12_password(&p12cred); 279*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 280*30a5e8faSwyllys KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); 281*30a5e8faSwyllys numattr++; 2827711facfSdinak 283*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 284*30a5e8faSwyllys KMF_OUTPUT_FILENAME_ATTR, outfile, strlen(outfile)); 285*30a5e8faSwyllys numattr++; 2867711facfSdinak 287*30a5e8faSwyllys rv = kmf_export_pk12(kmfhandle, numattr, attrlist); 2887711facfSdinak 289*30a5e8faSwyllys if (p12cred.cred) 290*30a5e8faSwyllys 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; 303*30a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 304*30a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 305*30a5e8faSwyllys 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)) { 313*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 314*30a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 315*30a5e8faSwyllys sizeof (kstype)); 316*30a5e8faSwyllys numattr++; 317*30a5e8faSwyllys 318*30a5e8faSwyllys if (certlabel != NULL) { 319*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 320*30a5e8faSwyllys KMF_CERT_LABEL_ATTR, certlabel, 321*30a5e8faSwyllys strlen(certlabel)); 322*30a5e8faSwyllys numattr++; 323*30a5e8faSwyllys } 32499ebb4caSwyllys 325*30a5e8faSwyllys if (issuer != NULL) { 326*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 327*30a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, 328*30a5e8faSwyllys strlen(issuer)); 329*30a5e8faSwyllys numattr++; 330*30a5e8faSwyllys } 33199ebb4caSwyllys 332*30a5e8faSwyllys if (subject != NULL) { 333*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 334*30a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, 335*30a5e8faSwyllys strlen(subject)); 336*30a5e8faSwyllys numattr++; 337*30a5e8faSwyllys } 338*30a5e8faSwyllys 339*30a5e8faSwyllys if (serial != NULL) { 340*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 341*30a5e8faSwyllys KMF_BIGINT_ATTR, serial, 342*30a5e8faSwyllys sizeof (KMF_BIGINT)); 343*30a5e8faSwyllys numattr++; 344*30a5e8faSwyllys } 345*30a5e8faSwyllys 346*30a5e8faSwyllys if (token_spec != NULL) { 347*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 348*30a5e8faSwyllys KMF_TOKEN_LABEL_ATTR, token_spec, 349*30a5e8faSwyllys strlen(token_spec)); 350*30a5e8faSwyllys numattr++; 351*30a5e8faSwyllys } 352*30a5e8faSwyllys 353*30a5e8faSwyllys rv = pk_find_export_cert(kmfhandle, attrlist, numattr, 354*30a5e8faSwyllys &kmfcert); 35599ebb4caSwyllys if (rv == KMF_OK) { 356*30a5e8faSwyllys kstype = KMF_KEYSTORE_OPENSSL; 357*30a5e8faSwyllys numattr = 0; 358*30a5e8faSwyllys 359*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 360*30a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 361*30a5e8faSwyllys numattr++; 36299ebb4caSwyllys 363*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 364*30a5e8faSwyllys KMF_CERT_DATA_ATTR, &kmfcert.certificate, 365*30a5e8faSwyllys sizeof (KMF_DATA)); 366*30a5e8faSwyllys numattr++; 36799ebb4caSwyllys 368*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 369*30a5e8faSwyllys KMF_CERT_FILENAME_ATTR, filename, 370*30a5e8faSwyllys strlen(filename)); 371*30a5e8faSwyllys numattr++; 372*30a5e8faSwyllys 373*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 374*30a5e8faSwyllys KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt)); 375*30a5e8faSwyllys numattr++; 376*30a5e8faSwyllys 377*30a5e8faSwyllys rv = kmf_store_cert(kmfhandle, numattr, attrlist); 378*30a5e8faSwyllys 379*30a5e8faSwyllys 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; 391*30a5e8faSwyllys KMF_KEYSTORE_TYPE kstype; 392*30a5e8faSwyllys KMF_CREDENTIAL p12cred = { NULL, 0}; 393*30a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 394*30a5e8faSwyllys int numattr = 0; 3957711facfSdinak 39699ebb4caSwyllys rv = select_token(kmfhandle, token_spec, TRUE); 39799ebb4caSwyllys if (rv != KMF_OK) { 39899ebb4caSwyllys return (rv); 3997711facfSdinak } 4007711facfSdinak 401*30a5e8faSwyllys kstype = KMF_KEYSTORE_PK11TOKEN; 402*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 403*30a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 404*30a5e8faSwyllys numattr++; 405*30a5e8faSwyllys 406*30a5e8faSwyllys if (certlabel != NULL) { 407*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 408*30a5e8faSwyllys KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); 409*30a5e8faSwyllys numattr++; 410*30a5e8faSwyllys } 411*30a5e8faSwyllys 412*30a5e8faSwyllys if (issuer != NULL) { 413*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 414*30a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); 415*30a5e8faSwyllys numattr++; 416*30a5e8faSwyllys } 417*30a5e8faSwyllys 418*30a5e8faSwyllys if (subject != NULL) { 419*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 420*30a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); 421*30a5e8faSwyllys numattr++; 422*30a5e8faSwyllys } 423*30a5e8faSwyllys 424*30a5e8faSwyllys if (serial != NULL) { 425*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 426*30a5e8faSwyllys KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); 427*30a5e8faSwyllys numattr++; 428*30a5e8faSwyllys } 429*30a5e8faSwyllys 430*30a5e8faSwyllys if (tokencred != NULL) { 431*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 432*30a5e8faSwyllys KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); 433*30a5e8faSwyllys numattr++; 434*30a5e8faSwyllys } 435*30a5e8faSwyllys 436*30a5e8faSwyllys (void) get_pk12_password(&p12cred); 437*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 438*30a5e8faSwyllys KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); 439*30a5e8faSwyllys numattr++; 440*30a5e8faSwyllys 441*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 442*30a5e8faSwyllys KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename)); 443*30a5e8faSwyllys numattr++; 444*30a5e8faSwyllys 445*30a5e8faSwyllys rv = kmf_export_pk12(kmfhandle, numattr, attrlist); 446*30a5e8faSwyllys 447*30a5e8faSwyllys if (p12cred.cred) 448*30a5e8faSwyllys free(p12cred.cred); 449*30a5e8faSwyllys 450*30a5e8faSwyllys return (rv); 451*30a5e8faSwyllys } 452*30a5e8faSwyllys 453*30a5e8faSwyllys static KMF_RETURN 454*30a5e8faSwyllys pk_export_pk11_keys(KMF_HANDLE_T kmfhandle, char *token, 455*30a5e8faSwyllys KMF_CREDENTIAL *cred, KMF_ENCODE_FORMAT format, 456*30a5e8faSwyllys char *label, char *filename) 457*30a5e8faSwyllys { 458*30a5e8faSwyllys KMF_RETURN rv = KMF_OK; 459*30a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 460*30a5e8faSwyllys int numattr = 0; 461*30a5e8faSwyllys uint32_t numkeys = 1; 462*30a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 463*30a5e8faSwyllys KMF_KEY_HANDLE key; 464*30a5e8faSwyllys KMF_KEY_CLASS keyclass = KMF_SYMMETRIC; 465*30a5e8faSwyllys boolean_t is_token = B_TRUE; 466*30a5e8faSwyllys 467*30a5e8faSwyllys if (EMPTYSTRING(label)) { 468*30a5e8faSwyllys cryptoerror(LOG_STDERR, gettext("A label " 469*30a5e8faSwyllys "must be specified to export a key.")); 470*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 471*30a5e8faSwyllys } 472*30a5e8faSwyllys 473*30a5e8faSwyllys rv = select_token(kmfhandle, token, TRUE); 474*30a5e8faSwyllys if (rv != KMF_OK) { 475*30a5e8faSwyllys return (rv); 476*30a5e8faSwyllys } 477*30a5e8faSwyllys 478*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 479*30a5e8faSwyllys &kstype, sizeof (kstype)); 480*30a5e8faSwyllys numattr++; 481*30a5e8faSwyllys 482*30a5e8faSwyllys if (cred != NULL) { 483*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 484*30a5e8faSwyllys cred, sizeof (KMF_CREDENTIAL)); 485*30a5e8faSwyllys numattr++; 486*30a5e8faSwyllys } 487*30a5e8faSwyllys 488*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, 489*30a5e8faSwyllys label, strlen(label)); 490*30a5e8faSwyllys numattr++; 491*30a5e8faSwyllys 492*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 493*30a5e8faSwyllys &numkeys, sizeof (numkeys)); 494*30a5e8faSwyllys numattr++; 4957711facfSdinak 496*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 497*30a5e8faSwyllys &key, sizeof (key)); 498*30a5e8faSwyllys numattr++; 4997711facfSdinak 500*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR, 501*30a5e8faSwyllys &is_token, sizeof (is_token)); 502*30a5e8faSwyllys numattr++; 5037711facfSdinak 504*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 505*30a5e8faSwyllys &format, sizeof (format)); 506*30a5e8faSwyllys numattr++; 507*30a5e8faSwyllys 508*30a5e8faSwyllys rv = kmf_find_key(kmfhandle, numattr, attrlist); 509*30a5e8faSwyllys if (rv == KMF_OK && key.keyclass == KMF_SYMMETRIC) { 510*30a5e8faSwyllys KMF_RAW_SYM_KEY rkey; 511*30a5e8faSwyllys 512*30a5e8faSwyllys (void) memset(&rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 513*30a5e8faSwyllys rv = kmf_get_sym_key_value(kmfhandle, &key, &rkey); 514*30a5e8faSwyllys if (rv == KMF_OK) { 515*30a5e8faSwyllys int fd, n, total = 0; 516*30a5e8faSwyllys 517*30a5e8faSwyllys fd = open(filename, O_CREAT | O_RDWR |O_TRUNC, 0600); 518*30a5e8faSwyllys if (fd == -1) { 519*30a5e8faSwyllys rv = KMF_ERR_OPEN_FILE; 520*30a5e8faSwyllys goto done; 521*30a5e8faSwyllys } 522*30a5e8faSwyllys do { 523*30a5e8faSwyllys n = write(fd, rkey.keydata.val + total, 524*30a5e8faSwyllys rkey.keydata.len - total); 525*30a5e8faSwyllys if (n < 0) { 526*30a5e8faSwyllys if (errno == EINTR) 527*30a5e8faSwyllys continue; 528*30a5e8faSwyllys close(fd); 529*30a5e8faSwyllys rv = KMF_ERR_WRITE_FILE; 530*30a5e8faSwyllys goto done; 531*30a5e8faSwyllys } 532*30a5e8faSwyllys total += n; 533*30a5e8faSwyllys 534*30a5e8faSwyllys } while (total < rkey.keydata.len); 535*30a5e8faSwyllys close(fd); 536*30a5e8faSwyllys } 537*30a5e8faSwyllys done: 538*30a5e8faSwyllys kmf_free_bigint(&rkey.keydata); 539*30a5e8faSwyllys kmf_free_kmf_key(kmfhandle, &key); 540*30a5e8faSwyllys } else if (rv == KMF_OK) { 541*30a5e8faSwyllys KMF_KEYSTORE_TYPE sslks = KMF_KEYSTORE_OPENSSL; 542*30a5e8faSwyllys printf(gettext("Found %d asymmetric keys\n"), numkeys); 543*30a5e8faSwyllys 544*30a5e8faSwyllys numattr = 0; 545*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 546*30a5e8faSwyllys &sslks, sizeof (sslks)); 547*30a5e8faSwyllys numattr++; 548*30a5e8faSwyllys 549*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR, 550*30a5e8faSwyllys key.keyp, sizeof (KMF_RAW_KEY_DATA)); 551*30a5e8faSwyllys numattr++; 552*30a5e8faSwyllys 553*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 554*30a5e8faSwyllys &format, sizeof (format)); 555*30a5e8faSwyllys numattr++; 556*30a5e8faSwyllys 557*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, 558*30a5e8faSwyllys filename, strlen(filename)); 559*30a5e8faSwyllys numattr++; 560*30a5e8faSwyllys 561*30a5e8faSwyllys rv = kmf_store_key(kmfhandle, numattr, attrlist); 562*30a5e8faSwyllys kmf_free_kmf_key(kmfhandle, &key); 563*30a5e8faSwyllys } 5647711facfSdinak 56599ebb4caSwyllys return (rv); 5667711facfSdinak } 5677711facfSdinak 56899ebb4caSwyllys static KMF_RETURN 56999ebb4caSwyllys pk_export_pk11_objects(KMF_HANDLE_T kmfhandle, char *token_spec, 57099ebb4caSwyllys char *certlabel, char *issuer, char *subject, 57199ebb4caSwyllys KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, 57299ebb4caSwyllys char *filename) 5737711facfSdinak { 57499ebb4caSwyllys KMF_RETURN rv = KMF_OK; 57599ebb4caSwyllys KMF_X509_DER_CERT kmfcert; 576*30a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 577*30a5e8faSwyllys int numattr = 0; 578*30a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 5797711facfSdinak 58099ebb4caSwyllys rv = select_token(kmfhandle, token_spec, TRUE); 5817711facfSdinak 58299ebb4caSwyllys if (rv != KMF_OK) { 5837711facfSdinak return (rv); 5847711facfSdinak } 5857711facfSdinak 586*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 587*30a5e8faSwyllys &kstype, sizeof (kstype)); 588*30a5e8faSwyllys numattr++; 5897711facfSdinak 590*30a5e8faSwyllys if (certlabel != NULL) { 591*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 592*30a5e8faSwyllys KMF_CERT_LABEL_ATTR, certlabel, 593*30a5e8faSwyllys strlen(certlabel)); 594*30a5e8faSwyllys numattr++; 595*30a5e8faSwyllys } 596*30a5e8faSwyllys 597*30a5e8faSwyllys if (issuer != NULL) { 598*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 599*30a5e8faSwyllys KMF_ISSUER_NAME_ATTR, issuer, 600*30a5e8faSwyllys strlen(issuer)); 601*30a5e8faSwyllys numattr++; 602*30a5e8faSwyllys } 603*30a5e8faSwyllys 604*30a5e8faSwyllys if (subject != NULL) { 605*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 606*30a5e8faSwyllys KMF_SUBJECT_NAME_ATTR, subject, 607*30a5e8faSwyllys strlen(subject)); 608*30a5e8faSwyllys numattr++; 609*30a5e8faSwyllys } 610*30a5e8faSwyllys 611*30a5e8faSwyllys if (serial != NULL) { 612*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 613*30a5e8faSwyllys KMF_BIGINT_ATTR, serial, 614*30a5e8faSwyllys sizeof (KMF_BIGINT)); 615*30a5e8faSwyllys numattr++; 616*30a5e8faSwyllys } 617*30a5e8faSwyllys 618*30a5e8faSwyllys rv = pk_find_export_cert(kmfhandle, attrlist, numattr, &kmfcert); 6197711facfSdinak 62099ebb4caSwyllys if (rv == KMF_OK) { 621*30a5e8faSwyllys kstype = KMF_KEYSTORE_OPENSSL; 622*30a5e8faSwyllys numattr = 0; 623*30a5e8faSwyllys 624*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 625*30a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 626*30a5e8faSwyllys numattr++; 627*30a5e8faSwyllys 628*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 629*30a5e8faSwyllys KMF_CERT_DATA_ATTR, &kmfcert.certificate, 630*30a5e8faSwyllys sizeof (KMF_DATA)); 631*30a5e8faSwyllys numattr++; 632*30a5e8faSwyllys 633*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 634*30a5e8faSwyllys KMF_CERT_FILENAME_ATTR, filename, strlen(filename)); 635*30a5e8faSwyllys numattr++; 636*30a5e8faSwyllys 637*30a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 638*30a5e8faSwyllys KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt)); 639*30a5e8faSwyllys numattr++; 6407711facfSdinak 641*30a5e8faSwyllys rv = kmf_store_cert(kmfhandle, numattr, attrlist); 6427711facfSdinak 643*30a5e8faSwyllys kmf_free_kmf_cert(kmfhandle, &kmfcert); 6447711facfSdinak } 64599ebb4caSwyllys return (rv); 6467711facfSdinak } 6477711facfSdinak 6487711facfSdinak /* 64999ebb4caSwyllys * Export objects from one keystore to a file. 6507711facfSdinak */ 6517711facfSdinak int 6527711facfSdinak pk_export(int argc, char *argv[]) 6537711facfSdinak { 65449e21299Sdinak int opt; 65549e21299Sdinak extern int optind_av; 65649e21299Sdinak extern char *optarg_av; 65749e21299Sdinak char *token_spec = NULL; 6587711facfSdinak char *filename = NULL; 65999ebb4caSwyllys char *dir = NULL; 66099ebb4caSwyllys char *prefix = NULL; 66199ebb4caSwyllys char *certlabel = NULL; 66299ebb4caSwyllys char *subject = NULL; 66399ebb4caSwyllys char *issuer = NULL; 66499ebb4caSwyllys char *infile = NULL; 66599ebb4caSwyllys char *keyfile = NULL; 66699ebb4caSwyllys char *certfile = NULL; 66799ebb4caSwyllys char *serstr = NULL; 66899ebb4caSwyllys KMF_KEYSTORE_TYPE kstype = 0; 66999ebb4caSwyllys KMF_ENCODE_FORMAT kfmt = KMF_FORMAT_PKCS12; 67099ebb4caSwyllys KMF_RETURN rv = KMF_OK; 67199ebb4caSwyllys int oclass = PK_CERT_OBJ; 67299ebb4caSwyllys KMF_BIGINT serial = { NULL, 0 }; 67399ebb4caSwyllys KMF_HANDLE_T kmfhandle = NULL; 67499ebb4caSwyllys KMF_CREDENTIAL tokencred = {NULL, 0}; 6757711facfSdinak 67649e21299Sdinak /* Parse command line options. Do NOT i18n/l10n. */ 67799ebb4caSwyllys while ((opt = getopt_av(argc, argv, 678*30a5e8faSwyllys "k:(keystore)y:(objtype)T:(token)" 679*30a5e8faSwyllys "d:(dir)p:(prefix)" 680*30a5e8faSwyllys "l:(label)n:(nickname)s:(subject)" 681*30a5e8faSwyllys "i:(issuer)S:(serial)" 682*30a5e8faSwyllys "K:(keyfile)c:(certfile)" 683*30a5e8faSwyllys "F:(outformat)" 684*30a5e8faSwyllys "I:(infile)o:(outfile)")) != EOF) { 68599ebb4caSwyllys if (EMPTYSTRING(optarg_av)) 68699ebb4caSwyllys return (PK_ERR_USAGE); 68749e21299Sdinak switch (opt) { 68899ebb4caSwyllys case 'k': 68999ebb4caSwyllys kstype = KS2Int(optarg_av); 69099ebb4caSwyllys if (kstype == 0) 69199ebb4caSwyllys return (PK_ERR_USAGE); 69299ebb4caSwyllys break; 69399ebb4caSwyllys case 'y': 69499ebb4caSwyllys oclass = OT2Int(optarg_av); 69599ebb4caSwyllys if (oclass == -1) 69699ebb4caSwyllys return (PK_ERR_USAGE); 69799ebb4caSwyllys break; 69849e21299Sdinak case 'T': /* token specifier */ 69949e21299Sdinak if (token_spec) 70049e21299Sdinak return (PK_ERR_USAGE); 70149e21299Sdinak token_spec = optarg_av; 70249e21299Sdinak break; 70399ebb4caSwyllys case 'd': 70499ebb4caSwyllys if (dir) 70599ebb4caSwyllys return (PK_ERR_USAGE); 70699ebb4caSwyllys dir = optarg_av; 70799ebb4caSwyllys break; 70899ebb4caSwyllys case 'p': 70999ebb4caSwyllys if (prefix) 71099ebb4caSwyllys return (PK_ERR_USAGE); 71199ebb4caSwyllys prefix = optarg_av; 71299ebb4caSwyllys break; 71399ebb4caSwyllys case 'n': 71499ebb4caSwyllys case 'l': 71599ebb4caSwyllys if (certlabel) 71699ebb4caSwyllys return (PK_ERR_USAGE); 71799ebb4caSwyllys certlabel = optarg_av; 71899ebb4caSwyllys break; 71999ebb4caSwyllys case 's': 72099ebb4caSwyllys if (subject) 72199ebb4caSwyllys return (PK_ERR_USAGE); 72299ebb4caSwyllys subject = optarg_av; 72399ebb4caSwyllys break; 72499ebb4caSwyllys case 'i': 72599ebb4caSwyllys if (issuer) 72699ebb4caSwyllys return (PK_ERR_USAGE); 72799ebb4caSwyllys issuer = optarg_av; 72899ebb4caSwyllys break; 72999ebb4caSwyllys case 'S': 73099ebb4caSwyllys serstr = optarg_av; 73199ebb4caSwyllys break; 73299ebb4caSwyllys case 'F': 73399ebb4caSwyllys kfmt = Str2Format(optarg_av); 73499ebb4caSwyllys if (kfmt == KMF_FORMAT_UNDEF) 73599ebb4caSwyllys return (PK_ERR_USAGE); 73699ebb4caSwyllys break; 73799ebb4caSwyllys case 'I': /* output file name */ 73899ebb4caSwyllys if (infile) 73999ebb4caSwyllys return (PK_ERR_USAGE); 74099ebb4caSwyllys infile = optarg_av; 74199ebb4caSwyllys break; 74249e21299Sdinak case 'o': /* output file name */ 74349e21299Sdinak if (filename) 74449e21299Sdinak return (PK_ERR_USAGE); 74549e21299Sdinak filename = optarg_av; 74649e21299Sdinak break; 74799ebb4caSwyllys case 'c': /* input cert file name */ 74899ebb4caSwyllys if (certfile) 74999ebb4caSwyllys return (PK_ERR_USAGE); 75099ebb4caSwyllys certfile = optarg_av; 75199ebb4caSwyllys break; 75299ebb4caSwyllys case 'K': /* input key file name */ 75399ebb4caSwyllys if (keyfile) 75499ebb4caSwyllys return (PK_ERR_USAGE); 75599ebb4caSwyllys keyfile = optarg_av; 75699ebb4caSwyllys break; 75749e21299Sdinak default: 75849e21299Sdinak return (PK_ERR_USAGE); 75949e21299Sdinak break; 76049e21299Sdinak } 76149e21299Sdinak } 7627711facfSdinak 76399ebb4caSwyllys /* Assume keystore = PKCS#11 if not specified */ 76499ebb4caSwyllys if (kstype == 0) 76599ebb4caSwyllys kstype = KMF_KEYSTORE_PK11TOKEN; 76649e21299Sdinak 76749e21299Sdinak /* Filename arg is required. */ 76899ebb4caSwyllys if (EMPTYSTRING(filename)) { 76999ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("You must specify " 770*30a5e8faSwyllys "an 'outfile' parameter when exporting.\n")); 7717711facfSdinak return (PK_ERR_USAGE); 77299ebb4caSwyllys } 7737711facfSdinak 77449e21299Sdinak /* No additional args allowed. */ 77549e21299Sdinak argc -= optind_av; 77649e21299Sdinak argv += optind_av; 77749e21299Sdinak if (argc) 77849e21299Sdinak return (PK_ERR_USAGE); 77999ebb4caSwyllys 78099ebb4caSwyllys /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ 78199ebb4caSwyllys if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && 782*30a5e8faSwyllys kstype != KMF_KEYSTORE_PK11TOKEN) { 78399ebb4caSwyllys 78499ebb4caSwyllys (void) fprintf(stderr, gettext("The objtype parameter " 785*30a5e8faSwyllys "is only relevant if keystore=pkcs11\n")); 78699ebb4caSwyllys return (PK_ERR_USAGE); 78799ebb4caSwyllys } 78899ebb4caSwyllys 78999ebb4caSwyllys if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) 79099ebb4caSwyllys token_spec = PK_DEFAULT_PK11TOKEN; 79199ebb4caSwyllys else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) 79299ebb4caSwyllys token_spec = DEFAULT_NSS_TOKEN; 79399ebb4caSwyllys 79499ebb4caSwyllys if (kstype == KMF_KEYSTORE_OPENSSL) { 79599ebb4caSwyllys if (kfmt != KMF_FORMAT_PKCS12) { 79699ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("PKCS12 " 797*30a5e8faSwyllys "is the only export format " 798*30a5e8faSwyllys "supported for the 'file' " 799*30a5e8faSwyllys "keystore.\n")); 80099ebb4caSwyllys return (PK_ERR_USAGE); 80199ebb4caSwyllys } 80299ebb4caSwyllys if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { 80399ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("A cert file" 804*30a5e8faSwyllys "and a key file must be specified " 805*30a5e8faSwyllys "when exporting to PKCS12 from the " 806*30a5e8faSwyllys "'file' keystore.\n")); 80799ebb4caSwyllys return (PK_ERR_USAGE); 80899ebb4caSwyllys } 80999ebb4caSwyllys } 8107711facfSdinak 8117711facfSdinak /* Check if the file exists and might be overwritten. */ 8127711facfSdinak if (access(filename, F_OK) == 0) { 81399ebb4caSwyllys cryptoerror(LOG_STDERR, 814*30a5e8faSwyllys gettext("Warning: file \"%s\" exists, " 815*30a5e8faSwyllys "will be overwritten."), filename); 8167711facfSdinak if (yesno(gettext("Continue with export? "), 8177711facfSdinak gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) { 8187711facfSdinak return (0); 8197711facfSdinak } 82099ebb4caSwyllys } else { 82199ebb4caSwyllys rv = verify_file(filename); 82299ebb4caSwyllys if (rv != KMF_OK) { 82399ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("The file (%s) " 824*30a5e8faSwyllys "cannot be created.\n"), filename); 82599ebb4caSwyllys return (PK_ERR_USAGE); 82699ebb4caSwyllys } 8277711facfSdinak } 8287711facfSdinak 82999ebb4caSwyllys if (serstr != NULL) { 83099ebb4caSwyllys uchar_t *bytes = NULL; 83199ebb4caSwyllys size_t bytelen; 8327711facfSdinak 833*30a5e8faSwyllys rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); 83499ebb4caSwyllys if (rv != KMF_OK || bytes == NULL) { 83599ebb4caSwyllys (void) fprintf(stderr, gettext("serial number " 836*30a5e8faSwyllys "must be specified as a hex number " 837*30a5e8faSwyllys "(ex: 0x0102030405ffeeddee)\n")); 83899ebb4caSwyllys return (PK_ERR_USAGE); 83999ebb4caSwyllys } 84099ebb4caSwyllys serial.val = bytes; 84199ebb4caSwyllys serial.len = bytelen; 8427711facfSdinak } 8437711facfSdinak 84499ebb4caSwyllys if ((kstype == KMF_KEYSTORE_PK11TOKEN || 845*30a5e8faSwyllys kstype == KMF_KEYSTORE_NSS) && 846*30a5e8faSwyllys (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ) || 847*30a5e8faSwyllys kfmt == KMF_FORMAT_PKCS12)) { 84899ebb4caSwyllys (void) get_token_password(kstype, token_spec, 849*30a5e8faSwyllys &tokencred); 8507711facfSdinak } 8517711facfSdinak 852*30a5e8faSwyllys if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 85399ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Error initializing " 854*30a5e8faSwyllys "KMF: 0x%02x\n"), rv); 85599ebb4caSwyllys return (rv); 8567711facfSdinak } 8577711facfSdinak 85899ebb4caSwyllys switch (kstype) { 85999ebb4caSwyllys case KMF_KEYSTORE_PK11TOKEN: 86099ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 861*30a5e8faSwyllys rv = pk_export_pk12_pk11(kmfhandle, 862*30a5e8faSwyllys token_spec, certlabel, 863*30a5e8faSwyllys issuer, subject, 864*30a5e8faSwyllys &serial, &tokencred, 865*30a5e8faSwyllys filename); 866*30a5e8faSwyllys else if ((oclass & PK_KEY_OBJ) || 867*30a5e8faSwyllys kfmt == KMF_FORMAT_RAWKEY) 868*30a5e8faSwyllys rv = pk_export_pk11_keys(kmfhandle, 869*30a5e8faSwyllys token_spec, &tokencred, kfmt, 870*30a5e8faSwyllys certlabel, filename); 87199ebb4caSwyllys else 87299ebb4caSwyllys rv = pk_export_pk11_objects(kmfhandle, 873*30a5e8faSwyllys token_spec, certlabel, 874*30a5e8faSwyllys issuer, subject, &serial, kfmt, 875*30a5e8faSwyllys filename); 87699ebb4caSwyllys break; 87799ebb4caSwyllys case KMF_KEYSTORE_NSS: 87899ebb4caSwyllys if (dir == NULL) 87999ebb4caSwyllys dir = PK_DEFAULT_DIRECTORY; 88099ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 88199ebb4caSwyllys rv = pk_export_pk12_nss(kmfhandle, 882*30a5e8faSwyllys token_spec, dir, prefix, 883*30a5e8faSwyllys certlabel, issuer, 884*30a5e8faSwyllys subject, &serial, 885*30a5e8faSwyllys &tokencred, filename); 88699ebb4caSwyllys else 88799ebb4caSwyllys rv = pk_export_nss_objects(kmfhandle, 888*30a5e8faSwyllys token_spec, 889*30a5e8faSwyllys oclass, certlabel, issuer, subject, 890*30a5e8faSwyllys &serial, kfmt, dir, prefix, filename); 89199ebb4caSwyllys break; 89299ebb4caSwyllys case KMF_KEYSTORE_OPENSSL: 89399ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 89499ebb4caSwyllys rv = pk_export_pk12_files(kmfhandle, 895*30a5e8faSwyllys certfile, keyfile, dir, 896*30a5e8faSwyllys filename); 89799ebb4caSwyllys else 89899ebb4caSwyllys rv = pk_export_file_objects(kmfhandle, oclass, 899*30a5e8faSwyllys issuer, subject, &serial, 900*30a5e8faSwyllys dir, infile, filename); 90199ebb4caSwyllys break; 90299ebb4caSwyllys default: 90399ebb4caSwyllys rv = PK_ERR_USAGE; 90499ebb4caSwyllys break; 9057711facfSdinak } 9067711facfSdinak 90799ebb4caSwyllys if (rv != KMF_OK) { 90899ebb4caSwyllys display_error(kmfhandle, rv, 909*30a5e8faSwyllys gettext("Error exporting objects")); 9107711facfSdinak } 9117711facfSdinak 91299ebb4caSwyllys if (serial.val != NULL) 91399ebb4caSwyllys free(serial.val); 9147711facfSdinak 915*30a5e8faSwyllys (void) kmf_finalize(kmfhandle); 9167711facfSdinak 91799ebb4caSwyllys return (rv); 9187711facfSdinak } 919