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#include <config.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#if defined(PKCS11CRYPTO) && defined(HAVE_PKCS11_GOST)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/entropy.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/mem.h>
699f790c49d03a9ef3c3234a72d272bb469203e8Evan Hunt#include <isc/safe.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/sha2.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/string.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/util.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <dns/keyvalues.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <dns/log.h>
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#include "dst_gost.h"
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt#include <pk11/pk11.h>
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt#include <pk11/internal.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define WANT_GOST_PARAMS
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt#include <pk11/constants.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <pkcs11/pkcs11.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/*
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * RU CryptoPro GOST keys:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * mechanisms:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * CKM_GOSTR3411
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * CKM_GOSTR3410_WITH_GOSTR3411
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * CKM_GOSTR3410_KEY_PAIR_GEN
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * domain parameters:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * CKA_GOSTR3410_PARAMS (fixed BER OID 1.2.643.2.2.35.1)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * CKA_GOSTR3411_PARAMS (fixed BER OID 1.2.643.2.2.30.1)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * CKA_GOST28147_PARAMS (optional, don't use)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * public keys:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * object class CKO_PUBLIC_KEY
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * key type CKK_GOSTR3410
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_VALUE (point Q)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_GOSTR3410_PARAMS
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_GOSTR3411_PARAMS
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_GOST28147_PARAMS
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * private keys:
e20788e1216ed720aefa84f3295f7899d9f28c22Mark Andrews * object class CKO_PRIVATE_KEY
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * key type CKK_GOSTR3410
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_VALUE (big int d)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_GOSTR3410_PARAMS
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_GOSTR3411_PARAMS
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_GOST28147_PARAMS
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * point format: <x> <y> (little endian)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define CKA_VALUE2 CKA_PRIVATE_EXPONENT
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define ISC_GOST_SIGNATURELENGTH 64
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define ISC_GOST_PUBKEYLENGTH 64
80169c379dd4e0a6e164b7cac4bf5fa013c91138Mark Andrews#define ISC_GOST_KEYSIZE 256
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/* HASH methods */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_gost_init(isc_gost_t *ctx) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_MECHANISM mech = { CKM_GOSTR3411, NULL, 0 };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt int ret = ISC_R_SUCCESS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt ret = pk11_get_session(ctx, OP_GOST, ISC_TRUE, ISC_FALSE,
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt ISC_FALSE, NULL, 0);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_CALL(pkcs_C_DigestInit, (ctx->session, &mech), ISC_R_FAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntvoid
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_gost_invalidate(isc_gost_t *ctx) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_BYTE garbage[ISC_GOST_DIGESTLENGTH];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ULONG len = ISC_GOST_DIGESTLENGTH;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ctx->handle == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DigestFinal(ctx->session, garbage, &len);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(garbage, sizeof(garbage));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(ctx);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_gost_update(isc_gost_t *ctx, const unsigned char *buf, unsigned int len) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_BYTE_PTR pPart;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt int ret = ISC_R_SUCCESS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DE_CONST(buf, pPart);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_CALL(pkcs_C_DigestUpdate,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (ctx->session, pPart, (CK_ULONG) len),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ISC_R_FAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_gost_final(isc_gost_t *ctx, unsigned char *digest) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ULONG len = ISC_GOST_DIGESTLENGTH;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt int ret = ISC_R_SUCCESS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_CALL(pkcs_C_DigestFinal,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (ctx->session, (CK_BYTE_PTR) digest, &len),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ISC_R_FAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(ctx);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/* DST methods */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic CK_BBOOL truevalue = TRUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic CK_BBOOL falsevalue = FALSE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define DST_RET(a) {ret = a; goto err;}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t pkcs11gost_todns(const dst_key_t *key, isc_buffer_t *data);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic void pkcs11gost_destroy(dst_key_t *key);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11gost_createctx_sign(dst_key_t *key, dst_context_t *dctx) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_KEY_TYPE keyType = CKK_GOSTR3410;
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_VALUE, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (CK_ULONG) sizeof(pk11_gost_a_paramset) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_GOSTR3411_PARAMS, pk11_gost_paramset,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (CK_ULONG) sizeof(pk11_gost_paramset) }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *gost;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t *pk11_ctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int i;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt REQUIRE(key != NULL);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt gost = key->keydata.pkey;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt REQUIRE(gost != NULL);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan 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_GOST, ISC_TRUE, ISC_FALSE,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt gost->reqlogon, NULL,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_get_best_token(OP_GOST));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto err;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (gost->ontoken && (gost->object != CK_INVALID_HANDLE)) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_ctx->ontoken = gost->ontoken;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_ctx->object = gost->object;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto token_key;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (attr = pk11_attribute_first(gost);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr != NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_next(gost, attr))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (attr->type) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_VALUE2:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(keyTemplate[6].type == CKA_VALUE);
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 }
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) 9,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt &pk11_ctx->object),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ISC_R_FAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt token_key:
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 <= 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, pk11_ctx->object);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 6; 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 Huntpkcs11gost_createctx_verify(dst_key_t *key, dst_context_t *dctx) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_KEY_TYPE keyType = CKK_GOSTR3410;
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_VALUE, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (CK_ULONG) sizeof(pk11_gost_a_paramset) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_GOSTR3411_PARAMS, pk11_gost_paramset,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (CK_ULONG) sizeof(pk11_gost_paramset) }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *gost;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t *pk11_ctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int i;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt REQUIRE(key != NULL);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt gost = key->keydata.pkey;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt REQUIRE(gost != NULL);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan 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_GOST, ISC_TRUE, ISC_FALSE,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt gost->reqlogon, NULL,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_get_best_token(OP_GOST));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto err;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (gost->ontoken && (gost->object != CK_INVALID_HANDLE)) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_ctx->ontoken = gost->ontoken;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_ctx->object = gost->object;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto token_key;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (attr = pk11_attribute_first(gost);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr != NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_next(gost, attr))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (attr->type) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_VALUE:
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 }
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) 8,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt &pk11_ctx->object),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ISC_R_FAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt token_key:
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 <= 5; 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, pk11_ctx->object);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 5; i <= 5; 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 Huntpkcs11gost_createctx(dst_key_t *key, dst_context_t *dctx) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dctx->use == DO_SIGN)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (pkcs11gost_createctx_sign(key, dctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (pkcs11gost_createctx_verify(key, dctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic void
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11gost_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,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan 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 Huntpkcs11gost_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 Huntpkcs11gost_sign(dst_context_t *dctx, isc_buffer_t *sig) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ULONG siglen = ISC_GOST_SIGNATURELENGTH;
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 isc_buffer_availableregion(sig, &r);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (r.length < ISC_GOST_SIGNATURELENGTH)
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 if (siglen != ISC_GOST_SIGNATURELENGTH)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_SIGNFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_add(sig, ISC_GOST_SIGNATURELENGTH);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt err:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11gost_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
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_boolean_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11gost_compare(const dst_key_t *key1, const dst_key_t *key2) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *gost1, *gost2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr1, *attr2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt gost1 = key1->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt gost2 = key2->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((gost1 == NULL) && (gost2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else if ((gost1 == NULL) || (gost2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr1 = pk11_attribute_bytype(gost1, CKA_VALUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr2 = pk11_attribute_bytype(gost2, CKA_VALUE);
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(gost1, CKA_VALUE2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr2 = pk11_attribute_bytype(gost2, CKA_VALUE2);
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 (!gost1->ontoken && !gost2->ontoken)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else if (gost1->ontoken || gost2->ontoken ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (gost1->object != gost2->object))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11gost_generate(dst_key_t *key, int unused, void (*callback)(int)) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_MECHANISM mech = { CKM_GOSTR3410_KEY_PAIR_GEN, NULL, 0 };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_KEY_TYPE keyType = CKK_GOSTR3410;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
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_GOSTR3410_PARAMS, pk11_gost_a_paramset,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (CK_ULONG) sizeof(pk11_gost_a_paramset) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_GOSTR3411_PARAMS, pk11_gost_paramset,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (CK_ULONG) sizeof(pk11_gost_paramset) }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_HANDLE 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 *gost;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t *pk11_ctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt UNUSED(unused);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt UNUSED(callback);
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 return (ISC_R_NOMEMORY);
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt ret = pk11_get_session(pk11_ctx, OP_GOST, ISC_TRUE, ISC_FALSE,
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt ISC_FALSE, NULL, pk11_get_best_token(OP_GOST));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto err;
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 gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (gost == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(gost, 0, sizeof(*gost));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->keydata.pkey = gost;
80169c379dd4e0a6e164b7cac4bf5fa013c91138Mark Andrews key->key_size = ISC_GOST_KEYSIZE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt sizeof(*attr) * 2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (gost->repr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(gost->repr, 0, sizeof(*attr) * 2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt gost->attrcnt = 2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = gost->repr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[0].type = CKA_VALUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[1].type = CKA_VALUE2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = gost->repr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, pub, attr, 1),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr->pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(attr->pValue, 0, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, pub, attr, 1),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->type = CKA_VALUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, priv, attr, 1),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr->pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(attr->pValue, 0, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, priv, attr, 1),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->type = CKA_VALUE2;
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);
e20788e1216ed720aefa84f3295f7899d9f28c22Mark Andrews
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt err:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11gost_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 Huntpkcs11gost_isprivate(const dst_key_t *key) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *gost = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (gost == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(gost, CKA_VALUE2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TF((attr != NULL) || gost->ontoken));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic void
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11gost_destroy(dst_key_t *key) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *gost = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (gost == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST((gost->object == CK_INVALID_HANDLE) || gost->ontoken);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (attr = pk11_attribute_first(gost);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr != NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_next(gost, attr))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (attr->type) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_VALUE:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_VALUE2:
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 (gost->repr != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(gost->repr, gost->attrcnt * sizeof(*attr));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman gost->repr, gost->attrcnt * sizeof(*attr));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(gost, sizeof(*gost));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, gost, sizeof(*gost));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->keydata.pkey = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11gost_todns(const dst_key_t *key, isc_buffer_t *data) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *gost;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_region_t r;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(key->keydata.pkey != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt gost = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(gost, CKA_VALUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((attr == NULL) || (attr->ulValueLen != ISC_GOST_PUBKEYLENGTH))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_FAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_availableregion(data, &r);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (r.length < ISC_GOST_PUBKEYLENGTH)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOSPACE);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(r.base, (CK_BYTE_PTR) attr->pValue, ISC_GOST_PUBKEYLENGTH);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_add(data, ISC_GOST_PUBKEYLENGTH);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11gost_fromdns(dst_key_t *key, isc_buffer_t *data) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *gost;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_region_t r;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_remainingregion(data, &r);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (r.length == 0)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (r.length != ISC_GOST_PUBKEYLENGTH)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_INVALIDPUBLICKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (gost == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(gost, 0, sizeof(*gost));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (gost->repr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto nomemory;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt gost->attrcnt = 1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = gost->repr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->type = CKA_VALUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = isc_mem_get(key->mctx, ISC_GOST_PUBKEYLENGTH);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr->pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto nomemory;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove((CK_BYTE_PTR) attr->pValue, r.base, ISC_GOST_PUBKEYLENGTH);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = ISC_GOST_PUBKEYLENGTH;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_forward(data, ISC_GOST_PUBKEYLENGTH);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->keydata.pkey = gost;
80169c379dd4e0a6e164b7cac4bf5fa013c91138Mark Andrews key->key_size = ISC_GOST_KEYSIZE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt nomemory:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (attr = pk11_attribute_first(gost);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr != NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_next(gost, attr))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (attr->type) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_VALUE:
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 (gost->repr != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(gost->repr, gost->attrcnt * sizeof(*attr));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman gost->repr, gost->attrcnt * sizeof(*attr));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(gost, sizeof(*gost));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, gost, sizeof(*gost));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Huntstatic unsigned char gost_private_der[39] = {
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt 0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06,
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30,
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02,
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02,
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt 0x02, 0x1e, 0x01, 0x04, 0x22, 0x02, 0x20
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt};
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt#ifdef PREFER_GOSTASN1
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Huntstatic isc_result_t
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Huntpkcs11gost_tofile(const dst_key_t *key, const char *directory) {
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt isc_result_t ret;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *gost;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt dst_private_t priv;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt unsigned char *buf = NULL;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt unsigned int i = 0;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt CK_ATTRIBUTE *attr;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt int adj;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt if (key->keydata.pkey == NULL)
12bf5d4796505b4c20680531da96a31e6c2c1144Evan 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
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt gost = key->keydata.pkey;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt attr = pk11_attribute_bytype(gost, CKA_VALUE2);
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt if (attr != NULL) {
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt buf = isc_mem_get(key->mctx, attr->ulValueLen + 39);
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt if (buf == NULL)
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt return (ISC_R_NOMEMORY);
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt priv.elements[i].tag = TAG_GOST_PRIVASN1;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt priv.elements[i].length =
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt (unsigned short) attr->ulValueLen + 39;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(buf, gost_private_der, 39);
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt memmove(buf + 39, attr->pValue, attr->ulValueLen);
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt adj = (int) attr->ulValueLen - 32;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt if (adj != 0) {
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt buf[1] += adj;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt buf[36] += adj;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt buf[38] += adj;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt }
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt priv.elements[i].data = buf;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt i++;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt } else
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt return (DST_R_CRYPTOFAILURE);
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt priv.nelements = i;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt ret = dst__privstruct_writefile(key, &priv, directory);
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt if (buf != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(buf, attr->ulValueLen);
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt isc_mem_put(key->mctx, buf, attr->ulValueLen);
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt }
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt return (ret);
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt}
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt#else
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11gost_tofile(const dst_key_t *key, const char *directory) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *gost;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dst_private_t priv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned char *buf = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int i = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (key->keydata.pkey == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_NULLKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
6972eaffdbb7bb83c1b8565adfc6778430f80c8cFrancis Dupont if (key->external) {
6972eaffdbb7bb83c1b8565adfc6778430f80c8cFrancis Dupont priv.nelements = 0;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt return (dst__privstruct_writefile(key, &priv, directory));
6972eaffdbb7bb83c1b8565adfc6778430f80c8cFrancis Dupont }
6972eaffdbb7bb83c1b8565adfc6778430f80c8cFrancis Dupont
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt gost = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(gost, CKA_VALUE2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt buf = isc_mem_get(key->mctx, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (buf == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_GOST_PRIVRAW;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].length = (unsigned short) attr->ulValueLen;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(buf, attr->pValue, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = buf;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt } else
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt return (DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.nelements = i;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ret = dst__privstruct_writefile(key, &priv, directory);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (buf != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(buf, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, buf, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt#endif
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11gost_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;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *gost = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr, *pattr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_t *mctx = key->mctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt if ((pub == NULL) || (pub->keydata.pkey == NULL))
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt DST_RET(DST_R_INVALIDPRIVATEKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt /* read private key file */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, 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
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 }
6972eaffdbb7bb83c1b8565adfc6778430f80c8cFrancis Dupont
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (priv.elements[0].tag == TAG_GOST_PRIVASN1) {
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt int adj = (int) priv.elements[0].length - (39 + 32);
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt unsigned char buf[39];
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt if ((adj > 0) || (adj < -31))
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt DST_RET(DST_R_INVALIDPRIVATEKEY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(buf, gost_private_der, 39);
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt if (adj != 0) {
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt buf[1] += adj;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt buf[36] += adj;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt buf[38] += adj;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt }
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt if (!isc_safe_memequal(priv.elements[0].data, buf, 39))
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt DST_RET(DST_R_INVALIDPRIVATEKEY);
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt priv.elements[0].tag = TAG_GOST_PRIVRAW;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt priv.elements[0].length -= 39;
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt memmove(priv.elements[0].data,
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt priv.elements[0].data + 39,
12bf5d4796505b4c20680531da96a31e6c2c1144Evan Hunt 32 + adj);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (gost == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(gost, 0, sizeof(*gost));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->keydata.pkey = gost;
80169c379dd4e0a6e164b7cac4bf5fa013c91138Mark Andrews key->key_size = ISC_GOST_KEYSIZE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt sizeof(*attr) * 2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (gost->repr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(gost->repr, 0, sizeof(*attr) * 2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt gost->attrcnt = 2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = gost->repr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->type = CKA_VALUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pattr = pk11_attribute_bytype(pub->keydata.pkey, CKA_VALUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(pattr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = isc_mem_get(key->mctx, pattr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr->pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(attr->pValue, pattr->pValue, pattr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = pattr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->type = CKA_VALUE2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = isc_mem_get(key->mctx, priv.elements[0].length);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr->pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(attr->pValue, priv.elements[0].data, priv.elements[0].length);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = priv.elements[0].length;
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 pkcs11gost_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 dst_func_t pkcs11gost_functions = {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11gost_createctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< createctx2 */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11gost_destroyctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11gost_adddata,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11gost_sign,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11gost_verify,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< verify2 */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< computesecret */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11gost_compare,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< paramcompare */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11gost_generate,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11gost_isprivate,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11gost_destroy,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11gost_todns,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11gost_fromdns,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11gost_tofile,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11gost_parse,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< cleanup */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< fromlabel */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< dump */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< restore */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt};
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntdst__pkcs11gost_init(dst_func_t **funcp) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(funcp != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (*funcp == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *funcp = &pkcs11gost_functions;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#else /* PKCS11CRYPTO && HAVE_PKCS11_GOST */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/util.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan HuntEMPTY_TRANSLATION_UNIT
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#endif /* PKCS11CRYPTO && HAVE_PKCS11_GOST */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/*! \file */