1 /* $NetBSD: pkcs11dsa_link.c,v 1.1.1.5 2015/09/03 07:21:36 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.
27 #include <isc/entropy.h>
32 #include <dst/result.h>
34 #include "dst_internal.h"
35 #include "dst_parse.h"
36 #include "dst_pkcs11.h"
38 #include <pk11/internal.h>
41 * FIPS 186-2 DSA keys:
44 * CKM_DSA_KEY_PAIR_GEN,
45 * CKM_DSA_PARAMETER_GEN
47 * object class CKO_DOMAIN_PARAMETERS
49 * attribute CKA_PRIME (prime p)
50 * attribute CKA_SUBPRIME (subprime q)
51 * attribute CKA_BASE (base g)
52 * optional attribute CKA_PRIME_BITS (p length in bits)
54 * object class CKO_PUBLIC_KEY
56 * attribute CKA_PRIME (prime p)
57 * attribute CKA_SUBPRIME (subprime q)
58 * attribute CKA_BASE (base g)
59 * attribute CKA_VALUE (public value y)
61 * object class CKO_PRIVATE_KEY
63 * attribute CKA_PRIME (prime p)
64 * attribute CKA_SUBPRIME (subprime q)
65 * attribute CKA_BASE (base g)
66 * attribute CKA_VALUE (private value x)
67 * reuse CKA_PRIVATE_EXPONENT for key pair private value
70 #define CKA_VALUE2 CKA_PRIVATE_EXPONENT
72 #define DST_RET(a) {ret = a; goto err;}
74 static CK_BBOOL truevalue
= TRUE
;
75 static CK_BBOOL falsevalue
= FALSE
;
77 static isc_result_t
pkcs11dsa_todns(const dst_key_t
*key
, isc_buffer_t
*data
);
78 static void pkcs11dsa_destroy(dst_key_t
*key
);
81 pkcs11dsa_createctx_sign(dst_key_t
*key
, dst_context_t
*dctx
) {
83 CK_MECHANISM mech
= { CKM_DSA_SHA1
, NULL
, 0 };
84 CK_OBJECT_CLASS keyClass
= CKO_PRIVATE_KEY
;
85 CK_KEY_TYPE keyType
= CKK_DSA
;
86 CK_ATTRIBUTE keyTemplate
[] =
88 { CKA_CLASS
, &keyClass
, (CK_ULONG
) sizeof(keyClass
) },
89 { CKA_KEY_TYPE
, &keyType
, (CK_ULONG
) sizeof(keyType
) },
90 { CKA_TOKEN
, &falsevalue
, (CK_ULONG
) sizeof(falsevalue
) },
91 { CKA_PRIVATE
, &falsevalue
, (CK_ULONG
) sizeof(falsevalue
) },
92 { CKA_SENSITIVE
, &falsevalue
, (CK_ULONG
) sizeof(falsevalue
) },
93 { CKA_SIGN
, &truevalue
, (CK_ULONG
) sizeof(truevalue
) },
94 { CKA_PRIME
, NULL
, 0 },
95 { CKA_SUBPRIME
, NULL
, 0 },
96 { CKA_BASE
, NULL
, 0 },
97 { CKA_VALUE
, NULL
, 0 }
101 pk11_context_t
*pk11_ctx
;
105 pk11_ctx
= (pk11_context_t
*) isc_mem_get(dctx
->mctx
,
107 if (pk11_ctx
== NULL
)
108 return (ISC_R_NOMEMORY
);
109 ret
= pk11_get_session(pk11_ctx
, OP_DSA
, ISC_TRUE
, ISC_FALSE
,
110 ISC_FALSE
, NULL
, pk11_get_best_token(OP_DSA
));
111 if (ret
!= ISC_R_SUCCESS
)
114 dsa
= key
->keydata
.pkey
;
115 if (dsa
->ontoken
&& (dsa
->object
!= CK_INVALID_HANDLE
)) {
116 pk11_ctx
->ontoken
= dsa
->ontoken
;
117 pk11_ctx
->object
= dsa
->object
;
121 for (attr
= pk11_attribute_first(dsa
);
123 attr
= pk11_attribute_next(dsa
, attr
))
124 switch (attr
->type
) {
126 INSIST(keyTemplate
[6].type
== attr
->type
);
127 keyTemplate
[6].pValue
= isc_mem_get(dctx
->mctx
,
129 if (keyTemplate
[6].pValue
== NULL
)
130 DST_RET(ISC_R_NOMEMORY
);
131 memmove(keyTemplate
[6].pValue
, attr
->pValue
,
133 keyTemplate
[6].ulValueLen
= attr
->ulValueLen
;
136 INSIST(keyTemplate
[7].type
== attr
->type
);
137 keyTemplate
[7].pValue
= isc_mem_get(dctx
->mctx
,
139 if (keyTemplate
[7].pValue
== NULL
)
140 DST_RET(ISC_R_NOMEMORY
);
141 memmove(keyTemplate
[7].pValue
, attr
->pValue
,
143 keyTemplate
[7].ulValueLen
= attr
->ulValueLen
;
146 INSIST(keyTemplate
[8].type
== attr
->type
);
147 keyTemplate
[8].pValue
= isc_mem_get(dctx
->mctx
,
149 if (keyTemplate
[8].pValue
== NULL
)
150 DST_RET(ISC_R_NOMEMORY
);
151 memmove(keyTemplate
[8].pValue
, attr
->pValue
,
153 keyTemplate
[8].ulValueLen
= attr
->ulValueLen
;
156 INSIST(keyTemplate
[9].type
== CKA_VALUE
);
157 keyTemplate
[9].pValue
= isc_mem_get(dctx
->mctx
,
159 if (keyTemplate
[9].pValue
== NULL
)
160 DST_RET(ISC_R_NOMEMORY
);
161 memmove(keyTemplate
[9].pValue
, attr
->pValue
,
163 keyTemplate
[9].ulValueLen
= attr
->ulValueLen
;
166 pk11_ctx
->object
= CK_INVALID_HANDLE
;
167 pk11_ctx
->ontoken
= ISC_FALSE
;
168 PK11_RET(pkcs_C_CreateObject
,
170 keyTemplate
, (CK_ULONG
) 10,
176 PK11_RET(pkcs_C_SignInit
,
177 (pk11_ctx
->session
, &mech
, pk11_ctx
->object
),
180 dctx
->ctxdata
.pk11_ctx
= pk11_ctx
;
182 for (i
= 6; i
<= 9; i
++)
183 if (keyTemplate
[i
].pValue
!= NULL
) {
184 memset(keyTemplate
[i
].pValue
, 0,
185 keyTemplate
[i
].ulValueLen
);
186 isc_mem_put(dctx
->mctx
,
187 keyTemplate
[i
].pValue
,
188 keyTemplate
[i
].ulValueLen
);
191 return (ISC_R_SUCCESS
);
194 if (!pk11_ctx
->ontoken
&& (pk11_ctx
->object
!= CK_INVALID_HANDLE
))
195 (void) pkcs_C_DestroyObject(pk11_ctx
->session
, pk11_ctx
->object
);
196 for (i
= 6; i
<= 9; i
++)
197 if (keyTemplate
[i
].pValue
!= NULL
) {
198 memset(keyTemplate
[i
].pValue
, 0,
199 keyTemplate
[i
].ulValueLen
);
200 isc_mem_put(dctx
->mctx
,
201 keyTemplate
[i
].pValue
,
202 keyTemplate
[i
].ulValueLen
);
204 pk11_return_session(pk11_ctx
);
205 memset(pk11_ctx
, 0, sizeof(*pk11_ctx
));
206 isc_mem_put(dctx
->mctx
, pk11_ctx
, sizeof(*pk11_ctx
));
212 pkcs11dsa_createctx_verify(dst_key_t
*key
, dst_context_t
*dctx
) {
214 CK_MECHANISM mech
= { CKM_DSA_SHA1
, NULL
, 0 };
215 CK_OBJECT_CLASS keyClass
= CKO_PUBLIC_KEY
;
216 CK_KEY_TYPE keyType
= CKK_DSA
;
217 CK_ATTRIBUTE keyTemplate
[] =
219 { CKA_CLASS
, &keyClass
, (CK_ULONG
) sizeof(keyClass
) },
220 { CKA_KEY_TYPE
, &keyType
, (CK_ULONG
) sizeof(keyType
) },
221 { CKA_TOKEN
, &falsevalue
, (CK_ULONG
) sizeof(falsevalue
) },
222 { CKA_PRIVATE
, &falsevalue
, (CK_ULONG
) sizeof(falsevalue
) },
223 { CKA_VERIFY
, &truevalue
, (CK_ULONG
) sizeof(truevalue
) },
224 { CKA_PRIME
, NULL
, 0 },
225 { CKA_SUBPRIME
, NULL
, 0 },
226 { CKA_BASE
, NULL
, 0 },
227 { CKA_VALUE
, NULL
, 0 }
231 pk11_context_t
*pk11_ctx
;
235 pk11_ctx
= (pk11_context_t
*) isc_mem_get(dctx
->mctx
,
237 if (pk11_ctx
== NULL
)
238 return (ISC_R_NOMEMORY
);
239 ret
= pk11_get_session(pk11_ctx
, OP_DSA
, ISC_TRUE
, ISC_FALSE
,
240 ISC_FALSE
, NULL
, pk11_get_best_token(OP_DSA
));
241 if (ret
!= ISC_R_SUCCESS
)
244 dsa
= key
->keydata
.pkey
;
245 if (dsa
->ontoken
&& (dsa
->object
!= CK_INVALID_HANDLE
)) {
246 pk11_ctx
->ontoken
= dsa
->ontoken
;
247 pk11_ctx
->object
= dsa
->object
;
251 for (attr
= pk11_attribute_first(dsa
);
253 attr
= pk11_attribute_next(dsa
, attr
))
254 switch (attr
->type
) {
256 INSIST(keyTemplate
[5].type
== attr
->type
);
257 keyTemplate
[5].pValue
= isc_mem_get(dctx
->mctx
,
259 if (keyTemplate
[5].pValue
== NULL
)
260 DST_RET(ISC_R_NOMEMORY
);
261 memmove(keyTemplate
[5].pValue
, attr
->pValue
,
263 keyTemplate
[5].ulValueLen
= attr
->ulValueLen
;
266 INSIST(keyTemplate
[6].type
== attr
->type
);
267 keyTemplate
[6].pValue
= isc_mem_get(dctx
->mctx
,
269 if (keyTemplate
[6].pValue
== NULL
)
270 DST_RET(ISC_R_NOMEMORY
);
271 memmove(keyTemplate
[6].pValue
, attr
->pValue
,
273 keyTemplate
[6].ulValueLen
= attr
->ulValueLen
;
276 INSIST(keyTemplate
[7].type
== attr
->type
);
277 keyTemplate
[7].pValue
= isc_mem_get(dctx
->mctx
,
279 if (keyTemplate
[7].pValue
== NULL
)
280 DST_RET(ISC_R_NOMEMORY
);
281 memmove(keyTemplate
[7].pValue
, attr
->pValue
,
283 keyTemplate
[7].ulValueLen
= attr
->ulValueLen
;
286 INSIST(keyTemplate
[8].type
== attr
->type
);
287 keyTemplate
[8].pValue
= isc_mem_get(dctx
->mctx
,
289 if (keyTemplate
[8].pValue
== NULL
)
290 DST_RET(ISC_R_NOMEMORY
);
291 memmove(keyTemplate
[8].pValue
, attr
->pValue
,
293 keyTemplate
[8].ulValueLen
= attr
->ulValueLen
;
296 pk11_ctx
->object
= CK_INVALID_HANDLE
;
297 pk11_ctx
->ontoken
= ISC_FALSE
;
298 PK11_RET(pkcs_C_CreateObject
,
300 keyTemplate
, (CK_ULONG
) 9,
306 PK11_RET(pkcs_C_VerifyInit
,
307 (pk11_ctx
->session
, &mech
, pk11_ctx
->object
),
310 dctx
->ctxdata
.pk11_ctx
= pk11_ctx
;
312 for (i
= 5; i
<= 8; i
++)
313 if (keyTemplate
[i
].pValue
!= NULL
) {
314 memset(keyTemplate
[i
].pValue
, 0,
315 keyTemplate
[i
].ulValueLen
);
316 isc_mem_put(dctx
->mctx
,
317 keyTemplate
[i
].pValue
,
318 keyTemplate
[i
].ulValueLen
);
321 return (ISC_R_SUCCESS
);
324 if (!pk11_ctx
->ontoken
&& (pk11_ctx
->object
!= CK_INVALID_HANDLE
))
325 (void) pkcs_C_DestroyObject(pk11_ctx
->session
, pk11_ctx
->object
);
326 for (i
= 5; i
<= 8; i
++)
327 if (keyTemplate
[i
].pValue
!= NULL
) {
328 memset(keyTemplate
[i
].pValue
, 0,
329 keyTemplate
[i
].ulValueLen
);
330 isc_mem_put(dctx
->mctx
,
331 keyTemplate
[i
].pValue
,
332 keyTemplate
[i
].ulValueLen
);
334 pk11_return_session(pk11_ctx
);
335 memset(pk11_ctx
, 0, sizeof(*pk11_ctx
));
336 isc_mem_put(dctx
->mctx
, pk11_ctx
, sizeof(*pk11_ctx
));
342 pkcs11dsa_createctx(dst_key_t
*key
, dst_context_t
*dctx
) {
343 if (dctx
->use
== DO_SIGN
)
344 return (pkcs11dsa_createctx_sign(key
, dctx
));
346 return (pkcs11dsa_createctx_verify(key
, dctx
));
350 pkcs11dsa_destroyctx(dst_context_t
*dctx
) {
351 pk11_context_t
*pk11_ctx
= dctx
->ctxdata
.pk11_ctx
;
353 if (pk11_ctx
!= NULL
) {
354 if (!pk11_ctx
->ontoken
&&
355 (pk11_ctx
->object
!= CK_INVALID_HANDLE
))
356 (void) pkcs_C_DestroyObject(pk11_ctx
->session
,
358 pk11_return_session(pk11_ctx
);
359 memset(pk11_ctx
, 0, sizeof(*pk11_ctx
));
360 isc_mem_put(dctx
->mctx
, pk11_ctx
, sizeof(*pk11_ctx
));
361 dctx
->ctxdata
.pk11_ctx
= NULL
;
366 pkcs11dsa_adddata(dst_context_t
*dctx
, const isc_region_t
*data
) {
368 pk11_context_t
*pk11_ctx
= dctx
->ctxdata
.pk11_ctx
;
369 isc_result_t ret
= ISC_R_SUCCESS
;
371 if (dctx
->use
== DO_SIGN
)
372 PK11_CALL(pkcs_C_SignUpdate
,
374 (CK_BYTE_PTR
) data
->base
,
375 (CK_ULONG
) data
->length
),
378 PK11_CALL(pkcs_C_VerifyUpdate
,
380 (CK_BYTE_PTR
) data
->base
,
381 (CK_ULONG
) data
->length
),
387 pkcs11dsa_sign(dst_context_t
*dctx
, isc_buffer_t
*sig
) {
389 CK_ULONG siglen
= ISC_SHA1_DIGESTLENGTH
* 2;
391 pk11_context_t
*pk11_ctx
= dctx
->ctxdata
.pk11_ctx
;
392 isc_result_t ret
= ISC_R_SUCCESS
;
395 isc_buffer_availableregion(sig
, &r
);
396 if (r
.length
< ISC_SHA1_DIGESTLENGTH
* 2 + 1)
397 return (ISC_R_NOSPACE
);
399 PK11_RET(pkcs_C_SignFinal
,
400 (pk11_ctx
->session
, (CK_BYTE_PTR
) r
.base
+ 1, &siglen
),
402 if (siglen
!= ISC_SHA1_DIGESTLENGTH
* 2)
403 return (DST_R_SIGNFAILURE
);
405 klen
= (dctx
->key
->key_size
- 512)/64;
407 return (ISC_R_FAILURE
);
409 isc_buffer_add(sig
, ISC_SHA1_DIGESTLENGTH
* 2 + 1);
416 pkcs11dsa_verify(dst_context_t
*dctx
, const isc_region_t
*sig
) {
418 pk11_context_t
*pk11_ctx
= dctx
->ctxdata
.pk11_ctx
;
419 isc_result_t ret
= ISC_R_SUCCESS
;
421 PK11_CALL(pkcs_C_VerifyFinal
,
423 (CK_BYTE_PTR
) sig
->base
+ 1,
424 (CK_ULONG
) sig
->length
- 1),
425 DST_R_VERIFYFAILURE
);
430 pkcs11dsa_compare(const dst_key_t
*key1
, const dst_key_t
*key2
) {
431 pk11_object_t
*dsa1
, *dsa2
;
432 CK_ATTRIBUTE
*attr1
, *attr2
;
434 dsa1
= key1
->keydata
.pkey
;
435 dsa2
= key2
->keydata
.pkey
;
437 if ((dsa1
== NULL
) && (dsa2
== NULL
))
439 else if ((dsa1
== NULL
) || (dsa2
== NULL
))
442 attr1
= pk11_attribute_bytype(dsa1
, CKA_PRIME
);
443 attr2
= pk11_attribute_bytype(dsa2
, CKA_PRIME
);
444 if ((attr1
== NULL
) && (attr2
== NULL
))
446 else if ((attr1
== NULL
) || (attr2
== NULL
) ||
447 (attr1
->ulValueLen
!= attr2
->ulValueLen
) ||
448 memcmp(attr1
->pValue
, attr2
->pValue
, attr1
->ulValueLen
))
451 attr1
= pk11_attribute_bytype(dsa1
, CKA_SUBPRIME
);
452 attr2
= pk11_attribute_bytype(dsa2
, CKA_SUBPRIME
);
453 if ((attr1
== NULL
) && (attr2
== NULL
))
455 else if ((attr1
== NULL
) || (attr2
== NULL
) ||
456 (attr1
->ulValueLen
!= attr2
->ulValueLen
) ||
457 memcmp(attr1
->pValue
, attr2
->pValue
, attr1
->ulValueLen
))
460 attr1
= pk11_attribute_bytype(dsa1
, CKA_BASE
);
461 attr2
= pk11_attribute_bytype(dsa2
, CKA_BASE
);
462 if ((attr1
== NULL
) && (attr2
== NULL
))
464 else if ((attr1
== NULL
) || (attr2
== NULL
) ||
465 (attr1
->ulValueLen
!= attr2
->ulValueLen
) ||
466 memcmp(attr1
->pValue
, attr2
->pValue
, attr1
->ulValueLen
))
469 attr1
= pk11_attribute_bytype(dsa1
, CKA_VALUE
);
470 attr2
= pk11_attribute_bytype(dsa2
, CKA_VALUE
);
471 if ((attr1
== NULL
) && (attr2
== NULL
))
473 else if ((attr1
== NULL
) || (attr2
== NULL
) ||
474 (attr1
->ulValueLen
!= attr2
->ulValueLen
) ||
475 memcmp(attr1
->pValue
, attr2
->pValue
, attr1
->ulValueLen
))
478 attr1
= pk11_attribute_bytype(dsa1
, CKA_VALUE2
);
479 attr2
= pk11_attribute_bytype(dsa2
, CKA_VALUE2
);
480 if (((attr1
!= NULL
) || (attr2
!= NULL
)) &&
481 ((attr1
== NULL
) || (attr2
== NULL
) ||
482 (attr1
->ulValueLen
!= attr2
->ulValueLen
) ||
483 memcmp(attr1
->pValue
, attr2
->pValue
, attr1
->ulValueLen
)))
486 if (!dsa1
->ontoken
&& !dsa2
->ontoken
)
488 else if (dsa1
->ontoken
|| dsa2
->ontoken
||
489 (dsa1
->object
!= dsa2
->object
))
496 pkcs11dsa_generate(dst_key_t
*key
, int unused
, void (*callback
)(int)) {
498 CK_MECHANISM mech
= { CKM_DSA_PARAMETER_GEN
, NULL
, 0 };
499 CK_OBJECT_HANDLE dp
= CK_INVALID_HANDLE
;
500 CK_OBJECT_CLASS dpClass
= CKO_DOMAIN_PARAMETERS
;
501 CK_KEY_TYPE keyType
= CKK_DSA
;
503 CK_ATTRIBUTE dpTemplate
[] =
505 { CKA_CLASS
, &dpClass
, (CK_ULONG
) sizeof(dpClass
) },
506 { CKA_KEY_TYPE
, &keyType
, (CK_ULONG
) sizeof(keyType
) },
507 { CKA_TOKEN
, &falsevalue
, (CK_ULONG
) sizeof(falsevalue
) },
508 { CKA_PRIVATE
, &falsevalue
, (CK_ULONG
) sizeof(falsevalue
) },
509 { CKA_PRIME_BITS
, &bits
, (CK_ULONG
) sizeof(bits
) },
511 CK_OBJECT_HANDLE pub
= CK_INVALID_HANDLE
;
512 CK_OBJECT_CLASS pubClass
= CKO_PUBLIC_KEY
;
513 CK_ATTRIBUTE pubTemplate
[] =
515 { CKA_CLASS
, &pubClass
, (CK_ULONG
) sizeof(pubClass
) },
516 { CKA_KEY_TYPE
, &keyType
, (CK_ULONG
) sizeof(keyType
) },
517 { CKA_TOKEN
, &falsevalue
, (CK_ULONG
) sizeof(falsevalue
) },
518 { CKA_PRIVATE
, &falsevalue
, (CK_ULONG
) sizeof(falsevalue
) },
519 { CKA_VERIFY
, &truevalue
, (CK_ULONG
) sizeof(truevalue
) },
520 { CKA_PRIME
, NULL
, 0 },
521 { CKA_SUBPRIME
, NULL
, 0 },
522 { CKA_BASE
, NULL
, 0 }
524 CK_OBJECT_HANDLE priv
= CK_INVALID_HANDLE
;
525 CK_OBJECT_HANDLE privClass
= CKO_PRIVATE_KEY
;
526 CK_ATTRIBUTE privTemplate
[] =
528 { CKA_CLASS
, &privClass
, (CK_ULONG
) sizeof(privClass
) },
529 { CKA_KEY_TYPE
, &keyType
, (CK_ULONG
) sizeof(keyType
) },
530 { CKA_TOKEN
, &falsevalue
, (CK_ULONG
) sizeof(falsevalue
) },
531 { CKA_PRIVATE
, &falsevalue
, (CK_ULONG
) sizeof(falsevalue
) },
532 { CKA_SENSITIVE
, &falsevalue
, (CK_ULONG
) sizeof(falsevalue
) },
533 { CKA_EXTRACTABLE
, &truevalue
, (CK_ULONG
) sizeof(truevalue
) },
534 { CKA_SIGN
, &truevalue
, (CK_ULONG
) sizeof(truevalue
) },
538 pk11_context_t
*pk11_ctx
;
545 pk11_ctx
= (pk11_context_t
*) isc_mem_get(key
->mctx
,
547 if (pk11_ctx
== NULL
)
548 return (ISC_R_NOMEMORY
);
549 ret
= pk11_get_session(pk11_ctx
, OP_DSA
, ISC_TRUE
, ISC_FALSE
,
550 ISC_FALSE
, NULL
, pk11_get_best_token(OP_DSA
));
551 if (ret
!= ISC_R_SUCCESS
)
554 bits
= key
->key_size
;
555 PK11_RET(pkcs_C_GenerateKey
,
556 (pk11_ctx
->session
, &mech
, dpTemplate
, (CK_ULONG
) 5, &dp
),
557 DST_R_CRYPTOFAILURE
);
559 dsa
= (pk11_object_t
*) isc_mem_get(key
->mctx
, sizeof(*dsa
));
561 DST_RET(ISC_R_NOMEMORY
);
562 memset(dsa
, 0, sizeof(*dsa
));
563 key
->keydata
.pkey
= dsa
;
564 dsa
->repr
= (CK_ATTRIBUTE
*) isc_mem_get(key
->mctx
, sizeof(*attr
) * 5);
565 if (dsa
->repr
== NULL
)
566 DST_RET(ISC_R_NOMEMORY
);
567 memset(dsa
->repr
, 0, sizeof(*attr
) * 5);
571 attr
[0].type
= CKA_PRIME
;
572 attr
[1].type
= CKA_SUBPRIME
;
573 attr
[2].type
= CKA_BASE
;
574 attr
[3].type
= CKA_VALUE
;
575 attr
[4].type
= CKA_VALUE2
;
577 PK11_RET(pkcs_C_GetAttributeValue
,
578 (pk11_ctx
->session
, dp
, attr
, 3),
579 DST_R_CRYPTOFAILURE
);
581 for (i
= 0; i
<= 2; i
++) {
582 attr
[i
].pValue
= isc_mem_get(key
->mctx
, attr
[i
].ulValueLen
);
583 if (attr
[i
].pValue
== NULL
)
584 DST_RET(ISC_R_NOMEMORY
);
585 memset(attr
[i
].pValue
, 0, attr
[i
].ulValueLen
);
587 PK11_RET(pkcs_C_GetAttributeValue
,
588 (pk11_ctx
->session
, dp
, attr
, 3),
589 DST_R_CRYPTOFAILURE
);
590 pubTemplate
[5].pValue
= attr
[0].pValue
;
591 pubTemplate
[5].ulValueLen
= attr
[0].ulValueLen
;
592 pubTemplate
[6].pValue
= attr
[1].pValue
;
593 pubTemplate
[6].ulValueLen
= attr
[1].ulValueLen
;
594 pubTemplate
[7].pValue
= attr
[2].pValue
;
595 pubTemplate
[7].ulValueLen
= attr
[2].ulValueLen
;
597 mech
.mechanism
= CKM_DSA_KEY_PAIR_GEN
;
598 PK11_RET(pkcs_C_GenerateKeyPair
,
599 (pk11_ctx
->session
, &mech
,
600 pubTemplate
, (CK_ULONG
) 8,
601 privTemplate
, (CK_ULONG
) 7,
603 DST_R_CRYPTOFAILURE
);
607 PK11_RET(pkcs_C_GetAttributeValue
,
608 (pk11_ctx
->session
, pub
, attr
, 1),
609 DST_R_CRYPTOFAILURE
);
610 attr
->pValue
= isc_mem_get(key
->mctx
, attr
->ulValueLen
);
611 if (attr
->pValue
== NULL
)
612 DST_RET(ISC_R_NOMEMORY
);
613 memset(attr
->pValue
, 0, attr
->ulValueLen
);
614 PK11_RET(pkcs_C_GetAttributeValue
,
615 (pk11_ctx
->session
, pub
, attr
, 1),
616 DST_R_CRYPTOFAILURE
);
619 attr
->type
= CKA_VALUE
;
620 PK11_RET(pkcs_C_GetAttributeValue
,
621 (pk11_ctx
->session
, priv
, attr
, 1),
622 DST_R_CRYPTOFAILURE
);
623 attr
->pValue
= isc_mem_get(key
->mctx
, attr
->ulValueLen
);
624 if (attr
->pValue
== NULL
)
625 DST_RET(ISC_R_NOMEMORY
);
626 memset(attr
->pValue
, 0, attr
->ulValueLen
);
627 PK11_RET(pkcs_C_GetAttributeValue
,
628 (pk11_ctx
->session
, priv
, attr
, 1),
629 DST_R_CRYPTOFAILURE
);
630 attr
->type
= CKA_VALUE2
;
632 (void) pkcs_C_DestroyObject(pk11_ctx
->session
, priv
);
633 (void) pkcs_C_DestroyObject(pk11_ctx
->session
, pub
);
634 (void) pkcs_C_DestroyObject(pk11_ctx
->session
, dp
);
635 pk11_return_session(pk11_ctx
);
636 memset(pk11_ctx
, 0, sizeof(*pk11_ctx
));
637 isc_mem_put(key
->mctx
, pk11_ctx
, sizeof(*pk11_ctx
));
639 return (ISC_R_SUCCESS
);
642 pkcs11dsa_destroy(key
);
643 if (priv
!= CK_INVALID_HANDLE
)
644 (void) pkcs_C_DestroyObject(pk11_ctx
->session
, priv
);
645 if (pub
!= CK_INVALID_HANDLE
)
646 (void) pkcs_C_DestroyObject(pk11_ctx
->session
, pub
);
647 if (dp
!= CK_INVALID_HANDLE
)
648 (void) pkcs_C_DestroyObject(pk11_ctx
->session
, dp
);
649 pk11_return_session(pk11_ctx
);
650 memset(pk11_ctx
, 0, sizeof(*pk11_ctx
));
651 isc_mem_put(key
->mctx
, pk11_ctx
, sizeof(*pk11_ctx
));
657 pkcs11dsa_isprivate(const dst_key_t
*key
) {
658 pk11_object_t
*dsa
= key
->keydata
.pkey
;
663 attr
= pk11_attribute_bytype(dsa
, CKA_VALUE2
);
664 return (ISC_TF((attr
!= NULL
) || dsa
->ontoken
));
668 pkcs11dsa_destroy(dst_key_t
*key
) {
669 pk11_object_t
*dsa
= key
->keydata
.pkey
;
675 INSIST((dsa
->object
== CK_INVALID_HANDLE
) || dsa
->ontoken
);
677 for (attr
= pk11_attribute_first(dsa
);
679 attr
= pk11_attribute_next(dsa
, attr
))
680 switch (attr
->type
) {
686 if (attr
->pValue
!= NULL
) {
687 memset(attr
->pValue
, 0, attr
->ulValueLen
);
688 isc_mem_put(key
->mctx
,
694 if (dsa
->repr
!= NULL
) {
695 memset(dsa
->repr
, 0, dsa
->attrcnt
* sizeof(*attr
));
696 isc_mem_put(key
->mctx
,
698 dsa
->attrcnt
* sizeof(*attr
));
700 memset(dsa
, 0, sizeof(*dsa
));
701 isc_mem_put(key
->mctx
, dsa
, sizeof(*dsa
));
702 key
->keydata
.pkey
= NULL
;
707 pkcs11dsa_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
712 unsigned int t
, p_bytes
;
713 CK_ATTRIBUTE
*prime
= NULL
, *subprime
= NULL
;
714 CK_ATTRIBUTE
*base
= NULL
, *pub_key
= NULL
;
717 REQUIRE(key
->keydata
.pkey
!= NULL
);
719 dsa
= key
->keydata
.pkey
;
721 for (attr
= pk11_attribute_first(dsa
);
723 attr
= pk11_attribute_next(dsa
, attr
))
724 switch (attr
->type
) {
738 REQUIRE((prime
!= NULL
) && (subprime
!= NULL
) &&
739 (base
!= NULL
) && (pub_key
!= NULL
));
741 isc_buffer_availableregion(data
, &r
);
743 t
= (prime
->ulValueLen
- 64) / 8;
745 return (DST_R_INVALIDPUBLICKEY
);
746 p_bytes
= 64 + 8 * t
;
748 dnslen
= 1 + (key
->key_size
* 3)/8 + ISC_SHA1_DIGESTLENGTH
;
749 if (r
.length
< (unsigned int) dnslen
)
750 return (ISC_R_NOSPACE
);
752 memset(r
.base
, 0, dnslen
);
754 isc_region_consume(&r
, 1);
756 cp
= (CK_BYTE
*) subprime
->pValue
;
757 memmove(r
.base
+ ISC_SHA1_DIGESTLENGTH
- subprime
->ulValueLen
,
758 cp
, subprime
->ulValueLen
);
759 isc_region_consume(&r
, ISC_SHA1_DIGESTLENGTH
);
760 cp
= (CK_BYTE
*) prime
->pValue
;
761 memmove(r
.base
+ key
->key_size
/8 - prime
->ulValueLen
,
762 cp
, prime
->ulValueLen
);
763 isc_region_consume(&r
, p_bytes
);
764 cp
= (CK_BYTE
*) base
->pValue
;
765 memmove(r
.base
+ key
->key_size
/8 - base
->ulValueLen
,
766 cp
, base
->ulValueLen
);
767 isc_region_consume(&r
, p_bytes
);
768 cp
= (CK_BYTE
*) pub_key
->pValue
;
769 memmove(r
.base
+ key
->key_size
/8 - pub_key
->ulValueLen
,
770 cp
, pub_key
->ulValueLen
);
771 isc_region_consume(&r
, p_bytes
);
773 isc_buffer_add(data
, dnslen
);
775 return (ISC_R_SUCCESS
);
779 pkcs11dsa_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
782 unsigned int t
, p_bytes
;
783 CK_BYTE
*prime
, *subprime
, *base
, *pub_key
;
786 isc_buffer_remainingregion(data
, &r
);
788 return (ISC_R_SUCCESS
);
790 dsa
= (pk11_object_t
*) isc_mem_get(key
->mctx
, sizeof(*dsa
));
792 return (ISC_R_NOMEMORY
);
793 memset(dsa
, 0, sizeof(*dsa
));
795 t
= (unsigned int) *r
.base
;
796 isc_region_consume(&r
, 1);
798 memset(dsa
, 0, sizeof(*dsa
));
799 isc_mem_put(key
->mctx
, dsa
, sizeof(*dsa
));
800 return (DST_R_INVALIDPUBLICKEY
);
802 p_bytes
= 64 + 8 * t
;
804 if (r
.length
< ISC_SHA1_DIGESTLENGTH
+ 3 * p_bytes
) {
805 memset(dsa
, 0, sizeof(*dsa
));
806 isc_mem_put(key
->mctx
, dsa
, sizeof(*dsa
));
807 return (DST_R_INVALIDPUBLICKEY
);
811 isc_region_consume(&r
, ISC_SHA1_DIGESTLENGTH
);
814 isc_region_consume(&r
, p_bytes
);
817 isc_region_consume(&r
, p_bytes
);
820 isc_region_consume(&r
, p_bytes
);
822 key
->key_size
= p_bytes
* 8;
824 isc_buffer_forward(data
, 1 + ISC_SHA1_DIGESTLENGTH
+ 3 * p_bytes
);
826 dsa
->repr
= (CK_ATTRIBUTE
*) isc_mem_get(key
->mctx
, sizeof(*attr
) * 4);
827 if (dsa
->repr
== NULL
)
829 memset(dsa
->repr
, 0, sizeof(*attr
) * 4);
833 attr
[0].type
= CKA_PRIME
;
834 attr
[0].pValue
= isc_mem_get(key
->mctx
, p_bytes
);
835 if (attr
[0].pValue
== NULL
)
837 memmove(attr
[0].pValue
, prime
, p_bytes
);
838 attr
[0].ulValueLen
= p_bytes
;
840 attr
[1].type
= CKA_SUBPRIME
;
841 attr
[1].pValue
= isc_mem_get(key
->mctx
, ISC_SHA1_DIGESTLENGTH
);
842 if (attr
[1].pValue
== NULL
)
844 memmove(attr
[1].pValue
, subprime
, ISC_SHA1_DIGESTLENGTH
);
845 attr
[1].ulValueLen
= ISC_SHA1_DIGESTLENGTH
;
847 attr
[2].type
= CKA_BASE
;
848 attr
[2].pValue
= isc_mem_get(key
->mctx
, p_bytes
);
849 if (attr
[2].pValue
== NULL
)
851 memmove(attr
[2].pValue
, base
, p_bytes
);
852 attr
[2].ulValueLen
= p_bytes
;
854 attr
[3].type
= CKA_VALUE
;
855 attr
[3].pValue
= isc_mem_get(key
->mctx
, p_bytes
);
856 if (attr
[3].pValue
== NULL
)
858 memmove(attr
[3].pValue
, pub_key
, p_bytes
);
859 attr
[3].ulValueLen
= p_bytes
;
861 key
->keydata
.pkey
= dsa
;
863 return (ISC_R_SUCCESS
);
866 for (attr
= pk11_attribute_first(dsa
);
868 attr
= pk11_attribute_next(dsa
, attr
))
869 switch (attr
->type
) {
874 if (attr
->pValue
!= NULL
) {
875 memset(attr
->pValue
, 0, attr
->ulValueLen
);
876 isc_mem_put(key
->mctx
,
882 if (dsa
->repr
!= NULL
) {
883 memset(dsa
->repr
, 0, dsa
->attrcnt
* sizeof(*attr
));
884 isc_mem_put(key
->mctx
,
886 dsa
->attrcnt
* sizeof(*attr
));
888 memset(dsa
, 0, sizeof(*dsa
));
889 isc_mem_put(key
->mctx
, dsa
, sizeof(*dsa
));
890 return (ISC_R_NOMEMORY
);
894 pkcs11dsa_tofile(const dst_key_t
*key
, const char *directory
) {
898 CK_ATTRIBUTE
*prime
= NULL
, *subprime
= NULL
, *base
= NULL
;
899 CK_ATTRIBUTE
*pub_key
= NULL
, *priv_key
= NULL
;
901 unsigned char bufs
[5][128];
903 if (key
->keydata
.pkey
== NULL
)
904 return (DST_R_NULLKEY
);
908 return (dst__privstruct_writefile(key
, &priv
, directory
));
911 dsa
= key
->keydata
.pkey
;
913 for (attr
= pk11_attribute_first(dsa
);
915 attr
= pk11_attribute_next(dsa
, attr
))
916 switch (attr
->type
) {
933 if ((prime
== NULL
) || (subprime
== NULL
) || (base
== NULL
) ||
934 (pub_key
== NULL
) || (priv_key
==NULL
))
935 return (DST_R_NULLKEY
);
937 priv
.elements
[cnt
].tag
= TAG_DSA_PRIME
;
938 priv
.elements
[cnt
].length
= (unsigned short) prime
->ulValueLen
;
939 memmove(bufs
[cnt
], prime
->pValue
, prime
->ulValueLen
);
940 priv
.elements
[cnt
].data
= bufs
[cnt
];
943 priv
.elements
[cnt
].tag
= TAG_DSA_SUBPRIME
;
944 priv
.elements
[cnt
].length
= (unsigned short) subprime
->ulValueLen
;
945 memmove(bufs
[cnt
], subprime
->pValue
, subprime
->ulValueLen
);
946 priv
.elements
[cnt
].data
= bufs
[cnt
];
949 priv
.elements
[cnt
].tag
= TAG_DSA_BASE
;
950 priv
.elements
[cnt
].length
= (unsigned short) base
->ulValueLen
;
951 memmove(bufs
[cnt
], base
->pValue
, base
->ulValueLen
);
952 priv
.elements
[cnt
].data
= bufs
[cnt
];
955 priv
.elements
[cnt
].tag
= TAG_DSA_PRIVATE
;
956 priv
.elements
[cnt
].length
= (unsigned short) priv_key
->ulValueLen
;
957 memmove(bufs
[cnt
], priv_key
->pValue
, priv_key
->ulValueLen
);
958 priv
.elements
[cnt
].data
= bufs
[cnt
];
961 priv
.elements
[cnt
].tag
= TAG_DSA_PUBLIC
;
962 priv
.elements
[cnt
].length
= (unsigned short) pub_key
->ulValueLen
;
963 memmove(bufs
[cnt
], pub_key
->pValue
, pub_key
->ulValueLen
);
964 priv
.elements
[cnt
].data
= bufs
[cnt
];
967 priv
.nelements
= cnt
;
968 return (dst__privstruct_writefile(key
, &priv
, directory
));
972 pkcs11dsa_parse(dst_key_t
*key
, isc_lex_t
*lexer
, dst_key_t
*pub
) {
976 pk11_object_t
*dsa
= NULL
;
978 isc_mem_t
*mctx
= key
->mctx
;
980 /* read private key file */
981 ret
= dst__privstruct_parse(key
, DST_ALG_DSA
, lexer
, mctx
, &priv
);
982 if (ret
!= ISC_R_SUCCESS
)
986 if (priv
.nelements
!= 0)
987 DST_RET(DST_R_INVALIDPRIVATEKEY
);
989 DST_RET(DST_R_INVALIDPRIVATEKEY
);
991 key
->keydata
.pkey
= pub
->keydata
.pkey
;
992 pub
->keydata
.pkey
= NULL
;
993 key
->key_size
= pub
->key_size
;
995 dst__privstruct_free(&priv
, mctx
);
996 memset(&priv
, 0, sizeof(priv
));
998 return (ISC_R_SUCCESS
);
1001 dsa
= (pk11_object_t
*) isc_mem_get(key
->mctx
, sizeof(*dsa
));
1003 DST_RET(ISC_R_NOMEMORY
);
1004 memset(dsa
, 0, sizeof(*dsa
));
1005 key
->keydata
.pkey
= dsa
;
1007 dsa
->repr
= (CK_ATTRIBUTE
*) isc_mem_get(key
->mctx
, sizeof(*attr
) * 5);
1008 if (dsa
->repr
== NULL
)
1009 DST_RET(ISC_R_NOMEMORY
);
1010 memset(dsa
->repr
, 0, sizeof(*attr
) * 5);
1013 attr
[0].type
= CKA_PRIME
;
1014 attr
[1].type
= CKA_SUBPRIME
;
1015 attr
[2].type
= CKA_BASE
;
1016 attr
[3].type
= CKA_VALUE
;
1017 attr
[4].type
= CKA_VALUE2
;
1019 for (i
= 0; i
< priv
.nelements
; i
++) {
1022 bn
= isc_mem_get(key
->mctx
, priv
.elements
[i
].length
);
1024 DST_RET(ISC_R_NOMEMORY
);
1025 memmove(bn
, priv
.elements
[i
].data
, priv
.elements
[i
].length
);
1027 switch (priv
.elements
[i
].tag
) {
1029 attr
= pk11_attribute_bytype(dsa
, CKA_PRIME
);
1030 INSIST(attr
!= NULL
);
1032 attr
->ulValueLen
= priv
.elements
[i
].length
;
1034 case TAG_DSA_SUBPRIME
:
1035 attr
= pk11_attribute_bytype(dsa
,
1037 INSIST(attr
!= NULL
);
1039 attr
->ulValueLen
= priv
.elements
[i
].length
;
1042 attr
= pk11_attribute_bytype(dsa
, CKA_BASE
);
1043 INSIST(attr
!= NULL
);
1045 attr
->ulValueLen
= priv
.elements
[i
].length
;
1047 case TAG_DSA_PRIVATE
:
1048 attr
= pk11_attribute_bytype(dsa
, CKA_VALUE2
);
1049 INSIST(attr
!= NULL
);
1051 attr
->ulValueLen
= priv
.elements
[i
].length
;
1053 case TAG_DSA_PUBLIC
:
1054 attr
= pk11_attribute_bytype(dsa
, CKA_VALUE
);
1055 INSIST(attr
!= NULL
);
1057 attr
->ulValueLen
= priv
.elements
[i
].length
;
1061 dst__privstruct_free(&priv
, mctx
);
1063 attr
= pk11_attribute_bytype(dsa
, CKA_PRIME
);
1064 INSIST(attr
!= NULL
);
1065 key
->key_size
= pk11_numbits(attr
->pValue
, attr
->ulValueLen
);
1067 return (ISC_R_SUCCESS
);
1070 pkcs11dsa_destroy(key
);
1071 dst__privstruct_free(&priv
, mctx
);
1072 memset(&priv
, 0, sizeof(priv
));
1076 static dst_func_t pkcs11dsa_functions
= {
1077 pkcs11dsa_createctx
,
1078 NULL
, /*%< createctx2 */
1079 pkcs11dsa_destroyctx
,
1083 NULL
, /*%< verify2 */
1084 NULL
, /*%< computesecret */
1086 NULL
, /*%< paramcompare */
1088 pkcs11dsa_isprivate
,
1094 NULL
, /*%< cleanup */
1095 NULL
, /*%< fromlabel */
1097 NULL
, /*%< restore */
1101 dst__pkcs11dsa_init(dst_func_t
**funcp
) {
1102 REQUIRE(funcp
!= NULL
);
1104 *funcp
= &pkcs11dsa_functions
;
1105 return (ISC_R_SUCCESS
);
1108 #else /* PKCS11CRYPTO */
1110 #include <isc/util.h>
1112 EMPTY_TRANSLATION_UNIT
1114 #endif /* PKCS11CRYPTO */