/* * 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 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * This file implements the import operation for this tool. * The basic flow of the process is to decrypt the PKCS#12 * input file if it has a password, parse the elements in * the file, find the soft token, log into it, import the * PKCS#11 objects into the soft token, and log out. */ #include #include #include #include #include #include #include #include #include "common.h" #include #define NEW_ATTRLIST(a, n) \ { \ a = (KMF_ATTRIBUTE *)malloc(n * sizeof (KMF_ATTRIBUTE)); \ if (a == NULL) { \ rv = KMF_ERR_MEMORY; \ goto end; \ } \ (void) memset(a, 0, n * sizeof (KMF_ATTRIBUTE)); \ } static KMF_RETURN pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred, char *outfile, char *certfile, char *keyfile, char *dir, char *keydir, KMF_ENCODE_FORMAT outformat) { KMF_RETURN rv = KMF_OK; KMF_X509_DER_CERT *certs = NULL; KMF_RAW_KEY_DATA *keys = NULL; int ncerts = 0; int nkeys = 0; int i; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; KMF_ATTRIBUTE *attrlist = NULL; int numattr = 0; rv = kmf_import_objects(kmfhandle, outfile, cred, &certs, &ncerts, &keys, &nkeys); if (rv == KMF_OK) { (void) printf(gettext("Found %d certificate(s) and %d " "key(s) in %s\n"), ncerts, nkeys, outfile); } if (rv == KMF_OK && ncerts > 0) { char newcertfile[MAXPATHLEN]; NEW_ATTRLIST(attrlist, (3 + (3 * ncerts))); 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++; } kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat)); numattr++; for (i = 0; rv == KMF_OK && i < ncerts; i++) { int num = numattr; /* * If storing more than 1 cert, gotta change * the name so we don't overwrite the previous one. * Just append a _# to the name. */ if (i > 0) { (void) snprintf(newcertfile, sizeof (newcertfile), "%s_%d", certfile, i); kmf_set_attr_at_index(attrlist, num, KMF_CERT_FILENAME_ATTR, newcertfile, strlen(newcertfile)); num++; } else { kmf_set_attr_at_index(attrlist, num, KMF_CERT_FILENAME_ATTR, certfile, strlen(certfile)); num++; } if (certs[i].kmf_private.label != NULL) { kmf_set_attr_at_index(attrlist, num, KMF_CERT_LABEL_ATTR, certs[i].kmf_private.label, strlen(certs[i].kmf_private.label)); num++; } kmf_set_attr_at_index(attrlist, num, KMF_CERT_DATA_ATTR, &certs[i].certificate, sizeof (KMF_DATA)); num++; rv = kmf_store_cert(kmfhandle, num, attrlist); } free(attrlist); } if (rv == KMF_OK && nkeys > 0) { char newkeyfile[MAXPATHLEN]; numattr = 0; NEW_ATTRLIST(attrlist, (4 + (4 * nkeys))); kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (keydir != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR, keydir, strlen(keydir)); numattr++; } kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat)); numattr++; if (cred != NULL && cred->credlen > 0) { kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); numattr++; } /* The order of certificates and keys should match */ for (i = 0; rv == KMF_OK && i < nkeys; i++) { int num = numattr; if (i > 0) { (void) snprintf(newkeyfile, sizeof (newkeyfile), "%s_%d", keyfile, i); kmf_set_attr_at_index(attrlist, num, KMF_KEY_FILENAME_ATTR, newkeyfile, strlen(newkeyfile)); num++; } else { kmf_set_attr_at_index(attrlist, num, KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile)); num++; } if (i < ncerts) { kmf_set_attr_at_index(attrlist, num, KMF_CERT_DATA_ATTR, &certs[i], sizeof (KMF_CERT_DATA_ATTR)); num++; } kmf_set_attr_at_index(attrlist, num, KMF_RAW_KEY_ATTR, &keys[i], sizeof (KMF_RAW_KEY_DATA)); num++; rv = kmf_store_key(kmfhandle, num, attrlist); } free(attrlist); } end: /* * Cleanup memory. */ if (certs) { for (i = 0; i < ncerts; i++) kmf_free_kmf_cert(kmfhandle, &certs[i]); free(certs); } if (keys) { for (i = 0; i < nkeys; i++) kmf_free_raw_key(&keys[i]); free(keys); } return (rv); } static KMF_RETURN pk_import_pk12_nss( KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred, KMF_CREDENTIAL *tokencred, char *token_spec, char *dir, char *prefix, char *nickname, char *trustflags, char *filename) { KMF_RETURN rv = KMF_OK; KMF_X509_DER_CERT *certs = NULL; KMF_RAW_KEY_DATA *keys = NULL; int ncerts = 0; int nkeys = 0; int i; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; KMF_ATTRIBUTE *attrlist = NULL; int numattr = 0; rv = configure_nss(kmfhandle, dir, prefix); if (rv != KMF_OK) return (rv); rv = kmf_import_objects(kmfhandle, filename, kmfcred, &certs, &ncerts, &keys, &nkeys); if (rv == KMF_OK) (void) printf(gettext("Found %d certificate(s) and %d " "key(s) in %s\n"), ncerts, nkeys, filename); if (rv == KMF_OK) { NEW_ATTRLIST(attrlist, (3 + (2 * ncerts))); kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (token_spec != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, token_spec, strlen(token_spec)); numattr++; } if (trustflags != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_TRUSTFLAG_ATTR, trustflags, strlen(trustflags)); numattr++; } for (i = 0; rv == KMF_OK && i < ncerts; i++) { int num = numattr; if (certs[i].kmf_private.label != NULL) { kmf_set_attr_at_index(attrlist, num, KMF_CERT_LABEL_ATTR, certs[i].kmf_private.label, strlen(certs[i].kmf_private.label)); num++; } else if (i == 0 && nickname != NULL) { kmf_set_attr_at_index(attrlist, num, KMF_CERT_LABEL_ATTR, nickname, strlen(nickname)); num++; } kmf_set_attr_at_index(attrlist, num, KMF_CERT_DATA_ATTR, &certs[i].certificate, sizeof (KMF_DATA)); num++; rv = kmf_store_cert(kmfhandle, num, attrlist); } free(attrlist); attrlist = NULL; if (rv != KMF_OK) { display_error(kmfhandle, rv, gettext("Error storing certificate in NSS token")); } } if (rv == KMF_OK) { numattr = 0; NEW_ATTRLIST(attrlist, (4 + (2 * nkeys))); kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (token_spec != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, token_spec, strlen(token_spec)); numattr++; } if (nickname != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, nickname, strlen(nickname)); numattr++; } if (tokencred->credlen > 0) { kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); numattr++; } /* The order of certificates and keys should match */ for (i = 0; i < nkeys; i++) { int num = numattr; if (i < ncerts) { kmf_set_attr_at_index(attrlist, num, KMF_CERT_DATA_ATTR, &certs[i], sizeof (KMF_DATA)); num++; } kmf_set_attr_at_index(attrlist, num, KMF_RAW_KEY_ATTR, &keys[i], sizeof (KMF_RAW_KEY_DATA)); num++; rv = kmf_store_key(kmfhandle, num, attrlist); } free(attrlist); } end: /* * Cleanup memory. */ if (certs) { for (i = 0; i < ncerts; i++) kmf_free_kmf_cert(kmfhandle, &certs[i]); free(certs); } if (keys) { for (i = 0; i < nkeys; i++) kmf_free_raw_key(&keys[i]); free(keys); } return (rv); } static KMF_RETURN pk_import_cert( KMF_HANDLE_T kmfhandle, KMF_KEYSTORE_TYPE kstype, char *label, char *token_spec, char *filename, char *dir, char *prefix, char *trustflags) { KMF_RETURN rv = KMF_OK; KMF_ATTRIBUTE attrlist[32]; KMF_CREDENTIAL tokencred; int i = 0; if (kstype == KMF_KEYSTORE_PK11TOKEN) { rv = select_token(kmfhandle, token_spec, FALSE); } else if (kstype == KMF_KEYSTORE_NSS) { rv = configure_nss(kmfhandle, dir, prefix); } if (rv != KMF_OK) return (rv); kmf_set_attr_at_index(attrlist, i, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE)); i++; kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR, filename, strlen(filename)); i++; if (label != NULL) { kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR, label, strlen(label)); i++; } if (kstype == KMF_KEYSTORE_NSS) { if (trustflags != NULL) { kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR, trustflags, strlen(trustflags)); i++; } if (token_spec != NULL) { kmf_set_attr_at_index(attrlist, i, KMF_TOKEN_LABEL_ATTR, token_spec, strlen(token_spec)); i++; } } rv = kmf_import_cert(kmfhandle, i, attrlist); if (rv == KMF_ERR_AUTH_FAILED) { /* * The token requires a credential, prompt and try again. */ (void) get_token_password(kstype, token_spec, &tokencred); kmf_set_attr_at_index(attrlist, i, KMF_CREDENTIAL_ATTR, &tokencred, sizeof (KMF_CREDENTIAL)); i++; rv = kmf_import_cert(kmfhandle, i, attrlist); } return (rv); } static KMF_RETURN pk_import_file_crl(void *kmfhandle, char *infile, char *outfile, char *outdir, KMF_ENCODE_FORMAT outfmt) { int numattr = 0; KMF_ATTRIBUTE attrlist[8]; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (infile) { kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR, infile, strlen(infile)); numattr++; } if (outdir) { kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR, outdir, strlen(outdir)); numattr++; } if (outfile) { kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile)); numattr++; } kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt)); numattr++; return (kmf_import_crl(kmfhandle, numattr, attrlist)); } static KMF_RETURN pk_import_nss_crl(void *kmfhandle, boolean_t verify_crl_flag, char *infile, char *outdir, char *prefix) { KMF_RETURN rv; int numattr = 0; KMF_ATTRIBUTE attrlist[4]; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; rv = configure_nss(kmfhandle, outdir, prefix); if (rv != KMF_OK) return (rv); kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (infile) { kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR, infile, strlen(infile)); numattr++; } kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR, &verify_crl_flag, sizeof (verify_crl_flag)); numattr++; return (kmf_import_crl(kmfhandle, numattr, attrlist)); } static KMF_RETURN pk_import_pk12_pk11( KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *p12cred, KMF_CREDENTIAL *tokencred, char *label, char *token_spec, char *filename) { KMF_RETURN rv = KMF_OK; KMF_X509_DER_CERT *certs = NULL; KMF_RAW_KEY_DATA *keys = NULL; int ncerts = 0; int nkeys = 0; int i; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; KMF_ATTRIBUTE *attrlist = NULL; int numattr = 0; rv = select_token(kmfhandle, token_spec, FALSE); if (rv != KMF_OK) { return (rv); } rv = kmf_import_objects(kmfhandle, filename, p12cred, &certs, &ncerts, &keys, &nkeys); if (rv == KMF_OK) { NEW_ATTRLIST(attrlist, (3 + (2 * nkeys))); kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (label != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, label, strlen(label)); numattr++; } if (tokencred != NULL && tokencred->credlen > 0) { kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); numattr++; } /* The order of certificates and keys should match */ for (i = 0; i < nkeys; i++) { int num = numattr; if (i < ncerts) { kmf_set_attr_at_index(attrlist, num, KMF_CERT_DATA_ATTR, &certs[i].certificate, sizeof (KMF_DATA)); num++; } kmf_set_attr_at_index(attrlist, num, KMF_RAW_KEY_ATTR, &keys[i], sizeof (KMF_RAW_KEY_DATA)); num++; rv = kmf_store_key(kmfhandle, num, attrlist); } free(attrlist); } if (rv == KMF_OK) { numattr = 0; NEW_ATTRLIST(attrlist, (1 + (2 * ncerts))); (void) printf(gettext("Found %d certificate(s) and %d " "key(s) in %s\n"), ncerts, nkeys, filename); kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; for (i = 0; rv == KMF_OK && i < ncerts; i++) { int num = numattr; if (certs[i].kmf_private.label != NULL) { kmf_set_attr_at_index(attrlist, num, KMF_CERT_LABEL_ATTR, certs[i].kmf_private.label, strlen(certs[i].kmf_private.label)); num++; } else if (i == 0 && label != NULL) { kmf_set_attr_at_index(attrlist, num, KMF_CERT_LABEL_ATTR, label, strlen(label)); num++; } kmf_set_attr_at_index(attrlist, num, KMF_CERT_DATA_ATTR, &certs[i].certificate, sizeof (KMF_DATA)); num++; rv = kmf_store_cert(kmfhandle, num, attrlist); } free(attrlist); } end: /* * Cleanup memory. */ if (certs) { for (i = 0; i < ncerts; i++) kmf_free_kmf_cert(kmfhandle, &certs[i]); free(certs); } if (keys) { for (i = 0; i < nkeys; i++) kmf_free_raw_key(&keys[i]); free(keys); } return (rv); } /*ARGSUSED*/ static KMF_RETURN pk_import_keys(KMF_HANDLE_T kmfhandle, KMF_KEYSTORE_TYPE kstype, char *token_spec, KMF_CREDENTIAL *cred, char *filename, char *label, char *senstr, char *extstr) { KMF_RETURN rv = KMF_OK; KMF_ATTRIBUTE attrlist[16]; KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL; int numattr = 0; KMF_KEY_HANDLE key; KMF_RAW_KEY_DATA rawkey; KMF_KEY_CLASS class = KMF_ASYM_PRI; int numkeys = 1; if (kstype == KMF_KEYSTORE_PK11TOKEN) { rv = select_token(kmfhandle, token_spec, FALSE); } if (rv != KMF_OK) return (rv); /* * First, set up to read the keyfile using the FILE plugin * mechanisms. */ kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &fileks, sizeof (fileks)); 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_RAW_KEY_ATTR, &rawkey, sizeof (rawkey)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, &class, sizeof (class)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, filename, strlen(filename)); numattr++; rv = kmf_find_key(kmfhandle, numattr, attrlist); if (rv == KMF_OK) { numattr = 0; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (cred != NULL && cred->credlen > 0) { kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); numattr++; } if (label != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, label, strlen(label)); numattr++; } kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey)); numattr++; rv = kmf_store_key(kmfhandle, numattr, attrlist); if (rv == KMF_OK) { (void) printf(gettext("Importing %d keys\n"), numkeys); } kmf_free_kmf_key(kmfhandle, &key); kmf_free_raw_key(&rawkey); } else { cryptoerror(LOG_STDERR, gettext("Failed to load key from file (%s)\n"), filename); } return (rv); } static KMF_RETURN pk_import_rawkey(KMF_HANDLE_T kmfhandle, KMF_KEYSTORE_TYPE kstype, char *token, KMF_CREDENTIAL *cred, char *filename, char *label, KMF_KEY_ALG keyAlg, char *senstr, char *extstr) { KMF_RETURN rv = KMF_OK; KMF_ATTRIBUTE attrlist[16]; int numattr = 0; uint32_t keylen; boolean_t sensitive = B_FALSE; boolean_t not_extractable = B_FALSE; KMF_DATA keydata = {NULL, 0}; KMF_KEY_HANDLE rawkey; rv = kmf_read_input_file(kmfhandle, filename, &keydata); if (rv != KMF_OK) return (rv); rv = select_token(kmfhandle, token, FALSE); if (rv != KMF_OK) { return (rv); } if (senstr != NULL) { if (tolower(senstr[0]) == 'y') sensitive = B_TRUE; else if (tolower(senstr[0]) == 'n') sensitive = B_FALSE; else { cryptoerror(LOG_STDERR, gettext("Incorrect sensitive option value.\n")); return (KMF_ERR_BAD_PARAMETER); } } if (extstr != NULL) { if (tolower(extstr[0]) == 'y') not_extractable = B_FALSE; else if (tolower(extstr[0]) == 'n') not_extractable = B_TRUE; else { cryptoerror(LOG_STDERR, gettext("Incorrect extractable option value.\n")); return (KMF_ERR_BAD_PARAMETER); } } kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length); numattr++; /* Key length is given in bits not bytes */ keylen = keydata.Length * 8; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_NON_EXTRACTABLE_BOOL_ATTR, ¬_extractable, sizeof (not_extractable)); numattr++; if (label != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, label, strlen(label)); numattr++; } if (cred != NULL && cred->credlen > 0) { kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); numattr++; } rv = kmf_create_sym_key(kmfhandle, numattr, attrlist); return (rv); } /* * Import objects from into KMF repositories. */ int pk_import(int argc, char *argv[]) { int opt; extern int optind_av; extern char *optarg_av; char *token_spec = NULL; char *filename = NULL; char *keyfile = NULL; char *certfile = NULL; char *crlfile = NULL; char *label = NULL; char *dir = NULL; char *keydir = NULL; char *prefix = NULL; char *trustflags = NULL; char *verify_crl = NULL; char *keytype = "generic"; char *senstr = NULL; char *extstr = NULL; boolean_t verify_crl_flag = B_FALSE; int oclass = 0; KMF_KEYSTORE_TYPE kstype = 0; KMF_ENCODE_FORMAT kfmt = 0; KMF_ENCODE_FORMAT okfmt = KMF_FORMAT_ASN1; KMF_RETURN rv = KMF_OK; KMF_CREDENTIAL pk12cred = { NULL, 0 }; KMF_CREDENTIAL tokencred = { NULL, 0 }; KMF_HANDLE_T kmfhandle = NULL; KMF_KEY_ALG keyAlg = KMF_GENERIC_SECRET; /* Parse command line options. Do NOT i18n/l10n. */ while ((opt = getopt_av(argc, argv, "T:(token)i:(infile)" "k:(keystore)y:(objtype)" "d:(dir)p:(prefix)" "n:(certlabel)N:(label)" "K:(outkey)c:(outcert)" "v:(verifycrl)l:(outcrl)" "E:(keytype)s:(sensitive)x:(extractable)" "t:(trust)D:(keydir)F:(outformat)")) != EOF) { if (EMPTYSTRING(optarg_av)) return (PK_ERR_USAGE); switch (opt) { case 'T': /* token specifier */ if (token_spec) return (PK_ERR_USAGE); token_spec = optarg_av; break; case 'c': /* output cert file name */ if (certfile) return (PK_ERR_USAGE); certfile = optarg_av; break; case 'l': /* output CRL file name */ if (crlfile) return (PK_ERR_USAGE); crlfile = optarg_av; break; case 'K': /* output key file name */ if (keyfile) return (PK_ERR_USAGE); keyfile = optarg_av; break; case 'i': /* input file name */ if (filename) return (PK_ERR_USAGE); filename = optarg_av; break; 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 'd': dir = optarg_av; break; case 'D': keydir = optarg_av; break; case 'p': if (prefix) return (PK_ERR_USAGE); prefix = optarg_av; break; case 'n': case 'N': if (label) return (PK_ERR_USAGE); label = optarg_av; break; case 'F': okfmt = Str2Format(optarg_av); if (okfmt == KMF_FORMAT_UNDEF) return (PK_ERR_USAGE); break; case 't': if (trustflags) return (PK_ERR_USAGE); trustflags = optarg_av; break; case 'v': verify_crl = optarg_av; if (tolower(verify_crl[0]) == 'y') verify_crl_flag = B_TRUE; else if (tolower(verify_crl[0]) == 'n') verify_crl_flag = B_FALSE; else return (PK_ERR_USAGE); break; case 'E': keytype = optarg_av; break; case 's': if (senstr) return (PK_ERR_USAGE); senstr = optarg_av; break; case 'x': if (extstr) return (PK_ERR_USAGE); extstr = 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("The 'infile' parameter" "is required for the import operation.\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); } /* * You must specify a certlabel (cert label) when importing * into NSS or PKCS#11. */ if (kstype == KMF_KEYSTORE_NSS && (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) { cryptoerror(LOG_STDERR, gettext("The 'label' argument " "is required for this operation\n")); return (PK_ERR_USAGE); } if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) { /* * Allow for raw key data to be imported. */ if (rv == KMF_ERR_ENCODING) { rv = KMF_OK; kfmt = KMF_FORMAT_RAWKEY; /* * Set the object class only if it was not * given on the command line or if it was * specified as a symmetric key object. */ if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) { oclass = PK_SYMKEY_OBJ; } else { cryptoerror(LOG_STDERR, gettext( "The input file does not contain the " "object type indicated on command " "line.")); return (KMF_ERR_BAD_PARAMETER); } } else { cryptoerror(LOG_STDERR, gettext("File format not recognized.")); return (rv); } } /* Check parameters for raw key import operation */ if (kfmt == KMF_FORMAT_RAWKEY) { if (keytype != NULL && Str2SymKeyType(keytype, &keyAlg) != 0) { cryptoerror(LOG_STDERR, gettext("Unrecognized keytype(%s).\n"), keytype); return (PK_ERR_USAGE); } if (senstr != NULL && extstr != NULL && kstype != KMF_KEYSTORE_PK11TOKEN) { cryptoerror(LOG_STDERR, gettext("The sensitive or extractable option " "applies only when importing a key from a file " "into a PKCS#11 keystore.\n")); return (PK_ERR_USAGE); } } /* If no objtype was given, treat it as a certificate */ if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 || kfmt == KMF_FORMAT_PEM)) oclass = PK_CERT_OBJ; if (kstype == KMF_KEYSTORE_NSS) { if (oclass == PK_CRL_OBJ && (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { cryptoerror(LOG_STDERR, gettext( "CRL data can only be imported as DER or " "PEM format")); return (PK_ERR_USAGE); } if (oclass == PK_CERT_OBJ && (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { cryptoerror(LOG_STDERR, gettext( "Certificates can only be imported as DER or " "PEM format")); return (PK_ERR_USAGE); } /* we do not import private keys except in PKCS12 bundles */ if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) { cryptoerror(LOG_STDERR, gettext( "Private key data can only be imported as part " "of a PKCS12 file.\n")); return (PK_ERR_USAGE); } } if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) { if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { cryptoerror(LOG_STDERR, gettext( "The 'outkey' and 'outcert' parameters " "are required for the import operation " "when the 'file' keystore is used.\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 (kfmt == KMF_FORMAT_PKCS12) { (void) get_pk12_password(&pk12cred); } if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY || (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) && (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) { (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); goto end; } switch (kstype) { case KMF_KEYSTORE_PK11TOKEN: if (kfmt == KMF_FORMAT_PKCS12) rv = pk_import_pk12_pk11( kmfhandle, &pk12cred, &tokencred, label, token_spec, filename); else if (oclass == PK_CERT_OBJ) rv = pk_import_cert( kmfhandle, kstype, label, token_spec, filename, NULL, NULL, NULL); else if (oclass == PK_CRL_OBJ) rv = pk_import_file_crl( kmfhandle, filename, crlfile, dir, okfmt); else if (kfmt == KMF_FORMAT_RAWKEY && oclass == PK_SYMKEY_OBJ) { rv = pk_import_rawkey(kmfhandle, kstype, token_spec, &tokencred, filename, label, keyAlg, senstr, extstr); } else if (kfmt == KMF_FORMAT_PEM || kfmt == KMF_FORMAT_PEM_KEYPAIR) { rv = pk_import_keys(kmfhandle, kstype, token_spec, &tokencred, filename, label, senstr, extstr); } else { rv = PK_ERR_USAGE; } break; case KMF_KEYSTORE_NSS: if (dir == NULL) dir = PK_DEFAULT_DIRECTORY; if (kfmt == KMF_FORMAT_PKCS12) rv = pk_import_pk12_nss( kmfhandle, &pk12cred, &tokencred, token_spec, dir, prefix, label, trustflags, filename); else if (oclass == PK_CERT_OBJ) { rv = pk_import_cert( kmfhandle, kstype, label, token_spec, filename, dir, prefix, trustflags); } else if (oclass == PK_CRL_OBJ) { rv = pk_import_nss_crl( kmfhandle, verify_crl_flag, filename, dir, prefix); } break; case KMF_KEYSTORE_OPENSSL: if (kfmt == KMF_FORMAT_PKCS12) rv = pk_import_pk12_files( kmfhandle, &pk12cred, filename, certfile, keyfile, dir, keydir, okfmt); else if (oclass == PK_CRL_OBJ) { rv = pk_import_file_crl( kmfhandle, filename, crlfile, dir, okfmt); } else /* * It doesn't make sense to import anything * else for the files plugin. */ return (PK_ERR_USAGE); break; default: rv = PK_ERR_USAGE; break; } end: if (rv != KMF_OK) display_error(kmfhandle, rv, gettext("Error importing objects")); if (tokencred.cred != NULL) free(tokencred.cred); if (pk12cred.cred != NULL) free(pk12cred.cred); (void) kmf_finalize(kmfhandle); if (rv != KMF_OK) return (PK_ERR_USAGE); return (0); }