1 /* $NetBSD: pkcs11rsa_link.c,v 1.1.1.5 2015/09/03 07:21:37 christos Exp $ */
4 * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
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.
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.
25 #include <isc/entropy.h>
30 #include <isc/string.h>
33 #include <dst/result.h>
35 #include "dst_internal.h"
36 #include "dst_parse.h"
37 #include "dst_pkcs11.h"
39 #include <pk11/internal.h>
42 * Limit the size of public exponents.
44 #ifndef RSA_MAX_PUBEXP_BITS
45 #define RSA_MAX_PUBEXP_BITS 35
48 #define DST_RET(a) {ret = a; goto err;}
50 static CK_BBOOL truevalue
= TRUE
;
51 static CK_BBOOL falsevalue
= FALSE
;
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
);
59 pkcs11rsa_createctx_sign(dst_key_t
*key
, dst_context_t
*dctx
) {
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
[] =
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 }
84 pk11_context_t
*pk11_ctx
;
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
);
94 rsa
= key
->keydata
.pkey
;
96 pk11_ctx
= (pk11_context_t
*) isc_mem_get(dctx
->mctx
,
99 return (ISC_R_NOMEMORY
);
100 memset(pk11_ctx
, 0, sizeof(*pk11_ctx
));
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
)
110 if (rsa
->ontoken
&& (rsa
->object
!= CK_INVALID_HANDLE
)) {
111 pk11_ctx
->ontoken
= rsa
->ontoken
;
112 pk11_ctx
->object
= rsa
->object
;
116 for (attr
= pk11_attribute_first(rsa
);
118 attr
= pk11_attribute_next(rsa
, attr
))
119 switch (attr
->type
) {
121 INSIST(keyTemplate
[6].type
== attr
->type
);
122 keyTemplate
[6].pValue
= isc_mem_get(dctx
->mctx
,
124 if (keyTemplate
[6].pValue
== NULL
)
125 DST_RET(ISC_R_NOMEMORY
);
126 memmove(keyTemplate
[6].pValue
, attr
->pValue
,
128 keyTemplate
[6].ulValueLen
= attr
->ulValueLen
;
130 case CKA_PUBLIC_EXPONENT
:
131 INSIST(keyTemplate
[7].type
== attr
->type
);
132 keyTemplate
[7].pValue
= isc_mem_get(dctx
->mctx
,
134 if (keyTemplate
[7].pValue
== NULL
)
135 DST_RET(ISC_R_NOMEMORY
);
136 memmove(keyTemplate
[7].pValue
, attr
->pValue
,
138 keyTemplate
[7].ulValueLen
= attr
->ulValueLen
;
140 case CKA_PRIVATE_EXPONENT
:
141 INSIST(keyTemplate
[8].type
== attr
->type
);
142 keyTemplate
[8].pValue
= isc_mem_get(dctx
->mctx
,
144 if (keyTemplate
[8].pValue
== NULL
)
145 DST_RET(ISC_R_NOMEMORY
);
146 memmove(keyTemplate
[8].pValue
, attr
->pValue
,
148 keyTemplate
[8].ulValueLen
= attr
->ulValueLen
;
151 INSIST(keyTemplate
[9].type
== attr
->type
);
152 keyTemplate
[9].pValue
= isc_mem_get(dctx
->mctx
,
154 if (keyTemplate
[9].pValue
== NULL
)
155 DST_RET(ISC_R_NOMEMORY
);
156 memmove(keyTemplate
[9].pValue
, attr
->pValue
,
158 keyTemplate
[9].ulValueLen
= attr
->ulValueLen
;
161 INSIST(keyTemplate
[10].type
== attr
->type
);
162 keyTemplate
[10].pValue
= isc_mem_get(dctx
->mctx
,
164 if (keyTemplate
[10].pValue
== NULL
)
165 DST_RET(ISC_R_NOMEMORY
);
166 memmove(keyTemplate
[10].pValue
, attr
->pValue
,
168 keyTemplate
[10].ulValueLen
= attr
->ulValueLen
;
171 INSIST(keyTemplate
[11].type
== attr
->type
);
172 keyTemplate
[11].pValue
= isc_mem_get(dctx
->mctx
,
174 if (keyTemplate
[11].pValue
== NULL
)
175 DST_RET(ISC_R_NOMEMORY
);
176 memmove(keyTemplate
[11].pValue
, attr
->pValue
,
178 keyTemplate
[11].ulValueLen
= attr
->ulValueLen
;
181 INSIST(keyTemplate
[12].type
== attr
->type
);
182 keyTemplate
[12].pValue
= isc_mem_get(dctx
->mctx
,
184 if (keyTemplate
[12].pValue
== NULL
)
185 DST_RET(ISC_R_NOMEMORY
);
186 memmove(keyTemplate
[12].pValue
, attr
->pValue
,
188 keyTemplate
[12].ulValueLen
= attr
->ulValueLen
;
190 case CKA_COEFFICIENT
:
191 INSIST(keyTemplate
[13].type
== attr
->type
);
192 keyTemplate
[13].pValue
= isc_mem_get(dctx
->mctx
,
194 if (keyTemplate
[13].pValue
== NULL
)
195 DST_RET(ISC_R_NOMEMORY
);
196 memmove(keyTemplate
[13].pValue
, attr
->pValue
,
198 keyTemplate
[13].ulValueLen
= attr
->ulValueLen
;
201 pk11_ctx
->object
= CK_INVALID_HANDLE
;
202 pk11_ctx
->ontoken
= ISC_FALSE
;
203 PK11_RET(pkcs_C_CreateObject
,
205 keyTemplate
, (CK_ULONG
) 14,
211 switch (dctx
->key
->key_alg
) {
213 mech
.mechanism
= CKM_MD5_RSA_PKCS
;
215 case DST_ALG_RSASHA1
:
216 case DST_ALG_NSEC3RSASHA1
:
217 mech
.mechanism
= CKM_SHA1_RSA_PKCS
;
219 case DST_ALG_RSASHA256
:
220 mech
.mechanism
= CKM_SHA256_RSA_PKCS
;
222 case DST_ALG_RSASHA512
:
223 mech
.mechanism
= CKM_SHA512_RSA_PKCS
;
229 PK11_RET(pkcs_C_SignInit
,
230 (pk11_ctx
->session
, &mech
, pk11_ctx
->object
),
233 dctx
->ctxdata
.pk11_ctx
= pk11_ctx
;
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
);
244 return (ISC_R_SUCCESS
);
247 if (!pk11_ctx
->ontoken
&& (pk11_ctx
->object
!= CK_INVALID_HANDLE
))
248 (void) pkcs_C_DestroyObject(pk11_ctx
->session
,
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
);
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
));
266 pkcs11rsa_createctx_verify(dst_key_t
*key
, unsigned int maxbits
,
267 dst_context_t
*dctx
) {
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
[] =
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 },
284 pk11_context_t
*pk11_ctx
;
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
);
294 rsa
= key
->keydata
.pkey
;
296 pk11_ctx
= (pk11_context_t
*) isc_mem_get(dctx
->mctx
,
298 if (pk11_ctx
== NULL
)
299 return (ISC_R_NOMEMORY
);
300 ret
= pk11_get_session(pk11_ctx
, OP_RSA
, ISC_TRUE
, ISC_FALSE
,
302 pk11_get_best_token(OP_RSA
));
303 if (ret
!= ISC_R_SUCCESS
)
306 for (attr
= pk11_attribute_first(rsa
);
308 attr
= pk11_attribute_next(rsa
, attr
))
309 switch (attr
->type
) {
311 INSIST(keyTemplate
[5].type
== attr
->type
);
312 keyTemplate
[5].pValue
= isc_mem_get(dctx
->mctx
,
314 if (keyTemplate
[5].pValue
== NULL
)
315 DST_RET(ISC_R_NOMEMORY
);
316 memmove(keyTemplate
[5].pValue
, attr
->pValue
,
318 keyTemplate
[5].ulValueLen
= attr
->ulValueLen
;
320 case CKA_PUBLIC_EXPONENT
:
321 INSIST(keyTemplate
[6].type
== attr
->type
);
322 keyTemplate
[6].pValue
= isc_mem_get(dctx
->mctx
,
324 if (keyTemplate
[6].pValue
== NULL
)
325 DST_RET(ISC_R_NOMEMORY
);
326 memmove(keyTemplate
[6].pValue
, attr
->pValue
,
328 keyTemplate
[6].ulValueLen
= attr
->ulValueLen
;
329 if (pk11_numbits(attr
->pValue
,
330 attr
->ulValueLen
) > maxbits
&&
332 DST_RET(DST_R_VERIFYFAILURE
);
335 pk11_ctx
->object
= CK_INVALID_HANDLE
;
336 pk11_ctx
->ontoken
= ISC_FALSE
;
337 PK11_RET(pkcs_C_CreateObject
,
339 keyTemplate
, (CK_ULONG
) 7,
343 switch (dctx
->key
->key_alg
) {
345 mech
.mechanism
= CKM_MD5_RSA_PKCS
;
347 case DST_ALG_RSASHA1
:
348 case DST_ALG_NSEC3RSASHA1
:
349 mech
.mechanism
= CKM_SHA1_RSA_PKCS
;
351 case DST_ALG_RSASHA256
:
352 mech
.mechanism
= CKM_SHA256_RSA_PKCS
;
354 case DST_ALG_RSASHA512
:
355 mech
.mechanism
= CKM_SHA512_RSA_PKCS
;
361 PK11_RET(pkcs_C_VerifyInit
,
362 (pk11_ctx
->session
, &mech
, pk11_ctx
->object
),
365 dctx
->ctxdata
.pk11_ctx
= pk11_ctx
;
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
);
376 return (ISC_R_SUCCESS
);
379 if (!pk11_ctx
->ontoken
&& (pk11_ctx
->object
!= CK_INVALID_HANDLE
))
380 (void) pkcs_C_DestroyObject(pk11_ctx
->session
,
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
);
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
));
398 pkcs11rsa_createctx(dst_key_t
*key
, dst_context_t
*dctx
) {
399 if (dctx
->use
== DO_SIGN
)
400 return (pkcs11rsa_createctx_sign(key
, dctx
));
402 return (pkcs11rsa_createctx_verify(key
, 0U, dctx
));
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
));
410 return (pkcs11rsa_createctx_verify(key
,
411 (unsigned) maxbits
, dctx
));
415 pkcs11rsa_destroyctx(dst_context_t
*dctx
) {
416 pk11_context_t
*pk11_ctx
= dctx
->ctxdata
.pk11_ctx
;
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
,
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
;
431 pkcs11rsa_adddata(dst_context_t
*dctx
, const isc_region_t
*data
) {
433 pk11_context_t
*pk11_ctx
= dctx
->ctxdata
.pk11_ctx
;
434 isc_result_t ret
= ISC_R_SUCCESS
;
436 if (dctx
->use
== DO_SIGN
)
437 PK11_CALL(pkcs_C_SignUpdate
,
439 (CK_BYTE_PTR
) data
->base
,
440 (CK_ULONG
) data
->length
),
443 PK11_CALL(pkcs_C_VerifyUpdate
,
445 (CK_BYTE_PTR
) data
->base
,
446 (CK_ULONG
) data
->length
),
452 pkcs11rsa_sign(dst_context_t
*dctx
, isc_buffer_t
*sig
) {
456 pk11_context_t
*pk11_ctx
= dctx
->ctxdata
.pk11_ctx
;
457 isc_result_t ret
= ISC_R_SUCCESS
;
459 PK11_RET(pkcs_C_SignFinal
,
460 (pk11_ctx
->session
, NULL
, &siglen
),
463 isc_buffer_availableregion(sig
, &r
);
465 if (r
.length
< (unsigned int) siglen
)
466 return (ISC_R_NOSPACE
);
468 PK11_RET(pkcs_C_SignFinal
,
469 (pk11_ctx
->session
, (CK_BYTE_PTR
) r
.base
, &siglen
),
472 isc_buffer_add(sig
, (unsigned int) siglen
);
479 pkcs11rsa_verify(dst_context_t
*dctx
, const isc_region_t
*sig
) {
481 pk11_context_t
*pk11_ctx
= dctx
->ctxdata
.pk11_ctx
;
482 isc_result_t ret
= ISC_R_SUCCESS
;
484 PK11_CALL(pkcs_C_VerifyFinal
,
486 (CK_BYTE_PTR
) sig
->base
,
487 (CK_ULONG
) sig
->length
),
488 DST_R_VERIFYFAILURE
);
493 pkcs11rsa_compare(const dst_key_t
*key1
, const dst_key_t
*key2
) {
494 pk11_object_t
*rsa1
, *rsa2
;
495 CK_ATTRIBUTE
*attr1
, *attr2
;
497 rsa1
= key1
->keydata
.pkey
;
498 rsa2
= key2
->keydata
.pkey
;
500 if ((rsa1
== NULL
) && (rsa2
== NULL
))
502 else if ((rsa1
== NULL
) || (rsa2
== NULL
))
505 attr1
= pk11_attribute_bytype(rsa1
, CKA_MODULUS
);
506 attr2
= pk11_attribute_bytype(rsa2
, CKA_MODULUS
);
507 if ((attr1
== NULL
) && (attr2
== NULL
))
509 else if ((attr1
== NULL
) || (attr2
== NULL
) ||
510 (attr1
->ulValueLen
!= attr2
->ulValueLen
) ||
511 memcmp(attr1
->pValue
, attr2
->pValue
, attr1
->ulValueLen
))
514 attr1
= pk11_attribute_bytype(rsa1
, CKA_PUBLIC_EXPONENT
);
515 attr2
= pk11_attribute_bytype(rsa2
, CKA_PUBLIC_EXPONENT
);
516 if ((attr1
== NULL
) && (attr2
== NULL
))
518 else if ((attr1
== NULL
) || (attr2
== NULL
) ||
519 (attr1
->ulValueLen
!= attr2
->ulValueLen
) ||
520 memcmp(attr1
->pValue
, attr2
->pValue
, attr1
->ulValueLen
))
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
)))
531 if (!rsa1
->ontoken
&& !rsa2
->ontoken
)
533 else if (rsa1
->ontoken
|| rsa2
->ontoken
||
534 (rsa1
->object
!= rsa2
->object
))
541 pkcs11rsa_generate(dst_key_t
*key
, int exp
, void (*callback
)(int)) {
543 CK_MECHANISM mech
= { CKM_RSA_PKCS_KEY_PAIR_GEN
, NULL
, 0 };
544 CK_OBJECT_HANDLE pub
= CK_INVALID_HANDLE
;
547 CK_OBJECT_CLASS pubClass
= CKO_PUBLIC_KEY
;
548 CK_KEY_TYPE keyType
= CKK_RSA
;
549 CK_ATTRIBUTE pubTemplate
[] =
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
) }
559 CK_OBJECT_HANDLE priv
= CK_INVALID_HANDLE
;
560 CK_OBJECT_CLASS privClass
= CKO_PRIVATE_KEY
;
561 CK_ATTRIBUTE privTemplate
[] =
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
) },
573 pk11_context_t
*pk11_ctx
;
579 pk11_ctx
= (pk11_context_t
*) isc_mem_get(key
->mctx
,
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
)
588 bits
= key
->key_size
;
594 pubTemplate
[6].ulValueLen
= 3;
602 pubTemplate
[6].ulValueLen
= 5;
605 PK11_RET(pkcs_C_GenerateKeyPair
,
606 (pk11_ctx
->session
, &mech
,
607 pubTemplate
, (CK_ULONG
) 7,
608 privTemplate
, (CK_ULONG
) 7,
610 DST_R_CRYPTOFAILURE
);
612 rsa
= (pk11_object_t
*) isc_mem_get(key
->mctx
, sizeof(*rsa
));
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);
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
;
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
);
642 PK11_RET(pkcs_C_GetAttributeValue
,
643 (pk11_ctx
->session
, pub
, attr
, 2),
644 DST_R_CRYPTOFAILURE
);
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
);
656 PK11_RET(pkcs_C_GetAttributeValue
,
657 (pk11_ctx
->session
, priv
, attr
, 6),
658 DST_R_CRYPTOFAILURE
);
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
));
666 return (ISC_R_SUCCESS
);
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
));
682 pkcs11rsa_isprivate(const dst_key_t
*key
) {
683 pk11_object_t
*rsa
= key
->keydata
.pkey
;
688 attr
= pk11_attribute_bytype(rsa
, CKA_PRIVATE_EXPONENT
);
689 return (ISC_TF((attr
!= NULL
) || rsa
->ontoken
));
693 pkcs11rsa_destroy(dst_key_t
*key
) {
694 pk11_object_t
*rsa
= key
->keydata
.pkey
;
700 INSIST((rsa
->object
== CK_INVALID_HANDLE
) || rsa
->ontoken
);
702 for (attr
= pk11_attribute_first(rsa
);
704 attr
= pk11_attribute_next(rsa
, attr
))
705 switch (attr
->type
) {
709 case CKA_PUBLIC_EXPONENT
:
710 case CKA_PRIVATE_EXPONENT
:
715 case CKA_COEFFICIENT
:
716 if (attr
->pValue
!= NULL
) {
717 memset(attr
->pValue
, 0, attr
->ulValueLen
);
718 isc_mem_put(key
->mctx
,
724 if (rsa
->repr
!= NULL
) {
725 memset(rsa
->repr
, 0, rsa
->attrcnt
* sizeof(*attr
));
726 isc_mem_put(key
->mctx
,
728 rsa
->attrcnt
* sizeof(*attr
));
730 memset(rsa
, 0, sizeof(*rsa
));
731 isc_mem_put(key
->mctx
, rsa
, sizeof(*rsa
));
732 key
->keydata
.pkey
= NULL
;
736 pkcs11rsa_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
740 unsigned int e_bytes
= 0, mod_bytes
= 0;
741 CK_BYTE
*exponent
= NULL
, *modulus
= NULL
;
743 REQUIRE(key
->keydata
.pkey
!= NULL
);
745 rsa
= key
->keydata
.pkey
;
747 for (attr
= pk11_attribute_first(rsa
);
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
;
756 modulus
= (CK_BYTE
*) attr
->pValue
;
757 mod_bytes
= (unsigned int) attr
->ulValueLen
;
760 REQUIRE((exponent
!= NULL
) && (modulus
!= NULL
));
762 isc_buffer_availableregion(data
, &r
);
764 if (e_bytes
< 256) { /*%< key exponent is <= 2040 bits */
766 return (ISC_R_NOSPACE
);
767 isc_buffer_putuint8(data
, (isc_uint8_t
) e_bytes
);
768 isc_region_consume(&r
, 1);
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);
777 if (r
.length
< e_bytes
+ mod_bytes
)
778 return (ISC_R_NOSPACE
);
780 memmove(r
.base
, exponent
, e_bytes
);
781 isc_region_consume(&r
, e_bytes
);
782 memmove(r
.base
, modulus
, mod_bytes
);
784 isc_buffer_add(data
, e_bytes
+ mod_bytes
);
786 return (ISC_R_SUCCESS
);
790 pkcs11rsa_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
793 unsigned int e_bytes
, mod_bytes
;
794 CK_BYTE
*exponent
= NULL
, *modulus
= NULL
;
798 isc_buffer_remainingregion(data
, &r
);
800 return (ISC_R_SUCCESS
);
803 rsa
= (pk11_object_t
*) isc_mem_get(key
->mctx
, sizeof(*rsa
));
805 return (ISC_R_NOMEMORY
);
807 memset(rsa
, 0, sizeof(*rsa
));
810 isc_region_consume(&r
, 1);
814 memset(rsa
, 0, sizeof(*rsa
));
815 isc_mem_put(key
->mctx
, rsa
, sizeof(*rsa
));
816 return (DST_R_INVALIDPUBLICKEY
);
818 e_bytes
= (*r
.base
) << 8;
819 isc_region_consume(&r
, 1);
821 isc_region_consume(&r
, 1);
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
);
830 isc_region_consume(&r
, e_bytes
);
832 mod_bytes
= r
.length
;
834 key
->key_size
= pk11_numbits(modulus
, mod_bytes
);
836 isc_buffer_forward(data
, length
);
838 rsa
->repr
= (CK_ATTRIBUTE
*) isc_mem_get(key
->mctx
, sizeof(*attr
) * 2);
839 if (rsa
->repr
== NULL
)
841 memset(rsa
->repr
, 0, sizeof(*attr
) * 2);
844 attr
[0].type
= CKA_MODULUS
;
845 attr
[0].pValue
= isc_mem_get(key
->mctx
, mod_bytes
);
846 if (attr
[0].pValue
== NULL
)
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
)
854 memmove(attr
[1].pValue
, exponent
, e_bytes
);
855 attr
[1].ulValueLen
= (CK_ULONG
) e_bytes
;
857 key
->keydata
.pkey
= rsa
;
859 return (ISC_R_SUCCESS
);
862 for (attr
= pk11_attribute_first(rsa
);
864 attr
= pk11_attribute_next(rsa
, attr
))
865 switch (attr
->type
) {
867 case CKA_PUBLIC_EXPONENT
:
868 if (attr
->pValue
!= NULL
) {
869 memset(attr
->pValue
, 0, attr
->ulValueLen
);
870 isc_mem_put(key
->mctx
,
876 if (rsa
->repr
!= NULL
) {
877 memset(rsa
->repr
, 0, rsa
->attrcnt
* sizeof(*attr
));
878 isc_mem_put(key
->mctx
,
880 rsa
->attrcnt
* sizeof(*attr
));
882 memset(rsa
, 0, sizeof(*rsa
));
883 isc_mem_put(key
->mctx
, rsa
, sizeof(*rsa
));
884 return (ISC_R_NOMEMORY
);
888 pkcs11rsa_tofile(const dst_key_t
*key
, const char *directory
) {
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
;
896 unsigned char *bufs
[10];
899 if (key
->keydata
.pkey
== NULL
)
900 return (DST_R_NULLKEY
);
904 return (dst__privstruct_writefile(key
, &priv
, directory
));
907 rsa
= key
->keydata
.pkey
;
909 for (attr
= pk11_attribute_first(rsa
);
911 attr
= pk11_attribute_next(rsa
, attr
))
912 switch (attr
->type
) {
916 case CKA_PUBLIC_EXPONENT
:
919 case CKA_PRIVATE_EXPONENT
:
934 case CKA_COEFFICIENT
:
938 if ((modulus
== NULL
) || (exponent
== NULL
))
939 return (DST_R_NULLKEY
);
941 memset(bufs
, 0, sizeof(bufs
));
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
;
949 memset(bufs
[i
], 0, modulus
->ulValueLen
);
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
];
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
];
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
];
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
];
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
];
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
];
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
];
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
];
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
;
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
;
1029 result
= dst__privstruct_writefile(key
, &priv
, directory
);
1031 for (i
= 0; i
< 10; i
++) {
1032 if (bufs
[i
] == NULL
)
1034 memset(bufs
[i
], 0, modulus
->ulValueLen
);
1035 isc_mem_put(key
->mctx
, bufs
[i
], modulus
->ulValueLen
);
1041 pkcs11rsa_fetch(dst_key_t
*key
, const char *engine
, const char *label
,
1045 CK_OBJECT_CLASS keyClass
= CKO_PRIVATE_KEY
;
1046 CK_KEY_TYPE keyType
= CKK_RSA
;
1047 CK_ATTRIBUTE searchTemplate
[] =
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 }
1056 CK_ATTRIBUTE
*pubattr
;
1058 pk11_object_t
*pubrsa
;
1059 pk11_context_t
*pk11_ctx
= NULL
;
1063 return (DST_R_NOENGINE
);
1065 rsa
= key
->keydata
.pkey
;
1066 pubrsa
= pub
->keydata
.pkey
;
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);
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
;
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
;
1095 ret
= pk11_parse_uri(rsa
, label
, key
->mctx
, OP_RSA
);
1096 if (ret
!= ISC_R_SUCCESS
)
1099 pk11_ctx
= (pk11_context_t
*) isc_mem_get(key
->mctx
,
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
)
1108 attr
= pk11_attribute_bytype(rsa
, CKA_LABEL
);
1110 attr
= pk11_attribute_bytype(rsa
, CKA_ID
);
1111 INSIST(attr
!= NULL
);
1112 searchTemplate
[3].type
= CKA_ID
;
1114 searchTemplate
[3].pValue
= attr
->pValue
;
1115 searchTemplate
[3].ulValueLen
= attr
->ulValueLen
;
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
);
1125 DST_RET(ISC_R_NOTFOUND
);
1127 DST_RET(ISC_R_EXISTS
);
1129 if (engine
!= NULL
) {
1130 key
->engine
= isc_mem_strdup(key
->mctx
, engine
);
1131 if (key
->engine
== NULL
)
1132 DST_RET(ISC_R_NOMEMORY
);
1135 key
->label
= isc_mem_strdup(key
->mctx
, label
);
1136 if (key
->label
== NULL
)
1137 DST_RET(ISC_R_NOMEMORY
);
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
));
1143 attr
= pk11_attribute_bytype(rsa
, CKA_MODULUS
);
1144 INSIST(attr
!= NULL
);
1145 key
->key_size
= pk11_numbits(attr
->pValue
, attr
->ulValueLen
);
1147 return (ISC_R_SUCCESS
);
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
));
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;
1167 REQUIRE(rsa
!= NULL
&& pubrsa
!= NULL
);
1169 privattr
= pk11_attribute_bytype(rsa
, CKA_PUBLIC_EXPONENT
);
1170 INSIST(privattr
!= NULL
);
1171 priv_exp
= privattr
->pValue
;
1172 priv_explen
= privattr
->ulValueLen
;
1174 pubattr
= pk11_attribute_bytype(pubrsa
, CKA_PUBLIC_EXPONENT
);
1175 INSIST(pubattr
!= NULL
);
1176 pub_exp
= pubattr
->pValue
;
1177 pub_explen
= pubattr
->ulValueLen
;
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
);
1185 privattr
->pValue
= pub_exp
;
1186 privattr
->ulValueLen
= pub_explen
;
1187 pubattr
->pValue
= NULL
;
1188 pubattr
->ulValueLen
= 0;
1191 if (privattr
->pValue
== NULL
)
1192 return (DST_R_INVALIDPRIVATEKEY
);
1194 privattr
= pk11_attribute_bytype(rsa
, CKA_MODULUS
);
1195 INSIST(privattr
!= NULL
);
1196 priv_mod
= privattr
->pValue
;
1197 priv_modlen
= privattr
->ulValueLen
;
1199 pubattr
= pk11_attribute_bytype(pubrsa
, CKA_MODULUS
);
1200 INSIST(pubattr
!= NULL
);
1201 pub_mod
= pubattr
->pValue
;
1202 pub_modlen
= pubattr
->ulValueLen
;
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
);
1210 privattr
->pValue
= pub_mod
;
1211 privattr
->ulValueLen
= pub_modlen
;
1212 pubattr
->pValue
= NULL
;
1213 pubattr
->ulValueLen
= 0;
1216 if (privattr
->pValue
== NULL
)
1217 return (DST_R_INVALIDPRIVATEKEY
);
1219 return (ISC_R_SUCCESS
);
1223 pkcs11rsa_parse(dst_key_t
*key
, isc_lex_t
*lexer
, dst_key_t
*pub
) {
1229 isc_mem_t
*mctx
= key
->mctx
;
1230 const char *engine
= NULL
, *label
= NULL
;
1232 /* read private key file */
1233 ret
= dst__privstruct_parse(key
, DST_ALG_RSA
, lexer
, mctx
, &priv
);
1234 if (ret
!= ISC_R_SUCCESS
)
1237 if (key
->external
) {
1238 if (priv
.nelements
!= 0)
1239 DST_RET(DST_R_INVALIDPRIVATEKEY
);
1241 DST_RET(DST_R_INVALIDPRIVATEKEY
);
1243 key
->keydata
.pkey
= pub
->keydata
.pkey
;
1244 pub
->keydata
.pkey
= NULL
;
1245 key
->key_size
= pub
->key_size
;
1247 dst__privstruct_free(&priv
, mctx
);
1248 memset(&priv
, 0, sizeof(priv
));
1250 return (ISC_R_SUCCESS
);
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
;
1259 label
= (char *)priv
.elements
[i
].data
;
1265 rsa
= (pk11_object_t
*) isc_mem_get(key
->mctx
, sizeof(*rsa
));
1267 DST_RET(ISC_R_NOMEMORY
);
1268 memset(rsa
, 0, sizeof(*rsa
));
1269 key
->keydata
.pkey
= rsa
;
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
)
1276 dst__privstruct_free(&priv
, mctx
);
1277 memset(&priv
, 0, sizeof(priv
));
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);
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
;
1296 for (i
= 0; i
< priv
.nelements
; i
++) {
1299 switch (priv
.elements
[i
].tag
) {
1300 case TAG_RSA_ENGINE
:
1305 bn
= isc_mem_get(key
->mctx
, priv
.elements
[i
].length
);
1307 DST_RET(ISC_R_NOMEMORY
);
1308 memmove(bn
, priv
.elements
[i
].data
,
1309 priv
.elements
[i
].length
);
1312 switch (priv
.elements
[i
].tag
) {
1313 case TAG_RSA_MODULUS
:
1314 attr
= pk11_attribute_bytype(rsa
, CKA_MODULUS
);
1315 INSIST(attr
!= NULL
);
1317 attr
->ulValueLen
= priv
.elements
[i
].length
;
1319 case TAG_RSA_PUBLICEXPONENT
:
1320 attr
= pk11_attribute_bytype(rsa
,
1321 CKA_PUBLIC_EXPONENT
);
1322 INSIST(attr
!= NULL
);
1324 attr
->ulValueLen
= priv
.elements
[i
].length
;
1326 case TAG_RSA_PRIVATEEXPONENT
:
1327 attr
= pk11_attribute_bytype(rsa
,
1328 CKA_PRIVATE_EXPONENT
);
1329 INSIST(attr
!= NULL
);
1331 attr
->ulValueLen
= priv
.elements
[i
].length
;
1333 case TAG_RSA_PRIME1
:
1334 attr
= pk11_attribute_bytype(rsa
, CKA_PRIME_1
);
1335 INSIST(attr
!= NULL
);
1337 attr
->ulValueLen
= priv
.elements
[i
].length
;
1339 case TAG_RSA_PRIME2
:
1340 attr
= pk11_attribute_bytype(rsa
, CKA_PRIME_2
);
1341 INSIST(attr
!= NULL
);
1343 attr
->ulValueLen
= priv
.elements
[i
].length
;
1345 case TAG_RSA_EXPONENT1
:
1346 attr
= pk11_attribute_bytype(rsa
,
1348 INSIST(attr
!= NULL
);
1350 attr
->ulValueLen
= priv
.elements
[i
].length
;
1352 case TAG_RSA_EXPONENT2
:
1353 attr
= pk11_attribute_bytype(rsa
,
1355 INSIST(attr
!= NULL
);
1357 attr
->ulValueLen
= priv
.elements
[i
].length
;
1359 case TAG_RSA_COEFFICIENT
:
1360 attr
= pk11_attribute_bytype(rsa
,
1362 INSIST(attr
!= NULL
);
1364 attr
->ulValueLen
= priv
.elements
[i
].length
;
1369 if (rsa_check(rsa
, pub
->keydata
.pkey
) != ISC_R_SUCCESS
)
1370 DST_RET(DST_R_INVALIDPRIVATEKEY
);
1372 attr
= pk11_attribute_bytype(rsa
, CKA_MODULUS
);
1373 INSIST(attr
!= NULL
);
1374 key
->key_size
= pk11_numbits(attr
->pValue
, attr
->ulValueLen
);
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
);
1381 dst__privstruct_free(&priv
, mctx
);
1382 memset(&priv
, 0, sizeof(priv
));
1384 return (ISC_R_SUCCESS
);
1387 pkcs11rsa_destroy(key
);
1388 dst__privstruct_free(&priv
, mctx
);
1389 memset(&priv
, 0, sizeof(priv
));
1394 pkcs11rsa_fromlabel(dst_key_t
*key
, const char *engine
, const char *label
,
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
[] =
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 }
1411 pk11_context_t
*pk11_ctx
= NULL
;
1417 rsa
= (pk11_object_t
*) isc_mem_get(key
->mctx
, sizeof(*rsa
));
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
;
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);
1432 attr
[0].type
= CKA_MODULUS
;
1433 attr
[1].type
= CKA_PUBLIC_EXPONENT
;
1435 ret
= pk11_parse_uri(rsa
, label
, key
->mctx
, OP_RSA
);
1436 if (ret
!= ISC_R_SUCCESS
)
1439 pk11_ctx
= (pk11_context_t
*) isc_mem_get(key
->mctx
,
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
)
1448 attr
= pk11_attribute_bytype(rsa
, CKA_LABEL
);
1450 attr
= pk11_attribute_bytype(rsa
, CKA_ID
);
1451 INSIST(attr
!= NULL
);
1452 searchTemplate
[3].type
= CKA_ID
;
1454 searchTemplate
[3].pValue
= attr
->pValue
;
1455 searchTemplate
[3].ulValueLen
= attr
->ulValueLen
;
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
);
1465 DST_RET(ISC_R_NOTFOUND
);
1467 DST_RET(ISC_R_EXISTS
);
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
);
1479 PK11_RET(pkcs_C_GetAttributeValue
,
1480 (pk11_ctx
->session
, hKey
, attr
, 2),
1481 DST_R_CRYPTOFAILURE
);
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
);
1492 DST_RET(ISC_R_NOTFOUND
);
1494 DST_RET(ISC_R_EXISTS
);
1496 if (engine
!= NULL
) {
1497 key
->engine
= isc_mem_strdup(key
->mctx
, engine
);
1498 if (key
->engine
== NULL
)
1499 DST_RET(ISC_R_NOMEMORY
);
1502 key
->label
= isc_mem_strdup(key
->mctx
, label
);
1503 if (key
->label
== NULL
)
1504 DST_RET(ISC_R_NOMEMORY
);
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
);
1511 attr
= pk11_attribute_bytype(rsa
, CKA_MODULUS
);
1512 INSIST(attr
!= NULL
);
1513 key
->key_size
= pk11_numbits(attr
->pValue
, attr
->ulValueLen
);
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
));
1519 return (ISC_R_SUCCESS
);
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
));
1532 static dst_func_t pkcs11rsa_functions
= {
1533 pkcs11rsa_createctx
,
1534 pkcs11rsa_createctx2
,
1535 pkcs11rsa_destroyctx
,
1539 NULL
, /*%< verify2 */
1540 NULL
, /*%< computesecret */
1542 NULL
, /*%< paramcompare */
1544 pkcs11rsa_isprivate
,
1550 NULL
, /*%< cleanup */
1551 pkcs11rsa_fromlabel
,
1553 NULL
, /*%< restore */
1557 dst__pkcs11rsa_init(dst_func_t
**funcp
) {
1558 REQUIRE(funcp
!= NULL
);
1561 *funcp
= &pkcs11rsa_functions
;
1562 return (ISC_R_SUCCESS
);
1565 #else /* PKCS11CRYPTO */
1567 #include <isc/util.h>
1569 EMPTY_TRANSLATION_UNIT
1571 #endif /* PKCS11CRYPTO */