]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] add support for native pkcs11 on keyper
authorEvan Hunt <each@isc.org>
Wed, 4 Jan 2017 00:40:11 +0000 (16:40 -0800)
committerEvan Hunt <each@isc.org>
Wed, 4 Jan 2017 00:42:18 +0000 (16:42 -0800)
4547. [port] Add support for --enable-native-pkcs11 on the AEP
Keyper HSM. [RT #42463]

CHANGES
configure.in
lib/dns/pkcs11dh_link.c
lib/dns/pkcs11dsa_link.c
lib/dns/pkcs11ecdsa_link.c
lib/dns/pkcs11gost_link.c
lib/dns/pkcs11rsa_link.c
lib/isc/include/pk11/README.site
lib/isc/include/pk11/site.h
lib/isc/pk11.c

diff --git a/CHANGES b/CHANGES
index 1f4c40a688e927b791f167a644a5ddbcbffea112..8508a1d662345fb8c3deec7f72171a30222f6cc9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+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
index 097a6f8013a75fa18036ecf2eb3c63e72591081d..68dd9783788c46569aa6dcc2218d42c03794d421 100644 (file)
@@ -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?)
index b9d895f3a638c8802a90c527414e559dde97533a..701a2da091f70b7d7baef4ec5861f8e493d43271 100644 (file)
@@ -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);
 
index 0737328f8bf9a200737b70d02406f9537737c468..9d595fc3886eb65f8ee58156f94d98e38f73a6f5 100644 (file)
@@ -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;
index 473eaf4097568037ed4fcb2d6b1a95094cf84051..e2b5b3c5b151116dfcd11a47c7b29def2ae0b5ce 100644 (file)
@@ -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:
 
index 79853a0b338e8fc85fef9fb2bbd5dc77970856ee..05d148c481dffd3726c68cddc6d94b99668fb829 100644 (file)
@@ -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;
index 9fca8e309fac346be4faf2e9f30402f105ceb1e9..32948d93eb67438745aef9b6cb2d2c7b7d7a23e1 100644 (file)
@@ -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,
index 7e81f642b858934371cfee2cc9c651e033d49e4c..b595b9188319da44261d89d1777385ae4b7903a2 100644 (file)
@@ -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
index b877b0f7f7b4da9dda70b6fba214e2e4b8040ba2..3a4b8c63b6b435ce6e53fd39f38b6fe9aba635af 100644 (file)
@@ -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 */
index 0296da73f3e6923b6e2d5fd234109ad87fa6835c..51db6c77e7808ce8d1b271371447eda82b13811d 100644 (file)
@@ -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;