/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * This file implements the export operation for this tool. * The basic flow of the process is to find the soft token, * log into it, find the PKCS#11 objects in the soft token * to be exported matching keys with their certificates, export * them to the PKCS#12 file encrypting them with a file password * if desired, and log out. */ #include #include #include #include #include #include "common.h" #include static KMF_RETURN pk_find_export_cert(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attrlist, int numattr, KMF_X509_DER_CERT *cert) { KMF_RETURN rv = KMF_OK; uint32_t numcerts = 0; numcerts = 0; (void) memset(cert, 0, sizeof (KMF_X509_DER_CERT)); kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t)); numattr++; rv = kmf_find_cert(kmfhandle, numattr, attrlist); if (rv != KMF_OK) { return (rv); } if (numcerts == 0) { cryptoerror(LOG_STDERR, gettext("No matching certificates found.")); return (KMF_ERR_CERT_NOT_FOUND); } else if (numcerts == 1) { kmf_set_attr_at_index(attrlist, numattr, KMF_X509_DER_CERT_ATTR, cert, sizeof (KMF_X509_DER_CERT)); numattr++; rv = kmf_find_cert(kmfhandle, numattr, attrlist); } else if (numcerts > 1) { cryptoerror(LOG_STDERR, gettext("%d certificates found, refine the " "search parameters to eliminate ambiguity\n"), numcerts); return (KMF_ERR_BAD_PARAMETER); } return (rv); } static KMF_RETURN pk_export_file_objects(KMF_HANDLE_T kmfhandle, int oclass, char *issuer, char *subject, KMF_BIGINT *serial, char *dir, char *infile, char *filename) { KMF_RETURN rv = KMF_OK; KMF_X509_DER_CERT kmfcert; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; int numattr = 0; KMF_ATTRIBUTE attrlist[16]; /* If searching for public objects or certificates, find certs now */ if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (issuer != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); numattr++; } if (subject != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); numattr++; } if (serial != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); numattr++; } if (dir != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR, dir, strlen(dir)); numattr++; } if (infile != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR, infile, strlen(infile)); numattr++; } rv = pk_find_export_cert(kmfhandle, attrlist, numattr, &kmfcert); if (rv == KMF_OK) { kstype = KMF_KEYSTORE_OPENSSL; numattr = 0; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, &kmfcert.certificate, sizeof (KMF_DATA)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR, filename, strlen(filename)); numattr++; rv = kmf_store_cert(kmfhandle, numattr, attrlist); kmf_free_kmf_cert(kmfhandle, &kmfcert); } } return (rv); } static KMF_RETURN pk_export_pk12_nss(KMF_HANDLE_T kmfhandle, char *token_spec, char *dir, char *prefix, char *certlabel, char *issuer, char *subject, KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, char *filename) { KMF_RETURN rv = KMF_OK; KMF_KEYSTORE_TYPE kstype; KMF_CREDENTIAL p12cred = { NULL, 0}; KMF_ATTRIBUTE attrlist[16]; int numattr = 0; rv = configure_nss(kmfhandle, dir, prefix); if (rv != KMF_OK) return (rv); if (token_spec == NULL) token_spec = DEFAULT_NSS_TOKEN; kstype = KMF_KEYSTORE_NSS; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (certlabel != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); numattr++; } if (issuer != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); numattr++; } if (subject != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); numattr++; } if (serial != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); numattr++; } if (tokencred != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); numattr++; } kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, token_spec, strlen(token_spec)); numattr++; (void) get_pk12_password(&p12cred); kmf_set_attr_at_index(attrlist, numattr, KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename)); numattr++; rv = kmf_export_pk12(kmfhandle, numattr, attrlist); if (p12cred.cred) free(p12cred.cred); return (rv); } static KMF_RETURN pk_export_pk12_files(KMF_HANDLE_T kmfhandle, char *certfile, char *keyfile, char *dir, char *outfile) { KMF_RETURN rv; KMF_KEYSTORE_TYPE kstype; KMF_CREDENTIAL p12cred = { NULL, 0}; KMF_ATTRIBUTE attrlist[16]; int numattr = 0; kstype = KMF_KEYSTORE_OPENSSL; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (dir != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR, dir, strlen(dir)); numattr++; } if (certfile != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR, certfile, strlen(certfile)); numattr++; } if (keyfile != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile)); numattr++; } (void) get_pk12_password(&p12cred); kmf_set_attr_at_index(attrlist, numattr, KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_OUTPUT_FILENAME_ATTR, outfile, strlen(outfile)); numattr++; rv = kmf_export_pk12(kmfhandle, numattr, attrlist); if (p12cred.cred) free(p12cred.cred); return (rv); } static KMF_RETURN pk_export_nss_objects(KMF_HANDLE_T kmfhandle, char *token_spec, int oclass, char *certlabel, char *issuer, char *subject, KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, char *dir, char *prefix, char *filename) { KMF_RETURN rv = KMF_OK; KMF_X509_DER_CERT kmfcert; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; KMF_ATTRIBUTE attrlist[16]; int numattr = 0; rv = configure_nss(kmfhandle, dir, prefix); if (rv != KMF_OK) return (rv); /* If searching for public objects or certificates, find certs now */ if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (certlabel != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); numattr++; } if (issuer != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); numattr++; } if (subject != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); numattr++; } if (serial != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); numattr++; } if (token_spec != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, token_spec, strlen(token_spec)); numattr++; } rv = pk_find_export_cert(kmfhandle, attrlist, numattr, &kmfcert); if (rv == KMF_OK) { kstype = KMF_KEYSTORE_OPENSSL; numattr = 0; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, &kmfcert.certificate, sizeof (KMF_DATA)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR, filename, strlen(filename)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt)); numattr++; rv = kmf_store_cert(kmfhandle, numattr, attrlist); kmf_free_kmf_cert(kmfhandle, &kmfcert); } } return (rv); } static KMF_RETURN pk_export_pk12_pk11(KMF_HANDLE_T kmfhandle, char *token_spec, char *certlabel, char *issuer, char *subject, KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, char *filename) { KMF_RETURN rv = KMF_OK; KMF_KEYSTORE_TYPE kstype; KMF_CREDENTIAL p12cred = { NULL, 0}; KMF_ATTRIBUTE attrlist[16]; int numattr = 0; rv = select_token(kmfhandle, token_spec, TRUE); if (rv != KMF_OK) { return (rv); } kstype = KMF_KEYSTORE_PK11TOKEN; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (certlabel != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); numattr++; } if (issuer != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); numattr++; } if (subject != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); numattr++; } if (serial != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); numattr++; } if (tokencred != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); numattr++; } (void) get_pk12_password(&p12cred); kmf_set_attr_at_index(attrlist, numattr, KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename)); numattr++; rv = kmf_export_pk12(kmfhandle, numattr, attrlist); if (p12cred.cred) free(p12cred.cred); return (rv); } static KMF_RETURN pk_export_pk11_keys(KMF_HANDLE_T kmfhandle, char *token, KMF_CREDENTIAL *cred, KMF_ENCODE_FORMAT format, char *label, char *filename, int oclass) { KMF_RETURN rv = KMF_OK; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; KMF_KEY_CLASS kclass = KMF_KEYCLASS_NONE; int numattr = 0; uint32_t numkeys = 1; KMF_ATTRIBUTE attrlist[16]; KMF_KEY_HANDLE key; boolean_t is_token = B_TRUE; if (EMPTYSTRING(label)) { cryptoerror(LOG_STDERR, gettext("A label " "must be specified to export a key.")); return (KMF_ERR_BAD_PARAMETER); } rv = select_token(kmfhandle, token, TRUE); if (rv != KMF_OK) { return (rv); } kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (cred != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); numattr++; } kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, label, strlen(label)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, &numkeys, sizeof (numkeys)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, &key, sizeof (key)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR, &is_token, sizeof (is_token)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format)); numattr++; /* Check to see if we are exporting private or public only */ if ((oclass & PK_KEY_OBJ) == PK_PRIKEY_OBJ) kclass = KMF_ASYM_PRI; else if ((oclass & PK_KEY_OBJ) == PK_PUBKEY_OBJ) kclass = KMF_ASYM_PUB; else if ((oclass & PK_KEY_OBJ) == PK_SYMKEY_OBJ) kclass = KMF_SYMMETRIC; else /* only 1 key at a time can be exported here, so default to pri */ kclass = KMF_ASYM_PRI; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, &kclass, sizeof (kclass)); numattr++; rv = kmf_find_key(kmfhandle, numattr, attrlist); if (rv == KMF_OK && key.keyclass == KMF_SYMMETRIC) { KMF_RAW_SYM_KEY rkey; (void) memset(&rkey, 0, sizeof (KMF_RAW_SYM_KEY)); rv = kmf_get_sym_key_value(kmfhandle, &key, &rkey); if (rv == KMF_OK) { int fd, n, total = 0; fd = open(filename, O_CREAT | O_RDWR |O_TRUNC, 0600); if (fd == -1) { rv = KMF_ERR_OPEN_FILE; goto done; } do { n = write(fd, rkey.keydata.val + total, rkey.keydata.len - total); if (n < 0) { if (errno == EINTR) continue; (void) close(fd); rv = KMF_ERR_WRITE_FILE; goto done; } total += n; } while (total < rkey.keydata.len); (void) close(fd); } done: kmf_free_bigint(&rkey.keydata); kmf_free_kmf_key(kmfhandle, &key); } else if (rv == KMF_OK) { KMF_KEYSTORE_TYPE sslks = KMF_KEYSTORE_OPENSSL; (void) printf(gettext("Found %d asymmetric keys\n"), numkeys); numattr = 0; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &sslks, sizeof (sslks)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR, key.keyp, sizeof (KMF_RAW_KEY_DATA)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, filename, strlen(filename)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, &key.keyclass, sizeof (KMF_KEY_CLASS)); numattr++; rv = kmf_store_key(kmfhandle, numattr, attrlist); kmf_free_kmf_key(kmfhandle, &key); } return (rv); } static KMF_RETURN pk_export_pk11_objects(KMF_HANDLE_T kmfhandle, char *token_spec, char *certlabel, char *issuer, char *subject, KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, char *filename) { KMF_RETURN rv = KMF_OK; KMF_X509_DER_CERT kmfcert; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; int numattr = 0; KMF_ATTRIBUTE attrlist[16]; rv = select_token(kmfhandle, token_spec, TRUE); if (rv != KMF_OK) { return (rv); } kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (certlabel != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); numattr++; } if (issuer != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); numattr++; } if (subject != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); numattr++; } if (serial != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); numattr++; } rv = pk_find_export_cert(kmfhandle, attrlist, numattr, &kmfcert); if (rv == KMF_OK) { kstype = KMF_KEYSTORE_OPENSSL; numattr = 0; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, &kmfcert.certificate, sizeof (KMF_DATA)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR, filename, strlen(filename)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt)); numattr++; rv = kmf_store_cert(kmfhandle, numattr, attrlist); kmf_free_kmf_cert(kmfhandle, &kmfcert); } return (rv); } /* * Export objects from one keystore to a file. */ int pk_export(int argc, char *argv[]) { int opt; extern int optind_av; extern char *optarg_av; char *token_spec = NULL; char *filename = NULL; char *dir = NULL; char *prefix = NULL; char *certlabel = NULL; char *subject = NULL; char *issuer = NULL; char *infile = NULL; char *keyfile = NULL; char *certfile = NULL; char *serstr = NULL; KMF_KEYSTORE_TYPE kstype = 0; KMF_ENCODE_FORMAT kfmt = KMF_FORMAT_PKCS12; KMF_RETURN rv = KMF_OK; int oclass = PK_CERT_OBJ; KMF_BIGINT serial = { NULL, 0 }; KMF_HANDLE_T kmfhandle = NULL; KMF_CREDENTIAL tokencred = {NULL, 0}; /* Parse command line options. Do NOT i18n/l10n. */ while ((opt = getopt_av(argc, argv, "k:(keystore)y:(objtype)T:(token)" "d:(dir)p:(prefix)" "l:(label)n:(nickname)s:(subject)" "i:(issuer)S:(serial)" "K:(keyfile)c:(certfile)" "F:(outformat)" "I:(infile)o:(outfile)")) != EOF) { if (EMPTYSTRING(optarg_av)) return (PK_ERR_USAGE); switch (opt) { case 'k': kstype = KS2Int(optarg_av); if (kstype == 0) return (PK_ERR_USAGE); break; case 'y': oclass = OT2Int(optarg_av); if (oclass == -1) return (PK_ERR_USAGE); break; case 'T': /* token specifier */ if (token_spec) return (PK_ERR_USAGE); token_spec = optarg_av; break; case 'd': if (dir) return (PK_ERR_USAGE); dir = optarg_av; break; case 'p': if (prefix) return (PK_ERR_USAGE); prefix = optarg_av; break; case 'n': case 'l': if (certlabel) return (PK_ERR_USAGE); certlabel = optarg_av; break; case 's': if (subject) return (PK_ERR_USAGE); subject = optarg_av; break; case 'i': if (issuer) return (PK_ERR_USAGE); issuer = optarg_av; break; case 'S': serstr = optarg_av; break; case 'F': kfmt = Str2Format(optarg_av); if (kfmt == KMF_FORMAT_UNDEF) return (PK_ERR_USAGE); break; case 'I': /* output file name */ if (infile) return (PK_ERR_USAGE); infile = optarg_av; break; case 'o': /* output file name */ if (filename) return (PK_ERR_USAGE); filename = optarg_av; break; case 'c': /* input cert file name */ if (certfile) return (PK_ERR_USAGE); certfile = optarg_av; break; case 'K': /* input key file name */ if (keyfile) return (PK_ERR_USAGE); keyfile = optarg_av; break; default: return (PK_ERR_USAGE); break; } } /* Assume keystore = PKCS#11 if not specified */ if (kstype == 0) kstype = KMF_KEYSTORE_PK11TOKEN; /* Filename arg is required. */ if (EMPTYSTRING(filename)) { cryptoerror(LOG_STDERR, gettext("You must specify " "an 'outfile' parameter when exporting.\n")); return (PK_ERR_USAGE); } /* No additional args allowed. */ argc -= optind_av; argv += optind_av; if (argc) return (PK_ERR_USAGE); /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && kstype != KMF_KEYSTORE_PK11TOKEN) { (void) fprintf(stderr, gettext("The objtype parameter " "is only relevant if keystore=pkcs11\n")); return (PK_ERR_USAGE); } if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) token_spec = PK_DEFAULT_PK11TOKEN; else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) token_spec = DEFAULT_NSS_TOKEN; if (kstype == KMF_KEYSTORE_OPENSSL) { if (kfmt != KMF_FORMAT_PKCS12) { cryptoerror(LOG_STDERR, gettext("PKCS12 " "is the only export format " "supported for the 'file' " "keystore.\n")); return (PK_ERR_USAGE); } if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { cryptoerror(LOG_STDERR, gettext("A cert file" "and a key file must be specified " "when exporting to PKCS12 from the " "'file' keystore.\n")); return (PK_ERR_USAGE); } } /* Check if the file exists and might be overwritten. */ if (access(filename, F_OK) == 0) { cryptoerror(LOG_STDERR, gettext("Warning: file \"%s\" exists, " "will be overwritten."), filename); if (yesno(gettext("Continue with export? "), gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) { return (0); } else { /* remove the file */ (void) unlink(filename); } } else { rv = verify_file(filename); if (rv != KMF_OK) { cryptoerror(LOG_STDERR, gettext("The file (%s) " "cannot be created.\n"), filename); return (PK_ERR_USAGE); } } if (serstr != NULL) { uchar_t *bytes = NULL; size_t bytelen; rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); if (rv != KMF_OK || bytes == NULL) { (void) fprintf(stderr, gettext("serial number " "must be specified as a hex number " "(ex: 0x0102030405ffeeddee)\n")); return (PK_ERR_USAGE); } serial.val = bytes; serial.len = bytelen; } if ((kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS) && (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ) || kfmt == KMF_FORMAT_PKCS12)) { (void) get_token_password(kstype, token_spec, &tokencred); } if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { cryptoerror(LOG_STDERR, gettext("Error initializing " "KMF: 0x%02x\n"), rv); return (rv); } switch (kstype) { case KMF_KEYSTORE_PK11TOKEN: if (kfmt == KMF_FORMAT_PKCS12) rv = pk_export_pk12_pk11(kmfhandle, token_spec, certlabel, issuer, subject, &serial, &tokencred, filename); else if ((oclass & PK_KEY_OBJ) || kfmt == KMF_FORMAT_RAWKEY) rv = pk_export_pk11_keys(kmfhandle, token_spec, &tokencred, kfmt, certlabel, filename, oclass); else rv = pk_export_pk11_objects(kmfhandle, token_spec, certlabel, issuer, subject, &serial, kfmt, filename); break; case KMF_KEYSTORE_NSS: if (dir == NULL) dir = PK_DEFAULT_DIRECTORY; if (kfmt == KMF_FORMAT_PKCS12) rv = pk_export_pk12_nss(kmfhandle, token_spec, dir, prefix, certlabel, issuer, subject, &serial, &tokencred, filename); else rv = pk_export_nss_objects(kmfhandle, token_spec, oclass, certlabel, issuer, subject, &serial, kfmt, dir, prefix, filename); break; case KMF_KEYSTORE_OPENSSL: if (kfmt == KMF_FORMAT_PKCS12) rv = pk_export_pk12_files(kmfhandle, certfile, keyfile, dir, filename); else rv = pk_export_file_objects(kmfhandle, oclass, issuer, subject, &serial, dir, infile, filename); break; default: rv = PK_ERR_USAGE; break; } if (rv != KMF_OK) { display_error(kmfhandle, rv, gettext("Error exporting objects")); } if (serial.val != NULL) free(serial.val); (void) kmf_finalize(kmfhandle); return (rv); }