import.c revision 7711facfe58561dd91d6ece0f5f41150c3956c83
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * CDDL HEADER START
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * The contents of this file are subject to the terms of the
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Common Development and Distribution License, Version 1.0 only
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * (the "License"). You may not use this file except in compliance
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * with the License.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * or http://www.opensolaris.org/os/licensing.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * See the License for the specific language governing permissions
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * and limitations under the License.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * When distributing Covered Code, include this CDDL HEADER in each
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * If applicable, add the following below this CDDL HEADER, with the
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * fields enclosed by brackets "[]" replaced with your own identifying
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * information: Portions Copyright [yyyy] [name of copyright owner]
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * CDDL HEADER END
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Use is subject to license terms.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#pragma ident "%Z%%M% %I% %E% SMI"
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * This file implements the import operation for this tool.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * The basic flow of the process is to decrypt the PKCS#12
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * input file if it has a password, parse the elements in
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * the file, find the soft token, log into it, import the
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * PKCS#11 objects into the soft token, and log out.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <stdio.h>
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <stdlib.h>
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <string.h>
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <errno.h>
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <fcntl.h>
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <sys/types.h>
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <sys/stat.h>
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <cryptoutil.h>
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <security/cryptoki.h>
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include "common.h"
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include "biginteger.h"
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include "osslcommon.h"
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include "p12common.h"
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <openssl/pkcs12.h>
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <openssl/err.h>
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Helper function decrypt and parse PKCS#12 import file.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic CK_RV
7711facfe58561dd91d6ece0f5f41150c3956c83dinakextract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/* ARGSUSED */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKCS12 *pk12, *pk12_tmp;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak EVP_PKEY *temp_pkey = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak X509 *temp_cert = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak STACK_OF(X509) *temp_ca = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside extract_pkcs12");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling PKCS12_new");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((pk12 = PKCS12_new()) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to create PKCS#12 context."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling d2i_PKCS12_bio");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* This is ok; it seems to mean there is no more to read. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 &&
7711facfe58561dd91d6ece0f5f41150c3956c83dinak ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak goto end_extract_pkcs12;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to populate PKCS#12 context."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKCS12_free(pk12);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pk12 = pk12_tmp;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling PKCS12_parse");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (PKCS12_parse(pk12, (char *)pin, &temp_pkey, &temp_cert,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak &temp_ca) <= 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak gettext("Unable to parse import file."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKCS12_free(pk12);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinakend_extract_pkcs12:
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *priv_key = temp_pkey;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *cert = temp_cert;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *ca = temp_ca;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKCS12_free(pk12);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Converts OpenSSL BIGNUM into PKCS#11 biginteger_t format.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic CK_RV
7711facfe58561dd91d6ece0f5f41150c3956c83dinakcvt_bn2bigint(BIGNUM *from, biginteger_t *to)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE *temp;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG temp_alloc_sz, temp_cvt_sz;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside cvt_bn2bigint");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (from == NULL || to == NULL)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_ARGUMENTS_BAD);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling BN_num_bytes");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak temp_alloc_sz = BN_num_bytes(from);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((temp = malloc(temp_alloc_sz)) == NULL)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_HOST_MEMORY);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling BN_bn2bin");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak temp_cvt_sz = BN_bn2bin(from, (unsigned char *)temp);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (temp_cvt_sz != temp_alloc_sz)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak to->big_value = temp;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak to->big_value_len = temp_cvt_sz;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Write RSA private key to token.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic CK_RV
7711facfe58561dd91d6ece0f5f41150c3956c83dinakwrite_rsa_private(CK_SESSION_HANDLE sess, RSA *rsa, X509 *cert)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_RV rv = CKR_OK;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int i = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak static CK_OBJECT_CLASS objclass = CKO_PRIVATE_KEY;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak static CK_KEY_TYPE keytype = CKK_RSA;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE *label = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG label_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE *id = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG id_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_DATE startdate = { "", "", "" };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_DATE enddate = { "", "", "" };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak char tmpdate[8];
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t mod = { NULL, 0 }; /* required */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t pubexp = { NULL, 0 }; /* required */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t priexp = { NULL, 0 }; /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t prime1 = { NULL, 0 }; /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t prime2 = { NULL, 0 }; /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t exp1 = { NULL, 0 }; /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t exp2 = { NULL, 0 }; /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t coef = { NULL, 0 }; /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ATTRIBUTE rsa_pri_attrs[16] = {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_CLASS, &objclass, sizeof (objclass) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_KEY_TYPE, &keytype, sizeof (keytype) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_PRIVATE, &pk_true, sizeof (pk_true) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_TOKEN, &pk_true, sizeof (pk_true) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_LABEL, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_ID, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_START_DATE, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_END_DATE, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_MODULUS, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_PUBLIC_EXPONENT, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { 0 /* CKA_PRIVATE_EXPONENT */, NULL, 0 }, /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { 0 /* CKA_PRIME_1 */, NULL, 0 }, /* | */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { 0 /* CKA_PRIME_2 */, NULL, 0 }, /* | */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { 0 /* CKA_EXPONENT_1 */, NULL, 0 }, /* | */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { 0 /* CKA_EXPONENT_2 */, NULL, 0 }, /* | */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { 0 /* CKA_COEFFICIENT */, NULL, 0 } /* V */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_OBJECT_HANDLE obj;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside write_rsa_private");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Attributes start at array index 4. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i = 4;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Recycle the certificate label for the private key label. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_alias_get0");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((label = X509_alias_get0(cert, (int *)&label_len)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak label = (CK_BYTE *)gettext("no label");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak label_len = strlen((char *)label);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr(label, label_len, &(rsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Recycle the certificate id for the private key id. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling PKTOOL_X509_keyid_get0");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((id = PKTOOL_X509_keyid_get0(cert, (int *)&id_len)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak id = (CK_BYTE *)gettext("no id");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak id_len = strlen((char *)id);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr(id, id_len, &(rsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Recycle the certificate start and end dates for private key. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_get_notBefore");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (PKTOOL_cvt_ossltime(X509_get_notBefore(cert), tmpdate)) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) memcpy(&startdate, tmpdate, sizeof (startdate));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr((CK_BYTE *)&startdate, sizeof (startdate),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak &(rsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_get_notAfter");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (PKTOOL_cvt_ossltime(X509_get_notAfter(cert), tmpdate)) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) memcpy(&enddate, tmpdate, sizeof (enddate));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr((CK_BYTE *)&enddate, sizeof (enddate),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak &(rsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Modulus n */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting RSA private key modulus");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(rsa->n, &mod)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert RSA private key modulus."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(mod, &(rsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Public exponent e */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting RSA private key public exponent");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(rsa->e, &pubexp)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert RSA private key public exponent."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(pubexp, &(rsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Private exponent d */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (rsa->d != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting RSA private key private exponent");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(rsa->d, &priexp)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext("Unable to convert "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "RSA private key private exponent."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak rsa_pri_attrs[i].type = CKA_PRIVATE_EXPONENT;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(priexp, &(rsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no RSA private key private exponent");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Prime p */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (rsa->p != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting RSA private key prime 1");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(rsa->p, &prime1)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert RSA private key prime 1."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak rsa_pri_attrs[i].type = CKA_PRIME_1;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(prime1, &(rsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no RSA private key prime 1");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Prime q */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (rsa->q != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting RSA private key prime 2");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(rsa->q, &prime2)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert RSA private key prime 2."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak rsa_pri_attrs[i].type = CKA_PRIME_2;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(prime2, &(rsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no RSA private key prime 2");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Private exponent d modulo p-1 */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (rsa->dmp1 != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting RSA private key exponent 1");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(rsa->dmp1, &exp1)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert RSA private key exponent 1."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak rsa_pri_attrs[i].type = CKA_EXPONENT_1;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(exp1, &(rsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no RSA private key exponent 1");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Private exponent d modulo q-1 */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (rsa->dmq1 != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting RSA private key exponent 2");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(rsa->dmq1, &exp2)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert RSA private key exponent 2."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak rsa_pri_attrs[i].type = CKA_EXPONENT_2;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(exp2, &(rsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no RSA private key exponent 2");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* CRT coefficient q-inverse mod p */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (rsa->iqmp != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting RSA private key coefficient");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(rsa->iqmp, &coef)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert RSA private key coefficient."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak rsa_pri_attrs[i].type = CKA_COEFFICIENT;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(coef, &(rsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no RSA private key coefficient");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Indicates programming error: attributes overran the template */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (i > count) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error: more attributes found than accounted for");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i = count;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling C_CreateObject");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_CreateObject(sess, rsa_pri_attrs, i, &obj)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to create RSA private key object."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Write DSA private key to token.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic CK_RV
7711facfe58561dd91d6ece0f5f41150c3956c83dinakwrite_dsa_private(CK_SESSION_HANDLE sess, DSA *dsa, X509 *cert)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_RV rv = CKR_OK;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int i = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak static CK_OBJECT_CLASS objclass = CKO_PRIVATE_KEY;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak static CK_KEY_TYPE keytype = CKK_DSA;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE *label = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG label_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE *id = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG id_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_DATE startdate = { "", "", "" };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_DATE enddate = { "", "", "" };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak char tmpdate[8];
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t prime = { NULL, 0 }; /* required */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t subprime = { NULL, 0 }; /* required */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t base = { NULL, 0 }; /* required */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t value = { NULL, 0 }; /* required */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ATTRIBUTE dsa_pri_attrs[12] = {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_CLASS, &objclass, sizeof (objclass) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_KEY_TYPE, &keytype, sizeof (keytype) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_PRIVATE, &pk_true, sizeof (pk_true) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_TOKEN, &pk_true, sizeof (pk_true) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_LABEL, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_ID, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_START_DATE, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_END_DATE, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_PRIME, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_SUBPRIME, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_BASE, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_VALUE, NULL, 0 }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_OBJECT_HANDLE obj;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside write_dsa_private");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Attributes start at array index 4. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i = 4;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Recycle the certificate label for the private key label. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_alias_get0");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((label = X509_alias_get0(cert, (int *)&label_len)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak label = (CK_BYTE *)gettext("no label");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak label_len = strlen((char *)label);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr(label, label_len, &(dsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Recycle the certificate id for the private key id. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling PKTOOL_X509_keyid_get0");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((id = PKTOOL_X509_keyid_get0(cert, (int *)&id_len)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak id = (CK_BYTE *)gettext("no id");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak id_len = strlen((char *)id);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr(id, id_len, &(dsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Recycle the certificate start and end dates for private key. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_get_notBefore");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (PKTOOL_cvt_ossltime(X509_get_notBefore(cert), tmpdate)) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) memcpy(&startdate, tmpdate, sizeof (startdate));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr((CK_BYTE *)&startdate, sizeof (startdate),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak &(dsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_get_notAfter");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (PKTOOL_cvt_ossltime(X509_get_notAfter(cert), tmpdate)) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) memcpy(&enddate, tmpdate, sizeof (enddate));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr((CK_BYTE *)&enddate, sizeof (enddate),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak &(dsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Prime p */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting DSA private key prime");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(dsa->p, &prime)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert DSA private key prime."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(prime, &(dsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Subprime q */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting DSA private key subprime");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(dsa->q, &subprime)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert DSA private key subprime."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(subprime, &(dsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Base g */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting DSA private key base");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(dsa->g, &base)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert DSA private key base."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(base, &(dsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Private key x */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting DSA private key value");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(dsa->priv_key, &value)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert DSA private key value."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(value, &(dsa_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Indicates programming error: attributes overran the template */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (i > count) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error: more attributes found than accounted for");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i = count;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling C_CreateObject");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_CreateObject(sess, dsa_pri_attrs, i, &obj)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to create DSA private key object."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Write DH private key to token.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic CK_RV
7711facfe58561dd91d6ece0f5f41150c3956c83dinakwrite_dh_private(CK_SESSION_HANDLE sess, DH *dh, X509 *cert)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_RV rv = CKR_OK;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int i = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak static CK_OBJECT_CLASS objclass = CKO_PRIVATE_KEY;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak static CK_KEY_TYPE keytype = CKK_DH;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE *label = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG label_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE *id = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG id_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_DATE startdate = { "", "", "" };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_DATE enddate = { "", "", "" };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak char tmpdate[8];
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t prime = { NULL, 0 }; /* required */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t base = { NULL, 0 }; /* required */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak biginteger_t value = { NULL, 0 }; /* required */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ATTRIBUTE dh_pri_attrs[11] = {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_CLASS, &objclass, sizeof (objclass) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_KEY_TYPE, &keytype, sizeof (keytype) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_PRIVATE, &pk_true, sizeof (pk_true) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_TOKEN, &pk_true, sizeof (pk_true) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_LABEL, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_ID, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_START_DATE, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_END_DATE, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_PRIME, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_BASE, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_VALUE, NULL, 0 }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG count = sizeof (dh_pri_attrs) / sizeof (CK_ATTRIBUTE);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_OBJECT_HANDLE obj;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside write_dh_private");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Attributes start at array index 4. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i = 4;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Recycle the certificate label for the private key label. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_alias_get0");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((label = X509_alias_get0(cert, (int *)&label_len)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak label = (CK_BYTE *)gettext("no label");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak label_len = strlen((char *)label);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr(label, label_len, &(dh_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Recycle the certificate id for the private key id. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("PKTOOL_X509_keyid_get0");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((id = PKTOOL_X509_keyid_get0(cert, (int *)&id_len)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak id = (CK_BYTE *)gettext("no id");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak id_len = strlen((char *)id);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr(id, id_len, &(dh_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Recycle the certificate start and end dates for private key. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_get_notBefore");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (PKTOOL_cvt_ossltime(X509_get_notBefore(cert), tmpdate)) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) memcpy(&startdate, tmpdate, sizeof (startdate));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr((CK_BYTE *)&startdate, sizeof (startdate),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak &(dh_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_get_notAfter");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (PKTOOL_cvt_ossltime(X509_get_notAfter(cert), tmpdate)) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) memcpy(&enddate, tmpdate, sizeof (enddate));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr((CK_BYTE *)&enddate, sizeof (enddate),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak &(dh_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Prime p */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting DH private key prime");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(dh->p, &prime)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert DH private key prime."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(prime, &(dh_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Base g */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting DH private key base");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(dh->g, &base)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert DH private key base."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(base, &(dh_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Private value x */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting DH private key value");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_bn2bigint(dh->priv_key, &value)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert DH private key value."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_bigint_to_attr(value, &(dh_pri_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Indicates programming error: attributes overran the template */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (i > count) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error: more attributes found than accounted for");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i = count;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling C_CreateObject");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_CreateObject(sess, dh_pri_attrs, i, &obj)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to create DH private key object."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Write certificate to token.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic CK_RV
7711facfe58561dd91d6ece0f5f41150c3956c83dinakwrite_cert(CK_SESSION_HANDLE sess, X509 *cert)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_RV rv = CKR_OK;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int i = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak static CK_OBJECT_CLASS objclass = CKO_CERTIFICATE;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak static CK_CERTIFICATE_TYPE certtype = CKC_X_509;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE *subject = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG subject_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE *value = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG value_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE *label = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG label_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE *id = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG id_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE *issuer = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG issuer_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE *serial = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG serial_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ATTRIBUTE cert_attrs[9] = {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_CLASS, &objclass, sizeof (objclass) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_CERTIFICATE_TYPE, &certtype, sizeof (certtype) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_TOKEN, &pk_true, sizeof (pk_true) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_SUBJECT, NULL, 0 }, /* required */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_VALUE, NULL, 0 }, /* required */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { 0 /* CKA_LABEL */, NULL, 0 }, /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { 0 /* CKA_ID */, NULL, 0 }, /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { 0 /* CKA_ISSUER */, NULL, 0 }, /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { 0 /* CKA_SERIAL_NUMBER */, NULL, 0 } /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG count = sizeof (cert_attrs) / sizeof (CK_ATTRIBUTE);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_OBJECT_HANDLE obj;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside write_cert");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Attributes start at array index 3. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i = 3;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * OpenSSL subject name and issuer (a little further below) are
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * actually stack structures that contain individual ASN.1
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * components. This stack of entries is packed into one DER string.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling PKTOOL_X509_subject_name");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((subject = PKTOOL_X509_subject_name(cert, (int *)&subject_len)) ==
7711facfe58561dd91d6ece0f5f41150c3956c83dinak NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak subject = (CK_BYTE *)gettext("no subject name");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak subject_len = strlen((char *)subject);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr(subject, subject_len, &(cert_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get cert value, but it has to be reconstructed from cert. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling PKTOOL_X509_cert_value");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((value = PKTOOL_X509_cert_value(cert, (int *)&value_len)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak value = (CK_BYTE *)gettext("no value");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak value_len = strlen((char *)value);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr(value, value_len, &(cert_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Get certificate label which is "friendlyName" Netscape,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * "alias" in OpenSSL.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((label = X509_alias_get0(cert, (int *)&label_len)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no certificate label");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cert_attrs[i].type = CKA_LABEL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr(label, label_len, &(cert_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get the keyid for the cert. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((id = PKTOOL_X509_keyid_get0(cert, (int *)&id_len)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no certificate id");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cert_attrs[i].type = CKA_ID;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr(id, id_len, &(cert_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get the issuer name for the cert. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((issuer = PKTOOL_X509_issuer_name(cert, (int *)&issuer_len)) ==
7711facfe58561dd91d6ece0f5f41150c3956c83dinak NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no certificate issuer name");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cert_attrs[i].type = CKA_ISSUER;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr(issuer, issuer_len, &(cert_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get the cert serial number. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((serial = PKTOOL_X509_serial_number(cert, (int *)&serial_len)) ==
7711facfe58561dd91d6ece0f5f41150c3956c83dinak NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no certificate serial number");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cert_attrs[i].type = CKA_SERIAL_NUMBER;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_string_to_attr(serial, serial_len, &(cert_attrs[i++]));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Indicates programming error: attributes overran the template */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (i > count) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error: more attributes found than accounted for");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i = count;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling C_CreateObject");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_CreateObject(sess, cert_attrs, i, &obj)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to create X.509 certificate object."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Helper function to write PKCS#12 items to token. Returns CKR_OK
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * or CKR_GENERAL_ERROR
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic CK_RV
7711facfe58561dd91d6ece0f5f41150c3956c83dinakwrite_token_objs(CK_SESSION_HANDLE sess, EVP_PKEY *priv_key, X509 *cert,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak STACK_OF(X509) *ca, int *successes, int *failures)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int i;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak X509 *c;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_RV rv = CKR_OK;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside write_token_objs");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Do not reset *successes or *failures -- keep running totals. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Import user key. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak switch (priv_key->type) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak case EVP_PKEY_RSA:
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) fprintf(stdout, gettext("Writing RSA private key...\n"));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = write_rsa_private(sess,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak EVP_PKEY_get1_RSA(priv_key), cert)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to write RSA private key (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*successes)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak break;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak case EVP_PKEY_DSA:
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) fprintf(stdout, gettext("Writing DSA private key...\n"));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = write_dsa_private(sess,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak EVP_PKEY_get1_DSA(priv_key), cert)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to write DSA private key (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*successes)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak break;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak case EVP_PKEY_DH:
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) fprintf(stdout, gettext("Writing DH private key...\n"));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = write_dh_private(sess,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak EVP_PKEY_get1_DH(priv_key), cert)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to write DH private key (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*successes)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak break;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak default:
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Note that EVP_PKEY_DH for X9.42 is not implemented
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * in the OpenSSL library.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Private key type 0x%02x import not supported."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak priv_key->type);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak break;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Import user certificate. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) fprintf(stdout, gettext("Writing user certificate...\n"));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = write_cert(sess, cert)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to write user certificate (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*successes)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Import as many stacks of authority certificates as possible. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak for (i = 0; i != sk_X509_num(ca); i++) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * sk_X509_value() is macro that embeds a cast to (X509 *).
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Here it translates into ((X509 *)sk_value((ca), (i))).
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Lint is complaining about the embedded casting, and
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * to fix it, you need to fix openssl header files.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* LINTED E_BAD_PTR_CAST_ALIGN */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak c = sk_X509_value(ca, i);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) fprintf(stdout, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Writing authority certificate...\n"));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = write_cert(sess, c)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to write authority certificate (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*successes)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) fprintf(stdout, gettext("PKCS#12 element scan completed.\n"));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (*failures != 0 ? CKR_GENERAL_ERROR : CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Import objects from PKCS#12 file into token.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakint
7711facfe58561dd91d6ece0f5f41150c3956c83dinakpk_import(int argc, char *argv[])
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak char *token_name = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak char *manuf_id = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak char *serial_no = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak char full_name[FULL_NAME_LEN];
7711facfe58561dd91d6ece0f5f41150c3956c83dinak char *filename = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak struct stat statbuf;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_SLOT_ID slot_id;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_FLAGS pin_state;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_UTF8CHAR_PTR pin = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG pinlen = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_UTF8CHAR_PTR pk12pin = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG pk12pinlen = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_SESSION_HANDLE sess;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak BIO *fbio = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak EVP_PKEY *priv_key = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak X509 *cert = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak STACK_OF(X509) *ca = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_RV rv = CKR_OK;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int i;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int good_count = 0, bad_count = 0; /* running totals */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside pk_import");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get rid of subcommand word "import". */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak argc--;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak argv++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* One additional arg required: filename. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (argc != 1)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_USAGE);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak filename = argv[0];
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Done parsing command line options. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Check that the file exists and is non-empty. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (access(filename, R_OK) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext("File \"%s\" is unreadable "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "(%s)."), filename, strerror(errno));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (stat(filename, &statbuf) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext("Unable to get size of "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "file \"%s\" (%s)."), filename, strerror(errno));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (statbuf.st_size == 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext("File \"%s\" is empty."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak filename);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Import operation only supported on softtoken. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (token_name == NULL)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak token_name = SOFT_TOKEN_LABEL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (manuf_id == NULL)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak manuf_id = SOFT_MANUFACTURER_ID;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (serial_no == NULL)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak serial_no = SOFT_TOKEN_SERIAL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak full_token_name(token_name, manuf_id, serial_no, full_name);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Find the slot with token. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = find_token_slot(token_name, manuf_id, serial_no, &slot_id,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak &pin_state)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to find token %s (%s)."), full_name,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_PK11);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get the user's PIN. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = get_pin(gettext("Enter token passphrase:"), NULL, &pin,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak &pinlen)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to get token passphrase (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(NULL);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_PK11);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Assume user must be logged in R/W to import objects into token. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = quick_start(slot_id, CKF_RW_SESSION, pin, pinlen, &sess)) !=
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak gettext("Unable to log into token (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_PK11);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Setup OpenSSL context. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKTOOL_setup_openssl();
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Open PKCS#12 file. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((open_pkcs12(filename, &fbio)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext("Unable to open import file."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_SYSTEM);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get the PIN for the PKCS#12 import file. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = get_pin(gettext("Enter import file passphrase:"), NULL,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak &pk12pin, &pk12pinlen)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to get import file passphrase (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak close_pkcs12(fbio);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_PK11);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* PKCS#12 import file may have multiple elements, loop until done. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak for (i = 0; /* */; i++) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Extract the contents of the PKCS#12 import file. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = extract_pkcs12(fbio, pk12pin, pk12pinlen, &priv_key,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak &cert, &ca)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to parse PKCS#12 element #%d "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "in import file (%s)."), i+1, pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak close_pkcs12(fbio);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_OPENSSL);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Reached end of import file? */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (rv == CKR_OK && priv_key == NULL && cert == NULL &&
7711facfe58561dd91d6ece0f5f41150c3956c83dinak ca == NULL)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak break;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) fprintf(stdout, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Scanning PKCS#12 element #%d for objects...\n"), i+1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Write the objects to the token. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = write_token_objs(sess, priv_key, cert, ca,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak &good_count, &bad_count)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to write PKCS#12 element #%d to token %s."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i+1, full_name);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak close_pkcs12(fbio);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_PK11);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) fprintf(stdout, gettext("%d PKCS#12 elements scanned: "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "%d objects imported, %d errors occurred.\n"), i,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak good_count, bad_count);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Close PKCS#12 file. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak close_pkcs12(fbio);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Clean up. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (0);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}