mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 12:40:00 -04:00
[v9_11] add support for native pkcs11 on keyper
4547. [port] Add support for --enable-native-pkcs11 on the AEP Keyper HSM. [RT #42463]
This commit is contained in:
parent
e7f06a8535
commit
f5c17a057f
11 changed files with 596 additions and 23 deletions
3
CHANGES
3
CHANGES
|
|
@ -1,3 +1,6 @@
|
|||
4547. [port] Add support for --enable-native-pkcs11 on the AEP
|
||||
Keyper HSM. [RT #42463]
|
||||
|
||||
--- 9.11.1b1 released ---
|
||||
|
||||
4545. [func] Expand YAML output from dnstap-read to include
|
||||
|
|
|
|||
20
configure
vendored
20
configure
vendored
|
|
@ -954,6 +954,7 @@ infodir
|
|||
docdir
|
||||
oldincludedir
|
||||
includedir
|
||||
runstatedir
|
||||
localstatedir
|
||||
sharedstatedir
|
||||
sysconfdir
|
||||
|
|
@ -1109,6 +1110,7 @@ datadir='${datarootdir}'
|
|||
sysconfdir='${prefix}/etc'
|
||||
sharedstatedir='${prefix}/com'
|
||||
localstatedir='${prefix}/var'
|
||||
runstatedir='${localstatedir}/run'
|
||||
includedir='${prefix}/include'
|
||||
oldincludedir='/usr/include'
|
||||
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
|
||||
|
|
@ -1361,6 +1363,15 @@ do
|
|||
| -silent | --silent | --silen | --sile | --sil)
|
||||
silent=yes ;;
|
||||
|
||||
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
||||
| --runstate | --runstat | --runsta | --runst | --runs \
|
||||
| --run | --ru | --r)
|
||||
ac_prev=runstatedir ;;
|
||||
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
||||
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
||||
| --run=* | --ru=* | --r=*)
|
||||
runstatedir=$ac_optarg ;;
|
||||
|
||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||
ac_prev=sbindir ;;
|
||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||
|
|
@ -1498,7 +1509,7 @@ fi
|
|||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||
libdir localedir mandir
|
||||
libdir localedir mandir runstatedir
|
||||
do
|
||||
eval ac_val=\$$ac_var
|
||||
# Remove trailing slashes.
|
||||
|
|
@ -1651,6 +1662,7 @@ Fine tuning of the installation directories:
|
|||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||
--includedir=DIR C header files [PREFIX/include]
|
||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||
|
|
@ -16721,8 +16733,10 @@ $as_echo "Cryptech" >&6; }
|
|||
set_pk11_flavor="yes"
|
||||
;;
|
||||
*Keyper*)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: AEP Keyper: not yet supported" >&5
|
||||
$as_echo "AEP Keyper: not yet supported" >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: AEP Keyper" >&5
|
||||
$as_echo "AEP Keyper" >&6; }
|
||||
pk11_flavor="PK11_AEP_FLAVOR"
|
||||
set_pk11_flavor="yes"
|
||||
;;
|
||||
undefined)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: undefined provider?" >&5
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
case CKA_MODULUS:
|
||||
INSIST(keyTemplate[5].type == attr->type);
|
||||
keyTemplate[5].pValue = isc_mem_get(dctx->mctx,
|
||||
attr->ulValueLen);
|
||||
if (keyTemplate[5].pValue == NULL)
|
||||
DST_RET(ISC_R_NOMEMORY);
|
||||
memmove(keyTemplate[5].pValue, attr->pValue,
|
||||
attr->ulValueLen);
|
||||
keyTemplate[5].ulValueLen = attr->ulValueLen;
|
||||
break;
|
||||
case CKA_PUBLIC_EXPONENT:
|
||||
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;
|
||||
if (pk11_numbits(attr->pValue,
|
||||
attr->ulValueLen)
|
||||
> RSA_MAX_PUBEXP_BITS)
|
||||
DST_RET(DST_R_VERIFYFAILURE);
|
||||
break;
|
||||
}
|
||||
pk11_ctx->object = CK_INVALID_HANDLE;
|
||||
pk11_ctx->ontoken = ISC_FALSE;
|
||||
PK11_RET(pkcs_C_CreateObject,
|
||||
(pk11_ctx->session,
|
||||
keyTemplate, (CK_ULONG) 7,
|
||||
&hKey),
|
||||
ISC_R_FAILURE);
|
||||
|
||||
PK11_RET(pkcs_C_VerifyInit,
|
||||
(pk11_ctx->session, &mech, hKey),
|
||||
ISC_R_FAILURE);
|
||||
|
||||
PK11_RET(pkcs_C_Verify,
|
||||
(pk11_ctx->session,
|
||||
digest, dgstlen,
|
||||
(CK_BYTE_PTR) sig->base, (CK_ULONG) sig->length),
|
||||
DST_R_VERIFYFAILURE);
|
||||
|
||||
err:
|
||||
if (hKey != CK_INVALID_HANDLE)
|
||||
(void) pkcs_C_DestroyObject(pk11_ctx->session, hKey);
|
||||
for (i = 5; i <= 6; 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);
|
||||
}
|
||||
#endif
|
||||
|
||||
static isc_boolean_t
|
||||
pkcs11rsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
|
||||
pk11_object_t *rsa1, *rsa2;
|
||||
|
|
@ -1546,7 +2051,11 @@ pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
|
|||
|
||||
static dst_func_t pkcs11rsa_functions = {
|
||||
pkcs11rsa_createctx,
|
||||
#ifndef PK11_RSA_PKCS_REPLACE
|
||||
pkcs11rsa_createctx2,
|
||||
#else
|
||||
NULL, /*%< createctx2 */
|
||||
#endif
|
||||
pkcs11rsa_destroyctx,
|
||||
pkcs11rsa_adddata,
|
||||
pkcs11rsa_sign,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ Current well-known HSMs are predefined in site.h according to HSM "flavors":
|
|||
...and with experimental status:
|
||||
|
||||
- OpenDNSSEC SoftHSMv1 with SHA224 support added
|
||||
- Cryptech with SHA224 support added
|
||||
- Cryptech
|
||||
- AEP Keyper
|
||||
|
||||
If BIND9 is configured with native PKCS#11 support (--enable-native-pkcs11),
|
||||
then pkcs11-tokens will raise an error when a mandatory algorithm is not
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
/* current implemented flags are:
|
||||
PK11_DH_PKCS_PARAMETER_GEN_SKIP
|
||||
PK11_DSA_PARAMETER_GEN_SKIP
|
||||
PK11_RSA_PKCS_REPLACE
|
||||
PK11_MD5_HMAC_REPLACE
|
||||
PK11_SHA_1_HMAC_REPLACE
|
||||
PK11_SHA224_HMAC_REPLACE
|
||||
|
|
@ -48,8 +49,10 @@ PK11_DH_DISABLE
|
|||
#define PK11_SOFTHSMV1_FLAVOR 1
|
||||
/* SoftHSMv2 */
|
||||
#define PK11_SOFTHSMV2_FLAVOR 2
|
||||
/* Cryptech with SHA224 */
|
||||
/* Cryptech */
|
||||
#define PK11_CRYPTECH_FLAVOR 3
|
||||
/* AEP Keyper */
|
||||
#define PK11_AEP_FLAVOR 4
|
||||
|
||||
/* Default is for Thales nCipher */
|
||||
#ifndef PK11_FLAVOR
|
||||
|
|
@ -87,4 +90,16 @@ PK11_DH_DISABLE
|
|||
#define PK11_SHA512_HMAC_REPLACE
|
||||
#endif
|
||||
|
||||
#if PK11_FLAVOR == PK11_AEP_FLAVOR
|
||||
#define PK11_DH_DISABLE
|
||||
#define PK11_DSA_DISABLE
|
||||
#define PK11_RSA_PKCS_REPLACE
|
||||
#define PK11_MD5_HMAC_REPLACE
|
||||
#define PK11_SHA_1_HMAC_REPLACE
|
||||
#define PK11_SHA224_HMAC_REPLACE
|
||||
#define PK11_SHA256_HMAC_REPLACE
|
||||
#define PK11_SHA384_HMAC_REPLACE
|
||||
#define PK11_SHA512_HMAC_REPLACE
|
||||
#endif
|
||||
|
||||
#endif /* PK11_SITE_H */
|
||||
|
|
|
|||
|
|
@ -631,7 +631,7 @@ scan_slots(void) {
|
|||
if ((rv != CKR_OK) ||
|
||||
((mechInfo.flags & CKF_SIGN) == 0) ||
|
||||
((mechInfo.flags & CKF_VERIFY) == 0)) {
|
||||
#ifndef PK11_MD5_DISABLE
|
||||
#if !defined(PK11_MD5_DISABLE) && !defined(PK11_RSA_PKCS_REPLACE)
|
||||
bad = ISC_TRUE;
|
||||
#endif
|
||||
PK11_TRACEM(CKM_MD5_RSA_PKCS);
|
||||
|
|
@ -641,7 +641,9 @@ scan_slots(void) {
|
|||
if ((rv != CKR_OK) ||
|
||||
((mechInfo.flags & CKF_SIGN) == 0) ||
|
||||
((mechInfo.flags & CKF_VERIFY) == 0)) {
|
||||
#ifndef PK11_RSA_PKCS_REPLACE
|
||||
bad = ISC_TRUE;
|
||||
#endif
|
||||
PK11_TRACEM(CKM_SHA1_RSA_PKCS);
|
||||
}
|
||||
rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA256_RSA_PKCS,
|
||||
|
|
@ -649,7 +651,9 @@ scan_slots(void) {
|
|||
if ((rv != CKR_OK) ||
|
||||
((mechInfo.flags & CKF_SIGN) == 0) ||
|
||||
((mechInfo.flags & CKF_VERIFY) == 0)) {
|
||||
#ifndef PK11_RSA_PKCS_REPLACE
|
||||
bad = ISC_TRUE;
|
||||
#endif
|
||||
PK11_TRACEM(CKM_SHA256_RSA_PKCS);
|
||||
}
|
||||
rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA512_RSA_PKCS,
|
||||
|
|
@ -657,9 +661,20 @@ scan_slots(void) {
|
|||
if ((rv != CKR_OK) ||
|
||||
((mechInfo.flags & CKF_SIGN) == 0) ||
|
||||
((mechInfo.flags & CKF_VERIFY) == 0)) {
|
||||
#ifndef PK11_RSA_PKCS_REPLACE
|
||||
bad = ISC_TRUE;
|
||||
#endif
|
||||
PK11_TRACEM(CKM_SHA512_RSA_PKCS);
|
||||
}
|
||||
rv = pkcs_C_GetMechanismInfo(slot, CKM_RSA_PKCS, &mechInfo);
|
||||
if ((rv != CKR_OK) ||
|
||||
((mechInfo.flags & CKF_SIGN) == 0) ||
|
||||
((mechInfo.flags & CKF_VERIFY) == 0)) {
|
||||
#ifdef PK11_RSA_PKCS_REPLACE
|
||||
bad = ISC_TRUE;
|
||||
#endif
|
||||
PK11_TRACEM(CKM_RSA_PKCS);
|
||||
}
|
||||
if (bad)
|
||||
goto try_dsa;
|
||||
token->operations |= 1 << OP_RSA;
|
||||
|
|
@ -1282,8 +1297,7 @@ pk11_error_fatalcheck(const char *file, int line,
|
|||
}
|
||||
|
||||
void
|
||||
pk11_dump_tokens(void)
|
||||
{
|
||||
pk11_dump_tokens(void) {
|
||||
pk11_token_t *token;
|
||||
isc_boolean_t first;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue