1*17Sdinak /* 2*17Sdinak * CDDL HEADER START 3*17Sdinak * 4*17Sdinak * The contents of this file are subject to the terms of the 5*17Sdinak * Common Development and Distribution License, Version 1.0 only 6*17Sdinak * (the "License"). You may not use this file except in compliance 7*17Sdinak * with the License. 8*17Sdinak * 9*17Sdinak * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*17Sdinak * or http://www.opensolaris.org/os/licensing. 11*17Sdinak * See the License for the specific language governing permissions 12*17Sdinak * and limitations under the License. 13*17Sdinak * 14*17Sdinak * When distributing Covered Code, include this CDDL HEADER in each 15*17Sdinak * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*17Sdinak * If applicable, add the following below this CDDL HEADER, with the 17*17Sdinak * fields enclosed by brackets "[]" replaced with your own identifying 18*17Sdinak * information: Portions Copyright [yyyy] [name of copyright owner] 19*17Sdinak * 20*17Sdinak * CDDL HEADER END 21*17Sdinak */ 22*17Sdinak /* 23*17Sdinak * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*17Sdinak * Use is subject to license terms. 25*17Sdinak */ 26*17Sdinak 27*17Sdinak #pragma ident "%Z%%M% %I% %E% SMI" 28*17Sdinak 29*17Sdinak /* 30*17Sdinak * This file implements the export operation for this tool. 31*17Sdinak * The basic flow of the process is to find the soft token, 32*17Sdinak * log into it, find the PKCS#11 objects in the soft token 33*17Sdinak * to be exported matching keys with their certificates, export 34*17Sdinak * them to the PKCS#12 file encrypting them with a file password 35*17Sdinak * if desired, and log out. 36*17Sdinak */ 37*17Sdinak 38*17Sdinak #include <stdio.h> 39*17Sdinak #include <stdlib.h> 40*17Sdinak #include <string.h> 41*17Sdinak #include <errno.h> 42*17Sdinak #include <cryptoutil.h> 43*17Sdinak #include <security/cryptoki.h> 44*17Sdinak #include "common.h" 45*17Sdinak #include "biginteger.h" 46*17Sdinak #include "osslcommon.h" 47*17Sdinak #include "p12common.h" 48*17Sdinak #include <openssl/pkcs12.h> 49*17Sdinak 50*17Sdinak /* 51*17Sdinak * Writes OpenSSL objects to PKCS#12 file. The PKCS#11 objects from 52*17Sdinak * the soft token need to be converted to OpenSSL structures prior 53*17Sdinak * to this call, since the PKCS#12 routines depend on that format. 54*17Sdinak * This code is patterned from OpenSSL apps that write PKCS#12 files. 55*17Sdinak * 56*17Sdinak * Note: it's not clear from the usage of all the functions here by 57*17Sdinak * OpenSSL apps whether these functions have return values or error 58*17Sdinak * conditions that can be checked. This function may benefit from 59*17Sdinak * a closer review at a later time. 60*17Sdinak */ 61*17Sdinak static int 62*17Sdinak write_objs_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen, 63*17Sdinak CK_BYTE_PTR id, CK_ULONG id_len, EVP_PKEY *priv_key, X509 *cert, 64*17Sdinak STACK_OF(X509) *ca_certs, int *successes, int *failures) 65*17Sdinak /* ARGSUSED */ 66*17Sdinak { 67*17Sdinak STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL; 68*17Sdinak PKCS12_SAFEBAG *bag = NULL; 69*17Sdinak X509 *ca = NULL; 70*17Sdinak PKCS7 *cert_authsafe = NULL; 71*17Sdinak PKCS8_PRIV_KEY_INFO *p8 = NULL; 72*17Sdinak PKCS7 *key_authsafe = NULL; 73*17Sdinak STACK_OF(PKCS7) *authsafe_stack = NULL; 74*17Sdinak PKCS12 *p12_elem = NULL; 75*17Sdinak unsigned char *lab = NULL; 76*17Sdinak int lab_len = 0; 77*17Sdinak int i; 78*17Sdinak int n_writes = 0; 79*17Sdinak 80*17Sdinak cryptodebug("inside write_objs_pkcs12"); 81*17Sdinak 82*17Sdinak /* Do not reset *successes or *failures -- keep running totals. */ 83*17Sdinak 84*17Sdinak /* If there is nothing to write to the PKCS#12 file, leave. */ 85*17Sdinak if (cert == NULL && ca_certs == NULL && priv_key == NULL) { 86*17Sdinak cryptodebug("nothing to write to export file"); 87*17Sdinak return (0); 88*17Sdinak } 89*17Sdinak 90*17Sdinak /* 91*17Sdinak * Section 1: 92*17Sdinak * 93*17Sdinak * The first PKCS#12 container (safebag) will hold the certificates 94*17Sdinak * associated with this key. The result of this section is a 95*17Sdinak * PIN-encrypted PKCS#7 container (authsafe). If there are no 96*17Sdinak * certificates, there is no point in creating the "safebag" or the 97*17Sdinak * "authsafe" so we go to the next section. 98*17Sdinak */ 99*17Sdinak if (cert != NULL || ca_certs != NULL) { 100*17Sdinak /* Start a PKCS#12 safebag container for the certificates. */ 101*17Sdinak cryptodebug("creating certificate PKCS#12 safebag"); 102*17Sdinak bag_stack = sk_PKCS12_SAFEBAG_new_null(); 103*17Sdinak if (bag_stack == NULL) { 104*17Sdinak cryptoerror(LOG_STDERR, gettext( 105*17Sdinak "Unable to create PKCS#12 certificate bag.")); 106*17Sdinak (*failures)++; 107*17Sdinak return (-1); 108*17Sdinak } 109*17Sdinak 110*17Sdinak /* Add the cert corresponding to private key to bag_stack. */ 111*17Sdinak if (cert) { 112*17Sdinak /* Convert cert from X509 struct to PKCS#12 bag */ 113*17Sdinak cryptodebug("adding certificate to PKCS#12 safebag"); 114*17Sdinak bag = PKCS12_x5092certbag(cert); 115*17Sdinak if (bag == NULL) { 116*17Sdinak cryptoerror(LOG_STDERR, gettext( 117*17Sdinak "Unable to convert certificate to " 118*17Sdinak "PKCS#12 bag.")); 119*17Sdinak /* Cleanup the safebag. */ 120*17Sdinak sk_PKCS12_SAFEBAG_pop_free(bag_stack, 121*17Sdinak PKCS12_SAFEBAG_free); 122*17Sdinak (*failures)++; 123*17Sdinak return (-1); 124*17Sdinak } 125*17Sdinak 126*17Sdinak /* Add the key id to the certificate bag. */ 127*17Sdinak cryptodebug("add key id to PKCS#12 safebag"); 128*17Sdinak if (!PKCS12_add_localkeyid(bag, id, id_len)) 129*17Sdinak cryptodebug("error not caught"); 130*17Sdinak 131*17Sdinak /* Add the friendly name to the certificate bag. */ 132*17Sdinak if ((lab = X509_alias_get0(cert, &lab_len)) != NULL) { 133*17Sdinak cryptodebug( 134*17Sdinak "label PKCS#12 safebag with friendly name"); 135*17Sdinak if (!PKCS12_add_friendlyname(bag, (char *)lab, 136*17Sdinak lab_len)) 137*17Sdinak cryptodebug("error not caught"); 138*17Sdinak } 139*17Sdinak 140*17Sdinak /* Pile it on the bag_stack. */ 141*17Sdinak if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) 142*17Sdinak cryptodebug("error not caught"); 143*17Sdinak 144*17Sdinak n_writes++; 145*17Sdinak } 146*17Sdinak 147*17Sdinak /* Add all the CA chain certs to the bag_stack. */ 148*17Sdinak if (ca_certs) { 149*17Sdinak cryptodebug("adding CA certificate chain to PKCS#12 " 150*17Sdinak "safebag"); 151*17Sdinak /* 152*17Sdinak * Go through the stack of CA certs, converting each 153*17Sdinak * one to a PKCS#12 bag and piling them onto the 154*17Sdinak * bag_stack. 155*17Sdinak */ 156*17Sdinak for (i = 0; i < sk_X509_num(ca_certs); i++) { 157*17Sdinak /* 158*17Sdinak * sk_X509_value() is macro that embeds a 159*17Sdinak * cast to (X509 *). Here it translates 160*17Sdinak * into ((X509 *)sk_value((ca_certs), (i))). 161*17Sdinak * Lint is complaining about the embedded 162*17Sdinak * casting, and to fix it, you need to fix 163*17Sdinak * openssl header files. 164*17Sdinak */ 165*17Sdinak /* LINTED E_BAD_PTR_CAST_ALIGN */ 166*17Sdinak ca = sk_X509_value(ca_certs, i); 167*17Sdinak 168*17Sdinak /* Convert CA cert to PKCS#12 bag. */ 169*17Sdinak cryptodebug("adding CA certificate #%d " 170*17Sdinak "to PKCS#12 safebag", i+1); 171*17Sdinak bag = PKCS12_x5092certbag(ca); 172*17Sdinak if (bag == NULL) { 173*17Sdinak cryptoerror(LOG_STDERR, gettext( 174*17Sdinak "Unable to convert CA certificate " 175*17Sdinak "#%d to PKCS#12 bag."), i+1); 176*17Sdinak /* Cleanup the safebag. */ 177*17Sdinak sk_PKCS12_SAFEBAG_pop_free(bag_stack, 178*17Sdinak PKCS12_SAFEBAG_free); 179*17Sdinak (*failures)++; 180*17Sdinak return (-1); 181*17Sdinak } 182*17Sdinak 183*17Sdinak /* Note CA certs do not have friendly name. */ 184*17Sdinak 185*17Sdinak /* Pile it onto the bag_stack. */ 186*17Sdinak if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) 187*17Sdinak cryptodebug("error not caught"); 188*17Sdinak 189*17Sdinak n_writes++; 190*17Sdinak } 191*17Sdinak } 192*17Sdinak 193*17Sdinak /* Turn bag_stack of certs into encrypted authsafe. */ 194*17Sdinak cryptodebug("encrypt certificate PKCS#12 bag into " 195*17Sdinak "PKCS#7 authsafe"); 196*17Sdinak cert_authsafe = PKCS12_pack_p7encdata( 197*17Sdinak NID_pbe_WithSHA1And40BitRC2_CBC, (char *)pin, -1, NULL, 198*17Sdinak 0, PKCS12_DEFAULT_ITER, bag_stack); 199*17Sdinak 200*17Sdinak /* Clear away this bag_stack, we're done with it. */ 201*17Sdinak sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 202*17Sdinak bag_stack = NULL; 203*17Sdinak 204*17Sdinak if (cert_authsafe == NULL) { 205*17Sdinak cryptoerror(LOG_STDERR, gettext( 206*17Sdinak "Unable to PKCS#7-encrypt certificate bag.")); 207*17Sdinak (*failures)++; 208*17Sdinak return (-1); 209*17Sdinak } 210*17Sdinak } 211*17Sdinak 212*17Sdinak /* 213*17Sdinak * Section 2: 214*17Sdinak * 215*17Sdinak * The second PKCS#12 container (safebag) will hold the private key 216*17Sdinak * that goes with the certificates above. The results of this section 217*17Sdinak * is an unencrypted PKCS#7 container (authsafe). If there is no 218*17Sdinak * private key, there is no point in creating the "safebag" or the 219*17Sdinak * "authsafe" so we go to the next section. 220*17Sdinak */ 221*17Sdinak if (priv_key != NULL) { 222*17Sdinak /* Make a PKCS#8 shrouded key bag. */ 223*17Sdinak cryptodebug("create PKCS#8 shrouded key out of private key"); 224*17Sdinak p8 = EVP_PKEY2PKCS8(priv_key); 225*17Sdinak if (p8 == NULL) { 226*17Sdinak cryptoerror(LOG_STDERR, gettext( 227*17Sdinak "Unable to create PKCS#8 shrouded key for " 228*17Sdinak "private key.")); 229*17Sdinak (*failures)++; 230*17Sdinak return (-1); 231*17Sdinak } 232*17Sdinak 233*17Sdinak /* Put the shrouded key into a PKCS#12 bag. */ 234*17Sdinak cryptodebug("convert shrouded key to PKCS#12 bag"); 235*17Sdinak bag = PKCS12_MAKE_SHKEYBAG( 236*17Sdinak NID_pbe_WithSHA1And3_Key_TripleDES_CBC, (char *)pin, 237*17Sdinak -1, NULL, 0, PKCS12_DEFAULT_ITER, p8); 238*17Sdinak 239*17Sdinak /* Clean up the PKCS#8 shrouded key, don't need it now. */ 240*17Sdinak PKCS8_PRIV_KEY_INFO_free(p8); 241*17Sdinak p8 = NULL; 242*17Sdinak 243*17Sdinak if (bag == NULL) { 244*17Sdinak cryptoerror(LOG_STDERR, gettext( 245*17Sdinak "Unable to convert private key to PKCS#12 bag.")); 246*17Sdinak (*failures)++; 247*17Sdinak return (-1); 248*17Sdinak } 249*17Sdinak 250*17Sdinak /* Add the key id to the certificate bag. */ 251*17Sdinak cryptodebug("add key id to PKCS#12 safebag"); 252*17Sdinak if (!PKCS12_add_localkeyid(bag, id, id_len)) 253*17Sdinak cryptodebug("error not caught"); 254*17Sdinak 255*17Sdinak /* Add the cert friendly name to the private key bag. */ 256*17Sdinak if (lab != NULL) { 257*17Sdinak cryptodebug("label PKCS#12 safebag with friendly name"); 258*17Sdinak if (!PKCS12_add_friendlyname(bag, (char *)lab, lab_len)) 259*17Sdinak cryptodebug("error not caught"); 260*17Sdinak } 261*17Sdinak 262*17Sdinak /* Start a PKCS#12 safebag container for the private key. */ 263*17Sdinak cryptodebug("creating private key PKCS#12 safebag"); 264*17Sdinak bag_stack = sk_PKCS12_SAFEBAG_new_null(); 265*17Sdinak if (bag_stack == NULL) { 266*17Sdinak cryptoerror(LOG_STDERR, gettext( 267*17Sdinak "Unable to create PKCS#12 private key bag.")); 268*17Sdinak (*failures)++; 269*17Sdinak return (-1); 270*17Sdinak } 271*17Sdinak 272*17Sdinak /* Pile on the private key on the bag_stack. */ 273*17Sdinak if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) 274*17Sdinak cryptodebug("error not caught"); 275*17Sdinak 276*17Sdinak /* Turn bag_stack with private key into unencrypted authsafe. */ 277*17Sdinak cryptodebug("put private PKCS#12 bag into PKCS#7 authsafe"); 278*17Sdinak key_authsafe = PKCS12_pack_p7data(bag_stack); 279*17Sdinak 280*17Sdinak /* Clear away this bag_stack, we're done with it. */ 281*17Sdinak sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 282*17Sdinak bag_stack = NULL; 283*17Sdinak 284*17Sdinak if (key_authsafe == NULL) { 285*17Sdinak cryptoerror(LOG_STDERR, gettext( 286*17Sdinak "Unable to PKCS#7-convert private key bag.")); 287*17Sdinak (*failures)++; 288*17Sdinak return (-1); 289*17Sdinak } 290*17Sdinak 291*17Sdinak n_writes++; 292*17Sdinak } 293*17Sdinak 294*17Sdinak /* 295*17Sdinak * Section 3: 296*17Sdinak * 297*17Sdinak * This is where the two PKCS#7 containers, one for the certificates 298*17Sdinak * and one for the private key, are put together into a PKCS#12 299*17Sdinak * element. This final PKCS#12 element is written to the export file. 300*17Sdinak */ 301*17Sdinak /* Start a PKCS#7 stack. */ 302*17Sdinak cryptodebug("create PKCS#7 authsafe for private key and certificates"); 303*17Sdinak authsafe_stack = sk_PKCS7_new_null(); 304*17Sdinak if (authsafe_stack == NULL) { 305*17Sdinak cryptoerror(LOG_STDERR, gettext( 306*17Sdinak "Unable to create PKCS#7 container for private key " 307*17Sdinak "and certificates.")); 308*17Sdinak (*failures)++; 309*17Sdinak return (-1); 310*17Sdinak } 311*17Sdinak 312*17Sdinak /* Put certificates and private key into PKCS#7 stack. */ 313*17Sdinak if (key_authsafe != NULL) { 314*17Sdinak cryptodebug("put private key authsafe into PKCS#7 container"); 315*17Sdinak if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) 316*17Sdinak cryptodebug("error not caught"); 317*17Sdinak } 318*17Sdinak if (cert_authsafe != NULL) { 319*17Sdinak cryptodebug("put certificate authsafe into PKCS#7 container"); 320*17Sdinak if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) 321*17Sdinak cryptodebug("error not caught"); 322*17Sdinak } 323*17Sdinak 324*17Sdinak /* Create PKCS#12 element out of PKCS#7 stack. */ 325*17Sdinak cryptodebug("create PKCS#12 element for export file"); 326*17Sdinak p12_elem = PKCS12_init(NID_pkcs7_data); 327*17Sdinak if (p12_elem == NULL) { 328*17Sdinak cryptoerror(LOG_STDERR, gettext( 329*17Sdinak "Unable to create PKCS#12 element for export file.")); 330*17Sdinak sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 331*17Sdinak (*failures)++; 332*17Sdinak return (-1); 333*17Sdinak } 334*17Sdinak 335*17Sdinak /* Put the PKCS#7 stack into the PKCS#12 element. */ 336*17Sdinak if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) 337*17Sdinak cryptodebug("error not caught"); 338*17Sdinak 339*17Sdinak /* Clear away the PKCS#7 stack, we're done with it. */ 340*17Sdinak sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 341*17Sdinak authsafe_stack = NULL; 342*17Sdinak 343*17Sdinak /* Set the integrity MAC on the PKCS#12 element. */ 344*17Sdinak cryptodebug("setting MAC for PKCS#12 element"); 345*17Sdinak if (!PKCS12_set_mac(p12_elem, (char *)pin, -1, NULL, 0, 346*17Sdinak PKCS12_DEFAULT_ITER, NULL)) 347*17Sdinak cryptodebug("error not caught"); 348*17Sdinak 349*17Sdinak /* Write the PKCS#12 element to the export file. */ 350*17Sdinak cryptodebug("writing PKCS#12 element to export file"); 351*17Sdinak if (!i2d_PKCS12_bio(fbio, p12_elem)) 352*17Sdinak cryptodebug("error not caught"); 353*17Sdinak 354*17Sdinak (*successes) += n_writes; 355*17Sdinak 356*17Sdinak /* Clear away the PKCS#12 element. */ 357*17Sdinak PKCS12_free(p12_elem); 358*17Sdinak return (0); 359*17Sdinak } 360*17Sdinak 361*17Sdinak /* 362*17Sdinak * Get token objects: private key, its cert, and its cert chain. 363*17Sdinak */ 364*17Sdinak static CK_RV 365*17Sdinak get_token_objs(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, 366*17Sdinak CK_OBJECT_HANDLE *mate, CK_OBJECT_HANDLE_PTR *chain, 367*17Sdinak CK_ULONG *chain_len, CK_BYTE_PTR *id, CK_ULONG *id_len) 368*17Sdinak { 369*17Sdinak CK_RV rv = CKR_OK; 370*17Sdinak CK_ATTRIBUTE keyid_attr[1] = { 371*17Sdinak { CKA_ID, NULL, 0 } 372*17Sdinak }; 373*17Sdinak static CK_OBJECT_CLASS class = CKO_CERTIFICATE; 374*17Sdinak static CK_CERTIFICATE_TYPE certtype = CKC_X_509; 375*17Sdinak CK_ATTRIBUTE cert_attr[4] = { 376*17Sdinak { CKA_CLASS, &class, sizeof (CK_OBJECT_CLASS) }, 377*17Sdinak { CKA_CERTIFICATE_TYPE, &certtype, sizeof (certtype) }, 378*17Sdinak { CKA_TOKEN, &pk_true, sizeof (pk_true) }, 379*17Sdinak { CKA_ID, NULL, 0 } 380*17Sdinak }; 381*17Sdinak CK_ULONG num_attr = sizeof (cert_attr) / sizeof (CK_ATTRIBUTE); 382*17Sdinak CK_OBJECT_HANDLE cert = ~0UL; 383*17Sdinak CK_ULONG num = 0; 384*17Sdinak 385*17Sdinak cryptodebug("inside get_token_objs"); 386*17Sdinak 387*17Sdinak /* Get the size of the object's CKA_ID field first. */ 388*17Sdinak cryptodebug("getting CKA_ID size for object 0x%x", obj); 389*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, keyid_attr, 1)) != CKR_OK) { 390*17Sdinak cryptoerror(LOG_STDERR, gettext("Unable to get size of object" 391*17Sdinak " key id (%s)."), pkcs11_strerror(rv)); 392*17Sdinak return (rv); 393*17Sdinak } 394*17Sdinak 395*17Sdinak /* Allocate the space needed for the key id. */ 396*17Sdinak if ((keyid_attr[0].pValue = malloc(keyid_attr[0].ulValueLen)) == NULL) { 397*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 398*17Sdinak return (CKR_HOST_MEMORY); 399*17Sdinak } 400*17Sdinak 401*17Sdinak /* Get the CKA_ID field to match obj with its cert. */ 402*17Sdinak cryptodebug("getting CKA_ID attribute for object 0x%x", obj); 403*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, keyid_attr, 1)) != CKR_OK) { 404*17Sdinak cryptoerror(LOG_STDERR, gettext("Unable to get object " 405*17Sdinak "key id (%s)."), pkcs11_strerror(rv)); 406*17Sdinak free(keyid_attr[0].pValue); 407*17Sdinak return (rv); 408*17Sdinak } 409*17Sdinak 410*17Sdinak /* Now try to find any certs that have the same id. */ 411*17Sdinak cryptodebug("searching for certificates with same CKA_ID"); 412*17Sdinak cert_attr[3].pValue = keyid_attr[0].pValue; 413*17Sdinak cert_attr[3].ulValueLen = keyid_attr[0].ulValueLen; 414*17Sdinak if ((rv = C_FindObjectsInit(sess, cert_attr, num_attr)) != CKR_OK) { 415*17Sdinak cryptoerror(LOG_STDERR, gettext("Unable to initialize " 416*17Sdinak "certificate search (%s)."), pkcs11_strerror(rv)); 417*17Sdinak free(keyid_attr[0].pValue); 418*17Sdinak return (rv); 419*17Sdinak } 420*17Sdinak 421*17Sdinak /* Find the first cert that matches the key id. */ 422*17Sdinak if ((rv = C_FindObjects(sess, &cert, 1, &num)) != CKR_OK) { 423*17Sdinak cryptoerror(LOG_STDERR, gettext("Certificate search failed " 424*17Sdinak "(%s)."), pkcs11_strerror(rv)); 425*17Sdinak free(keyid_attr[0].pValue); 426*17Sdinak return (rv); 427*17Sdinak } 428*17Sdinak 429*17Sdinak (void) C_FindObjectsFinal(sess); 430*17Sdinak 431*17Sdinak *id = keyid_attr[0].pValue; 432*17Sdinak *id_len = keyid_attr[0].ulValueLen; 433*17Sdinak 434*17Sdinak *mate = (num == 1) ? cert : ~0UL; 435*17Sdinak 436*17Sdinak /* We currently do not find all the certs in the chain. */ 437*17Sdinak *chain_len = 0; 438*17Sdinak *chain = NULL; 439*17Sdinak 440*17Sdinak return (CKR_OK); 441*17Sdinak } 442*17Sdinak 443*17Sdinak /* 444*17Sdinak * Converts PKCS#11 biginteger_t format to OpenSSL BIGNUM. 445*17Sdinak * "to" should be the address of a ptr init'ed to NULL to 446*17Sdinak * receive the BIGNUM, e.g., 447*17Sdinak * biginteger_t from; 448*17Sdinak * BIGNUM *foo = NULL; 449*17Sdinak * cvt_bigint2bn(&from, &foo); 450*17Sdinak */ 451*17Sdinak static int 452*17Sdinak cvt_bigint2bn(biginteger_t *from, BIGNUM **to) 453*17Sdinak { 454*17Sdinak BIGNUM *temp = NULL; 455*17Sdinak 456*17Sdinak cryptodebug("inside cvt_bigint2bn"); 457*17Sdinak 458*17Sdinak if (from == NULL || to == NULL) 459*17Sdinak return (-1); 460*17Sdinak 461*17Sdinak cryptodebug("calling BN_bin2bn"); 462*17Sdinak if ((temp = BN_bin2bn(from->big_value, from->big_value_len, *to)) == 463*17Sdinak NULL) 464*17Sdinak return (-1); 465*17Sdinak 466*17Sdinak *to = temp; 467*17Sdinak return (0); 468*17Sdinak } 469*17Sdinak 470*17Sdinak /* 471*17Sdinak * Convert PKCS#11 RSA private key to OpenSSL EVP_PKEY structure. 472*17Sdinak */ 473*17Sdinak static CK_RV 474*17Sdinak cvt_rsa2evp_pkey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, EVP_PKEY **pk) 475*17Sdinak { 476*17Sdinak CK_RV rv = CKR_OK; 477*17Sdinak EVP_PKEY *key = NULL; /* OpenSSL representation */ 478*17Sdinak RSA *rsa = NULL; /* OpenSSL representation */ 479*17Sdinak biginteger_t mod = { NULL, 0 }; /* required */ 480*17Sdinak biginteger_t pubexp = { NULL, 0 }; /* required */ 481*17Sdinak biginteger_t priexp = { NULL, 0 }; /* optional */ 482*17Sdinak biginteger_t prime1 = { NULL, 0 }; /* optional */ 483*17Sdinak biginteger_t prime2 = { NULL, 0 }; /* optional */ 484*17Sdinak biginteger_t exp1 = { NULL, 0 }; /* optional */ 485*17Sdinak biginteger_t exp2 = { NULL, 0 }; /* optional */ 486*17Sdinak biginteger_t coef = { NULL, 0 }; /* optional */ 487*17Sdinak CK_ATTRIBUTE rsa_pri_attrs[8] = { 488*17Sdinak { CKA_MODULUS, NULL, 0 }, 489*17Sdinak { CKA_PUBLIC_EXPONENT, NULL, 0 }, 490*17Sdinak { CKA_PRIVATE_EXPONENT, NULL, 0 }, /* optional */ 491*17Sdinak { CKA_PRIME_1, NULL, 0 }, /* | */ 492*17Sdinak { CKA_PRIME_2, NULL, 0 }, /* | */ 493*17Sdinak { CKA_EXPONENT_1, NULL, 0 }, /* | */ 494*17Sdinak { CKA_EXPONENT_2, NULL, 0 }, /* | */ 495*17Sdinak { CKA_COEFFICIENT, NULL, 0 } /* V */ 496*17Sdinak }; 497*17Sdinak CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE); 498*17Sdinak int i; 499*17Sdinak 500*17Sdinak cryptodebug("inside cvt_rsa2evp_pkey"); 501*17Sdinak 502*17Sdinak cryptodebug("calling RSA_new"); 503*17Sdinak if ((rsa = RSA_new()) == NULL) { 504*17Sdinak cryptoerror(LOG_STDERR, gettext( 505*17Sdinak "Unable to allocate internal RSA structure.")); 506*17Sdinak return (CKR_HOST_MEMORY); 507*17Sdinak } 508*17Sdinak 509*17Sdinak /* Get the sizes of the attributes we need. */ 510*17Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 511*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, rsa_pri_attrs, count)) != 512*17Sdinak CKR_OK) { 513*17Sdinak cryptoerror(LOG_STDERR, gettext( 514*17Sdinak "Unable to get RSA private key attribute sizes (%s)."), 515*17Sdinak pkcs11_strerror(rv)); 516*17Sdinak return (rv); 517*17Sdinak } 518*17Sdinak 519*17Sdinak /* Allocate memory for each attribute. */ 520*17Sdinak for (i = 0; i < count; i++) { 521*17Sdinak if (rsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 || 522*17Sdinak rsa_pri_attrs[i].ulValueLen == 0) { 523*17Sdinak cryptodebug("cvt_rsa2evp_pkey: *** should not happen"); 524*17Sdinak rsa_pri_attrs[i].ulValueLen = 0; 525*17Sdinak continue; 526*17Sdinak } 527*17Sdinak if ((rsa_pri_attrs[i].pValue = 528*17Sdinak malloc(rsa_pri_attrs[i].ulValueLen)) == NULL) { 529*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 530*17Sdinak return (CKR_HOST_MEMORY); 531*17Sdinak } 532*17Sdinak } 533*17Sdinak 534*17Sdinak /* Now really get the attributes. */ 535*17Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 536*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, rsa_pri_attrs, count)) != 537*17Sdinak CKR_OK) { 538*17Sdinak cryptoerror(LOG_STDERR, gettext( 539*17Sdinak "Unable to get RSA private key attributes (%s)."), 540*17Sdinak pkcs11_strerror(rv)); 541*17Sdinak return (rv); 542*17Sdinak } 543*17Sdinak 544*17Sdinak /* 545*17Sdinak * Fill in all the temp variables. Modulus and public exponent 546*17Sdinak * are required. The rest are optional. 547*17Sdinak */ 548*17Sdinak i = 0; 549*17Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i++]), &mod); 550*17Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i++]), &pubexp); 551*17Sdinak 552*17Sdinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 553*17Sdinak rsa_pri_attrs[i].ulValueLen != 0) 554*17Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &priexp); 555*17Sdinak i++; 556*17Sdinak 557*17Sdinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 558*17Sdinak rsa_pri_attrs[i].ulValueLen != 0) 559*17Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &prime1); 560*17Sdinak i++; 561*17Sdinak 562*17Sdinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 563*17Sdinak rsa_pri_attrs[i].ulValueLen != 0) 564*17Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &prime2); 565*17Sdinak i++; 566*17Sdinak 567*17Sdinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 568*17Sdinak rsa_pri_attrs[i].ulValueLen != 0) 569*17Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &exp1); 570*17Sdinak i++; 571*17Sdinak 572*17Sdinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 573*17Sdinak rsa_pri_attrs[i].ulValueLen != 0) 574*17Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &exp2); 575*17Sdinak i++; 576*17Sdinak 577*17Sdinak if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 578*17Sdinak rsa_pri_attrs[i].ulValueLen != 0) 579*17Sdinak copy_attr_to_bigint(&(rsa_pri_attrs[i]), &coef); 580*17Sdinak i++; 581*17Sdinak 582*17Sdinak /* Start the conversion to internal OpenSSL RSA structure. */ 583*17Sdinak 584*17Sdinak /* Modulus n */ 585*17Sdinak if (cvt_bigint2bn(&mod, &(rsa->n)) < 0) { 586*17Sdinak cryptoerror(LOG_STDERR, gettext( 587*17Sdinak "Unable to convert RSA private key modulus.")); 588*17Sdinak return (CKR_GENERAL_ERROR); 589*17Sdinak } 590*17Sdinak 591*17Sdinak /* Public exponent e */ 592*17Sdinak if (cvt_bigint2bn(&pubexp, &(rsa->e)) < 0) { 593*17Sdinak cryptoerror(LOG_STDERR, gettext( 594*17Sdinak "Unable to convert RSA private key public exponent.")); 595*17Sdinak return (CKR_GENERAL_ERROR); 596*17Sdinak } 597*17Sdinak 598*17Sdinak /* Private exponent e */ 599*17Sdinak if (priexp.big_value != NULL) { 600*17Sdinak if (cvt_bigint2bn(&priexp, &(rsa->d)) < 0) { 601*17Sdinak cryptoerror(LOG_STDERR, gettext("Unable to convert " 602*17Sdinak "RSA private key private exponent.")); 603*17Sdinak return (CKR_GENERAL_ERROR); 604*17Sdinak } 605*17Sdinak } else 606*17Sdinak cryptodebug("no RSA private key private exponent"); 607*17Sdinak 608*17Sdinak /* Prime p */ 609*17Sdinak if (prime1.big_value != NULL) { 610*17Sdinak if (cvt_bigint2bn(&prime1, &(rsa->p)) < 0) { 611*17Sdinak cryptoerror(LOG_STDERR, gettext( 612*17Sdinak "Unable to convert RSA private key prime 1.")); 613*17Sdinak return (CKR_GENERAL_ERROR); 614*17Sdinak } 615*17Sdinak } else 616*17Sdinak cryptodebug("no RSA private key prime 1"); 617*17Sdinak 618*17Sdinak /* Prime q */ 619*17Sdinak if (prime2.big_value != NULL) { 620*17Sdinak if (cvt_bigint2bn(&prime2, &(rsa->q)) < 0) { 621*17Sdinak cryptoerror(LOG_STDERR, gettext( 622*17Sdinak "Unable to convert RSA private key prime 2.")); 623*17Sdinak return (CKR_GENERAL_ERROR); 624*17Sdinak } 625*17Sdinak } else 626*17Sdinak cryptodebug("no RSA private key prime 2"); 627*17Sdinak 628*17Sdinak /* Private exponent d modulo p-1 */ 629*17Sdinak if (exp1.big_value != NULL) { 630*17Sdinak if (cvt_bigint2bn(&exp1, &(rsa->dmp1)) < 0) { 631*17Sdinak cryptoerror(LOG_STDERR, gettext( 632*17Sdinak "Unable to convert RSA private key exponent 1.")); 633*17Sdinak return (CKR_GENERAL_ERROR); 634*17Sdinak } 635*17Sdinak } else 636*17Sdinak cryptodebug("no RSA private key exponent 1"); 637*17Sdinak 638*17Sdinak /* Private exponent d modulo q-1 */ 639*17Sdinak if (exp2.big_value != NULL) { 640*17Sdinak if (cvt_bigint2bn(&exp2, &(rsa->dmq1)) < 0) { 641*17Sdinak cryptoerror(LOG_STDERR, gettext( 642*17Sdinak "Unable to convert RSA private key exponent 2.")); 643*17Sdinak return (CKR_GENERAL_ERROR); 644*17Sdinak } 645*17Sdinak } else 646*17Sdinak cryptodebug("no RSA private key exponent 2"); 647*17Sdinak 648*17Sdinak /* CRT coefficient q-inverse mod p */ 649*17Sdinak if (coef.big_value != NULL) { 650*17Sdinak if (cvt_bigint2bn(&coef, &(rsa->iqmp)) < 0) { 651*17Sdinak cryptoerror(LOG_STDERR, gettext( 652*17Sdinak "Unable to convert RSA private key coefficient.")); 653*17Sdinak return (CKR_GENERAL_ERROR); 654*17Sdinak } 655*17Sdinak } else 656*17Sdinak cryptodebug("no RSA private key coefficient"); 657*17Sdinak 658*17Sdinak /* Create OpenSSL EVP_PKEY struct in which to stuff RSA struct. */ 659*17Sdinak cryptodebug("calling EVP_PKEY_new"); 660*17Sdinak if ((key = EVP_PKEY_new()) == NULL) { 661*17Sdinak cryptoerror(LOG_STDERR, gettext( 662*17Sdinak "Unable to allocate internal EVP_PKEY structure.")); 663*17Sdinak return (CKR_HOST_MEMORY); 664*17Sdinak } 665*17Sdinak 666*17Sdinak /* Put the RSA struct into the EVP_PKEY struct and return it. */ 667*17Sdinak cryptodebug("calling EVP_PKEY_set1_RSA"); 668*17Sdinak (void) EVP_PKEY_set1_RSA(key, rsa); 669*17Sdinak 670*17Sdinak *pk = key; 671*17Sdinak return (CKR_OK); 672*17Sdinak } 673*17Sdinak 674*17Sdinak /* 675*17Sdinak * Convert PKCS#11 DSA private key to OpenSSL EVP_PKEY structure. 676*17Sdinak */ 677*17Sdinak static CK_RV 678*17Sdinak cvt_dsa2evp_pkey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, EVP_PKEY **pk) 679*17Sdinak { 680*17Sdinak CK_RV rv = CKR_OK; 681*17Sdinak EVP_PKEY *key = NULL; /* OpenSSL representation */ 682*17Sdinak DSA *dsa = NULL; /* OpenSSL representation */ 683*17Sdinak biginteger_t prime = { NULL, 0 }; /* required */ 684*17Sdinak biginteger_t subprime = { NULL, 0 }; /* required */ 685*17Sdinak biginteger_t base = { NULL, 0 }; /* required */ 686*17Sdinak biginteger_t value = { NULL, 0 }; /* required */ 687*17Sdinak CK_ATTRIBUTE dsa_pri_attrs[4] = { 688*17Sdinak { CKA_PRIME, NULL, 0 }, 689*17Sdinak { CKA_SUBPRIME, NULL, 0 }, 690*17Sdinak { CKA_BASE, NULL, 0 }, 691*17Sdinak { CKA_VALUE, NULL, 0 } 692*17Sdinak }; 693*17Sdinak CK_ULONG count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE); 694*17Sdinak int i; 695*17Sdinak 696*17Sdinak cryptodebug("inside cvt_dsa2evp_pkey"); 697*17Sdinak 698*17Sdinak cryptodebug("calling DSA_new"); 699*17Sdinak if ((dsa = DSA_new()) == NULL) { 700*17Sdinak cryptoerror(LOG_STDERR, gettext( 701*17Sdinak "Unable to allocate internal DSA structure.")); 702*17Sdinak return (CKR_HOST_MEMORY); 703*17Sdinak } 704*17Sdinak 705*17Sdinak /* Get the sizes of the attributes we need. */ 706*17Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 707*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, dsa_pri_attrs, count)) != 708*17Sdinak CKR_OK) { 709*17Sdinak cryptoerror(LOG_STDERR, gettext( 710*17Sdinak "Unable to get DSA private key object attributes (%s)."), 711*17Sdinak pkcs11_strerror(rv)); 712*17Sdinak return (rv); 713*17Sdinak } 714*17Sdinak 715*17Sdinak /* Allocate memory for each attribute. */ 716*17Sdinak for (i = 0; i < count; i++) { 717*17Sdinak if (dsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 || 718*17Sdinak dsa_pri_attrs[i].ulValueLen == 0) { 719*17Sdinak cryptodebug("cvt_dsa2evp_pkey: *** should not happen"); 720*17Sdinak dsa_pri_attrs[i].ulValueLen = 0; 721*17Sdinak continue; 722*17Sdinak } 723*17Sdinak if ((dsa_pri_attrs[i].pValue = 724*17Sdinak malloc(dsa_pri_attrs[i].ulValueLen)) == NULL) { 725*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 726*17Sdinak return (CKR_HOST_MEMORY); 727*17Sdinak } 728*17Sdinak } 729*17Sdinak 730*17Sdinak /* Now really get the attributes. */ 731*17Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 732*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, dsa_pri_attrs, count)) != 733*17Sdinak CKR_OK) { 734*17Sdinak cryptoerror(LOG_STDERR, gettext( 735*17Sdinak "Unable to get DSA private key attributes (%s)."), 736*17Sdinak pkcs11_strerror(rv)); 737*17Sdinak return (rv); 738*17Sdinak } 739*17Sdinak 740*17Sdinak /* Fill in all the temp variables. They are all required. */ 741*17Sdinak i = 0; 742*17Sdinak copy_attr_to_bigint(&(dsa_pri_attrs[i++]), &prime); 743*17Sdinak copy_attr_to_bigint(&(dsa_pri_attrs[i++]), &subprime); 744*17Sdinak copy_attr_to_bigint(&(dsa_pri_attrs[i++]), &base); 745*17Sdinak copy_attr_to_bigint(&(dsa_pri_attrs[i++]), &value); 746*17Sdinak 747*17Sdinak /* Start the conversion to internal OpenSSL DSA structure. */ 748*17Sdinak 749*17Sdinak /* Prime p */ 750*17Sdinak if (cvt_bigint2bn(&prime, &(dsa->p)) < 0) { 751*17Sdinak cryptoerror(LOG_STDERR, gettext( 752*17Sdinak "Unable to convert DSA private key prime.")); 753*17Sdinak return (CKR_GENERAL_ERROR); 754*17Sdinak } 755*17Sdinak 756*17Sdinak /* Subprime q */ 757*17Sdinak if (cvt_bigint2bn(&subprime, &(dsa->q)) < 0) { 758*17Sdinak cryptoerror(LOG_STDERR, gettext( 759*17Sdinak "Unable to convert DSA private key subprime.")); 760*17Sdinak return (CKR_GENERAL_ERROR); 761*17Sdinak } 762*17Sdinak 763*17Sdinak /* Base g */ 764*17Sdinak if (cvt_bigint2bn(&base, &(dsa->g)) < 0) { 765*17Sdinak cryptoerror(LOG_STDERR, gettext( 766*17Sdinak "Unable to convert DSA private key base.")); 767*17Sdinak return (CKR_GENERAL_ERROR); 768*17Sdinak } 769*17Sdinak 770*17Sdinak /* Private key x */ 771*17Sdinak if (cvt_bigint2bn(&value, &(dsa->priv_key)) < 0) { 772*17Sdinak cryptoerror(LOG_STDERR, gettext( 773*17Sdinak "Unable to convert DSA private key value.")); 774*17Sdinak return (CKR_GENERAL_ERROR); 775*17Sdinak } 776*17Sdinak 777*17Sdinak /* Create OpenSSL EVP PKEY struct in which to stuff DSA struct. */ 778*17Sdinak cryptodebug("calling EVP_PKEY_new"); 779*17Sdinak if ((key = EVP_PKEY_new()) == NULL) { 780*17Sdinak cryptoerror(LOG_STDERR, gettext( 781*17Sdinak "Unable to allocate internal EVP_PKEY structure.")); 782*17Sdinak return (CKR_HOST_MEMORY); 783*17Sdinak } 784*17Sdinak 785*17Sdinak /* Put the DSA struct into the EVP_PKEY struct and return it. */ 786*17Sdinak cryptodebug("calling EVP_PKEY_set1_DSA"); 787*17Sdinak (void) EVP_PKEY_set1_DSA(key, dsa); 788*17Sdinak 789*17Sdinak *pk = key; 790*17Sdinak return (CKR_OK); 791*17Sdinak } 792*17Sdinak 793*17Sdinak /* 794*17Sdinak * Convert PKCS#11 DH private key to OpenSSL EVP_PKEY structure. 795*17Sdinak */ 796*17Sdinak static CK_RV 797*17Sdinak cvt_dh2evp_pkey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, EVP_PKEY **pk) 798*17Sdinak { 799*17Sdinak CK_RV rv = CKR_OK; 800*17Sdinak EVP_PKEY *key = NULL; /* OpenSSL representation */ 801*17Sdinak DH *dh = NULL; /* OpenSSL representation */ 802*17Sdinak biginteger_t prime = { NULL, 0 }; /* required */ 803*17Sdinak biginteger_t base = { NULL, 0 }; /* required */ 804*17Sdinak biginteger_t value = { NULL, 0 }; /* required */ 805*17Sdinak CK_ATTRIBUTE dh_pri_attrs[3] = { 806*17Sdinak { CKA_PRIME, NULL, 0 }, 807*17Sdinak { CKA_BASE, NULL, 0 }, 808*17Sdinak { CKA_VALUE, NULL, 0 } 809*17Sdinak }; 810*17Sdinak CK_ULONG count = sizeof (dh_pri_attrs) / sizeof (CK_ATTRIBUTE); 811*17Sdinak int i; 812*17Sdinak 813*17Sdinak cryptodebug("inside cvt_dh2evp_pkey"); 814*17Sdinak 815*17Sdinak cryptodebug("calling DH_new"); 816*17Sdinak if ((dh = DH_new()) == NULL) { 817*17Sdinak cryptoerror(LOG_STDERR, gettext( 818*17Sdinak "Unable to allocate internal DH structure.")); 819*17Sdinak return (CKR_HOST_MEMORY); 820*17Sdinak } 821*17Sdinak 822*17Sdinak /* Get the sizes of the attributes we need. */ 823*17Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 824*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, dh_pri_attrs, count)) != 825*17Sdinak CKR_OK) { 826*17Sdinak cryptoerror(LOG_STDERR, gettext( 827*17Sdinak "Unable to get DH private key object attributes (%s)."), 828*17Sdinak pkcs11_strerror(rv)); 829*17Sdinak return (rv); 830*17Sdinak } 831*17Sdinak 832*17Sdinak /* Allocate memory for each attribute. */ 833*17Sdinak for (i = 0; i < count; i++) { 834*17Sdinak if (dh_pri_attrs[i].ulValueLen == (CK_ULONG)-1 || 835*17Sdinak dh_pri_attrs[i].ulValueLen == 0) { 836*17Sdinak cryptodebug("cvt_dh2evp_pkey: ***should not happen"); 837*17Sdinak dh_pri_attrs[i].ulValueLen = 0; 838*17Sdinak continue; 839*17Sdinak } 840*17Sdinak if ((dh_pri_attrs[i].pValue = 841*17Sdinak malloc(dh_pri_attrs[i].ulValueLen)) == NULL) { 842*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 843*17Sdinak return (CKR_HOST_MEMORY); 844*17Sdinak } 845*17Sdinak } 846*17Sdinak 847*17Sdinak /* Now really get the attributes. */ 848*17Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 849*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, dh_pri_attrs, count)) != 850*17Sdinak CKR_OK) { 851*17Sdinak cryptoerror(LOG_STDERR, gettext( 852*17Sdinak "Unable to get DH private key attributes (%s)."), 853*17Sdinak pkcs11_strerror(rv)); 854*17Sdinak return (rv); 855*17Sdinak } 856*17Sdinak 857*17Sdinak /* Fill in all the temp variables. They are all required. */ 858*17Sdinak i = 0; 859*17Sdinak copy_attr_to_bigint(&(dh_pri_attrs[i++]), &prime); 860*17Sdinak copy_attr_to_bigint(&(dh_pri_attrs[i++]), &base); 861*17Sdinak copy_attr_to_bigint(&(dh_pri_attrs[i++]), &value); 862*17Sdinak 863*17Sdinak /* Start the conversion to internal OpenSSL DH structure. */ 864*17Sdinak 865*17Sdinak /* Prime p */ 866*17Sdinak if (cvt_bigint2bn(&prime, &(dh->p)) < 0) { 867*17Sdinak cryptoerror(LOG_STDERR, gettext( 868*17Sdinak "Unable to convert DH private key prime.")); 869*17Sdinak return (CKR_GENERAL_ERROR); 870*17Sdinak } 871*17Sdinak 872*17Sdinak /* Base g */ 873*17Sdinak if (cvt_bigint2bn(&base, &(dh->g)) < 0) { 874*17Sdinak cryptoerror(LOG_STDERR, gettext( 875*17Sdinak "Unable to convert DH private key base.")); 876*17Sdinak return (CKR_GENERAL_ERROR); 877*17Sdinak } 878*17Sdinak 879*17Sdinak /* Private value x */ 880*17Sdinak if (cvt_bigint2bn(&value, &(dh->priv_key)) < 0) { 881*17Sdinak cryptoerror(LOG_STDERR, gettext( 882*17Sdinak "Unable to convert DH private key value.")); 883*17Sdinak return (CKR_GENERAL_ERROR); 884*17Sdinak } 885*17Sdinak 886*17Sdinak /* Create OpenSSL EVP PKEY struct in which to stuff DH struct. */ 887*17Sdinak cryptodebug("calling EVP_PKEY_new"); 888*17Sdinak if ((key = EVP_PKEY_new()) == NULL) { 889*17Sdinak cryptoerror(LOG_STDERR, gettext( 890*17Sdinak "Unable to allocate internal EVP_PKEY structure.")); 891*17Sdinak return (CKR_HOST_MEMORY); 892*17Sdinak } 893*17Sdinak 894*17Sdinak /* Put the DH struct into the EVP_PKEY struct and return it. */ 895*17Sdinak cryptodebug("calling EVP_PKEY_set1_DH"); 896*17Sdinak (void) EVP_PKEY_set1_DH(key, dh); 897*17Sdinak 898*17Sdinak *pk = key; 899*17Sdinak return (CKR_OK); 900*17Sdinak } 901*17Sdinak 902*17Sdinak /* 903*17Sdinak * Convert PKCS#11 private key object to OpenSSL EVP_PKEY structure. 904*17Sdinak */ 905*17Sdinak static CK_RV 906*17Sdinak cvt_obj2evp_pkey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, EVP_PKEY **pk) 907*17Sdinak { 908*17Sdinak CK_RV rv = CKR_OK; 909*17Sdinak static CK_KEY_TYPE keytype = 0; 910*17Sdinak CK_ATTRIBUTE keytype_attr[1] = { 911*17Sdinak { CKA_KEY_TYPE, &keytype, sizeof (keytype) } 912*17Sdinak }; 913*17Sdinak 914*17Sdinak cryptodebug("inside cvt_obj2evp_pkey"); 915*17Sdinak 916*17Sdinak /* Find out the key type to do the right conversion. */ 917*17Sdinak cryptodebug("calling C_GetAttributeValue"); 918*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, keytype_attr, 1)) != 919*17Sdinak CKR_OK) { 920*17Sdinak cryptoerror(LOG_STDERR, gettext( 921*17Sdinak "Unable to get token object key type (%s)."), 922*17Sdinak pkcs11_strerror(rv)); 923*17Sdinak return (rv); 924*17Sdinak } 925*17Sdinak 926*17Sdinak switch (keytype) { 927*17Sdinak case CKK_RSA: 928*17Sdinak cryptodebug("converting RSA key"); 929*17Sdinak return (cvt_rsa2evp_pkey(sess, obj, pk)); 930*17Sdinak case CKK_DSA: 931*17Sdinak cryptodebug("converting DSA key"); 932*17Sdinak return (cvt_dsa2evp_pkey(sess, obj, pk)); 933*17Sdinak case CKK_DH: 934*17Sdinak cryptodebug("converting DH key"); 935*17Sdinak return (cvt_dh2evp_pkey(sess, obj, pk)); 936*17Sdinak default: 937*17Sdinak cryptoerror(LOG_STDERR, gettext( 938*17Sdinak "Private key type 0x%02x conversion not supported."), 939*17Sdinak keytype); 940*17Sdinak return (CKR_GENERAL_ERROR); 941*17Sdinak } 942*17Sdinak } 943*17Sdinak 944*17Sdinak /* 945*17Sdinak * Convert PKCS#11 certificate object to OpenSSL X509 structure. 946*17Sdinak */ 947*17Sdinak static CK_RV 948*17Sdinak cvt_cert2x509(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, X509 **c) 949*17Sdinak { 950*17Sdinak CK_RV rv = CKR_OK; 951*17Sdinak X509 *cert = NULL; /* OpenSSL representation */ 952*17Sdinak X509 *temp_cert = NULL; 953*17Sdinak CK_BYTE *subject = NULL; 954*17Sdinak CK_ULONG subject_len = 0; 955*17Sdinak CK_BYTE *value = NULL; 956*17Sdinak CK_ULONG value_len = 0; 957*17Sdinak CK_BYTE *label = NULL; 958*17Sdinak CK_ULONG label_len = 0; 959*17Sdinak CK_BYTE *id = NULL; 960*17Sdinak CK_ULONG id_len = 0; 961*17Sdinak CK_BYTE *issuer = NULL; 962*17Sdinak CK_ULONG issuer_len = 0; 963*17Sdinak CK_BYTE *serial = NULL; 964*17Sdinak CK_ULONG serial_len = 0; 965*17Sdinak CK_ATTRIBUTE cert_attrs[6] = { 966*17Sdinak { CKA_SUBJECT, NULL, 0 }, /* required */ 967*17Sdinak { CKA_VALUE, NULL, 0 }, /* required */ 968*17Sdinak { CKA_LABEL, NULL, 0 }, /* optional */ 969*17Sdinak { CKA_ID, NULL, 0 }, /* optional */ 970*17Sdinak { CKA_ISSUER, NULL, 0 }, /* optional */ 971*17Sdinak { CKA_SERIAL_NUMBER, NULL, 0 } /* optional */ 972*17Sdinak }; 973*17Sdinak CK_ULONG count = sizeof (cert_attrs) / sizeof (CK_ATTRIBUTE); 974*17Sdinak int i = 0; 975*17Sdinak X509_NAME *ssl_subject = NULL; 976*17Sdinak X509_NAME *ssl_issuer = NULL; 977*17Sdinak ASN1_INTEGER *ssl_serial = NULL; 978*17Sdinak 979*17Sdinak cryptodebug("inside cvt_cert2x509"); 980*17Sdinak 981*17Sdinak cryptodebug("calling X509_new"); 982*17Sdinak if ((cert = X509_new()) == NULL) { 983*17Sdinak cryptoerror(LOG_STDERR, gettext( 984*17Sdinak "Unable to allocate internal X509 structure.")); 985*17Sdinak return (CKR_HOST_MEMORY); 986*17Sdinak } 987*17Sdinak 988*17Sdinak /* Get the sizes of the attributes we need. */ 989*17Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 990*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, cert_attrs, count)) != 991*17Sdinak CKR_OK) { 992*17Sdinak cryptoerror(LOG_STDERR, gettext( 993*17Sdinak "Unable to get certificate attribute sizes (%s)."), 994*17Sdinak pkcs11_strerror(rv)); 995*17Sdinak return (rv); 996*17Sdinak } 997*17Sdinak 998*17Sdinak /* Allocate memory for each attribute. */ 999*17Sdinak for (i = 0; i < count; i++) { 1000*17Sdinak if (cert_attrs[i].ulValueLen == (CK_ULONG)-1 || 1001*17Sdinak cert_attrs[i].ulValueLen == 0) { 1002*17Sdinak cryptodebug("cvt_cert2x509: *** should not happen"); 1003*17Sdinak cert_attrs[i].ulValueLen = 0; 1004*17Sdinak continue; 1005*17Sdinak } 1006*17Sdinak if ((cert_attrs[i].pValue = malloc(cert_attrs[i].ulValueLen)) 1007*17Sdinak == NULL) { 1008*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 1009*17Sdinak return (CKR_HOST_MEMORY); 1010*17Sdinak } 1011*17Sdinak } 1012*17Sdinak 1013*17Sdinak /* Now really get the attributes. */ 1014*17Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 1015*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, cert_attrs, count)) != 1016*17Sdinak CKR_OK) { 1017*17Sdinak cryptoerror(LOG_STDERR, gettext( 1018*17Sdinak "Unable to get certificate attributes (%s)."), 1019*17Sdinak pkcs11_strerror(rv)); 1020*17Sdinak return (rv); 1021*17Sdinak } 1022*17Sdinak 1023*17Sdinak /* 1024*17Sdinak * Fill in all the temp variables. Subject and value are required. 1025*17Sdinak * The rest are optional. 1026*17Sdinak */ 1027*17Sdinak i = 0; 1028*17Sdinak copy_attr_to_string(&(cert_attrs[i++]), &subject, &subject_len); 1029*17Sdinak copy_attr_to_string(&(cert_attrs[i++]), &value, &value_len); 1030*17Sdinak 1031*17Sdinak if (cert_attrs[i].ulValueLen != (CK_ULONG)-1 && 1032*17Sdinak cert_attrs[i].ulValueLen != 0) 1033*17Sdinak copy_attr_to_string(&(cert_attrs[i]), &label, &label_len); 1034*17Sdinak i++; 1035*17Sdinak 1036*17Sdinak if (cert_attrs[i].ulValueLen != (CK_ULONG)-1 && 1037*17Sdinak cert_attrs[i].ulValueLen != 0) 1038*17Sdinak copy_attr_to_string(&(cert_attrs[i]), &id, &id_len); 1039*17Sdinak i++; 1040*17Sdinak 1041*17Sdinak if (cert_attrs[i].ulValueLen != (CK_ULONG)-1 && 1042*17Sdinak cert_attrs[i].ulValueLen != 0) 1043*17Sdinak copy_attr_to_string(&(cert_attrs[i]), &issuer, &issuer_len); 1044*17Sdinak i++; 1045*17Sdinak 1046*17Sdinak if (cert_attrs[i].ulValueLen != (CK_ULONG)-1 && 1047*17Sdinak cert_attrs[i].ulValueLen != 0) 1048*17Sdinak copy_attr_to_string(&(cert_attrs[i]), &serial, &serial_len); 1049*17Sdinak i++; 1050*17Sdinak 1051*17Sdinak /* Start the conversion to internal OpenSSL X509 structure. */ 1052*17Sdinak 1053*17Sdinak /* Subject name (required) */ 1054*17Sdinak cryptodebug("calling d2i_X509_NAME for subject name"); 1055*17Sdinak if ((ssl_subject = d2i_X509_NAME(NULL, &subject, subject_len)) == 1056*17Sdinak NULL) { 1057*17Sdinak cryptoerror(LOG_STDERR, gettext( 1058*17Sdinak "Unable to convert certificate subject name.")); 1059*17Sdinak return (CKR_GENERAL_ERROR); 1060*17Sdinak } 1061*17Sdinak cryptodebug("calling X509_set_subject_name"); 1062*17Sdinak if (!X509_set_subject_name(cert, ssl_subject)) { 1063*17Sdinak cryptoerror(LOG_STDERR, gettext( 1064*17Sdinak "Unable to pack certificate subject name entries.")); 1065*17Sdinak return (CKR_GENERAL_ERROR); 1066*17Sdinak } 1067*17Sdinak 1068*17Sdinak /* Label (optional) */ 1069*17Sdinak cryptodebug("calling X509_alias_set1"); 1070*17Sdinak if (!X509_alias_set1(cert, label, label_len)) 1071*17Sdinak cryptodebug("error not caught"); 1072*17Sdinak 1073*17Sdinak /* Id (optional) */ 1074*17Sdinak cryptodebug("calling X509_keyid_set1"); 1075*17Sdinak if (!X509_keyid_set1(cert, id, id_len)) 1076*17Sdinak cryptodebug("error not caught"); 1077*17Sdinak 1078*17Sdinak /* Issuer name (optional) */ 1079*17Sdinak cryptodebug("calling d2i_X509_NAME for issuer name"); 1080*17Sdinak if ((ssl_issuer = d2i_X509_NAME(NULL, &issuer, issuer_len)) == NULL) { 1081*17Sdinak cryptoerror(LOG_STDERR, gettext( 1082*17Sdinak "Unable to convert certificate issuer name.")); 1083*17Sdinak return (CKR_GENERAL_ERROR); 1084*17Sdinak } 1085*17Sdinak cryptodebug("calling X509_set_issuer_name"); 1086*17Sdinak if (!X509_set_issuer_name(cert, ssl_issuer)) { 1087*17Sdinak cryptoerror(LOG_STDERR, gettext( 1088*17Sdinak "Unable to pack certificate issuer name entries.")); 1089*17Sdinak return (CKR_GENERAL_ERROR); 1090*17Sdinak } 1091*17Sdinak 1092*17Sdinak /* Serial number (optional) */ 1093*17Sdinak cryptodebug("calling c2i_ASN1_INTEGER for serial number"); 1094*17Sdinak if ((ssl_serial = c2i_ASN1_INTEGER(NULL, &serial, serial_len)) == 1095*17Sdinak NULL) { 1096*17Sdinak cryptoerror(LOG_STDERR, gettext( 1097*17Sdinak "Unable to convert certificate serial number.")); 1098*17Sdinak return (CKR_GENERAL_ERROR); 1099*17Sdinak } 1100*17Sdinak cryptodebug("calling X509_set_serialNumber"); 1101*17Sdinak if (!X509_set_serialNumber(cert, ssl_serial)) 1102*17Sdinak cryptodebug("error not caught"); 1103*17Sdinak 1104*17Sdinak /* 1105*17Sdinak * Value (required) 1106*17Sdinak * 1107*17Sdinak * The rest of this code takes the CKA_VALUE attribute, converts 1108*17Sdinak * it into a temp OpenSSL X509 structure and picks out the rest 1109*17Sdinak * of the fields we need to convert it back into the current X509 1110*17Sdinak * structure that will get exported. The reason we don't just 1111*17Sdinak * start with CKA_VALUE is because while the object was in the 1112*17Sdinak * softtoken, it is possible that some of its attributes changed. 1113*17Sdinak * Those changes would not appear in CKA_VALUE and would be lost 1114*17Sdinak * if we started with CKA_VALUE that was saved originally. 1115*17Sdinak */ 1116*17Sdinak cryptodebug("calling d2i_X509 for cert value"); 1117*17Sdinak if ((temp_cert = d2i_X509(NULL, &value, value_len)) == NULL) { 1118*17Sdinak cryptoerror(LOG_STDERR, gettext( 1119*17Sdinak "Unable to convert main certificate values.")); 1120*17Sdinak return (CKR_GENERAL_ERROR); 1121*17Sdinak } 1122*17Sdinak 1123*17Sdinak /* Transfer these values from temp_cert to cert. */ 1124*17Sdinak cryptodebug("calling X509_set_version/X509_get_version"); 1125*17Sdinak if (!X509_set_version(cert, X509_get_version(temp_cert))) 1126*17Sdinak cryptodebug("error not caught"); 1127*17Sdinak 1128*17Sdinak cryptodebug("calling X509_set_notBefore/X509_get_notBefore"); 1129*17Sdinak if (!X509_set_notBefore(cert, X509_get_notBefore(temp_cert))) 1130*17Sdinak cryptodebug("error not caught"); 1131*17Sdinak 1132*17Sdinak cryptodebug("calling X509_set_notAfter/X509_get_notAfter"); 1133*17Sdinak if (!X509_set_notAfter(cert, X509_get_notAfter(temp_cert))) 1134*17Sdinak cryptodebug("error not caught"); 1135*17Sdinak 1136*17Sdinak cryptodebug("calling X509_set_pubkey/X509_get_pubkey"); 1137*17Sdinak if (!X509_set_pubkey(cert, X509_get_pubkey(temp_cert))) 1138*17Sdinak cryptodebug("error not caught"); 1139*17Sdinak 1140*17Sdinak /* 1141*17Sdinak * These don't get transfered from temp_cert to cert. 1142*17Sdinak * It -appears- that they may get regenerated as needed. 1143*17Sdinak * 1144*17Sdinak * cert->cert_info->signature = dup(temp_cert->cert_info->signature); 1145*17Sdinak * cert->sig_alg = dup(temp_cert->sig_alg); 1146*17Sdinak * cert->signature = dup(temp_cert->signature); 1147*17Sdinak * cert->skid = dup(temp_cert->skid); 1148*17Sdinak * cert->akid = dup(temp_cert->akid); 1149*17Sdinak */ 1150*17Sdinak 1151*17Sdinak *c = cert; 1152*17Sdinak return (CKR_OK); 1153*17Sdinak } 1154*17Sdinak 1155*17Sdinak static CK_RV 1156*17Sdinak convert_token_objs(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, 1157*17Sdinak CK_OBJECT_HANDLE mate, CK_OBJECT_HANDLE *chain, CK_ULONG chain_len, 1158*17Sdinak EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca) 1159*17Sdinak { 1160*17Sdinak CK_RV rv = CKR_OK; 1161*17Sdinak EVP_PKEY *pk = NULL; 1162*17Sdinak X509 *c = NULL; 1163*17Sdinak X509 *one_ca = NULL; 1164*17Sdinak STACK_OF(X509) *ch = NULL; 1165*17Sdinak int i; 1166*17Sdinak 1167*17Sdinak cryptodebug("inside convert_token_objs"); 1168*17Sdinak 1169*17Sdinak if ((rv = cvt_obj2evp_pkey(sess, obj, &pk)) != CKR_OK) 1170*17Sdinak return (rv); 1171*17Sdinak 1172*17Sdinak if (mate != ~0UL) { 1173*17Sdinak cryptodebug("converting cert corresponding to private key"); 1174*17Sdinak if ((rv = cvt_cert2x509(sess, mate, &c)) != CKR_OK) 1175*17Sdinak return (rv); 1176*17Sdinak } 1177*17Sdinak 1178*17Sdinak if (chain_len != 0) { 1179*17Sdinak cryptodebug("converting ca chain of %d certs corresponding " 1180*17Sdinak "to private key", chain_len); 1181*17Sdinak ch = sk_X509_new_null(); 1182*17Sdinak for (i = 0; i < chain_len; i++) { 1183*17Sdinak if ((rv = cvt_cert2x509(sess, chain[i], &one_ca)) != 1184*17Sdinak CKR_OK) { 1185*17Sdinak return (rv); 1186*17Sdinak } 1187*17Sdinak if (!sk_X509_push(ch, one_ca)) 1188*17Sdinak cryptodebug("error not caught"); 1189*17Sdinak } 1190*17Sdinak } 1191*17Sdinak 1192*17Sdinak *priv_key = pk; 1193*17Sdinak *cert = (mate != ~0UL) ? c : NULL; 1194*17Sdinak *ca = (chain_len != 0) ? ch : NULL; 1195*17Sdinak return (CKR_OK); 1196*17Sdinak } 1197*17Sdinak 1198*17Sdinak /* 1199*17Sdinak * Export objects from token to PKCS#12 file. 1200*17Sdinak */ 1201*17Sdinak int 1202*17Sdinak pk_export(int argc, char *argv[]) 1203*17Sdinak { 1204*17Sdinak char *token_name = NULL; 1205*17Sdinak char *manuf_id = NULL; 1206*17Sdinak char *serial_no = NULL; 1207*17Sdinak char full_name[FULL_NAME_LEN]; 1208*17Sdinak char *filename = NULL; 1209*17Sdinak CK_SLOT_ID slot_id; 1210*17Sdinak CK_FLAGS pin_state; 1211*17Sdinak CK_UTF8CHAR_PTR pin = NULL; 1212*17Sdinak CK_ULONG pinlen = 0; 1213*17Sdinak CK_UTF8CHAR_PTR pk12pin = NULL; 1214*17Sdinak CK_ULONG pk12pinlen = 0; 1215*17Sdinak CK_SESSION_HANDLE sess; 1216*17Sdinak BIO *fbio = NULL; 1217*17Sdinak EVP_PKEY *priv_key = NULL; 1218*17Sdinak X509 *cert = NULL; 1219*17Sdinak STACK_OF(X509) *ca = NULL; 1220*17Sdinak CK_RV rv = CKR_OK; 1221*17Sdinak CK_OBJECT_HANDLE *objs = NULL; 1222*17Sdinak CK_ULONG num_objs = 0; 1223*17Sdinak CK_OBJECT_HANDLE mate = ~0UL; 1224*17Sdinak CK_OBJECT_HANDLE *chain = NULL; 1225*17Sdinak CK_ULONG chain_len; 1226*17Sdinak CK_BYTE *id = NULL; 1227*17Sdinak CK_ULONG id_len = 0; 1228*17Sdinak int i = 0; 1229*17Sdinak int good_ones = 0, bad_ones = 0; /* running totals */ 1230*17Sdinak 1231*17Sdinak cryptodebug("inside pk_export"); 1232*17Sdinak 1233*17Sdinak /* Get rid of subcommand work "export". */ 1234*17Sdinak argc--; 1235*17Sdinak argv++; 1236*17Sdinak 1237*17Sdinak /* One additional arg required: filename. */ 1238*17Sdinak if (argc != 1) 1239*17Sdinak return (PK_ERR_USAGE); 1240*17Sdinak 1241*17Sdinak filename = argv[0]; 1242*17Sdinak /* Done parsing command line options. */ 1243*17Sdinak 1244*17Sdinak /* Check if the file exists and might be overwritten. */ 1245*17Sdinak if (access(filename, F_OK) == 0) { 1246*17Sdinak cryptoerror(LOG_STDERR, gettext("Warning: file \"%s\" exists, " 1247*17Sdinak "will be overwritten."), filename); 1248*17Sdinak if (yesno(gettext("Continue with export? "), 1249*17Sdinak gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) { 1250*17Sdinak return (0); 1251*17Sdinak } 1252*17Sdinak } 1253*17Sdinak 1254*17Sdinak /* Export operation only supported on softtoken. */ 1255*17Sdinak if (token_name == NULL) 1256*17Sdinak token_name = SOFT_TOKEN_LABEL; 1257*17Sdinak if (manuf_id == NULL) 1258*17Sdinak manuf_id = SOFT_MANUFACTURER_ID; 1259*17Sdinak if (serial_no == NULL) 1260*17Sdinak serial_no = SOFT_TOKEN_SERIAL; 1261*17Sdinak full_token_name(token_name, manuf_id, serial_no, full_name); 1262*17Sdinak 1263*17Sdinak /* Find the slot with token. */ 1264*17Sdinak if ((rv = find_token_slot(token_name, manuf_id, serial_no, &slot_id, 1265*17Sdinak &pin_state)) != CKR_OK) { 1266*17Sdinak cryptoerror(LOG_STDERR, gettext( 1267*17Sdinak "Unable to find token %s (%s)."), full_name, 1268*17Sdinak pkcs11_strerror(rv)); 1269*17Sdinak return (PK_ERR_PK11); 1270*17Sdinak } 1271*17Sdinak 1272*17Sdinak /* Get the user's PIN. */ 1273*17Sdinak if ((rv = get_pin(gettext("Enter token passphrase:"), NULL, &pin, 1274*17Sdinak &pinlen)) != CKR_OK) { 1275*17Sdinak cryptoerror(LOG_STDERR, gettext( 1276*17Sdinak "Unable to get token passphrase (%s)."), 1277*17Sdinak pkcs11_strerror(rv)); 1278*17Sdinak quick_finish(NULL); 1279*17Sdinak return (PK_ERR_PK11); 1280*17Sdinak } 1281*17Sdinak 1282*17Sdinak /* Assume user must be logged in R/W to export objects from token. */ 1283*17Sdinak if ((rv = quick_start(slot_id, CKF_RW_SESSION, pin, pinlen, &sess)) != 1284*17Sdinak CKR_OK) { 1285*17Sdinak cryptoerror(LOG_STDERR, 1286*17Sdinak gettext("Unable to log into token (%s)."), 1287*17Sdinak pkcs11_strerror(rv)); 1288*17Sdinak quick_finish(sess); 1289*17Sdinak return (PK_ERR_PK11); 1290*17Sdinak } 1291*17Sdinak 1292*17Sdinak /* Collect all private keys first. */ 1293*17Sdinak if ((rv = find_objs(sess, PK_PRIVATE_OBJ|PK_KEY_OBJ, NULL, 1294*17Sdinak &objs, &num_objs)) != CKR_OK) { 1295*17Sdinak cryptoerror(LOG_STDERR, gettext( 1296*17Sdinak "Unable to retrieve private key token objects (%s)."), 1297*17Sdinak pkcs11_strerror(rv)); 1298*17Sdinak quick_finish(sess); 1299*17Sdinak return (PK_ERR_PK11); 1300*17Sdinak } 1301*17Sdinak 1302*17Sdinak /* Nothing to do? */ 1303*17Sdinak if (num_objs == 0) { 1304*17Sdinak cryptoerror(LOG_STDERR, gettext("No objects found.")); 1305*17Sdinak quick_finish(sess); 1306*17Sdinak return (0); 1307*17Sdinak } 1308*17Sdinak 1309*17Sdinak /* Setup OpenSSL context. */ 1310*17Sdinak PKTOOL_setup_openssl(); 1311*17Sdinak 1312*17Sdinak /* Create PKCS#12 file. */ 1313*17Sdinak if ((create_pkcs12(filename, &fbio)) < 0) { 1314*17Sdinak cryptoerror(LOG_STDERR, gettext("No export file created.")); 1315*17Sdinak quick_finish(sess); 1316*17Sdinak return (PK_ERR_SYSTEM); 1317*17Sdinak } 1318*17Sdinak 1319*17Sdinak /* Get the PIN for the PKCS#12 export file. */ 1320*17Sdinak if ((rv = get_pin(gettext("Create export file passphrase:"), gettext( 1321*17Sdinak "Re-enter export file passphrase:"), &pk12pin, &pk12pinlen)) != 1322*17Sdinak CKR_OK) { 1323*17Sdinak cryptoerror(LOG_STDERR, 1324*17Sdinak gettext("Unable to get export file passphrase (%s)."), 1325*17Sdinak pkcs11_strerror(rv)); 1326*17Sdinak close_pkcs12(fbio); 1327*17Sdinak quick_finish(sess); 1328*17Sdinak return (PK_ERR_PK11); 1329*17Sdinak } 1330*17Sdinak 1331*17Sdinak for (i = 0; i < num_objs; i++) { 1332*17Sdinak /* Get a private key and its certificate and CA chain. */ 1333*17Sdinak if ((rv = get_token_objs(sess, objs[i], &mate, &chain, 1334*17Sdinak &chain_len, &id, &id_len)) != CKR_OK) { 1335*17Sdinak /* 1336*17Sdinak * Note this "rv" is either CKR_OK or !CKR_OK. The 1337*17Sdinak * real error codes/messages are handled inside 1338*17Sdinak * read_token_objs(). 1339*17Sdinak */ 1340*17Sdinak cryptoerror(LOG_STDERR, 1341*17Sdinak gettext("Unable to get token objects.")); 1342*17Sdinak free(id); 1343*17Sdinak close_pkcs12(fbio); 1344*17Sdinak quick_finish(sess); 1345*17Sdinak return (PK_ERR_PK11); 1346*17Sdinak } 1347*17Sdinak 1348*17Sdinak /* Convert to OpenSSL equivalents. */ 1349*17Sdinak if ((rv = convert_token_objs(sess, objs[i], mate, chain, 1350*17Sdinak chain_len, &priv_key, &cert, &ca)) != CKR_OK) { 1351*17Sdinak /* 1352*17Sdinak * Note this "rv" is either CKR_OK or !CKR_OK. The 1353*17Sdinak * real error codes/messages are handled inside 1354*17Sdinak * read_token_objs(). 1355*17Sdinak */ 1356*17Sdinak cryptoerror(LOG_STDERR, 1357*17Sdinak gettext("Unable to convert token objects.")); 1358*17Sdinak free(id); 1359*17Sdinak close_pkcs12(fbio); 1360*17Sdinak quick_finish(sess); 1361*17Sdinak return (PK_ERR_PK11); 1362*17Sdinak } 1363*17Sdinak 1364*17Sdinak /* 1365*17Sdinak * When exporting of cert chains is implemented, these 1366*17Sdinak * messages should be updated accordingly. 1367*17Sdinak */ 1368*17Sdinak if (mate == ~0UL) 1369*17Sdinak (void) fprintf(stdout, gettext( 1370*17Sdinak "Writing object #%d...\n"), i+1); 1371*17Sdinak else 1372*17Sdinak (void) fprintf(stdout, gettext("Writing object #%d " 1373*17Sdinak "and its certificate...\n"), i+1); 1374*17Sdinak 1375*17Sdinak /* Write object and its certs to the PKCS#12 export file. */ 1376*17Sdinak if (write_objs_pkcs12(fbio, pk12pin, pk12pinlen, id, id_len, 1377*17Sdinak priv_key, cert, ca, &good_ones, &bad_ones) < 0) { 1378*17Sdinak cryptoerror(LOG_STDERR, gettext( 1379*17Sdinak "Unable to write object #%d to export file."), i+1); 1380*17Sdinak sk_X509_pop_free(ca, X509_free); 1381*17Sdinak free(id); 1382*17Sdinak close_pkcs12(fbio); 1383*17Sdinak quick_finish(sess); 1384*17Sdinak return (PK_ERR_OPENSSL); 1385*17Sdinak } 1386*17Sdinak 1387*17Sdinak /* Destroy key id and CA cert chain, done with them. */ 1388*17Sdinak free(id); 1389*17Sdinak id = NULL; 1390*17Sdinak sk_X509_pop_free(ca, X509_free); 1391*17Sdinak ca = NULL; 1392*17Sdinak } 1393*17Sdinak 1394*17Sdinak (void) fprintf(stdout, gettext( 1395*17Sdinak "%d token objects exported, %d errors occurred.\n"), 1396*17Sdinak good_ones, bad_ones); 1397*17Sdinak 1398*17Sdinak /* Close PKCS#12 file. */ 1399*17Sdinak close_pkcs12(fbio); 1400*17Sdinak 1401*17Sdinak /* Clean up. */ 1402*17Sdinak quick_finish(sess); 1403*17Sdinak return (0); 1404*17Sdinak } 1405