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