ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/*
2728d0618e15ee3a2ecc5f6d15acd7898e6de85aTinderbox User * Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#ifdef PKCS11CRYPTO
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <config.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/entropy.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/md5.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/sha1.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/sha2.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/mem.h>
699f790c49d03a9ef3c3234a72d272bb469203e8Evan Hunt#include <isc/safe.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/string.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/util.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <dst/result.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include "dst_internal.h"
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include "dst_parse.h"
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include "dst_pkcs11.h"
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt#include <pk11/internal.h>
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#include <pk11/site.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/*
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * Limit the size of public exponents.
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#ifndef RSA_MAX_PUBEXP_BITS
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define RSA_MAX_PUBEXP_BITS 35
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#endif
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define DST_RET(a) {ret = a; goto err;}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic CK_BBOOL truevalue = TRUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic CK_BBOOL falsevalue = FALSE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic void pkcs11rsa_destroy(dst_key_t *key);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t pkcs11rsa_fetch(dst_key_t *key, const char *engine,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt const char *label, dst_key_t *pub);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#ifndef PK11_RSA_PKCS_REPLACE
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_MECHANISM mech = { 0, NULL, 0 };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_KEY_TYPE keyType = CKK_RSA;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE keyTemplate[] =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_MODULUS, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PUBLIC_EXPONENT, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIVATE_EXPONENT, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIME_1, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIME_2, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_EXPONENT_1, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_EXPONENT_2, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_COEFFICIENT, NULL, 0 }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_SLOT_ID slotid;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *rsa;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t *pk11_ctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int i;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#ifndef PK11_MD5_DISABLE
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(key->key_alg == DST_ALG_RSAMD5 ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->key_alg == DST_ALG_RSASHA1 ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->key_alg == DST_ALG_NSEC3RSASHA1 ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->key_alg == DST_ALG_RSASHA256 ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->key_alg == DST_ALG_RSASHA512);
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#else
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews REQUIRE(key->key_alg == DST_ALG_RSASHA1 ||
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews key->key_alg == DST_ALG_NSEC3RSASHA1 ||
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews key->key_alg == DST_ALG_RSASHA256 ||
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews key->key_alg == DST_ALG_RSASHA512);
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#endif
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /*
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman * Reject incorrect RSA key lengths.
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman switch (dctx->key->key_alg) {
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSAMD5:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA1:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_NSEC3RSASHA1:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 3110 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if (dctx->key->key_size > 4096)
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA256:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 5702 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if ((dctx->key->key_size < 512) ||
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman (dctx->key->key_size > 4096))
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA512:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 5702 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if ((dctx->key->key_size < 1024) ||
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman (dctx->key->key_size > 4096))
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman default:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman INSIST(0);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman }
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pk11_ctx == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(pk11_ctx, 0, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa->ontoken)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt slotid = rsa->slot;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt slotid = pk11_get_best_token(OP_RSA);
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->reqlogon, NULL, slotid);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto err;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa->ontoken && (rsa->object != CK_INVALID_HANDLE)) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_ctx->ontoken = rsa->ontoken;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_ctx->object = rsa->object;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto token_key;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (attr = pk11_attribute_first(rsa);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr != NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_next(rsa, attr))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (attr->type) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_MODULUS:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(keyTemplate[6].type == attr->type);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[6].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(keyTemplate[6].pValue, attr->pValue,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[6].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PUBLIC_EXPONENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(keyTemplate[7].type == attr->type);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[7].pValue = isc_mem_get(dctx->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[7].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(keyTemplate[7].pValue, attr->pValue,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[7].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PRIVATE_EXPONENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(keyTemplate[8].type == attr->type);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[8].pValue = isc_mem_get(dctx->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[8].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(keyTemplate[8].pValue, attr->pValue,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[8].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PRIME_1:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(keyTemplate[9].type == attr->type);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[9].pValue = isc_mem_get(dctx->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[9].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(keyTemplate[9].pValue, attr->pValue,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[9].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PRIME_2:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(keyTemplate[10].type == attr->type);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[10].pValue = isc_mem_get(dctx->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[10].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(keyTemplate[10].pValue, attr->pValue,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[10].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_EXPONENT_1:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(keyTemplate[11].type == attr->type);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[11].pValue = isc_mem_get(dctx->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[11].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(keyTemplate[11].pValue, attr->pValue,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[11].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_EXPONENT_2:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(keyTemplate[12].type == attr->type);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[12].pValue = isc_mem_get(dctx->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[12].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(keyTemplate[12].pValue, attr->pValue,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[12].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_COEFFICIENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(keyTemplate[13].type == attr->type);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[13].pValue = isc_mem_get(dctx->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[13].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(keyTemplate[13].pValue, attr->pValue,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[13].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_ctx->object = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_ctx->ontoken = ISC_FALSE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_CreateObject,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate, (CK_ULONG) 14,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt &pk11_ctx->object),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ISC_R_FAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt token_key:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (dctx->key->key_alg) {
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#ifndef PK11_MD5_DISABLE
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case DST_ALG_RSAMD5:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt mech.mechanism = CKM_MD5_RSA_PKCS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#endif
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case DST_ALG_RSASHA1:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case DST_ALG_NSEC3RSASHA1:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt mech.mechanism = CKM_SHA1_RSA_PKCS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case DST_ALG_RSASHA256:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt mech.mechanism = CKM_SHA256_RSA_PKCS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case DST_ALG_RSASHA512:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt mech.mechanism = CKM_SHA512_RSA_PKCS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt default:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(0);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_SignInit,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, &mech, pk11_ctx->object),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ISC_R_FAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dctx->ctxdata.pk11_ctx = pk11_ctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 6; i <= 13; i++)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[i].pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(keyTemplate[i].pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman keyTemplate[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(dctx->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[i].pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt err:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_ctx->object);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 6; i <= 13; i++)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[i].pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(keyTemplate[i].pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman keyTemplate[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(dctx->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[i].pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dst_context_t *dctx) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_MECHANISM mech = { 0, NULL, 0 };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_KEY_TYPE keyType = CKK_RSA;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE keyTemplate[] =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_MODULUS, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PUBLIC_EXPONENT, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *rsa;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t *pk11_ctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int i;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#ifndef PK11_MD5_DISABLE
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(key->key_alg == DST_ALG_RSAMD5 ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->key_alg == DST_ALG_RSASHA1 ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->key_alg == DST_ALG_NSEC3RSASHA1 ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->key_alg == DST_ALG_RSASHA256 ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->key_alg == DST_ALG_RSASHA512);
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#else
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews REQUIRE(key->key_alg == DST_ALG_RSASHA1 ||
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews key->key_alg == DST_ALG_NSEC3RSASHA1 ||
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews key->key_alg == DST_ALG_RSASHA256 ||
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews key->key_alg == DST_ALG_RSASHA512);
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#endif
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /*
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman * Reject incorrect RSA key lengths.
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman switch (dctx->key->key_alg) {
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSAMD5:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA1:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_NSEC3RSASHA1:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 3110 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if (dctx->key->key_size > 4096)
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA256:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 5702 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if ((dctx->key->key_size < 512) ||
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman (dctx->key->key_size > 4096))
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA512:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 5702 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if ((dctx->key->key_size < 1024) ||
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman (dctx->key->key_size > 4096))
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman default:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman INSIST(0);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman }
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pk11_ctx == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOMEMORY);
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->reqlogon, NULL,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_get_best_token(OP_RSA));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto err;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (attr = pk11_attribute_first(rsa);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr != NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_next(rsa, attr))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (attr->type) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_MODULUS:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(keyTemplate[5].type == attr->type);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[5].pValue = isc_mem_get(dctx->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[5].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(keyTemplate[5].pValue, attr->pValue,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[5].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PUBLIC_EXPONENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(keyTemplate[6].type == attr->type);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[6].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(keyTemplate[6].pValue, attr->pValue,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[6].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pk11_numbits(attr->pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen) > maxbits &&
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt maxbits != 0)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(DST_R_VERIFYFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_ctx->object = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_ctx->ontoken = ISC_FALSE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_CreateObject,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate, (CK_ULONG) 7,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt &pk11_ctx->object),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ISC_R_FAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (dctx->key->key_alg) {
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#ifndef PK11_MD5_DISABLE
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case DST_ALG_RSAMD5:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt mech.mechanism = CKM_MD5_RSA_PKCS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#endif
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case DST_ALG_RSASHA1:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case DST_ALG_NSEC3RSASHA1:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt mech.mechanism = CKM_SHA1_RSA_PKCS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case DST_ALG_RSASHA256:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt mech.mechanism = CKM_SHA256_RSA_PKCS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case DST_ALG_RSASHA512:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt mech.mechanism = CKM_SHA512_RSA_PKCS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt default:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(0);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_VerifyInit,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, &mech, pk11_ctx->object),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ISC_R_FAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dctx->ctxdata.pk11_ctx = pk11_ctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 5; i <= 6; i++)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[i].pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(keyTemplate[i].pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman keyTemplate[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(dctx->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[i].pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt err:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_ctx->object);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 5; i <= 6; i++)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[i].pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(keyTemplate[i].pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman keyTemplate[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(dctx->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[i].pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_createctx(dst_key_t *key, dst_context_t *dctx) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dctx->use == DO_SIGN)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (pkcs11rsa_createctx_sign(key, dctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (pkcs11rsa_createctx_verify(key, 0U, dctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_createctx2(dst_key_t *key, int maxbits, dst_context_t *dctx) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dctx->use == DO_SIGN)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (pkcs11rsa_createctx_sign(key, dctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (pkcs11rsa_createctx_verify(key,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (unsigned) maxbits, dctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic void
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_destroyctx(dst_context_t *dctx) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pk11_ctx != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (!pk11_ctx->ontoken &&
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->object != CK_INVALID_HANDLE))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session,
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_ctx->object);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dctx->ctxdata.pk11_ctx = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret = ISC_R_SUCCESS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dctx->use == DO_SIGN)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_CALL(pkcs_C_SignUpdate,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (CK_BYTE_PTR) data->base,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (CK_ULONG) data->length),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ISC_R_FAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_CALL(pkcs_C_VerifyUpdate,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (CK_BYTE_PTR) data->base,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (CK_ULONG) data->length),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ISC_R_FAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ULONG siglen = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_region_t r;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret = ISC_R_SUCCESS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_SignFinal,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, NULL, &siglen),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_SIGNFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_availableregion(sig, &r);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (r.length < (unsigned int) siglen)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOSPACE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_SignFinal,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, (CK_BYTE_PTR) r.base, &siglen),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_SIGNFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_add(sig, (unsigned int) siglen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt err:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret = ISC_R_SUCCESS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_CALL(pkcs_C_VerifyFinal,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (CK_BYTE_PTR) sig->base,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (CK_ULONG) sig->length),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_VERIFYFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#else
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt/*
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt * CKM_<hash>_RSA_PKCS mechanisms are not available so fall back
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt * to CKM_RSA_PKCS and do the EMSA-PKCS#1-v1.5 encapsulation by hand.
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt */
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan HuntCK_BYTE md5_der[] =
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt 0x04, 0x10 };
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan HuntCK_BYTE sha1_der[] =
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan HuntCK_BYTE sha256_der[] =
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt 0x00, 0x04, 0x20 };
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan HuntCK_BYTE sha512_der[] =
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt 0x00, 0x04, 0x40 };
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#define MAX_DER_SIZE 19
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#define MIN_PKCS1_PADLEN 11
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Huntstatic isc_result_t
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Huntpkcs11rsa_createctx(dst_key_t *key, dst_context_t *dctx) {
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_RV rv;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_MECHANISM mech = { 0, NULL, 0 };
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_SLOT_ID slotid;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_object_t *rsa = key->keydata.pkey;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_context_t *pk11_ctx;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt isc_result_t ret;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#ifndef PK11_MD5_DISABLE
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt REQUIRE(key->key_alg == DST_ALG_RSAMD5 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA1 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_NSEC3RSASHA1 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA256 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA512);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#else
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt REQUIRE(key->key_alg == DST_ALG_RSASHA1 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_NSEC3RSASHA1 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA256 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA512);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#endif
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt REQUIRE(rsa != NULL);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /*
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman * Reject incorrect RSA key lengths.
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman switch (dctx->key->key_alg) {
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSAMD5:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA1:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_NSEC3RSASHA1:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 3110 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if (dctx->key->key_size > 4096)
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA256:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 5702 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if ((dctx->key->key_size < 512) ||
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman (dctx->key->key_size > 4096))
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA512:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 5702 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if ((dctx->key->key_size < 1024) ||
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman (dctx->key->key_size > 4096))
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman default:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman INSIST(0);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman }
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt switch (key->key_alg) {
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#ifndef PK11_MD5_DISABLE
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_RSAMD5:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt mech.mechanism = CKM_MD5;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#endif
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_RSASHA1:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_NSEC3RSASHA1:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt mech.mechanism = CKM_SHA_1;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_RSASHA256:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt mech.mechanism = CKM_SHA256;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_RSASHA512:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt mech.mechanism = CKM_SHA512;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt default:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(0);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt }
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt sizeof(*pk11_ctx));
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (pk11_ctx == NULL)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt return (ISC_R_NOMEMORY);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt memset(pk11_ctx, 0, sizeof(*pk11_ctx));
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (rsa->ontoken)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt slotid = rsa->slot;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt else
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt slotid = pk11_get_best_token(OP_RSA);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt rsa->reqlogon, NULL, slotid);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (ret != ISC_R_SUCCESS)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt goto err;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt PK11_RET(pkcs_C_DigestInit, (pk11_ctx->session, &mech), ISC_R_FAILURE);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt dctx->ctxdata.pk11_ctx = pk11_ctx;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt return (ISC_R_SUCCESS);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt err:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt return (ret);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt}
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Huntstatic void
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Huntpkcs11rsa_destroyctx(dst_context_t *dctx) {
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_BYTE garbage[ISC_SHA512_DIGESTLENGTH];
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_ULONG len = ISC_SHA512_DIGESTLENGTH;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (pk11_ctx != NULL) {
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (void) pkcs_C_DigestFinal(pk11_ctx->session, garbage, &len);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(garbage, sizeof(garbage));
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt dctx->ctxdata.pk11_ctx = NULL;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt }
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt}
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Huntstatic isc_result_t
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Huntpkcs11rsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_RV rv;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt isc_result_t ret = ISC_R_SUCCESS;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt PK11_CALL(pkcs_C_DigestUpdate,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (pk11_ctx->session,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (CK_BYTE_PTR) data->base,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (CK_ULONG) data->length),
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt ISC_R_FAILURE);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt return (ret);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt}
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Huntstatic isc_result_t
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Huntpkcs11rsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_RV rv;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_MECHANISM mech = { CKM_RSA_PKCS, NULL, 0 };
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_KEY_TYPE keyType = CKK_RSA;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_ATTRIBUTE keyTemplate[] =
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt {
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_MODULUS, NULL, 0 },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_PUBLIC_EXPONENT, NULL, 0 },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_PRIVATE_EXPONENT, NULL, 0 },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_PRIME_1, NULL, 0 },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_PRIME_2, NULL, 0 },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_EXPONENT_1, NULL, 0 },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_EXPONENT_2, NULL, 0 },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_COEFFICIENT, NULL, 0 }
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt };
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_ATTRIBUTE *attr;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_BYTE digest[MAX_DER_SIZE + ISC_SHA512_DIGESTLENGTH];
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_BYTE *der;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_ULONG derlen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_ULONG hashlen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_ULONG dgstlen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_ULONG siglen = 0;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt dst_key_t *key = dctx->key;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_object_t *rsa = key->keydata.pkey;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt isc_region_t r;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt isc_result_t ret = ISC_R_SUCCESS;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt unsigned int i;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#ifndef PK11_MD5_DISABLE
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt REQUIRE(key->key_alg == DST_ALG_RSAMD5 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA1 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_NSEC3RSASHA1 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA256 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA512);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#else
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt REQUIRE(key->key_alg == DST_ALG_RSASHA1 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_NSEC3RSASHA1 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA256 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA512);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#endif
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt REQUIRE(rsa != NULL);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /*
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman * Reject incorrect RSA key lengths.
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman switch (dctx->key->key_alg) {
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSAMD5:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA1:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_NSEC3RSASHA1:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 3110 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if (dctx->key->key_size > 4096)
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA256:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 5702 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if ((dctx->key->key_size < 512) ||
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman (dctx->key->key_size > 4096))
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA512:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 5702 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if ((dctx->key->key_size < 1024) ||
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman (dctx->key->key_size > 4096))
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman default:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman INSIST(0);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman }
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt switch (key->key_alg) {
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#ifndef PK11_MD5_DISABLE
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_RSAMD5:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt der = md5_der;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt derlen = sizeof(md5_der);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt hashlen = ISC_MD5_DIGESTLENGTH;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#endif
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_RSASHA1:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_NSEC3RSASHA1:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt der = sha1_der;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt derlen = sizeof(sha1_der);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt hashlen = ISC_SHA1_DIGESTLENGTH;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_RSASHA256:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt der = sha256_der;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt derlen = sizeof(sha256_der);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt hashlen = ISC_SHA256_DIGESTLENGTH;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_RSASHA512:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt der = sha512_der;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt derlen = sizeof(sha512_der);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt hashlen = ISC_SHA512_DIGESTLENGTH;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt default:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(0);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt }
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt dgstlen = derlen + hashlen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(dgstlen <= sizeof(digest));
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt memmove(digest, der, derlen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt PK11_RET(pkcs_C_DigestFinal,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (pk11_ctx->session, digest + derlen, &hashlen),
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_R_SIGNFAILURE);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt isc_buffer_availableregion(sig, &r);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (r.length < (unsigned int) dgstlen + MIN_PKCS1_PADLEN)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt return (ISC_R_NOSPACE);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (rsa->ontoken && (rsa->object != CK_INVALID_HANDLE)) {
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_ctx->ontoken = rsa->ontoken;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_ctx->object = rsa->object;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt goto token_key;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt }
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt for (attr = pk11_attribute_first(rsa);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr != NULL;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr = pk11_attribute_next(rsa, attr))
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt switch (attr->type) {
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case CKA_MODULUS:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(keyTemplate[6].type == attr->type);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (keyTemplate[6].pValue == NULL)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_RET(ISC_R_NOMEMORY);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt memmove(keyTemplate[6].pValue, attr->pValue,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[6].ulValueLen = attr->ulValueLen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case CKA_PUBLIC_EXPONENT:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(keyTemplate[7].type == attr->type);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[7].pValue = isc_mem_get(dctx->mctx,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (keyTemplate[7].pValue == NULL)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_RET(ISC_R_NOMEMORY);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt memmove(keyTemplate[7].pValue, attr->pValue,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[7].ulValueLen = attr->ulValueLen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case CKA_PRIVATE_EXPONENT:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(keyTemplate[8].type == attr->type);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[8].pValue = isc_mem_get(dctx->mctx,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (keyTemplate[8].pValue == NULL)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_RET(ISC_R_NOMEMORY);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt memmove(keyTemplate[8].pValue, attr->pValue,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[8].ulValueLen = attr->ulValueLen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case CKA_PRIME_1:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(keyTemplate[9].type == attr->type);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[9].pValue = isc_mem_get(dctx->mctx,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (keyTemplate[9].pValue == NULL)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_RET(ISC_R_NOMEMORY);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt memmove(keyTemplate[9].pValue, attr->pValue,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[9].ulValueLen = attr->ulValueLen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case CKA_PRIME_2:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(keyTemplate[10].type == attr->type);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[10].pValue = isc_mem_get(dctx->mctx,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (keyTemplate[10].pValue == NULL)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_RET(ISC_R_NOMEMORY);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt memmove(keyTemplate[10].pValue, attr->pValue,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[10].ulValueLen = attr->ulValueLen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case CKA_EXPONENT_1:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(keyTemplate[11].type == attr->type);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[11].pValue = isc_mem_get(dctx->mctx,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (keyTemplate[11].pValue == NULL)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_RET(ISC_R_NOMEMORY);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt memmove(keyTemplate[11].pValue, attr->pValue,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[11].ulValueLen = attr->ulValueLen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case CKA_EXPONENT_2:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(keyTemplate[12].type == attr->type);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[12].pValue = isc_mem_get(dctx->mctx,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (keyTemplate[12].pValue == NULL)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_RET(ISC_R_NOMEMORY);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt memmove(keyTemplate[12].pValue, attr->pValue,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[12].ulValueLen = attr->ulValueLen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case CKA_COEFFICIENT:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(keyTemplate[13].type == attr->type);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[13].pValue = isc_mem_get(dctx->mctx,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (keyTemplate[13].pValue == NULL)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_RET(ISC_R_NOMEMORY);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt memmove(keyTemplate[13].pValue, attr->pValue,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[13].ulValueLen = attr->ulValueLen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt }
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_ctx->object = CK_INVALID_HANDLE;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_ctx->ontoken = ISC_FALSE;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt PK11_RET(pkcs_C_CreateObject,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (pk11_ctx->session,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate, (CK_ULONG) 14,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt &hKey),
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt ISC_R_FAILURE);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt token_key:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt PK11_RET(pkcs_C_SignInit,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (pk11_ctx->session, &mech,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_ctx->ontoken ? pk11_ctx->object : hKey),
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt ISC_R_FAILURE);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt PK11_RET(pkcs_C_Sign,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (pk11_ctx->session,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt digest, dgstlen,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt NULL, &siglen),
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_R_SIGNFAILURE);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (r.length < (unsigned int) siglen)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt return (ISC_R_NOSPACE);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt PK11_RET(pkcs_C_Sign,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (pk11_ctx->session,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt digest, dgstlen,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (CK_BYTE_PTR) r.base, &siglen),
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_R_SIGNFAILURE);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt isc_buffer_add(sig, (unsigned int) siglen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt err:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (hKey != CK_INVALID_HANDLE)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt for (i = 6; i <= 13; i++)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (keyTemplate[i].pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(keyTemplate[i].pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman keyTemplate[i].ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt isc_mem_put(dctx->mctx,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[i].pValue,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[i].ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt }
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt dctx->ctxdata.pk11_ctx = NULL;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt return (ret);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt}
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Huntstatic isc_result_t
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Huntpkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_RV rv;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_MECHANISM mech = { CKM_RSA_PKCS, NULL, 0 };
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_KEY_TYPE keyType = CKK_RSA;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_ATTRIBUTE keyTemplate[] =
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt {
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_MODULUS, NULL, 0 },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt { CKA_PUBLIC_EXPONENT, NULL, 0 },
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt };
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_ATTRIBUTE *attr;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_BYTE digest[MAX_DER_SIZE + ISC_SHA512_DIGESTLENGTH];
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_BYTE *der;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_ULONG derlen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_ULONG hashlen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt CK_ULONG dgstlen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt dst_key_t *key = dctx->key;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_object_t *rsa = key->keydata.pkey;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt isc_result_t ret = ISC_R_SUCCESS;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt unsigned int i;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#ifndef PK11_MD5_DISABLE
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt REQUIRE(key->key_alg == DST_ALG_RSAMD5 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA1 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_NSEC3RSASHA1 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA256 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA512);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#else
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt REQUIRE(key->key_alg == DST_ALG_RSASHA1 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_NSEC3RSASHA1 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA256 ||
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt key->key_alg == DST_ALG_RSASHA512);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#endif
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt REQUIRE(rsa != NULL);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt switch (key->key_alg) {
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#ifndef PK11_MD5_DISABLE
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_RSAMD5:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt der = md5_der;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt derlen = sizeof(md5_der);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt hashlen = ISC_MD5_DIGESTLENGTH;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#endif
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_RSASHA1:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_NSEC3RSASHA1:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt der = sha1_der;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt derlen = sizeof(sha1_der);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt hashlen = ISC_SHA1_DIGESTLENGTH;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_RSASHA256:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt der = sha256_der;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt derlen = sizeof(sha256_der);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt hashlen = ISC_SHA256_DIGESTLENGTH;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case DST_ALG_RSASHA512:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt der = sha512_der;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt derlen = sizeof(sha512_der);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt hashlen = ISC_SHA512_DIGESTLENGTH;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt default:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(0);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt }
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt dgstlen = derlen + hashlen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(dgstlen <= sizeof(digest));
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt memmove(digest, der, derlen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt PK11_RET(pkcs_C_DigestFinal,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (pk11_ctx->session, digest + derlen, &hashlen),
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_R_SIGNFAILURE);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt for (attr = pk11_attribute_first(rsa);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr != NULL;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr = pk11_attribute_next(rsa, attr))
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt switch (attr->type) {
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case CKA_MODULUS:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(keyTemplate[5].type == attr->type);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[5].pValue = isc_mem_get(dctx->mctx,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (keyTemplate[5].pValue == NULL)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_RET(ISC_R_NOMEMORY);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt memmove(keyTemplate[5].pValue, attr->pValue,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[5].ulValueLen = attr->ulValueLen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt case CKA_PUBLIC_EXPONENT:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt INSIST(keyTemplate[6].type == attr->type);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (keyTemplate[6].pValue == NULL)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_RET(ISC_R_NOMEMORY);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt memmove(keyTemplate[6].pValue, attr->pValue,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[6].ulValueLen = attr->ulValueLen;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (pk11_numbits(attr->pValue,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt attr->ulValueLen)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt > RSA_MAX_PUBEXP_BITS)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_RET(DST_R_VERIFYFAILURE);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt break;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt }
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_ctx->object = CK_INVALID_HANDLE;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_ctx->ontoken = ISC_FALSE;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt PK11_RET(pkcs_C_CreateObject,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (pk11_ctx->session,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate, (CK_ULONG) 7,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt &hKey),
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt ISC_R_FAILURE);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt PK11_RET(pkcs_C_VerifyInit,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (pk11_ctx->session, &mech, hKey),
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt ISC_R_FAILURE);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt PK11_RET(pkcs_C_Verify,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (pk11_ctx->session,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt digest, dgstlen,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (CK_BYTE_PTR) sig->base, (CK_ULONG) sig->length),
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt DST_R_VERIFYFAILURE);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt err:
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (hKey != CK_INVALID_HANDLE)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt for (i = 5; i <= 6; i++)
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt if (keyTemplate[i].pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(keyTemplate[i].pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman keyTemplate[i].ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt isc_mem_put(dctx->mctx,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[i].pValue,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt keyTemplate[i].ulValueLen);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt }
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt dctx->ctxdata.pk11_ctx = NULL;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt return (ret);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt}
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#endif
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_boolean_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *rsa1, *rsa2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr1, *attr2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa1 = key1->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa2 = key2->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((rsa1 == NULL) && (rsa2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else if ((rsa1 == NULL) || (rsa2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr1 = pk11_attribute_bytype(rsa1, CKA_MODULUS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr2 = pk11_attribute_bytype(rsa2, CKA_MODULUS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((attr1 == NULL) && (attr2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else if ((attr1 == NULL) || (attr2 == NULL) ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (attr1->ulValueLen != attr2->ulValueLen) ||
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt !isc_safe_memequal(attr1->pValue, attr2->pValue,
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt attr1->ulValueLen))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr1 = pk11_attribute_bytype(rsa1, CKA_PUBLIC_EXPONENT);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr2 = pk11_attribute_bytype(rsa2, CKA_PUBLIC_EXPONENT);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((attr1 == NULL) && (attr2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else if ((attr1 == NULL) || (attr2 == NULL) ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (attr1->ulValueLen != attr2->ulValueLen) ||
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt !isc_safe_memequal(attr1->pValue, attr2->pValue,
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt attr1->ulValueLen))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr1 = pk11_attribute_bytype(rsa1, CKA_PRIVATE_EXPONENT);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr2 = pk11_attribute_bytype(rsa2, CKA_PRIVATE_EXPONENT);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (((attr1 != NULL) || (attr2 != NULL)) &&
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ((attr1 == NULL) || (attr2 == NULL) ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (attr1->ulValueLen != attr2->ulValueLen) ||
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt !isc_safe_memequal(attr1->pValue, attr2->pValue,
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt attr1->ulValueLen)))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (!rsa1->ontoken && !rsa2->ontoken)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else if (rsa1->ontoken || rsa2->ontoken ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (rsa1->object != rsa2->object))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_generate(dst_key_t *key, int exp, void (*callback)(int)) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0 };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ULONG bits = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_BYTE pubexp[5];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_KEY_TYPE keyType = CKK_RSA;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE pubTemplate[] =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_MODULUS_BITS, &bits, (CK_ULONG) sizeof(bits) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PUBLIC_EXPONENT, &pubexp, (CK_ULONG) sizeof(pubexp) }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE privTemplate[] =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *rsa;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t *pk11_ctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int i;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt UNUSED(callback);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /*
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman * Reject incorrect RSA key lengths.
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman switch (key->key_alg) {
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSAMD5:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA1:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_NSEC3RSASHA1:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 3110 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if (key->key_size > 4096)
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA256:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 5702 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if ((key->key_size < 512) ||
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman (key->key_size > 4096))
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman case DST_ALG_RSASHA512:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman /* From RFC 5702 */
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman if ((key->key_size < 1024) ||
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman (key->key_size > 4096))
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman return (ISC_R_FAILURE);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman break;
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman default:
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman INSIST(0);
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman }
264e17e73941059877ccf3c96f26aac15a25500bMukund Sivaraman
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx,
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pk11_ctx == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOMEMORY);
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt ISC_FALSE, NULL, pk11_get_best_token(OP_RSA));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto err;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt bits = key->key_size;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (exp == 0) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt /* RSA_F4 0x10001 */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubexp[0] = 1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubexp[1] = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubexp[2] = 1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[6].ulValueLen = 3;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt } else {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt /* F5 0x100000001 */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubexp[0] = 1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubexp[1] = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubexp[2] = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubexp[3] = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubexp[4] = 1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[6].ulValueLen = 5;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GenerateKeyPair,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, &mech,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate, (CK_ULONG) 7,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt privTemplate, (CK_ULONG) 7,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt &pub, &priv),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(rsa, 0, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->keydata.pkey = rsa;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa->repr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(rsa->repr, 0, sizeof(*attr) * 8);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->attrcnt = 8;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = rsa->repr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[0].type = CKA_MODULUS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[1].type = CKA_PUBLIC_EXPONENT;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[2].type = CKA_PRIVATE_EXPONENT;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[3].type = CKA_PRIME_1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[4].type = CKA_PRIME_2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[5].type = CKA_EXPONENT_1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[6].type = CKA_EXPONENT_2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[7].type = CKA_COEFFICIENT;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, pub, attr, 2),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 0; i <= 1; i++) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr[i].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(attr[i].pValue, 0, attr[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, pub, attr, 2),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr += 2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, priv, attr, 6),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 0; i <= 5; i++) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr[i].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(attr[i].pValue, 0, attr[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, priv, attr, 6),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt err:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_destroy(key);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (priv != CK_INVALID_HANDLE)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pub != CK_INVALID_HANDLE)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_boolean_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_isprivate(const dst_key_t *key) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *rsa = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa, CKA_PRIVATE_EXPONENT);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TF((attr != NULL) || rsa->ontoken));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic void
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_destroy(dst_key_t *key) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *rsa = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST((rsa->object == CK_INVALID_HANDLE) || rsa->ontoken);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (attr = pk11_attribute_first(rsa);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr != NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_next(rsa, attr))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (attr->type) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_LABEL:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_ID:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_MODULUS:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PUBLIC_EXPONENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PRIVATE_EXPONENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PRIME_1:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PRIME_2:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_EXPONENT_1:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_EXPONENT_2:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_COEFFICIENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr->pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(attr->pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa->repr != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(rsa->repr, rsa->attrcnt * sizeof(*attr));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->repr,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->attrcnt * sizeof(*attr));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(rsa, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, rsa, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->keydata.pkey = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *rsa;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_region_t r;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int e_bytes = 0, mod_bytes = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_BYTE *exponent = NULL, *modulus = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(key->keydata.pkey != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (attr = pk11_attribute_first(rsa);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr != NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_next(rsa, attr))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (attr->type) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PUBLIC_EXPONENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt exponent = (CK_BYTE *) attr->pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt e_bytes = (unsigned int) attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_MODULUS:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt modulus = (CK_BYTE *) attr->pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt mod_bytes = (unsigned int) attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE((exponent != NULL) && (modulus != NULL));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_availableregion(data, &r);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (e_bytes < 256) { /*%< key exponent is <= 2040 bits */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (r.length < 1)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOSPACE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_putuint8(data, (isc_uint8_t) e_bytes);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_region_consume(&r, 1);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt } else {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (r.length < 3)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOSPACE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_putuint8(data, 0);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_putuint16(data, (isc_uint16_t) e_bytes);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_region_consume(&r, 3);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (r.length < e_bytes + mod_bytes)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOSPACE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(r.base, exponent, e_bytes);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_region_consume(&r, e_bytes);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(r.base, modulus, mod_bytes);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_add(data, e_bytes + mod_bytes);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *rsa;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_region_t r;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int e_bytes, mod_bytes;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_BYTE *exponent = NULL, *modulus = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt unsigned int length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_remainingregion(data, &r);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (r.length == 0)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt length = r.length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOMEMORY);
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(rsa, 0, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt e_bytes = *r.base;
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_region_consume(&r, 1);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (e_bytes == 0) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (r.length < 2) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(rsa, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, rsa, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_INVALIDPUBLICKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt e_bytes = (*r.base) << 8;
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_region_consume(&r, 1);
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt e_bytes += *r.base;
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_region_consume(&r, 1);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (r.length < e_bytes) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(rsa, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, rsa, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_INVALIDPUBLICKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt exponent = r.base;
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_region_consume(&r, e_bytes);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt modulus = r.base;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt mod_bytes = r.length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->key_size = pk11_numbits(modulus, mod_bytes);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_buffer_forward(data, length);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa->repr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto nomemory;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(rsa->repr, 0, sizeof(*attr) * 2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->attrcnt = 2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = rsa->repr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[0].type = CKA_MODULUS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[0].pValue = isc_mem_get(key->mctx, mod_bytes);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr[0].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto nomemory;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(attr[0].pValue, modulus, mod_bytes);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[0].ulValueLen = (CK_ULONG) mod_bytes;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[1].type = CKA_PUBLIC_EXPONENT;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[1].pValue = isc_mem_get(key->mctx, e_bytes);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr[1].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto nomemory;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(attr[1].pValue, exponent, e_bytes);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[1].ulValueLen = (CK_ULONG) e_bytes;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->keydata.pkey = rsa;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt nomemory:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (attr = pk11_attribute_first(rsa);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr != NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_next(rsa, attr))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (attr->type) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_MODULUS:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PUBLIC_EXPONENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr->pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(attr->pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa->repr != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(rsa->repr,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman rsa->attrcnt * sizeof(*attr));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->repr,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->attrcnt * sizeof(*attr));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(rsa, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, rsa, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_tofile(const dst_key_t *key, const char *directory) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt int i;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *rsa;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *modulus = NULL, *exponent = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *d = NULL, *p = NULL, *q = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dst_private_t priv;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt unsigned char *bufs[10];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t result;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (key->keydata.pkey == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_NULLKEY);
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt if (key->external) {
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt priv.nelements = 0;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt return (dst__privstruct_writefile(key, &priv, directory));
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt }
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (attr = pk11_attribute_first(rsa);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr != NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_next(rsa, attr))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (attr->type) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_MODULUS:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt modulus = attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PUBLIC_EXPONENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt exponent = attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PRIVATE_EXPONENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt d = attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PRIME_1:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt p = attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PRIME_2:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt q = attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_EXPONENT_1:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dmp1 = attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_EXPONENT_2:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dmq1 = attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_COEFFICIENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt iqmp = attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((modulus == NULL) || (exponent == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_NULLKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(bufs, 0, sizeof(bufs));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt for (i = 0; i < 10; i++) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt bufs[i] = isc_mem_get(key->mctx, modulus->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (bufs[i] == NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt result = ISC_R_NOMEMORY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto fail;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(bufs[i], 0, modulus->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_RSA_MODULUS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].length = (unsigned short) modulus->ulValueLen;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(bufs[i], modulus->pValue, modulus->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = bufs[i];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].length = (unsigned short) exponent->ulValueLen;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(bufs[i], exponent->pValue, exponent->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = bufs[i];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (d != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].length = (unsigned short) d->ulValueLen;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(bufs[i], d->pValue, d->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = bufs[i];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (p != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_RSA_PRIME1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].length = (unsigned short) p->ulValueLen;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(bufs[i], p->pValue, p->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = bufs[i];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (q != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_RSA_PRIME2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].length = (unsigned short) q->ulValueLen;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(bufs[i], q->pValue, q->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = bufs[i];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dmp1 != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_RSA_EXPONENT1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].length = (unsigned short) dmp1->ulValueLen;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(bufs[i], dmp1->pValue, dmp1->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = bufs[i];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dmq1 != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_RSA_EXPONENT2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].length = (unsigned short) dmq1->ulValueLen;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(bufs[i], dmq1->pValue, dmq1->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = bufs[i];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (iqmp != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_RSA_COEFFICIENT;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].length = (unsigned short) iqmp->ulValueLen;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(bufs[i], iqmp->pValue, iqmp->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = bufs[i];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (key->engine != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_RSA_ENGINE;
bcb68be0a8f3c3eca58d6a6a869267e5c1841de2Francis Dupont priv.elements[i].length =
bcb68be0a8f3c3eca58d6a6a869267e5c1841de2Francis Dupont (unsigned short)strlen(key->engine) + 1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = (unsigned char *)key->engine;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (key->label != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_RSA_LABEL;
bcb68be0a8f3c3eca58d6a6a869267e5c1841de2Francis Dupont priv.elements[i].length =
bcb68be0a8f3c3eca58d6a6a869267e5c1841de2Francis Dupont (unsigned short)strlen(key->label) + 1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = (unsigned char *)key->label;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.nelements = i;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt result = dst__privstruct_writefile(key, &priv, directory);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt fail:
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt for (i = 0; i < 10; i++) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (bufs[i] == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(bufs[i], modulus->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, bufs[i], modulus->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (result);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dst_key_t *pub)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt{
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_KEY_TYPE keyType = CKK_RSA;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE searchTemplate[] =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_LABEL, NULL, 0 }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ULONG cnt;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *pubattr;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *rsa;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *pubrsa;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t *pk11_ctx = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (label == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_NOENGINE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubrsa = pub->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->object = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->ontoken = ISC_TRUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->reqlogon = ISC_TRUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa->repr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(rsa->repr, 0, sizeof(*attr) * 2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->attrcnt = 2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = rsa->repr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->type = CKA_MODULUS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr->pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = pubattr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->type = CKA_PUBLIC_EXPONENT;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr->pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = pubattr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto err;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx,
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pk11_ctx == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->reqlogon, NULL, rsa->slot);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto err;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa, CKA_LABEL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr == NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa, CKA_ID);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt searchTemplate[3].type = CKA_ID;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt searchTemplate[3].pValue = attr->pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt searchTemplate[3].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_FindObjectsInit,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, searchTemplate, (CK_ULONG) 4),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_FindObjects,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_FindObjectsFinal(pk11_ctx->session);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (cnt == 0)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOTFOUND);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (cnt > 1)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_EXISTS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (engine != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->engine = isc_mem_strdup(key->mctx, engine);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (key->engine == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->label = isc_mem_strdup(key->mctx, label);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (key->label == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt err:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pk11_ctx != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Huntrsa_check(pk11_object_t *rsa, pk11_object_t *pubrsa) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *pubattr, *privattr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_BYTE *priv_exp = NULL, *priv_mod = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_BYTE *pub_exp = NULL, *pub_mod = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int priv_explen = 0, priv_modlen = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int pub_explen = 0, pub_modlen = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(rsa != NULL && pubrsa != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt privattr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(privattr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv_exp = privattr->pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv_explen = privattr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(pubattr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pub_exp = pubattr->pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pub_explen = pubattr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (priv_exp != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (priv_explen != pub_explen)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_INVALIDPRIVATEKEY);
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt if (!isc_safe_memequal(priv_exp, pub_exp, pub_explen))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_INVALIDPRIVATEKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt } else {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt privattr->pValue = pub_exp;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt privattr->ulValueLen = pub_explen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubattr->pValue = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubattr->ulValueLen = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (privattr->pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_INVALIDPRIVATEKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt privattr = pk11_attribute_bytype(rsa, CKA_MODULUS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(privattr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv_mod = privattr->pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv_modlen = privattr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(pubattr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pub_mod = pubattr->pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pub_modlen = pubattr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (priv_mod != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (priv_modlen != pub_modlen)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_INVALIDPRIVATEKEY);
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt if (!isc_safe_memequal(priv_mod, pub_mod, pub_modlen))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_INVALIDPRIVATEKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt } else {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt privattr->pValue = pub_mod;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt privattr->ulValueLen = pub_modlen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubattr->pValue = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubattr->ulValueLen = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (privattr->pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_INVALIDPRIVATEKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dst_private_t priv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt int i;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *rsa;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_t *mctx = key->mctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt const char *engine = NULL, *label = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt /* read private key file */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt if (key->external) {
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt if (priv.nelements != 0)
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt DST_RET(DST_R_INVALIDPRIVATEKEY);
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt if (pub == NULL)
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt DST_RET(DST_R_INVALIDPRIVATEKEY);
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt key->keydata.pkey = pub->keydata.pkey;
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt pub->keydata.pkey = NULL;
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt key->key_size = pub->key_size;
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt dst__privstruct_free(&priv, mctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(&priv, sizeof(priv));
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt return (ISC_R_SUCCESS);
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 0; i < priv.nelements; i++) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (priv.elements[i].tag) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_RSA_ENGINE:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt engine = (char *)priv.elements[i].data;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_RSA_LABEL:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt label = (char *)priv.elements[i].data;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt default:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(rsa, 0, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->keydata.pkey = rsa;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt /* Is this key is stored in a HSM? See if we can fetch it. */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((label != NULL) || (engine != NULL)) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ret = pkcs11rsa_fetch(key, engine, label, pub);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto err;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dst__privstruct_free(&priv, mctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(&priv, sizeof(priv));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa->repr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(rsa->repr, 0, sizeof(*attr) * 8);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->attrcnt = 8;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = rsa->repr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[0].type = CKA_MODULUS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[1].type = CKA_PUBLIC_EXPONENT;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[2].type = CKA_PRIVATE_EXPONENT;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[3].type = CKA_PRIME_1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[4].type = CKA_PRIME_2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[5].type = CKA_EXPONENT_1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[6].type = CKA_EXPONENT_2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[7].type = CKA_COEFFICIENT;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 0; i < priv.nelements; i++) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_BYTE *bn;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (priv.elements[i].tag) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_RSA_ENGINE:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt continue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_RSA_LABEL:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt continue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt default:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt bn = isc_mem_get(key->mctx, priv.elements[i].length);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (bn == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(bn, priv.elements[i].data,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt priv.elements[i].length);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (priv.elements[i].tag) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_RSA_MODULUS:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = bn;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = priv.elements[i].length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_RSA_PUBLICEXPONENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CKA_PUBLIC_EXPONENT);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = bn;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = priv.elements[i].length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_RSA_PRIVATEEXPONENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CKA_PRIVATE_EXPONENT);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = bn;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = priv.elements[i].length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_RSA_PRIME1:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa, CKA_PRIME_1);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = bn;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = priv.elements[i].length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_RSA_PRIME2:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa, CKA_PRIME_2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = bn;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = priv.elements[i].length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_RSA_EXPONENT1:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CKA_EXPONENT_1);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = bn;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = priv.elements[i].length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_RSA_EXPONENT2:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CKA_EXPONENT_2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = bn;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = priv.elements[i].length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_RSA_COEFFICIENT:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CKA_COEFFICIENT);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = bn;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = priv.elements[i].length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa_check(rsa, pub->keydata.pkey) != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(DST_R_INVALIDPRIVATEKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_RANGE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dst__privstruct_free(&priv, mctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(&priv, sizeof(priv));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt err:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_destroy(key);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dst__privstruct_free(&priv, mctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(&priv, sizeof(priv));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt const char *pin)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt{
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_KEY_TYPE keyType = CKK_RSA;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE searchTemplate[] =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_LABEL, NULL, 0 }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ULONG cnt;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *rsa;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t *pk11_ctx = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int i;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt UNUSED(pin);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(rsa, 0, sizeof(*rsa));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->object = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->ontoken = ISC_TRUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->reqlogon = ISC_TRUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->keydata.pkey = rsa;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rsa->repr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(rsa->repr, 0, sizeof(*attr) * 2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->attrcnt = 2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = rsa->repr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[0].type = CKA_MODULUS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[1].type = CKA_PUBLIC_EXPONENT;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto err;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx,
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pk11_ctx == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rsa->reqlogon, NULL, rsa->slot);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto err;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa, CKA_LABEL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr == NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa, CKA_ID);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt searchTemplate[3].type = CKA_ID;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt searchTemplate[3].pValue = attr->pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt searchTemplate[3].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_FindObjectsInit,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, searchTemplate, (CK_ULONG) 4),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_FindObjects,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, &hKey, (CK_ULONG) 1, &cnt),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_FindObjectsFinal(pk11_ctx->session);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (cnt == 0)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOTFOUND);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (cnt > 1)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_EXISTS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = rsa->repr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, hKey, attr, 2),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 0; i <= 1; i++) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr[i].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(attr[i].pValue, 0, attr[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, hKey, attr, 2),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyClass = CKO_PRIVATE_KEY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_FindObjectsInit,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, searchTemplate, (CK_ULONG) 4),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_FindObjects,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_FindObjectsFinal(pk11_ctx->session);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (cnt == 0)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOTFOUND);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (cnt > 1)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_EXISTS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (engine != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->engine = isc_mem_strdup(key->mctx, engine);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (key->engine == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->label = isc_mem_strdup(key->mctx, label);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (key->label == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_RANGE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt err:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_destroy(key);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pk11_ctx != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic dst_func_t pkcs11rsa_functions = {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_createctx,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#ifndef PK11_RSA_PKCS_REPLACE
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_createctx2,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#else
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt NULL, /*%< createctx2 */
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt#endif
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_destroyctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_adddata,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_sign,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_verify,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< verify2 */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< computesecret */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_compare,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< paramcompare */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_generate,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_isprivate,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_destroy,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_todns,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_fromdns,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_tofile,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_parse,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< cleanup */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11rsa_fromlabel,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< dump */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< restore */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt};
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntdst__pkcs11rsa_init(dst_func_t **funcp) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(funcp != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (*funcp == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *funcp = &pkcs11rsa_functions;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#else /* PKCS11CRYPTO */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/util.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan HuntEMPTY_TRANSLATION_UNIT
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#endif /* PKCS11CRYPTO */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/*! \file */