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