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 /* 22*fa60c371Swyllys * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237711facfSdinak * Use is subject to license terms. 247711facfSdinak */ 257711facfSdinak 267711facfSdinak #pragma ident "%Z%%M% %I% %E% SMI" 277711facfSdinak 287711facfSdinak /* 297711facfSdinak * This file implements the import operation for this tool. 307711facfSdinak * The basic flow of the process is to decrypt the PKCS#12 317711facfSdinak * input file if it has a password, parse the elements in 327711facfSdinak * the file, find the soft token, log into it, import the 337711facfSdinak * PKCS#11 objects into the soft token, and log out. 347711facfSdinak */ 357711facfSdinak 367711facfSdinak #include <stdio.h> 377711facfSdinak #include <stdlib.h> 387711facfSdinak #include <string.h> 3999ebb4caSwyllys #include <ctype.h> 407711facfSdinak #include <errno.h> 417711facfSdinak #include <fcntl.h> 427711facfSdinak #include <sys/types.h> 437711facfSdinak #include <sys/stat.h> 447711facfSdinak #include "common.h" 457711facfSdinak 4699ebb4caSwyllys #include <kmfapi.h> 4799ebb4caSwyllys 485b3e1433Swyllys #define NEW_ATTRLIST(a, n) \ 495b3e1433Swyllys { \ 505b3e1433Swyllys a = (KMF_ATTRIBUTE *)malloc(n * sizeof (KMF_ATTRIBUTE)); \ 515b3e1433Swyllys if (a == NULL) { \ 525b3e1433Swyllys rv = KMF_ERR_MEMORY; \ 535b3e1433Swyllys goto end; \ 545b3e1433Swyllys } \ 555b3e1433Swyllys (void) memset(a, 0, n * sizeof (KMF_ATTRIBUTE)); \ 565b3e1433Swyllys } 575b3e1433Swyllys 5899ebb4caSwyllys static KMF_RETURN 5999ebb4caSwyllys pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred, 6099ebb4caSwyllys char *outfile, char *certfile, char *keyfile, 6199ebb4caSwyllys char *dir, char *keydir, KMF_ENCODE_FORMAT outformat) 627711facfSdinak { 6399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 645b3e1433Swyllys KMF_X509_DER_CERT *certs = NULL; 6599ebb4caSwyllys KMF_RAW_KEY_DATA *keys = NULL; 6699ebb4caSwyllys int ncerts = 0; 6799ebb4caSwyllys int nkeys = 0; 6899ebb4caSwyllys int i; 6930a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 705b3e1433Swyllys KMF_ATTRIBUTE *attrlist = NULL; 7130a5e8faSwyllys int numattr = 0; 7299ebb4caSwyllys 7330a5e8faSwyllys rv = kmf_import_objects(kmfhandle, outfile, cred, 7430a5e8faSwyllys &certs, &ncerts, &keys, &nkeys); 7599ebb4caSwyllys 7699ebb4caSwyllys if (rv == KMF_OK) { 7799ebb4caSwyllys (void) printf(gettext("Found %d certificate(s) and %d " 7830a5e8faSwyllys "key(s) in %s\n"), ncerts, nkeys, outfile); 7999ebb4caSwyllys } 8099ebb4caSwyllys 8199ebb4caSwyllys if (rv == KMF_OK && ncerts > 0) { 8299ebb4caSwyllys char newcertfile[MAXPATHLEN]; 8399ebb4caSwyllys 845b3e1433Swyllys NEW_ATTRLIST(attrlist, (3 + (3 * ncerts))); 855b3e1433Swyllys 8630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 8730a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 8830a5e8faSwyllys numattr++; 8930a5e8faSwyllys 9030a5e8faSwyllys if (dir != NULL) { 9130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 9230a5e8faSwyllys KMF_DIRPATH_ATTR, dir, strlen(dir)); 9330a5e8faSwyllys numattr++; 9430a5e8faSwyllys } 9530a5e8faSwyllys 9630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 9730a5e8faSwyllys KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat)); 9830a5e8faSwyllys numattr++; 9999ebb4caSwyllys 10099ebb4caSwyllys for (i = 0; rv == KMF_OK && i < ncerts; i++) { 10130a5e8faSwyllys int num = numattr; 10230a5e8faSwyllys 10399ebb4caSwyllys /* 10499ebb4caSwyllys * If storing more than 1 cert, gotta change 10599ebb4caSwyllys * the name so we don't overwrite the previous one. 10699ebb4caSwyllys * Just append a _# to the name. 10799ebb4caSwyllys */ 10899ebb4caSwyllys if (i > 0) { 10999ebb4caSwyllys (void) snprintf(newcertfile, 11030a5e8faSwyllys sizeof (newcertfile), "%s_%d", certfile, i); 11130a5e8faSwyllys 11230a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 11330a5e8faSwyllys KMF_CERT_FILENAME_ATTR, newcertfile, 11430a5e8faSwyllys strlen(newcertfile)); 11530a5e8faSwyllys num++; 11699ebb4caSwyllys } else { 11730a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 11830a5e8faSwyllys KMF_CERT_FILENAME_ATTR, certfile, 11930a5e8faSwyllys strlen(certfile)); 12030a5e8faSwyllys num++; 12199ebb4caSwyllys } 12230a5e8faSwyllys 1235b3e1433Swyllys if (certs[i].kmf_private.label != NULL) { 1245b3e1433Swyllys kmf_set_attr_at_index(attrlist, num, 1255b3e1433Swyllys KMF_CERT_LABEL_ATTR, 1265b3e1433Swyllys certs[i].kmf_private.label, 1275b3e1433Swyllys strlen(certs[i].kmf_private.label)); 1285b3e1433Swyllys num++; 1295b3e1433Swyllys } 13030a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 1315b3e1433Swyllys KMF_CERT_DATA_ATTR, &certs[i].certificate, 1325b3e1433Swyllys sizeof (KMF_DATA)); 13330a5e8faSwyllys num++; 13430a5e8faSwyllys rv = kmf_store_cert(kmfhandle, num, attrlist); 13599ebb4caSwyllys } 1365b3e1433Swyllys free(attrlist); 1377711facfSdinak } 13899ebb4caSwyllys if (rv == KMF_OK && nkeys > 0) { 13999ebb4caSwyllys char newkeyfile[MAXPATHLEN]; 14030a5e8faSwyllys numattr = 0; 1415b3e1433Swyllys NEW_ATTRLIST(attrlist, (4 + (4 * nkeys))); 14230a5e8faSwyllys 14330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 14430a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 14530a5e8faSwyllys sizeof (kstype)); 14630a5e8faSwyllys numattr++; 14730a5e8faSwyllys 14830a5e8faSwyllys if (keydir != NULL) { 14930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 15030a5e8faSwyllys KMF_DIRPATH_ATTR, keydir, 15130a5e8faSwyllys strlen(keydir)); 15230a5e8faSwyllys numattr++; 15330a5e8faSwyllys } 15430a5e8faSwyllys 15530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 15630a5e8faSwyllys KMF_ENCODE_FORMAT_ATTR, &outformat, 15730a5e8faSwyllys sizeof (outformat)); 15830a5e8faSwyllys numattr++; 15930a5e8faSwyllys 16030a5e8faSwyllys if (cred != NULL && cred->credlen > 0) { 16130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 16230a5e8faSwyllys KMF_CREDENTIAL_ATTR, cred, 16330a5e8faSwyllys sizeof (KMF_CREDENTIAL)); 16430a5e8faSwyllys numattr++; 16530a5e8faSwyllys } 16699ebb4caSwyllys 16799ebb4caSwyllys /* The order of certificates and keys should match */ 16899ebb4caSwyllys for (i = 0; rv == KMF_OK && i < nkeys; i++) { 16930a5e8faSwyllys int num = numattr; 17099ebb4caSwyllys 17199ebb4caSwyllys if (i > 0) { 17299ebb4caSwyllys (void) snprintf(newkeyfile, 17330a5e8faSwyllys sizeof (newkeyfile), "%s_%d", keyfile, i); 17430a5e8faSwyllys 17530a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 17630a5e8faSwyllys KMF_KEY_FILENAME_ATTR, newkeyfile, 17730a5e8faSwyllys strlen(newkeyfile)); 17830a5e8faSwyllys num++; 17999ebb4caSwyllys } else { 18030a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 18130a5e8faSwyllys KMF_KEY_FILENAME_ATTR, keyfile, 18230a5e8faSwyllys strlen(keyfile)); 18330a5e8faSwyllys num++; 18499ebb4caSwyllys } 18599ebb4caSwyllys 1865b3e1433Swyllys if (i < ncerts) { 1875b3e1433Swyllys kmf_set_attr_at_index(attrlist, num, 1885b3e1433Swyllys KMF_CERT_DATA_ATTR, &certs[i], 1895b3e1433Swyllys sizeof (KMF_CERT_DATA_ATTR)); 1905b3e1433Swyllys num++; 1915b3e1433Swyllys } 19230a5e8faSwyllys 19330a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 19430a5e8faSwyllys KMF_RAW_KEY_ATTR, &keys[i], 19530a5e8faSwyllys sizeof (KMF_RAW_KEY_DATA)); 19630a5e8faSwyllys num++; 19730a5e8faSwyllys 19830a5e8faSwyllys rv = kmf_store_key(kmfhandle, num, attrlist); 19999ebb4caSwyllys } 2005b3e1433Swyllys free(attrlist); 2017711facfSdinak } 2025b3e1433Swyllys end: 20399ebb4caSwyllys /* 20499ebb4caSwyllys * Cleanup memory. 20599ebb4caSwyllys */ 20699ebb4caSwyllys if (certs) { 20799ebb4caSwyllys for (i = 0; i < ncerts; i++) 2085b3e1433Swyllys kmf_free_kmf_cert(kmfhandle, &certs[i]); 20999ebb4caSwyllys free(certs); 21099ebb4caSwyllys } 21199ebb4caSwyllys if (keys) { 21299ebb4caSwyllys for (i = 0; i < nkeys; i++) 21330a5e8faSwyllys kmf_free_raw_key(&keys[i]); 21499ebb4caSwyllys free(keys); 2157711facfSdinak } 2167711facfSdinak 2177711facfSdinak 21899ebb4caSwyllys return (rv); 2197711facfSdinak } 2207711facfSdinak 22199ebb4caSwyllys 22299ebb4caSwyllys static KMF_RETURN 22399ebb4caSwyllys pk_import_pk12_nss( 22499ebb4caSwyllys KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred, 22599ebb4caSwyllys KMF_CREDENTIAL *tokencred, 22699ebb4caSwyllys char *token_spec, char *dir, char *prefix, 22799ebb4caSwyllys char *nickname, char *trustflags, char *filename) 2287711facfSdinak { 22999ebb4caSwyllys KMF_RETURN rv = KMF_OK; 2305b3e1433Swyllys KMF_X509_DER_CERT *certs = NULL; 23199ebb4caSwyllys KMF_RAW_KEY_DATA *keys = NULL; 23299ebb4caSwyllys int ncerts = 0; 23399ebb4caSwyllys int nkeys = 0; 23499ebb4caSwyllys int i; 23530a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 2365b3e1433Swyllys KMF_ATTRIBUTE *attrlist = NULL; 23730a5e8faSwyllys int numattr = 0; 23899ebb4caSwyllys 23999ebb4caSwyllys rv = configure_nss(kmfhandle, dir, prefix); 24099ebb4caSwyllys if (rv != KMF_OK) 24199ebb4caSwyllys return (rv); 2427711facfSdinak 24330a5e8faSwyllys rv = kmf_import_objects(kmfhandle, filename, kmfcred, 24430a5e8faSwyllys &certs, &ncerts, &keys, &nkeys); 2457711facfSdinak 24699ebb4caSwyllys if (rv == KMF_OK) 24799ebb4caSwyllys (void) printf(gettext("Found %d certificate(s) and %d " 24830a5e8faSwyllys "key(s) in %s\n"), ncerts, nkeys, filename); 2497711facfSdinak 25099ebb4caSwyllys if (rv == KMF_OK) { 2515b3e1433Swyllys NEW_ATTRLIST(attrlist, (3 + (2 * ncerts))); 2525b3e1433Swyllys 25330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 25430a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 25530a5e8faSwyllys numattr++; 25630a5e8faSwyllys 25730a5e8faSwyllys if (token_spec != NULL) { 25830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 25930a5e8faSwyllys KMF_TOKEN_LABEL_ATTR, token_spec, 26030a5e8faSwyllys strlen(token_spec)); 26130a5e8faSwyllys numattr++; 26230a5e8faSwyllys } 2637711facfSdinak 26430a5e8faSwyllys if (trustflags != NULL) { 26530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 26630a5e8faSwyllys KMF_TRUSTFLAG_ATTR, trustflags, 26730a5e8faSwyllys strlen(trustflags)); 26830a5e8faSwyllys numattr++; 26930a5e8faSwyllys } 2707711facfSdinak 27199ebb4caSwyllys for (i = 0; rv == KMF_OK && i < ncerts; i++) { 27230a5e8faSwyllys int num = numattr; 2737711facfSdinak 2745b3e1433Swyllys if (certs[i].kmf_private.label != NULL) { 2755b3e1433Swyllys kmf_set_attr_at_index(attrlist, num, 2765b3e1433Swyllys KMF_CERT_LABEL_ATTR, 2775b3e1433Swyllys certs[i].kmf_private.label, 2785b3e1433Swyllys strlen(certs[i].kmf_private.label)); 2795b3e1433Swyllys num++; 2805b3e1433Swyllys } else if (i == 0 && nickname != NULL) { 28130a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 28230a5e8faSwyllys KMF_CERT_LABEL_ATTR, nickname, 28330a5e8faSwyllys strlen(nickname)); 28430a5e8faSwyllys num++; 28530a5e8faSwyllys } 28630a5e8faSwyllys 28730a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 2885b3e1433Swyllys KMF_CERT_DATA_ATTR, 2895b3e1433Swyllys &certs[i].certificate, sizeof (KMF_DATA)); 29030a5e8faSwyllys num++; 29130a5e8faSwyllys rv = kmf_store_cert(kmfhandle, num, attrlist); 2927711facfSdinak } 2935b3e1433Swyllys free(attrlist); 2945b3e1433Swyllys attrlist = NULL; 29599ebb4caSwyllys if (rv != KMF_OK) { 29699ebb4caSwyllys display_error(kmfhandle, rv, 29730a5e8faSwyllys gettext("Error storing certificate in NSS token")); 2987711facfSdinak } 2997711facfSdinak } 3007711facfSdinak 30199ebb4caSwyllys if (rv == KMF_OK) { 30230a5e8faSwyllys numattr = 0; 3035b3e1433Swyllys NEW_ATTRLIST(attrlist, (4 + (2 * nkeys))); 30430a5e8faSwyllys 30530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 30630a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 30730a5e8faSwyllys sizeof (kstype)); 30830a5e8faSwyllys numattr++; 30930a5e8faSwyllys 31030a5e8faSwyllys if (token_spec != NULL) { 31130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 31230a5e8faSwyllys KMF_TOKEN_LABEL_ATTR, token_spec, 31330a5e8faSwyllys strlen(token_spec)); 31430a5e8faSwyllys numattr++; 31530a5e8faSwyllys } 31630a5e8faSwyllys 31730a5e8faSwyllys if (nickname != NULL) { 31830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 31930a5e8faSwyllys KMF_KEYLABEL_ATTR, nickname, 32030a5e8faSwyllys strlen(nickname)); 32130a5e8faSwyllys numattr++; 32230a5e8faSwyllys } 32330a5e8faSwyllys 32430a5e8faSwyllys if (tokencred->credlen > 0) { 32530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 32630a5e8faSwyllys KMF_CREDENTIAL_ATTR, tokencred, 32730a5e8faSwyllys sizeof (KMF_CREDENTIAL)); 32830a5e8faSwyllys numattr++; 32930a5e8faSwyllys } 3307711facfSdinak 33199ebb4caSwyllys /* The order of certificates and keys should match */ 33299ebb4caSwyllys for (i = 0; i < nkeys; i++) { 33330a5e8faSwyllys int num = numattr; 33430a5e8faSwyllys 3355b3e1433Swyllys if (i < ncerts) { 3365b3e1433Swyllys kmf_set_attr_at_index(attrlist, num, 3375b3e1433Swyllys KMF_CERT_DATA_ATTR, &certs[i], 3385b3e1433Swyllys sizeof (KMF_DATA)); 3395b3e1433Swyllys num++; 3405b3e1433Swyllys } 34130a5e8faSwyllys 34230a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 34330a5e8faSwyllys KMF_RAW_KEY_ATTR, &keys[i], 34430a5e8faSwyllys sizeof (KMF_RAW_KEY_DATA)); 34530a5e8faSwyllys num++; 3467711facfSdinak 34730a5e8faSwyllys rv = kmf_store_key(kmfhandle, num, attrlist); 34899ebb4caSwyllys } 3495b3e1433Swyllys free(attrlist); 3507711facfSdinak } 3517711facfSdinak 3525b3e1433Swyllys end: 35399ebb4caSwyllys /* 35499ebb4caSwyllys * Cleanup memory. 35599ebb4caSwyllys */ 35699ebb4caSwyllys if (certs) { 35799ebb4caSwyllys for (i = 0; i < ncerts; i++) 3585b3e1433Swyllys kmf_free_kmf_cert(kmfhandle, &certs[i]); 35999ebb4caSwyllys free(certs); 3607711facfSdinak } 36199ebb4caSwyllys if (keys) { 36299ebb4caSwyllys for (i = 0; i < nkeys; i++) 36330a5e8faSwyllys kmf_free_raw_key(&keys[i]); 36499ebb4caSwyllys free(keys); 3657711facfSdinak } 3667711facfSdinak 36799ebb4caSwyllys return (rv); 36899ebb4caSwyllys } 3697711facfSdinak 37099ebb4caSwyllys static KMF_RETURN 37199ebb4caSwyllys pk_import_cert( 37299ebb4caSwyllys KMF_HANDLE_T kmfhandle, 37399ebb4caSwyllys KMF_KEYSTORE_TYPE kstype, 37499ebb4caSwyllys char *label, char *token_spec, char *filename, 37599ebb4caSwyllys char *dir, char *prefix, char *trustflags) 37699ebb4caSwyllys { 37799ebb4caSwyllys KMF_RETURN rv = KMF_OK; 37830a5e8faSwyllys KMF_ATTRIBUTE attrlist[32]; 379*fa60c371Swyllys KMF_CREDENTIAL tokencred; 38030a5e8faSwyllys int i = 0; 3817711facfSdinak 38299ebb4caSwyllys if (kstype == KMF_KEYSTORE_PK11TOKEN) { 38399ebb4caSwyllys rv = select_token(kmfhandle, token_spec, FALSE); 38430a5e8faSwyllys } else if (kstype == KMF_KEYSTORE_NSS) { 38530a5e8faSwyllys rv = configure_nss(kmfhandle, dir, prefix); 3867711facfSdinak } 38730a5e8faSwyllys if (rv != KMF_OK) 38830a5e8faSwyllys return (rv); 3897711facfSdinak 39030a5e8faSwyllys kmf_set_attr_at_index(attrlist, i, 39130a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE)); 39230a5e8faSwyllys i++; 3937711facfSdinak 39430a5e8faSwyllys kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR, 39530a5e8faSwyllys filename, strlen(filename)); 39630a5e8faSwyllys i++; 39730a5e8faSwyllys 39830a5e8faSwyllys if (label != NULL) { 39930a5e8faSwyllys kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR, 40030a5e8faSwyllys label, strlen(label)); 40130a5e8faSwyllys i++; 4027711facfSdinak } 4037711facfSdinak 40430a5e8faSwyllys if (kstype == KMF_KEYSTORE_NSS) { 40530a5e8faSwyllys if (trustflags != NULL) { 40630a5e8faSwyllys kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR, 40730a5e8faSwyllys trustflags, strlen(trustflags)); 40830a5e8faSwyllys i++; 40930a5e8faSwyllys } 4107711facfSdinak 41130a5e8faSwyllys if (token_spec != NULL) { 41230a5e8faSwyllys kmf_set_attr_at_index(attrlist, i, 41330a5e8faSwyllys KMF_TOKEN_LABEL_ATTR, 41430a5e8faSwyllys token_spec, strlen(token_spec)); 41530a5e8faSwyllys i++; 41630a5e8faSwyllys } 41730a5e8faSwyllys } 41830a5e8faSwyllys 41930a5e8faSwyllys rv = kmf_import_cert(kmfhandle, i, attrlist); 420*fa60c371Swyllys if (rv == KMF_ERR_AUTH_FAILED) { 421*fa60c371Swyllys /* 422*fa60c371Swyllys * The token requires a credential, prompt and try again. 423*fa60c371Swyllys */ 424*fa60c371Swyllys (void) get_token_password(kstype, token_spec, &tokencred); 425*fa60c371Swyllys kmf_set_attr_at_index(attrlist, i, KMF_CREDENTIAL_ATTR, 426*fa60c371Swyllys &tokencred, sizeof (KMF_CREDENTIAL)); 427*fa60c371Swyllys i++; 428*fa60c371Swyllys 429*fa60c371Swyllys rv = kmf_import_cert(kmfhandle, i, attrlist); 430*fa60c371Swyllys 431*fa60c371Swyllys } 43299ebb4caSwyllys return (rv); 4337711facfSdinak } 4347711facfSdinak 43599ebb4caSwyllys static KMF_RETURN 43699ebb4caSwyllys pk_import_file_crl(void *kmfhandle, 43799ebb4caSwyllys char *infile, 43899ebb4caSwyllys char *outfile, 43999ebb4caSwyllys char *outdir, 44099ebb4caSwyllys KMF_ENCODE_FORMAT outfmt) 4417711facfSdinak { 44230a5e8faSwyllys int numattr = 0; 44330a5e8faSwyllys KMF_ATTRIBUTE attrlist[8]; 44430a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 44530a5e8faSwyllys 44630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 44730a5e8faSwyllys &kstype, sizeof (kstype)); 44830a5e8faSwyllys numattr++; 44930a5e8faSwyllys if (infile) { 45030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 45130a5e8faSwyllys KMF_CRL_FILENAME_ATTR, infile, strlen(infile)); 45230a5e8faSwyllys numattr++; 45330a5e8faSwyllys } 45430a5e8faSwyllys if (outdir) { 45530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 45630a5e8faSwyllys KMF_DIRPATH_ATTR, outdir, strlen(outdir)); 45730a5e8faSwyllys numattr++; 45830a5e8faSwyllys } 45930a5e8faSwyllys if (outfile) { 46030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 46130a5e8faSwyllys KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile)); 46230a5e8faSwyllys numattr++; 46330a5e8faSwyllys } 46430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 46530a5e8faSwyllys KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt)); 46630a5e8faSwyllys numattr++; 4677711facfSdinak 46830a5e8faSwyllys return (kmf_import_crl(kmfhandle, numattr, attrlist)); 46999ebb4caSwyllys } 4707711facfSdinak 47199ebb4caSwyllys static KMF_RETURN 47299ebb4caSwyllys pk_import_nss_crl(void *kmfhandle, 47399ebb4caSwyllys boolean_t verify_crl_flag, 47499ebb4caSwyllys char *infile, 47599ebb4caSwyllys char *outdir, 47699ebb4caSwyllys char *prefix) 47799ebb4caSwyllys { 47899ebb4caSwyllys KMF_RETURN rv; 47930a5e8faSwyllys int numattr = 0; 48030a5e8faSwyllys KMF_ATTRIBUTE attrlist[4]; 48130a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 48299ebb4caSwyllys 48399ebb4caSwyllys rv = configure_nss(kmfhandle, outdir, prefix); 48499ebb4caSwyllys if (rv != KMF_OK) 4857711facfSdinak return (rv); 4867711facfSdinak 48730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 48830a5e8faSwyllys &kstype, sizeof (kstype)); 48930a5e8faSwyllys numattr++; 49030a5e8faSwyllys if (infile) { 49130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR, 49230a5e8faSwyllys infile, strlen(infile)); 49330a5e8faSwyllys numattr++; 49430a5e8faSwyllys } 49530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR, 49630a5e8faSwyllys &verify_crl_flag, sizeof (verify_crl_flag)); 49730a5e8faSwyllys numattr++; 4987711facfSdinak 49930a5e8faSwyllys return (kmf_import_crl(kmfhandle, numattr, attrlist)); 5007711facfSdinak 5017711facfSdinak } 5027711facfSdinak 50399ebb4caSwyllys static KMF_RETURN 50499ebb4caSwyllys pk_import_pk12_pk11( 50599ebb4caSwyllys KMF_HANDLE_T kmfhandle, 50699ebb4caSwyllys KMF_CREDENTIAL *p12cred, 50799ebb4caSwyllys KMF_CREDENTIAL *tokencred, 50899ebb4caSwyllys char *label, char *token_spec, 50999ebb4caSwyllys char *filename) 5107711facfSdinak { 51199ebb4caSwyllys KMF_RETURN rv = KMF_OK; 5125b3e1433Swyllys KMF_X509_DER_CERT *certs = NULL; 51399ebb4caSwyllys KMF_RAW_KEY_DATA *keys = NULL; 51499ebb4caSwyllys int ncerts = 0; 51599ebb4caSwyllys int nkeys = 0; 51699ebb4caSwyllys int i; 51730a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 5185b3e1433Swyllys KMF_ATTRIBUTE *attrlist = NULL; 51930a5e8faSwyllys int numattr = 0; 5207711facfSdinak 52199ebb4caSwyllys rv = select_token(kmfhandle, token_spec, FALSE); 5227711facfSdinak 52399ebb4caSwyllys if (rv != KMF_OK) { 52499ebb4caSwyllys return (rv); 5257711facfSdinak } 5267711facfSdinak 52730a5e8faSwyllys rv = kmf_import_objects(kmfhandle, filename, p12cred, 52830a5e8faSwyllys &certs, &ncerts, &keys, &nkeys); 5297711facfSdinak 53099ebb4caSwyllys if (rv == KMF_OK) { 5315b3e1433Swyllys NEW_ATTRLIST(attrlist, (3 + (2 * nkeys))); 53230a5e8faSwyllys 53330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 53430a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 53530a5e8faSwyllys sizeof (kstype)); 53630a5e8faSwyllys numattr++; 53730a5e8faSwyllys 53830a5e8faSwyllys if (label != NULL) { 53930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 54030a5e8faSwyllys KMF_KEYLABEL_ATTR, label, 54130a5e8faSwyllys strlen(label)); 54230a5e8faSwyllys numattr++; 54330a5e8faSwyllys } 54430a5e8faSwyllys 54530a5e8faSwyllys if (tokencred != NULL && tokencred->credlen > 0) { 54630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 54730a5e8faSwyllys KMF_CREDENTIAL_ATTR, tokencred, 54830a5e8faSwyllys sizeof (KMF_CREDENTIAL)); 54930a5e8faSwyllys numattr++; 55030a5e8faSwyllys } 5517711facfSdinak 55299ebb4caSwyllys /* The order of certificates and keys should match */ 55399ebb4caSwyllys for (i = 0; i < nkeys; i++) { 55430a5e8faSwyllys int num = numattr; 55530a5e8faSwyllys 5565b3e1433Swyllys if (i < ncerts) { 5575b3e1433Swyllys kmf_set_attr_at_index(attrlist, num, 5585b3e1433Swyllys KMF_CERT_DATA_ATTR, &certs[i].certificate, 5595b3e1433Swyllys sizeof (KMF_DATA)); 5605b3e1433Swyllys num++; 5615b3e1433Swyllys } 56230a5e8faSwyllys 56330a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 56430a5e8faSwyllys KMF_RAW_KEY_ATTR, &keys[i], 56530a5e8faSwyllys sizeof (KMF_RAW_KEY_DATA)); 56630a5e8faSwyllys num++; 56730a5e8faSwyllys 56830a5e8faSwyllys rv = kmf_store_key(kmfhandle, num, attrlist); 5697711facfSdinak 57099ebb4caSwyllys } 5715b3e1433Swyllys free(attrlist); 5727711facfSdinak } 5737711facfSdinak 57499ebb4caSwyllys if (rv == KMF_OK) { 5755b3e1433Swyllys numattr = 0; 5765b3e1433Swyllys NEW_ATTRLIST(attrlist, (1 + (2 * ncerts))); 5777711facfSdinak 57899ebb4caSwyllys (void) printf(gettext("Found %d certificate(s) and %d " 57930a5e8faSwyllys "key(s) in %s\n"), ncerts, nkeys, filename); 5805b3e1433Swyllys 58130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 58230a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 58330a5e8faSwyllys numattr++; 5847711facfSdinak 58599ebb4caSwyllys for (i = 0; rv == KMF_OK && i < ncerts; i++) { 58630a5e8faSwyllys int num = numattr; 5875b3e1433Swyllys if (certs[i].kmf_private.label != NULL) { 5885b3e1433Swyllys kmf_set_attr_at_index(attrlist, num, 5895b3e1433Swyllys KMF_CERT_LABEL_ATTR, 5905b3e1433Swyllys certs[i].kmf_private.label, 5915b3e1433Swyllys strlen(certs[i].kmf_private.label)); 5925b3e1433Swyllys num++; 5935b3e1433Swyllys } else if (i == 0 && label != NULL) { 59430a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 59530a5e8faSwyllys KMF_CERT_LABEL_ATTR, label, strlen(label)); 59630a5e8faSwyllys num++; 59730a5e8faSwyllys } 5987711facfSdinak 59930a5e8faSwyllys kmf_set_attr_at_index(attrlist, num, 6005b3e1433Swyllys KMF_CERT_DATA_ATTR, &certs[i].certificate, 6015b3e1433Swyllys sizeof (KMF_DATA)); 60230a5e8faSwyllys num++; 60330a5e8faSwyllys 60430a5e8faSwyllys rv = kmf_store_cert(kmfhandle, num, attrlist); 60599ebb4caSwyllys } 6065b3e1433Swyllys free(attrlist); 6077711facfSdinak } 6087711facfSdinak 6095b3e1433Swyllys end: 61099ebb4caSwyllys /* 61199ebb4caSwyllys * Cleanup memory. 61299ebb4caSwyllys */ 61399ebb4caSwyllys if (certs) { 61499ebb4caSwyllys for (i = 0; i < ncerts; i++) 6155b3e1433Swyllys kmf_free_kmf_cert(kmfhandle, &certs[i]); 61699ebb4caSwyllys free(certs); 61799ebb4caSwyllys } 61899ebb4caSwyllys if (keys) { 61999ebb4caSwyllys for (i = 0; i < nkeys; i++) 62030a5e8faSwyllys kmf_free_raw_key(&keys[i]); 62199ebb4caSwyllys free(keys); 6227711facfSdinak } 6237711facfSdinak 62499ebb4caSwyllys return (rv); 6257711facfSdinak } 6267711facfSdinak 62746d33f7eSwyllys /*ARGSUSED*/ 62830a5e8faSwyllys static KMF_RETURN 62930a5e8faSwyllys pk_import_keys(KMF_HANDLE_T kmfhandle, 63030a5e8faSwyllys KMF_KEYSTORE_TYPE kstype, char *token_spec, 63130a5e8faSwyllys KMF_CREDENTIAL *cred, char *filename, 63230a5e8faSwyllys char *label, char *senstr, char *extstr) 63330a5e8faSwyllys { 63430a5e8faSwyllys KMF_RETURN rv = KMF_OK; 63530a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 63630a5e8faSwyllys KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL; 63730a5e8faSwyllys int numattr = 0; 63830a5e8faSwyllys KMF_KEY_HANDLE key; 63930a5e8faSwyllys KMF_RAW_KEY_DATA rawkey; 64030a5e8faSwyllys KMF_KEY_CLASS class = KMF_ASYM_PRI; 64130a5e8faSwyllys int numkeys = 1; 64230a5e8faSwyllys 64330a5e8faSwyllys if (kstype == KMF_KEYSTORE_PK11TOKEN) { 64430a5e8faSwyllys rv = select_token(kmfhandle, token_spec, FALSE); 64530a5e8faSwyllys } 64630a5e8faSwyllys if (rv != KMF_OK) 64730a5e8faSwyllys return (rv); 64830a5e8faSwyllys /* 64930a5e8faSwyllys * First, set up to read the keyfile using the FILE plugin 65030a5e8faSwyllys * mechanisms. 65130a5e8faSwyllys */ 65230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 65330a5e8faSwyllys &fileks, sizeof (fileks)); 65430a5e8faSwyllys numattr++; 65530a5e8faSwyllys 65630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 65730a5e8faSwyllys &numkeys, sizeof (numkeys)); 65830a5e8faSwyllys numattr++; 65930a5e8faSwyllys 66030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 66130a5e8faSwyllys &key, sizeof (key)); 66230a5e8faSwyllys numattr++; 66330a5e8faSwyllys 66430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR, 66530a5e8faSwyllys &rawkey, sizeof (rawkey)); 66630a5e8faSwyllys numattr++; 66730a5e8faSwyllys 66830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, 66930a5e8faSwyllys &class, sizeof (class)); 67030a5e8faSwyllys numattr++; 67130a5e8faSwyllys 67230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, 67330a5e8faSwyllys filename, strlen(filename)); 67430a5e8faSwyllys numattr++; 67530a5e8faSwyllys 67630a5e8faSwyllys rv = kmf_find_key(kmfhandle, numattr, attrlist); 67730a5e8faSwyllys if (rv == KMF_OK) { 67830a5e8faSwyllys numattr = 0; 67930a5e8faSwyllys 68030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 68130a5e8faSwyllys &kstype, sizeof (kstype)); 68230a5e8faSwyllys numattr++; 68330a5e8faSwyllys 68430a5e8faSwyllys if (cred != NULL && cred->credlen > 0) { 68530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 68630a5e8faSwyllys KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); 68730a5e8faSwyllys numattr++; 68830a5e8faSwyllys } 68930a5e8faSwyllys 69030a5e8faSwyllys if (label != NULL) { 69130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 69230a5e8faSwyllys KMF_KEYLABEL_ATTR, label, strlen(label)); 69330a5e8faSwyllys numattr++; 69430a5e8faSwyllys } 69530a5e8faSwyllys 69630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 69730a5e8faSwyllys KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey)); 69830a5e8faSwyllys numattr++; 69930a5e8faSwyllys 70030a5e8faSwyllys rv = kmf_store_key(kmfhandle, numattr, attrlist); 70130a5e8faSwyllys if (rv == KMF_OK) { 70246d33f7eSwyllys (void) printf(gettext("Importing %d keys\n"), numkeys); 70330a5e8faSwyllys } 70430a5e8faSwyllys 70530a5e8faSwyllys kmf_free_kmf_key(kmfhandle, &key); 70630a5e8faSwyllys kmf_free_raw_key(&rawkey); 70730a5e8faSwyllys } else { 70830a5e8faSwyllys cryptoerror(LOG_STDERR, 70930a5e8faSwyllys gettext("Failed to load key from file (%s)\n"), 71030a5e8faSwyllys filename); 71130a5e8faSwyllys } 71230a5e8faSwyllys return (rv); 71330a5e8faSwyllys } 71430a5e8faSwyllys 71530a5e8faSwyllys static KMF_RETURN 71630a5e8faSwyllys pk_import_rawkey(KMF_HANDLE_T kmfhandle, 71730a5e8faSwyllys KMF_KEYSTORE_TYPE kstype, char *token, 71830a5e8faSwyllys KMF_CREDENTIAL *cred, 71930a5e8faSwyllys char *filename, char *label, KMF_KEY_ALG keyAlg, 72030a5e8faSwyllys char *senstr, char *extstr) 72130a5e8faSwyllys { 72230a5e8faSwyllys KMF_RETURN rv = KMF_OK; 72330a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 72430a5e8faSwyllys int numattr = 0; 72530a5e8faSwyllys uint32_t keylen; 72630a5e8faSwyllys boolean_t sensitive = B_FALSE; 72730a5e8faSwyllys boolean_t not_extractable = B_FALSE; 72830a5e8faSwyllys KMF_DATA keydata = {NULL, 0}; 72930a5e8faSwyllys KMF_KEY_HANDLE rawkey; 73030a5e8faSwyllys 73130a5e8faSwyllys rv = kmf_read_input_file(kmfhandle, filename, &keydata); 73230a5e8faSwyllys if (rv != KMF_OK) 73330a5e8faSwyllys return (rv); 73430a5e8faSwyllys 73530a5e8faSwyllys rv = select_token(kmfhandle, token, FALSE); 73630a5e8faSwyllys 73730a5e8faSwyllys if (rv != KMF_OK) { 73830a5e8faSwyllys return (rv); 73930a5e8faSwyllys } 74030a5e8faSwyllys if (senstr != NULL) { 74130a5e8faSwyllys if (tolower(senstr[0]) == 'y') 74230a5e8faSwyllys sensitive = B_TRUE; 74330a5e8faSwyllys else if (tolower(senstr[0]) == 'n') 74430a5e8faSwyllys sensitive = B_FALSE; 74530a5e8faSwyllys else { 74630a5e8faSwyllys cryptoerror(LOG_STDERR, 74730a5e8faSwyllys gettext("Incorrect sensitive option value.\n")); 74830a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 74930a5e8faSwyllys } 75030a5e8faSwyllys } 75130a5e8faSwyllys 75230a5e8faSwyllys if (extstr != NULL) { 75330a5e8faSwyllys if (tolower(extstr[0]) == 'y') 75430a5e8faSwyllys not_extractable = B_FALSE; 75530a5e8faSwyllys else if (tolower(extstr[0]) == 'n') 75630a5e8faSwyllys not_extractable = B_TRUE; 75730a5e8faSwyllys else { 75830a5e8faSwyllys cryptoerror(LOG_STDERR, 75930a5e8faSwyllys gettext("Incorrect extractable option value.\n")); 76030a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 76130a5e8faSwyllys } 76230a5e8faSwyllys } 76330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 76430a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 76530a5e8faSwyllys numattr++; 76630a5e8faSwyllys 76730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 76830a5e8faSwyllys KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey)); 76930a5e8faSwyllys numattr++; 77030a5e8faSwyllys 77130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 77230a5e8faSwyllys KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG)); 77330a5e8faSwyllys numattr++; 77430a5e8faSwyllys 77530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 77630a5e8faSwyllys KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length); 77730a5e8faSwyllys numattr++; 77830a5e8faSwyllys 77930a5e8faSwyllys /* Key length is given in bits not bytes */ 78030a5e8faSwyllys keylen = keydata.Length * 8; 78130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 78230a5e8faSwyllys KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length)); 78330a5e8faSwyllys numattr++; 78430a5e8faSwyllys 78530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 78630a5e8faSwyllys KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive)); 78730a5e8faSwyllys numattr++; 78830a5e8faSwyllys 78930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 79030a5e8faSwyllys KMF_NON_EXTRACTABLE_BOOL_ATTR, ¬_extractable, 79130a5e8faSwyllys sizeof (not_extractable)); 79230a5e8faSwyllys numattr++; 79330a5e8faSwyllys 79430a5e8faSwyllys if (label != NULL) { 79530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 79630a5e8faSwyllys KMF_KEYLABEL_ATTR, label, strlen(label)); 79730a5e8faSwyllys numattr++; 79830a5e8faSwyllys } 79930a5e8faSwyllys if (cred != NULL && cred->credlen > 0) { 80030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, 80130a5e8faSwyllys KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); 80230a5e8faSwyllys numattr++; 80330a5e8faSwyllys } 80430a5e8faSwyllys rv = kmf_create_sym_key(kmfhandle, numattr, attrlist); 80530a5e8faSwyllys 80630a5e8faSwyllys return (rv); 80730a5e8faSwyllys } 80830a5e8faSwyllys 8097711facfSdinak /* 81099ebb4caSwyllys * Import objects from into KMF repositories. 8117711facfSdinak */ 8127711facfSdinak int 8137711facfSdinak pk_import(int argc, char *argv[]) 8147711facfSdinak { 81549e21299Sdinak int opt; 81649e21299Sdinak extern int optind_av; 81749e21299Sdinak extern char *optarg_av; 81849e21299Sdinak char *token_spec = NULL; 8197711facfSdinak char *filename = NULL; 82099ebb4caSwyllys char *keyfile = NULL; 82199ebb4caSwyllys char *certfile = NULL; 82299ebb4caSwyllys char *crlfile = NULL; 82330a5e8faSwyllys char *label = NULL; 82499ebb4caSwyllys char *dir = NULL; 82599ebb4caSwyllys char *keydir = NULL; 82699ebb4caSwyllys char *prefix = NULL; 82799ebb4caSwyllys char *trustflags = NULL; 82899ebb4caSwyllys char *verify_crl = NULL; 82930a5e8faSwyllys char *keytype = "generic"; 83030a5e8faSwyllys char *senstr = NULL; 83130a5e8faSwyllys char *extstr = NULL; 83299ebb4caSwyllys boolean_t verify_crl_flag = B_FALSE; 83399ebb4caSwyllys int oclass = 0; 83499ebb4caSwyllys KMF_KEYSTORE_TYPE kstype = 0; 83599ebb4caSwyllys KMF_ENCODE_FORMAT kfmt = 0; 83699ebb4caSwyllys KMF_ENCODE_FORMAT okfmt = KMF_FORMAT_ASN1; 83799ebb4caSwyllys KMF_RETURN rv = KMF_OK; 83899ebb4caSwyllys KMF_CREDENTIAL pk12cred = { NULL, 0 }; 83999ebb4caSwyllys KMF_CREDENTIAL tokencred = { NULL, 0 }; 84099ebb4caSwyllys KMF_HANDLE_T kmfhandle = NULL; 84130a5e8faSwyllys KMF_KEY_ALG keyAlg = KMF_GENERIC_SECRET; 8427711facfSdinak 84349e21299Sdinak /* Parse command line options. Do NOT i18n/l10n. */ 84499ebb4caSwyllys while ((opt = getopt_av(argc, argv, 84530a5e8faSwyllys "T:(token)i:(infile)" 84630a5e8faSwyllys "k:(keystore)y:(objtype)" 84730a5e8faSwyllys "d:(dir)p:(prefix)" 84830a5e8faSwyllys "n:(certlabel)N:(label)" 84930a5e8faSwyllys "K:(outkey)c:(outcert)" 85030a5e8faSwyllys "v:(verifycrl)l:(outcrl)" 85130a5e8faSwyllys "E:(keytype)s:(sensitive)x:(extractable)" 85230a5e8faSwyllys "t:(trust)D:(keydir)F:(outformat)")) != EOF) { 85399ebb4caSwyllys if (EMPTYSTRING(optarg_av)) 85499ebb4caSwyllys return (PK_ERR_USAGE); 85549e21299Sdinak switch (opt) { 85649e21299Sdinak case 'T': /* token specifier */ 85749e21299Sdinak if (token_spec) 85849e21299Sdinak return (PK_ERR_USAGE); 85949e21299Sdinak token_spec = optarg_av; 86049e21299Sdinak break; 86199ebb4caSwyllys case 'c': /* output cert file name */ 86299ebb4caSwyllys if (certfile) 86399ebb4caSwyllys return (PK_ERR_USAGE); 86499ebb4caSwyllys certfile = optarg_av; 86599ebb4caSwyllys break; 86699ebb4caSwyllys case 'l': /* output CRL file name */ 86799ebb4caSwyllys if (crlfile) 86899ebb4caSwyllys return (PK_ERR_USAGE); 86999ebb4caSwyllys crlfile = optarg_av; 87099ebb4caSwyllys break; 87199ebb4caSwyllys case 'K': /* output key file name */ 87299ebb4caSwyllys if (keyfile) 87399ebb4caSwyllys return (PK_ERR_USAGE); 87499ebb4caSwyllys keyfile = optarg_av; 87599ebb4caSwyllys break; 87649e21299Sdinak case 'i': /* input file name */ 87749e21299Sdinak if (filename) 87849e21299Sdinak return (PK_ERR_USAGE); 87949e21299Sdinak filename = optarg_av; 88049e21299Sdinak break; 88199ebb4caSwyllys case 'k': 88299ebb4caSwyllys kstype = KS2Int(optarg_av); 88399ebb4caSwyllys if (kstype == 0) 88499ebb4caSwyllys return (PK_ERR_USAGE); 88599ebb4caSwyllys break; 88699ebb4caSwyllys case 'y': 88799ebb4caSwyllys oclass = OT2Int(optarg_av); 88899ebb4caSwyllys if (oclass == -1) 88999ebb4caSwyllys return (PK_ERR_USAGE); 89099ebb4caSwyllys break; 89199ebb4caSwyllys case 'd': 89299ebb4caSwyllys dir = optarg_av; 89399ebb4caSwyllys break; 89499ebb4caSwyllys case 'D': 89599ebb4caSwyllys keydir = optarg_av; 89699ebb4caSwyllys break; 89799ebb4caSwyllys case 'p': 89899ebb4caSwyllys if (prefix) 89999ebb4caSwyllys return (PK_ERR_USAGE); 90099ebb4caSwyllys prefix = optarg_av; 90199ebb4caSwyllys break; 90299ebb4caSwyllys case 'n': 90399ebb4caSwyllys case 'N': 90430a5e8faSwyllys if (label) 90599ebb4caSwyllys return (PK_ERR_USAGE); 90630a5e8faSwyllys label = optarg_av; 90799ebb4caSwyllys break; 90899ebb4caSwyllys case 'F': 90999ebb4caSwyllys okfmt = Str2Format(optarg_av); 91099ebb4caSwyllys if (okfmt == KMF_FORMAT_UNDEF) 91199ebb4caSwyllys return (PK_ERR_USAGE); 91299ebb4caSwyllys break; 91399ebb4caSwyllys case 't': 91499ebb4caSwyllys if (trustflags) 91599ebb4caSwyllys return (PK_ERR_USAGE); 91699ebb4caSwyllys trustflags = optarg_av; 91799ebb4caSwyllys break; 91899ebb4caSwyllys case 'v': 91999ebb4caSwyllys verify_crl = optarg_av; 92099ebb4caSwyllys if (tolower(verify_crl[0]) == 'y') 92199ebb4caSwyllys verify_crl_flag = B_TRUE; 92299ebb4caSwyllys else if (tolower(verify_crl[0]) == 'n') 92399ebb4caSwyllys verify_crl_flag = B_FALSE; 92499ebb4caSwyllys else 92599ebb4caSwyllys return (PK_ERR_USAGE); 92699ebb4caSwyllys break; 92730a5e8faSwyllys case 'E': 92830a5e8faSwyllys keytype = optarg_av; 92930a5e8faSwyllys break; 93030a5e8faSwyllys case 's': 93130a5e8faSwyllys if (senstr) 93230a5e8faSwyllys return (PK_ERR_USAGE); 93330a5e8faSwyllys senstr = optarg_av; 93430a5e8faSwyllys break; 93530a5e8faSwyllys case 'x': 93630a5e8faSwyllys if (extstr) 93730a5e8faSwyllys return (PK_ERR_USAGE); 93830a5e8faSwyllys extstr = optarg_av; 93930a5e8faSwyllys break; 94049e21299Sdinak default: 94149e21299Sdinak return (PK_ERR_USAGE); 94249e21299Sdinak break; 94349e21299Sdinak } 94449e21299Sdinak } 94549e21299Sdinak 94699ebb4caSwyllys /* Assume keystore = PKCS#11 if not specified */ 94799ebb4caSwyllys if (kstype == 0) 94899ebb4caSwyllys kstype = KMF_KEYSTORE_PK11TOKEN; 9497711facfSdinak 95049e21299Sdinak /* Filename arg is required. */ 95199ebb4caSwyllys if (EMPTYSTRING(filename)) { 95299ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("The 'infile' parameter" 95330a5e8faSwyllys "is required for the import operation.\n")); 9547711facfSdinak return (PK_ERR_USAGE); 95599ebb4caSwyllys } 9567711facfSdinak 95749e21299Sdinak /* No additional args allowed. */ 95849e21299Sdinak argc -= optind_av; 95949e21299Sdinak argv += optind_av; 96049e21299Sdinak if (argc) 96149e21299Sdinak return (PK_ERR_USAGE); 9627711facfSdinak 96399ebb4caSwyllys /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ 96499ebb4caSwyllys if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && 96530a5e8faSwyllys kstype != KMF_KEYSTORE_PK11TOKEN) { 9667711facfSdinak 96799ebb4caSwyllys (void) fprintf(stderr, gettext("The objtype parameter " 96830a5e8faSwyllys "is only relevant if keystore=pkcs11\n")); 96999ebb4caSwyllys return (PK_ERR_USAGE); 97099ebb4caSwyllys } 9717711facfSdinak 97299ebb4caSwyllys /* 97399ebb4caSwyllys * You must specify a certlabel (cert label) when importing 97499ebb4caSwyllys * into NSS or PKCS#11. 97599ebb4caSwyllys */ 97699ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS && 97730a5e8faSwyllys (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) { 97899ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("The 'label' argument " 97930a5e8faSwyllys "is required for this operation\n")); 98099ebb4caSwyllys return (PK_ERR_USAGE); 9817711facfSdinak } 9827711facfSdinak 98330a5e8faSwyllys if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) { 98430a5e8faSwyllys /* 98530a5e8faSwyllys * Allow for raw key data to be imported. 98630a5e8faSwyllys */ 98730a5e8faSwyllys if (rv == KMF_ERR_ENCODING) { 98830a5e8faSwyllys rv = KMF_OK; 98930a5e8faSwyllys kfmt = KMF_FORMAT_RAWKEY; 99030a5e8faSwyllys /* 99130a5e8faSwyllys * Set the object class only if it was not 99230a5e8faSwyllys * given on the command line or if it was 99330a5e8faSwyllys * specified as a symmetric key object. 99430a5e8faSwyllys */ 99530a5e8faSwyllys if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) { 99630a5e8faSwyllys oclass = PK_SYMKEY_OBJ; 99730a5e8faSwyllys } else { 99830a5e8faSwyllys cryptoerror(LOG_STDERR, gettext( 99930a5e8faSwyllys "The input file does not contain the " 100030a5e8faSwyllys "object type indicated on command " 100130a5e8faSwyllys "line.")); 100230a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 100330a5e8faSwyllys } 100430a5e8faSwyllys } else { 100530a5e8faSwyllys cryptoerror(LOG_STDERR, 100630a5e8faSwyllys gettext("File format not recognized.")); 100730a5e8faSwyllys return (rv); 100899ebb4caSwyllys } 10097711facfSdinak } 10107711facfSdinak 101130a5e8faSwyllys /* Check parameters for raw key import operation */ 101230a5e8faSwyllys if (kfmt == KMF_FORMAT_RAWKEY) { 101330a5e8faSwyllys if (keytype != NULL && 101430a5e8faSwyllys Str2SymKeyType(keytype, &keyAlg) != 0) { 101530a5e8faSwyllys cryptoerror(LOG_STDERR, 101630a5e8faSwyllys gettext("Unrecognized keytype(%s).\n"), keytype); 101730a5e8faSwyllys return (PK_ERR_USAGE); 101830a5e8faSwyllys } 101930a5e8faSwyllys if (senstr != NULL && extstr != NULL && 102030a5e8faSwyllys kstype != KMF_KEYSTORE_PK11TOKEN) { 102130a5e8faSwyllys cryptoerror(LOG_STDERR, 102230a5e8faSwyllys gettext("The sensitive or extractable option " 102330a5e8faSwyllys "applies only when importing a key from a file " 102430a5e8faSwyllys "into a PKCS#11 keystore.\n")); 102530a5e8faSwyllys return (PK_ERR_USAGE); 102630a5e8faSwyllys } 10277711facfSdinak } 102830a5e8faSwyllys 102930a5e8faSwyllys /* If no objtype was given, treat it as a certificate */ 103099ebb4caSwyllys if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 || 103130a5e8faSwyllys kfmt == KMF_FORMAT_PEM)) 103299ebb4caSwyllys oclass = PK_CERT_OBJ; 10337711facfSdinak 103499ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS) { 103599ebb4caSwyllys if (oclass == PK_CRL_OBJ && 103630a5e8faSwyllys (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { 103799ebb4caSwyllys cryptoerror(LOG_STDERR, gettext( 103830a5e8faSwyllys "CRL data can only be imported as DER or " 103930a5e8faSwyllys "PEM format")); 104099ebb4caSwyllys return (PK_ERR_USAGE); 104199ebb4caSwyllys } 10427711facfSdinak 104399ebb4caSwyllys if (oclass == PK_CERT_OBJ && 104430a5e8faSwyllys (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) { 104599ebb4caSwyllys cryptoerror(LOG_STDERR, gettext( 104630a5e8faSwyllys "Certificates can only be imported as DER or " 104730a5e8faSwyllys "PEM format")); 104899ebb4caSwyllys return (PK_ERR_USAGE); 104999ebb4caSwyllys } 10507711facfSdinak 105199ebb4caSwyllys /* we do not import private keys except in PKCS12 bundles */ 105299ebb4caSwyllys if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) { 105399ebb4caSwyllys cryptoerror(LOG_STDERR, gettext( 105430a5e8faSwyllys "Private key data can only be imported as part " 105530a5e8faSwyllys "of a PKCS12 file.\n")); 105699ebb4caSwyllys return (PK_ERR_USAGE); 105799ebb4caSwyllys } 10587711facfSdinak } 10597711facfSdinak 106099ebb4caSwyllys if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) { 106199ebb4caSwyllys if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) { 10627711facfSdinak cryptoerror(LOG_STDERR, gettext( 106330a5e8faSwyllys "The 'outkey' and 'outcert' parameters " 106430a5e8faSwyllys "are required for the import operation " 106530a5e8faSwyllys "when the 'file' keystore is used.\n")); 106699ebb4caSwyllys return (PK_ERR_USAGE); 10677711facfSdinak } 106899ebb4caSwyllys } 10697711facfSdinak 107099ebb4caSwyllys if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) 107199ebb4caSwyllys token_spec = PK_DEFAULT_PK11TOKEN; 107299ebb4caSwyllys else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) 107399ebb4caSwyllys token_spec = DEFAULT_NSS_TOKEN; 107499ebb4caSwyllys 107599ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) { 107699ebb4caSwyllys (void) get_pk12_password(&pk12cred); 107730a5e8faSwyllys } 107899ebb4caSwyllys 107930a5e8faSwyllys if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY || 108030a5e8faSwyllys (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) && 108130a5e8faSwyllys (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) { 108230a5e8faSwyllys (void) get_token_password(kstype, token_spec, &tokencred); 108399ebb4caSwyllys } 108499ebb4caSwyllys 108530a5e8faSwyllys if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 108699ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Error initializing " 108730a5e8faSwyllys "KMF: 0x%02x\n"), rv); 108899ebb4caSwyllys goto end; 108999ebb4caSwyllys } 109099ebb4caSwyllys 109199ebb4caSwyllys switch (kstype) { 109299ebb4caSwyllys case KMF_KEYSTORE_PK11TOKEN: 109399ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 109499ebb4caSwyllys rv = pk_import_pk12_pk11( 109530a5e8faSwyllys kmfhandle, &pk12cred, 109630a5e8faSwyllys &tokencred, label, 109730a5e8faSwyllys token_spec, filename); 109899ebb4caSwyllys else if (oclass == PK_CERT_OBJ) 109999ebb4caSwyllys rv = pk_import_cert( 110030a5e8faSwyllys kmfhandle, kstype, 110130a5e8faSwyllys label, token_spec, 110230a5e8faSwyllys filename, 110330a5e8faSwyllys NULL, NULL, NULL); 110499ebb4caSwyllys else if (oclass == PK_CRL_OBJ) 110599ebb4caSwyllys rv = pk_import_file_crl( 110630a5e8faSwyllys kmfhandle, filename, 110730a5e8faSwyllys crlfile, dir, okfmt); 110830a5e8faSwyllys else if (kfmt == KMF_FORMAT_RAWKEY && 110930a5e8faSwyllys oclass == PK_SYMKEY_OBJ) { 111030a5e8faSwyllys rv = pk_import_rawkey(kmfhandle, 111130a5e8faSwyllys kstype, token_spec, &tokencred, 111230a5e8faSwyllys filename, label, 111330a5e8faSwyllys keyAlg, senstr, extstr); 111430a5e8faSwyllys } else if (kfmt == KMF_FORMAT_PEM || 111530a5e8faSwyllys kfmt == KMF_FORMAT_PEM_KEYPAIR) { 111630a5e8faSwyllys rv = pk_import_keys(kmfhandle, 111730a5e8faSwyllys kstype, token_spec, &tokencred, 111830a5e8faSwyllys filename, label, senstr, extstr); 111930a5e8faSwyllys } else { 112030a5e8faSwyllys rv = PK_ERR_USAGE; 112130a5e8faSwyllys } 11227711facfSdinak break; 112399ebb4caSwyllys case KMF_KEYSTORE_NSS: 112499ebb4caSwyllys if (dir == NULL) 112599ebb4caSwyllys dir = PK_DEFAULT_DIRECTORY; 112699ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 112799ebb4caSwyllys rv = pk_import_pk12_nss( 112830a5e8faSwyllys kmfhandle, &pk12cred, 112930a5e8faSwyllys &tokencred, 113030a5e8faSwyllys token_spec, dir, prefix, 113130a5e8faSwyllys label, trustflags, filename); 113299ebb4caSwyllys else if (oclass == PK_CERT_OBJ) { 113399ebb4caSwyllys rv = pk_import_cert( 113430a5e8faSwyllys kmfhandle, kstype, 113530a5e8faSwyllys label, token_spec, 113630a5e8faSwyllys filename, dir, prefix, trustflags); 113799ebb4caSwyllys } else if (oclass == PK_CRL_OBJ) { 113899ebb4caSwyllys rv = pk_import_nss_crl( 113930a5e8faSwyllys kmfhandle, verify_crl_flag, 114030a5e8faSwyllys filename, dir, prefix); 114199ebb4caSwyllys } 114299ebb4caSwyllys break; 114399ebb4caSwyllys case KMF_KEYSTORE_OPENSSL: 114499ebb4caSwyllys if (kfmt == KMF_FORMAT_PKCS12) 114599ebb4caSwyllys rv = pk_import_pk12_files( 114630a5e8faSwyllys kmfhandle, &pk12cred, 114730a5e8faSwyllys filename, certfile, keyfile, 114830a5e8faSwyllys dir, keydir, okfmt); 114999ebb4caSwyllys else if (oclass == PK_CRL_OBJ) { 115099ebb4caSwyllys rv = pk_import_file_crl( 115130a5e8faSwyllys kmfhandle, filename, 115230a5e8faSwyllys crlfile, dir, okfmt); 115399ebb4caSwyllys } else 115499ebb4caSwyllys /* 115599ebb4caSwyllys * It doesn't make sense to import anything 115699ebb4caSwyllys * else for the files plugin. 115799ebb4caSwyllys */ 115899ebb4caSwyllys return (PK_ERR_USAGE); 115999ebb4caSwyllys break; 116099ebb4caSwyllys default: 116199ebb4caSwyllys rv = PK_ERR_USAGE; 116299ebb4caSwyllys break; 116399ebb4caSwyllys } 11647711facfSdinak 116599ebb4caSwyllys end: 116699ebb4caSwyllys if (rv != KMF_OK) 116799ebb4caSwyllys display_error(kmfhandle, rv, 116830a5e8faSwyllys gettext("Error importing objects")); 11697711facfSdinak 117099ebb4caSwyllys if (tokencred.cred != NULL) 117199ebb4caSwyllys free(tokencred.cred); 11727711facfSdinak 117399ebb4caSwyllys if (pk12cred.cred != NULL) 117499ebb4caSwyllys free(pk12cred.cred); 11757711facfSdinak 117630a5e8faSwyllys (void) kmf_finalize(kmfhandle); 117799ebb4caSwyllys 117899ebb4caSwyllys if (rv != KMF_OK) 117999ebb4caSwyllys return (PK_ERR_USAGE); 11807711facfSdinak 11817711facfSdinak return (0); 11827711facfSdinak } 1183