1 /*	$NetBSD: pkcs11rsa_link.c,v 1.1.1.5 2015/09/03 07:21:37 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /* Id */
20 
21 #ifdef PKCS11CRYPTO
22 
23 #include <config.h>
24 
25 #include <isc/entropy.h>
26 #include <isc/md5.h>
27 #include <isc/sha1.h>
28 #include <isc/sha2.h>
29 #include <isc/mem.h>
30 #include <isc/string.h>
31 #include <isc/util.h>
32 
33 #include <dst/result.h>
34 
35 #include "dst_internal.h"
36 #include "dst_parse.h"
37 #include "dst_pkcs11.h"
38 
39 #include <pk11/internal.h>
40 
41 /*
42  * Limit the size of public exponents.
43  */
44 #ifndef RSA_MAX_PUBEXP_BITS
45 #define RSA_MAX_PUBEXP_BITS    35
46 #endif
47 
48 #define DST_RET(a) {ret = a; goto err;}
49 
50 static CK_BBOOL truevalue = TRUE;
51 static CK_BBOOL falsevalue = FALSE;
52 
53 static isc_result_t pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data);
54 static void pkcs11rsa_destroy(dst_key_t *key);
55 static isc_result_t pkcs11rsa_fetch(dst_key_t *key, const char *engine,
56 				    const char *label, dst_key_t *pub);
57 
58 static isc_result_t
59 pkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) {
60 	CK_RV rv;
61 	CK_MECHANISM mech = { 0, NULL, 0 };
62 	CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
63 	CK_KEY_TYPE keyType = CKK_RSA;
64 	CK_ATTRIBUTE keyTemplate[] =
65 	{
66 		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
67 		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
68 		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
69 		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
70 		{ CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
71 		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
72 		{ CKA_MODULUS, NULL, 0 },
73 		{ CKA_PUBLIC_EXPONENT, NULL, 0 },
74 		{ CKA_PRIVATE_EXPONENT, NULL, 0 },
75 		{ CKA_PRIME_1, NULL, 0 },
76 		{ CKA_PRIME_2, NULL, 0 },
77 		{ CKA_EXPONENT_1, NULL, 0 },
78 		{ CKA_EXPONENT_2, NULL, 0 },
79 		{ CKA_COEFFICIENT, NULL, 0 }
80 	};
81 	CK_ATTRIBUTE *attr;
82 	CK_SLOT_ID slotid;
83 	pk11_object_t *rsa;
84 	pk11_context_t *pk11_ctx;
85 	isc_result_t ret;
86 	unsigned int i;
87 
88 	REQUIRE(key->key_alg == DST_ALG_RSAMD5 ||
89 		key->key_alg == DST_ALG_RSASHA1 ||
90 		key->key_alg == DST_ALG_NSEC3RSASHA1 ||
91 		key->key_alg == DST_ALG_RSASHA256 ||
92 		key->key_alg == DST_ALG_RSASHA512);
93 
94 	rsa = key->keydata.pkey;
95 
96 	pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
97 						  sizeof(*pk11_ctx));
98 	if (pk11_ctx == NULL)
99 		return (ISC_R_NOMEMORY);
100 	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
101 	if (rsa->ontoken)
102 		slotid = rsa->slot;
103 	else
104 		slotid = pk11_get_best_token(OP_RSA);
105 	ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
106 			       rsa->reqlogon, NULL, slotid);
107 	if (ret != ISC_R_SUCCESS)
108 		goto err;
109 
110 	if (rsa->ontoken && (rsa->object != CK_INVALID_HANDLE)) {
111 		pk11_ctx->ontoken = rsa->ontoken;
112 		pk11_ctx->object = rsa->object;
113 		goto token_key;
114 	}
115 
116 	for (attr = pk11_attribute_first(rsa);
117 	     attr != NULL;
118 	     attr = pk11_attribute_next(rsa, attr))
119 		switch (attr->type) {
120 		case CKA_MODULUS:
121 			INSIST(keyTemplate[6].type == attr->type);
122 			keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
123 							    attr->ulValueLen);
124 			if (keyTemplate[6].pValue == NULL)
125 				DST_RET(ISC_R_NOMEMORY);
126 			memmove(keyTemplate[6].pValue, attr->pValue,
127 				attr->ulValueLen);
128 			keyTemplate[6].ulValueLen = attr->ulValueLen;
129 			break;
130 		case CKA_PUBLIC_EXPONENT:
131 			INSIST(keyTemplate[7].type == attr->type);
132 			keyTemplate[7].pValue = isc_mem_get(dctx->mctx,
133 							    attr->ulValueLen);
134 			if (keyTemplate[7].pValue == NULL)
135 				DST_RET(ISC_R_NOMEMORY);
136 			memmove(keyTemplate[7].pValue, attr->pValue,
137 				attr->ulValueLen);
138 			keyTemplate[7].ulValueLen = attr->ulValueLen;
139 			break;
140 		case CKA_PRIVATE_EXPONENT:
141 			INSIST(keyTemplate[8].type == attr->type);
142 			keyTemplate[8].pValue = isc_mem_get(dctx->mctx,
143 							    attr->ulValueLen);
144 			if (keyTemplate[8].pValue == NULL)
145 				DST_RET(ISC_R_NOMEMORY);
146 			memmove(keyTemplate[8].pValue, attr->pValue,
147 				attr->ulValueLen);
148 			keyTemplate[8].ulValueLen = attr->ulValueLen;
149 			break;
150 		case CKA_PRIME_1:
151 			INSIST(keyTemplate[9].type == attr->type);
152 			keyTemplate[9].pValue = isc_mem_get(dctx->mctx,
153 							    attr->ulValueLen);
154 			if (keyTemplate[9].pValue == NULL)
155 				DST_RET(ISC_R_NOMEMORY);
156 			memmove(keyTemplate[9].pValue, attr->pValue,
157 				attr->ulValueLen);
158 			keyTemplate[9].ulValueLen = attr->ulValueLen;
159 			break;
160 		case CKA_PRIME_2:
161 			INSIST(keyTemplate[10].type == attr->type);
162 			keyTemplate[10].pValue = isc_mem_get(dctx->mctx,
163 							    attr->ulValueLen);
164 			if (keyTemplate[10].pValue == NULL)
165 				DST_RET(ISC_R_NOMEMORY);
166 			memmove(keyTemplate[10].pValue, attr->pValue,
167 				attr->ulValueLen);
168 			keyTemplate[10].ulValueLen = attr->ulValueLen;
169 			break;
170 		case CKA_EXPONENT_1:
171 			INSIST(keyTemplate[11].type == attr->type);
172 			keyTemplate[11].pValue = isc_mem_get(dctx->mctx,
173 							     attr->ulValueLen);
174 			if (keyTemplate[11].pValue == NULL)
175 				DST_RET(ISC_R_NOMEMORY);
176 			memmove(keyTemplate[11].pValue, attr->pValue,
177 				attr->ulValueLen);
178 			keyTemplate[11].ulValueLen = attr->ulValueLen;
179 			break;
180 		case CKA_EXPONENT_2:
181 			INSIST(keyTemplate[12].type == attr->type);
182 			keyTemplate[12].pValue = isc_mem_get(dctx->mctx,
183 							     attr->ulValueLen);
184 			if (keyTemplate[12].pValue == NULL)
185 				DST_RET(ISC_R_NOMEMORY);
186 			memmove(keyTemplate[12].pValue, attr->pValue,
187 				attr->ulValueLen);
188 			keyTemplate[12].ulValueLen = attr->ulValueLen;
189 			break;
190 		case CKA_COEFFICIENT:
191 			INSIST(keyTemplate[13].type == attr->type);
192 			keyTemplate[13].pValue = isc_mem_get(dctx->mctx,
193 							     attr->ulValueLen);
194 			if (keyTemplate[13].pValue == NULL)
195 				DST_RET(ISC_R_NOMEMORY);
196 			memmove(keyTemplate[13].pValue, attr->pValue,
197 				attr->ulValueLen);
198 			keyTemplate[13].ulValueLen = attr->ulValueLen;
199 			break;
200 		}
201 	pk11_ctx->object = CK_INVALID_HANDLE;
202 	pk11_ctx->ontoken = ISC_FALSE;
203 	PK11_RET(pkcs_C_CreateObject,
204 		 (pk11_ctx->session,
205 		  keyTemplate, (CK_ULONG) 14,
206 		  &pk11_ctx->object),
207 		 ISC_R_FAILURE);
208 
209     token_key:
210 
211 	switch (dctx->key->key_alg) {
212 	case DST_ALG_RSAMD5:
213 		mech.mechanism = CKM_MD5_RSA_PKCS;
214 		break;
215 	case DST_ALG_RSASHA1:
216 	case DST_ALG_NSEC3RSASHA1:
217 		mech.mechanism = CKM_SHA1_RSA_PKCS;
218 		break;
219 	case DST_ALG_RSASHA256:
220 		mech.mechanism = CKM_SHA256_RSA_PKCS;
221 		break;
222 	case DST_ALG_RSASHA512:
223 		mech.mechanism = CKM_SHA512_RSA_PKCS;
224 		break;
225 	default:
226 		INSIST(0);
227 	}
228 
229 	PK11_RET(pkcs_C_SignInit,
230 		 (pk11_ctx->session, &mech, pk11_ctx->object),
231 		 ISC_R_FAILURE);
232 
233 	dctx->ctxdata.pk11_ctx = pk11_ctx;
234 
235 	for (i = 6; i <= 13; i++)
236 		if (keyTemplate[i].pValue != NULL) {
237 			memset(keyTemplate[i].pValue, 0,
238 			       keyTemplate[i].ulValueLen);
239 			isc_mem_put(dctx->mctx,
240 				    keyTemplate[i].pValue,
241 				    keyTemplate[i].ulValueLen);
242 		}
243 
244 	return (ISC_R_SUCCESS);
245 
246     err:
247 	if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE))
248 		(void) pkcs_C_DestroyObject(pk11_ctx->session,
249 					    pk11_ctx->object);
250 	for (i = 6; i <= 13; i++)
251 		if (keyTemplate[i].pValue != NULL) {
252 			memset(keyTemplate[i].pValue, 0,
253 			       keyTemplate[i].ulValueLen);
254 			isc_mem_put(dctx->mctx,
255 				    keyTemplate[i].pValue,
256 				    keyTemplate[i].ulValueLen);
257 		}
258 	pk11_return_session(pk11_ctx);
259 	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
260 	isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
261 
262 	return (ret);
263 }
264 
265 static isc_result_t
266 pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits,
267 			   dst_context_t *dctx) {
268 	CK_RV rv;
269 	CK_MECHANISM mech = { 0, NULL, 0 };
270 	CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
271 	CK_KEY_TYPE keyType = CKK_RSA;
272 	CK_ATTRIBUTE keyTemplate[] =
273 	{
274 		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
275 		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
276 		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
277 		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
278 		{ CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
279 		{ CKA_MODULUS, NULL, 0 },
280 		{ CKA_PUBLIC_EXPONENT, NULL, 0 },
281 	};
282 	CK_ATTRIBUTE *attr;
283 	pk11_object_t *rsa;
284 	pk11_context_t *pk11_ctx;
285 	isc_result_t ret;
286 	unsigned int i;
287 
288 	REQUIRE(key->key_alg == DST_ALG_RSAMD5 ||
289 		key->key_alg == DST_ALG_RSASHA1 ||
290 		key->key_alg == DST_ALG_NSEC3RSASHA1 ||
291 		key->key_alg == DST_ALG_RSASHA256 ||
292 		key->key_alg == DST_ALG_RSASHA512);
293 
294 	rsa = key->keydata.pkey;
295 
296 	pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
297 						  sizeof(*pk11_ctx));
298 	if (pk11_ctx == NULL)
299 		return (ISC_R_NOMEMORY);
300 	ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
301 			       rsa->reqlogon, NULL,
302 			       pk11_get_best_token(OP_RSA));
303 	if (ret != ISC_R_SUCCESS)
304 		goto err;
305 
306 	for (attr = pk11_attribute_first(rsa);
307 	     attr != NULL;
308 	     attr = pk11_attribute_next(rsa, attr))
309 		switch (attr->type) {
310 		case CKA_MODULUS:
311 			INSIST(keyTemplate[5].type == attr->type);
312 			keyTemplate[5].pValue = isc_mem_get(dctx->mctx,
313 							    attr->ulValueLen);
314 			if (keyTemplate[5].pValue == NULL)
315 				DST_RET(ISC_R_NOMEMORY);
316 			memmove(keyTemplate[5].pValue, attr->pValue,
317 				attr->ulValueLen);
318 			keyTemplate[5].ulValueLen = attr->ulValueLen;
319 			break;
320 		case CKA_PUBLIC_EXPONENT:
321 			INSIST(keyTemplate[6].type == attr->type);
322 			keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
323 							    attr->ulValueLen);
324 			if (keyTemplate[6].pValue == NULL)
325 				DST_RET(ISC_R_NOMEMORY);
326 			memmove(keyTemplate[6].pValue, attr->pValue,
327 				attr->ulValueLen);
328 			keyTemplate[6].ulValueLen = attr->ulValueLen;
329 			if (pk11_numbits(attr->pValue,
330 					 attr->ulValueLen) > maxbits &&
331 			    maxbits != 0)
332 				DST_RET(DST_R_VERIFYFAILURE);
333 			break;
334 		}
335 	pk11_ctx->object = CK_INVALID_HANDLE;
336 	pk11_ctx->ontoken = ISC_FALSE;
337 	PK11_RET(pkcs_C_CreateObject,
338 		 (pk11_ctx->session,
339 		  keyTemplate, (CK_ULONG) 7,
340 		  &pk11_ctx->object),
341 		 ISC_R_FAILURE);
342 
343 	switch (dctx->key->key_alg) {
344 	case DST_ALG_RSAMD5:
345 		mech.mechanism = CKM_MD5_RSA_PKCS;
346 		break;
347 	case DST_ALG_RSASHA1:
348 	case DST_ALG_NSEC3RSASHA1:
349 		mech.mechanism = CKM_SHA1_RSA_PKCS;
350 		break;
351 	case DST_ALG_RSASHA256:
352 		mech.mechanism = CKM_SHA256_RSA_PKCS;
353 		break;
354 	case DST_ALG_RSASHA512:
355 		mech.mechanism = CKM_SHA512_RSA_PKCS;
356 		break;
357 	default:
358 		INSIST(0);
359 	}
360 
361 	PK11_RET(pkcs_C_VerifyInit,
362 		 (pk11_ctx->session, &mech, pk11_ctx->object),
363 		 ISC_R_FAILURE);
364 
365 	dctx->ctxdata.pk11_ctx = pk11_ctx;
366 
367 	for (i = 5; i <= 6; i++)
368 		if (keyTemplate[i].pValue != NULL) {
369 			memset(keyTemplate[i].pValue, 0,
370 			       keyTemplate[i].ulValueLen);
371 			isc_mem_put(dctx->mctx,
372 				    keyTemplate[i].pValue,
373 				    keyTemplate[i].ulValueLen);
374 		}
375 
376 	return (ISC_R_SUCCESS);
377 
378     err:
379 	if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE))
380 		(void) pkcs_C_DestroyObject(pk11_ctx->session,
381 					    pk11_ctx->object);
382 	for (i = 5; i <= 6; i++)
383 		if (keyTemplate[i].pValue != NULL) {
384 			memset(keyTemplate[i].pValue, 0,
385 			       keyTemplate[i].ulValueLen);
386 			isc_mem_put(dctx->mctx,
387 				    keyTemplate[i].pValue,
388 				    keyTemplate[i].ulValueLen);
389 		}
390 	pk11_return_session(pk11_ctx);
391 	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
392 	isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
393 
394 	return (ret);
395 }
396 
397 static isc_result_t
398 pkcs11rsa_createctx(dst_key_t *key, dst_context_t *dctx) {
399 	if (dctx->use == DO_SIGN)
400 		return (pkcs11rsa_createctx_sign(key, dctx));
401 	else
402 		return (pkcs11rsa_createctx_verify(key, 0U, dctx));
403 }
404 
405 static isc_result_t
406 pkcs11rsa_createctx2(dst_key_t *key, int maxbits, dst_context_t *dctx) {
407 	if (dctx->use == DO_SIGN)
408 		return (pkcs11rsa_createctx_sign(key, dctx));
409 	else
410 		return (pkcs11rsa_createctx_verify(key,
411 						   (unsigned) maxbits, dctx));
412 }
413 
414 static void
415 pkcs11rsa_destroyctx(dst_context_t *dctx) {
416 	pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
417 
418 	if (pk11_ctx != NULL) {
419 		if (!pk11_ctx->ontoken &&
420 		    (pk11_ctx->object != CK_INVALID_HANDLE))
421 			(void) pkcs_C_DestroyObject(pk11_ctx->session,
422 						    pk11_ctx->object);
423 		pk11_return_session(pk11_ctx);
424 		memset(pk11_ctx, 0, sizeof(*pk11_ctx));
425 		isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
426 		dctx->ctxdata.pk11_ctx = NULL;
427 	}
428 }
429 
430 static isc_result_t
431 pkcs11rsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
432 	CK_RV rv;
433 	pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
434 	isc_result_t ret = ISC_R_SUCCESS;
435 
436 	if (dctx->use == DO_SIGN)
437 		PK11_CALL(pkcs_C_SignUpdate,
438 			  (pk11_ctx->session,
439 			   (CK_BYTE_PTR) data->base,
440 			   (CK_ULONG) data->length),
441 			  ISC_R_FAILURE);
442 	else
443 		PK11_CALL(pkcs_C_VerifyUpdate,
444 			  (pk11_ctx->session,
445 			   (CK_BYTE_PTR) data->base,
446 			   (CK_ULONG) data->length),
447 			  ISC_R_FAILURE);
448 	return (ret);
449 }
450 
451 static isc_result_t
452 pkcs11rsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
453 	CK_RV rv;
454 	CK_ULONG siglen = 0;
455 	isc_region_t r;
456 	pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
457 	isc_result_t ret = ISC_R_SUCCESS;
458 
459 	PK11_RET(pkcs_C_SignFinal,
460 		 (pk11_ctx->session, NULL, &siglen),
461 		 DST_R_SIGNFAILURE);
462 
463 	isc_buffer_availableregion(sig, &r);
464 
465 	if (r.length < (unsigned int) siglen)
466 		return (ISC_R_NOSPACE);
467 
468 	PK11_RET(pkcs_C_SignFinal,
469 		 (pk11_ctx->session, (CK_BYTE_PTR) r.base, &siglen),
470 		 DST_R_SIGNFAILURE);
471 
472 	isc_buffer_add(sig, (unsigned int) siglen);
473 
474     err:
475 	return (ret);
476 }
477 
478 static isc_result_t
479 pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
480 	CK_RV rv;
481 	pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
482 	isc_result_t ret = ISC_R_SUCCESS;
483 
484 	PK11_CALL(pkcs_C_VerifyFinal,
485 		  (pk11_ctx->session,
486 		   (CK_BYTE_PTR) sig->base,
487 		   (CK_ULONG) sig->length),
488 		  DST_R_VERIFYFAILURE);
489 	return (ret);
490 }
491 
492 static isc_boolean_t
493 pkcs11rsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
494 	pk11_object_t *rsa1, *rsa2;
495 	CK_ATTRIBUTE *attr1, *attr2;
496 
497 	rsa1 = key1->keydata.pkey;
498 	rsa2 = key2->keydata.pkey;
499 
500 	if ((rsa1 == NULL) && (rsa2 == NULL))
501 		return (ISC_TRUE);
502 	else if ((rsa1 == NULL) || (rsa2 == NULL))
503 		return (ISC_FALSE);
504 
505 	attr1 = pk11_attribute_bytype(rsa1, CKA_MODULUS);
506 	attr2 = pk11_attribute_bytype(rsa2, CKA_MODULUS);
507 	if ((attr1 == NULL) && (attr2 == NULL))
508 		return (ISC_TRUE);
509 	else if ((attr1 == NULL) || (attr2 == NULL) ||
510 		 (attr1->ulValueLen != attr2->ulValueLen) ||
511 		 memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))
512 		return (ISC_FALSE);
513 
514 	attr1 = pk11_attribute_bytype(rsa1, CKA_PUBLIC_EXPONENT);
515 	attr2 = pk11_attribute_bytype(rsa2, CKA_PUBLIC_EXPONENT);
516 	if ((attr1 == NULL) && (attr2 == NULL))
517 		return (ISC_TRUE);
518 	else if ((attr1 == NULL) || (attr2 == NULL) ||
519 		 (attr1->ulValueLen != attr2->ulValueLen) ||
520 		 memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))
521 		return (ISC_FALSE);
522 
523 	attr1 = pk11_attribute_bytype(rsa1, CKA_PRIVATE_EXPONENT);
524 	attr2 = pk11_attribute_bytype(rsa2, CKA_PRIVATE_EXPONENT);
525 	if (((attr1 != NULL) || (attr2 != NULL)) &&
526 	    ((attr1 == NULL) || (attr2 == NULL) ||
527 	     (attr1->ulValueLen != attr2->ulValueLen) ||
528 	     memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)))
529 		return (ISC_FALSE);
530 
531 	if (!rsa1->ontoken && !rsa2->ontoken)
532 		return (ISC_TRUE);
533 	else if (rsa1->ontoken || rsa2->ontoken ||
534 		 (rsa1->object != rsa2->object))
535 		return (ISC_FALSE);
536 
537 	return (ISC_TRUE);
538 }
539 
540 static isc_result_t
541 pkcs11rsa_generate(dst_key_t *key, int exp, void (*callback)(int)) {
542 	CK_RV rv;
543 	CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0 };
544 	CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE;
545 	CK_ULONG bits = 0;
546 	CK_BYTE pubexp[5];
547 	CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
548 	CK_KEY_TYPE  keyType = CKK_RSA;
549 	CK_ATTRIBUTE pubTemplate[] =
550 	{
551 		{ CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) },
552 		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
553 		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
554 		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
555 		{ CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
556 		{ CKA_MODULUS_BITS, &bits, (CK_ULONG) sizeof(bits) },
557 		{ CKA_PUBLIC_EXPONENT, &pubexp, (CK_ULONG) sizeof(pubexp) }
558 	};
559 	CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE;
560 	CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
561 	CK_ATTRIBUTE privTemplate[] =
562 	{
563 		{ CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) },
564 		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
565 		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
566 		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
567 		{ CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
568 		{ CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) },
569 		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
570 	};
571 	CK_ATTRIBUTE *attr;
572 	pk11_object_t *rsa;
573 	pk11_context_t *pk11_ctx;
574 	isc_result_t ret;
575 	unsigned int i;
576 
577 	UNUSED(callback);
578 
579 	pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx,
580 						  sizeof(*pk11_ctx));
581 	if (pk11_ctx == NULL)
582 		return (ISC_R_NOMEMORY);
583 	ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
584 			       ISC_FALSE, NULL, pk11_get_best_token(OP_RSA));
585 	if (ret != ISC_R_SUCCESS)
586 		goto err;
587 
588 	bits = key->key_size;
589 	if (exp == 0) {
590 		/* RSA_F4 0x10001 */
591 		pubexp[0] = 1;
592 		pubexp[1] = 0;
593 		pubexp[2] = 1;
594 		pubTemplate[6].ulValueLen = 3;
595 	} else {
596 		/* F5 0x100000001 */
597 		pubexp[0] = 1;
598 		pubexp[1] = 0;
599 		pubexp[2] = 0;
600 		pubexp[3] = 0;
601 		pubexp[4] = 1;
602 		pubTemplate[6].ulValueLen = 5;
603 	}
604 
605 	PK11_RET(pkcs_C_GenerateKeyPair,
606 		 (pk11_ctx->session, &mech,
607 		  pubTemplate, (CK_ULONG) 7,
608 		  privTemplate, (CK_ULONG) 7,
609 		  &pub, &priv),
610 		 DST_R_CRYPTOFAILURE);
611 
612 	rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
613 	if (rsa == NULL)
614 		DST_RET(ISC_R_NOMEMORY);
615 	memset(rsa, 0, sizeof(*rsa));
616 	key->keydata.pkey = rsa;
617 	rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8);
618 	if (rsa->repr == NULL)
619 		DST_RET(ISC_R_NOMEMORY);
620 	memset(rsa->repr, 0, sizeof(*attr) * 8);
621 	rsa->attrcnt = 8;
622 
623 	attr = rsa->repr;
624 	attr[0].type = CKA_MODULUS;
625 	attr[1].type = CKA_PUBLIC_EXPONENT;
626 	attr[2].type = CKA_PRIVATE_EXPONENT;
627 	attr[3].type = CKA_PRIME_1;
628 	attr[4].type = CKA_PRIME_2;
629 	attr[5].type = CKA_EXPONENT_1;
630 	attr[6].type = CKA_EXPONENT_2;
631 	attr[7].type = CKA_COEFFICIENT;
632 
633 	PK11_RET(pkcs_C_GetAttributeValue,
634 		 (pk11_ctx->session, pub, attr, 2),
635 		 DST_R_CRYPTOFAILURE);
636 	for (i = 0; i <= 1; i++) {
637 		attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen);
638 		if (attr[i].pValue == NULL)
639 			DST_RET(ISC_R_NOMEMORY);
640 		memset(attr[i].pValue, 0, attr[i].ulValueLen);
641 	}
642 	PK11_RET(pkcs_C_GetAttributeValue,
643 		 (pk11_ctx->session, pub, attr, 2),
644 		 DST_R_CRYPTOFAILURE);
645 
646 	attr += 2;
647 	PK11_RET(pkcs_C_GetAttributeValue,
648 		 (pk11_ctx->session, priv, attr, 6),
649 		 DST_R_CRYPTOFAILURE);
650 	for (i = 0; i <= 5; i++) {
651 		attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen);
652 		if (attr[i].pValue == NULL)
653 			DST_RET(ISC_R_NOMEMORY);
654 		memset(attr[i].pValue, 0, attr[i].ulValueLen);
655 	}
656 	PK11_RET(pkcs_C_GetAttributeValue,
657 		 (pk11_ctx->session, priv, attr, 6),
658 		 DST_R_CRYPTOFAILURE);
659 
660 	(void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
661 	(void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
662 	pk11_return_session(pk11_ctx);
663 	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
664 	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
665 
666 	return (ISC_R_SUCCESS);
667 
668     err:
669 	pkcs11rsa_destroy(key);
670 	if (priv != CK_INVALID_HANDLE)
671 		(void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
672 	if (pub != CK_INVALID_HANDLE)
673 		(void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
674 	pk11_return_session(pk11_ctx);
675 	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
676 	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
677 
678 	return (ret);
679 }
680 
681 static isc_boolean_t
682 pkcs11rsa_isprivate(const dst_key_t *key) {
683 	pk11_object_t *rsa = key->keydata.pkey;
684 	CK_ATTRIBUTE *attr;
685 
686 	if (rsa == NULL)
687 		return (ISC_FALSE);
688 	attr = pk11_attribute_bytype(rsa, CKA_PRIVATE_EXPONENT);
689 	return (ISC_TF((attr != NULL) || rsa->ontoken));
690 }
691 
692 static void
693 pkcs11rsa_destroy(dst_key_t *key) {
694 	pk11_object_t *rsa = key->keydata.pkey;
695 	CK_ATTRIBUTE *attr;
696 
697 	if (rsa == NULL)
698 		return;
699 
700 	INSIST((rsa->object == CK_INVALID_HANDLE) || rsa->ontoken);
701 
702 	for (attr = pk11_attribute_first(rsa);
703 	     attr != NULL;
704 	     attr = pk11_attribute_next(rsa, attr))
705 		switch (attr->type) {
706 		case CKA_LABEL:
707 		case CKA_ID:
708 		case CKA_MODULUS:
709 		case CKA_PUBLIC_EXPONENT:
710 		case CKA_PRIVATE_EXPONENT:
711 		case CKA_PRIME_1:
712 		case CKA_PRIME_2:
713 		case CKA_EXPONENT_1:
714 		case CKA_EXPONENT_2:
715 		case CKA_COEFFICIENT:
716 			if (attr->pValue != NULL) {
717 				memset(attr->pValue, 0, attr->ulValueLen);
718 				isc_mem_put(key->mctx,
719 					    attr->pValue,
720 					    attr->ulValueLen);
721 			}
722 			break;
723 		}
724 	if (rsa->repr != NULL) {
725 		memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr));
726 		isc_mem_put(key->mctx,
727 			    rsa->repr,
728 			    rsa->attrcnt * sizeof(*attr));
729 	}
730 	memset(rsa, 0, sizeof(*rsa));
731 	isc_mem_put(key->mctx, rsa, sizeof(*rsa));
732 	key->keydata.pkey = NULL;
733 }
734 
735 static isc_result_t
736 pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data) {
737 	pk11_object_t *rsa;
738 	CK_ATTRIBUTE *attr;
739 	isc_region_t r;
740 	unsigned int e_bytes = 0, mod_bytes = 0;
741 	CK_BYTE *exponent = NULL, *modulus = NULL;
742 
743 	REQUIRE(key->keydata.pkey != NULL);
744 
745 	rsa = key->keydata.pkey;
746 
747 	for (attr = pk11_attribute_first(rsa);
748 	     attr != NULL;
749 	     attr = pk11_attribute_next(rsa, attr))
750 		switch (attr->type) {
751 		case CKA_PUBLIC_EXPONENT:
752 			exponent = (CK_BYTE *) attr->pValue;
753 			e_bytes = (unsigned int) attr->ulValueLen;
754 			break;
755 		case CKA_MODULUS:
756 			modulus = (CK_BYTE *) attr->pValue;
757 			mod_bytes = (unsigned int) attr->ulValueLen;
758 			break;
759 		}
760 	REQUIRE((exponent != NULL) && (modulus != NULL));
761 
762 	isc_buffer_availableregion(data, &r);
763 
764 	if (e_bytes < 256) {	/*%< key exponent is <= 2040 bits */
765 		if (r.length < 1)
766 			return (ISC_R_NOSPACE);
767 		isc_buffer_putuint8(data, (isc_uint8_t) e_bytes);
768 		isc_region_consume(&r, 1);
769 	} else {
770 		if (r.length < 3)
771 			return (ISC_R_NOSPACE);
772 		isc_buffer_putuint8(data, 0);
773 		isc_buffer_putuint16(data, (isc_uint16_t) e_bytes);
774 		isc_region_consume(&r, 3);
775 	}
776 
777 	if (r.length < e_bytes + mod_bytes)
778 		return (ISC_R_NOSPACE);
779 
780 	memmove(r.base, exponent, e_bytes);
781 	isc_region_consume(&r, e_bytes);
782 	memmove(r.base, modulus, mod_bytes);
783 
784 	isc_buffer_add(data, e_bytes + mod_bytes);
785 
786 	return (ISC_R_SUCCESS);
787 }
788 
789 static isc_result_t
790 pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
791 	pk11_object_t *rsa;
792 	isc_region_t r;
793 	unsigned int e_bytes, mod_bytes;
794 	CK_BYTE *exponent = NULL, *modulus = NULL;
795 	CK_ATTRIBUTE *attr;
796 	unsigned int length;
797 
798 	isc_buffer_remainingregion(data, &r);
799 	if (r.length == 0)
800 		return (ISC_R_SUCCESS);
801 	length = r.length;
802 
803 	rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
804 	if (rsa == NULL)
805 		return (ISC_R_NOMEMORY);
806 
807 	memset(rsa, 0, sizeof(*rsa));
808 
809 	e_bytes = *r.base;
810 	isc_region_consume(&r, 1);
811 
812 	if (e_bytes == 0) {
813 		if (r.length < 2) {
814 			memset(rsa, 0, sizeof(*rsa));
815 			isc_mem_put(key->mctx, rsa, sizeof(*rsa));
816 			return (DST_R_INVALIDPUBLICKEY);
817 		}
818 		e_bytes = (*r.base) << 8;
819 		isc_region_consume(&r, 1);
820 		e_bytes += *r.base;
821 		isc_region_consume(&r, 1);
822 	}
823 
824 	if (r.length < e_bytes) {
825 		memset(rsa, 0, sizeof(*rsa));
826 		isc_mem_put(key->mctx, rsa, sizeof(*rsa));
827 		return (DST_R_INVALIDPUBLICKEY);
828 	}
829 	exponent = r.base;
830 	isc_region_consume(&r, e_bytes);
831 	modulus = r.base;
832 	mod_bytes = r.length;
833 
834 	key->key_size = pk11_numbits(modulus, mod_bytes);
835 
836 	isc_buffer_forward(data, length);
837 
838 	rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2);
839 	if (rsa->repr == NULL)
840 		goto nomemory;
841 	memset(rsa->repr, 0, sizeof(*attr) * 2);
842 	rsa->attrcnt = 2;
843 	attr = rsa->repr;
844 	attr[0].type = CKA_MODULUS;
845 	attr[0].pValue = isc_mem_get(key->mctx, mod_bytes);
846 	if (attr[0].pValue == NULL)
847 		goto nomemory;
848 	memmove(attr[0].pValue, modulus, mod_bytes);
849 	attr[0].ulValueLen = (CK_ULONG) mod_bytes;
850 	attr[1].type = CKA_PUBLIC_EXPONENT;
851 	attr[1].pValue = isc_mem_get(key->mctx, e_bytes);
852 	if (attr[1].pValue == NULL)
853 		goto nomemory;
854 	memmove(attr[1].pValue, exponent, e_bytes);
855 	attr[1].ulValueLen = (CK_ULONG) e_bytes;
856 
857 	key->keydata.pkey = rsa;
858 
859 	return (ISC_R_SUCCESS);
860 
861     nomemory:
862 	for (attr = pk11_attribute_first(rsa);
863 	     attr != NULL;
864 	     attr = pk11_attribute_next(rsa, attr))
865 		switch (attr->type) {
866 		case CKA_MODULUS:
867 		case CKA_PUBLIC_EXPONENT:
868 			if (attr->pValue != NULL) {
869 				memset(attr->pValue, 0, attr->ulValueLen);
870 				isc_mem_put(key->mctx,
871 					    attr->pValue,
872 					    attr->ulValueLen);
873 			}
874 			break;
875 		}
876 	if (rsa->repr != NULL) {
877 		memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr));
878 		isc_mem_put(key->mctx,
879 			    rsa->repr,
880 			    rsa->attrcnt * sizeof(*attr));
881 	}
882 	memset(rsa, 0, sizeof(*rsa));
883 	isc_mem_put(key->mctx, rsa, sizeof(*rsa));
884 	return (ISC_R_NOMEMORY);
885 }
886 
887 static isc_result_t
888 pkcs11rsa_tofile(const dst_key_t *key, const char *directory) {
889 	int i;
890 	pk11_object_t *rsa;
891 	CK_ATTRIBUTE *attr;
892 	CK_ATTRIBUTE *modulus = NULL, *exponent = NULL;
893 	CK_ATTRIBUTE  *d = NULL, *p = NULL, *q = NULL;
894 	CK_ATTRIBUTE *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
895 	dst_private_t priv;
896 	unsigned char *bufs[10];
897 	isc_result_t result;
898 
899 	if (key->keydata.pkey == NULL)
900 		return (DST_R_NULLKEY);
901 
902 	if (key->external) {
903 		priv.nelements = 0;
904 		return (dst__privstruct_writefile(key, &priv, directory));
905 	}
906 
907 	rsa = key->keydata.pkey;
908 
909 	for (attr = pk11_attribute_first(rsa);
910 	     attr != NULL;
911 	     attr = pk11_attribute_next(rsa, attr))
912 		switch (attr->type) {
913 		case CKA_MODULUS:
914 			modulus = attr;
915 			break;
916 		case CKA_PUBLIC_EXPONENT:
917 			exponent = attr;
918 			break;
919 		case CKA_PRIVATE_EXPONENT:
920 			d = attr;
921 			break;
922 		case CKA_PRIME_1:
923 			p = attr;
924 			break;
925 		case CKA_PRIME_2:
926 			q = attr;
927 			break;
928 		case CKA_EXPONENT_1:
929 			dmp1 = attr;
930 			break;
931 		case CKA_EXPONENT_2:
932 			dmq1 = attr;
933 			break;
934 		case CKA_COEFFICIENT:
935 			iqmp = attr;
936 			break;
937 		}
938 	if ((modulus == NULL) || (exponent == NULL))
939 		return (DST_R_NULLKEY);
940 
941 	memset(bufs, 0, sizeof(bufs));
942 
943 	for (i = 0; i < 10; i++) {
944 		bufs[i] = isc_mem_get(key->mctx, modulus->ulValueLen);
945 		if (bufs[i] == NULL) {
946 			result = ISC_R_NOMEMORY;
947 			goto fail;
948 		}
949 		memset(bufs[i], 0, modulus->ulValueLen);
950 	}
951 
952 	i = 0;
953 
954 	priv.elements[i].tag = TAG_RSA_MODULUS;
955 	priv.elements[i].length = (unsigned short) modulus->ulValueLen;
956 	memmove(bufs[i], modulus->pValue, modulus->ulValueLen);
957 	priv.elements[i].data = bufs[i];
958 	i++;
959 
960 	priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT;
961 	priv.elements[i].length = (unsigned short) exponent->ulValueLen;
962 	memmove(bufs[i], exponent->pValue, exponent->ulValueLen);
963 	priv.elements[i].data = bufs[i];
964 	i++;
965 
966 	if (d != NULL) {
967 		priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT;
968 		priv.elements[i].length = (unsigned short) d->ulValueLen;
969 		memmove(bufs[i], d->pValue, d->ulValueLen);
970 		priv.elements[i].data = bufs[i];
971 		i++;
972 	}
973 
974 	if (p != NULL) {
975 		priv.elements[i].tag = TAG_RSA_PRIME1;
976 		priv.elements[i].length = (unsigned short) p->ulValueLen;
977 		memmove(bufs[i], p->pValue, p->ulValueLen);
978 		priv.elements[i].data = bufs[i];
979 		i++;
980 	}
981 
982 	if (q != NULL) {
983 		priv.elements[i].tag = TAG_RSA_PRIME2;
984 		priv.elements[i].length = (unsigned short) q->ulValueLen;
985 		memmove(bufs[i], q->pValue, q->ulValueLen);
986 		priv.elements[i].data = bufs[i];
987 		i++;
988 	}
989 
990 	if (dmp1 != NULL) {
991 		priv.elements[i].tag = TAG_RSA_EXPONENT1;
992 		priv.elements[i].length = (unsigned short) dmp1->ulValueLen;
993 		memmove(bufs[i], dmp1->pValue, dmp1->ulValueLen);
994 		priv.elements[i].data = bufs[i];
995 		i++;
996 	}
997 
998 	if (dmq1 != NULL) {
999 		priv.elements[i].tag = TAG_RSA_EXPONENT2;
1000 		priv.elements[i].length = (unsigned short) dmq1->ulValueLen;
1001 		memmove(bufs[i], dmq1->pValue, dmq1->ulValueLen);
1002 		priv.elements[i].data = bufs[i];
1003 		i++;
1004 	}
1005 
1006 	if (iqmp != NULL) {
1007 		priv.elements[i].tag = TAG_RSA_COEFFICIENT;
1008 		priv.elements[i].length = (unsigned short) iqmp->ulValueLen;
1009 		memmove(bufs[i], iqmp->pValue, iqmp->ulValueLen);
1010 		priv.elements[i].data = bufs[i];
1011 		i++;
1012 	}
1013 
1014 	if (key->engine != NULL) {
1015 		priv.elements[i].tag = TAG_RSA_ENGINE;
1016 		priv.elements[i].length = strlen(key->engine) + 1;
1017 		priv.elements[i].data = (unsigned char *)key->engine;
1018 		i++;
1019 	}
1020 
1021 	if (key->label != NULL) {
1022 		priv.elements[i].tag = TAG_RSA_LABEL;
1023 		priv.elements[i].length = strlen(key->label) + 1;
1024 		priv.elements[i].data = (unsigned char *)key->label;
1025 		i++;
1026 	}
1027 
1028 	priv.nelements = i;
1029 	result = dst__privstruct_writefile(key, &priv, directory);
1030  fail:
1031 	for (i = 0; i < 10; i++) {
1032 		if (bufs[i] == NULL)
1033 			break;
1034 		memset(bufs[i], 0, modulus->ulValueLen);
1035 		isc_mem_put(key->mctx, bufs[i], modulus->ulValueLen);
1036 	}
1037 	return (result);
1038 }
1039 
1040 static isc_result_t
1041 pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label,
1042 		dst_key_t *pub)
1043 {
1044 	CK_RV rv;
1045 	CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
1046 	CK_KEY_TYPE keyType = CKK_RSA;
1047 	CK_ATTRIBUTE searchTemplate[] =
1048 	{
1049 		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
1050 		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
1051 		{ CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) },
1052 		{ CKA_LABEL, NULL, 0 }
1053 	};
1054 	CK_ULONG cnt;
1055 	CK_ATTRIBUTE *attr;
1056 	CK_ATTRIBUTE *pubattr;
1057 	pk11_object_t *rsa;
1058 	pk11_object_t *pubrsa;
1059 	pk11_context_t *pk11_ctx = NULL;
1060 	isc_result_t ret;
1061 
1062 	if (label == NULL)
1063 		return (DST_R_NOENGINE);
1064 
1065 	rsa = key->keydata.pkey;
1066 	pubrsa = pub->keydata.pkey;
1067 
1068 	rsa->object = CK_INVALID_HANDLE;
1069 	rsa->ontoken = ISC_TRUE;
1070 	rsa->reqlogon = ISC_TRUE;
1071 	rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2);
1072 	if (rsa->repr == NULL)
1073 		return (ISC_R_NOMEMORY);
1074 	memset(rsa->repr, 0, sizeof(*attr) * 2);
1075 	rsa->attrcnt = 2;
1076 	attr = rsa->repr;
1077 
1078 	attr->type = CKA_MODULUS;
1079 	pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS);
1080 	attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
1081 	if (attr->pValue == NULL)
1082 		DST_RET(ISC_R_NOMEMORY);
1083 	memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen);
1084 	attr->ulValueLen = pubattr->ulValueLen;
1085 	attr++;
1086 
1087 	attr->type = CKA_PUBLIC_EXPONENT;
1088 	pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT);
1089 	attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
1090 	if (attr->pValue == NULL)
1091 		DST_RET(ISC_R_NOMEMORY);
1092 	memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen);
1093 	attr->ulValueLen = pubattr->ulValueLen;
1094 
1095 	ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA);
1096 	if (ret != ISC_R_SUCCESS)
1097 		goto err;
1098 
1099 	pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx,
1100 						  sizeof(*pk11_ctx));
1101 	if (pk11_ctx == NULL)
1102 		DST_RET(ISC_R_NOMEMORY);
1103 	ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
1104 			       rsa->reqlogon, NULL, rsa->slot);
1105 	if (ret != ISC_R_SUCCESS)
1106 		goto err;
1107 
1108 	attr = pk11_attribute_bytype(rsa, CKA_LABEL);
1109 	if (attr == NULL) {
1110 		attr = pk11_attribute_bytype(rsa, CKA_ID);
1111 		INSIST(attr != NULL);
1112 		searchTemplate[3].type = CKA_ID;
1113 	}
1114 	searchTemplate[3].pValue = attr->pValue;
1115 	searchTemplate[3].ulValueLen = attr->ulValueLen;
1116 
1117 	PK11_RET(pkcs_C_FindObjectsInit,
1118 		 (pk11_ctx->session, searchTemplate, (CK_ULONG) 4),
1119 		 DST_R_CRYPTOFAILURE);
1120 	PK11_RET(pkcs_C_FindObjects,
1121 		 (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt),
1122 		 DST_R_CRYPTOFAILURE);
1123 	(void) pkcs_C_FindObjectsFinal(pk11_ctx->session);
1124 	if (cnt == 0)
1125 		DST_RET(ISC_R_NOTFOUND);
1126 	if (cnt > 1)
1127 		DST_RET(ISC_R_EXISTS);
1128 
1129 	if (engine != NULL) {
1130 		key->engine = isc_mem_strdup(key->mctx, engine);
1131 		if (key->engine == NULL)
1132 			DST_RET(ISC_R_NOMEMORY);
1133 	}
1134 
1135 	key->label = isc_mem_strdup(key->mctx, label);
1136 	if (key->label == NULL)
1137 		DST_RET(ISC_R_NOMEMORY);
1138 
1139 	pk11_return_session(pk11_ctx);
1140 	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
1141 	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
1142 
1143 	attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
1144 	INSIST(attr != NULL);
1145 	key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
1146 
1147 	return (ISC_R_SUCCESS);
1148 
1149     err:
1150 	if (pk11_ctx != NULL) {
1151 		pk11_return_session(pk11_ctx);
1152 		memset(pk11_ctx, 0, sizeof(*pk11_ctx));
1153 		isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
1154 	}
1155 
1156 	return (ret);
1157 }
1158 
1159 static isc_result_t
1160 rsa_check(pk11_object_t *rsa, pk11_object_t *pubrsa) {
1161 	CK_ATTRIBUTE *pubattr, *privattr;
1162 	CK_BYTE *priv_exp = NULL, *priv_mod = NULL;
1163 	CK_BYTE *pub_exp = NULL, *pub_mod = NULL;
1164 	unsigned int priv_explen = 0, priv_modlen = 0;
1165 	unsigned int pub_explen = 0, pub_modlen = 0;
1166 
1167 	REQUIRE(rsa != NULL && pubrsa != NULL);
1168 
1169 	privattr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT);
1170 	INSIST(privattr != NULL);
1171 	priv_exp = privattr->pValue;
1172 	priv_explen = privattr->ulValueLen;
1173 
1174 	pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT);
1175 	INSIST(pubattr != NULL);
1176 	pub_exp = pubattr->pValue;
1177 	pub_explen = pubattr->ulValueLen;
1178 
1179 	if (priv_exp != NULL) {
1180 		if (priv_explen != pub_explen)
1181 			return (DST_R_INVALIDPRIVATEKEY);
1182 		if (memcmp(priv_exp, pub_exp, pub_explen) != 0)
1183 			return (DST_R_INVALIDPRIVATEKEY);
1184 	} else {
1185 		privattr->pValue = pub_exp;
1186 		privattr->ulValueLen = pub_explen;
1187 		pubattr->pValue = NULL;
1188 		pubattr->ulValueLen = 0;
1189 	}
1190 
1191 	if (privattr->pValue == NULL)
1192 		return (DST_R_INVALIDPRIVATEKEY);
1193 
1194 	privattr = pk11_attribute_bytype(rsa, CKA_MODULUS);
1195 	INSIST(privattr != NULL);
1196 	priv_mod = privattr->pValue;
1197 	priv_modlen = privattr->ulValueLen;
1198 
1199 	pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS);
1200 	INSIST(pubattr != NULL);
1201 	pub_mod = pubattr->pValue;
1202 	pub_modlen = pubattr->ulValueLen;
1203 
1204 	if (priv_mod != NULL) {
1205 		if (priv_modlen != pub_modlen)
1206 			return (DST_R_INVALIDPRIVATEKEY);
1207 		if (memcmp(priv_mod, pub_mod, pub_modlen) != 0)
1208 			return (DST_R_INVALIDPRIVATEKEY);
1209 	} else {
1210 		privattr->pValue = pub_mod;
1211 		privattr->ulValueLen = pub_modlen;
1212 		pubattr->pValue = NULL;
1213 		pubattr->ulValueLen = 0;
1214 	}
1215 
1216 	if (privattr->pValue == NULL)
1217 		return (DST_R_INVALIDPRIVATEKEY);
1218 
1219 	return (ISC_R_SUCCESS);
1220 }
1221 
1222 static isc_result_t
1223 pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
1224 	dst_private_t priv;
1225 	isc_result_t ret;
1226 	int i;
1227 	pk11_object_t *rsa;
1228 	CK_ATTRIBUTE *attr;
1229 	isc_mem_t *mctx = key->mctx;
1230 	const char *engine = NULL, *label = NULL;
1231 
1232 	/* read private key file */
1233 	ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv);
1234 	if (ret != ISC_R_SUCCESS)
1235 		return (ret);
1236 
1237 	if (key->external) {
1238 		if (priv.nelements != 0)
1239 			DST_RET(DST_R_INVALIDPRIVATEKEY);
1240 		if (pub == NULL)
1241 			DST_RET(DST_R_INVALIDPRIVATEKEY);
1242 
1243 		key->keydata.pkey = pub->keydata.pkey;
1244 		pub->keydata.pkey = NULL;
1245 		key->key_size = pub->key_size;
1246 
1247 		dst__privstruct_free(&priv, mctx);
1248 		memset(&priv, 0, sizeof(priv));
1249 
1250 		return (ISC_R_SUCCESS);
1251 	}
1252 
1253 	for (i = 0; i < priv.nelements; i++) {
1254 		switch (priv.elements[i].tag) {
1255 		case TAG_RSA_ENGINE:
1256 			engine = (char *)priv.elements[i].data;
1257 			break;
1258 		case TAG_RSA_LABEL:
1259 			label = (char *)priv.elements[i].data;
1260 			break;
1261 		default:
1262 			break;
1263 		}
1264 	}
1265 	rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
1266 	if (rsa == NULL)
1267 		DST_RET(ISC_R_NOMEMORY);
1268 	memset(rsa, 0, sizeof(*rsa));
1269 	key->keydata.pkey = rsa;
1270 
1271 	/* Is this key is stored in a HSM? See if we can fetch it. */
1272 	if ((label != NULL) || (engine != NULL)) {
1273 		ret = pkcs11rsa_fetch(key, engine, label, pub);
1274 		if (ret != ISC_R_SUCCESS)
1275 			goto err;
1276 		dst__privstruct_free(&priv, mctx);
1277 		memset(&priv, 0, sizeof(priv));
1278 		return (ret);
1279 	}
1280 
1281 	rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8);
1282 	if (rsa->repr == NULL)
1283 		DST_RET(ISC_R_NOMEMORY);
1284 	memset(rsa->repr, 0, sizeof(*attr) * 8);
1285 	rsa->attrcnt = 8;
1286 	attr = rsa->repr;
1287 	attr[0].type = CKA_MODULUS;
1288 	attr[1].type = CKA_PUBLIC_EXPONENT;
1289 	attr[2].type = CKA_PRIVATE_EXPONENT;
1290 	attr[3].type = CKA_PRIME_1;
1291 	attr[4].type = CKA_PRIME_2;
1292 	attr[5].type = CKA_EXPONENT_1;
1293 	attr[6].type = CKA_EXPONENT_2;
1294 	attr[7].type = CKA_COEFFICIENT;
1295 
1296 	for (i = 0; i < priv.nelements; i++) {
1297 		CK_BYTE *bn;
1298 
1299 		switch (priv.elements[i].tag) {
1300 		case TAG_RSA_ENGINE:
1301 			continue;
1302 		case TAG_RSA_LABEL:
1303 			continue;
1304 		default:
1305 			bn = isc_mem_get(key->mctx, priv.elements[i].length);
1306 			if (bn == NULL)
1307 				DST_RET(ISC_R_NOMEMORY);
1308 			memmove(bn, priv.elements[i].data,
1309 				priv.elements[i].length);
1310 		}
1311 
1312 		switch (priv.elements[i].tag) {
1313 			case TAG_RSA_MODULUS:
1314 				attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
1315 				INSIST(attr != NULL);
1316 				attr->pValue = bn;
1317 				attr->ulValueLen = priv.elements[i].length;
1318 				break;
1319 			case TAG_RSA_PUBLICEXPONENT:
1320 				attr = pk11_attribute_bytype(rsa,
1321 						CKA_PUBLIC_EXPONENT);
1322 				INSIST(attr != NULL);
1323 				attr->pValue = bn;
1324 				attr->ulValueLen = priv.elements[i].length;
1325 				break;
1326 			case TAG_RSA_PRIVATEEXPONENT:
1327 				attr = pk11_attribute_bytype(rsa,
1328 						CKA_PRIVATE_EXPONENT);
1329 				INSIST(attr != NULL);
1330 				attr->pValue = bn;
1331 				attr->ulValueLen = priv.elements[i].length;
1332 				break;
1333 			case TAG_RSA_PRIME1:
1334 				attr = pk11_attribute_bytype(rsa, CKA_PRIME_1);
1335 				INSIST(attr != NULL);
1336 				attr->pValue = bn;
1337 				attr->ulValueLen = priv.elements[i].length;
1338 				break;
1339 			case TAG_RSA_PRIME2:
1340 				attr = pk11_attribute_bytype(rsa, CKA_PRIME_2);
1341 				INSIST(attr != NULL);
1342 				attr->pValue = bn;
1343 				attr->ulValueLen = priv.elements[i].length;
1344 				break;
1345 			case TAG_RSA_EXPONENT1:
1346 				attr = pk11_attribute_bytype(rsa,
1347 							     CKA_EXPONENT_1);
1348 				INSIST(attr != NULL);
1349 				attr->pValue = bn;
1350 				attr->ulValueLen = priv.elements[i].length;
1351 				break;
1352 			case TAG_RSA_EXPONENT2:
1353 				attr = pk11_attribute_bytype(rsa,
1354 							     CKA_EXPONENT_2);
1355 				INSIST(attr != NULL);
1356 				attr->pValue = bn;
1357 				attr->ulValueLen = priv.elements[i].length;
1358 				break;
1359 			case TAG_RSA_COEFFICIENT:
1360 				attr = pk11_attribute_bytype(rsa,
1361 							     CKA_COEFFICIENT);
1362 				INSIST(attr != NULL);
1363 				attr->pValue = bn;
1364 				attr->ulValueLen = priv.elements[i].length;
1365 				break;
1366 		}
1367 	}
1368 
1369 	if (rsa_check(rsa, pub->keydata.pkey) != ISC_R_SUCCESS)
1370 		DST_RET(DST_R_INVALIDPRIVATEKEY);
1371 
1372 	attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
1373 	INSIST(attr != NULL);
1374 	key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
1375 
1376 	attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT);
1377 	INSIST(attr != NULL);
1378 	if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS)
1379 		DST_RET(ISC_R_RANGE);
1380 
1381 	dst__privstruct_free(&priv, mctx);
1382 	memset(&priv, 0, sizeof(priv));
1383 
1384 	return (ISC_R_SUCCESS);
1385 
1386  err:
1387 	pkcs11rsa_destroy(key);
1388 	dst__privstruct_free(&priv, mctx);
1389 	memset(&priv, 0, sizeof(priv));
1390 	return (ret);
1391 }
1392 
1393 static isc_result_t
1394 pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
1395 		    const char *pin)
1396 {
1397 	CK_RV rv;
1398 	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
1399 	CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
1400 	CK_KEY_TYPE keyType = CKK_RSA;
1401 	CK_ATTRIBUTE searchTemplate[] =
1402 	{
1403 		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
1404 		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
1405 		{ CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) },
1406 		{ CKA_LABEL, NULL, 0 }
1407 	};
1408 	CK_ULONG cnt;
1409 	CK_ATTRIBUTE *attr;
1410 	pk11_object_t *rsa;
1411 	pk11_context_t *pk11_ctx = NULL;
1412 	isc_result_t ret;
1413 	unsigned int i;
1414 
1415 	UNUSED(pin);
1416 
1417 	rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
1418 	if (rsa == NULL)
1419 		return (ISC_R_NOMEMORY);
1420 	memset(rsa, 0, sizeof(*rsa));
1421 	rsa->object = CK_INVALID_HANDLE;
1422 	rsa->ontoken = ISC_TRUE;
1423 	rsa->reqlogon = ISC_TRUE;
1424 	key->keydata.pkey = rsa;
1425 
1426 	rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2);
1427 	if (rsa->repr == NULL)
1428 		DST_RET(ISC_R_NOMEMORY);
1429 	memset(rsa->repr, 0, sizeof(*attr) * 2);
1430 	rsa->attrcnt = 2;
1431 	attr = rsa->repr;
1432 	attr[0].type = CKA_MODULUS;
1433 	attr[1].type = CKA_PUBLIC_EXPONENT;
1434 
1435 	ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA);
1436 	if (ret != ISC_R_SUCCESS)
1437 		goto err;
1438 
1439 	pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx,
1440 						  sizeof(*pk11_ctx));
1441 	if (pk11_ctx == NULL)
1442 		DST_RET(ISC_R_NOMEMORY);
1443 	ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
1444 			       rsa->reqlogon, NULL, rsa->slot);
1445 	if (ret != ISC_R_SUCCESS)
1446 		goto err;
1447 
1448 	attr = pk11_attribute_bytype(rsa, CKA_LABEL);
1449 	if (attr == NULL) {
1450 		attr = pk11_attribute_bytype(rsa, CKA_ID);
1451 		INSIST(attr != NULL);
1452 		searchTemplate[3].type = CKA_ID;
1453 	}
1454 	searchTemplate[3].pValue = attr->pValue;
1455 	searchTemplate[3].ulValueLen = attr->ulValueLen;
1456 
1457 	PK11_RET(pkcs_C_FindObjectsInit,
1458 		 (pk11_ctx->session, searchTemplate, (CK_ULONG) 4),
1459 		 DST_R_CRYPTOFAILURE);
1460 	PK11_RET(pkcs_C_FindObjects,
1461 		 (pk11_ctx->session, &hKey, (CK_ULONG) 1, &cnt),
1462 		 DST_R_CRYPTOFAILURE);
1463 	(void) pkcs_C_FindObjectsFinal(pk11_ctx->session);
1464 	if (cnt == 0)
1465 		DST_RET(ISC_R_NOTFOUND);
1466 	if (cnt > 1)
1467 		DST_RET(ISC_R_EXISTS);
1468 
1469 	attr = rsa->repr;
1470 	PK11_RET(pkcs_C_GetAttributeValue,
1471 		 (pk11_ctx->session, hKey, attr, 2),
1472 		 DST_R_CRYPTOFAILURE);
1473 	for (i = 0; i <= 1; i++) {
1474 		attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen);
1475 		if (attr[i].pValue == NULL)
1476 			DST_RET(ISC_R_NOMEMORY);
1477 		memset(attr[i].pValue, 0, attr[i].ulValueLen);
1478 	}
1479 	PK11_RET(pkcs_C_GetAttributeValue,
1480 		 (pk11_ctx->session, hKey, attr, 2),
1481 		 DST_R_CRYPTOFAILURE);
1482 
1483 	keyClass = CKO_PRIVATE_KEY;
1484 	PK11_RET(pkcs_C_FindObjectsInit,
1485 		 (pk11_ctx->session, searchTemplate, (CK_ULONG) 4),
1486 		 DST_R_CRYPTOFAILURE);
1487 	PK11_RET(pkcs_C_FindObjects,
1488 		 (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt),
1489 		 DST_R_CRYPTOFAILURE);
1490 	(void) pkcs_C_FindObjectsFinal(pk11_ctx->session);
1491 	if (cnt == 0)
1492 		DST_RET(ISC_R_NOTFOUND);
1493 	if (cnt > 1)
1494 		DST_RET(ISC_R_EXISTS);
1495 
1496 	if (engine != NULL) {
1497 		key->engine = isc_mem_strdup(key->mctx, engine);
1498 		if (key->engine == NULL)
1499 			DST_RET(ISC_R_NOMEMORY);
1500 	}
1501 
1502 	key->label = isc_mem_strdup(key->mctx, label);
1503 	if (key->label == NULL)
1504 		DST_RET(ISC_R_NOMEMORY);
1505 
1506 	attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT);
1507 	INSIST(attr != NULL);
1508 	if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS)
1509 		DST_RET(ISC_R_RANGE);
1510 
1511 	attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
1512 	INSIST(attr != NULL);
1513 	key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
1514 
1515 	pk11_return_session(pk11_ctx);
1516 	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
1517 	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
1518 
1519 	return (ISC_R_SUCCESS);
1520 
1521     err:
1522 	pkcs11rsa_destroy(key);
1523 	if (pk11_ctx != NULL) {
1524 		pk11_return_session(pk11_ctx);
1525 		memset(pk11_ctx, 0, sizeof(*pk11_ctx));
1526 		isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
1527 	}
1528 
1529 	return (ret);
1530 }
1531 
1532 static dst_func_t pkcs11rsa_functions = {
1533 	pkcs11rsa_createctx,
1534 	pkcs11rsa_createctx2,
1535 	pkcs11rsa_destroyctx,
1536 	pkcs11rsa_adddata,
1537 	pkcs11rsa_sign,
1538 	pkcs11rsa_verify,
1539 	NULL, /*%< verify2 */
1540 	NULL, /*%< computesecret */
1541 	pkcs11rsa_compare,
1542 	NULL, /*%< paramcompare */
1543 	pkcs11rsa_generate,
1544 	pkcs11rsa_isprivate,
1545 	pkcs11rsa_destroy,
1546 	pkcs11rsa_todns,
1547 	pkcs11rsa_fromdns,
1548 	pkcs11rsa_tofile,
1549 	pkcs11rsa_parse,
1550 	NULL, /*%< cleanup */
1551 	pkcs11rsa_fromlabel,
1552 	NULL, /*%< dump */
1553 	NULL, /*%< restore */
1554 };
1555 
1556 isc_result_t
1557 dst__pkcs11rsa_init(dst_func_t **funcp) {
1558 	REQUIRE(funcp != NULL);
1559 
1560 	if (*funcp == NULL)
1561 		*funcp = &pkcs11rsa_functions;
1562 	return (ISC_R_SUCCESS);
1563 }
1564 
1565 #else /* PKCS11CRYPTO */
1566 
1567 #include <isc/util.h>
1568 
1569 EMPTY_TRANSLATION_UNIT
1570 
1571 #endif /* PKCS11CRYPTO */
1572 /*! \file */
1573