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 20*99ebb4caSwyllys * 21*99ebb4caSwyllys * 229e860378Sdinak * Copyright 2006 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> 41*99ebb4caSwyllys #include <fcntl.h> 427711facfSdinak #include "common.h" 437711facfSdinak 44*99ebb4caSwyllys #include <kmfapi.h> 457711facfSdinak 46*99ebb4caSwyllys static KMF_RETURN 47*99ebb4caSwyllys pk_find_export_cert(KMF_HANDLE_T kmfhandle, KMF_FINDCERT_PARAMS *parms, 48*99ebb4caSwyllys KMF_X509_DER_CERT *cert) 497711facfSdinak { 50*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 51*99ebb4caSwyllys uint32_t numcerts = 0; 527711facfSdinak 53*99ebb4caSwyllys numcerts = 0; 54*99ebb4caSwyllys (void) memset(cert, 0, sizeof (KMF_X509_DER_CERT)); 55*99ebb4caSwyllys rv = KMF_FindCert(kmfhandle, parms, NULL, &numcerts); 56*99ebb4caSwyllys if (rv != KMF_OK) { 577711facfSdinak return (rv); 587711facfSdinak } 59*99ebb4caSwyllys if (numcerts == 0) { 60*99ebb4caSwyllys cryptoerror(LOG_STDERR, 61*99ebb4caSwyllys gettext("No matching certificates found.")); 62*99ebb4caSwyllys return (KMF_ERR_CERT_NOT_FOUND); 637711facfSdinak 64*99ebb4caSwyllys } else if (numcerts == 1) { 65*99ebb4caSwyllys rv = KMF_FindCert(kmfhandle, parms, cert, &numcerts); 667711facfSdinak 67*99ebb4caSwyllys } else if (numcerts > 1) { 68*99ebb4caSwyllys cryptoerror(LOG_STDERR, 69*99ebb4caSwyllys gettext("%d certificates found, refine the " 70*99ebb4caSwyllys "search parameters to eliminate ambiguity\n"), 71*99ebb4caSwyllys numcerts); 72*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 737711facfSdinak } 74*99ebb4caSwyllys return (rv); 757711facfSdinak } 767711facfSdinak 77*99ebb4caSwyllys static KMF_RETURN 78*99ebb4caSwyllys pk_export_file_objects(KMF_HANDLE_T kmfhandle, int oclass, 79*99ebb4caSwyllys char *issuer, char *subject, KMF_BIGINT *serial, 80*99ebb4caSwyllys KMF_ENCODE_FORMAT ofmt, 81*99ebb4caSwyllys char *dir, char *infile, char *filename) 827711facfSdinak { 83*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 84*99ebb4caSwyllys KMF_STORECERT_PARAMS scparms; 85*99ebb4caSwyllys KMF_X509_DER_CERT kmfcert; 86*99ebb4caSwyllys 87*99ebb4caSwyllys /* If searching for public objects or certificates, find certs now */ 88*99ebb4caSwyllys if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) { 89*99ebb4caSwyllys KMF_FINDCERT_PARAMS fcargs; 90*99ebb4caSwyllys 91*99ebb4caSwyllys (void) memset(&fcargs, 0, sizeof (fcargs)); 92*99ebb4caSwyllys fcargs.kstype = KMF_KEYSTORE_OPENSSL; 93*99ebb4caSwyllys fcargs.certLabel = NULL; 94*99ebb4caSwyllys fcargs.issuer = issuer; 95*99ebb4caSwyllys fcargs.subject = subject; 96*99ebb4caSwyllys fcargs.serial = serial; 97*99ebb4caSwyllys fcargs.sslparms.dirpath = dir; 98*99ebb4caSwyllys fcargs.sslparms.certfile = infile; 99*99ebb4caSwyllys fcargs.sslparms.format = ofmt; 100*99ebb4caSwyllys 101*99ebb4caSwyllys rv = pk_find_export_cert(kmfhandle, &fcargs, &kmfcert); 102*99ebb4caSwyllys if (rv == KMF_OK) { 103*99ebb4caSwyllys (void) memset(&scparms, 0, sizeof (scparms)); 104*99ebb4caSwyllys scparms.kstype = KMF_KEYSTORE_OPENSSL; 105*99ebb4caSwyllys scparms.sslparms.certfile = filename; 106*99ebb4caSwyllys rv = KMF_StoreCert(kmfhandle, &scparms, 107*99ebb4caSwyllys &kmfcert.certificate); 108*99ebb4caSwyllys 109*99ebb4caSwyllys KMF_FreeKMFCert(kmfhandle, &kmfcert); 110*99ebb4caSwyllys } 111*99ebb4caSwyllys } 112*99ebb4caSwyllys return (rv); 1137711facfSdinak } 1147711facfSdinak 115*99ebb4caSwyllys static KMF_RETURN 116*99ebb4caSwyllys pk_export_pk12_nss(KMF_HANDLE_T kmfhandle, 117*99ebb4caSwyllys char *token_spec, char *dir, char *prefix, 118*99ebb4caSwyllys char *certlabel, char *issuer, char *subject, 119*99ebb4caSwyllys KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, 120*99ebb4caSwyllys char *filename) 1217711facfSdinak { 122*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 123*99ebb4caSwyllys KMF_EXPORTP12_PARAMS p12parms; 1247711facfSdinak 125*99ebb4caSwyllys rv = configure_nss(kmfhandle, dir, prefix); 126*99ebb4caSwyllys if (rv != KMF_OK) 1277711facfSdinak return (rv); 1287711facfSdinak 129*99ebb4caSwyllys (void) memset(&p12parms, 0, sizeof (p12parms)); 130*99ebb4caSwyllys if (token_spec == NULL) 131*99ebb4caSwyllys token_spec = DEFAULT_NSS_TOKEN; 1327711facfSdinak 133*99ebb4caSwyllys p12parms.kstype = KMF_KEYSTORE_NSS; 134*99ebb4caSwyllys p12parms.certLabel = certlabel; 135*99ebb4caSwyllys p12parms.issuer = issuer; 136*99ebb4caSwyllys p12parms.subject = subject; 137*99ebb4caSwyllys p12parms.serial = serial; 138*99ebb4caSwyllys p12parms.idstr = NULL; 139*99ebb4caSwyllys if (tokencred != NULL) 140*99ebb4caSwyllys p12parms.cred = *tokencred; 141*99ebb4caSwyllys p12parms.nssparms.slotlabel = token_spec; 1427711facfSdinak 143*99ebb4caSwyllys (void) get_pk12_password(&p12parms.p12cred); 1447711facfSdinak 145*99ebb4caSwyllys rv = KMF_ExportPK12(kmfhandle, &p12parms, filename); 146*99ebb4caSwyllys if (p12parms.p12cred.cred) 147*99ebb4caSwyllys free(p12parms.p12cred.cred); 1487711facfSdinak 149*99ebb4caSwyllys return (rv); 1507711facfSdinak } 1517711facfSdinak 152*99ebb4caSwyllys static KMF_RETURN 153*99ebb4caSwyllys pk_export_pk12_files(KMF_HANDLE_T kmfhandle, 154*99ebb4caSwyllys char *certfile, char *keyfile, char *dir, 155*99ebb4caSwyllys char *outfile) 1567711facfSdinak { 157*99ebb4caSwyllys KMF_RETURN rv; 158*99ebb4caSwyllys KMF_EXPORTP12_PARAMS p12parms; 1597711facfSdinak 160*99ebb4caSwyllys (void) memset(&p12parms, 0, sizeof (p12parms)); 1617711facfSdinak 162*99ebb4caSwyllys p12parms.kstype = KMF_KEYSTORE_OPENSSL; 163*99ebb4caSwyllys p12parms.certLabel = NULL; 164*99ebb4caSwyllys p12parms.issuer = NULL; 165*99ebb4caSwyllys p12parms.subject = NULL; 166*99ebb4caSwyllys p12parms.serial = 0; 167*99ebb4caSwyllys p12parms.idstr = NULL; 168*99ebb4caSwyllys p12parms.sslparms.dirpath = dir; 169*99ebb4caSwyllys p12parms.sslparms.certfile = certfile; 170*99ebb4caSwyllys p12parms.sslparms.keyfile = keyfile; 1717711facfSdinak 172*99ebb4caSwyllys (void) get_pk12_password(&p12parms.p12cred); 1737711facfSdinak 174*99ebb4caSwyllys rv = KMF_ExportPK12(kmfhandle, &p12parms, outfile); 1757711facfSdinak 176*99ebb4caSwyllys if (p12parms.p12cred.cred) 177*99ebb4caSwyllys free(p12parms.p12cred.cred); 1787711facfSdinak 179*99ebb4caSwyllys return (rv); 1807711facfSdinak } 1817711facfSdinak 182*99ebb4caSwyllys static KMF_RETURN 183*99ebb4caSwyllys pk_export_nss_objects(KMF_HANDLE_T kmfhandle, char *token_spec, 184*99ebb4caSwyllys int oclass, char *certlabel, char *issuer, char *subject, 185*99ebb4caSwyllys KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, char *dir, 186*99ebb4caSwyllys char *prefix, char *filename) 1877711facfSdinak { 188*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 189*99ebb4caSwyllys KMF_STORECERT_PARAMS scparms; 190*99ebb4caSwyllys KMF_X509_DER_CERT kmfcert; 1917711facfSdinak 192*99ebb4caSwyllys rv = configure_nss(kmfhandle, dir, prefix); 193*99ebb4caSwyllys if (rv != KMF_OK) 1947711facfSdinak return (rv); 1957711facfSdinak 196*99ebb4caSwyllys /* If searching for public objects or certificates, find certs now */ 197*99ebb4caSwyllys if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) { 198*99ebb4caSwyllys KMF_FINDCERT_PARAMS fcargs; 199*99ebb4caSwyllys 200*99ebb4caSwyllys (void) memset(&fcargs, 0, sizeof (fcargs)); 201*99ebb4caSwyllys fcargs.kstype = KMF_KEYSTORE_NSS; 202*99ebb4caSwyllys fcargs.certLabel = certlabel; 203*99ebb4caSwyllys fcargs.issuer = issuer; 204*99ebb4caSwyllys fcargs.subject = subject; 205*99ebb4caSwyllys fcargs.serial = serial; 206*99ebb4caSwyllys fcargs.nssparms.slotlabel = token_spec; 207*99ebb4caSwyllys 208*99ebb4caSwyllys rv = pk_find_export_cert(kmfhandle, &fcargs, &kmfcert); 209*99ebb4caSwyllys if (rv == KMF_OK) { 210*99ebb4caSwyllys (void) memset(&scparms, 0, sizeof (scparms)); 211*99ebb4caSwyllys scparms.kstype = KMF_KEYSTORE_OPENSSL; 212*99ebb4caSwyllys scparms.sslparms.certfile = filename; 213*99ebb4caSwyllys scparms.sslparms.format = kfmt; 214*99ebb4caSwyllys 215*99ebb4caSwyllys rv = KMF_StoreCert(kmfhandle, &scparms, 216*99ebb4caSwyllys &kmfcert.certificate); 217*99ebb4caSwyllys 218*99ebb4caSwyllys KMF_FreeKMFCert(kmfhandle, &kmfcert); 2197711facfSdinak } 2207711facfSdinak } 221*99ebb4caSwyllys return (rv); 222*99ebb4caSwyllys } 2237711facfSdinak 224*99ebb4caSwyllys static KMF_RETURN 225*99ebb4caSwyllys pk_export_pk12_pk11(KMF_HANDLE_T kmfhandle, char *token_spec, 226*99ebb4caSwyllys char *certlabel, char *issuer, char *subject, 227*99ebb4caSwyllys KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, char *filename) 228*99ebb4caSwyllys { 229*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 230*99ebb4caSwyllys KMF_EXPORTP12_PARAMS p12parms; 2317711facfSdinak 232*99ebb4caSwyllys rv = select_token(kmfhandle, token_spec, TRUE); 233*99ebb4caSwyllys if (rv != KMF_OK) { 234*99ebb4caSwyllys return (rv); 2357711facfSdinak } 2367711facfSdinak 237*99ebb4caSwyllys (void) memset(&p12parms, 0, sizeof (p12parms)); 2387711facfSdinak 239*99ebb4caSwyllys p12parms.kstype = KMF_KEYSTORE_PK11TOKEN; 240*99ebb4caSwyllys p12parms.certLabel = certlabel; 241*99ebb4caSwyllys p12parms.issuer = issuer; 242*99ebb4caSwyllys p12parms.subject = subject; 243*99ebb4caSwyllys p12parms.serial = serial; 244*99ebb4caSwyllys p12parms.idstr = NULL; 245*99ebb4caSwyllys if (tokencred != NULL) 246*99ebb4caSwyllys p12parms.cred = *tokencred; 247*99ebb4caSwyllys (void) get_pk12_password(&p12parms.p12cred); 2487711facfSdinak 249*99ebb4caSwyllys rv = KMF_ExportPK12(kmfhandle, &p12parms, filename); 2507711facfSdinak 251*99ebb4caSwyllys if (p12parms.p12cred.cred) 252*99ebb4caSwyllys free(p12parms.p12cred.cred); 2537711facfSdinak 254*99ebb4caSwyllys return (rv); 2557711facfSdinak } 2567711facfSdinak 257*99ebb4caSwyllys static KMF_RETURN 258*99ebb4caSwyllys pk_export_pk11_objects(KMF_HANDLE_T kmfhandle, char *token_spec, 259*99ebb4caSwyllys char *certlabel, char *issuer, char *subject, 260*99ebb4caSwyllys KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, 261*99ebb4caSwyllys char *filename) 2627711facfSdinak { 263*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 264*99ebb4caSwyllys KMF_FINDCERT_PARAMS fcparms; 265*99ebb4caSwyllys KMF_STORECERT_PARAMS scparms; 266*99ebb4caSwyllys KMF_X509_DER_CERT kmfcert; 2677711facfSdinak 268*99ebb4caSwyllys rv = select_token(kmfhandle, token_spec, TRUE); 2697711facfSdinak 270*99ebb4caSwyllys if (rv != KMF_OK) { 2717711facfSdinak return (rv); 2727711facfSdinak } 2737711facfSdinak 274*99ebb4caSwyllys (void) memset(&fcparms, 0, sizeof (fcparms)); 275*99ebb4caSwyllys fcparms.kstype = KMF_KEYSTORE_PK11TOKEN; 276*99ebb4caSwyllys fcparms.certLabel = certlabel; 277*99ebb4caSwyllys fcparms.issuer = issuer; 278*99ebb4caSwyllys fcparms.subject = subject; 279*99ebb4caSwyllys fcparms.serial = serial; 2807711facfSdinak 281*99ebb4caSwyllys rv = pk_find_export_cert(kmfhandle, &fcparms, &kmfcert); 2827711facfSdinak 283*99ebb4caSwyllys if (rv == KMF_OK) { 284*99ebb4caSwyllys (void) memset(&scparms, 0, sizeof (scparms)); 285*99ebb4caSwyllys scparms.kstype = KMF_KEYSTORE_OPENSSL; 286*99ebb4caSwyllys scparms.sslparms.certfile = filename; 287*99ebb4caSwyllys scparms.sslparms.format = kfmt; 2887711facfSdinak 289*99ebb4caSwyllys rv = KMF_StoreCert(kmfhandle, &scparms, 290*99ebb4caSwyllys &kmfcert.certificate); 2917711facfSdinak 292*99ebb4caSwyllys KMF_FreeKMFCert(kmfhandle, &kmfcert); 2937711facfSdinak } 294*99ebb4caSwyllys return (rv); 2957711facfSdinak } 2967711facfSdinak 2977711facfSdinak /* 298*99ebb4caSwyllys * Export objects from one keystore to a file. 2997711facfSdinak */ 3007711facfSdinak int 3017711facfSdinak pk_export(int argc, char *argv[]) 3027711facfSdinak { 30349e21299Sdinak int opt; 30449e21299Sdinak extern int optind_av; 30549e21299Sdinak extern char *optarg_av; 30649e21299Sdinak char *token_spec = NULL; 3077711facfSdinak char *filename = NULL; 308*99ebb4caSwyllys char *dir = NULL; 309*99ebb4caSwyllys char *prefix = NULL; 310*99ebb4caSwyllys char *certlabel = NULL; 311*99ebb4caSwyllys char *subject = NULL; 312*99ebb4caSwyllys char *issuer = NULL; 313*99ebb4caSwyllys char *infile = NULL; 314*99ebb4caSwyllys char *keyfile = NULL; 315*99ebb4caSwyllys char *certfile = NULL; 316*99ebb4caSwyllys char *serstr = NULL; 317*99ebb4caSwyllys KMF_KEYSTORE_TYPE kstype = 0; 318*99ebb4caSwyllys KMF_ENCODE_FORMAT kfmt = KMF_FORMAT_PKCS12; 319*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 320*99ebb4caSwyllys int oclass = PK_CERT_OBJ; 321*99ebb4caSwyllys KMF_BIGINT serial = { NULL, 0 }; 322*99ebb4caSwyllys KMF_HANDLE_T kmfhandle = NULL; 323*99ebb4caSwyllys KMF_CREDENTIAL tokencred = {NULL, 0}; 3247711facfSdinak 32549e21299Sdinak /* Parse command line options. Do NOT i18n/l10n. */ 326*99ebb4caSwyllys while ((opt = getopt_av(argc, argv, 327*99ebb4caSwyllys "k:(keystore)y:(objtype)T:(token)" 328*99ebb4caSwyllys "d:(dir)p:(prefix)" 329*99ebb4caSwyllys "l:(label)n:(nickname)s:(subject)" 330*99ebb4caSwyllys "i:(issuer)S:(serial)" 331*99ebb4caSwyllys "K:(keyfile)c:(certfile)" 332*99ebb4caSwyllys "F:(outformat)" 333*99ebb4caSwyllys "I:(infile)o:(outfile)")) != EOF) { 334*99ebb4caSwyllys if (EMPTYSTRING(optarg_av)) 335*99ebb4caSwyllys return (PK_ERR_USAGE); 33649e21299Sdinak switch (opt) { 337*99ebb4caSwyllys case 'k': 338*99ebb4caSwyllys kstype = KS2Int(optarg_av); 339*99ebb4caSwyllys if (kstype == 0) 340*99ebb4caSwyllys return (PK_ERR_USAGE); 341*99ebb4caSwyllys break; 342*99ebb4caSwyllys case 'y': 343*99ebb4caSwyllys oclass = OT2Int(optarg_av); 344*99ebb4caSwyllys if (oclass == -1) 345*99ebb4caSwyllys return (PK_ERR_USAGE); 346*99ebb4caSwyllys break; 34749e21299Sdinak case 'T': /* token specifier */ 34849e21299Sdinak if (token_spec) 34949e21299Sdinak return (PK_ERR_USAGE); 35049e21299Sdinak token_spec = optarg_av; 35149e21299Sdinak break; 352*99ebb4caSwyllys case 'd': 353*99ebb4caSwyllys if (dir) 354*99ebb4caSwyllys return (PK_ERR_USAGE); 355*99ebb4caSwyllys dir = optarg_av; 356*99ebb4caSwyllys break; 357*99ebb4caSwyllys case 'p': 358*99ebb4caSwyllys if (prefix) 359*99ebb4caSwyllys return (PK_ERR_USAGE); 360*99ebb4caSwyllys prefix = optarg_av; 361*99ebb4caSwyllys break; 362*99ebb4caSwyllys case 'n': 363*99ebb4caSwyllys case 'l': 364*99ebb4caSwyllys if (certlabel) 365*99ebb4caSwyllys return (PK_ERR_USAGE); 366*99ebb4caSwyllys certlabel = optarg_av; 367*99ebb4caSwyllys break; 368*99ebb4caSwyllys case 's': 369*99ebb4caSwyllys if (subject) 370*99ebb4caSwyllys return (PK_ERR_USAGE); 371*99ebb4caSwyllys subject = optarg_av; 372*99ebb4caSwyllys break; 373*99ebb4caSwyllys case 'i': 374*99ebb4caSwyllys if (issuer) 375*99ebb4caSwyllys return (PK_ERR_USAGE); 376*99ebb4caSwyllys issuer = optarg_av; 377*99ebb4caSwyllys break; 378*99ebb4caSwyllys case 'S': 379*99ebb4caSwyllys serstr = optarg_av; 380*99ebb4caSwyllys break; 381*99ebb4caSwyllys case 'F': 382*99ebb4caSwyllys kfmt = Str2Format(optarg_av); 383*99ebb4caSwyllys if (kfmt == KMF_FORMAT_UNDEF) 384*99ebb4caSwyllys return (PK_ERR_USAGE); 385*99ebb4caSwyllys break; 386*99ebb4caSwyllys case 'I': /* output file name */ 387*99ebb4caSwyllys if (infile) 388*99ebb4caSwyllys return (PK_ERR_USAGE); 389*99ebb4caSwyllys infile = optarg_av; 390*99ebb4caSwyllys break; 39149e21299Sdinak case 'o': /* output file name */ 39249e21299Sdinak if (filename) 39349e21299Sdinak return (PK_ERR_USAGE); 39449e21299Sdinak filename = optarg_av; 39549e21299Sdinak break; 396*99ebb4caSwyllys case 'c': /* input cert file name */ 397*99ebb4caSwyllys if (certfile) 398*99ebb4caSwyllys return (PK_ERR_USAGE); 399*99ebb4caSwyllys certfile = optarg_av; 400*99ebb4caSwyllys break; 401*99ebb4caSwyllys case 'K': /* input key file name */ 402*99ebb4caSwyllys if (keyfile) 403*99ebb4caSwyllys return (PK_ERR_USAGE); 404*99ebb4caSwyllys keyfile = optarg_av; 405*99ebb4caSwyllys break; 40649e21299Sdinak default: 40749e21299Sdinak return (PK_ERR_USAGE); 40849e21299Sdinak break; 40949e21299Sdinak } 41049e21299Sdinak } 4117711facfSdinak 412*99ebb4caSwyllys /* Assume keystore = PKCS#11 if not specified */ 413*99ebb4caSwyllys if (kstype == 0) 414*99ebb4caSwyllys kstype = KMF_KEYSTORE_PK11TOKEN; 41549e21299Sdinak 41649e21299Sdinak /* Filename arg is required. */ 417*99ebb4caSwyllys if (EMPTYSTRING(filename)) { 418*99ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("You must specify " 419*99ebb4caSwyllys "an 'outfile' parameter when exporting.\n")); 4207711facfSdinak return (PK_ERR_USAGE); 421*99ebb4caSwyllys } 4227711facfSdinak 42349e21299Sdinak /* No additional args allowed. */ 42449e21299Sdinak argc -= optind_av; 42549e21299Sdinak argv += optind_av; 42649e21299Sdinak if (argc) 42749e21299Sdinak return (PK_ERR_USAGE); 428*99ebb4caSwyllys 429*99ebb4caSwyllys /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ 430*99ebb4caSwyllys if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && 431*99ebb4caSwyllys kstype != KMF_KEYSTORE_PK11TOKEN) { 432*99ebb4caSwyllys 433*99ebb4caSwyllys (void) fprintf(stderr, gettext("The objtype parameter " 434*99ebb4caSwyllys "is only relevant if keystore=pkcs11\n")); 435*99ebb4caSwyllys return (PK_ERR_USAGE); 436*99ebb4caSwyllys } 437*99ebb4caSwyllys 438*99ebb4caSwyllys if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) 439*99ebb4caSwyllys token_spec = PK_DEFAULT_PK11TOKEN; 440*99ebb4caSwyllys else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) 441*99ebb4caSwyllys token_spec = DEFAULT_NSS_TOKEN; 442*99ebb4caSwyllys 443*99ebb4caSwyllys if (kstype == KMF_KEYSTORE_OPENSSL) { 444*99ebb4caSwyllys if (kfmt != KMF_FORMAT_PKCS12) { 445*99ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("PKCS12 " 446*99ebb4caSwyllys "is the only export format " 447*99ebb4caSwyllys "supported for the 'file' " 448*99ebb4caSwyllys "keystore.\n")); 449*99ebb4caSwyllys return (PK_ERR_USAGE); 450*99ebb4caSwyllys } 451*99ebb4caSwyllys if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { 452*99ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("A cert file" 453*99ebb4caSwyllys "and a key file must be specified " 454*99ebb4caSwyllys "when exporting to PKCS12 from the " 455*99ebb4caSwyllys "'file' keystore.\n")); 456*99ebb4caSwyllys return (PK_ERR_USAGE); 457*99ebb4caSwyllys } 458*99ebb4caSwyllys } 4597711facfSdinak 4607711facfSdinak /* Check if the file exists and might be overwritten. */ 4617711facfSdinak if (access(filename, F_OK) == 0) { 462*99ebb4caSwyllys cryptoerror(LOG_STDERR, 463*99ebb4caSwyllys gettext("Warning: file \"%s\" exists, " 464*99ebb4caSwyllys "will be overwritten."), filename); 4657711facfSdinak if (yesno(gettext("Continue with export? "), 4667711facfSdinak gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) { 4677711facfSdinak return (0); 4687711facfSdinak } 469*99ebb4caSwyllys } else { 470*99ebb4caSwyllys rv = verify_file(filename); 471*99ebb4caSwyllys if (rv != KMF_OK) { 472*99ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("The file (%s) " 473*99ebb4caSwyllys "cannot be created.\n"), filename); 474*99ebb4caSwyllys return (PK_ERR_USAGE); 475*99ebb4caSwyllys } 4767711facfSdinak } 4777711facfSdinak 478*99ebb4caSwyllys if (serstr != NULL) { 479*99ebb4caSwyllys uchar_t *bytes = NULL; 480*99ebb4caSwyllys size_t bytelen; 4817711facfSdinak 482*99ebb4caSwyllys rv = KMF_HexString2Bytes((uchar_t *)serstr, &bytes, &bytelen); 483*99ebb4caSwyllys if (rv != KMF_OK || bytes == NULL) { 484*99ebb4caSwyllys (void) fprintf(stderr, gettext("serial number " 485*99ebb4caSwyllys "must be specified as a hex number " 486*99ebb4caSwyllys "(ex: 0x0102030405ffeeddee)\n")); 487*99ebb4caSwyllys return (PK_ERR_USAGE); 488*99ebb4caSwyllys } 489*99ebb4caSwyllys serial.val = bytes; 490*99ebb4caSwyllys serial.len = bytelen; 4917711facfSdinak } 4927711facfSdinak 493*99ebb4caSwyllys if ((kstype == KMF_KEYSTORE_PK11TOKEN || 494*99ebb4caSwyllys kstype == KMF_KEYSTORE_NSS) && 495*99ebb4caSwyllys (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ) || 496*99ebb4caSwyllys kfmt == KMF_FORMAT_PKCS12)) { 497*99ebb4caSwyllys (void) get_token_password(kstype, token_spec, 498*99ebb4caSwyllys &tokencred); 4997711facfSdinak } 5007711facfSdinak 501*99ebb4caSwyllys if ((rv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 502*99ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Error initializing " 503*99ebb4caSwyllys "KMF: 0x%02x\n"), rv); 504*99ebb4caSwyllys return (rv); 5057711facfSdinak } 5067711facfSdinak 507*99ebb4caSwyllys switch (kstype) { 508*99ebb4caSwyllys case KMF_KEYSTORE_PK11TOKEN: 509*99ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 510*99ebb4caSwyllys rv = pk_export_pk12_pk11( 511*99ebb4caSwyllys kmfhandle, 512*99ebb4caSwyllys token_spec, 513*99ebb4caSwyllys certlabel, 514*99ebb4caSwyllys issuer, subject, 515*99ebb4caSwyllys &serial, &tokencred, 516*99ebb4caSwyllys filename); 517*99ebb4caSwyllys else 518*99ebb4caSwyllys rv = pk_export_pk11_objects(kmfhandle, 519*99ebb4caSwyllys token_spec, 520*99ebb4caSwyllys certlabel, 521*99ebb4caSwyllys issuer, subject, 522*99ebb4caSwyllys &serial, kfmt, 523*99ebb4caSwyllys filename); 524*99ebb4caSwyllys break; 525*99ebb4caSwyllys case KMF_KEYSTORE_NSS: 526*99ebb4caSwyllys if (dir == NULL) 527*99ebb4caSwyllys dir = PK_DEFAULT_DIRECTORY; 528*99ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 529*99ebb4caSwyllys rv = pk_export_pk12_nss(kmfhandle, 530*99ebb4caSwyllys token_spec, dir, prefix, 531*99ebb4caSwyllys certlabel, issuer, 532*99ebb4caSwyllys subject, &serial, 533*99ebb4caSwyllys &tokencred, filename); 534*99ebb4caSwyllys else 535*99ebb4caSwyllys rv = pk_export_nss_objects(kmfhandle, 536*99ebb4caSwyllys token_spec, 537*99ebb4caSwyllys oclass, certlabel, issuer, subject, 538*99ebb4caSwyllys &serial, kfmt, dir, prefix, filename); 539*99ebb4caSwyllys break; 540*99ebb4caSwyllys case KMF_KEYSTORE_OPENSSL: 541*99ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 542*99ebb4caSwyllys rv = pk_export_pk12_files(kmfhandle, 543*99ebb4caSwyllys certfile, keyfile, dir, 544*99ebb4caSwyllys filename); 545*99ebb4caSwyllys else 546*99ebb4caSwyllys rv = pk_export_file_objects(kmfhandle, oclass, 547*99ebb4caSwyllys issuer, subject, &serial, kfmt, 548*99ebb4caSwyllys dir, infile, filename); 549*99ebb4caSwyllys break; 550*99ebb4caSwyllys default: 551*99ebb4caSwyllys rv = PK_ERR_USAGE; 552*99ebb4caSwyllys break; 5537711facfSdinak } 5547711facfSdinak 555*99ebb4caSwyllys if (rv != KMF_OK) { 556*99ebb4caSwyllys display_error(kmfhandle, rv, 557*99ebb4caSwyllys gettext("Error exporting objects")); 5587711facfSdinak } 5597711facfSdinak 560*99ebb4caSwyllys if (serial.val != NULL) 561*99ebb4caSwyllys free(serial.val); 5627711facfSdinak 563*99ebb4caSwyllys (void) KMF_Finalize(kmfhandle); 5647711facfSdinak 565*99ebb4caSwyllys return (rv); 5667711facfSdinak } 567