17711facfSdinak /* 27711facfSdinak * CDDL HEADER START 37711facfSdinak * 47711facfSdinak * The contents of this file are subject to the terms of the 599ebb4caSwyllys * Common Development and Distribution License (the "License"). 699ebb4caSwyllys * 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 207711facfSdinak */ 217711facfSdinak /* 229e765c33SHuie-Ying Lee * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237711facfSdinak * Use is subject to license terms. 2433f5ff17SMilan Jurik * Copyright 2012 Milan Jurik. All rights reserved. 257711facfSdinak */ 267711facfSdinak 277711facfSdinak /* 287711facfSdinak * This file implements the import operation for this tool. 297711facfSdinak * The basic flow of the process is to decrypt the PKCS#12 307711facfSdinak * input file if it has a password, parse the elements in 317711facfSdinak * the file, find the soft token, log into it, import the 327711facfSdinak * PKCS#11 objects into the soft token, and log out. 337711facfSdinak */ 347711facfSdinak 357711facfSdinak #include <stdio.h> 367711facfSdinak #include <stdlib.h> 377711facfSdinak #include <string.h> 3899ebb4caSwyllys #include <ctype.h> 397711facfSdinak #include <errno.h> 407711facfSdinak #include <fcntl.h> 417711facfSdinak #include <sys/types.h> 427711facfSdinak #include <sys/stat.h> 437711facfSdinak #include "common.h" 447711facfSdinak 4599ebb4caSwyllys #include <kmfapi.h> 4699ebb4caSwyllys 475b3e1433Swyllys #define NEW_ATTRLIST(a, n) \ 485b3e1433Swyllys { \ 495b3e1433Swyllys a = (KMF_ATTRIBUTE *)malloc(n * sizeof (KMF_ATTRIBUTE)); \ 505b3e1433Swyllys if (a == NULL) { \ 515b3e1433Swyllys rv = KMF_ERR_MEMORY; \ 525b3e1433Swyllys goto end; \ 535b3e1433Swyllys } \ 545b3e1433Swyllys (void) memset(a, 0, n * sizeof (KMF_ATTRIBUTE)); \ 555b3e1433Swyllys } 565b3e1433Swyllys 5799ebb4caSwyllys static KMF_RETURN 5899ebb4caSwyllys pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred, 5999ebb4caSwyllys char *outfile, char *certfile, char *keyfile, 60448b8615Swyllys KMF_ENCODE_FORMAT outformat) 617711facfSdinak { 6299ebb4caSwyllys KMF_RETURN rv = KMF_OK; 635b3e1433Swyllys KMF_X509_DER_CERT *certs = NULL; 6499ebb4caSwyllys KMF_RAW_KEY_DATA *keys = NULL; 6599ebb4caSwyllys int ncerts = 0; 6699ebb4caSwyllys int nkeys = 0; 677711facfSdinak int i; 6830a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 695b3e1433Swyllys KMF_ATTRIBUTE *attrlist = NULL; 7030a5e8faSwyllys int numattr = 0; 717711facfSdinak 7230a5e8faSwyllys rv = kmf_import_objects(kmfhandle, outfile, cred, 7399ebb4caSwyllys &certs, &ncerts, &keys, &nkeys); 747711facfSdinak 7599ebb4caSwyllys if (rv == KMF_OK) { 7699ebb4caSwyllys (void) printf(gettext("Found %d certificate(s) and %d " 7799ebb4caSwyllys "key(s) in %s\n"), ncerts, nkeys, outfile); 7899ebb4caSwyllys } 797711facfSdinak 8099ebb4caSwyllys if (rv == KMF_OK && ncerts > 0) { 8199ebb4caSwyllys char newcertfile[MAXPATHLEN]; 827711facfSdinak 835b3e1433Swyllys NEW_ATTRLIST(attrlist, (3 + (3 * ncerts))); 845b3e1433Swyllys 8530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 8630a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 8730a5e8faSwyllys numattr++; 8830a5e8faSwyllys 8930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 9030a5e8faSwyllys KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat)); 9130a5e8faSwyllys numattr++; 9299ebb4caSwyllys 9399ebb4caSwyllys for (i = 0; rv == KMF_OK && i < ncerts; i++) { 9430a5e8faSwyllys int num = numattr; 9530a5e8faSwyllys 967711facfSdinak /* 9799ebb4caSwyllys * If storing more than 1 cert, gotta change 9899ebb4caSwyllys * the name so we don't overwrite the previous one. 9999ebb4caSwyllys * Just append a _# to the name. 1007711facfSdinak */ 10199ebb4caSwyllys if (i > 0) { 10299ebb4caSwyllys (void) snprintf(newcertfile, 10330a5e8faSwyllys sizeof (newcertfile), "%s_%d", certfile, i); 10430a5e8faSwyllys 10530a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 10630a5e8faSwyllys KMF_CERT_FILENAME_ATTR, newcertfile, 10730a5e8faSwyllys strlen(newcertfile)); 10830a5e8faSwyllys num++; 10999ebb4caSwyllys } else { 11030a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 11130a5e8faSwyllys KMF_CERT_FILENAME_ATTR, certfile, 11230a5e8faSwyllys strlen(certfile)); 11330a5e8faSwyllys num++; 11499ebb4caSwyllys } 11530a5e8faSwyllys 1165b3e1433Swyllys if (certs[i].kmf_private.label != NULL) { 11730a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 1185b3e1433Swyllys KMF_CERT_LABEL_ATTR, 1195b3e1433Swyllys certs[i].kmf_private.label, 1205b3e1433Swyllys strlen(certs[i].kmf_private.label)); 1215b3e1433Swyllys num++; 1225b3e1433Swyllys } 1235b3e1433Swyllys kmf_set_attr_at_index(attrlist, num, 1245b3e1433Swyllys KMF_CERT_DATA_ATTR, &certs[i].certificate, 1255b3e1433Swyllys sizeof (KMF_DATA)); 12630a5e8faSwyllys num++; 12730a5e8faSwyllys rv = kmf_store_cert(kmfhandle, num, attrlist); 12899ebb4caSwyllys } 1295b3e1433Swyllys free(attrlist); 13099ebb4caSwyllys } 13199ebb4caSwyllys if (rv == KMF_OK && nkeys > 0) { 13299ebb4caSwyllys char newkeyfile[MAXPATHLEN]; 13330a5e8faSwyllys numattr = 0; 1345b3e1433Swyllys NEW_ATTRLIST(attrlist, (4 + (4 * nkeys))); 13530a5e8faSwyllys 13630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 13730a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 13830a5e8faSwyllys sizeof (kstype)); 13930a5e8faSwyllys numattr++; 14030a5e8faSwyllys 14130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 14230a5e8faSwyllys KMF_ENCODE_FORMAT_ATTR, &outformat, 14330a5e8faSwyllys sizeof (outformat)); 14430a5e8faSwyllys numattr++; 14530a5e8faSwyllys 14630a5e8faSwyllys if (cred != NULL && cred->credlen > 0) { 14730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 14830a5e8faSwyllys KMF_CREDENTIAL_ATTR, cred, 14930a5e8faSwyllys sizeof (KMF_CREDENTIAL)); 15030a5e8faSwyllys numattr++; 15130a5e8faSwyllys } 15299ebb4caSwyllys 15399ebb4caSwyllys /* The order of certificates and keys should match */ 15499ebb4caSwyllys for (i = 0; rv == KMF_OK && i < nkeys; i++) { 15530a5e8faSwyllys int num = numattr; 15699ebb4caSwyllys 15799ebb4caSwyllys if (i > 0) { 15899ebb4caSwyllys (void) snprintf(newkeyfile, 15930a5e8faSwyllys sizeof (newkeyfile), "%s_%d", keyfile, i); 16030a5e8faSwyllys 16130a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 16230a5e8faSwyllys KMF_KEY_FILENAME_ATTR, newkeyfile, 16330a5e8faSwyllys strlen(newkeyfile)); 16430a5e8faSwyllys num++; 16599ebb4caSwyllys } else { 16630a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 16730a5e8faSwyllys KMF_KEY_FILENAME_ATTR, keyfile, 16830a5e8faSwyllys strlen(keyfile)); 16930a5e8faSwyllys num++; 1707711facfSdinak } 1717711facfSdinak 1725b3e1433Swyllys if (i < ncerts) { 17330a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 17430a5e8faSwyllys KMF_CERT_DATA_ATTR, &certs[i], 1755b3e1433Swyllys sizeof (KMF_CERT_DATA_ATTR)); 17630a5e8faSwyllys num++; 1775b3e1433Swyllys } 17830a5e8faSwyllys 17930a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 18030a5e8faSwyllys KMF_RAW_KEY_ATTR, &keys[i], 18130a5e8faSwyllys sizeof (KMF_RAW_KEY_DATA)); 18230a5e8faSwyllys num++; 18330a5e8faSwyllys 18430a5e8faSwyllys rv = kmf_store_key(kmfhandle, num, attrlist); 18599ebb4caSwyllys } 1865b3e1433Swyllys free(attrlist); 18799ebb4caSwyllys } 1885b3e1433Swyllys end: 1897711facfSdinak /* 19099ebb4caSwyllys * Cleanup memory. 1917711facfSdinak */ 19299ebb4caSwyllys if (certs) { 19399ebb4caSwyllys for (i = 0; i < ncerts; i++) 1945b3e1433Swyllys kmf_free_kmf_cert(kmfhandle, &certs[i]); 19599ebb4caSwyllys free(certs); 19699ebb4caSwyllys } 19799ebb4caSwyllys if (keys) { 19899ebb4caSwyllys for (i = 0; i < nkeys; i++) 19930a5e8faSwyllys kmf_free_raw_key(&keys[i]); 20099ebb4caSwyllys free(keys); 2017711facfSdinak } 2027711facfSdinak 20399ebb4caSwyllys 20499ebb4caSwyllys return (rv); 20599ebb4caSwyllys } 20699ebb4caSwyllys 20799ebb4caSwyllys 20899ebb4caSwyllys static KMF_RETURN 20999ebb4caSwyllys pk_import_pk12_nss( 21099ebb4caSwyllys KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred, 21199ebb4caSwyllys KMF_CREDENTIAL *tokencred, 21299ebb4caSwyllys char *token_spec, char *dir, char *prefix, 21399ebb4caSwyllys char *nickname, char *trustflags, char *filename) 21499ebb4caSwyllys { 21599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 2165b3e1433Swyllys KMF_X509_DER_CERT *certs = NULL; 21799ebb4caSwyllys KMF_RAW_KEY_DATA *keys = NULL; 21899ebb4caSwyllys int ncerts = 0; 21999ebb4caSwyllys int nkeys = 0; 22099ebb4caSwyllys int i; 22130a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 2225b3e1433Swyllys KMF_ATTRIBUTE *attrlist = NULL; 22330a5e8faSwyllys int numattr = 0; 22499ebb4caSwyllys 22599ebb4caSwyllys rv = configure_nss(kmfhandle, dir, prefix); 22699ebb4caSwyllys if (rv != KMF_OK) 22799ebb4caSwyllys return (rv); 22899ebb4caSwyllys 22930a5e8faSwyllys rv = kmf_import_objects(kmfhandle, filename, kmfcred, 23099ebb4caSwyllys &certs, &ncerts, &keys, &nkeys); 23199ebb4caSwyllys 23299ebb4caSwyllys if (rv == KMF_OK) 23399ebb4caSwyllys (void) printf(gettext("Found %d certificate(s) and %d " 23499ebb4caSwyllys "key(s) in %s\n"), ncerts, nkeys, filename); 23599ebb4caSwyllys 23699ebb4caSwyllys if (rv == KMF_OK) { 23730a5e8faSwyllys numattr = 0; 2385b3e1433Swyllys NEW_ATTRLIST(attrlist, (4 + (2 * nkeys))); 23930a5e8faSwyllys 24030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 24130a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 24230a5e8faSwyllys sizeof (kstype)); 24330a5e8faSwyllys numattr++; 24430a5e8faSwyllys 24530a5e8faSwyllys if (token_spec != NULL) { 24630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 24730a5e8faSwyllys KMF_TOKEN_LABEL_ATTR, token_spec, 24830a5e8faSwyllys strlen(token_spec)); 24930a5e8faSwyllys numattr++; 25030a5e8faSwyllys } 25130a5e8faSwyllys 25230a5e8faSwyllys if (nickname != NULL) { 25330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 25430a5e8faSwyllys KMF_KEYLABEL_ATTR, nickname, 25530a5e8faSwyllys strlen(nickname)); 25630a5e8faSwyllys numattr++; 25730a5e8faSwyllys } 25830a5e8faSwyllys 25930a5e8faSwyllys if (tokencred->credlen > 0) { 26030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 26130a5e8faSwyllys KMF_CREDENTIAL_ATTR, tokencred, 26230a5e8faSwyllys sizeof (KMF_CREDENTIAL)); 26330a5e8faSwyllys numattr++; 26430a5e8faSwyllys } 26599ebb4caSwyllys 26699ebb4caSwyllys /* The order of certificates and keys should match */ 26799ebb4caSwyllys for (i = 0; i < nkeys; i++) { 26830a5e8faSwyllys int num = numattr; 26999ebb4caSwyllys 2705b3e1433Swyllys if (i < ncerts) { 27130a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 27230a5e8faSwyllys KMF_CERT_DATA_ATTR, &certs[i], 27330a5e8faSwyllys sizeof (KMF_DATA)); 27430a5e8faSwyllys num++; 2755b3e1433Swyllys } 27630a5e8faSwyllys 27730a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 27830a5e8faSwyllys KMF_RAW_KEY_ATTR, &keys[i], 27930a5e8faSwyllys sizeof (KMF_RAW_KEY_DATA)); 28030a5e8faSwyllys num++; 28130a5e8faSwyllys 28230a5e8faSwyllys rv = kmf_store_key(kmfhandle, num, attrlist); 28399ebb4caSwyllys } 2845b3e1433Swyllys free(attrlist); 28564012b18Swyllys attrlist = NULL; 28664012b18Swyllys } 28764012b18Swyllys 28864012b18Swyllys if (rv == KMF_OK) { 2899e765c33SHuie-Ying Lee numattr = 0; 29064012b18Swyllys NEW_ATTRLIST(attrlist, (3 + (2 * ncerts))); 29164012b18Swyllys 29264012b18Swyllys kmf_set_attr_at_index(attrlist, numattr, 29364012b18Swyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 29464012b18Swyllys numattr++; 29564012b18Swyllys 29664012b18Swyllys if (token_spec != NULL) { 29764012b18Swyllys kmf_set_attr_at_index(attrlist, numattr, 29864012b18Swyllys KMF_TOKEN_LABEL_ATTR, token_spec, 29964012b18Swyllys strlen(token_spec)); 30064012b18Swyllys numattr++; 30164012b18Swyllys } 30264012b18Swyllys 30364012b18Swyllys if (trustflags != NULL) { 30464012b18Swyllys kmf_set_attr_at_index(attrlist, numattr, 30564012b18Swyllys KMF_TRUSTFLAG_ATTR, trustflags, 30664012b18Swyllys strlen(trustflags)); 30764012b18Swyllys numattr++; 30864012b18Swyllys } 30964012b18Swyllys 31064012b18Swyllys for (i = 0; rv == KMF_OK && i < ncerts; i++) { 31164012b18Swyllys int num = numattr; 31264012b18Swyllys 31364012b18Swyllys if (certs[i].kmf_private.label != NULL) { 31464012b18Swyllys kmf_set_attr_at_index(attrlist, num, 31564012b18Swyllys KMF_CERT_LABEL_ATTR, 31664012b18Swyllys certs[i].kmf_private.label, 31764012b18Swyllys strlen(certs[i].kmf_private.label)); 31864012b18Swyllys num++; 31964012b18Swyllys } else if (i == 0 && nickname != NULL) { 32064012b18Swyllys kmf_set_attr_at_index(attrlist, num, 32164012b18Swyllys KMF_CERT_LABEL_ATTR, nickname, 32264012b18Swyllys strlen(nickname)); 32364012b18Swyllys num++; 32464012b18Swyllys } 32564012b18Swyllys 32664012b18Swyllys kmf_set_attr_at_index(attrlist, num, 32764012b18Swyllys KMF_CERT_DATA_ATTR, 32864012b18Swyllys &certs[i].certificate, sizeof (KMF_DATA)); 32964012b18Swyllys num++; 33064012b18Swyllys rv = kmf_store_cert(kmfhandle, num, attrlist); 33164012b18Swyllys } 33264012b18Swyllys free(attrlist); 33364012b18Swyllys attrlist = NULL; 33464012b18Swyllys if (rv != KMF_OK) { 33564012b18Swyllys display_error(kmfhandle, rv, 33664012b18Swyllys gettext("Error storing certificate in NSS token")); 33764012b18Swyllys } 3387711facfSdinak } 3397711facfSdinak 3405b3e1433Swyllys end: 3417711facfSdinak /* 34299ebb4caSwyllys * Cleanup memory. 34399ebb4caSwyllys */ 34499ebb4caSwyllys if (certs) { 34599ebb4caSwyllys for (i = 0; i < ncerts; i++) 3465b3e1433Swyllys kmf_free_kmf_cert(kmfhandle, &certs[i]); 34799ebb4caSwyllys free(certs); 34899ebb4caSwyllys } 34999ebb4caSwyllys if (keys) { 35099ebb4caSwyllys for (i = 0; i < nkeys; i++) 35130a5e8faSwyllys kmf_free_raw_key(&keys[i]); 35299ebb4caSwyllys free(keys); 35399ebb4caSwyllys } 35499ebb4caSwyllys 35599ebb4caSwyllys return (rv); 35699ebb4caSwyllys } 35799ebb4caSwyllys 35899ebb4caSwyllys static KMF_RETURN 35999ebb4caSwyllys pk_import_cert( 36099ebb4caSwyllys KMF_HANDLE_T kmfhandle, 36199ebb4caSwyllys KMF_KEYSTORE_TYPE kstype, 36299ebb4caSwyllys char *label, char *token_spec, char *filename, 36399ebb4caSwyllys char *dir, char *prefix, char *trustflags) 36499ebb4caSwyllys { 36599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 36630a5e8faSwyllys KMF_ATTRIBUTE attrlist[32]; 367fa60c371Swyllys KMF_CREDENTIAL tokencred; 36830a5e8faSwyllys int i = 0; 36999ebb4caSwyllys 37099ebb4caSwyllys if (kstype == KMF_KEYSTORE_PK11TOKEN) { 37199ebb4caSwyllys rv = select_token(kmfhandle, token_spec, FALSE); 37230a5e8faSwyllys } else if (kstype == KMF_KEYSTORE_NSS) { 37399ebb4caSwyllys rv = configure_nss(kmfhandle, dir, prefix); 37430a5e8faSwyllys } 37599ebb4caSwyllys if (rv != KMF_OK) 37699ebb4caSwyllys return (rv); 37730a5e8faSwyllys 37830a5e8faSwyllys kmf_set_attr_at_index(attrlist, i, 37930a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE)); 38030a5e8faSwyllys i++; 38130a5e8faSwyllys 38230a5e8faSwyllys kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR, 38330a5e8faSwyllys filename, strlen(filename)); 38430a5e8faSwyllys i++; 38530a5e8faSwyllys 38630a5e8faSwyllys if (label != NULL) { 38730a5e8faSwyllys kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR, 38830a5e8faSwyllys label, strlen(label)); 38930a5e8faSwyllys i++; 39099ebb4caSwyllys } 39199ebb4caSwyllys 39230a5e8faSwyllys if (kstype == KMF_KEYSTORE_NSS) { 39330a5e8faSwyllys if (trustflags != NULL) { 39430a5e8faSwyllys kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR, 39530a5e8faSwyllys trustflags, strlen(trustflags)); 39630a5e8faSwyllys i++; 39730a5e8faSwyllys } 39899ebb4caSwyllys 39930a5e8faSwyllys if (token_spec != NULL) { 40030a5e8faSwyllys kmf_set_attr_at_index(attrlist, i, 40130a5e8faSwyllys KMF_TOKEN_LABEL_ATTR, 40230a5e8faSwyllys token_spec, strlen(token_spec)); 40330a5e8faSwyllys i++; 40430a5e8faSwyllys } 40530a5e8faSwyllys } 40630a5e8faSwyllys 40730a5e8faSwyllys rv = kmf_import_cert(kmfhandle, i, attrlist); 408fa60c371Swyllys if (rv == KMF_ERR_AUTH_FAILED) { 409fa60c371Swyllys /* 410fa60c371Swyllys * The token requires a credential, prompt and try again. 411fa60c371Swyllys */ 412fa60c371Swyllys (void) get_token_password(kstype, token_spec, &tokencred); 413fa60c371Swyllys kmf_set_attr_at_index(attrlist, i, KMF_CREDENTIAL_ATTR, 414fa60c371Swyllys &tokencred, sizeof (KMF_CREDENTIAL)); 415fa60c371Swyllys i++; 416fa60c371Swyllys 417fa60c371Swyllys rv = kmf_import_cert(kmfhandle, i, attrlist); 418fa60c371Swyllys 419fa60c371Swyllys } 42099ebb4caSwyllys return (rv); 42199ebb4caSwyllys } 42299ebb4caSwyllys 42399ebb4caSwyllys static KMF_RETURN 42499ebb4caSwyllys pk_import_file_crl(void *kmfhandle, 42599ebb4caSwyllys char *infile, 42699ebb4caSwyllys char *outfile, 42799ebb4caSwyllys KMF_ENCODE_FORMAT outfmt) 42899ebb4caSwyllys { 42930a5e8faSwyllys int numattr = 0; 43030a5e8faSwyllys KMF_ATTRIBUTE attrlist[8]; 43130a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 43299ebb4caSwyllys 43330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 43430a5e8faSwyllys &kstype, sizeof (kstype)); 43530a5e8faSwyllys numattr++; 43630a5e8faSwyllys if (infile) { 43730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 43830a5e8faSwyllys KMF_CRL_FILENAME_ATTR, infile, strlen(infile)); 43930a5e8faSwyllys numattr++; 44030a5e8faSwyllys } 44130a5e8faSwyllys if (outfile) { 44230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 44330a5e8faSwyllys KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile)); 44430a5e8faSwyllys numattr++; 44530a5e8faSwyllys } 44630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 44730a5e8faSwyllys KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt)); 44830a5e8faSwyllys numattr++; 44999ebb4caSwyllys 45030a5e8faSwyllys return (kmf_import_crl(kmfhandle, numattr, attrlist)); 45199ebb4caSwyllys } 45299ebb4caSwyllys 45399ebb4caSwyllys static KMF_RETURN 45499ebb4caSwyllys pk_import_nss_crl(void *kmfhandle, 45599ebb4caSwyllys boolean_t verify_crl_flag, 45699ebb4caSwyllys char *infile, 45799ebb4caSwyllys char *outdir, 45899ebb4caSwyllys char *prefix) 45999ebb4caSwyllys { 46099ebb4caSwyllys KMF_RETURN rv; 46130a5e8faSwyllys int numattr = 0; 46230a5e8faSwyllys KMF_ATTRIBUTE attrlist[4]; 46330a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 46499ebb4caSwyllys 46599ebb4caSwyllys rv = configure_nss(kmfhandle, outdir, prefix); 46699ebb4caSwyllys if (rv != KMF_OK) 46799ebb4caSwyllys return (rv); 46899ebb4caSwyllys 46930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 47030a5e8faSwyllys &kstype, sizeof (kstype)); 47130a5e8faSwyllys numattr++; 47230a5e8faSwyllys if (infile) { 47330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR, 47430a5e8faSwyllys infile, strlen(infile)); 47530a5e8faSwyllys numattr++; 47630a5e8faSwyllys } 47730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR, 47830a5e8faSwyllys &verify_crl_flag, sizeof (verify_crl_flag)); 47930a5e8faSwyllys numattr++; 48099ebb4caSwyllys 48130a5e8faSwyllys return (kmf_import_crl(kmfhandle, numattr, attrlist)); 48299ebb4caSwyllys 48399ebb4caSwyllys } 48499ebb4caSwyllys 48599ebb4caSwyllys static KMF_RETURN 48699ebb4caSwyllys pk_import_pk12_pk11( 48799ebb4caSwyllys KMF_HANDLE_T kmfhandle, 48899ebb4caSwyllys KMF_CREDENTIAL *p12cred, 48999ebb4caSwyllys KMF_CREDENTIAL *tokencred, 49099ebb4caSwyllys char *label, char *token_spec, 49199ebb4caSwyllys char *filename) 49299ebb4caSwyllys { 49399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 4945b3e1433Swyllys KMF_X509_DER_CERT *certs = NULL; 49599ebb4caSwyllys KMF_RAW_KEY_DATA *keys = NULL; 49699ebb4caSwyllys int ncerts = 0; 49799ebb4caSwyllys int nkeys = 0; 49899ebb4caSwyllys int i; 49930a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 5005b3e1433Swyllys KMF_ATTRIBUTE *attrlist = NULL; 50130a5e8faSwyllys int numattr = 0; 50299ebb4caSwyllys 50399ebb4caSwyllys rv = select_token(kmfhandle, token_spec, FALSE); 50499ebb4caSwyllys 50599ebb4caSwyllys if (rv != KMF_OK) { 50699ebb4caSwyllys return (rv); 50799ebb4caSwyllys } 50899ebb4caSwyllys 50930a5e8faSwyllys rv = kmf_import_objects(kmfhandle, filename, p12cred, 51099ebb4caSwyllys &certs, &ncerts, &keys, &nkeys); 51199ebb4caSwyllys 51299ebb4caSwyllys if (rv == KMF_OK) { 5135b3e1433Swyllys NEW_ATTRLIST(attrlist, (3 + (2 * nkeys))); 51430a5e8faSwyllys 51530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 51630a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 51730a5e8faSwyllys sizeof (kstype)); 51830a5e8faSwyllys numattr++; 51930a5e8faSwyllys 52030a5e8faSwyllys if (label != NULL) { 52130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 52230a5e8faSwyllys KMF_KEYLABEL_ATTR, label, 52330a5e8faSwyllys strlen(label)); 52430a5e8faSwyllys numattr++; 52530a5e8faSwyllys } 52630a5e8faSwyllys 52730a5e8faSwyllys if (tokencred != NULL && tokencred->credlen > 0) { 52830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 52930a5e8faSwyllys KMF_CREDENTIAL_ATTR, tokencred, 53030a5e8faSwyllys sizeof (KMF_CREDENTIAL)); 53130a5e8faSwyllys numattr++; 53230a5e8faSwyllys } 53399ebb4caSwyllys 53499ebb4caSwyllys /* The order of certificates and keys should match */ 53599ebb4caSwyllys for (i = 0; i < nkeys; i++) { 53630a5e8faSwyllys int num = numattr; 53799ebb4caSwyllys 5385b3e1433Swyllys if (i < ncerts) { 53930a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 5405b3e1433Swyllys KMF_CERT_DATA_ATTR, &certs[i].certificate, 54130a5e8faSwyllys sizeof (KMF_DATA)); 54230a5e8faSwyllys num++; 5435b3e1433Swyllys } 54430a5e8faSwyllys 54530a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 54630a5e8faSwyllys KMF_RAW_KEY_ATTR, &keys[i], 54730a5e8faSwyllys sizeof (KMF_RAW_KEY_DATA)); 54830a5e8faSwyllys num++; 54930a5e8faSwyllys 55030a5e8faSwyllys rv = kmf_store_key(kmfhandle, num, attrlist); 55130a5e8faSwyllys 55299ebb4caSwyllys } 5535b3e1433Swyllys free(attrlist); 55499ebb4caSwyllys } 55599ebb4caSwyllys 55699ebb4caSwyllys if (rv == KMF_OK) { 5575b3e1433Swyllys numattr = 0; 5585b3e1433Swyllys NEW_ATTRLIST(attrlist, (1 + (2 * ncerts))); 55999ebb4caSwyllys 56099ebb4caSwyllys (void) printf(gettext("Found %d certificate(s) and %d " 56199ebb4caSwyllys "key(s) in %s\n"), ncerts, nkeys, filename); 5625b3e1433Swyllys 56330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 56430a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 56530a5e8faSwyllys numattr++; 56699ebb4caSwyllys 56799ebb4caSwyllys for (i = 0; rv == KMF_OK && i < ncerts; i++) { 56830a5e8faSwyllys int num = numattr; 5695b3e1433Swyllys if (certs[i].kmf_private.label != NULL) { 5705b3e1433Swyllys kmf_set_attr_at_index(attrlist, num, 5715b3e1433Swyllys KMF_CERT_LABEL_ATTR, 5725b3e1433Swyllys certs[i].kmf_private.label, 5735b3e1433Swyllys strlen(certs[i].kmf_private.label)); 5745b3e1433Swyllys num++; 5755b3e1433Swyllys } else if (i == 0 && label != NULL) { 57630a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 57730a5e8faSwyllys KMF_CERT_LABEL_ATTR, label, strlen(label)); 57830a5e8faSwyllys num++; 57930a5e8faSwyllys } 58030a5e8faSwyllys 58130a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 5825b3e1433Swyllys KMF_CERT_DATA_ATTR, &certs[i].certificate, 5835b3e1433Swyllys sizeof (KMF_DATA)); 58430a5e8faSwyllys num++; 58530a5e8faSwyllys 58630a5e8faSwyllys rv = kmf_store_cert(kmfhandle, num, attrlist); 58799ebb4caSwyllys } 5885b3e1433Swyllys free(attrlist); 58999ebb4caSwyllys } 59099ebb4caSwyllys 5915b3e1433Swyllys end: 59299ebb4caSwyllys /* 59399ebb4caSwyllys * Cleanup memory. 59499ebb4caSwyllys */ 59599ebb4caSwyllys if (certs) { 59699ebb4caSwyllys for (i = 0; i < ncerts; i++) 5975b3e1433Swyllys kmf_free_kmf_cert(kmfhandle, &certs[i]); 59899ebb4caSwyllys free(certs); 59999ebb4caSwyllys } 60099ebb4caSwyllys if (keys) { 60199ebb4caSwyllys for (i = 0; i < nkeys; i++) 60230a5e8faSwyllys kmf_free_raw_key(&keys[i]); 60399ebb4caSwyllys free(keys); 60499ebb4caSwyllys } 60599ebb4caSwyllys 60699ebb4caSwyllys return (rv); 60799ebb4caSwyllys } 60899ebb4caSwyllys 60946d33f7eSwyllys /*ARGSUSED*/ 61030a5e8faSwyllys static KMF_RETURN 61130a5e8faSwyllys pk_import_keys(KMF_HANDLE_T kmfhandle, 61230a5e8faSwyllys KMF_KEYSTORE_TYPE kstype, char *token_spec, 61330a5e8faSwyllys KMF_CREDENTIAL *cred, char *filename, 61430a5e8faSwyllys char *label, char *senstr, char *extstr) 61530a5e8faSwyllys { 61630a5e8faSwyllys KMF_RETURN rv = KMF_OK; 61730a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 61830a5e8faSwyllys KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL; 61930a5e8faSwyllys int numattr = 0; 62030a5e8faSwyllys KMF_KEY_HANDLE key; 62130a5e8faSwyllys KMF_RAW_KEY_DATA rawkey; 62230a5e8faSwyllys KMF_KEY_CLASS class = KMF_ASYM_PRI; 62330a5e8faSwyllys int numkeys = 1; 62430a5e8faSwyllys 62530a5e8faSwyllys if (kstype == KMF_KEYSTORE_PK11TOKEN) { 62630a5e8faSwyllys rv = select_token(kmfhandle, token_spec, FALSE); 62730a5e8faSwyllys } 62830a5e8faSwyllys if (rv != KMF_OK) 62930a5e8faSwyllys return (rv); 63030a5e8faSwyllys /* 63130a5e8faSwyllys * First, set up to read the keyfile using the FILE plugin 63230a5e8faSwyllys * mechanisms. 63330a5e8faSwyllys */ 63430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 63530a5e8faSwyllys &fileks, sizeof (fileks)); 63630a5e8faSwyllys numattr++; 63730a5e8faSwyllys 63830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 63930a5e8faSwyllys &numkeys, sizeof (numkeys)); 64030a5e8faSwyllys numattr++; 64130a5e8faSwyllys 64230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 64330a5e8faSwyllys &key, sizeof (key)); 64430a5e8faSwyllys numattr++; 64530a5e8faSwyllys 64630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR, 64730a5e8faSwyllys &rawkey, sizeof (rawkey)); 64830a5e8faSwyllys numattr++; 64930a5e8faSwyllys 65030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, 65130a5e8faSwyllys &class, sizeof (class)); 65230a5e8faSwyllys numattr++; 65330a5e8faSwyllys 65430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, 65530a5e8faSwyllys filename, strlen(filename)); 65630a5e8faSwyllys numattr++; 65730a5e8faSwyllys 65830a5e8faSwyllys rv = kmf_find_key(kmfhandle, numattr, attrlist); 65930a5e8faSwyllys if (rv == KMF_OK) { 66030a5e8faSwyllys numattr = 0; 66130a5e8faSwyllys 66230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 66330a5e8faSwyllys &kstype, sizeof (kstype)); 66430a5e8faSwyllys numattr++; 66530a5e8faSwyllys 66630a5e8faSwyllys if (cred != NULL && cred->credlen > 0) { 66730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 66830a5e8faSwyllys KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); 66930a5e8faSwyllys numattr++; 67030a5e8faSwyllys } 67130a5e8faSwyllys 67230a5e8faSwyllys if (label != NULL) { 67330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 67430a5e8faSwyllys KMF_KEYLABEL_ATTR, label, strlen(label)); 67530a5e8faSwyllys numattr++; 67630a5e8faSwyllys } 67730a5e8faSwyllys 67830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 67930a5e8faSwyllys KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey)); 68030a5e8faSwyllys numattr++; 68130a5e8faSwyllys 68230a5e8faSwyllys rv = kmf_store_key(kmfhandle, numattr, attrlist); 68330a5e8faSwyllys if (rv == KMF_OK) { 68446d33f7eSwyllys (void) printf(gettext("Importing %d keys\n"), numkeys); 68530a5e8faSwyllys } 68630a5e8faSwyllys 68730a5e8faSwyllys kmf_free_kmf_key(kmfhandle, &key); 68830a5e8faSwyllys kmf_free_raw_key(&rawkey); 68930a5e8faSwyllys } else { 69030a5e8faSwyllys cryptoerror(LOG_STDERR, 69130a5e8faSwyllys gettext("Failed to load key from file (%s)\n"), 69230a5e8faSwyllys filename); 69330a5e8faSwyllys } 69430a5e8faSwyllys return (rv); 69530a5e8faSwyllys } 69630a5e8faSwyllys 69730a5e8faSwyllys static KMF_RETURN 69830a5e8faSwyllys pk_import_rawkey(KMF_HANDLE_T kmfhandle, 69930a5e8faSwyllys KMF_KEYSTORE_TYPE kstype, char *token, 70030a5e8faSwyllys KMF_CREDENTIAL *cred, 70130a5e8faSwyllys char *filename, char *label, KMF_KEY_ALG keyAlg, 70230a5e8faSwyllys char *senstr, char *extstr) 70330a5e8faSwyllys { 70430a5e8faSwyllys KMF_RETURN rv = KMF_OK; 70530a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 70630a5e8faSwyllys int numattr = 0; 70730a5e8faSwyllys uint32_t keylen; 70830a5e8faSwyllys boolean_t sensitive = B_FALSE; 70930a5e8faSwyllys boolean_t not_extractable = B_FALSE; 710*6b35cb3cSRichard PALO KMF_DATA keydata = { 0, NULL }; 71130a5e8faSwyllys KMF_KEY_HANDLE rawkey; 71230a5e8faSwyllys 71330a5e8faSwyllys rv = kmf_read_input_file(kmfhandle, filename, &keydata); 71430a5e8faSwyllys if (rv != KMF_OK) 71530a5e8faSwyllys return (rv); 71630a5e8faSwyllys 71730a5e8faSwyllys rv = select_token(kmfhandle, token, FALSE); 71830a5e8faSwyllys 71930a5e8faSwyllys if (rv != KMF_OK) { 72030a5e8faSwyllys return (rv); 72130a5e8faSwyllys } 72230a5e8faSwyllys if (senstr != NULL) { 72330a5e8faSwyllys if (tolower(senstr[0]) == 'y') 72430a5e8faSwyllys sensitive = B_TRUE; 72530a5e8faSwyllys else if (tolower(senstr[0]) == 'n') 72630a5e8faSwyllys sensitive = B_FALSE; 72730a5e8faSwyllys else { 72830a5e8faSwyllys cryptoerror(LOG_STDERR, 72930a5e8faSwyllys gettext("Incorrect sensitive option value.\n")); 73030a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 73130a5e8faSwyllys } 73230a5e8faSwyllys } 73330a5e8faSwyllys 73430a5e8faSwyllys if (extstr != NULL) { 73530a5e8faSwyllys if (tolower(extstr[0]) == 'y') 73630a5e8faSwyllys not_extractable = B_FALSE; 73730a5e8faSwyllys else if (tolower(extstr[0]) == 'n') 73830a5e8faSwyllys not_extractable = B_TRUE; 73930a5e8faSwyllys else { 74030a5e8faSwyllys cryptoerror(LOG_STDERR, 74130a5e8faSwyllys gettext("Incorrect extractable option value.\n")); 74230a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 74330a5e8faSwyllys } 74430a5e8faSwyllys } 74530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 74630a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 74730a5e8faSwyllys numattr++; 74830a5e8faSwyllys 74930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 75030a5e8faSwyllys KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey)); 75130a5e8faSwyllys numattr++; 75230a5e8faSwyllys 75330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 75430a5e8faSwyllys KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG)); 75530a5e8faSwyllys numattr++; 75630a5e8faSwyllys 75730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 75830a5e8faSwyllys KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length); 75930a5e8faSwyllys numattr++; 76030a5e8faSwyllys 76130a5e8faSwyllys /* Key length is given in bits not bytes */ 76230a5e8faSwyllys keylen = keydata.Length * 8; 76330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 76430a5e8faSwyllys KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length)); 76530a5e8faSwyllys numattr++; 76630a5e8faSwyllys 76730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 76830a5e8faSwyllys KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive)); 76930a5e8faSwyllys numattr++; 77030a5e8faSwyllys 77130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 77230a5e8faSwyllys KMF_NON_EXTRACTABLE_BOOL_ATTR, ¬_extractable, 77330a5e8faSwyllys sizeof (not_extractable)); 77430a5e8faSwyllys numattr++; 77530a5e8faSwyllys 77630a5e8faSwyllys if (label != NULL) { 77730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 77830a5e8faSwyllys KMF_KEYLABEL_ATTR, label, strlen(label)); 77930a5e8faSwyllys numattr++; 78030a5e8faSwyllys } 78130a5e8faSwyllys if (cred != NULL && cred->credlen > 0) { 78230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 78330a5e8faSwyllys KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); 78430a5e8faSwyllys numattr++; 78530a5e8faSwyllys } 78630a5e8faSwyllys rv = kmf_create_sym_key(kmfhandle, numattr, attrlist); 78730a5e8faSwyllys 78830a5e8faSwyllys return (rv); 78930a5e8faSwyllys } 79030a5e8faSwyllys 79199ebb4caSwyllys /* 79299ebb4caSwyllys * Import objects from into KMF repositories. 7937711facfSdinak */ 7947711facfSdinak int 7957711facfSdinak pk_import(int argc, char *argv[]) 7967711facfSdinak { 79749e21299Sdinak int opt; 79849e21299Sdinak extern int optind_av; 79949e21299Sdinak extern char *optarg_av; 80049e21299Sdinak char *token_spec = NULL; 8017711facfSdinak char *filename = NULL; 80299ebb4caSwyllys char *keyfile = NULL; 80399ebb4caSwyllys char *certfile = NULL; 80499ebb4caSwyllys char *crlfile = NULL; 80530a5e8faSwyllys char *label = NULL; 80699ebb4caSwyllys char *dir = NULL; 80799ebb4caSwyllys char *prefix = NULL; 80899ebb4caSwyllys char *trustflags = NULL; 80999ebb4caSwyllys char *verify_crl = NULL; 81030a5e8faSwyllys char *keytype = "generic"; 81130a5e8faSwyllys char *senstr = NULL; 81230a5e8faSwyllys char *extstr = NULL; 81399ebb4caSwyllys boolean_t verify_crl_flag = B_FALSE; 81499ebb4caSwyllys int oclass = 0; 81599ebb4caSwyllys KMF_KEYSTORE_TYPE kstype = 0; 81699ebb4caSwyllys KMF_ENCODE_FORMAT kfmt = 0; 81799ebb4caSwyllys KMF_ENCODE_FORMAT okfmt = KMF_FORMAT_ASN1; 81899ebb4caSwyllys KMF_RETURN rv = KMF_OK; 81999ebb4caSwyllys KMF_CREDENTIAL pk12cred = { NULL, 0 }; 82099ebb4caSwyllys KMF_CREDENTIAL tokencred = { NULL, 0 }; 82199ebb4caSwyllys KMF_HANDLE_T kmfhandle = NULL; 82230a5e8faSwyllys KMF_KEY_ALG keyAlg = KMF_GENERIC_SECRET; 8237711facfSdinak 82449e21299Sdinak /* Parse command line options. Do NOT i18n/l10n. */ 82599ebb4caSwyllys while ((opt = getopt_av(argc, argv, 82699ebb4caSwyllys "T:(token)i:(infile)" 82799ebb4caSwyllys "k:(keystore)y:(objtype)" 82899ebb4caSwyllys "d:(dir)p:(prefix)" 82999ebb4caSwyllys "n:(certlabel)N:(label)" 83099ebb4caSwyllys "K:(outkey)c:(outcert)" 83199ebb4caSwyllys "v:(verifycrl)l:(outcrl)" 83230a5e8faSwyllys "E:(keytype)s:(sensitive)x:(extractable)" 833448b8615Swyllys "t:(trust)F:(outformat)")) != EOF) { 83499ebb4caSwyllys if (EMPTYSTRING(optarg_av)) 83599ebb4caSwyllys return (PK_ERR_USAGE); 83649e21299Sdinak switch (opt) { 83749e21299Sdinak case 'T': /* token specifier */ 83849e21299Sdinak if (token_spec) 83949e21299Sdinak return (PK_ERR_USAGE); 84049e21299Sdinak token_spec = optarg_av; 84149e21299Sdinak break; 84299ebb4caSwyllys case 'c': /* output cert file name */ 84399ebb4caSwyllys if (certfile) 84499ebb4caSwyllys return (PK_ERR_USAGE); 84599ebb4caSwyllys certfile = optarg_av; 84699ebb4caSwyllys break; 84799ebb4caSwyllys case 'l': /* output CRL file name */ 84899ebb4caSwyllys if (crlfile) 84999ebb4caSwyllys return (PK_ERR_USAGE); 85099ebb4caSwyllys crlfile = optarg_av; 85199ebb4caSwyllys break; 85299ebb4caSwyllys case 'K': /* output key file name */ 85399ebb4caSwyllys if (keyfile) 85499ebb4caSwyllys return (PK_ERR_USAGE); 85599ebb4caSwyllys keyfile = optarg_av; 85699ebb4caSwyllys break; 85749e21299Sdinak case 'i': /* input file name */ 85849e21299Sdinak if (filename) 85949e21299Sdinak return (PK_ERR_USAGE); 86049e21299Sdinak filename = optarg_av; 86149e21299Sdinak break; 86299ebb4caSwyllys case 'k': 86399ebb4caSwyllys kstype = KS2Int(optarg_av); 86499ebb4caSwyllys if (kstype == 0) 86599ebb4caSwyllys return (PK_ERR_USAGE); 86699ebb4caSwyllys break; 86799ebb4caSwyllys case 'y': 86899ebb4caSwyllys oclass = OT2Int(optarg_av); 86999ebb4caSwyllys if (oclass == -1) 87099ebb4caSwyllys return (PK_ERR_USAGE); 87199ebb4caSwyllys break; 87299ebb4caSwyllys case 'd': 87399ebb4caSwyllys dir = optarg_av; 87499ebb4caSwyllys break; 87599ebb4caSwyllys case 'p': 87699ebb4caSwyllys if (prefix) 87799ebb4caSwyllys return (PK_ERR_USAGE); 87899ebb4caSwyllys prefix = optarg_av; 87999ebb4caSwyllys break; 88099ebb4caSwyllys case 'n': 88199ebb4caSwyllys case 'N': 88230a5e8faSwyllys if (label) 88399ebb4caSwyllys return (PK_ERR_USAGE); 88430a5e8faSwyllys label = optarg_av; 88599ebb4caSwyllys break; 88699ebb4caSwyllys case 'F': 88799ebb4caSwyllys okfmt = Str2Format(optarg_av); 88899ebb4caSwyllys if (okfmt == KMF_FORMAT_UNDEF) 88999ebb4caSwyllys return (PK_ERR_USAGE); 89099ebb4caSwyllys break; 89199ebb4caSwyllys case 't': 89299ebb4caSwyllys if (trustflags) 89399ebb4caSwyllys return (PK_ERR_USAGE); 89499ebb4caSwyllys trustflags = optarg_av; 89599ebb4caSwyllys break; 89699ebb4caSwyllys case 'v': 89799ebb4caSwyllys verify_crl = optarg_av; 89899ebb4caSwyllys if (tolower(verify_crl[0]) == 'y') 89999ebb4caSwyllys verify_crl_flag = B_TRUE; 90099ebb4caSwyllys else if (tolower(verify_crl[0]) == 'n') 90199ebb4caSwyllys verify_crl_flag = B_FALSE; 90299ebb4caSwyllys else 90399ebb4caSwyllys return (PK_ERR_USAGE); 90499ebb4caSwyllys break; 90530a5e8faSwyllys case 'E': 90630a5e8faSwyllys keytype = optarg_av; 90730a5e8faSwyllys break; 90830a5e8faSwyllys case 's': 90930a5e8faSwyllys if (senstr) 91030a5e8faSwyllys return (PK_ERR_USAGE); 91130a5e8faSwyllys senstr = optarg_av; 91230a5e8faSwyllys break; 91330a5e8faSwyllys case 'x': 91430a5e8faSwyllys if (extstr) 91530a5e8faSwyllys return (PK_ERR_USAGE); 91630a5e8faSwyllys extstr = optarg_av; 91730a5e8faSwyllys break; 91849e21299Sdinak default: 91949e21299Sdinak return (PK_ERR_USAGE); 92049e21299Sdinak } 92149e21299Sdinak } 9227711facfSdinak 92399ebb4caSwyllys /* Assume keystore = PKCS#11 if not specified */ 92499ebb4caSwyllys if (kstype == 0) 92599ebb4caSwyllys kstype = KMF_KEYSTORE_PK11TOKEN; 92649e21299Sdinak 92749e21299Sdinak /* Filename arg is required. */ 92899ebb4caSwyllys if (EMPTYSTRING(filename)) { 92999ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("The 'infile' parameter" 93099ebb4caSwyllys "is required for the import operation.\n")); 9317711facfSdinak return (PK_ERR_USAGE); 93299ebb4caSwyllys } 9337711facfSdinak 93449e21299Sdinak /* No additional args allowed. */ 93549e21299Sdinak argc -= optind_av; 93649e21299Sdinak argv += optind_av; 93749e21299Sdinak if (argc) 93849e21299Sdinak return (PK_ERR_USAGE); 9397711facfSdinak 940577f4726Swyllys DIR_OPTION_CHECK(kstype, dir); 941577f4726Swyllys 94299ebb4caSwyllys /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ 94399ebb4caSwyllys if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && 94499ebb4caSwyllys kstype != KMF_KEYSTORE_PK11TOKEN) { 94599ebb4caSwyllys 94699ebb4caSwyllys (void) fprintf(stderr, gettext("The objtype parameter " 94799ebb4caSwyllys "is only relevant if keystore=pkcs11\n")); 94899ebb4caSwyllys return (PK_ERR_USAGE); 9497711facfSdinak } 9507711facfSdinak 95199ebb4caSwyllys /* 95299ebb4caSwyllys * You must specify a certlabel (cert label) when importing 95399ebb4caSwyllys * into NSS or PKCS#11. 95499ebb4caSwyllys */ 95599ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS && 95630a5e8faSwyllys (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) { 95799ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("The 'label' argument " 95899ebb4caSwyllys "is required for this operation\n")); 95999ebb4caSwyllys return (PK_ERR_USAGE); 96099ebb4caSwyllys } 9617711facfSdinak 96230a5e8faSwyllys if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) { 963592106a2SWyllys Ingersoll char *kmferrstr = NULL; 964592106a2SWyllys Ingersoll KMF_RETURN rv2; 96599ebb4caSwyllys /* 96630a5e8faSwyllys * Allow for raw key data to be imported. 96799ebb4caSwyllys */ 96830a5e8faSwyllys if (rv == KMF_ERR_ENCODING) { 96930a5e8faSwyllys rv = KMF_OK; 97030a5e8faSwyllys kfmt = KMF_FORMAT_RAWKEY; 97130a5e8faSwyllys /* 97230a5e8faSwyllys * Set the object class only if it was not 97330a5e8faSwyllys * given on the command line or if it was 97430a5e8faSwyllys * specified as a symmetric key object. 97530a5e8faSwyllys */ 97630a5e8faSwyllys if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) { 97730a5e8faSwyllys oclass = PK_SYMKEY_OBJ; 97830a5e8faSwyllys } else { 9797711facfSdinak cryptoerror(LOG_STDERR, gettext( 98030a5e8faSwyllys "The input file does not contain the " 98130a5e8faSwyllys "object type indicated on command " 98230a5e8faSwyllys "line.")); 98330a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 98499ebb4caSwyllys } 98530a5e8faSwyllys } else { 986592106a2SWyllys Ingersoll if (rv == KMF_ERR_OPEN_FILE) { 9877711facfSdinak cryptoerror(LOG_STDERR, 988592106a2SWyllys Ingersoll gettext("Cannot open file (%s)\n."), 989592106a2SWyllys Ingersoll filename); 990592106a2SWyllys Ingersoll } else { 991592106a2SWyllys Ingersoll rv2 = kmf_get_kmf_error_str(rv, &kmferrstr); 992592106a2SWyllys Ingersoll if (rv2 == KMF_OK && kmferrstr) { 993592106a2SWyllys Ingersoll cryptoerror(LOG_STDERR, 994592106a2SWyllys Ingersoll gettext("libkmf error: %s"), 995592106a2SWyllys Ingersoll kmferrstr); 996592106a2SWyllys Ingersoll kmf_free_str(kmferrstr); 997592106a2SWyllys Ingersoll } 998592106a2SWyllys Ingersoll } 99999ebb4caSwyllys return (rv); 10007711facfSdinak } 100130a5e8faSwyllys } 100230a5e8faSwyllys 100330a5e8faSwyllys /* Check parameters for raw key import operation */ 100430a5e8faSwyllys if (kfmt == KMF_FORMAT_RAWKEY) { 100530a5e8faSwyllys if (keytype != NULL && 100630a5e8faSwyllys Str2SymKeyType(keytype, &keyAlg) != 0) { 100730a5e8faSwyllys cryptoerror(LOG_STDERR, 100830a5e8faSwyllys gettext("Unrecognized keytype(%s).\n"), keytype); 100930a5e8faSwyllys return (PK_ERR_USAGE); 101030a5e8faSwyllys } 101130a5e8faSwyllys if (senstr != NULL && extstr != NULL && 101230a5e8faSwyllys kstype != KMF_KEYSTORE_PK11TOKEN) { 101330a5e8faSwyllys cryptoerror(LOG_STDERR, 101430a5e8faSwyllys gettext("The sensitive or extractable option " 101530a5e8faSwyllys "applies only when importing a key from a file " 101630a5e8faSwyllys "into a PKCS#11 keystore.\n")); 101730a5e8faSwyllys return (PK_ERR_USAGE); 101830a5e8faSwyllys } 101930a5e8faSwyllys } 102030a5e8faSwyllys 102130a5e8faSwyllys /* If no objtype was given, treat it as a certificate */ 102299ebb4caSwyllys if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 || 102399ebb4caSwyllys kfmt == KMF_FORMAT_PEM)) 102499ebb4caSwyllys oclass = PK_CERT_OBJ; 10257711facfSdinak 102699ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS) { 102799ebb4caSwyllys if (oclass == PK_CRL_OBJ && 102899ebb4caSwyllys (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { 10297711facfSdinak cryptoerror(LOG_STDERR, gettext( 103099ebb4caSwyllys "CRL data can only be imported as DER or " 103199ebb4caSwyllys "PEM format")); 103299ebb4caSwyllys return (PK_ERR_USAGE); 10337711facfSdinak } 10347711facfSdinak 103599ebb4caSwyllys if (oclass == PK_CERT_OBJ && 103699ebb4caSwyllys (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { 10377711facfSdinak cryptoerror(LOG_STDERR, gettext( 103899ebb4caSwyllys "Certificates can only be imported as DER or " 103999ebb4caSwyllys "PEM format")); 104099ebb4caSwyllys return (PK_ERR_USAGE); 10417711facfSdinak } 10427711facfSdinak 104399ebb4caSwyllys /* we do not import private keys except in PKCS12 bundles */ 104499ebb4caSwyllys if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) { 104599ebb4caSwyllys cryptoerror(LOG_STDERR, gettext( 104699ebb4caSwyllys "Private key data can only be imported as part " 104799ebb4caSwyllys "of a PKCS12 file.\n")); 104899ebb4caSwyllys return (PK_ERR_USAGE); 104999ebb4caSwyllys } 105099ebb4caSwyllys } 105199ebb4caSwyllys 105299ebb4caSwyllys if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) { 105399ebb4caSwyllys if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { 105499ebb4caSwyllys cryptoerror(LOG_STDERR, gettext( 105599ebb4caSwyllys "The 'outkey' and 'outcert' parameters " 105699ebb4caSwyllys "are required for the import operation " 105799ebb4caSwyllys "when the 'file' keystore is used.\n")); 105899ebb4caSwyllys return (PK_ERR_USAGE); 105999ebb4caSwyllys } 106099ebb4caSwyllys } 106199ebb4caSwyllys 106299ebb4caSwyllys if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) 106399ebb4caSwyllys token_spec = PK_DEFAULT_PK11TOKEN; 106499ebb4caSwyllys else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) 106599ebb4caSwyllys token_spec = DEFAULT_NSS_TOKEN; 106699ebb4caSwyllys 106799ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) { 106899ebb4caSwyllys (void) get_pk12_password(&pk12cred); 106999ebb4caSwyllys } 107099ebb4caSwyllys 107130a5e8faSwyllys if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY || 107230a5e8faSwyllys (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) && 107330a5e8faSwyllys (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) { 107430a5e8faSwyllys (void) get_token_password(kstype, token_spec, &tokencred); 107530a5e8faSwyllys } 107630a5e8faSwyllys 107730a5e8faSwyllys if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 107899ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Error initializing " 107999ebb4caSwyllys "KMF: 0x%02x\n"), rv); 108099ebb4caSwyllys goto end; 108199ebb4caSwyllys } 108299ebb4caSwyllys 108399ebb4caSwyllys switch (kstype) { 108499ebb4caSwyllys case KMF_KEYSTORE_PK11TOKEN: 108599ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 108699ebb4caSwyllys rv = pk_import_pk12_pk11( 108730a5e8faSwyllys kmfhandle, &pk12cred, 108830a5e8faSwyllys &tokencred, label, 108930a5e8faSwyllys token_spec, filename); 109099ebb4caSwyllys else if (oclass == PK_CERT_OBJ) 109199ebb4caSwyllys rv = pk_import_cert( 109230a5e8faSwyllys kmfhandle, kstype, 109330a5e8faSwyllys label, token_spec, 109499ebb4caSwyllys filename, 109599ebb4caSwyllys NULL, NULL, NULL); 109699ebb4caSwyllys else if (oclass == PK_CRL_OBJ) 109799ebb4caSwyllys rv = pk_import_file_crl( 109830a5e8faSwyllys kmfhandle, filename, 1099448b8615Swyllys crlfile, okfmt); 110030a5e8faSwyllys else if (kfmt == KMF_FORMAT_RAWKEY && 110130a5e8faSwyllys oclass == PK_SYMKEY_OBJ) { 110230a5e8faSwyllys rv = pk_import_rawkey(kmfhandle, 110330a5e8faSwyllys kstype, token_spec, &tokencred, 110430a5e8faSwyllys filename, label, 110530a5e8faSwyllys keyAlg, senstr, extstr); 110630a5e8faSwyllys } else if (kfmt == KMF_FORMAT_PEM || 110730a5e8faSwyllys kfmt == KMF_FORMAT_PEM_KEYPAIR) { 110830a5e8faSwyllys rv = pk_import_keys(kmfhandle, 110930a5e8faSwyllys kstype, token_spec, &tokencred, 111030a5e8faSwyllys filename, label, senstr, extstr); 111130a5e8faSwyllys } else { 111230a5e8faSwyllys rv = PK_ERR_USAGE; 111330a5e8faSwyllys } 11147711facfSdinak break; 111599ebb4caSwyllys case KMF_KEYSTORE_NSS: 111699ebb4caSwyllys if (dir == NULL) 111799ebb4caSwyllys dir = PK_DEFAULT_DIRECTORY; 111899ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 111999ebb4caSwyllys rv = pk_import_pk12_nss( 112099ebb4caSwyllys kmfhandle, &pk12cred, 112199ebb4caSwyllys &tokencred, 112299ebb4caSwyllys token_spec, dir, prefix, 112330a5e8faSwyllys label, trustflags, filename); 112499ebb4caSwyllys else if (oclass == PK_CERT_OBJ) { 112599ebb4caSwyllys rv = pk_import_cert( 112699ebb4caSwyllys kmfhandle, kstype, 112730a5e8faSwyllys label, token_spec, 112899ebb4caSwyllys filename, dir, prefix, trustflags); 112999ebb4caSwyllys } else if (oclass == PK_CRL_OBJ) { 113099ebb4caSwyllys rv = pk_import_nss_crl( 113130a5e8faSwyllys kmfhandle, verify_crl_flag, 113230a5e8faSwyllys filename, dir, prefix); 11337711facfSdinak } 113499ebb4caSwyllys break; 113599ebb4caSwyllys case KMF_KEYSTORE_OPENSSL: 113699ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 113799ebb4caSwyllys rv = pk_import_pk12_files( 113899ebb4caSwyllys kmfhandle, &pk12cred, 113999ebb4caSwyllys filename, certfile, keyfile, 1140448b8615Swyllys okfmt); 114199ebb4caSwyllys else if (oclass == PK_CRL_OBJ) { 114299ebb4caSwyllys rv = pk_import_file_crl( 114330a5e8faSwyllys kmfhandle, filename, 1144448b8615Swyllys crlfile, okfmt); 114599ebb4caSwyllys } else 114699ebb4caSwyllys /* 114799ebb4caSwyllys * It doesn't make sense to import anything 114899ebb4caSwyllys * else for the files plugin. 114999ebb4caSwyllys */ 115099ebb4caSwyllys return (PK_ERR_USAGE); 115199ebb4caSwyllys break; 115299ebb4caSwyllys default: 115399ebb4caSwyllys rv = PK_ERR_USAGE; 115499ebb4caSwyllys break; 11557711facfSdinak } 11567711facfSdinak 115799ebb4caSwyllys end: 115899ebb4caSwyllys if (rv != KMF_OK) 115999ebb4caSwyllys display_error(kmfhandle, rv, 116099ebb4caSwyllys gettext("Error importing objects")); 11617711facfSdinak 116299ebb4caSwyllys if (tokencred.cred != NULL) 116399ebb4caSwyllys free(tokencred.cred); 11647711facfSdinak 116599ebb4caSwyllys if (pk12cred.cred != NULL) 116699ebb4caSwyllys free(pk12cred.cred); 116799ebb4caSwyllys 116830a5e8faSwyllys (void) kmf_finalize(kmfhandle); 116999ebb4caSwyllys 117099ebb4caSwyllys if (rv != KMF_OK) 117199ebb4caSwyllys return (PK_ERR_USAGE); 117299ebb4caSwyllys 11737711facfSdinak return (0); 11747711facfSdinak } 1175