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