117Sdinak /* 217Sdinak * CDDL HEADER START 317Sdinak * 417Sdinak * The contents of this file are subject to the terms of the 517Sdinak * Common Development and Distribution License, Version 1.0 only 617Sdinak * (the "License"). You may not use this file except in compliance 717Sdinak * with the License. 817Sdinak * 917Sdinak * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 1017Sdinak * or http://www.opensolaris.org/os/licensing. 1117Sdinak * See the License for the specific language governing permissions 1217Sdinak * and limitations under the License. 1317Sdinak * 1417Sdinak * When distributing Covered Code, include this CDDL HEADER in each 1517Sdinak * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1617Sdinak * If applicable, add the following below this CDDL HEADER, with the 1717Sdinak * fields enclosed by brackets "[]" replaced with your own identifying 1817Sdinak * information: Portions Copyright [yyyy] [name of copyright owner] 1917Sdinak * 2017Sdinak * CDDL HEADER END 2117Sdinak */ 2217Sdinak /* 2317Sdinak * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 2417Sdinak * Use is subject to license terms. 2517Sdinak */ 2617Sdinak 2717Sdinak #pragma ident "%Z%%M% %I% %E% SMI" 2817Sdinak 2917Sdinak /* 3017Sdinak * This file implements the export operation for this tool. 3117Sdinak * The basic flow of the process is to find the soft token, 3217Sdinak * log into it, find the PKCS#11 objects in the soft token 3317Sdinak * to be exported matching keys with their certificates, export 3417Sdinak * them to the PKCS#12 file encrypting them with a file password 3517Sdinak * if desired, and log out. 3617Sdinak */ 3717Sdinak 3817Sdinak #include <stdio.h> 3917Sdinak #include <stdlib.h> 4017Sdinak #include <string.h> 4117Sdinak #include <errno.h> 4217Sdinak #include <cryptoutil.h> 4317Sdinak #include <security/cryptoki.h> 4417Sdinak #include "common.h" 4517Sdinak #include "biginteger.h" 4617Sdinak #include "osslcommon.h" 4717Sdinak #include "p12common.h" 4817Sdinak #include <openssl/pkcs12.h> 4917Sdinak 5017Sdinak /* 5117Sdinak * Writes OpenSSL objects to PKCS#12 file. The PKCS#11 objects from 5217Sdinak * the soft token need to be converted to OpenSSL structures prior 5317Sdinak * to this call, since the PKCS#12 routines depend on that format. 5417Sdinak * This code is patterned from OpenSSL apps that write PKCS#12 files. 5517Sdinak * 5617Sdinak * Note: it's not clear from the usage of all the functions here by 5717Sdinak * OpenSSL apps whether these functions have return values or error 5817Sdinak * conditions that can be checked. This function may benefit from 5917Sdinak * a closer review at a later time. 6017Sdinak */ 6117Sdinak static int 6217Sdinak write_objs_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen, 6317Sdinak CK_BYTE_PTR id, CK_ULONG id_len, EVP_PKEY *priv_key, X509 *cert, 6417Sdinak STACK_OF(X509) *ca_certs, int *successes, int *failures) 6517Sdinak /* ARGSUSED */ 6617Sdinak { 6717Sdinak STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL; 6817Sdinak PKCS12_SAFEBAG *bag = NULL; 6917Sdinak X509 *ca = NULL; 7017Sdinak PKCS7 *cert_authsafe = NULL; 7117Sdinak PKCS8_PRIV_KEY_INFO *p8 = NULL; 7217Sdinak PKCS7 *key_authsafe = NULL; 7317Sdinak STACK_OF(PKCS7) *authsafe_stack = NULL; 7417Sdinak PKCS12 *p12_elem = NULL; 7517Sdinak unsigned char *lab = NULL; 7617Sdinak int lab_len = 0; 7717Sdinak int i; 7817Sdinak int n_writes = 0; 7917Sdinak 8017Sdinak cryptodebug("inside write_objs_pkcs12"); 8117Sdinak 8217Sdinak /* Do not reset *successes or *failures -- keep running totals. */ 8317Sdinak 8417Sdinak /* If there is nothing to write to the PKCS#12 file, leave. */ 8517Sdinak if (cert == NULL && ca_certs == NULL && priv_key == NULL) { 8617Sdinak cryptodebug("nothing to write to export file"); 8717Sdinak return (0); 8817Sdinak } 8917Sdinak 9017Sdinak /* 9117Sdinak * Section 1: 9217Sdinak * 9317Sdinak * The first PKCS#12 container (safebag) will hold the certificates 9417Sdinak * associated with this key. The result of this section is a 9517Sdinak * PIN-encrypted PKCS#7 container (authsafe). If there are no 9617Sdinak * certificates, there is no point in creating the "safebag" or the 9717Sdinak * "authsafe" so we go to the next section. 9817Sdinak */ 9917Sdinak if (cert != NULL || ca_certs != NULL) { 10017Sdinak /* Start a PKCS#12 safebag container for the certificates. */ 10117Sdinak cryptodebug("creating certificate PKCS#12 safebag"); 10217Sdinak bag_stack = sk_PKCS12_SAFEBAG_new_null(); 10317Sdinak if (bag_stack == NULL) { 10417Sdinak cryptoerror(LOG_STDERR, gettext( 10517Sdinak "Unable to create PKCS#12 certificate bag.")); 10617Sdinak (*failures)++; 10717Sdinak return (-1); 10817Sdinak } 10917Sdinak 11017Sdinak /* Add the cert corresponding to private key to bag_stack. */ 11117Sdinak if (cert) { 11217Sdinak /* Convert cert from X509 struct to PKCS#12 bag */ 11317Sdinak cryptodebug("adding certificate to PKCS#12 safebag"); 11417Sdinak bag = PKCS12_x5092certbag(cert); 11517Sdinak if (bag == NULL) { 11617Sdinak cryptoerror(LOG_STDERR, gettext( 11717Sdinak "Unable to convert certificate to " 11817Sdinak "PKCS#12 bag.")); 11917Sdinak /* Cleanup the safebag. */ 12017Sdinak sk_PKCS12_SAFEBAG_pop_free(bag_stack, 12117Sdinak PKCS12_SAFEBAG_free); 12217Sdinak (*failures)++; 12317Sdinak return (-1); 12417Sdinak } 12517Sdinak 12617Sdinak /* Add the key id to the certificate bag. */ 12717Sdinak cryptodebug("add key id to PKCS#12 safebag"); 12817Sdinak if (!PKCS12_add_localkeyid(bag, id, id_len)) 12917Sdinak cryptodebug("error not caught"); 13017Sdinak 13117Sdinak /* Add the friendly name to the certificate bag. */ 13217Sdinak if ((lab = X509_alias_get0(cert, &lab_len)) != NULL) { 13317Sdinak cryptodebug( 13417Sdinak "label PKCS#12 safebag with friendly name"); 13517Sdinak if (!PKCS12_add_friendlyname(bag, (char *)lab, 13617Sdinak lab_len)) 13717Sdinak cryptodebug("error not caught"); 13817Sdinak } 13917Sdinak 14017Sdinak /* Pile it on the bag_stack. */ 14117Sdinak if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) 14217Sdinak cryptodebug("error not caught"); 14317Sdinak 14417Sdinak n_writes++; 14517Sdinak } 14617Sdinak 14717Sdinak /* Add all the CA chain certs to the bag_stack. */ 14817Sdinak if (ca_certs) { 14917Sdinak cryptodebug("adding CA certificate chain to PKCS#12 " 15017Sdinak "safebag"); 15117Sdinak /* 15217Sdinak * Go through the stack of CA certs, converting each 15317Sdinak * one to a PKCS#12 bag and piling them onto the 15417Sdinak * bag_stack. 15517Sdinak */ 15617Sdinak for (i = 0; i < sk_X509_num(ca_certs); i++) { 15717Sdinak /* 15817Sdinak * sk_X509_value() is macro that embeds a 15917Sdinak * cast to (X509 *). Here it translates 16017Sdinak * into ((X509 *)sk_value((ca_certs), (i))). 16117Sdinak * Lint is complaining about the embedded 16217Sdinak * casting, and to fix it, you need to fix 16317Sdinak * openssl header files. 16417Sdinak */ 16517Sdinak /* LINTED E_BAD_PTR_CAST_ALIGN */ 16617Sdinak ca = sk_X509_value(ca_certs, i); 16717Sdinak 16817Sdinak /* Convert CA cert to PKCS#12 bag. */ 16917Sdinak cryptodebug("adding CA certificate #%d " 17017Sdinak "to PKCS#12 safebag", i+1); 17117Sdinak bag = PKCS12_x5092certbag(ca); 17217Sdinak if (bag == NULL) { 17317Sdinak cryptoerror(LOG_STDERR, gettext( 17417Sdinak "Unable to convert CA certificate " 17517Sdinak "#%d to PKCS#12 bag."), i+1); 17617Sdinak /* Cleanup the safebag. */ 17717Sdinak sk_PKCS12_SAFEBAG_pop_free(bag_stack, 17817Sdinak PKCS12_SAFEBAG_free); 17917Sdinak (*failures)++; 18017Sdinak return (-1); 18117Sdinak } 18217Sdinak 18317Sdinak /* Note CA certs do not have friendly name. */ 18417Sdinak 18517Sdinak /* Pile it onto the bag_stack. */ 18617Sdinak if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) 18717Sdinak cryptodebug("error not caught"); 18817Sdinak 18917Sdinak n_writes++; 19017Sdinak } 19117Sdinak } 19217Sdinak 19317Sdinak /* Turn bag_stack of certs into encrypted authsafe. */ 19417Sdinak cryptodebug("encrypt certificate PKCS#12 bag into " 19517Sdinak "PKCS#7 authsafe"); 19617Sdinak cert_authsafe = PKCS12_pack_p7encdata( 19717Sdinak NID_pbe_WithSHA1And40BitRC2_CBC, (char *)pin, -1, NULL, 19817Sdinak 0, PKCS12_DEFAULT_ITER, bag_stack); 19917Sdinak 20017Sdinak /* Clear away this bag_stack, we're done with it. */ 20117Sdinak sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 20217Sdinak bag_stack = NULL; 20317Sdinak 20417Sdinak if (cert_authsafe == NULL) { 20517Sdinak cryptoerror(LOG_STDERR, gettext( 20617Sdinak "Unable to PKCS#7-encrypt certificate bag.")); 20717Sdinak (*failures)++; 20817Sdinak return (-1); 20917Sdinak } 21017Sdinak } 21117Sdinak 21217Sdinak /* 21317Sdinak * Section 2: 21417Sdinak * 21517Sdinak * The second PKCS#12 container (safebag) will hold the private key 21617Sdinak * that goes with the certificates above. The results of this section 21717Sdinak * is an unencrypted PKCS#7 container (authsafe). If there is no 21817Sdinak * private key, there is no point in creating the "safebag" or the 21917Sdinak * "authsafe" so we go to the next section. 22017Sdinak */ 22117Sdinak if (priv_key != NULL) { 22217Sdinak /* Make a PKCS#8 shrouded key bag. */ 22317Sdinak cryptodebug("create PKCS#8 shrouded key out of private key"); 22417Sdinak p8 = EVP_PKEY2PKCS8(priv_key); 22517Sdinak if (p8 == NULL) { 22617Sdinak cryptoerror(LOG_STDERR, gettext( 22717Sdinak "Unable to create PKCS#8 shrouded key for " 22817Sdinak "private key.")); 22917Sdinak (*failures)++; 23017Sdinak return (-1); 23117Sdinak } 23217Sdinak 23317Sdinak /* Put the shrouded key into a PKCS#12 bag. */ 23417Sdinak cryptodebug("convert shrouded key to PKCS#12 bag"); 23517Sdinak bag = PKCS12_MAKE_SHKEYBAG( 23617Sdinak NID_pbe_WithSHA1And3_Key_TripleDES_CBC, (char *)pin, 23717Sdinak -1, NULL, 0, PKCS12_DEFAULT_ITER, p8); 23817Sdinak 23917Sdinak /* Clean up the PKCS#8 shrouded key, don't need it now. */ 24017Sdinak PKCS8_PRIV_KEY_INFO_free(p8); 24117Sdinak p8 = NULL; 24217Sdinak 24317Sdinak if (bag == NULL) { 24417Sdinak cryptoerror(LOG_STDERR, gettext( 24517Sdinak "Unable to convert private key to PKCS#12 bag.")); 24617Sdinak (*failures)++; 24717Sdinak return (-1); 24817Sdinak } 24917Sdinak 25017Sdinak /* Add the key id to the certificate bag. */ 25117Sdinak cryptodebug("add key id to PKCS#12 safebag"); 25217Sdinak if (!PKCS12_add_localkeyid(bag, id, id_len)) 25317Sdinak cryptodebug("error not caught"); 25417Sdinak 25517Sdinak /* Add the cert friendly name to the private key bag. */ 25617Sdinak if (lab != NULL) { 25717Sdinak cryptodebug("label PKCS#12 safebag with friendly name"); 25817Sdinak if (!PKCS12_add_friendlyname(bag, (char *)lab, lab_len)) 25917Sdinak cryptodebug("error not caught"); 26017Sdinak } 26117Sdinak 26217Sdinak /* Start a PKCS#12 safebag container for the private key. */ 26317Sdinak cryptodebug("creating private key PKCS#12 safebag"); 26417Sdinak bag_stack = sk_PKCS12_SAFEBAG_new_null(); 26517Sdinak if (bag_stack == NULL) { 26617Sdinak cryptoerror(LOG_STDERR, gettext( 26717Sdinak "Unable to create PKCS#12 private key bag.")); 26817Sdinak (*failures)++; 26917Sdinak return (-1); 27017Sdinak } 27117Sdinak 27217Sdinak /* Pile on the private key on the bag_stack. */ 27317Sdinak if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) 27417Sdinak cryptodebug("error not caught"); 27517Sdinak 27617Sdinak /* Turn bag_stack with private key into unencrypted authsafe. */ 27717Sdinak cryptodebug("put private PKCS#12 bag into PKCS#7 authsafe"); 27817Sdinak key_authsafe = PKCS12_pack_p7data(bag_stack); 27917Sdinak 28017Sdinak /* Clear away this bag_stack, we're done with it. */ 28117Sdinak sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 28217Sdinak bag_stack = NULL; 28317Sdinak 28417Sdinak if (key_authsafe == NULL) { 28517Sdinak cryptoerror(LOG_STDERR, gettext( 28617Sdinak "Unable to PKCS#7-convert private key bag.")); 28717Sdinak (*failures)++; 28817Sdinak return (-1); 28917Sdinak } 29017Sdinak 29117Sdinak n_writes++; 29217Sdinak } 29317Sdinak 29417Sdinak /* 29517Sdinak * Section 3: 29617Sdinak * 29717Sdinak * This is where the two PKCS#7 containers, one for the certificates 29817Sdinak * and one for the private key, are put together into a PKCS#12 29917Sdinak * element. This final PKCS#12 element is written to the export file. 30017Sdinak */ 30117Sdinak /* Start a PKCS#7 stack. */ 30217Sdinak cryptodebug("create PKCS#7 authsafe for private key and certificates"); 30317Sdinak authsafe_stack = sk_PKCS7_new_null(); 30417Sdinak if (authsafe_stack == NULL) { 30517Sdinak cryptoerror(LOG_STDERR, gettext( 30617Sdinak "Unable to create PKCS#7 container for private key " 30717Sdinak "and certificates.")); 30817Sdinak (*failures)++; 30917Sdinak return (-1); 31017Sdinak } 31117Sdinak 31217Sdinak /* Put certificates and private key into PKCS#7 stack. */ 31317Sdinak if (key_authsafe != NULL) { 31417Sdinak cryptodebug("put private key authsafe into PKCS#7 container"); 31517Sdinak if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) 31617Sdinak cryptodebug("error not caught"); 31717Sdinak } 31817Sdinak if (cert_authsafe != NULL) { 31917Sdinak cryptodebug("put certificate authsafe into PKCS#7 container"); 32017Sdinak if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) 32117Sdinak cryptodebug("error not caught"); 32217Sdinak } 32317Sdinak 32417Sdinak /* Create PKCS#12 element out of PKCS#7 stack. */ 32517Sdinak cryptodebug("create PKCS#12 element for export file"); 32617Sdinak p12_elem = PKCS12_init(NID_pkcs7_data); 32717Sdinak if (p12_elem == NULL) { 32817Sdinak cryptoerror(LOG_STDERR, gettext( 32917Sdinak "Unable to create PKCS#12 element for export file.")); 33017Sdinak sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 33117Sdinak (*failures)++; 33217Sdinak return (-1); 33317Sdinak } 33417Sdinak 33517Sdinak /* Put the PKCS#7 stack into the PKCS#12 element. */ 33617Sdinak if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) 33717Sdinak cryptodebug("error not caught"); 33817Sdinak 33917Sdinak /* Clear away the PKCS#7 stack, we're done with it. */ 34017Sdinak sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 34117Sdinak authsafe_stack = NULL; 34217Sdinak 34317Sdinak /* Set the integrity MAC on the PKCS#12 element. */ 34417Sdinak cryptodebug("setting MAC for PKCS#12 element"); 34517Sdinak if (!PKCS12_set_mac(p12_elem, (char *)pin, -1, NULL, 0, 34617Sdinak PKCS12_DEFAULT_ITER, NULL)) 34717Sdinak cryptodebug("error not caught"); 34817Sdinak 34917Sdinak /* Write the PKCS#12 element to the export file. */ 35017Sdinak cryptodebug("writing PKCS#12 element to export file"); 35117Sdinak if (!i2d_PKCS12_bio(fbio, p12_elem)) 35217Sdinak cryptodebug("error not caught"); 35317Sdinak 35417Sdinak (*successes) += n_writes; 35517Sdinak 35617Sdinak /* Clear away the PKCS#12 element. */ 35717Sdinak PKCS12_free(p12_elem); 35817Sdinak return (0); 35917Sdinak } 36017Sdinak 36117Sdinak /* 36217Sdinak * Get token objects: private key, its cert, and its cert chain. 36317Sdinak */ 36417Sdinak static CK_RV 36517Sdinak get_token_objs(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, 36617Sdinak CK_OBJECT_HANDLE *mate, CK_OBJECT_HANDLE_PTR *chain, 36717Sdinak CK_ULONG *chain_len, CK_BYTE_PTR *id, CK_ULONG *id_len) 36817Sdinak { 36917Sdinak CK_RV rv = CKR_OK; 37017Sdinak CK_ATTRIBUTE keyid_attr[1] = { 37117Sdinak { CKA_ID, NULL, 0 } 37217Sdinak }; 37317Sdinak static CK_OBJECT_CLASS class = CKO_CERTIFICATE; 37417Sdinak static CK_CERTIFICATE_TYPE certtype = CKC_X_509; 37517Sdinak CK_ATTRIBUTE cert_attr[4] = { 37617Sdinak { CKA_CLASS, &class, sizeof (CK_OBJECT_CLASS) }, 37717Sdinak { CKA_CERTIFICATE_TYPE, &certtype, sizeof (certtype) }, 37817Sdinak { CKA_TOKEN, &pk_true, sizeof (pk_true) }, 37917Sdinak { CKA_ID, NULL, 0 } 38017Sdinak }; 38117Sdinak CK_ULONG num_attr = sizeof (cert_attr) / sizeof (CK_ATTRIBUTE); 38217Sdinak CK_OBJECT_HANDLE cert = ~0UL; 38317Sdinak CK_ULONG num = 0; 38417Sdinak 38517Sdinak cryptodebug("inside get_token_objs"); 38617Sdinak 38717Sdinak /* Get the size of the object's CKA_ID field first. */ 38817Sdinak cryptodebug("getting CKA_ID size for object 0x%x", obj); 38917Sdinak if ((rv = C_GetAttributeValue(sess, obj, keyid_attr, 1)) != CKR_OK) { 39017Sdinak cryptoerror(LOG_STDERR, gettext("Unable to get size of object" 39117Sdinak " key id (%s)."), pkcs11_strerror(rv)); 39217Sdinak return (rv); 39317Sdinak } 39417Sdinak 39517Sdinak /* Allocate the space needed for the key id. */ 39617Sdinak if ((keyid_attr[0].pValue = malloc(keyid_attr[0].ulValueLen)) == NULL) { 39717Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 39817Sdinak return (CKR_HOST_MEMORY); 39917Sdinak } 40017Sdinak 40117Sdinak /* Get the CKA_ID field to match obj with its cert. */ 40217Sdinak cryptodebug("getting CKA_ID attribute for object 0x%x", obj); 40317Sdinak if ((rv = C_GetAttributeValue(sess, obj, keyid_attr, 1)) != CKR_OK) { 40417Sdinak cryptoerror(LOG_STDERR, gettext("Unable to get object " 40517Sdinak "key id (%s)."), pkcs11_strerror(rv)); 40617Sdinak free(keyid_attr[0].pValue); 40717Sdinak return (rv); 40817Sdinak } 40917Sdinak 41017Sdinak /* Now try to find any certs that have the same id. */ 41117Sdinak cryptodebug("searching for certificates with same CKA_ID"); 41217Sdinak cert_attr[3].pValue = keyid_attr[0].pValue; 41317Sdinak cert_attr[3].ulValueLen = keyid_attr[0].ulValueLen; 41417Sdinak if ((rv = C_FindObjectsInit(sess, cert_attr, num_attr)) != CKR_OK) { 41517Sdinak cryptoerror(LOG_STDERR, gettext("Unable to initialize " 41617Sdinak "certificate search (%s)."), pkcs11_strerror(rv)); 41717Sdinak free(keyid_attr[0].pValue); 41817Sdinak return (rv); 41917Sdinak } 42017Sdinak 42117Sdinak /* Find the first cert that matches the key id. */ 42217Sdinak if ((rv = C_FindObjects(sess, &cert, 1, &num)) != CKR_OK) { 42317Sdinak cryptoerror(LOG_STDERR, gettext("Certificate search failed " 42417Sdinak "(%s)."), pkcs11_strerror(rv)); 42517Sdinak free(keyid_attr[0].pValue); 42617Sdinak return (rv); 42717Sdinak } 42817Sdinak 42917Sdinak (void) C_FindObjectsFinal(sess); 43017Sdinak 43117Sdinak *id = keyid_attr[0].pValue; 43217Sdinak *id_len = keyid_attr[0].ulValueLen; 43317Sdinak 43417Sdinak *mate = (num == 1) ? cert : ~0UL; 43517Sdinak 43617Sdinak /* We currently do not find all the certs in the chain. */ 43717Sdinak *chain_len = 0; 43817Sdinak *chain = NULL; 43917Sdinak 44017Sdinak return (CKR_OK); 44117Sdinak } 44217Sdinak 44317Sdinak /* 44417Sdinak * Converts PKCS#11 biginteger_t format to OpenSSL BIGNUM. 44517Sdinak * "to" should be the address of a ptr init'ed to NULL to 44617Sdinak * receive the BIGNUM, e.g., 44717Sdinak * biginteger_t from; 44817Sdinak * BIGNUM *foo = NULL; 44917Sdinak * cvt_bigint2bn(&from, &foo); 45017Sdinak */ 45117Sdinak static int 45217Sdinak cvt_bigint2bn(biginteger_t *from, BIGNUM **to) 45317Sdinak { 45417Sdinak BIGNUM *temp = NULL; 45517Sdinak 45617Sdinak cryptodebug("inside cvt_bigint2bn"); 45717Sdinak 45817Sdinak if (from == NULL || to == NULL) 45917Sdinak return (-1); 46017Sdinak 46117Sdinak cryptodebug("calling BN_bin2bn"); 46217Sdinak if ((temp = BN_bin2bn(from->big_value, from->big_value_len, *to)) == 46317Sdinak NULL) 46417Sdinak return (-1); 46517Sdinak 46617Sdinak *to = temp; 46717Sdinak return (0); 46817Sdinak } 46917Sdinak 47017Sdinak /* 47117Sdinak * Convert PKCS#11 RSA private key to OpenSSL EVP_PKEY structure. 47217Sdinak */ 47317Sdinak static CK_RV 47417Sdinak cvt_rsa2evp_pkey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, EVP_PKEY **pk) 47517Sdinak { 47617Sdinak CK_RV rv = CKR_OK; 47717Sdinak EVP_PKEY *key = NULL; /* OpenSSL representation */ 47817Sdinak RSA *rsa = NULL; /* OpenSSL representation */ 47917Sdinak biginteger_t mod = { NULL, 0 }; /* required */ 48017Sdinak biginteger_t pubexp = { NULL, 0 }; /* required */ 48117Sdinak biginteger_t priexp = { NULL, 0 }; /* optional */ 48217Sdinak biginteger_t prime1 = { NULL, 0 }; /* optional */ 48317Sdinak biginteger_t prime2 = { NULL, 0 }; /* optional */ 48417Sdinak biginteger_t exp1 = { NULL, 0 }; /* optional */ 48517Sdinak biginteger_t exp2 = { NULL, 0 }; /* optional */ 48617Sdinak biginteger_t coef = { NULL, 0 }; /* optional */ 48717Sdinak CK_ATTRIBUTE rsa_pri_attrs[8] = { 48817Sdinak { CKA_MODULUS, NULL, 0 }, 48917Sdinak { CKA_PUBLIC_EXPONENT, NULL, 0 }, 49017Sdinak { CKA_PRIVATE_EXPONENT, NULL, 0 }, /* optional */ 49117Sdinak { CKA_PRIME_1, NULL, 0 }, /* | */ 49217Sdinak { CKA_PRIME_2, NULL, 0 }, /* | */ 49317Sdinak { CKA_EXPONENT_1, NULL, 0 }, /* | */ 49417Sdinak { CKA_EXPONENT_2, NULL, 0 }, /* | */ 49517Sdinak { CKA_COEFFICIENT, NULL, 0 } /* V */ 49617Sdinak }; 49717Sdinak CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE); 49817Sdinak int i; 49917Sdinak 50017Sdinak cryptodebug("inside cvt_rsa2evp_pkey"); 50117Sdinak 50217Sdinak cryptodebug("calling RSA_new"); 50317Sdinak if ((rsa = RSA_new()) == NULL) { 50417Sdinak cryptoerror(LOG_STDERR, gettext( 50517Sdinak "Unable to allocate internal RSA structure.")); 50617Sdinak return (CKR_HOST_MEMORY); 50717Sdinak } 50817Sdinak 50917Sdinak /* Get the sizes of the attributes we need. */ 51017Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 51117Sdinak if ((rv = C_GetAttributeValue(sess, obj, rsa_pri_attrs, count)) != 51217Sdinak CKR_OK) { 51317Sdinak cryptoerror(LOG_STDERR, gettext( 51417Sdinak "Unable to get RSA private key attribute sizes (%s)."), 51517Sdinak pkcs11_strerror(rv)); 51617Sdinak return (rv); 51717Sdinak } 51817Sdinak 51917Sdinak /* Allocate memory for each attribute. */ 52017Sdinak for (i = 0; i < count; i++) { 52117Sdinak if (rsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 || 52217Sdinak rsa_pri_attrs[i].ulValueLen == 0) { 52317Sdinak cryptodebug("cvt_rsa2evp_pkey: *** should not happen"); 52417Sdinak rsa_pri_attrs[i].ulValueLen = 0; 52517Sdinak continue; 52617Sdinak } 52717Sdinak if ((rsa_pri_attrs[i].pValue = 52817Sdinak malloc(rsa_pri_attrs[i].ulValueLen)) == NULL) { 52917Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 53017Sdinak return (CKR_HOST_MEMORY); 53117Sdinak } 53217Sdinak } 53317Sdinak 53417Sdinak /* Now really get the attributes. */ 53517Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 53617Sdinak if ((rv = C_GetAttributeValue(sess, obj, rsa_pri_attrs, count)) != 53717Sdinak CKR_OK) { 53817Sdinak cryptoerror(LOG_STDERR, gettext( 53917Sdinak "Unable to get RSA private key attributes (%s)."), 54017Sdinak pkcs11_strerror(rv)); 54117Sdinak return (rv); 54217Sdinak } 54317Sdinak 54417Sdinak /* 54517Sdinak * Fill in all the temp variables. Modulus and public exponent 54617Sdinak * are required. The rest are optional. 54717Sdinak */ 54817Sdinak i = 0; 54917Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i++]), &mod); 55017Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i++]), &pubexp); 55117Sdinak 55217Sdinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 55317Sdinak rsa_pri_attrs[i].ulValueLen != 0) 55417Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &priexp); 55517Sdinak i++; 55617Sdinak 55717Sdinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 55817Sdinak rsa_pri_attrs[i].ulValueLen != 0) 55917Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &prime1); 56017Sdinak i++; 56117Sdinak 56217Sdinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 56317Sdinak rsa_pri_attrs[i].ulValueLen != 0) 56417Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &prime2); 56517Sdinak i++; 56617Sdinak 56717Sdinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 56817Sdinak rsa_pri_attrs[i].ulValueLen != 0) 56917Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &exp1); 57017Sdinak i++; 57117Sdinak 57217Sdinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 57317Sdinak rsa_pri_attrs[i].ulValueLen != 0) 57417Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &exp2); 57517Sdinak i++; 57617Sdinak 57717Sdinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 57817Sdinak rsa_pri_attrs[i].ulValueLen != 0) 57917Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &coef); 58017Sdinak i++; 58117Sdinak 58217Sdinak /* Start the conversion to internal OpenSSL RSA structure. */ 58317Sdinak 58417Sdinak /* Modulus n */ 58517Sdinak if (cvt_bigint2bn(&mod, &(rsa->n)) < 0) { 58617Sdinak cryptoerror(LOG_STDERR, gettext( 58717Sdinak "Unable to convert RSA private key modulus.")); 58817Sdinak return (CKR_GENERAL_ERROR); 58917Sdinak } 59017Sdinak 59117Sdinak /* Public exponent e */ 59217Sdinak if (cvt_bigint2bn(&pubexp, &(rsa->e)) < 0) { 59317Sdinak cryptoerror(LOG_STDERR, gettext( 59417Sdinak "Unable to convert RSA private key public exponent.")); 59517Sdinak return (CKR_GENERAL_ERROR); 59617Sdinak } 59717Sdinak 59817Sdinak /* Private exponent e */ 59917Sdinak if (priexp.big_value != NULL) { 60017Sdinak if (cvt_bigint2bn(&priexp, &(rsa->d)) < 0) { 60117Sdinak cryptoerror(LOG_STDERR, gettext("Unable to convert " 60217Sdinak "RSA private key private exponent.")); 60317Sdinak return (CKR_GENERAL_ERROR); 60417Sdinak } 60517Sdinak } else 60617Sdinak cryptodebug("no RSA private key private exponent"); 60717Sdinak 60817Sdinak /* Prime p */ 60917Sdinak if (prime1.big_value != NULL) { 61017Sdinak if (cvt_bigint2bn(&prime1, &(rsa->p)) < 0) { 61117Sdinak cryptoerror(LOG_STDERR, gettext( 61217Sdinak "Unable to convert RSA private key prime 1.")); 61317Sdinak return (CKR_GENERAL_ERROR); 61417Sdinak } 61517Sdinak } else 61617Sdinak cryptodebug("no RSA private key prime 1"); 61717Sdinak 61817Sdinak /* Prime q */ 61917Sdinak if (prime2.big_value != NULL) { 62017Sdinak if (cvt_bigint2bn(&prime2, &(rsa->q)) < 0) { 62117Sdinak cryptoerror(LOG_STDERR, gettext( 62217Sdinak "Unable to convert RSA private key prime 2.")); 62317Sdinak return (CKR_GENERAL_ERROR); 62417Sdinak } 62517Sdinak } else 62617Sdinak cryptodebug("no RSA private key prime 2"); 62717Sdinak 62817Sdinak /* Private exponent d modulo p-1 */ 62917Sdinak if (exp1.big_value != NULL) { 63017Sdinak if (cvt_bigint2bn(&exp1, &(rsa->dmp1)) < 0) { 63117Sdinak cryptoerror(LOG_STDERR, gettext( 63217Sdinak "Unable to convert RSA private key exponent 1.")); 63317Sdinak return (CKR_GENERAL_ERROR); 63417Sdinak } 63517Sdinak } else 63617Sdinak cryptodebug("no RSA private key exponent 1"); 63717Sdinak 63817Sdinak /* Private exponent d modulo q-1 */ 63917Sdinak if (exp2.big_value != NULL) { 64017Sdinak if (cvt_bigint2bn(&exp2, &(rsa->dmq1)) < 0) { 64117Sdinak cryptoerror(LOG_STDERR, gettext( 64217Sdinak "Unable to convert RSA private key exponent 2.")); 64317Sdinak return (CKR_GENERAL_ERROR); 64417Sdinak } 64517Sdinak } else 64617Sdinak cryptodebug("no RSA private key exponent 2"); 64717Sdinak 64817Sdinak /* CRT coefficient q-inverse mod p */ 64917Sdinak if (coef.big_value != NULL) { 65017Sdinak if (cvt_bigint2bn(&coef, &(rsa->iqmp)) < 0) { 65117Sdinak cryptoerror(LOG_STDERR, gettext( 65217Sdinak "Unable to convert RSA private key coefficient.")); 65317Sdinak return (CKR_GENERAL_ERROR); 65417Sdinak } 65517Sdinak } else 65617Sdinak cryptodebug("no RSA private key coefficient"); 65717Sdinak 65817Sdinak /* Create OpenSSL EVP_PKEY struct in which to stuff RSA struct. */ 65917Sdinak cryptodebug("calling EVP_PKEY_new"); 66017Sdinak if ((key = EVP_PKEY_new()) == NULL) { 66117Sdinak cryptoerror(LOG_STDERR, gettext( 66217Sdinak "Unable to allocate internal EVP_PKEY structure.")); 66317Sdinak return (CKR_HOST_MEMORY); 66417Sdinak } 66517Sdinak 66617Sdinak /* Put the RSA struct into the EVP_PKEY struct and return it. */ 66717Sdinak cryptodebug("calling EVP_PKEY_set1_RSA"); 66817Sdinak (void) EVP_PKEY_set1_RSA(key, rsa); 66917Sdinak 67017Sdinak *pk = key; 67117Sdinak return (CKR_OK); 67217Sdinak } 67317Sdinak 67417Sdinak /* 67517Sdinak * Convert PKCS#11 DSA private key to OpenSSL EVP_PKEY structure. 67617Sdinak */ 67717Sdinak static CK_RV 67817Sdinak cvt_dsa2evp_pkey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, EVP_PKEY **pk) 67917Sdinak { 68017Sdinak CK_RV rv = CKR_OK; 68117Sdinak EVP_PKEY *key = NULL; /* OpenSSL representation */ 68217Sdinak DSA *dsa = NULL; /* OpenSSL representation */ 68317Sdinak biginteger_t prime = { NULL, 0 }; /* required */ 68417Sdinak biginteger_t subprime = { NULL, 0 }; /* required */ 68517Sdinak biginteger_t base = { NULL, 0 }; /* required */ 68617Sdinak biginteger_t value = { NULL, 0 }; /* required */ 68717Sdinak CK_ATTRIBUTE dsa_pri_attrs[4] = { 68817Sdinak { CKA_PRIME, NULL, 0 }, 68917Sdinak { CKA_SUBPRIME, NULL, 0 }, 69017Sdinak { CKA_BASE, NULL, 0 }, 69117Sdinak { CKA_VALUE, NULL, 0 } 69217Sdinak }; 69317Sdinak CK_ULONG count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE); 69417Sdinak int i; 69517Sdinak 69617Sdinak cryptodebug("inside cvt_dsa2evp_pkey"); 69717Sdinak 69817Sdinak cryptodebug("calling DSA_new"); 69917Sdinak if ((dsa = DSA_new()) == NULL) { 70017Sdinak cryptoerror(LOG_STDERR, gettext( 70117Sdinak "Unable to allocate internal DSA structure.")); 70217Sdinak return (CKR_HOST_MEMORY); 70317Sdinak } 70417Sdinak 70517Sdinak /* Get the sizes of the attributes we need. */ 70617Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 70717Sdinak if ((rv = C_GetAttributeValue(sess, obj, dsa_pri_attrs, count)) != 70817Sdinak CKR_OK) { 70917Sdinak cryptoerror(LOG_STDERR, gettext( 71017Sdinak "Unable to get DSA private key object attributes (%s)."), 71117Sdinak pkcs11_strerror(rv)); 71217Sdinak return (rv); 71317Sdinak } 71417Sdinak 71517Sdinak /* Allocate memory for each attribute. */ 71617Sdinak for (i = 0; i < count; i++) { 71717Sdinak if (dsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 || 71817Sdinak dsa_pri_attrs[i].ulValueLen == 0) { 71917Sdinak cryptodebug("cvt_dsa2evp_pkey: *** should not happen"); 72017Sdinak dsa_pri_attrs[i].ulValueLen = 0; 72117Sdinak continue; 72217Sdinak } 72317Sdinak if ((dsa_pri_attrs[i].pValue = 72417Sdinak malloc(dsa_pri_attrs[i].ulValueLen)) == NULL) { 72517Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 72617Sdinak return (CKR_HOST_MEMORY); 72717Sdinak } 72817Sdinak } 72917Sdinak 73017Sdinak /* Now really get the attributes. */ 73117Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 73217Sdinak if ((rv = C_GetAttributeValue(sess, obj, dsa_pri_attrs, count)) != 73317Sdinak CKR_OK) { 73417Sdinak cryptoerror(LOG_STDERR, gettext( 73517Sdinak "Unable to get DSA private key attributes (%s)."), 73617Sdinak pkcs11_strerror(rv)); 73717Sdinak return (rv); 73817Sdinak } 73917Sdinak 74017Sdinak /* Fill in all the temp variables. They are all required. */ 74117Sdinak i = 0; 74217Sdinak copy_attr_to_bigint(&(dsa_pri_attrs[i++]), &prime); 74317Sdinak copy_attr_to_bigint(&(dsa_pri_attrs[i++]), &subprime); 74417Sdinak copy_attr_to_bigint(&(dsa_pri_attrs[i++]), &base); 74517Sdinak copy_attr_to_bigint(&(dsa_pri_attrs[i++]), &value); 74617Sdinak 74717Sdinak /* Start the conversion to internal OpenSSL DSA structure. */ 74817Sdinak 74917Sdinak /* Prime p */ 75017Sdinak if (cvt_bigint2bn(&prime, &(dsa->p)) < 0) { 75117Sdinak cryptoerror(LOG_STDERR, gettext( 75217Sdinak "Unable to convert DSA private key prime.")); 75317Sdinak return (CKR_GENERAL_ERROR); 75417Sdinak } 75517Sdinak 75617Sdinak /* Subprime q */ 75717Sdinak if (cvt_bigint2bn(&subprime, &(dsa->q)) < 0) { 75817Sdinak cryptoerror(LOG_STDERR, gettext( 75917Sdinak "Unable to convert DSA private key subprime.")); 76017Sdinak return (CKR_GENERAL_ERROR); 76117Sdinak } 76217Sdinak 76317Sdinak /* Base g */ 76417Sdinak if (cvt_bigint2bn(&base, &(dsa->g)) < 0) { 76517Sdinak cryptoerror(LOG_STDERR, gettext( 76617Sdinak "Unable to convert DSA private key base.")); 76717Sdinak return (CKR_GENERAL_ERROR); 76817Sdinak } 76917Sdinak 77017Sdinak /* Private key x */ 77117Sdinak if (cvt_bigint2bn(&value, &(dsa->priv_key)) < 0) { 77217Sdinak cryptoerror(LOG_STDERR, gettext( 77317Sdinak "Unable to convert DSA private key value.")); 77417Sdinak return (CKR_GENERAL_ERROR); 77517Sdinak } 77617Sdinak 77717Sdinak /* Create OpenSSL EVP PKEY struct in which to stuff DSA struct. */ 77817Sdinak cryptodebug("calling EVP_PKEY_new"); 77917Sdinak if ((key = EVP_PKEY_new()) == NULL) { 78017Sdinak cryptoerror(LOG_STDERR, gettext( 78117Sdinak "Unable to allocate internal EVP_PKEY structure.")); 78217Sdinak return (CKR_HOST_MEMORY); 78317Sdinak } 78417Sdinak 78517Sdinak /* Put the DSA struct into the EVP_PKEY struct and return it. */ 78617Sdinak cryptodebug("calling EVP_PKEY_set1_DSA"); 78717Sdinak (void) EVP_PKEY_set1_DSA(key, dsa); 78817Sdinak 78917Sdinak *pk = key; 79017Sdinak return (CKR_OK); 79117Sdinak } 79217Sdinak 79317Sdinak /* 79417Sdinak * Convert PKCS#11 DH private key to OpenSSL EVP_PKEY structure. 79517Sdinak */ 79617Sdinak static CK_RV 79717Sdinak cvt_dh2evp_pkey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, EVP_PKEY **pk) 79817Sdinak { 79917Sdinak CK_RV rv = CKR_OK; 80017Sdinak EVP_PKEY *key = NULL; /* OpenSSL representation */ 80117Sdinak DH *dh = NULL; /* OpenSSL representation */ 80217Sdinak biginteger_t prime = { NULL, 0 }; /* required */ 80317Sdinak biginteger_t base = { NULL, 0 }; /* required */ 80417Sdinak biginteger_t value = { NULL, 0 }; /* required */ 80517Sdinak CK_ATTRIBUTE dh_pri_attrs[3] = { 80617Sdinak { CKA_PRIME, NULL, 0 }, 80717Sdinak { CKA_BASE, NULL, 0 }, 80817Sdinak { CKA_VALUE, NULL, 0 } 80917Sdinak }; 81017Sdinak CK_ULONG count = sizeof (dh_pri_attrs) / sizeof (CK_ATTRIBUTE); 81117Sdinak int i; 81217Sdinak 81317Sdinak cryptodebug("inside cvt_dh2evp_pkey"); 81417Sdinak 81517Sdinak cryptodebug("calling DH_new"); 81617Sdinak if ((dh = DH_new()) == NULL) { 81717Sdinak cryptoerror(LOG_STDERR, gettext( 81817Sdinak "Unable to allocate internal DH structure.")); 81917Sdinak return (CKR_HOST_MEMORY); 82017Sdinak } 82117Sdinak 82217Sdinak /* Get the sizes of the attributes we need. */ 82317Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 82417Sdinak if ((rv = C_GetAttributeValue(sess, obj, dh_pri_attrs, count)) != 82517Sdinak CKR_OK) { 82617Sdinak cryptoerror(LOG_STDERR, gettext( 82717Sdinak "Unable to get DH private key object attributes (%s)."), 82817Sdinak pkcs11_strerror(rv)); 82917Sdinak return (rv); 83017Sdinak } 83117Sdinak 83217Sdinak /* Allocate memory for each attribute. */ 83317Sdinak for (i = 0; i < count; i++) { 83417Sdinak if (dh_pri_attrs[i].ulValueLen == (CK_ULONG)-1 || 83517Sdinak dh_pri_attrs[i].ulValueLen == 0) { 83617Sdinak cryptodebug("cvt_dh2evp_pkey: ***should not happen"); 83717Sdinak dh_pri_attrs[i].ulValueLen = 0; 83817Sdinak continue; 83917Sdinak } 84017Sdinak if ((dh_pri_attrs[i].pValue = 84117Sdinak malloc(dh_pri_attrs[i].ulValueLen)) == NULL) { 84217Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 84317Sdinak return (CKR_HOST_MEMORY); 84417Sdinak } 84517Sdinak } 84617Sdinak 84717Sdinak /* Now really get the attributes. */ 84817Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 84917Sdinak if ((rv = C_GetAttributeValue(sess, obj, dh_pri_attrs, count)) != 85017Sdinak CKR_OK) { 85117Sdinak cryptoerror(LOG_STDERR, gettext( 85217Sdinak "Unable to get DH private key attributes (%s)."), 85317Sdinak pkcs11_strerror(rv)); 85417Sdinak return (rv); 85517Sdinak } 85617Sdinak 85717Sdinak /* Fill in all the temp variables. They are all required. */ 85817Sdinak i = 0; 85917Sdinak copy_attr_to_bigint(&(dh_pri_attrs[i++]), &prime); 86017Sdinak copy_attr_to_bigint(&(dh_pri_attrs[i++]), &base); 86117Sdinak copy_attr_to_bigint(&(dh_pri_attrs[i++]), &value); 86217Sdinak 86317Sdinak /* Start the conversion to internal OpenSSL DH structure. */ 86417Sdinak 86517Sdinak /* Prime p */ 86617Sdinak if (cvt_bigint2bn(&prime, &(dh->p)) < 0) { 86717Sdinak cryptoerror(LOG_STDERR, gettext( 86817Sdinak "Unable to convert DH private key prime.")); 86917Sdinak return (CKR_GENERAL_ERROR); 87017Sdinak } 87117Sdinak 87217Sdinak /* Base g */ 87317Sdinak if (cvt_bigint2bn(&base, &(dh->g)) < 0) { 87417Sdinak cryptoerror(LOG_STDERR, gettext( 87517Sdinak "Unable to convert DH private key base.")); 87617Sdinak return (CKR_GENERAL_ERROR); 87717Sdinak } 87817Sdinak 87917Sdinak /* Private value x */ 88017Sdinak if (cvt_bigint2bn(&value, &(dh->priv_key)) < 0) { 88117Sdinak cryptoerror(LOG_STDERR, gettext( 88217Sdinak "Unable to convert DH private key value.")); 88317Sdinak return (CKR_GENERAL_ERROR); 88417Sdinak } 88517Sdinak 88617Sdinak /* Create OpenSSL EVP PKEY struct in which to stuff DH struct. */ 88717Sdinak cryptodebug("calling EVP_PKEY_new"); 88817Sdinak if ((key = EVP_PKEY_new()) == NULL) { 88917Sdinak cryptoerror(LOG_STDERR, gettext( 89017Sdinak "Unable to allocate internal EVP_PKEY structure.")); 89117Sdinak return (CKR_HOST_MEMORY); 89217Sdinak } 89317Sdinak 89417Sdinak /* Put the DH struct into the EVP_PKEY struct and return it. */ 89517Sdinak cryptodebug("calling EVP_PKEY_set1_DH"); 89617Sdinak (void) EVP_PKEY_set1_DH(key, dh); 89717Sdinak 89817Sdinak *pk = key; 89917Sdinak return (CKR_OK); 90017Sdinak } 90117Sdinak 90217Sdinak /* 90317Sdinak * Convert PKCS#11 private key object to OpenSSL EVP_PKEY structure. 90417Sdinak */ 90517Sdinak static CK_RV 90617Sdinak cvt_obj2evp_pkey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, EVP_PKEY **pk) 90717Sdinak { 90817Sdinak CK_RV rv = CKR_OK; 90917Sdinak static CK_KEY_TYPE keytype = 0; 91017Sdinak CK_ATTRIBUTE keytype_attr[1] = { 91117Sdinak { CKA_KEY_TYPE, &keytype, sizeof (keytype) } 91217Sdinak }; 91317Sdinak 91417Sdinak cryptodebug("inside cvt_obj2evp_pkey"); 91517Sdinak 91617Sdinak /* Find out the key type to do the right conversion. */ 91717Sdinak cryptodebug("calling C_GetAttributeValue"); 91817Sdinak if ((rv = C_GetAttributeValue(sess, obj, keytype_attr, 1)) != 91917Sdinak CKR_OK) { 92017Sdinak cryptoerror(LOG_STDERR, gettext( 92117Sdinak "Unable to get token object key type (%s)."), 92217Sdinak pkcs11_strerror(rv)); 92317Sdinak return (rv); 92417Sdinak } 92517Sdinak 92617Sdinak switch (keytype) { 92717Sdinak case CKK_RSA: 92817Sdinak cryptodebug("converting RSA key"); 92917Sdinak return (cvt_rsa2evp_pkey(sess, obj, pk)); 93017Sdinak case CKK_DSA: 93117Sdinak cryptodebug("converting DSA key"); 93217Sdinak return (cvt_dsa2evp_pkey(sess, obj, pk)); 93317Sdinak case CKK_DH: 93417Sdinak cryptodebug("converting DH key"); 93517Sdinak return (cvt_dh2evp_pkey(sess, obj, pk)); 93617Sdinak default: 93717Sdinak cryptoerror(LOG_STDERR, gettext( 93817Sdinak "Private key type 0x%02x conversion not supported."), 93917Sdinak keytype); 94017Sdinak return (CKR_GENERAL_ERROR); 94117Sdinak } 94217Sdinak } 94317Sdinak 94417Sdinak /* 94517Sdinak * Convert PKCS#11 certificate object to OpenSSL X509 structure. 94617Sdinak */ 94717Sdinak static CK_RV 94817Sdinak cvt_cert2x509(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, X509 **c) 94917Sdinak { 95017Sdinak CK_RV rv = CKR_OK; 95117Sdinak X509 *cert = NULL; /* OpenSSL representation */ 95217Sdinak X509 *temp_cert = NULL; 95317Sdinak CK_BYTE *subject = NULL; 95417Sdinak CK_ULONG subject_len = 0; 95517Sdinak CK_BYTE *value = NULL; 95617Sdinak CK_ULONG value_len = 0; 95717Sdinak CK_BYTE *label = NULL; 95817Sdinak CK_ULONG label_len = 0; 95917Sdinak CK_BYTE *id = NULL; 96017Sdinak CK_ULONG id_len = 0; 96117Sdinak CK_BYTE *issuer = NULL; 96217Sdinak CK_ULONG issuer_len = 0; 96317Sdinak CK_BYTE *serial = NULL; 96417Sdinak CK_ULONG serial_len = 0; 96517Sdinak CK_ATTRIBUTE cert_attrs[6] = { 96617Sdinak { CKA_SUBJECT, NULL, 0 }, /* required */ 96717Sdinak { CKA_VALUE, NULL, 0 }, /* required */ 96817Sdinak { CKA_LABEL, NULL, 0 }, /* optional */ 96917Sdinak { CKA_ID, NULL, 0 }, /* optional */ 97017Sdinak { CKA_ISSUER, NULL, 0 }, /* optional */ 97117Sdinak { CKA_SERIAL_NUMBER, NULL, 0 } /* optional */ 97217Sdinak }; 97317Sdinak CK_ULONG count = sizeof (cert_attrs) / sizeof (CK_ATTRIBUTE); 97417Sdinak int i = 0; 97517Sdinak X509_NAME *ssl_subject = NULL; 97617Sdinak X509_NAME *ssl_issuer = NULL; 97717Sdinak ASN1_INTEGER *ssl_serial = NULL; 97817Sdinak 97917Sdinak cryptodebug("inside cvt_cert2x509"); 98017Sdinak 98117Sdinak cryptodebug("calling X509_new"); 98217Sdinak if ((cert = X509_new()) == NULL) { 98317Sdinak cryptoerror(LOG_STDERR, gettext( 98417Sdinak "Unable to allocate internal X509 structure.")); 98517Sdinak return (CKR_HOST_MEMORY); 98617Sdinak } 98717Sdinak 98817Sdinak /* Get the sizes of the attributes we need. */ 98917Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 99017Sdinak if ((rv = C_GetAttributeValue(sess, obj, cert_attrs, count)) != 99117Sdinak CKR_OK) { 99217Sdinak cryptoerror(LOG_STDERR, gettext( 99317Sdinak "Unable to get certificate attribute sizes (%s)."), 99417Sdinak pkcs11_strerror(rv)); 99517Sdinak return (rv); 99617Sdinak } 99717Sdinak 99817Sdinak /* Allocate memory for each attribute. */ 99917Sdinak for (i = 0; i < count; i++) { 100017Sdinak if (cert_attrs[i].ulValueLen == (CK_ULONG)-1 || 100117Sdinak cert_attrs[i].ulValueLen == 0) { 100217Sdinak cryptodebug("cvt_cert2x509: *** should not happen"); 100317Sdinak cert_attrs[i].ulValueLen = 0; 100417Sdinak continue; 100517Sdinak } 100617Sdinak if ((cert_attrs[i].pValue = malloc(cert_attrs[i].ulValueLen)) 100717Sdinak == NULL) { 100817Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 100917Sdinak return (CKR_HOST_MEMORY); 101017Sdinak } 101117Sdinak } 101217Sdinak 101317Sdinak /* Now really get the attributes. */ 101417Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 101517Sdinak if ((rv = C_GetAttributeValue(sess, obj, cert_attrs, count)) != 101617Sdinak CKR_OK) { 101717Sdinak cryptoerror(LOG_STDERR, gettext( 101817Sdinak "Unable to get certificate attributes (%s)."), 101917Sdinak pkcs11_strerror(rv)); 102017Sdinak return (rv); 102117Sdinak } 102217Sdinak 102317Sdinak /* 102417Sdinak * Fill in all the temp variables. Subject and value are required. 102517Sdinak * The rest are optional. 102617Sdinak */ 102717Sdinak i = 0; 102817Sdinak copy_attr_to_string(&(cert_attrs[i++]), &subject, &subject_len); 102917Sdinak copy_attr_to_string(&(cert_attrs[i++]), &value, &value_len); 103017Sdinak 103117Sdinak if (cert_attrs[i].ulValueLen != (CK_ULONG)-1 && 103217Sdinak cert_attrs[i].ulValueLen != 0) 103317Sdinak copy_attr_to_string(&(cert_attrs[i]), &label, &label_len); 103417Sdinak i++; 103517Sdinak 103617Sdinak if (cert_attrs[i].ulValueLen != (CK_ULONG)-1 && 103717Sdinak cert_attrs[i].ulValueLen != 0) 103817Sdinak copy_attr_to_string(&(cert_attrs[i]), &id, &id_len); 103917Sdinak i++; 104017Sdinak 104117Sdinak if (cert_attrs[i].ulValueLen != (CK_ULONG)-1 && 104217Sdinak cert_attrs[i].ulValueLen != 0) 104317Sdinak copy_attr_to_string(&(cert_attrs[i]), &issuer, &issuer_len); 104417Sdinak i++; 104517Sdinak 104617Sdinak if (cert_attrs[i].ulValueLen != (CK_ULONG)-1 && 104717Sdinak cert_attrs[i].ulValueLen != 0) 104817Sdinak copy_attr_to_string(&(cert_attrs[i]), &serial, &serial_len); 104917Sdinak i++; 105017Sdinak 105117Sdinak /* Start the conversion to internal OpenSSL X509 structure. */ 105217Sdinak 105317Sdinak /* Subject name (required) */ 105417Sdinak cryptodebug("calling d2i_X509_NAME for subject name"); 105517Sdinak if ((ssl_subject = d2i_X509_NAME(NULL, &subject, subject_len)) == 105617Sdinak NULL) { 105717Sdinak cryptoerror(LOG_STDERR, gettext( 105817Sdinak "Unable to convert certificate subject name.")); 105917Sdinak return (CKR_GENERAL_ERROR); 106017Sdinak } 106117Sdinak cryptodebug("calling X509_set_subject_name"); 106217Sdinak if (!X509_set_subject_name(cert, ssl_subject)) { 106317Sdinak cryptoerror(LOG_STDERR, gettext( 106417Sdinak "Unable to pack certificate subject name entries.")); 106517Sdinak return (CKR_GENERAL_ERROR); 106617Sdinak } 106717Sdinak 106817Sdinak /* Label (optional) */ 106917Sdinak cryptodebug("calling X509_alias_set1"); 107017Sdinak if (!X509_alias_set1(cert, label, label_len)) 107117Sdinak cryptodebug("error not caught"); 107217Sdinak 107317Sdinak /* Id (optional) */ 107417Sdinak cryptodebug("calling X509_keyid_set1"); 107517Sdinak if (!X509_keyid_set1(cert, id, id_len)) 107617Sdinak cryptodebug("error not caught"); 107717Sdinak 107817Sdinak /* Issuer name (optional) */ 107917Sdinak cryptodebug("calling d2i_X509_NAME for issuer name"); 108017Sdinak if ((ssl_issuer = d2i_X509_NAME(NULL, &issuer, issuer_len)) == NULL) { 108117Sdinak cryptoerror(LOG_STDERR, gettext( 108217Sdinak "Unable to convert certificate issuer name.")); 108317Sdinak return (CKR_GENERAL_ERROR); 108417Sdinak } 108517Sdinak cryptodebug("calling X509_set_issuer_name"); 108617Sdinak if (!X509_set_issuer_name(cert, ssl_issuer)) { 108717Sdinak cryptoerror(LOG_STDERR, gettext( 108817Sdinak "Unable to pack certificate issuer name entries.")); 108917Sdinak return (CKR_GENERAL_ERROR); 109017Sdinak } 109117Sdinak 109217Sdinak /* Serial number (optional) */ 109317Sdinak cryptodebug("calling c2i_ASN1_INTEGER for serial number"); 109417Sdinak if ((ssl_serial = c2i_ASN1_INTEGER(NULL, &serial, serial_len)) == 109517Sdinak NULL) { 109617Sdinak cryptoerror(LOG_STDERR, gettext( 109717Sdinak "Unable to convert certificate serial number.")); 109817Sdinak return (CKR_GENERAL_ERROR); 109917Sdinak } 110017Sdinak cryptodebug("calling X509_set_serialNumber"); 110117Sdinak if (!X509_set_serialNumber(cert, ssl_serial)) 110217Sdinak cryptodebug("error not caught"); 110317Sdinak 110417Sdinak /* 110517Sdinak * Value (required) 110617Sdinak * 110717Sdinak * The rest of this code takes the CKA_VALUE attribute, converts 110817Sdinak * it into a temp OpenSSL X509 structure and picks out the rest 110917Sdinak * of the fields we need to convert it back into the current X509 111017Sdinak * structure that will get exported. The reason we don't just 111117Sdinak * start with CKA_VALUE is because while the object was in the 111217Sdinak * softtoken, it is possible that some of its attributes changed. 111317Sdinak * Those changes would not appear in CKA_VALUE and would be lost 111417Sdinak * if we started with CKA_VALUE that was saved originally. 111517Sdinak */ 111617Sdinak cryptodebug("calling d2i_X509 for cert value"); 111717Sdinak if ((temp_cert = d2i_X509(NULL, &value, value_len)) == NULL) { 111817Sdinak cryptoerror(LOG_STDERR, gettext( 111917Sdinak "Unable to convert main certificate values.")); 112017Sdinak return (CKR_GENERAL_ERROR); 112117Sdinak } 112217Sdinak 112317Sdinak /* Transfer these values from temp_cert to cert. */ 112417Sdinak cryptodebug("calling X509_set_version/X509_get_version"); 112517Sdinak if (!X509_set_version(cert, X509_get_version(temp_cert))) 112617Sdinak cryptodebug("error not caught"); 112717Sdinak 112817Sdinak cryptodebug("calling X509_set_notBefore/X509_get_notBefore"); 112917Sdinak if (!X509_set_notBefore(cert, X509_get_notBefore(temp_cert))) 113017Sdinak cryptodebug("error not caught"); 113117Sdinak 113217Sdinak cryptodebug("calling X509_set_notAfter/X509_get_notAfter"); 113317Sdinak if (!X509_set_notAfter(cert, X509_get_notAfter(temp_cert))) 113417Sdinak cryptodebug("error not caught"); 113517Sdinak 113617Sdinak cryptodebug("calling X509_set_pubkey/X509_get_pubkey"); 113717Sdinak if (!X509_set_pubkey(cert, X509_get_pubkey(temp_cert))) 113817Sdinak cryptodebug("error not caught"); 113917Sdinak 114017Sdinak /* 114117Sdinak * These don't get transfered from temp_cert to cert. 114217Sdinak * It -appears- that they may get regenerated as needed. 114317Sdinak * 114417Sdinak * cert->cert_info->signature = dup(temp_cert->cert_info->signature); 114517Sdinak * cert->sig_alg = dup(temp_cert->sig_alg); 114617Sdinak * cert->signature = dup(temp_cert->signature); 114717Sdinak * cert->skid = dup(temp_cert->skid); 114817Sdinak * cert->akid = dup(temp_cert->akid); 114917Sdinak */ 115017Sdinak 115117Sdinak *c = cert; 115217Sdinak return (CKR_OK); 115317Sdinak } 115417Sdinak 115517Sdinak static CK_RV 115617Sdinak convert_token_objs(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, 115717Sdinak CK_OBJECT_HANDLE mate, CK_OBJECT_HANDLE *chain, CK_ULONG chain_len, 115817Sdinak EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca) 115917Sdinak { 116017Sdinak CK_RV rv = CKR_OK; 116117Sdinak EVP_PKEY *pk = NULL; 116217Sdinak X509 *c = NULL; 116317Sdinak X509 *one_ca = NULL; 116417Sdinak STACK_OF(X509) *ch = NULL; 116517Sdinak int i; 116617Sdinak 116717Sdinak cryptodebug("inside convert_token_objs"); 116817Sdinak 116917Sdinak if ((rv = cvt_obj2evp_pkey(sess, obj, &pk)) != CKR_OK) 117017Sdinak return (rv); 117117Sdinak 117217Sdinak if (mate != ~0UL) { 117317Sdinak cryptodebug("converting cert corresponding to private key"); 117417Sdinak if ((rv = cvt_cert2x509(sess, mate, &c)) != CKR_OK) 117517Sdinak return (rv); 117617Sdinak } 117717Sdinak 117817Sdinak if (chain_len != 0) { 117917Sdinak cryptodebug("converting ca chain of %d certs corresponding " 118017Sdinak "to private key", chain_len); 118117Sdinak ch = sk_X509_new_null(); 118217Sdinak for (i = 0; i < chain_len; i++) { 118317Sdinak if ((rv = cvt_cert2x509(sess, chain[i], &one_ca)) != 118417Sdinak CKR_OK) { 118517Sdinak return (rv); 118617Sdinak } 118717Sdinak if (!sk_X509_push(ch, one_ca)) 118817Sdinak cryptodebug("error not caught"); 118917Sdinak } 119017Sdinak } 119117Sdinak 119217Sdinak *priv_key = pk; 119317Sdinak *cert = (mate != ~0UL) ? c : NULL; 119417Sdinak *ca = (chain_len != 0) ? ch : NULL; 119517Sdinak return (CKR_OK); 119617Sdinak } 119717Sdinak 119817Sdinak /* 119917Sdinak * Export objects from token to PKCS#12 file. 120017Sdinak */ 120117Sdinak int 120217Sdinak pk_export(int argc, char *argv[]) 120317Sdinak { 1204*864Sdinak int opt; 1205*864Sdinak extern int optind_av; 1206*864Sdinak extern char *optarg_av; 1207*864Sdinak char *token_spec = NULL; 120817Sdinak char *token_name = NULL; 120917Sdinak char *manuf_id = NULL; 121017Sdinak char *serial_no = NULL; 121117Sdinak char full_name[FULL_NAME_LEN]; 121217Sdinak char *filename = NULL; 121317Sdinak CK_SLOT_ID slot_id; 121417Sdinak CK_FLAGS pin_state; 121517Sdinak CK_UTF8CHAR_PTR pin = NULL; 121617Sdinak CK_ULONG pinlen = 0; 121717Sdinak CK_UTF8CHAR_PTR pk12pin = NULL; 121817Sdinak CK_ULONG pk12pinlen = 0; 121917Sdinak CK_SESSION_HANDLE sess; 122017Sdinak BIO *fbio = NULL; 122117Sdinak EVP_PKEY *priv_key = NULL; 122217Sdinak X509 *cert = NULL; 122317Sdinak STACK_OF(X509) *ca = NULL; 122417Sdinak CK_RV rv = CKR_OK; 122517Sdinak CK_OBJECT_HANDLE *objs = NULL; 122617Sdinak CK_ULONG num_objs = 0; 122717Sdinak CK_OBJECT_HANDLE mate = ~0UL; 122817Sdinak CK_OBJECT_HANDLE *chain = NULL; 122917Sdinak CK_ULONG chain_len; 123017Sdinak CK_BYTE *id = NULL; 123117Sdinak CK_ULONG id_len = 0; 123217Sdinak int i = 0; 123317Sdinak int good_ones = 0, bad_ones = 0; /* running totals */ 123417Sdinak 123517Sdinak cryptodebug("inside pk_export"); 123617Sdinak 1237*864Sdinak /* Parse command line options. Do NOT i18n/l10n. */ 1238*864Sdinak while ((opt = getopt_av(argc, argv, "T:(token)o:(outfile)")) != EOF) { 1239*864Sdinak switch (opt) { 1240*864Sdinak case 'T': /* token specifier */ 1241*864Sdinak if (token_spec) 1242*864Sdinak return (PK_ERR_USAGE); 1243*864Sdinak token_spec = optarg_av; 1244*864Sdinak break; 1245*864Sdinak case 'o': /* output file name */ 1246*864Sdinak if (filename) 1247*864Sdinak return (PK_ERR_USAGE); 1248*864Sdinak filename = optarg_av; 1249*864Sdinak break; 1250*864Sdinak default: 1251*864Sdinak return (PK_ERR_USAGE); 1252*864Sdinak break; 1253*864Sdinak } 1254*864Sdinak } 125517Sdinak 1256*864Sdinak /* If nothing is specified, default is to use softtoken. */ 1257*864Sdinak if (token_spec == NULL) { 1258*864Sdinak token_name = SOFT_TOKEN_LABEL; 1259*864Sdinak manuf_id = SOFT_MANUFACTURER_ID; 1260*864Sdinak serial_no = SOFT_TOKEN_SERIAL; 1261*864Sdinak } else { 1262*864Sdinak /* 1263*864Sdinak * Parse token specifier into token_name, manuf_id, serial_no. 1264*864Sdinak * Token_name is required; manuf_id and serial_no are optional. 1265*864Sdinak */ 1266*864Sdinak if (parse_token_spec(token_spec, &token_name, &manuf_id, 1267*864Sdinak &serial_no) < 0) 1268*864Sdinak return (PK_ERR_USAGE); 1269*864Sdinak } 1270*864Sdinak 1271*864Sdinak /* Filename arg is required. */ 1272*864Sdinak if (filename == NULL) 127317Sdinak return (PK_ERR_USAGE); 127417Sdinak 1275*864Sdinak /* No additional args allowed. */ 1276*864Sdinak argc -= optind_av; 1277*864Sdinak argv += optind_av; 1278*864Sdinak if (argc) 1279*864Sdinak return (PK_ERR_USAGE); 128017Sdinak /* Done parsing command line options. */ 128117Sdinak 128217Sdinak /* Check if the file exists and might be overwritten. */ 128317Sdinak if (access(filename, F_OK) == 0) { 128417Sdinak cryptoerror(LOG_STDERR, gettext("Warning: file \"%s\" exists, " 128517Sdinak "will be overwritten."), filename); 128617Sdinak if (yesno(gettext("Continue with export? "), 128717Sdinak gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) { 128817Sdinak return (0); 128917Sdinak } 129017Sdinak } 129117Sdinak 129217Sdinak full_token_name(token_name, manuf_id, serial_no, full_name); 129317Sdinak 129417Sdinak /* Find the slot with token. */ 129517Sdinak if ((rv = find_token_slot(token_name, manuf_id, serial_no, &slot_id, 129617Sdinak &pin_state)) != CKR_OK) { 129717Sdinak cryptoerror(LOG_STDERR, gettext( 129817Sdinak "Unable to find token %s (%s)."), full_name, 129917Sdinak pkcs11_strerror(rv)); 130017Sdinak return (PK_ERR_PK11); 130117Sdinak } 130217Sdinak 130317Sdinak /* Get the user's PIN. */ 130417Sdinak if ((rv = get_pin(gettext("Enter token passphrase:"), NULL, &pin, 130517Sdinak &pinlen)) != CKR_OK) { 130617Sdinak cryptoerror(LOG_STDERR, gettext( 130717Sdinak "Unable to get token passphrase (%s)."), 130817Sdinak pkcs11_strerror(rv)); 130917Sdinak quick_finish(NULL); 131017Sdinak return (PK_ERR_PK11); 131117Sdinak } 131217Sdinak 131317Sdinak /* Assume user must be logged in R/W to export objects from token. */ 131417Sdinak if ((rv = quick_start(slot_id, CKF_RW_SESSION, pin, pinlen, &sess)) != 131517Sdinak CKR_OK) { 131617Sdinak cryptoerror(LOG_STDERR, 131717Sdinak gettext("Unable to log into token (%s)."), 131817Sdinak pkcs11_strerror(rv)); 131917Sdinak quick_finish(sess); 132017Sdinak return (PK_ERR_PK11); 132117Sdinak } 132217Sdinak 132317Sdinak /* Collect all private keys first. */ 132417Sdinak if ((rv = find_objs(sess, PK_PRIVATE_OBJ|PK_KEY_OBJ, NULL, 132517Sdinak &objs, &num_objs)) != CKR_OK) { 132617Sdinak cryptoerror(LOG_STDERR, gettext( 132717Sdinak "Unable to retrieve private key token objects (%s)."), 132817Sdinak pkcs11_strerror(rv)); 132917Sdinak quick_finish(sess); 133017Sdinak return (PK_ERR_PK11); 133117Sdinak } 133217Sdinak 133317Sdinak /* Nothing to do? */ 133417Sdinak if (num_objs == 0) { 133517Sdinak cryptoerror(LOG_STDERR, gettext("No objects found.")); 133617Sdinak quick_finish(sess); 133717Sdinak return (0); 133817Sdinak } 133917Sdinak 134017Sdinak /* Setup OpenSSL context. */ 134117Sdinak PKTOOL_setup_openssl(); 134217Sdinak 134317Sdinak /* Create PKCS#12 file. */ 134417Sdinak if ((create_pkcs12(filename, &fbio)) < 0) { 134517Sdinak cryptoerror(LOG_STDERR, gettext("No export file created.")); 134617Sdinak quick_finish(sess); 134717Sdinak return (PK_ERR_SYSTEM); 134817Sdinak } 134917Sdinak 135017Sdinak /* Get the PIN for the PKCS#12 export file. */ 135117Sdinak if ((rv = get_pin(gettext("Create export file passphrase:"), gettext( 135217Sdinak "Re-enter export file passphrase:"), &pk12pin, &pk12pinlen)) != 135317Sdinak CKR_OK) { 135417Sdinak cryptoerror(LOG_STDERR, 135517Sdinak gettext("Unable to get export file passphrase (%s)."), 135617Sdinak pkcs11_strerror(rv)); 135717Sdinak close_pkcs12(fbio); 135817Sdinak quick_finish(sess); 135917Sdinak return (PK_ERR_PK11); 136017Sdinak } 136117Sdinak 136217Sdinak for (i = 0; i < num_objs; i++) { 136317Sdinak /* Get a private key and its certificate and CA chain. */ 136417Sdinak if ((rv = get_token_objs(sess, objs[i], &mate, &chain, 136517Sdinak &chain_len, &id, &id_len)) != CKR_OK) { 136617Sdinak /* 136717Sdinak * Note this "rv" is either CKR_OK or !CKR_OK. The 136817Sdinak * real error codes/messages are handled inside 136917Sdinak * read_token_objs(). 137017Sdinak */ 137117Sdinak cryptoerror(LOG_STDERR, 137217Sdinak gettext("Unable to get token objects.")); 137317Sdinak free(id); 137417Sdinak close_pkcs12(fbio); 137517Sdinak quick_finish(sess); 137617Sdinak return (PK_ERR_PK11); 137717Sdinak } 137817Sdinak 137917Sdinak /* Convert to OpenSSL equivalents. */ 138017Sdinak if ((rv = convert_token_objs(sess, objs[i], mate, chain, 138117Sdinak chain_len, &priv_key, &cert, &ca)) != CKR_OK) { 138217Sdinak /* 138317Sdinak * Note this "rv" is either CKR_OK or !CKR_OK. The 138417Sdinak * real error codes/messages are handled inside 138517Sdinak * read_token_objs(). 138617Sdinak */ 138717Sdinak cryptoerror(LOG_STDERR, 138817Sdinak gettext("Unable to convert token objects.")); 138917Sdinak free(id); 139017Sdinak close_pkcs12(fbio); 139117Sdinak quick_finish(sess); 139217Sdinak return (PK_ERR_PK11); 139317Sdinak } 139417Sdinak 139517Sdinak /* 139617Sdinak * When exporting of cert chains is implemented, these 139717Sdinak * messages should be updated accordingly. 139817Sdinak */ 139917Sdinak if (mate == ~0UL) 140017Sdinak (void) fprintf(stdout, gettext( 140117Sdinak "Writing object #%d...\n"), i+1); 140217Sdinak else 140317Sdinak (void) fprintf(stdout, gettext("Writing object #%d " 140417Sdinak "and its certificate...\n"), i+1); 140517Sdinak 140617Sdinak /* Write object and its certs to the PKCS#12 export file. */ 140717Sdinak if (write_objs_pkcs12(fbio, pk12pin, pk12pinlen, id, id_len, 140817Sdinak priv_key, cert, ca, &good_ones, &bad_ones) < 0) { 140917Sdinak cryptoerror(LOG_STDERR, gettext( 141017Sdinak "Unable to write object #%d to export file."), i+1); 141117Sdinak sk_X509_pop_free(ca, X509_free); 141217Sdinak free(id); 141317Sdinak close_pkcs12(fbio); 141417Sdinak quick_finish(sess); 141517Sdinak return (PK_ERR_OPENSSL); 141617Sdinak } 141717Sdinak 141817Sdinak /* Destroy key id and CA cert chain, done with them. */ 141917Sdinak free(id); 142017Sdinak id = NULL; 142117Sdinak sk_X509_pop_free(ca, X509_free); 142217Sdinak ca = NULL; 142317Sdinak } 142417Sdinak 142517Sdinak (void) fprintf(stdout, gettext( 142617Sdinak "%d token objects exported, %d errors occurred.\n"), 142717Sdinak good_ones, bad_ones); 142817Sdinak 142917Sdinak /* Close PKCS#12 file. */ 143017Sdinak close_pkcs12(fbio); 143117Sdinak 143217Sdinak /* Clean up. */ 143317Sdinak quick_finish(sess); 143417Sdinak return (0); 143517Sdinak } 1436