Commit 185d680e authored by Evan Hunt's avatar Evan Hunt
Browse files

[master] add support for native pkcs11 on keyper

4547.	[port]		Add support for --enable-native-pkcs11 on the AEP
			Keyper HSM. [RT #42463]
parent 1015ce24
4547. [port] Add support for --enable-native-pkcs11 on the AEP
Keyper HSM. [RT #42463]
4546. [func] Extend the use of const declarations. [RT #43379]
4545. [func] Expand YAML output from dnstap-read to include
......
......@@ -2184,7 +2184,9 @@ case "$want_native_pkcs11" in
set_pk11_flavor="yes"
;;
*Keyper*)
AC_MSG_RESULT(AEP Keyper: not yet supported)
AC_MSG_RESULT(AEP Keyper)
pk11_flavor="PK11_AEP_FLAVOR"
set_pk11_flavor="yes"
;;
undefined)
AC_MSG_RESULT(undefined provider?)
......
......@@ -191,8 +191,9 @@ pkcs11dh_computesecret(const dst_key_t *pub, const dst_key_t *priv,
if (attr == NULL)
return (DST_R_INVALIDPUBLICKEY);
ret = pk11_get_session(&ctx, OP_DH, ISC_TRUE, ISC_FALSE, ISC_FALSE,
NULL, pk11_get_best_token(OP_DH));
ret = pk11_get_session(&ctx, OP_DH, ISC_TRUE, ISC_FALSE,
priv->keydata.pkey->reqlogon, NULL,
pk11_get_best_token(OP_DH));
if (ret != ISC_R_SUCCESS)
return (ret);
......
......@@ -95,16 +95,20 @@ pkcs11dsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) {
isc_result_t ret;
unsigned int i;
REQUIRE(key != NULL);
dsa = key->keydata.pkey;
REQUIRE(dsa != NULL);
pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
sizeof(*pk11_ctx));
if (pk11_ctx == NULL)
return (ISC_R_NOMEMORY);
ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE,
ISC_FALSE, NULL, pk11_get_best_token(OP_DSA));
dsa->reqlogon, NULL,
pk11_get_best_token(OP_DSA));
if (ret != ISC_R_SUCCESS)
goto err;
dsa = key->keydata.pkey;
if (dsa->ontoken && (dsa->object != CK_INVALID_HANDLE)) {
pk11_ctx->ontoken = dsa->ontoken;
pk11_ctx->object = dsa->object;
......@@ -225,16 +229,18 @@ pkcs11dsa_createctx_verify(dst_key_t *key, dst_context_t *dctx) {
isc_result_t ret;
unsigned int i;
dsa = key->keydata.pkey;
REQUIRE(dsa != NULL);
pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
sizeof(*pk11_ctx));
if (pk11_ctx == NULL)
return (ISC_R_NOMEMORY);
ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE,
ISC_FALSE, NULL, pk11_get_best_token(OP_DSA));
dsa->reqlogon, NULL,
pk11_get_best_token(OP_DSA));
if (ret != ISC_R_SUCCESS)
goto err;
dsa = key->keydata.pkey;
if (dsa->ontoken && (dsa->object != CK_INVALID_HANDLE)) {
pk11_ctx->ontoken = dsa->ontoken;
pk11_ctx->object = dsa->object;
......
......@@ -74,9 +74,9 @@ pkcs11ecdsa_createctx(dst_key_t *key, dst_context_t *dctx) {
pk11_object_t *ec = key->keydata.pkey;
isc_result_t ret;
UNUSED(key);
REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
dctx->key->key_alg == DST_ALG_ECDSA384);
REQUIRE(ec != NULL);
if (dctx->key->key_alg == DST_ALG_ECDSA256)
mech.mechanism = CKM_SHA256;
......@@ -92,8 +92,8 @@ pkcs11ecdsa_createctx(dst_key_t *key, dst_context_t *dctx) {
slotid = ec->slot;
else
slotid = pk11_get_best_token(OP_EC);
ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE, ISC_FALSE,
NULL, slotid);
ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE,
ec->reqlogon, NULL, slotid);
if (ret != ISC_R_SUCCESS)
goto err;
......@@ -348,7 +348,7 @@ pkcs11ecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
(pk11_ctx->session,
digest, dgstlen,
(CK_BYTE_PTR) sig->base, (CK_ULONG) sig->length),
DST_R_SIGNFAILURE);
DST_R_VERIFYFAILURE);
err:
......
......@@ -156,16 +156,20 @@ pkcs11gost_createctx_sign(dst_key_t *key, dst_context_t *dctx) {
isc_result_t ret;
unsigned int i;
REQUIRE(key != NULL);
gost = key->keydata.pkey;
REQUIRE(gost != NULL);
pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
sizeof(*pk11_ctx));
if (pk11_ctx == NULL)
return (ISC_R_NOMEMORY);
ret = pk11_get_session(pk11_ctx, OP_GOST, ISC_TRUE, ISC_FALSE,
ISC_FALSE, NULL, pk11_get_best_token(OP_GOST));
gost->reqlogon, NULL,
pk11_get_best_token(OP_GOST));
if (ret != ISC_R_SUCCESS)
goto err;
gost = key->keydata.pkey;
if (gost->ontoken && (gost->object != CK_INVALID_HANDLE)) {
pk11_ctx->ontoken = gost->ontoken;
pk11_ctx->object = gost->object;
......@@ -257,16 +261,20 @@ pkcs11gost_createctx_verify(dst_key_t *key, dst_context_t *dctx) {
isc_result_t ret;
unsigned int i;
REQUIRE(key != NULL);
gost = key->keydata.pkey;
REQUIRE(gost != NULL);
pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
sizeof(*pk11_ctx));
if (pk11_ctx == NULL)
return (ISC_R_NOMEMORY);
ret = pk11_get_session(pk11_ctx, OP_GOST, ISC_TRUE, ISC_FALSE,
ISC_FALSE, NULL, pk11_get_best_token(OP_GOST));
gost->reqlogon, NULL,
pk11_get_best_token(OP_GOST));
if (ret != ISC_R_SUCCESS)
goto err;
gost = key->keydata.pkey;
if (gost->ontoken && (gost->object != CK_INVALID_HANDLE)) {
pk11_ctx->ontoken = gost->ontoken;
pk11_ctx->object = gost->object;
......
......@@ -47,6 +47,8 @@ static void pkcs11rsa_destroy(dst_key_t *key);
static isc_result_t pkcs11rsa_fetch(dst_key_t *key, const char *engine,
const char *label, dst_key_t *pub);
#ifndef PK11_RSA_PKCS_REPLACE
static isc_result_t
pkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) {
CK_RV rv;
......@@ -499,6 +501,509 @@ pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
return (ret);
}
#else
/*
* CKM_<hash>_RSA_PKCS mechanisms are not available so fall back
* to CKM_RSA_PKCS and do the EMSA-PKCS#1-v1.5 encapsulation by hand.
*/
CK_BYTE md5_der[] =
{ 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00,
0x04, 0x10 };
CK_BYTE sha1_der[] =
{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
CK_BYTE sha256_der[] =
{ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
0x00, 0x04, 0x20 };
CK_BYTE sha512_der[] =
{ 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
0x00, 0x04, 0x40 };
#define MAX_DER_SIZE 19
#define MIN_PKCS1_PADLEN 11
static isc_result_t
pkcs11rsa_createctx(dst_key_t *key, dst_context_t *dctx) {
CK_RV rv;
CK_MECHANISM mech = { 0, NULL, 0 };
CK_SLOT_ID slotid;
pk11_object_t *rsa = key->keydata.pkey;
pk11_context_t *pk11_ctx;
isc_result_t ret;
#ifndef PK11_MD5_DISABLE
REQUIRE(key->key_alg == DST_ALG_RSAMD5 ||
key->key_alg == DST_ALG_RSASHA1 ||
key->key_alg == DST_ALG_NSEC3RSASHA1 ||
key->key_alg == DST_ALG_RSASHA256 ||
key->key_alg == DST_ALG_RSASHA512);
#else
REQUIRE(key->key_alg == DST_ALG_RSASHA1 ||
key->key_alg == DST_ALG_NSEC3RSASHA1 ||
key->key_alg == DST_ALG_RSASHA256 ||
key->key_alg == DST_ALG_RSASHA512);
#endif
REQUIRE(rsa != NULL);
switch (key->key_alg) {
#ifndef PK11_MD5_DISABLE
case DST_ALG_RSAMD5:
mech.mechanism = CKM_MD5;
break;
#endif
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
mech.mechanism = CKM_SHA_1;
break;
case DST_ALG_RSASHA256:
mech.mechanism = CKM_SHA256;
break;
case DST_ALG_RSASHA512:
mech.mechanism = CKM_SHA512;
break;
default:
INSIST(0);
}
pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
sizeof(*pk11_ctx));
if (pk11_ctx == NULL)
return (ISC_R_NOMEMORY);
memset(pk11_ctx, 0, sizeof(*pk11_ctx));
if (rsa->ontoken)
slotid = rsa->slot;
else
slotid = pk11_get_best_token(OP_RSA);
ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
rsa->reqlogon, NULL, slotid);
if (ret != ISC_R_SUCCESS)
goto err;
PK11_RET(pkcs_C_DigestInit, (pk11_ctx->session, &mech), ISC_R_FAILURE);
dctx->ctxdata.pk11_ctx = pk11_ctx;
return (ISC_R_SUCCESS);
err:
pk11_return_session(pk11_ctx);
memset(pk11_ctx, 0, sizeof(*pk11_ctx));
isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
return (ret);
}
static void
pkcs11rsa_destroyctx(dst_context_t *dctx) {
CK_BYTE garbage[ISC_SHA512_DIGESTLENGTH];
CK_ULONG len = ISC_SHA512_DIGESTLENGTH;
pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
if (pk11_ctx != NULL) {
(void) pkcs_C_DigestFinal(pk11_ctx->session, garbage, &len);
memset(garbage, 0, sizeof(garbage));
pk11_return_session(pk11_ctx);
memset(pk11_ctx, 0, sizeof(*pk11_ctx));
isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
dctx->ctxdata.pk11_ctx = NULL;
}
}
static isc_result_t
pkcs11rsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
CK_RV rv;
pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
isc_result_t ret = ISC_R_SUCCESS;
PK11_CALL(pkcs_C_DigestUpdate,
(pk11_ctx->session,
(CK_BYTE_PTR) data->base,
(CK_ULONG) data->length),
ISC_R_FAILURE);
return (ret);
}
static isc_result_t
pkcs11rsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
CK_RV rv;
CK_MECHANISM mech = { CKM_RSA_PKCS, NULL, 0 };
CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
CK_KEY_TYPE keyType = CKK_RSA;
CK_ATTRIBUTE keyTemplate[] =
{
{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
{ CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
{ CKA_MODULUS, NULL, 0 },
{ CKA_PUBLIC_EXPONENT, NULL, 0 },
{ CKA_PRIVATE_EXPONENT, NULL, 0 },
{ CKA_PRIME_1, NULL, 0 },
{ CKA_PRIME_2, NULL, 0 },
{ CKA_EXPONENT_1, NULL, 0 },
{ CKA_EXPONENT_2, NULL, 0 },
{ CKA_COEFFICIENT, NULL, 0 }
};
CK_ATTRIBUTE *attr;
CK_BYTE digest[MAX_DER_SIZE + ISC_SHA512_DIGESTLENGTH];
CK_BYTE *der;
CK_ULONG derlen;
CK_ULONG hashlen;
CK_ULONG dgstlen;
CK_ULONG siglen = 0;
pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
dst_key_t *key = dctx->key;
pk11_object_t *rsa = key->keydata.pkey;
isc_region_t r;
isc_result_t ret = ISC_R_SUCCESS;
unsigned int i;
#ifndef PK11_MD5_DISABLE
REQUIRE(key->key_alg == DST_ALG_RSAMD5 ||
key->key_alg == DST_ALG_RSASHA1 ||
key->key_alg == DST_ALG_NSEC3RSASHA1 ||
key->key_alg == DST_ALG_RSASHA256 ||
key->key_alg == DST_ALG_RSASHA512);
#else
REQUIRE(key->key_alg == DST_ALG_RSASHA1 ||
key->key_alg == DST_ALG_NSEC3RSASHA1 ||
key->key_alg == DST_ALG_RSASHA256 ||
key->key_alg == DST_ALG_RSASHA512);
#endif
REQUIRE(rsa != NULL);
switch (key->key_alg) {
#ifndef PK11_MD5_DISABLE
case DST_ALG_RSAMD5:
der = md5_der;
derlen = sizeof(md5_der);
hashlen = ISC_MD5_DIGESTLENGTH;
break;
#endif
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
der = sha1_der;
derlen = sizeof(sha1_der);
hashlen = ISC_SHA1_DIGESTLENGTH;
break;
case DST_ALG_RSASHA256:
der = sha256_der;
derlen = sizeof(sha256_der);
hashlen = ISC_SHA256_DIGESTLENGTH;
break;
case DST_ALG_RSASHA512:
der = sha512_der;
derlen = sizeof(sha512_der);
hashlen = ISC_SHA512_DIGESTLENGTH;
break;
default:
INSIST(0);
}
dgstlen = derlen + hashlen;
INSIST(dgstlen <= sizeof(digest));
memmove(digest, der, derlen);
PK11_RET(pkcs_C_DigestFinal,
(pk11_ctx->session, digest + derlen, &hashlen),
DST_R_SIGNFAILURE);
isc_buffer_availableregion(sig, &r);
if (r.length < (unsigned int) dgstlen + MIN_PKCS1_PADLEN)
return (ISC_R_NOSPACE);
if (rsa->ontoken && (rsa->object != CK_INVALID_HANDLE)) {
pk11_ctx->ontoken = rsa->ontoken;
pk11_ctx->object = rsa->object;
goto token_key;
}
for (attr = pk11_attribute_first(rsa);
attr != NULL;
attr = pk11_attribute_next(rsa, attr))
switch (attr->type) {
case CKA_MODULUS:
INSIST(keyTemplate[6].type == attr->type);
keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
attr->ulValueLen);
if (keyTemplate[6].pValue == NULL)
DST_RET(ISC_R_NOMEMORY);
memmove(keyTemplate[6].pValue, attr->pValue,
attr->ulValueLen);
keyTemplate[6].ulValueLen = attr->ulValueLen;
break;
case CKA_PUBLIC_EXPONENT:
INSIST(keyTemplate[7].type == attr->type);
keyTemplate[7].pValue = isc_mem_get(dctx->mctx,
attr->ulValueLen);
if (keyTemplate[7].pValue == NULL)
DST_RET(ISC_R_NOMEMORY);
memmove(keyTemplate[7].pValue, attr->pValue,
attr->ulValueLen);
keyTemplate[7].ulValueLen = attr->ulValueLen;
break;
case CKA_PRIVATE_EXPONENT:
INSIST(keyTemplate[8].type == attr->type);
keyTemplate[8].pValue = isc_mem_get(dctx->mctx,
attr->ulValueLen);
if (keyTemplate[8].pValue == NULL)
DST_RET(ISC_R_NOMEMORY);
memmove(keyTemplate[8].pValue, attr->pValue,
attr->ulValueLen);
keyTemplate[8].ulValueLen = attr->ulValueLen;
break;
case CKA_PRIME_1:
INSIST(keyTemplate[9].type == attr->type);
keyTemplate[9].pValue = isc_mem_get(dctx->mctx,
attr->ulValueLen);
if (keyTemplate[9].pValue == NULL)
DST_RET(ISC_R_NOMEMORY);
memmove(keyTemplate[9].pValue, attr->pValue,
attr->ulValueLen);
keyTemplate[9].ulValueLen = attr->ulValueLen;
break;
case CKA_PRIME_2:
INSIST(keyTemplate[10].type == attr->type);
keyTemplate[10].pValue = isc_mem_get(dctx->mctx,
attr->ulValueLen);
if (keyTemplate[10].pValue == NULL)
DST_RET(ISC_R_NOMEMORY);
memmove(keyTemplate[10].pValue, attr->pValue,
attr->ulValueLen);
keyTemplate[10].ulValueLen = attr->ulValueLen;
break;
case CKA_EXPONENT_1:
INSIST(keyTemplate[11].type == attr->type);
keyTemplate[11].pValue = isc_mem_get(dctx->mctx,
attr->ulValueLen);
if (keyTemplate[11].pValue == NULL)
DST_RET(ISC_R_NOMEMORY);
memmove(keyTemplate[11].pValue, attr->pValue,
attr->ulValueLen);
keyTemplate[11].ulValueLen = attr->ulValueLen;
break;
case CKA_EXPONENT_2:
INSIST(keyTemplate[12].type == attr->type);
keyTemplate[12].pValue = isc_mem_get(dctx->mctx,
attr->ulValueLen);
if (keyTemplate[12].pValue == NULL)
DST_RET(ISC_R_NOMEMORY);
memmove(keyTemplate[12].pValue, attr->pValue,
attr->ulValueLen);
keyTemplate[12].ulValueLen = attr->ulValueLen;
break;
case CKA_COEFFICIENT:
INSIST(keyTemplate[13].type == attr->type);
keyTemplate[13].pValue = isc_mem_get(dctx->mctx,
attr->ulValueLen);
if (keyTemplate[13].pValue == NULL)
DST_RET(ISC_R_NOMEMORY);
memmove(keyTemplate[13].pValue, attr->pValue,
attr->ulValueLen);
keyTemplate[13].ulValueLen = attr->ulValueLen;
break;
}
pk11_ctx->object = CK_INVALID_HANDLE;
pk11_ctx->ontoken = ISC_FALSE;
PK11_RET(pkcs_C_CreateObject,
(pk11_ctx->session,
keyTemplate, (CK_ULONG) 14,
&hKey),
ISC_R_FAILURE);
token_key:
PK11_RET(pkcs_C_SignInit,
(pk11_ctx->session, &mech,
pk11_ctx->ontoken ? pk11_ctx->object : hKey),
ISC_R_FAILURE);
PK11_RET(pkcs_C_Sign,
(pk11_ctx->session,
digest, dgstlen,
NULL, &siglen),
DST_R_SIGNFAILURE);
if (r.length < (unsigned int) siglen)
return (ISC_R_NOSPACE);
PK11_RET(pkcs_C_Sign,
(pk11_ctx->session,
digest, dgstlen,
(CK_BYTE_PTR) r.base, &siglen),
DST_R_SIGNFAILURE);
isc_buffer_add(sig, (unsigned int) siglen);
err:
if (hKey != CK_INVALID_HANDLE)
(void) pkcs_C_DestroyObject(pk11_ctx->session, hKey);
for (i = 6; i <= 13; i++)
if (keyTemplate[i].pValue != NULL) {
memset(keyTemplate[i].pValue, 0,
keyTemplate[i].ulValueLen);
isc_mem_put(dctx->mctx,
keyTemplate[i].pValue,
keyTemplate[i].ulValueLen);
}
pk11_return_session(pk11_ctx);
memset(pk11_ctx, 0, sizeof(*pk11_ctx));
isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
dctx->ctxdata.pk11_ctx = NULL;
return (ret);
}
static isc_result_t
pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
CK_RV rv;
CK_MECHANISM mech = { CKM_RSA_PKCS, NULL, 0 };
CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
CK_KEY_TYPE keyType = CKK_RSA;
CK_ATTRIBUTE keyTemplate[] =
{
{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
{ CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
{ CKA_MODULUS, NULL, 0 },
{ CKA_PUBLIC_EXPONENT, NULL, 0 },
};
CK_ATTRIBUTE *attr;
CK_BYTE digest[MAX_DER_SIZE + ISC_SHA512_DIGESTLENGTH];
CK_BYTE *der;
CK_ULONG derlen;
CK_ULONG hashlen;
CK_ULONG dgstlen;
pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
dst_key_t *key = dctx->key;
pk11_object_t *rsa = key->keydata.pkey;
isc_result_t ret = ISC_R_SUCCESS;
unsigned int i;
#ifndef PK11_MD5_DISABLE
REQUIRE(key->key_alg == DST_ALG_RSAMD5 ||
key->key_alg == DST_ALG_RSASHA1 ||
key->key_alg == DST_ALG_NSEC3RSASHA1 ||
key->key_alg == DST_ALG_RSASHA256 ||
key->key_alg == DST_ALG_RSASHA512);
#else
REQUIRE(key->key_alg == DST_ALG_RSASHA1 ||
key->key_alg == DST_ALG_NSEC3RSASHA1 ||
key->key_alg == DST_ALG_RSASHA256 ||
key->key_alg == DST_ALG_RSASHA512);
#endif
REQUIRE(rsa != NULL);
switch (key->key_alg) {
#ifndef PK11_MD5_DISABLE
case DST_ALG_RSAMD5:
der = md5_der;
derlen = sizeof(md5_der);
hashlen = ISC_MD5_DIGESTLENGTH;
break;
#endif
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
der = sha1_der;
derlen = sizeof(sha1_der);
hashlen = ISC_SHA1_DIGESTLENGTH;
break;
case DST_ALG_RSASHA256:
der = sha256_der;
derlen = sizeof(sha256_der);
hashlen = ISC_SHA256_DIGESTLENGTH;
break;
case DST_ALG_RSASHA512:
der = sha512_der;
derlen = sizeof(sha512_der);
hashlen = ISC_SHA512_DIGESTLENGTH;
break;
default:
INSIST(0);
}
dgstlen = derlen + hashlen;
INSIST(dgstlen <= sizeof(digest));
memmove(digest, der, derlen);
PK11_RET(pkcs_C_DigestFinal,
(pk11_ctx->session, digest + derlen, &hashlen),
DST_R_SIGNFAILURE);
for (attr = pk11_attribute_first(rsa);
attr != NULL;
attr = pk11_attribute_next(rsa, attr))
switch (attr->type