export.c revision 9e860378843d64d584ff9a1833e3cadea8dd71e1
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * CDDL HEADER START
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * The contents of this file are subject to the terms of the
9e860378843d64d584ff9a1833e3cadea8dd71e1dinak * Common Development and Distribution License (the "License").
9e860378843d64d584ff9a1833e3cadea8dd71e1dinak * You may not use this file except in compliance 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/*
9e860378843d64d584ff9a1833e3cadea8dd71e1dinak * Copyright 2006 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 export operation for this tool.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * The basic flow of the process is to find the soft token,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * log into it, find the PKCS#11 objects in the soft token
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * to be exported matching keys with their certificates, export
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * them to the PKCS#12 file encrypting them with a file password
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * if desired, and log out.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <stdio.h>
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <stdlib.h>
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <string.h>
7711facfe58561dd91d6ece0f5f41150c3956c83dinak#include <errno.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
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Writes OpenSSL objects to PKCS#12 file. The PKCS#11 objects from
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * the soft token need to be converted to OpenSSL structures prior
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * to this call, since the PKCS#12 routines depend on that format.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * This code is patterned from OpenSSL apps that write PKCS#12 files.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Note: it's not clear from the usage of all the functions here by
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * OpenSSL apps whether these functions have return values or error
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * conditions that can be checked. This function may benefit from
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * a closer review at a later time.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic int
7711facfe58561dd91d6ece0f5f41150c3956c83dinakwrite_objs_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE_PTR id, CK_ULONG id_len, EVP_PKEY *priv_key, X509 *cert,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak STACK_OF(X509) *ca_certs, int *successes, int *failures)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/* ARGSUSED */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKCS12_SAFEBAG *bag = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak X509 *ca = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKCS7 *cert_authsafe = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKCS8_PRIV_KEY_INFO *p8 = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKCS7 *key_authsafe = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak STACK_OF(PKCS7) *authsafe_stack = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKCS12 *p12_elem = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak unsigned char *lab = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int lab_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int i;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int n_writes = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside write_objs_pkcs12");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Do not reset *successes or *failures -- keep running totals. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* If there is nothing to write to the PKCS#12 file, leave. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cert == NULL && ca_certs == NULL && priv_key == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("nothing to write to export file");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (0);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Section 1:
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * The first PKCS#12 container (safebag) will hold the certificates
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * associated with this key. The result of this section is a
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * PIN-encrypted PKCS#7 container (authsafe). If there are no
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * certificates, there is no point in creating the "safebag" or the
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * "authsafe" so we go to the next section.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cert != NULL || ca_certs != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Start a PKCS#12 safebag container for the certificates. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("creating certificate PKCS#12 safebag");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak bag_stack = sk_PKCS12_SAFEBAG_new_null();
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (bag_stack == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to create PKCS#12 certificate bag."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (-1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Add the cert corresponding to private key to bag_stack. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cert) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Convert cert from X509 struct to PKCS#12 bag */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("adding certificate to PKCS#12 safebag");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak bag = PKCS12_x5092certbag(cert);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (bag == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert certificate to "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "PKCS#12 bag."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Cleanup the safebag. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak sk_PKCS12_SAFEBAG_pop_free(bag_stack,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKCS12_SAFEBAG_free);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (-1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Add the key id to the certificate bag. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("add key id to PKCS#12 safebag");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!PKCS12_add_localkeyid(bag, id, id_len))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Add the friendly name to the certificate bag. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((lab = X509_alias_get0(cert, &lab_len)) != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "label PKCS#12 safebag with friendly name");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!PKCS12_add_friendlyname(bag, (char *)lab,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak lab_len))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Pile it on the bag_stack. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak n_writes++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Add all the CA chain certs to the bag_stack. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (ca_certs) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("adding CA certificate chain to PKCS#12 "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "safebag");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Go through the stack of CA certs, converting each
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * one to a PKCS#12 bag and piling them onto the
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * bag_stack.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak for (i = 0; i < sk_X509_num(ca_certs); i++) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * sk_X509_value() is macro that embeds a
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * cast to (X509 *). Here it translates
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * into ((X509 *)sk_value((ca_certs), (i))).
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Lint is complaining about the embedded
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * casting, and to fix it, you need to fix
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * openssl header files.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* LINTED E_BAD_PTR_CAST_ALIGN */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak ca = sk_X509_value(ca_certs, i);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Convert CA cert to PKCS#12 bag. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("adding CA certificate #%d "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "to PKCS#12 safebag", i+1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak bag = PKCS12_x5092certbag(ca);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (bag == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert CA certificate "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "#%d to PKCS#12 bag."), i+1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Cleanup the safebag. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak sk_PKCS12_SAFEBAG_pop_free(bag_stack,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKCS12_SAFEBAG_free);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (-1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Note CA certs do not have friendly name. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Pile it onto the bag_stack. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak n_writes++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Turn bag_stack of certs into encrypted authsafe. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("encrypt certificate PKCS#12 bag into "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "PKCS#7 authsafe");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cert_authsafe = PKCS12_pack_p7encdata(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak NID_pbe_WithSHA1And40BitRC2_CBC, (char *)pin, -1, NULL,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak 0, PKCS12_DEFAULT_ITER, bag_stack);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Clear away this bag_stack, we're done with it. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak bag_stack = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cert_authsafe == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to PKCS#7-encrypt certificate bag."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (-1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Section 2:
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * The second PKCS#12 container (safebag) will hold the private key
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * that goes with the certificates above. The results of this section
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * is an unencrypted PKCS#7 container (authsafe). If there is no
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * private key, there is no point in creating the "safebag" or the
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * "authsafe" so we go to the next section.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (priv_key != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Make a PKCS#8 shrouded key bag. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("create PKCS#8 shrouded key out of private key");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak p8 = EVP_PKEY2PKCS8(priv_key);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (p8 == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to create PKCS#8 shrouded key for "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "private key."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (-1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Put the shrouded key into a PKCS#12 bag. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("convert shrouded key to PKCS#12 bag");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak bag = PKCS12_MAKE_SHKEYBAG(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak NID_pbe_WithSHA1And3_Key_TripleDES_CBC, (char *)pin,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak -1, NULL, 0, PKCS12_DEFAULT_ITER, p8);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Clean up the PKCS#8 shrouded key, don't need it now. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKCS8_PRIV_KEY_INFO_free(p8);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak p8 = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (bag == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert private key to PKCS#12 bag."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (-1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Add the key id to the certificate bag. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("add key id to PKCS#12 safebag");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!PKCS12_add_localkeyid(bag, id, id_len))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Add the cert friendly name to the private key bag. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (lab != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("label PKCS#12 safebag with friendly name");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!PKCS12_add_friendlyname(bag, (char *)lab, lab_len))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Start a PKCS#12 safebag container for the private key. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("creating private key PKCS#12 safebag");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak bag_stack = sk_PKCS12_SAFEBAG_new_null();
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (bag_stack == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to create PKCS#12 private key bag."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (-1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Pile on the private key on the bag_stack. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Turn bag_stack with private key into unencrypted authsafe. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("put private PKCS#12 bag into PKCS#7 authsafe");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak key_authsafe = PKCS12_pack_p7data(bag_stack);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Clear away this bag_stack, we're done with it. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak bag_stack = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (key_authsafe == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to PKCS#7-convert private key bag."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (-1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak n_writes++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Section 3:
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * This is where the two PKCS#7 containers, one for the certificates
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * and one for the private key, are put together into a PKCS#12
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * element. This final PKCS#12 element is written to the export file.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Start a PKCS#7 stack. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("create PKCS#7 authsafe for private key and certificates");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak authsafe_stack = sk_PKCS7_new_null();
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (authsafe_stack == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to create PKCS#7 container for private key "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "and certificates."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (-1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Put certificates and private key into PKCS#7 stack. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (key_authsafe != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("put private key authsafe into PKCS#7 container");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!sk_PKCS7_push(authsafe_stack, key_authsafe))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cert_authsafe != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("put certificate authsafe into PKCS#7 container");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!sk_PKCS7_push(authsafe_stack, cert_authsafe))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Create PKCS#12 element out of PKCS#7 stack. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("create PKCS#12 element for export file");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak p12_elem = PKCS12_init(NID_pkcs7_data);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (p12_elem == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to create PKCS#12 element for export file."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*failures)++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (-1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Put the PKCS#7 stack into the PKCS#12 element. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Clear away the PKCS#7 stack, we're done with it. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak authsafe_stack = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Set the integrity MAC on the PKCS#12 element. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("setting MAC for PKCS#12 element");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!PKCS12_set_mac(p12_elem, (char *)pin, -1, NULL, 0,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKCS12_DEFAULT_ITER, NULL))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Write the PKCS#12 element to the export file. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("writing PKCS#12 element to export file");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!i2d_PKCS12_bio(fbio, p12_elem))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (*successes) += n_writes;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Clear away the PKCS#12 element. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKCS12_free(p12_elem);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (0);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Get token objects: private key, its cert, and its cert chain.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic CK_RV
7711facfe58561dd91d6ece0f5f41150c3956c83dinakget_token_objs(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_OBJECT_HANDLE *mate, CK_OBJECT_HANDLE_PTR *chain,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG *chain_len, CK_BYTE_PTR *id, CK_ULONG *id_len)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_RV rv = CKR_OK;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ATTRIBUTE keyid_attr[1] = {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_ID, NULL, 0 }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak static CK_OBJECT_CLASS class = CKO_CERTIFICATE;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak static CK_CERTIFICATE_TYPE certtype = CKC_X_509;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ATTRIBUTE cert_attr[4] = {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_CLASS, &class, sizeof (CK_OBJECT_CLASS) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_CERTIFICATE_TYPE, &certtype, sizeof (certtype) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_TOKEN, &pk_true, sizeof (pk_true) },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_ID, NULL, 0 }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG num_attr = sizeof (cert_attr) / sizeof (CK_ATTRIBUTE);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_OBJECT_HANDLE cert = ~0UL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG num = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside get_token_objs");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get the size of the object's CKA_ID field first. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("getting CKA_ID size for object 0x%x", obj);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_GetAttributeValue(sess, obj, keyid_attr, 1)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext("Unable to get size of object"
7711facfe58561dd91d6ece0f5f41150c3956c83dinak " key id (%s)."), pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Allocate the space needed for the key id. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((keyid_attr[0].pValue = malloc(keyid_attr[0].ulValueLen)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, "%s.", strerror(errno));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_HOST_MEMORY);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get the CKA_ID field to match obj with its cert. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("getting CKA_ID attribute for object 0x%x", obj);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_GetAttributeValue(sess, obj, keyid_attr, 1)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext("Unable to get object "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "key id (%s)."), pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak free(keyid_attr[0].pValue);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Now try to find any certs that have the same id. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("searching for certificates with same CKA_ID");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cert_attr[3].pValue = keyid_attr[0].pValue;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cert_attr[3].ulValueLen = keyid_attr[0].ulValueLen;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_FindObjectsInit(sess, cert_attr, num_attr)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext("Unable to initialize "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "certificate search (%s)."), pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak free(keyid_attr[0].pValue);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Find the first cert that matches the key id. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_FindObjects(sess, &cert, 1, &num)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext("Certificate search failed "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "(%s)."), pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak free(keyid_attr[0].pValue);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) C_FindObjectsFinal(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *id = keyid_attr[0].pValue;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *id_len = keyid_attr[0].ulValueLen;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *mate = (num == 1) ? cert : ~0UL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* We currently do not find all the certs in the chain. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *chain_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *chain = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Converts PKCS#11 biginteger_t format to OpenSSL BIGNUM.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * "to" should be the address of a ptr init'ed to NULL to
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * receive the BIGNUM, e.g.,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * biginteger_t from;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * BIGNUM *foo = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * cvt_bigint2bn(&from, &foo);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic int
7711facfe58561dd91d6ece0f5f41150c3956c83dinakcvt_bigint2bn(biginteger_t *from, BIGNUM **to)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak BIGNUM *temp = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside cvt_bigint2bn");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (from == NULL || to == NULL)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (-1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling BN_bin2bn");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((temp = BN_bin2bn(from->big_value, from->big_value_len, *to)) ==
7711facfe58561dd91d6ece0f5f41150c3956c83dinak NULL)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (-1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *to = temp;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (0);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Convert PKCS#11 RSA private key to OpenSSL EVP_PKEY structure.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic CK_RV
7711facfe58561dd91d6ece0f5f41150c3956c83dinakcvt_rsa2evp_pkey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, EVP_PKEY **pk)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_RV rv = CKR_OK;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak EVP_PKEY *key = NULL; /* OpenSSL representation */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak RSA *rsa = NULL; /* OpenSSL representation */
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[8] = {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_MODULUS, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_PUBLIC_EXPONENT, NULL, 0 },
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_PRIVATE_EXPONENT, NULL, 0 }, /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_PRIME_1, NULL, 0 }, /* | */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_PRIME_2, NULL, 0 }, /* | */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_EXPONENT_1, NULL, 0 }, /* | */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_EXPONENT_2, NULL, 0 }, /* | */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_COEFFICIENT, NULL, 0 } /* V */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int i;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside cvt_rsa2evp_pkey");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling RSA_new");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rsa = RSA_new()) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to allocate internal RSA structure."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_HOST_MEMORY);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get the sizes of the attributes we need. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling C_GetAttributeValue for size info");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_GetAttributeValue(sess, obj, rsa_pri_attrs, count)) !=
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to get RSA private key attribute sizes (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Allocate memory for each attribute. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak for (i = 0; i < count; i++) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (rsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
7711facfe58561dd91d6ece0f5f41150c3956c83dinak rsa_pri_attrs[i].ulValueLen == 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("cvt_rsa2evp_pkey: *** should not happen");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak rsa_pri_attrs[i].ulValueLen = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak continue;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rsa_pri_attrs[i].pValue =
7711facfe58561dd91d6ece0f5f41150c3956c83dinak malloc(rsa_pri_attrs[i].ulValueLen)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, "%s.", strerror(errno));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_HOST_MEMORY);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Now really get the attributes. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling C_GetAttributeValue for attribute info");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_GetAttributeValue(sess, obj, rsa_pri_attrs, count)) !=
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to get RSA private key attributes (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Fill in all the temp variables. Modulus and public exponent
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * are required. The rest are optional.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(rsa_pri_attrs[i++]), &mod);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(rsa_pri_attrs[i++]), &pubexp);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 &&
7711facfe58561dd91d6ece0f5f41150c3956c83dinak rsa_pri_attrs[i].ulValueLen != 0)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &priexp);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 &&
7711facfe58561dd91d6ece0f5f41150c3956c83dinak rsa_pri_attrs[i].ulValueLen != 0)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &prime1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 &&
7711facfe58561dd91d6ece0f5f41150c3956c83dinak rsa_pri_attrs[i].ulValueLen != 0)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &prime2);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 &&
7711facfe58561dd91d6ece0f5f41150c3956c83dinak rsa_pri_attrs[i].ulValueLen != 0)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &exp1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 &&
7711facfe58561dd91d6ece0f5f41150c3956c83dinak rsa_pri_attrs[i].ulValueLen != 0)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &exp2);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 &&
7711facfe58561dd91d6ece0f5f41150c3956c83dinak rsa_pri_attrs[i].ulValueLen != 0)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &coef);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Start the conversion to internal OpenSSL RSA structure. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Modulus n */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&mod, &(rsa->n)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert RSA private key modulus."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Public exponent e */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&pubexp, &(rsa->e)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert RSA private key public exponent."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Private exponent e */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (priexp.big_value != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&priexp, &(rsa->d)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext("Unable to convert "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "RSA private key private exponent."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no RSA private key private exponent");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Prime p */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (prime1.big_value != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&prime1, &(rsa->p)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert RSA private key prime 1."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no RSA private key prime 1");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Prime q */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (prime2.big_value != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&prime2, &(rsa->q)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert RSA private key prime 2."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no RSA private key prime 2");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Private exponent d modulo p-1 */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (exp1.big_value != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&exp1, &(rsa->dmp1)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert RSA private key exponent 1."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no RSA private key exponent 1");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Private exponent d modulo q-1 */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (exp2.big_value != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&exp2, &(rsa->dmq1)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert RSA private key exponent 2."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no RSA private key exponent 2");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* CRT coefficient q-inverse mod p */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (coef.big_value != NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&coef, &(rsa->iqmp)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert RSA private key coefficient."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak } else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("no RSA private key coefficient");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Create OpenSSL EVP_PKEY struct in which to stuff RSA struct. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling EVP_PKEY_new");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((key = EVP_PKEY_new()) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to allocate internal EVP_PKEY structure."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_HOST_MEMORY);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Put the RSA struct into the EVP_PKEY struct and return it. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling EVP_PKEY_set1_RSA");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) EVP_PKEY_set1_RSA(key, rsa);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *pk = key;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Convert PKCS#11 DSA private key to OpenSSL EVP_PKEY structure.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic CK_RV
7711facfe58561dd91d6ece0f5f41150c3956c83dinakcvt_dsa2evp_pkey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, EVP_PKEY **pk)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_RV rv = CKR_OK;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak EVP_PKEY *key = NULL; /* OpenSSL representation */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak DSA *dsa = NULL; /* OpenSSL representation */
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[4] = {
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 int i;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside cvt_dsa2evp_pkey");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling DSA_new");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((dsa = DSA_new()) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to allocate internal DSA structure."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_HOST_MEMORY);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get the sizes of the attributes we need. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling C_GetAttributeValue for size info");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_GetAttributeValue(sess, obj, dsa_pri_attrs, count)) !=
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to get DSA private key object attributes (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Allocate memory for each attribute. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak for (i = 0; i < count; i++) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (dsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
7711facfe58561dd91d6ece0f5f41150c3956c83dinak dsa_pri_attrs[i].ulValueLen == 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("cvt_dsa2evp_pkey: *** should not happen");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak dsa_pri_attrs[i].ulValueLen = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak continue;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((dsa_pri_attrs[i].pValue =
7711facfe58561dd91d6ece0f5f41150c3956c83dinak malloc(dsa_pri_attrs[i].ulValueLen)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, "%s.", strerror(errno));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_HOST_MEMORY);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Now really get the attributes. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling C_GetAttributeValue for attribute info");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_GetAttributeValue(sess, obj, dsa_pri_attrs, count)) !=
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to get DSA private key attributes (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Fill in all the temp variables. They are all required. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(dsa_pri_attrs[i++]), &prime);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(dsa_pri_attrs[i++]), &subprime);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(dsa_pri_attrs[i++]), &base);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(dsa_pri_attrs[i++]), &value);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Start the conversion to internal OpenSSL DSA structure. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Prime p */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&prime, &(dsa->p)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert DSA private key prime."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Subprime q */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&subprime, &(dsa->q)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert DSA private key subprime."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Base g */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&base, &(dsa->g)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert DSA private key base."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Private key x */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&value, &(dsa->priv_key)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert DSA private key value."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Create OpenSSL EVP PKEY struct in which to stuff DSA struct. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling EVP_PKEY_new");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((key = EVP_PKEY_new()) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to allocate internal EVP_PKEY structure."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_HOST_MEMORY);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Put the DSA struct into the EVP_PKEY struct and return it. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling EVP_PKEY_set1_DSA");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) EVP_PKEY_set1_DSA(key, dsa);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *pk = key;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Convert PKCS#11 DH private key to OpenSSL EVP_PKEY structure.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic CK_RV
7711facfe58561dd91d6ece0f5f41150c3956c83dinakcvt_dh2evp_pkey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, EVP_PKEY **pk)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_RV rv = CKR_OK;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak EVP_PKEY *key = NULL; /* OpenSSL representation */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak DH *dh = NULL; /* OpenSSL representation */
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[3] = {
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 int i;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside cvt_dh2evp_pkey");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling DH_new");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((dh = DH_new()) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to allocate internal DH structure."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_HOST_MEMORY);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get the sizes of the attributes we need. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling C_GetAttributeValue for size info");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_GetAttributeValue(sess, obj, dh_pri_attrs, count)) !=
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to get DH private key object attributes (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Allocate memory for each attribute. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak for (i = 0; i < count; i++) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (dh_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
7711facfe58561dd91d6ece0f5f41150c3956c83dinak dh_pri_attrs[i].ulValueLen == 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("cvt_dh2evp_pkey: ***should not happen");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak dh_pri_attrs[i].ulValueLen = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak continue;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((dh_pri_attrs[i].pValue =
7711facfe58561dd91d6ece0f5f41150c3956c83dinak malloc(dh_pri_attrs[i].ulValueLen)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, "%s.", strerror(errno));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_HOST_MEMORY);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Now really get the attributes. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling C_GetAttributeValue for attribute info");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_GetAttributeValue(sess, obj, dh_pri_attrs, count)) !=
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to get DH private key attributes (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Fill in all the temp variables. They are all required. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(dh_pri_attrs[i++]), &prime);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(dh_pri_attrs[i++]), &base);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_bigint(&(dh_pri_attrs[i++]), &value);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Start the conversion to internal OpenSSL DH structure. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Prime p */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&prime, &(dh->p)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert DH private key prime."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Base g */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&base, &(dh->g)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert DH private key base."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Private value x */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cvt_bigint2bn(&value, &(dh->priv_key)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert DH private key value."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Create OpenSSL EVP PKEY struct in which to stuff DH struct. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling EVP_PKEY_new");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((key = EVP_PKEY_new()) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to allocate internal EVP_PKEY structure."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_HOST_MEMORY);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Put the DH struct into the EVP_PKEY struct and return it. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling EVP_PKEY_set1_DH");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) EVP_PKEY_set1_DH(key, dh);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *pk = key;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Convert PKCS#11 private key object to OpenSSL EVP_PKEY structure.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic CK_RV
7711facfe58561dd91d6ece0f5f41150c3956c83dinakcvt_obj2evp_pkey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, EVP_PKEY **pk)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_RV rv = CKR_OK;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak static CK_KEY_TYPE keytype = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ATTRIBUTE keytype_attr[1] = {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_KEY_TYPE, &keytype, sizeof (keytype) }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside cvt_obj2evp_pkey");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Find out the key type to do the right conversion. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling C_GetAttributeValue");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_GetAttributeValue(sess, obj, keytype_attr, 1)) !=
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to get token object key type (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak switch (keytype) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak case CKK_RSA:
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting RSA key");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (cvt_rsa2evp_pkey(sess, obj, pk));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak case CKK_DSA:
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting DSA key");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (cvt_dsa2evp_pkey(sess, obj, pk));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak case CKK_DH:
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting DH key");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (cvt_dh2evp_pkey(sess, obj, pk));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak default:
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Private key type 0x%02x conversion not supported."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak keytype);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Convert PKCS#11 certificate object to OpenSSL X509 structure.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic CK_RV
7711facfe58561dd91d6ece0f5f41150c3956c83dinakcvt_cert2x509(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, X509 **c)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_RV rv = CKR_OK;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak X509 *cert = NULL; /* OpenSSL representation */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak X509 *temp_cert = NULL;
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[6] = {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_SUBJECT, NULL, 0 }, /* required */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_VALUE, NULL, 0 }, /* required */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_LABEL, NULL, 0 }, /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_ID, NULL, 0 }, /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_ISSUER, NULL, 0 }, /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak { CKA_SERIAL_NUMBER, NULL, 0 } /* optional */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak };
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG count = sizeof (cert_attrs) / sizeof (CK_ATTRIBUTE);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int i = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak X509_NAME *ssl_subject = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak X509_NAME *ssl_issuer = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak ASN1_INTEGER *ssl_serial = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside cvt_cert2x509");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_new");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((cert = X509_new()) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to allocate internal X509 structure."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_HOST_MEMORY);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get the sizes of the attributes we need. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling C_GetAttributeValue for size info");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_GetAttributeValue(sess, obj, cert_attrs, count)) !=
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to get certificate attribute sizes (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Allocate memory for each attribute. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak for (i = 0; i < count; i++) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cert_attrs[i].ulValueLen == (CK_ULONG)-1 ||
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cert_attrs[i].ulValueLen == 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("cvt_cert2x509: *** should not happen");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cert_attrs[i].ulValueLen = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak continue;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((cert_attrs[i].pValue = malloc(cert_attrs[i].ulValueLen))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, "%s.", strerror(errno));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_HOST_MEMORY);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Now really get the attributes. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling C_GetAttributeValue for attribute info");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = C_GetAttributeValue(sess, obj, cert_attrs, count)) !=
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to get certificate attributes (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Fill in all the temp variables. Subject and value are required.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * The rest are optional.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_string(&(cert_attrs[i++]), &subject, &subject_len);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_string(&(cert_attrs[i++]), &value, &value_len);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cert_attrs[i].ulValueLen != (CK_ULONG)-1 &&
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cert_attrs[i].ulValueLen != 0)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_string(&(cert_attrs[i]), &label, &label_len);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cert_attrs[i].ulValueLen != (CK_ULONG)-1 &&
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cert_attrs[i].ulValueLen != 0)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_string(&(cert_attrs[i]), &id, &id_len);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cert_attrs[i].ulValueLen != (CK_ULONG)-1 &&
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cert_attrs[i].ulValueLen != 0)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_string(&(cert_attrs[i]), &issuer, &issuer_len);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (cert_attrs[i].ulValueLen != (CK_ULONG)-1 &&
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cert_attrs[i].ulValueLen != 0)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak copy_attr_to_string(&(cert_attrs[i]), &serial, &serial_len);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak i++;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Start the conversion to internal OpenSSL X509 structure. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Subject name (required) */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling d2i_X509_NAME for subject name");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((ssl_subject = d2i_X509_NAME(NULL, &subject, subject_len)) ==
7711facfe58561dd91d6ece0f5f41150c3956c83dinak NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert certificate subject name."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_set_subject_name");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!X509_set_subject_name(cert, ssl_subject)) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to pack certificate subject name entries."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Label (optional) */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_alias_set1");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!X509_alias_set1(cert, label, label_len))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Id (optional) */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_keyid_set1");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!X509_keyid_set1(cert, id, id_len))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Issuer name (optional) */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling d2i_X509_NAME for issuer name");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((ssl_issuer = d2i_X509_NAME(NULL, &issuer, issuer_len)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert certificate issuer name."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_set_issuer_name");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!X509_set_issuer_name(cert, ssl_issuer)) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to pack certificate issuer name entries."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Serial number (optional) */
9e860378843d64d584ff9a1833e3cadea8dd71e1dinak cryptodebug("calling OPENSSL_malloc() for serial number");
9e860378843d64d584ff9a1833e3cadea8dd71e1dinak if ((ssl_serial = OPENSSL_malloc(sizeof (ASN1_INTEGER))) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert certificate serial number."));
9e860378843d64d584ff9a1833e3cadea8dd71e1dinak return (CKR_HOST_MEMORY);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
9e860378843d64d584ff9a1833e3cadea8dd71e1dinak ssl_serial->length = serial_len;
9e860378843d64d584ff9a1833e3cadea8dd71e1dinak ssl_serial->type = (serial[0] & 0x80) ? V_ASN1_NEG_INTEGER :
9e860378843d64d584ff9a1833e3cadea8dd71e1dinak V_ASN1_INTEGER;
9e860378843d64d584ff9a1833e3cadea8dd71e1dinak ssl_serial->data = serial;
9e860378843d64d584ff9a1833e3cadea8dd71e1dinak ssl_serial->flags = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_set_serialNumber");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!X509_set_serialNumber(cert, ssl_serial))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Value (required)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * The rest of this code takes the CKA_VALUE attribute, converts
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * it into a temp OpenSSL X509 structure and picks out the rest
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * of the fields we need to convert it back into the current X509
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * structure that will get exported. The reason we don't just
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * start with CKA_VALUE is because while the object was in the
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * softtoken, it is possible that some of its attributes changed.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Those changes would not appear in CKA_VALUE and would be lost
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * if we started with CKA_VALUE that was saved originally.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling d2i_X509 for cert value");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((temp_cert = d2i_X509(NULL, &value, value_len)) == NULL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to convert main certificate values."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_GENERAL_ERROR);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Transfer these values from temp_cert to cert. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_set_version/X509_get_version");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!X509_set_version(cert, X509_get_version(temp_cert)))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_set_notBefore/X509_get_notBefore");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!X509_set_notBefore(cert, X509_get_notBefore(temp_cert)))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_set_notAfter/X509_get_notAfter");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!X509_set_notAfter(cert, X509_get_notAfter(temp_cert)))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("calling X509_set_pubkey/X509_get_pubkey");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!X509_set_pubkey(cert, X509_get_pubkey(temp_cert)))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * These don't get transfered from temp_cert to cert.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * It -appears- that they may get regenerated as needed.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * cert->cert_info->signature = dup(temp_cert->cert_info->signature);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * cert->sig_alg = dup(temp_cert->sig_alg);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * cert->signature = dup(temp_cert->signature);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * cert->skid = dup(temp_cert->skid);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * cert->akid = dup(temp_cert->akid);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *c = cert;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinakstatic CK_RV
7711facfe58561dd91d6ece0f5f41150c3956c83dinakconvert_token_objs(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_OBJECT_HANDLE mate, CK_OBJECT_HANDLE *chain, CK_ULONG chain_len,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_RV rv = CKR_OK;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak EVP_PKEY *pk = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak X509 *c = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak X509 *one_ca = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak STACK_OF(X509) *ch = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int i;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside convert_token_objs");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_obj2evp_pkey(sess, obj, &pk)) != CKR_OK)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (mate != ~0UL) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting cert corresponding to private key");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_cert2x509(sess, mate, &c)) != CKR_OK)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (chain_len != 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("converting ca chain of %d certs corresponding "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "to private key", chain_len);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak ch = sk_X509_new_null();
7711facfe58561dd91d6ece0f5f41150c3956c83dinak for (i = 0; i < chain_len; i++) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = cvt_cert2x509(sess, chain[i], &one_ca)) !=
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (rv);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (!sk_X509_push(ch, one_ca))
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("error not caught");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *priv_key = pk;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *cert = (mate != ~0UL) ? c : NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak *ca = (chain_len != 0) ? ch : NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (CKR_OK);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak/*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Export objects from token to PKCS#12 file.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinakint
7711facfe58561dd91d6ece0f5f41150c3956c83dinakpk_export(int argc, char *argv[])
7711facfe58561dd91d6ece0f5f41150c3956c83dinak{
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak int opt;
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak extern int optind_av;
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak extern char *optarg_av;
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak char *token_spec = NULL;
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 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 CK_OBJECT_HANDLE *objs = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG num_objs = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_OBJECT_HANDLE mate = ~0UL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_OBJECT_HANDLE *chain = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG chain_len;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_BYTE *id = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CK_ULONG id_len = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int i = 0;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak int good_ones = 0, bad_ones = 0; /* running totals */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptodebug("inside pk_export");
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak /* Parse command line options. Do NOT i18n/l10n. */
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak while ((opt = getopt_av(argc, argv, "T:(token)o:(outfile)")) != EOF) {
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak switch (opt) {
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak case 'T': /* token specifier */
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak if (token_spec)
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak return (PK_ERR_USAGE);
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak token_spec = optarg_av;
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak break;
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak case 'o': /* output file name */
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak if (filename)
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak return (PK_ERR_USAGE);
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak filename = optarg_av;
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak break;
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak default:
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak return (PK_ERR_USAGE);
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak break;
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak }
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak /* If nothing is specified, default is to use softtoken. */
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak if (token_spec == NULL) {
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak token_name = SOFT_TOKEN_LABEL;
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak manuf_id = SOFT_MANUFACTURER_ID;
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak serial_no = SOFT_TOKEN_SERIAL;
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak } else {
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak /*
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak * Parse token specifier into token_name, manuf_id, serial_no.
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak * Token_name is required; manuf_id and serial_no are optional.
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak */
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak if (parse_token_spec(token_spec, &token_name, &manuf_id,
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak &serial_no) < 0)
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak return (PK_ERR_USAGE);
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak }
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak /* Filename arg is required. */
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak if (filename == NULL)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_USAGE);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak /* No additional args allowed. */
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak argc -= optind_av;
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak argv += optind_av;
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak if (argc)
49e212991a3065f7e499a4b29ae8d8eaf33f3135dinak return (PK_ERR_USAGE);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Done parsing command line options. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Check if the file exists and might be overwritten. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (access(filename, F_OK) == 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext("Warning: file \"%s\" exists, "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "will be overwritten."), filename);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (yesno(gettext("Continue with export? "),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (0);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
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 export objects from 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 /* Collect all private keys first. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = find_objs(sess, PK_PRIVATE_OBJ|PK_KEY_OBJ, NULL,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak &objs, &num_objs)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to retrieve private key token objects (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_PK11);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Nothing to do? */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (num_objs == 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext("No objects found."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (0);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Setup OpenSSL context. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak PKTOOL_setup_openssl();
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Create PKCS#12 file. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((create_pkcs12(filename, &fbio)) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext("No export file created."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_SYSTEM);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get the PIN for the PKCS#12 export file. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = get_pin(gettext("Create export file passphrase:"), gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Re-enter export file passphrase:"), &pk12pin, &pk12pinlen)) !=
7711facfe58561dd91d6ece0f5f41150c3956c83dinak CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak gettext("Unable to get export file passphrase (%s)."),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak pkcs11_strerror(rv));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak close_pkcs12(fbio);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_PK11);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak for (i = 0; i < num_objs; i++) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Get a private key and its certificate and CA chain. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = get_token_objs(sess, objs[i], &mate, &chain,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak &chain_len, &id, &id_len)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Note this "rv" is either CKR_OK or !CKR_OK. The
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * real error codes/messages are handled inside
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * read_token_objs().
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak gettext("Unable to get token objects."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak free(id);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak close_pkcs12(fbio);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_PK11);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Convert to OpenSSL equivalents. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if ((rv = convert_token_objs(sess, objs[i], mate, chain,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak chain_len, &priv_key, &cert, &ca)) != CKR_OK) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * Note this "rv" is either CKR_OK or !CKR_OK. The
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * real error codes/messages are handled inside
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * read_token_objs().
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak gettext("Unable to convert token objects."));
7711facfe58561dd91d6ece0f5f41150c3956c83dinak free(id);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak close_pkcs12(fbio);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_PK11);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /*
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * When exporting of cert chains is implemented, these
7711facfe58561dd91d6ece0f5f41150c3956c83dinak * messages should be updated accordingly.
7711facfe58561dd91d6ece0f5f41150c3956c83dinak */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (mate == ~0UL)
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) fprintf(stdout, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Writing object #%d...\n"), i+1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak else
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) fprintf(stdout, gettext("Writing object #%d "
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "and its certificate...\n"), i+1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Write object and its certs to the PKCS#12 export file. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak if (write_objs_pkcs12(fbio, pk12pin, pk12pinlen, id, id_len,
7711facfe58561dd91d6ece0f5f41150c3956c83dinak priv_key, cert, ca, &good_ones, &bad_ones) < 0) {
7711facfe58561dd91d6ece0f5f41150c3956c83dinak cryptoerror(LOG_STDERR, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "Unable to write object #%d to export file."), i+1);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak sk_X509_pop_free(ca, X509_free);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak free(id);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak close_pkcs12(fbio);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (PK_ERR_OPENSSL);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Destroy key id and CA cert chain, done with them. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak free(id);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak id = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak sk_X509_pop_free(ca, X509_free);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak ca = NULL;
7711facfe58561dd91d6ece0f5f41150c3956c83dinak }
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak (void) fprintf(stdout, gettext(
7711facfe58561dd91d6ece0f5f41150c3956c83dinak "%d token objects exported, %d errors occurred.\n"),
7711facfe58561dd91d6ece0f5f41150c3956c83dinak good_ones, bad_ones);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Close PKCS#12 file. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak close_pkcs12(fbio);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak
7711facfe58561dd91d6ece0f5f41150c3956c83dinak /* Clean up. */
7711facfe58561dd91d6ece0f5f41150c3956c83dinak quick_finish(sess);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak return (0);
7711facfe58561dd91d6ece0f5f41150c3956c83dinak}