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 import operation for this tool. 31*17Sdinak * The basic flow of the process is to decrypt the PKCS#12 32*17Sdinak * input file if it has a password, parse the elements in 33*17Sdinak * the file, find the soft token, log into it, import the 34*17Sdinak * PKCS#11 objects into the soft token, and log out. 35*17Sdinak */ 36*17Sdinak 37*17Sdinak #include <stdio.h> 38*17Sdinak #include <stdlib.h> 39*17Sdinak #include <string.h> 40*17Sdinak #include <errno.h> 41*17Sdinak #include <fcntl.h> 42*17Sdinak #include <sys/types.h> 43*17Sdinak #include <sys/stat.h> 44*17Sdinak #include <cryptoutil.h> 45*17Sdinak #include <security/cryptoki.h> 46*17Sdinak #include "common.h" 47*17Sdinak #include "biginteger.h" 48*17Sdinak #include "osslcommon.h" 49*17Sdinak #include "p12common.h" 50*17Sdinak #include <openssl/pkcs12.h> 51*17Sdinak #include <openssl/err.h> 52*17Sdinak 53*17Sdinak /* 54*17Sdinak * Helper function decrypt and parse PKCS#12 import file. 55*17Sdinak */ 56*17Sdinak static CK_RV 57*17Sdinak extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen, 58*17Sdinak EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca) 59*17Sdinak /* ARGSUSED */ 60*17Sdinak { 61*17Sdinak PKCS12 *pk12, *pk12_tmp; 62*17Sdinak EVP_PKEY *temp_pkey = NULL; 63*17Sdinak X509 *temp_cert = NULL; 64*17Sdinak STACK_OF(X509) *temp_ca = NULL; 65*17Sdinak 66*17Sdinak cryptodebug("inside extract_pkcs12"); 67*17Sdinak 68*17Sdinak cryptodebug("calling PKCS12_new"); 69*17Sdinak if ((pk12 = PKCS12_new()) == NULL) { 70*17Sdinak cryptoerror(LOG_STDERR, gettext( 71*17Sdinak "Unable to create PKCS#12 context.")); 72*17Sdinak return (CKR_GENERAL_ERROR); 73*17Sdinak } 74*17Sdinak 75*17Sdinak cryptodebug("calling d2i_PKCS12_bio"); 76*17Sdinak if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) { 77*17Sdinak /* This is ok; it seems to mean there is no more to read. */ 78*17Sdinak if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 && 79*17Sdinak ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG) 80*17Sdinak goto end_extract_pkcs12; 81*17Sdinak 82*17Sdinak cryptoerror(LOG_STDERR, gettext( 83*17Sdinak "Unable to populate PKCS#12 context.")); 84*17Sdinak PKCS12_free(pk12); 85*17Sdinak return (CKR_GENERAL_ERROR); 86*17Sdinak } 87*17Sdinak pk12 = pk12_tmp; 88*17Sdinak 89*17Sdinak cryptodebug("calling PKCS12_parse"); 90*17Sdinak if (PKCS12_parse(pk12, (char *)pin, &temp_pkey, &temp_cert, 91*17Sdinak &temp_ca) <= 0) { 92*17Sdinak cryptoerror(LOG_STDERR, 93*17Sdinak gettext("Unable to parse import file.")); 94*17Sdinak PKCS12_free(pk12); 95*17Sdinak return (CKR_GENERAL_ERROR); 96*17Sdinak } 97*17Sdinak 98*17Sdinak end_extract_pkcs12: 99*17Sdinak 100*17Sdinak *priv_key = temp_pkey; 101*17Sdinak *cert = temp_cert; 102*17Sdinak *ca = temp_ca; 103*17Sdinak 104*17Sdinak PKCS12_free(pk12); 105*17Sdinak return (CKR_OK); 106*17Sdinak } 107*17Sdinak 108*17Sdinak /* 109*17Sdinak * Converts OpenSSL BIGNUM into PKCS#11 biginteger_t format. 110*17Sdinak */ 111*17Sdinak static CK_RV 112*17Sdinak cvt_bn2bigint(BIGNUM *from, biginteger_t *to) 113*17Sdinak { 114*17Sdinak CK_BYTE *temp; 115*17Sdinak CK_ULONG temp_alloc_sz, temp_cvt_sz; 116*17Sdinak 117*17Sdinak cryptodebug("inside cvt_bn2bigint"); 118*17Sdinak 119*17Sdinak if (from == NULL || to == NULL) 120*17Sdinak return (CKR_ARGUMENTS_BAD); 121*17Sdinak 122*17Sdinak cryptodebug("calling BN_num_bytes"); 123*17Sdinak temp_alloc_sz = BN_num_bytes(from); 124*17Sdinak if ((temp = malloc(temp_alloc_sz)) == NULL) 125*17Sdinak return (CKR_HOST_MEMORY); 126*17Sdinak 127*17Sdinak cryptodebug("calling BN_bn2bin"); 128*17Sdinak temp_cvt_sz = BN_bn2bin(from, (unsigned char *)temp); 129*17Sdinak if (temp_cvt_sz != temp_alloc_sz) 130*17Sdinak return (CKR_GENERAL_ERROR); 131*17Sdinak 132*17Sdinak to->big_value = temp; 133*17Sdinak to->big_value_len = temp_cvt_sz; 134*17Sdinak return (CKR_OK); 135*17Sdinak } 136*17Sdinak 137*17Sdinak /* 138*17Sdinak * Write RSA private key to token. 139*17Sdinak */ 140*17Sdinak static CK_RV 141*17Sdinak write_rsa_private(CK_SESSION_HANDLE sess, RSA *rsa, X509 *cert) 142*17Sdinak { 143*17Sdinak CK_RV rv = CKR_OK; 144*17Sdinak int i = 0; 145*17Sdinak static CK_OBJECT_CLASS objclass = CKO_PRIVATE_KEY; 146*17Sdinak static CK_KEY_TYPE keytype = CKK_RSA; 147*17Sdinak CK_BYTE *label = NULL; 148*17Sdinak CK_ULONG label_len = 0; 149*17Sdinak CK_BYTE *id = NULL; 150*17Sdinak CK_ULONG id_len = 0; 151*17Sdinak CK_DATE startdate = { "", "", "" }; 152*17Sdinak CK_DATE enddate = { "", "", "" }; 153*17Sdinak char tmpdate[8]; 154*17Sdinak biginteger_t mod = { NULL, 0 }; /* required */ 155*17Sdinak biginteger_t pubexp = { NULL, 0 }; /* required */ 156*17Sdinak biginteger_t priexp = { NULL, 0 }; /* optional */ 157*17Sdinak biginteger_t prime1 = { NULL, 0 }; /* optional */ 158*17Sdinak biginteger_t prime2 = { NULL, 0 }; /* optional */ 159*17Sdinak biginteger_t exp1 = { NULL, 0 }; /* optional */ 160*17Sdinak biginteger_t exp2 = { NULL, 0 }; /* optional */ 161*17Sdinak biginteger_t coef = { NULL, 0 }; /* optional */ 162*17Sdinak CK_ATTRIBUTE rsa_pri_attrs[16] = { 163*17Sdinak { CKA_CLASS, &objclass, sizeof (objclass) }, 164*17Sdinak { CKA_KEY_TYPE, &keytype, sizeof (keytype) }, 165*17Sdinak { CKA_PRIVATE, &pk_true, sizeof (pk_true) }, 166*17Sdinak { CKA_TOKEN, &pk_true, sizeof (pk_true) }, 167*17Sdinak { CKA_LABEL, NULL, 0 }, 168*17Sdinak { CKA_ID, NULL, 0 }, 169*17Sdinak { CKA_START_DATE, NULL, 0 }, 170*17Sdinak { CKA_END_DATE, NULL, 0 }, 171*17Sdinak { CKA_MODULUS, NULL, 0 }, 172*17Sdinak { CKA_PUBLIC_EXPONENT, NULL, 0 }, 173*17Sdinak { 0 /* CKA_PRIVATE_EXPONENT */, NULL, 0 }, /* optional */ 174*17Sdinak { 0 /* CKA_PRIME_1 */, NULL, 0 }, /* | */ 175*17Sdinak { 0 /* CKA_PRIME_2 */, NULL, 0 }, /* | */ 176*17Sdinak { 0 /* CKA_EXPONENT_1 */, NULL, 0 }, /* | */ 177*17Sdinak { 0 /* CKA_EXPONENT_2 */, NULL, 0 }, /* | */ 178*17Sdinak { 0 /* CKA_COEFFICIENT */, NULL, 0 } /* V */ 179*17Sdinak }; 180*17Sdinak CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE); 181*17Sdinak CK_OBJECT_HANDLE obj; 182*17Sdinak 183*17Sdinak cryptodebug("inside write_rsa_private"); 184*17Sdinak 185*17Sdinak /* Attributes start at array index 4. */ 186*17Sdinak i = 4; 187*17Sdinak 188*17Sdinak /* Recycle the certificate label for the private key label. */ 189*17Sdinak cryptodebug("calling X509_alias_get0"); 190*17Sdinak if ((label = X509_alias_get0(cert, (int *)&label_len)) == NULL) { 191*17Sdinak label = (CK_BYTE *)gettext("no label"); 192*17Sdinak label_len = strlen((char *)label); 193*17Sdinak } 194*17Sdinak copy_string_to_attr(label, label_len, &(rsa_pri_attrs[i++])); 195*17Sdinak 196*17Sdinak /* Recycle the certificate id for the private key id. */ 197*17Sdinak cryptodebug("calling PKTOOL_X509_keyid_get0"); 198*17Sdinak if ((id = PKTOOL_X509_keyid_get0(cert, (int *)&id_len)) == NULL) { 199*17Sdinak id = (CK_BYTE *)gettext("no id"); 200*17Sdinak id_len = strlen((char *)id); 201*17Sdinak } 202*17Sdinak copy_string_to_attr(id, id_len, &(rsa_pri_attrs[i++])); 203*17Sdinak 204*17Sdinak /* Recycle the certificate start and end dates for private key. */ 205*17Sdinak cryptodebug("calling X509_get_notBefore"); 206*17Sdinak if (PKTOOL_cvt_ossltime(X509_get_notBefore(cert), tmpdate)) { 207*17Sdinak (void) memcpy(&startdate, tmpdate, sizeof (startdate)); 208*17Sdinak copy_string_to_attr((CK_BYTE *)&startdate, sizeof (startdate), 209*17Sdinak &(rsa_pri_attrs[i++])); 210*17Sdinak } 211*17Sdinak 212*17Sdinak cryptodebug("calling X509_get_notAfter"); 213*17Sdinak if (PKTOOL_cvt_ossltime(X509_get_notAfter(cert), tmpdate)) { 214*17Sdinak (void) memcpy(&enddate, tmpdate, sizeof (enddate)); 215*17Sdinak copy_string_to_attr((CK_BYTE *)&enddate, sizeof (enddate), 216*17Sdinak &(rsa_pri_attrs[i++])); 217*17Sdinak } 218*17Sdinak 219*17Sdinak /* Modulus n */ 220*17Sdinak cryptodebug("converting RSA private key modulus"); 221*17Sdinak if ((rv = cvt_bn2bigint(rsa->n, &mod)) != CKR_OK) { 222*17Sdinak cryptoerror(LOG_STDERR, gettext( 223*17Sdinak "Unable to convert RSA private key modulus.")); 224*17Sdinak return (rv); 225*17Sdinak } 226*17Sdinak copy_bigint_to_attr(mod, &(rsa_pri_attrs[i++])); 227*17Sdinak 228*17Sdinak /* Public exponent e */ 229*17Sdinak cryptodebug("converting RSA private key public exponent"); 230*17Sdinak if ((rv = cvt_bn2bigint(rsa->e, &pubexp)) != CKR_OK) { 231*17Sdinak cryptoerror(LOG_STDERR, gettext( 232*17Sdinak "Unable to convert RSA private key public exponent.")); 233*17Sdinak return (rv); 234*17Sdinak } 235*17Sdinak copy_bigint_to_attr(pubexp, &(rsa_pri_attrs[i++])); 236*17Sdinak 237*17Sdinak /* Private exponent d */ 238*17Sdinak if (rsa->d != NULL) { 239*17Sdinak cryptodebug("converting RSA private key private exponent"); 240*17Sdinak if ((rv = cvt_bn2bigint(rsa->d, &priexp)) != CKR_OK) { 241*17Sdinak cryptoerror(LOG_STDERR, gettext("Unable to convert " 242*17Sdinak "RSA private key private exponent.")); 243*17Sdinak return (rv); 244*17Sdinak } 245*17Sdinak rsa_pri_attrs[i].type = CKA_PRIVATE_EXPONENT; 246*17Sdinak copy_bigint_to_attr(priexp, &(rsa_pri_attrs[i++])); 247*17Sdinak } else 248*17Sdinak cryptodebug("no RSA private key private exponent"); 249*17Sdinak 250*17Sdinak /* Prime p */ 251*17Sdinak if (rsa->p != NULL) { 252*17Sdinak cryptodebug("converting RSA private key prime 1"); 253*17Sdinak if ((rv = cvt_bn2bigint(rsa->p, &prime1)) != CKR_OK) { 254*17Sdinak cryptoerror(LOG_STDERR, gettext( 255*17Sdinak "Unable to convert RSA private key prime 1.")); 256*17Sdinak return (rv); 257*17Sdinak } 258*17Sdinak rsa_pri_attrs[i].type = CKA_PRIME_1; 259*17Sdinak copy_bigint_to_attr(prime1, &(rsa_pri_attrs[i++])); 260*17Sdinak } else 261*17Sdinak cryptodebug("no RSA private key prime 1"); 262*17Sdinak 263*17Sdinak /* Prime q */ 264*17Sdinak if (rsa->q != NULL) { 265*17Sdinak cryptodebug("converting RSA private key prime 2"); 266*17Sdinak if ((rv = cvt_bn2bigint(rsa->q, &prime2)) != CKR_OK) { 267*17Sdinak cryptoerror(LOG_STDERR, gettext( 268*17Sdinak "Unable to convert RSA private key prime 2.")); 269*17Sdinak return (rv); 270*17Sdinak } 271*17Sdinak rsa_pri_attrs[i].type = CKA_PRIME_2; 272*17Sdinak copy_bigint_to_attr(prime2, &(rsa_pri_attrs[i++])); 273*17Sdinak } else 274*17Sdinak cryptodebug("no RSA private key prime 2"); 275*17Sdinak 276*17Sdinak /* Private exponent d modulo p-1 */ 277*17Sdinak if (rsa->dmp1 != NULL) { 278*17Sdinak cryptodebug("converting RSA private key exponent 1"); 279*17Sdinak if ((rv = cvt_bn2bigint(rsa->dmp1, &exp1)) != CKR_OK) { 280*17Sdinak cryptoerror(LOG_STDERR, gettext( 281*17Sdinak "Unable to convert RSA private key exponent 1.")); 282*17Sdinak return (rv); 283*17Sdinak } 284*17Sdinak rsa_pri_attrs[i].type = CKA_EXPONENT_1; 285*17Sdinak copy_bigint_to_attr(exp1, &(rsa_pri_attrs[i++])); 286*17Sdinak } else 287*17Sdinak cryptodebug("no RSA private key exponent 1"); 288*17Sdinak 289*17Sdinak /* Private exponent d modulo q-1 */ 290*17Sdinak if (rsa->dmq1 != NULL) { 291*17Sdinak cryptodebug("converting RSA private key exponent 2"); 292*17Sdinak if ((rv = cvt_bn2bigint(rsa->dmq1, &exp2)) != CKR_OK) { 293*17Sdinak cryptoerror(LOG_STDERR, gettext( 294*17Sdinak "Unable to convert RSA private key exponent 2.")); 295*17Sdinak return (rv); 296*17Sdinak } 297*17Sdinak rsa_pri_attrs[i].type = CKA_EXPONENT_2; 298*17Sdinak copy_bigint_to_attr(exp2, &(rsa_pri_attrs[i++])); 299*17Sdinak } else 300*17Sdinak cryptodebug("no RSA private key exponent 2"); 301*17Sdinak 302*17Sdinak /* CRT coefficient q-inverse mod p */ 303*17Sdinak if (rsa->iqmp != NULL) { 304*17Sdinak cryptodebug("converting RSA private key coefficient"); 305*17Sdinak if ((rv = cvt_bn2bigint(rsa->iqmp, &coef)) != CKR_OK) { 306*17Sdinak cryptoerror(LOG_STDERR, gettext( 307*17Sdinak "Unable to convert RSA private key coefficient.")); 308*17Sdinak return (rv); 309*17Sdinak } 310*17Sdinak rsa_pri_attrs[i].type = CKA_COEFFICIENT; 311*17Sdinak copy_bigint_to_attr(coef, &(rsa_pri_attrs[i++])); 312*17Sdinak } else 313*17Sdinak cryptodebug("no RSA private key coefficient"); 314*17Sdinak 315*17Sdinak /* Indicates programming error: attributes overran the template */ 316*17Sdinak if (i > count) { 317*17Sdinak cryptodebug("error: more attributes found than accounted for"); 318*17Sdinak i = count; 319*17Sdinak } 320*17Sdinak 321*17Sdinak cryptodebug("calling C_CreateObject"); 322*17Sdinak if ((rv = C_CreateObject(sess, rsa_pri_attrs, i, &obj)) != CKR_OK) { 323*17Sdinak cryptoerror(LOG_STDERR, gettext( 324*17Sdinak "Unable to create RSA private key object.")); 325*17Sdinak return (rv); 326*17Sdinak } 327*17Sdinak 328*17Sdinak return (CKR_OK); 329*17Sdinak } 330*17Sdinak 331*17Sdinak /* 332*17Sdinak * Write DSA private key to token. 333*17Sdinak */ 334*17Sdinak static CK_RV 335*17Sdinak write_dsa_private(CK_SESSION_HANDLE sess, DSA *dsa, X509 *cert) 336*17Sdinak { 337*17Sdinak CK_RV rv = CKR_OK; 338*17Sdinak int i = 0; 339*17Sdinak static CK_OBJECT_CLASS objclass = CKO_PRIVATE_KEY; 340*17Sdinak static CK_KEY_TYPE keytype = CKK_DSA; 341*17Sdinak CK_BYTE *label = NULL; 342*17Sdinak CK_ULONG label_len = 0; 343*17Sdinak CK_BYTE *id = NULL; 344*17Sdinak CK_ULONG id_len = 0; 345*17Sdinak CK_DATE startdate = { "", "", "" }; 346*17Sdinak CK_DATE enddate = { "", "", "" }; 347*17Sdinak char tmpdate[8]; 348*17Sdinak biginteger_t prime = { NULL, 0 }; /* required */ 349*17Sdinak biginteger_t subprime = { NULL, 0 }; /* required */ 350*17Sdinak biginteger_t base = { NULL, 0 }; /* required */ 351*17Sdinak biginteger_t value = { NULL, 0 }; /* required */ 352*17Sdinak CK_ATTRIBUTE dsa_pri_attrs[12] = { 353*17Sdinak { CKA_CLASS, &objclass, sizeof (objclass) }, 354*17Sdinak { CKA_KEY_TYPE, &keytype, sizeof (keytype) }, 355*17Sdinak { CKA_PRIVATE, &pk_true, sizeof (pk_true) }, 356*17Sdinak { CKA_TOKEN, &pk_true, sizeof (pk_true) }, 357*17Sdinak { CKA_LABEL, NULL, 0 }, 358*17Sdinak { CKA_ID, NULL, 0 }, 359*17Sdinak { CKA_START_DATE, NULL, 0 }, 360*17Sdinak { CKA_END_DATE, NULL, 0 }, 361*17Sdinak { CKA_PRIME, NULL, 0 }, 362*17Sdinak { CKA_SUBPRIME, NULL, 0 }, 363*17Sdinak { CKA_BASE, NULL, 0 }, 364*17Sdinak { CKA_VALUE, NULL, 0 } 365*17Sdinak }; 366*17Sdinak CK_ULONG count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE); 367*17Sdinak CK_OBJECT_HANDLE obj; 368*17Sdinak 369*17Sdinak cryptodebug("inside write_dsa_private"); 370*17Sdinak 371*17Sdinak /* Attributes start at array index 4. */ 372*17Sdinak i = 4; 373*17Sdinak 374*17Sdinak /* Recycle the certificate label for the private key label. */ 375*17Sdinak cryptodebug("calling X509_alias_get0"); 376*17Sdinak if ((label = X509_alias_get0(cert, (int *)&label_len)) == NULL) { 377*17Sdinak label = (CK_BYTE *)gettext("no label"); 378*17Sdinak label_len = strlen((char *)label); 379*17Sdinak } 380*17Sdinak copy_string_to_attr(label, label_len, &(dsa_pri_attrs[i++])); 381*17Sdinak 382*17Sdinak /* Recycle the certificate id for the private key id. */ 383*17Sdinak cryptodebug("calling PKTOOL_X509_keyid_get0"); 384*17Sdinak if ((id = PKTOOL_X509_keyid_get0(cert, (int *)&id_len)) == NULL) { 385*17Sdinak id = (CK_BYTE *)gettext("no id"); 386*17Sdinak id_len = strlen((char *)id); 387*17Sdinak } 388*17Sdinak copy_string_to_attr(id, id_len, &(dsa_pri_attrs[i++])); 389*17Sdinak 390*17Sdinak /* Recycle the certificate start and end dates for private key. */ 391*17Sdinak cryptodebug("calling X509_get_notBefore"); 392*17Sdinak if (PKTOOL_cvt_ossltime(X509_get_notBefore(cert), tmpdate)) { 393*17Sdinak (void) memcpy(&startdate, tmpdate, sizeof (startdate)); 394*17Sdinak copy_string_to_attr((CK_BYTE *)&startdate, sizeof (startdate), 395*17Sdinak &(dsa_pri_attrs[i++])); 396*17Sdinak } 397*17Sdinak 398*17Sdinak cryptodebug("calling X509_get_notAfter"); 399*17Sdinak if (PKTOOL_cvt_ossltime(X509_get_notAfter(cert), tmpdate)) { 400*17Sdinak (void) memcpy(&enddate, tmpdate, sizeof (enddate)); 401*17Sdinak copy_string_to_attr((CK_BYTE *)&enddate, sizeof (enddate), 402*17Sdinak &(dsa_pri_attrs[i++])); 403*17Sdinak } 404*17Sdinak 405*17Sdinak /* Prime p */ 406*17Sdinak cryptodebug("converting DSA private key prime"); 407*17Sdinak if ((rv = cvt_bn2bigint(dsa->p, &prime)) != CKR_OK) { 408*17Sdinak cryptoerror(LOG_STDERR, gettext( 409*17Sdinak "Unable to convert DSA private key prime.")); 410*17Sdinak return (rv); 411*17Sdinak } 412*17Sdinak copy_bigint_to_attr(prime, &(dsa_pri_attrs[i++])); 413*17Sdinak 414*17Sdinak /* Subprime q */ 415*17Sdinak cryptodebug("converting DSA private key subprime"); 416*17Sdinak if ((rv = cvt_bn2bigint(dsa->q, &subprime)) != CKR_OK) { 417*17Sdinak cryptoerror(LOG_STDERR, gettext( 418*17Sdinak "Unable to convert DSA private key subprime.")); 419*17Sdinak return (rv); 420*17Sdinak } 421*17Sdinak copy_bigint_to_attr(subprime, &(dsa_pri_attrs[i++])); 422*17Sdinak 423*17Sdinak /* Base g */ 424*17Sdinak cryptodebug("converting DSA private key base"); 425*17Sdinak if ((rv = cvt_bn2bigint(dsa->g, &base)) != CKR_OK) { 426*17Sdinak cryptoerror(LOG_STDERR, gettext( 427*17Sdinak "Unable to convert DSA private key base.")); 428*17Sdinak return (rv); 429*17Sdinak } 430*17Sdinak copy_bigint_to_attr(base, &(dsa_pri_attrs[i++])); 431*17Sdinak 432*17Sdinak /* Private key x */ 433*17Sdinak cryptodebug("converting DSA private key value"); 434*17Sdinak if ((rv = cvt_bn2bigint(dsa->priv_key, &value)) != CKR_OK) { 435*17Sdinak cryptoerror(LOG_STDERR, gettext( 436*17Sdinak "Unable to convert DSA private key value.")); 437*17Sdinak return (rv); 438*17Sdinak } 439*17Sdinak copy_bigint_to_attr(value, &(dsa_pri_attrs[i++])); 440*17Sdinak 441*17Sdinak /* Indicates programming error: attributes overran the template */ 442*17Sdinak if (i > count) { 443*17Sdinak cryptodebug("error: more attributes found than accounted for"); 444*17Sdinak i = count; 445*17Sdinak } 446*17Sdinak 447*17Sdinak cryptodebug("calling C_CreateObject"); 448*17Sdinak if ((rv = C_CreateObject(sess, dsa_pri_attrs, i, &obj)) != CKR_OK) { 449*17Sdinak cryptoerror(LOG_STDERR, gettext( 450*17Sdinak "Unable to create DSA private key object.")); 451*17Sdinak return (rv); 452*17Sdinak } 453*17Sdinak 454*17Sdinak return (CKR_OK); 455*17Sdinak } 456*17Sdinak 457*17Sdinak /* 458*17Sdinak * Write DH private key to token. 459*17Sdinak */ 460*17Sdinak static CK_RV 461*17Sdinak write_dh_private(CK_SESSION_HANDLE sess, DH *dh, X509 *cert) 462*17Sdinak { 463*17Sdinak CK_RV rv = CKR_OK; 464*17Sdinak int i = 0; 465*17Sdinak static CK_OBJECT_CLASS objclass = CKO_PRIVATE_KEY; 466*17Sdinak static CK_KEY_TYPE keytype = CKK_DH; 467*17Sdinak CK_BYTE *label = NULL; 468*17Sdinak CK_ULONG label_len = 0; 469*17Sdinak CK_BYTE *id = NULL; 470*17Sdinak CK_ULONG id_len = 0; 471*17Sdinak CK_DATE startdate = { "", "", "" }; 472*17Sdinak CK_DATE enddate = { "", "", "" }; 473*17Sdinak char tmpdate[8]; 474*17Sdinak biginteger_t prime = { NULL, 0 }; /* required */ 475*17Sdinak biginteger_t base = { NULL, 0 }; /* required */ 476*17Sdinak biginteger_t value = { NULL, 0 }; /* required */ 477*17Sdinak CK_ATTRIBUTE dh_pri_attrs[11] = { 478*17Sdinak { CKA_CLASS, &objclass, sizeof (objclass) }, 479*17Sdinak { CKA_KEY_TYPE, &keytype, sizeof (keytype) }, 480*17Sdinak { CKA_PRIVATE, &pk_true, sizeof (pk_true) }, 481*17Sdinak { CKA_TOKEN, &pk_true, sizeof (pk_true) }, 482*17Sdinak { CKA_LABEL, NULL, 0 }, 483*17Sdinak { CKA_ID, NULL, 0 }, 484*17Sdinak { CKA_START_DATE, NULL, 0 }, 485*17Sdinak { CKA_END_DATE, NULL, 0 }, 486*17Sdinak { CKA_PRIME, NULL, 0 }, 487*17Sdinak { CKA_BASE, NULL, 0 }, 488*17Sdinak { CKA_VALUE, NULL, 0 } 489*17Sdinak }; 490*17Sdinak CK_ULONG count = sizeof (dh_pri_attrs) / sizeof (CK_ATTRIBUTE); 491*17Sdinak CK_OBJECT_HANDLE obj; 492*17Sdinak 493*17Sdinak cryptodebug("inside write_dh_private"); 494*17Sdinak 495*17Sdinak /* Attributes start at array index 4. */ 496*17Sdinak i = 4; 497*17Sdinak 498*17Sdinak /* Recycle the certificate label for the private key label. */ 499*17Sdinak cryptodebug("calling X509_alias_get0"); 500*17Sdinak if ((label = X509_alias_get0(cert, (int *)&label_len)) == NULL) { 501*17Sdinak label = (CK_BYTE *)gettext("no label"); 502*17Sdinak label_len = strlen((char *)label); 503*17Sdinak } 504*17Sdinak copy_string_to_attr(label, label_len, &(dh_pri_attrs[i++])); 505*17Sdinak 506*17Sdinak /* Recycle the certificate id for the private key id. */ 507*17Sdinak cryptodebug("PKTOOL_X509_keyid_get0"); 508*17Sdinak if ((id = PKTOOL_X509_keyid_get0(cert, (int *)&id_len)) == NULL) { 509*17Sdinak id = (CK_BYTE *)gettext("no id"); 510*17Sdinak id_len = strlen((char *)id); 511*17Sdinak } 512*17Sdinak copy_string_to_attr(id, id_len, &(dh_pri_attrs[i++])); 513*17Sdinak 514*17Sdinak /* Recycle the certificate start and end dates for private key. */ 515*17Sdinak cryptodebug("calling X509_get_notBefore"); 516*17Sdinak if (PKTOOL_cvt_ossltime(X509_get_notBefore(cert), tmpdate)) { 517*17Sdinak (void) memcpy(&startdate, tmpdate, sizeof (startdate)); 518*17Sdinak copy_string_to_attr((CK_BYTE *)&startdate, sizeof (startdate), 519*17Sdinak &(dh_pri_attrs[i++])); 520*17Sdinak } 521*17Sdinak 522*17Sdinak cryptodebug("calling X509_get_notAfter"); 523*17Sdinak if (PKTOOL_cvt_ossltime(X509_get_notAfter(cert), tmpdate)) { 524*17Sdinak (void) memcpy(&enddate, tmpdate, sizeof (enddate)); 525*17Sdinak copy_string_to_attr((CK_BYTE *)&enddate, sizeof (enddate), 526*17Sdinak &(dh_pri_attrs[i++])); 527*17Sdinak } 528*17Sdinak 529*17Sdinak /* Prime p */ 530*17Sdinak cryptodebug("converting DH private key prime"); 531*17Sdinak if ((rv = cvt_bn2bigint(dh->p, &prime)) != CKR_OK) { 532*17Sdinak cryptoerror(LOG_STDERR, gettext( 533*17Sdinak "Unable to convert DH private key prime.")); 534*17Sdinak return (rv); 535*17Sdinak } 536*17Sdinak copy_bigint_to_attr(prime, &(dh_pri_attrs[i++])); 537*17Sdinak 538*17Sdinak /* Base g */ 539*17Sdinak cryptodebug("converting DH private key base"); 540*17Sdinak if ((rv = cvt_bn2bigint(dh->g, &base)) != CKR_OK) { 541*17Sdinak cryptoerror(LOG_STDERR, gettext( 542*17Sdinak "Unable to convert DH private key base.")); 543*17Sdinak return (rv); 544*17Sdinak } 545*17Sdinak copy_bigint_to_attr(base, &(dh_pri_attrs[i++])); 546*17Sdinak 547*17Sdinak /* Private value x */ 548*17Sdinak cryptodebug("converting DH private key value"); 549*17Sdinak if ((rv = cvt_bn2bigint(dh->priv_key, &value)) != CKR_OK) { 550*17Sdinak cryptoerror(LOG_STDERR, gettext( 551*17Sdinak "Unable to convert DH private key value.")); 552*17Sdinak return (rv); 553*17Sdinak } 554*17Sdinak copy_bigint_to_attr(value, &(dh_pri_attrs[i++])); 555*17Sdinak 556*17Sdinak /* Indicates programming error: attributes overran the template */ 557*17Sdinak if (i > count) { 558*17Sdinak cryptodebug("error: more attributes found than accounted for"); 559*17Sdinak i = count; 560*17Sdinak } 561*17Sdinak 562*17Sdinak cryptodebug("calling C_CreateObject"); 563*17Sdinak if ((rv = C_CreateObject(sess, dh_pri_attrs, i, &obj)) != CKR_OK) { 564*17Sdinak cryptoerror(LOG_STDERR, gettext( 565*17Sdinak "Unable to create DH private key object.")); 566*17Sdinak return (rv); 567*17Sdinak } 568*17Sdinak 569*17Sdinak return (CKR_OK); 570*17Sdinak } 571*17Sdinak 572*17Sdinak /* 573*17Sdinak * Write certificate to token. 574*17Sdinak */ 575*17Sdinak static CK_RV 576*17Sdinak write_cert(CK_SESSION_HANDLE sess, X509 *cert) 577*17Sdinak { 578*17Sdinak CK_RV rv = CKR_OK; 579*17Sdinak int i = 0; 580*17Sdinak static CK_OBJECT_CLASS objclass = CKO_CERTIFICATE; 581*17Sdinak static CK_CERTIFICATE_TYPE certtype = CKC_X_509; 582*17Sdinak CK_BYTE *subject = NULL; 583*17Sdinak CK_ULONG subject_len = 0; 584*17Sdinak CK_BYTE *value = NULL; 585*17Sdinak CK_ULONG value_len = 0; 586*17Sdinak CK_BYTE *label = NULL; 587*17Sdinak CK_ULONG label_len = 0; 588*17Sdinak CK_BYTE *id = NULL; 589*17Sdinak CK_ULONG id_len = 0; 590*17Sdinak CK_BYTE *issuer = NULL; 591*17Sdinak CK_ULONG issuer_len = 0; 592*17Sdinak CK_BYTE *serial = NULL; 593*17Sdinak CK_ULONG serial_len = 0; 594*17Sdinak CK_ATTRIBUTE cert_attrs[9] = { 595*17Sdinak { CKA_CLASS, &objclass, sizeof (objclass) }, 596*17Sdinak { CKA_CERTIFICATE_TYPE, &certtype, sizeof (certtype) }, 597*17Sdinak { CKA_TOKEN, &pk_true, sizeof (pk_true) }, 598*17Sdinak { CKA_SUBJECT, NULL, 0 }, /* required */ 599*17Sdinak { CKA_VALUE, NULL, 0 }, /* required */ 600*17Sdinak { 0 /* CKA_LABEL */, NULL, 0 }, /* optional */ 601*17Sdinak { 0 /* CKA_ID */, NULL, 0 }, /* optional */ 602*17Sdinak { 0 /* CKA_ISSUER */, NULL, 0 }, /* optional */ 603*17Sdinak { 0 /* CKA_SERIAL_NUMBER */, NULL, 0 } /* optional */ 604*17Sdinak }; 605*17Sdinak CK_ULONG count = sizeof (cert_attrs) / sizeof (CK_ATTRIBUTE); 606*17Sdinak CK_OBJECT_HANDLE obj; 607*17Sdinak 608*17Sdinak cryptodebug("inside write_cert"); 609*17Sdinak 610*17Sdinak /* Attributes start at array index 3. */ 611*17Sdinak i = 3; 612*17Sdinak 613*17Sdinak /* 614*17Sdinak * OpenSSL subject name and issuer (a little further below) are 615*17Sdinak * actually stack structures that contain individual ASN.1 616*17Sdinak * components. This stack of entries is packed into one DER string. 617*17Sdinak */ 618*17Sdinak cryptodebug("calling PKTOOL_X509_subject_name"); 619*17Sdinak if ((subject = PKTOOL_X509_subject_name(cert, (int *)&subject_len)) == 620*17Sdinak NULL) { 621*17Sdinak subject = (CK_BYTE *)gettext("no subject name"); 622*17Sdinak subject_len = strlen((char *)subject); 623*17Sdinak } 624*17Sdinak copy_string_to_attr(subject, subject_len, &(cert_attrs[i++])); 625*17Sdinak 626*17Sdinak /* Get cert value, but it has to be reconstructed from cert. */ 627*17Sdinak cryptodebug("calling PKTOOL_X509_cert_value"); 628*17Sdinak if ((value = PKTOOL_X509_cert_value(cert, (int *)&value_len)) == NULL) { 629*17Sdinak value = (CK_BYTE *)gettext("no value"); 630*17Sdinak value_len = strlen((char *)value); 631*17Sdinak } 632*17Sdinak copy_string_to_attr(value, value_len, &(cert_attrs[i++])); 633*17Sdinak 634*17Sdinak /* 635*17Sdinak * Get certificate label which is "friendlyName" Netscape, 636*17Sdinak * "alias" in OpenSSL. 637*17Sdinak */ 638*17Sdinak if ((label = X509_alias_get0(cert, (int *)&label_len)) == NULL) { 639*17Sdinak cryptodebug("no certificate label"); 640*17Sdinak } else { 641*17Sdinak cert_attrs[i].type = CKA_LABEL; 642*17Sdinak copy_string_to_attr(label, label_len, &(cert_attrs[i++])); 643*17Sdinak } 644*17Sdinak 645*17Sdinak /* Get the keyid for the cert. */ 646*17Sdinak if ((id = PKTOOL_X509_keyid_get0(cert, (int *)&id_len)) == NULL) { 647*17Sdinak cryptodebug("no certificate id"); 648*17Sdinak } else { 649*17Sdinak cert_attrs[i].type = CKA_ID; 650*17Sdinak copy_string_to_attr(id, id_len, &(cert_attrs[i++])); 651*17Sdinak } 652*17Sdinak 653*17Sdinak /* Get the issuer name for the cert. */ 654*17Sdinak if ((issuer = PKTOOL_X509_issuer_name(cert, (int *)&issuer_len)) == 655*17Sdinak NULL) { 656*17Sdinak cryptodebug("no certificate issuer name"); 657*17Sdinak } else { 658*17Sdinak cert_attrs[i].type = CKA_ISSUER; 659*17Sdinak copy_string_to_attr(issuer, issuer_len, &(cert_attrs[i++])); 660*17Sdinak } 661*17Sdinak 662*17Sdinak /* Get the cert serial number. */ 663*17Sdinak if ((serial = PKTOOL_X509_serial_number(cert, (int *)&serial_len)) == 664*17Sdinak NULL) { 665*17Sdinak cryptodebug("no certificate serial number"); 666*17Sdinak } else { 667*17Sdinak cert_attrs[i].type = CKA_SERIAL_NUMBER; 668*17Sdinak copy_string_to_attr(serial, serial_len, &(cert_attrs[i++])); 669*17Sdinak } 670*17Sdinak 671*17Sdinak /* Indicates programming error: attributes overran the template */ 672*17Sdinak if (i > count) { 673*17Sdinak cryptodebug("error: more attributes found than accounted for"); 674*17Sdinak i = count; 675*17Sdinak } 676*17Sdinak 677*17Sdinak cryptodebug("calling C_CreateObject"); 678*17Sdinak if ((rv = C_CreateObject(sess, cert_attrs, i, &obj)) != CKR_OK) { 679*17Sdinak cryptoerror(LOG_STDERR, gettext( 680*17Sdinak "Unable to create X.509 certificate object.")); 681*17Sdinak return (rv); 682*17Sdinak } 683*17Sdinak 684*17Sdinak return (CKR_OK); 685*17Sdinak } 686*17Sdinak 687*17Sdinak /* 688*17Sdinak * Helper function to write PKCS#12 items to token. Returns CKR_OK 689*17Sdinak * or CKR_GENERAL_ERROR 690*17Sdinak */ 691*17Sdinak static CK_RV 692*17Sdinak write_token_objs(CK_SESSION_HANDLE sess, EVP_PKEY *priv_key, X509 *cert, 693*17Sdinak STACK_OF(X509) *ca, int *successes, int *failures) 694*17Sdinak { 695*17Sdinak int i; 696*17Sdinak X509 *c; 697*17Sdinak CK_RV rv = CKR_OK; 698*17Sdinak 699*17Sdinak cryptodebug("inside write_token_objs"); 700*17Sdinak 701*17Sdinak /* Do not reset *successes or *failures -- keep running totals. */ 702*17Sdinak 703*17Sdinak /* Import user key. */ 704*17Sdinak switch (priv_key->type) { 705*17Sdinak case EVP_PKEY_RSA: 706*17Sdinak (void) fprintf(stdout, gettext("Writing RSA private key...\n")); 707*17Sdinak if ((rv = write_rsa_private(sess, 708*17Sdinak EVP_PKEY_get1_RSA(priv_key), cert)) != CKR_OK) { 709*17Sdinak cryptoerror(LOG_STDERR, gettext( 710*17Sdinak "Unable to write RSA private key (%s)."), 711*17Sdinak pkcs11_strerror(rv)); 712*17Sdinak (*failures)++; 713*17Sdinak } else 714*17Sdinak (*successes)++; 715*17Sdinak break; 716*17Sdinak case EVP_PKEY_DSA: 717*17Sdinak (void) fprintf(stdout, gettext("Writing DSA private key...\n")); 718*17Sdinak if ((rv = write_dsa_private(sess, 719*17Sdinak EVP_PKEY_get1_DSA(priv_key), cert)) != CKR_OK) { 720*17Sdinak cryptoerror(LOG_STDERR, gettext( 721*17Sdinak "Unable to write DSA private key (%s)."), 722*17Sdinak pkcs11_strerror(rv)); 723*17Sdinak (*failures)++; 724*17Sdinak } else 725*17Sdinak (*successes)++; 726*17Sdinak break; 727*17Sdinak case EVP_PKEY_DH: 728*17Sdinak (void) fprintf(stdout, gettext("Writing DH private key...\n")); 729*17Sdinak if ((rv = write_dh_private(sess, 730*17Sdinak EVP_PKEY_get1_DH(priv_key), cert)) != CKR_OK) { 731*17Sdinak cryptoerror(LOG_STDERR, gettext( 732*17Sdinak "Unable to write DH private key (%s)."), 733*17Sdinak pkcs11_strerror(rv)); 734*17Sdinak (*failures)++; 735*17Sdinak } else 736*17Sdinak (*successes)++; 737*17Sdinak break; 738*17Sdinak 739*17Sdinak default: 740*17Sdinak /* 741*17Sdinak * Note that EVP_PKEY_DH for X9.42 is not implemented 742*17Sdinak * in the OpenSSL library. 743*17Sdinak */ 744*17Sdinak cryptoerror(LOG_STDERR, gettext( 745*17Sdinak "Private key type 0x%02x import not supported."), 746*17Sdinak priv_key->type); 747*17Sdinak (*failures)++; 748*17Sdinak break; 749*17Sdinak } 750*17Sdinak 751*17Sdinak /* Import user certificate. */ 752*17Sdinak (void) fprintf(stdout, gettext("Writing user certificate...\n")); 753*17Sdinak if ((rv = write_cert(sess, cert)) != CKR_OK) { 754*17Sdinak cryptoerror(LOG_STDERR, gettext( 755*17Sdinak "Unable to write user certificate (%s)."), 756*17Sdinak pkcs11_strerror(rv)); 757*17Sdinak (*failures)++; 758*17Sdinak } else 759*17Sdinak (*successes)++; 760*17Sdinak 761*17Sdinak /* Import as many stacks of authority certificates as possible. */ 762*17Sdinak for (i = 0; i != sk_X509_num(ca); i++) { 763*17Sdinak /* 764*17Sdinak * sk_X509_value() is macro that embeds a cast to (X509 *). 765*17Sdinak * Here it translates into ((X509 *)sk_value((ca), (i))). 766*17Sdinak * Lint is complaining about the embedded casting, and 767*17Sdinak * to fix it, you need to fix openssl header files. 768*17Sdinak */ 769*17Sdinak /* LINTED E_BAD_PTR_CAST_ALIGN */ 770*17Sdinak c = sk_X509_value(ca, i); 771*17Sdinak (void) fprintf(stdout, gettext( 772*17Sdinak "Writing authority certificate...\n")); 773*17Sdinak if ((rv = write_cert(sess, c)) != CKR_OK) { 774*17Sdinak cryptoerror(LOG_STDERR, gettext( 775*17Sdinak "Unable to write authority certificate (%s)."), 776*17Sdinak pkcs11_strerror(rv)); 777*17Sdinak (*failures)++; 778*17Sdinak } else 779*17Sdinak (*successes)++; 780*17Sdinak } 781*17Sdinak 782*17Sdinak (void) fprintf(stdout, gettext("PKCS#12 element scan completed.\n")); 783*17Sdinak return (*failures != 0 ? CKR_GENERAL_ERROR : CKR_OK); 784*17Sdinak } 785*17Sdinak 786*17Sdinak /* 787*17Sdinak * Import objects from PKCS#12 file into token. 788*17Sdinak */ 789*17Sdinak int 790*17Sdinak pk_import(int argc, char *argv[]) 791*17Sdinak { 792*17Sdinak char *token_name = NULL; 793*17Sdinak char *manuf_id = NULL; 794*17Sdinak char *serial_no = NULL; 795*17Sdinak char full_name[FULL_NAME_LEN]; 796*17Sdinak char *filename = NULL; 797*17Sdinak struct stat statbuf; 798*17Sdinak CK_SLOT_ID slot_id; 799*17Sdinak CK_FLAGS pin_state; 800*17Sdinak CK_UTF8CHAR_PTR pin = NULL; 801*17Sdinak CK_ULONG pinlen = 0; 802*17Sdinak CK_UTF8CHAR_PTR pk12pin = NULL; 803*17Sdinak CK_ULONG pk12pinlen = 0; 804*17Sdinak CK_SESSION_HANDLE sess; 805*17Sdinak BIO *fbio = NULL; 806*17Sdinak EVP_PKEY *priv_key = NULL; 807*17Sdinak X509 *cert = NULL; 808*17Sdinak STACK_OF(X509) *ca = NULL; 809*17Sdinak CK_RV rv = CKR_OK; 810*17Sdinak int i; 811*17Sdinak int good_count = 0, bad_count = 0; /* running totals */ 812*17Sdinak 813*17Sdinak cryptodebug("inside pk_import"); 814*17Sdinak 815*17Sdinak /* Get rid of subcommand word "import". */ 816*17Sdinak argc--; 817*17Sdinak argv++; 818*17Sdinak 819*17Sdinak /* One additional arg required: filename. */ 820*17Sdinak if (argc != 1) 821*17Sdinak return (PK_ERR_USAGE); 822*17Sdinak 823*17Sdinak filename = argv[0]; 824*17Sdinak /* Done parsing command line options. */ 825*17Sdinak 826*17Sdinak /* Check that the file exists and is non-empty. */ 827*17Sdinak if (access(filename, R_OK) < 0) { 828*17Sdinak cryptoerror(LOG_STDERR, gettext("File \"%s\" is unreadable " 829*17Sdinak "(%s)."), filename, strerror(errno)); 830*17Sdinak return (CKR_OK); 831*17Sdinak } 832*17Sdinak if (stat(filename, &statbuf) < 0) { 833*17Sdinak cryptoerror(LOG_STDERR, gettext("Unable to get size of " 834*17Sdinak "file \"%s\" (%s)."), filename, strerror(errno)); 835*17Sdinak return (CKR_OK); 836*17Sdinak } 837*17Sdinak if (statbuf.st_size == 0) { 838*17Sdinak cryptoerror(LOG_STDERR, gettext("File \"%s\" is empty."), 839*17Sdinak filename); 840*17Sdinak return (CKR_OK); 841*17Sdinak } 842*17Sdinak 843*17Sdinak /* Import operation only supported on softtoken. */ 844*17Sdinak if (token_name == NULL) 845*17Sdinak token_name = SOFT_TOKEN_LABEL; 846*17Sdinak if (manuf_id == NULL) 847*17Sdinak manuf_id = SOFT_MANUFACTURER_ID; 848*17Sdinak if (serial_no == NULL) 849*17Sdinak serial_no = SOFT_TOKEN_SERIAL; 850*17Sdinak full_token_name(token_name, manuf_id, serial_no, full_name); 851*17Sdinak 852*17Sdinak /* Find the slot with token. */ 853*17Sdinak if ((rv = find_token_slot(token_name, manuf_id, serial_no, &slot_id, 854*17Sdinak &pin_state)) != CKR_OK) { 855*17Sdinak cryptoerror(LOG_STDERR, gettext( 856*17Sdinak "Unable to find token %s (%s)."), full_name, 857*17Sdinak pkcs11_strerror(rv)); 858*17Sdinak return (PK_ERR_PK11); 859*17Sdinak } 860*17Sdinak 861*17Sdinak /* Get the user's PIN. */ 862*17Sdinak if ((rv = get_pin(gettext("Enter token passphrase:"), NULL, &pin, 863*17Sdinak &pinlen)) != CKR_OK) { 864*17Sdinak cryptoerror(LOG_STDERR, gettext( 865*17Sdinak "Unable to get token passphrase (%s)."), 866*17Sdinak pkcs11_strerror(rv)); 867*17Sdinak quick_finish(NULL); 868*17Sdinak return (PK_ERR_PK11); 869*17Sdinak } 870*17Sdinak 871*17Sdinak /* Assume user must be logged in R/W to import objects into token. */ 872*17Sdinak if ((rv = quick_start(slot_id, CKF_RW_SESSION, pin, pinlen, &sess)) != 873*17Sdinak CKR_OK) { 874*17Sdinak cryptoerror(LOG_STDERR, 875*17Sdinak gettext("Unable to log into token (%s)."), 876*17Sdinak pkcs11_strerror(rv)); 877*17Sdinak quick_finish(sess); 878*17Sdinak return (PK_ERR_PK11); 879*17Sdinak } 880*17Sdinak 881*17Sdinak /* Setup OpenSSL context. */ 882*17Sdinak PKTOOL_setup_openssl(); 883*17Sdinak 884*17Sdinak /* Open PKCS#12 file. */ 885*17Sdinak if ((open_pkcs12(filename, &fbio)) < 0) { 886*17Sdinak cryptoerror(LOG_STDERR, gettext("Unable to open import file.")); 887*17Sdinak quick_finish(sess); 888*17Sdinak return (PK_ERR_SYSTEM); 889*17Sdinak } 890*17Sdinak 891*17Sdinak /* Get the PIN for the PKCS#12 import file. */ 892*17Sdinak if ((rv = get_pin(gettext("Enter import file passphrase:"), NULL, 893*17Sdinak &pk12pin, &pk12pinlen)) != CKR_OK) { 894*17Sdinak cryptoerror(LOG_STDERR, gettext( 895*17Sdinak "Unable to get import file passphrase (%s)."), 896*17Sdinak pkcs11_strerror(rv)); 897*17Sdinak close_pkcs12(fbio); 898*17Sdinak quick_finish(sess); 899*17Sdinak return (PK_ERR_PK11); 900*17Sdinak } 901*17Sdinak 902*17Sdinak /* PKCS#12 import file may have multiple elements, loop until done. */ 903*17Sdinak for (i = 0; /* */; i++) { 904*17Sdinak /* Extract the contents of the PKCS#12 import file. */ 905*17Sdinak if ((rv = extract_pkcs12(fbio, pk12pin, pk12pinlen, &priv_key, 906*17Sdinak &cert, &ca)) != CKR_OK) { 907*17Sdinak cryptoerror(LOG_STDERR, gettext( 908*17Sdinak "Unable to parse PKCS#12 element #%d " 909*17Sdinak "in import file (%s)."), i+1, pkcs11_strerror(rv)); 910*17Sdinak close_pkcs12(fbio); 911*17Sdinak quick_finish(sess); 912*17Sdinak return (PK_ERR_OPENSSL); 913*17Sdinak } 914*17Sdinak 915*17Sdinak /* Reached end of import file? */ 916*17Sdinak if (rv == CKR_OK && priv_key == NULL && cert == NULL && 917*17Sdinak ca == NULL) 918*17Sdinak break; 919*17Sdinak 920*17Sdinak (void) fprintf(stdout, gettext( 921*17Sdinak "Scanning PKCS#12 element #%d for objects...\n"), i+1); 922*17Sdinak 923*17Sdinak /* Write the objects to the token. */ 924*17Sdinak if ((rv = write_token_objs(sess, priv_key, cert, ca, 925*17Sdinak &good_count, &bad_count)) != CKR_OK) { 926*17Sdinak cryptoerror(LOG_STDERR, gettext( 927*17Sdinak "Unable to write PKCS#12 element #%d to token %s."), 928*17Sdinak i+1, full_name); 929*17Sdinak close_pkcs12(fbio); 930*17Sdinak quick_finish(sess); 931*17Sdinak return (PK_ERR_PK11); 932*17Sdinak } 933*17Sdinak } 934*17Sdinak 935*17Sdinak (void) fprintf(stdout, gettext("%d PKCS#12 elements scanned: " 936*17Sdinak "%d objects imported, %d errors occurred.\n"), i, 937*17Sdinak good_count, bad_count); 938*17Sdinak 939*17Sdinak /* Close PKCS#12 file. */ 940*17Sdinak close_pkcs12(fbio); 941*17Sdinak 942*17Sdinak /* Clean up. */ 943*17Sdinak quick_finish(sess); 944*17Sdinak return (0); 945*17Sdinak } 946