pkcs11dh_link.c revision ce9f893e21d2ffc6f6a78bf226c038c396740aeb
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson/*
431a83fb29482c5170b3e4026e59bb14849a6707Tinderbox User * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Permission to use, copy, modify, and/or distribute this software for any
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * purpose with or without fee is hereby granted, provided that the above
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson * copyright notice and this permission notice appear in all copies.
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews */
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson#ifdef PKCS11CRYPTO
313b4dc3b2e2be29994ce030c42c39c9eef9c46bAutomatic Updater
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#include <config.h>
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence#include <ctype.h>
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson#include <isc/mem.h>
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson#include <isc/string.h>
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews#include <isc/util.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <dst/result.h>
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson#include "dst_internal.h"
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt#include "dst_parse.h"
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson#include "dst_pkcs11.h"
501941f0b6cce74c2ff75b10aff3f230d5d37e4cEvan Hunt
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt#include <pk11/pk11.h>
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt#include <pk11/internal.h>
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt#define WANT_DH_PRIMES
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt#include <pk11/constants.h>
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson#include <pkcs11/pkcs11.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson/*
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson * PKCS#3 DH keys:
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson * mechanisms:
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * CKM_DH_PKCS_PARAMETER_GEN,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * CKM_DH_PKCS_KEY_PAIR_GEN,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * CKM_DH_PKCS_DERIVE
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson * domain parameters:
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson * object class CKO_DOMAIN_PARAMETERS
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * key type CKK_DH
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson * attribute CKA_PRIME (prime p)
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson * attribute CKA_BASE (base g)
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson * optional attribute CKA_PRIME_BITS (p length in bits)
df925e6c66d45d960fbac0383169763967d2111cEvan Hunt * public key:
df925e6c66d45d960fbac0383169763967d2111cEvan Hunt * object class CKO_PUBLIC_KEY
df925e6c66d45d960fbac0383169763967d2111cEvan Hunt * key type CKK_DH
df925e6c66d45d960fbac0383169763967d2111cEvan Hunt * attribute CKA_PRIME (prime p)
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson * attribute CKA_BASE (base g)
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt * attribute CKA_VALUE (public value y)
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews * private key:
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews * object class CKO_PRIVATE_KEY
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews * key type CKK_DH
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews * attribute CKA_PRIME (prime p)
18d0b5e54be891a1aa938c165b6d439859121ec8Mark Andrews * attribute CKA_BASE (base g)
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt * attribute CKA_VALUE (private value x)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews * optional attribute CKA_VALUE_BITS (x length in bits)
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt * reuse CKA_PRIVATE_EXPONENT for key pair private value
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt */
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt#define CKA_VALUE2 CKA_PRIVATE_EXPONENT
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafssonstatic CK_BBOOL truevalue = TRUE;
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafssonstatic CK_BBOOL falsevalue = FALSE;
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson
114c14f8adfc249cf2e5cdcb9007af46fed257e3Mark Andrews#define DST_RET(a) {ret = a; goto err;}
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafssonstatic void pkcs11dh_destroy(dst_key_t *key);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencestatic isc_result_t pkcs11dh_todns(const dst_key_t *key, isc_buffer_t *data);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencestatic isc_result_t
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencepkcs11dh_loadpriv(const dst_key_t *key,
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson CK_SESSION_HANDLE session,
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson CK_OBJECT_HANDLE *hKey)
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson{
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson CK_RV rv;
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson CK_KEY_TYPE keyType = CKK_DH;
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson CK_ATTRIBUTE keyTemplate[] =
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson {
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson { CKA_DERIVE, &truevalue, (CK_ULONG) sizeof(truevalue) },
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson { CKA_PRIME, NULL, 0 },
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson { CKA_BASE, NULL, 0 },
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt { CKA_VALUE, NULL, 0 }
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt };
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt CK_ATTRIBUTE *attr;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt const pk11_object_t *priv;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt isc_result_t ret;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt unsigned int i;
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence priv = key->keydata.pkey;
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson if ((priv->object != CK_INVALID_HANDLE) && priv->ontoken) {
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson *hKey = priv->object;
e7220c9b841bbd3d16736726f786a86fec3c0e18Evan Hunt return (ISC_R_SUCCESS);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt }
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson attr = pk11_attribute_bytype(priv, CKA_PRIME);
1aba9fe67899522364a9dbc3ee5a14da081f0314Evan Hunt if (attr == NULL)
1aba9fe67899522364a9dbc3ee5a14da081f0314Evan Hunt return (DST_R_INVALIDPRIVATEKEY);
1aba9fe67899522364a9dbc3ee5a14da081f0314Evan Hunt keyTemplate[6].pValue = isc_mem_get(key->mctx, attr->ulValueLen);
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater if (keyTemplate[6].pValue == NULL)
1aba9fe67899522364a9dbc3ee5a14da081f0314Evan Hunt DST_RET(ISC_R_NOMEMORY);
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen);
1aba9fe67899522364a9dbc3ee5a14da081f0314Evan Hunt keyTemplate[6].ulValueLen = attr->ulValueLen;
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson attr = pk11_attribute_bytype(priv, CKA_BASE);
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson if (attr == NULL)
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson DST_RET(DST_R_INVALIDPRIVATEKEY);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt keyTemplate[7].pValue = isc_mem_get(key->mctx, attr->ulValueLen);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt if (keyTemplate[7].pValue == NULL)
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt DST_RET(ISC_R_NOMEMORY);
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson memmove(keyTemplate[7].pValue, attr->pValue, attr->ulValueLen);
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson keyTemplate[7].ulValueLen = attr->ulValueLen;
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson attr = pk11_attribute_bytype(priv, CKA_VALUE2);
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson if (attr == NULL)
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt DST_RET(DST_R_INVALIDPRIVATEKEY);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt keyTemplate[8].pValue = isc_mem_get(key->mctx, attr->ulValueLen);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt if (keyTemplate[8].pValue == NULL)
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson DST_RET(ISC_R_NOMEMORY);
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson memmove(keyTemplate[8].pValue, attr->pValue, attr->ulValueLen);
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson keyTemplate[8].ulValueLen = attr->ulValueLen;
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson
7693d4de8fca501dfe6989a7f30d8d3c86fe096aAndreas Gustafsson PK11_CALL(pkcs_C_CreateObject,
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt (session, keyTemplate, (CK_ULONG) 9, hKey),
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt DST_R_COMPUTESECRETFAILURE);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt if (rv == CKR_OK)
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt ret = ISC_R_SUCCESS;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt err:
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt for (i = 6; i <= 8; i++)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (keyTemplate[i].pValue != NULL) {
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews memset(keyTemplate[i].pValue, 0,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews keyTemplate[i].ulValueLen);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews isc_mem_put(key->mctx,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews keyTemplate[i].pValue,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews keyTemplate[i].ulValueLen);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews }
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt return (ret);
e80f661db8ec9596eb977d6fc537484aa3662e22Evan Hunt}
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Huntstatic isc_result_t
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Huntpkcs11dh_computesecret(const dst_key_t *pub, const dst_key_t *priv,
e80f661db8ec9596eb977d6fc537484aa3662e22Evan Hunt isc_buffer_t *secret)
106360491ad40eef9669fd792c35710d6af1dab0Evan Hunt{
cdbb3d27740fd052f18067b937097ebf35df356bAutomatic Updater CK_RV rv;
28ad0be64ee756013c0f6a474fc447ee613ee0d1Evan Hunt CK_MECHANISM mech = { CKM_DH_PKCS_DERIVE, NULL, 0 };
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt CK_OBJECT_HANDLE hDerived = CK_INVALID_HANDLE;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt CK_ATTRIBUTE *attr;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt CK_ULONG secLen;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt CK_ATTRIBUTE keyTemplate[] =
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt {
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) },
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt { CKA_VALUE_LEN, &secLen, (CK_ULONG) sizeof(secLen) }
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt };
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt CK_ATTRIBUTE valTemplate[] =
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt {
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt { CKA_VALUE, NULL, 0 }
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt };
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt CK_BYTE *secValue;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pk11_context_t ctx;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt isc_result_t ret;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt unsigned int i;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt isc_region_t r;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater REQUIRE(pub->keydata.pkey != NULL);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt REQUIRE(priv->keydata.pkey != NULL);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt REQUIRE(priv->keydata.pkey->repr != NULL);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_PRIME);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson if (attr == NULL)
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews return (DST_R_INVALIDPUBLICKEY);
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews REQUIRE(attr != NULL);
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews secLen = attr->ulValueLen;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_VALUE);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson if (attr == NULL)
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt return (DST_R_INVALIDPUBLICKEY);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt ret = pk11_get_session(&ctx, OP_DH, ISC_TRUE, ISC_FALSE, ISC_FALSE,
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt NULL, pk11_get_best_token(OP_DH));
175a8bd2b798bbc568cd912b72c8a026cfca8527Mark Andrews if (ret != ISC_R_SUCCESS)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ret);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt mech.ulParameterLen = attr->ulValueLen;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews mech.pParameter = isc_mem_get(pub->mctx, mech.ulParameterLen);
8bb77cd31b7518fb5d2a6a9d75e16e4abd59df61Andreas Gustafsson if (mech.pParameter == NULL)
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson DST_RET(ISC_R_NOMEMORY);
d8d0c5b1bc97ac0f07e35a31b58ced80ce613c55David Lawrence memmove(mech.pParameter, attr->pValue, mech.ulParameterLen);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt ret = pkcs11dh_loadpriv(priv, ctx.session, &hKey);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt if (ret != ISC_R_SUCCESS)
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt goto err;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews PK11_RET(pkcs_C_DeriveKey,
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt (ctx.session, &mech, hKey,
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt keyTemplate, (CK_ULONG) 6, &hDerived),
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt DST_R_COMPUTESECRETFAILURE);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt attr = valTemplate;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt PK11_RET(pkcs_C_GetAttributeValue,
fc7043d7d1294478c9988c10af9a7fb8fd810338Evan Hunt (ctx.session, hDerived, attr, (CK_ULONG) 1),
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt DST_R_CRYPTOFAILURE);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt attr->pValue = isc_mem_get(pub->mctx, attr->ulValueLen);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt if (attr->pValue == NULL)
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt DST_RET(ISC_R_NOMEMORY);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt memset(attr->pValue, 0, attr->ulValueLen);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt PK11_RET(pkcs_C_GetAttributeValue,
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt (ctx.session, hDerived, attr, (CK_ULONG) 1),
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt DST_R_CRYPTOFAILURE);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt /* strip leading zeros */
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt secValue = (CK_BYTE_PTR) attr->pValue;
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt for (i = 0; i < attr->ulValueLen; i++)
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt if (secValue[i] != 0)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews break;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews isc_buffer_availableregion(secret, &r);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (r.length < attr->ulValueLen - i)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews DST_RET(ISC_R_NOSPACE);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt memmove(r.base, secValue + i, attr->ulValueLen - i);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews isc_buffer_add(secret, attr->ulValueLen - i);
8bb77cd31b7518fb5d2a6a9d75e16e4abd59df61Andreas Gustafsson ret = ISC_R_SUCCESS;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence err:
114c14f8adfc249cf2e5cdcb9007af46fed257e3Mark Andrews if (hDerived != CK_INVALID_HANDLE)
aeadcd63196f164b219629a53c0e0925519288f3Evan Hunt (void) pkcs_C_DestroyObject(ctx.session, hDerived);
aeadcd63196f164b219629a53c0e0925519288f3Evan Hunt if (valTemplate[0].pValue != NULL) {
114c14f8adfc249cf2e5cdcb9007af46fed257e3Mark Andrews memset(valTemplate[0].pValue, 0, valTemplate[0].ulValueLen);
aeadcd63196f164b219629a53c0e0925519288f3Evan Hunt isc_mem_put(pub->mctx,
114c14f8adfc249cf2e5cdcb9007af46fed257e3Mark Andrews valTemplate[0].pValue,
ba7ea2326d98edb4296098749fc9cf44b5157643David Lawrence valTemplate[0].ulValueLen);
ba7ea2326d98edb4296098749fc9cf44b5157643David Lawrence }
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if ((hKey != CK_INVALID_HANDLE) && !priv->keydata.pkey->ontoken)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews (void) pkcs_C_DestroyObject(ctx.session, hKey);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (mech.pParameter != NULL) {
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews memset(mech.pParameter, 0, mech.ulParameterLen);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews isc_mem_put(pub->mctx, mech.pParameter, mech.ulParameterLen);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews }
aeadcd63196f164b219629a53c0e0925519288f3Evan Hunt pk11_return_session(&ctx);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson return (ret);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson}
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Huntstatic isc_boolean_t
aeadcd63196f164b219629a53c0e0925519288f3Evan Huntpkcs11dh_compare(const dst_key_t *key1, const dst_key_t *key2) {
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson pk11_object_t *dh1, *dh2;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson CK_ATTRIBUTE *attr1, *attr2;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt dh1 = key1->keydata.pkey;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt dh2 = key2->keydata.pkey;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt if ((dh1 == NULL) && (dh2 == NULL))
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt return (ISC_TRUE);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt else if ((dh1 == NULL) || (dh2 == NULL))
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt return (ISC_FALSE);
584848087f7463c1f659ce4712dc047d8e7f2b07Francis Dupont
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt attr1 = pk11_attribute_bytype(dh1, CKA_PRIME);
aa39170da817cae7b4c6c735cc832e05ec3d2351Mark Andrews attr2 = pk11_attribute_bytype(dh2, CKA_PRIME);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt if ((attr1 == NULL) && (attr2 == NULL))
aa39170da817cae7b4c6c735cc832e05ec3d2351Mark Andrews return (ISC_TRUE);
12e0477d4e132c9122312246ed60aaa646f819b2Mark Andrews else if ((attr1 == NULL) || (attr2 == NULL) ||
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews (attr1->ulValueLen != attr2->ulValueLen) ||
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_FALSE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews attr1 = pk11_attribute_bytype(dh1, CKA_BASE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews attr2 = pk11_attribute_bytype(dh2, CKA_BASE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if ((attr1 == NULL) && (attr2 == NULL))
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_TRUE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews else if ((attr1 == NULL) || (attr2 == NULL) ||
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews (attr1->ulValueLen != attr2->ulValueLen) ||
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_FALSE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews attr1 = pk11_attribute_bytype(dh1, CKA_VALUE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews attr2 = pk11_attribute_bytype(dh2, CKA_VALUE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if ((attr1 == NULL) && (attr2 == NULL))
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_TRUE);
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt else if ((attr1 == NULL) || (attr2 == NULL) ||
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt (attr1->ulValueLen != attr2->ulValueLen) ||
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_FALSE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews attr1 = pk11_attribute_bytype(dh1, CKA_VALUE2);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews attr2 = pk11_attribute_bytype(dh2, CKA_VALUE2);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (((attr1 != NULL) || (attr2 != NULL)) &&
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews ((attr1 == NULL) || (attr2 == NULL) ||
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews (attr1->ulValueLen != attr2->ulValueLen) ||
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)))
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_FALSE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (!dh1->ontoken && !dh2->ontoken)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_TRUE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews else if (dh1->ontoken || dh2->ontoken ||
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews (dh1->object != dh2->object))
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_FALSE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_TRUE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews}
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrewsstatic isc_boolean_t
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrewspkcs11dh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) {
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pk11_object_t *dh1, *dh2;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews CK_ATTRIBUTE *attr1, *attr2;
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews dh1 = key1->keydata.pkey;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews dh2 = key2->keydata.pkey;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt if ((dh1 == NULL) && (dh2 == NULL))
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_TRUE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews else if ((dh1 == NULL) || (dh2 == NULL))
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_FALSE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews attr1 = pk11_attribute_bytype(dh1, CKA_PRIME);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews attr2 = pk11_attribute_bytype(dh2, CKA_PRIME);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if ((attr1 == NULL) && (attr2 == NULL))
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_TRUE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews else if ((attr1 == NULL) || (attr2 == NULL) ||
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews (attr1->ulValueLen != attr2->ulValueLen) ||
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_FALSE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews attr1 = pk11_attribute_bytype(dh1, CKA_BASE);
c2638d3d5ab1fa10fde4026e92c5ffff23b77bdfMark Andrews attr2 = pk11_attribute_bytype(dh2, CKA_BASE);
c0c4512020c0a4a9e5b087cb8cad1cd68fb3f52eEvan Hunt if ((attr1 == NULL) && (attr2 == NULL))
c0c4512020c0a4a9e5b087cb8cad1cd68fb3f52eEvan Hunt return (ISC_TRUE);
c0c4512020c0a4a9e5b087cb8cad1cd68fb3f52eEvan Hunt else if ((attr1 == NULL) || (attr2 == NULL) ||
c0c4512020c0a4a9e5b087cb8cad1cd68fb3f52eEvan Hunt (attr1->ulValueLen != attr2->ulValueLen) ||
c0c4512020c0a4a9e5b087cb8cad1cd68fb3f52eEvan Hunt memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))
c2638d3d5ab1fa10fde4026e92c5ffff23b77bdfMark Andrews return (ISC_FALSE);
c0c4512020c0a4a9e5b087cb8cad1cd68fb3f52eEvan Hunt
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_TRUE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews}
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrewsstatic isc_result_t
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updaterpkcs11dh_generate(dst_key_t *key, int generator, void (*callback)(int)) {
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews CK_RV rv;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews CK_MECHANISM mech = { CKM_DH_PKCS_PARAMETER_GEN, NULL, 0 };
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews CK_OBJECT_HANDLE domainparams = CK_INVALID_HANDLE;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews CK_OBJECT_CLASS dClass = CKO_DOMAIN_PARAMETERS;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews CK_KEY_TYPE keyType = CKK_DH;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews CK_ULONG bits = 0;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews CK_ATTRIBUTE dTemplate[] =
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews {
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews { CKA_CLASS, &dClass, (CK_ULONG) sizeof(dClass) },
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews { CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) }
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews };
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews CK_ATTRIBUTE pTemplate[] =
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews {
aa39170da817cae7b4c6c735cc832e05ec3d2351Mark Andrews { CKA_PRIME, NULL, 0 },
aa39170da817cae7b4c6c735cc832e05ec3d2351Mark Andrews { CKA_BASE, NULL, 0 }
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt };
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt CK_ATTRIBUTE pubTemplate[] =
584848087f7463c1f659ce4712dc047d8e7f2b07Francis Dupont {
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) },
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt { CKA_KEY_TYPE,&keyType, (CK_ULONG) sizeof(keyType) },
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson { CKA_PRIME, NULL, 0 },
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews { CKA_BASE, NULL, 0 },
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews };
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews CK_ATTRIBUTE privTemplate[] =
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson {
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) },
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) },
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson { CKA_DERIVE, &truevalue, (CK_ULONG) sizeof(truevalue) },
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt };
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews CK_ATTRIBUTE *attr;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pk11_object_t *dh = NULL;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pk11_context_t *pk11_ctx;
501941f0b6cce74c2ff75b10aff3f230d5d37e4cEvan Hunt isc_result_t ret;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews UNUSED(callback);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews sizeof(*pk11_ctx));
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (pk11_ctx == NULL)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_R_NOMEMORY);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews ret = pk11_get_session(pk11_ctx, OP_DH, ISC_TRUE, ISC_FALSE,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews ISC_FALSE, NULL, pk11_get_best_token(OP_DH));
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (ret != ISC_R_SUCCESS)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews goto err;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews bits = key->key_size;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if ((generator == 0) &&
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews ((bits == 768) || (bits == 1024) || (bits == 1536))) {
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (bits == 768) {
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pubTemplate[4].pValue =
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews isc_mem_get(key->mctx, sizeof(pk11_dh_bn768));
501941f0b6cce74c2ff75b10aff3f230d5d37e4cEvan Hunt if (pubTemplate[4].pValue == NULL)
501941f0b6cce74c2ff75b10aff3f230d5d37e4cEvan Hunt DST_RET(ISC_R_NOMEMORY);
0666e6db543cda2de2b8472ba49ed9b53c836326Tinderbox User memmove(pubTemplate[4].pValue,
d0803df3310ad09447c34b972e7594d576f5cbb5Evan Hunt pk11_dh_bn768, sizeof(pk11_dh_bn768));
501941f0b6cce74c2ff75b10aff3f230d5d37e4cEvan Hunt pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn768);
501941f0b6cce74c2ff75b10aff3f230d5d37e4cEvan Hunt } else if (bits == 1024) {
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pubTemplate[4].pValue =
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews isc_mem_get(key->mctx, sizeof(pk11_dh_bn1024));
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (pubTemplate[4].pValue == NULL)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews DST_RET(ISC_R_NOMEMORY);
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater memmove(pubTemplate[4].pValue,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pk11_dh_bn1024, sizeof(pk11_dh_bn1024));
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1024);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews } else {
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pubTemplate[4].pValue =
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews isc_mem_get(key->mctx, sizeof(pk11_dh_bn1536));
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (pubTemplate[4].pValue == NULL)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews DST_RET(ISC_R_NOMEMORY);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews memmove(pubTemplate[4].pValue,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pk11_dh_bn1536, sizeof(pk11_dh_bn1536));
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1536);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews }
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pubTemplate[5].pValue = isc_mem_get(key->mctx,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews sizeof(pk11_dh_bn2));
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (pubTemplate[5].pValue == NULL)
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews DST_RET(ISC_R_NOMEMORY);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews memmove(pubTemplate[5].pValue, pk11_dh_bn2,
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater sizeof(pk11_dh_bn2));
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pubTemplate[5].ulValueLen = sizeof(pk11_dh_bn2);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews } else {
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews PK11_RET(pkcs_C_GenerateKey,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews (pk11_ctx->session, &mech,
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson dTemplate, (CK_ULONG) 5, &domainparams),
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews DST_R_CRYPTOFAILURE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews PK11_RET(pkcs_C_GetAttributeValue,
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater (pk11_ctx->session, domainparams,
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson pTemplate, (CK_ULONG) 2),
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater DST_R_CRYPTOFAILURE);
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson pTemplate[0].pValue = isc_mem_get(key->mctx,
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson pTemplate[0].ulValueLen);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if (pTemplate[0].pValue == NULL)
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson DST_RET(ISC_R_NOMEMORY);
e7220c9b841bbd3d16736726f786a86fec3c0e18Evan Hunt memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen);
aa23a35d81a9618a40c4a9b44be48009553e4777Andreas Gustafsson pTemplate[1].pValue = isc_mem_get(key->mctx,
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson pTemplate[1].ulValueLen);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson if (pTemplate[1].pValue == NULL)
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson DST_RET(ISC_R_NOMEMORY);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence PK11_RET(pkcs_C_GetAttributeValue,
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson (pk11_ctx->session, domainparams,
e7220c9b841bbd3d16736726f786a86fec3c0e18Evan Hunt pTemplate, (CK_ULONG) 2),
e7220c9b841bbd3d16736726f786a86fec3c0e18Evan Hunt DST_R_CRYPTOFAILURE);
e7220c9b841bbd3d16736726f786a86fec3c0e18Evan Hunt
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson pubTemplate[4].pValue = pTemplate[0].pValue;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson pubTemplate[4].ulValueLen = pTemplate[0].ulValueLen;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt pTemplate[0].pValue = NULL;
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt pubTemplate[5].pValue = pTemplate[1].pValue;
12e0477d4e132c9122312246ed60aaa646f819b2Mark Andrews pubTemplate[5].ulValueLen = pTemplate[1].ulValueLen;
12e0477d4e132c9122312246ed60aaa646f819b2Mark Andrews pTemplate[1].pValue = NULL;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson }
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson mech.mechanism = CKM_DH_PKCS_KEY_PAIR_GEN;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson PK11_RET(pkcs_C_GenerateKeyPair,
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson (pk11_ctx->session, &mech,
ea419adc4eca4c3e44f2c282035b5dce6b795fe2Andreas Gustafsson pubTemplate, (CK_ULONG) 6,
ea419adc4eca4c3e44f2c282035b5dce6b795fe2Andreas Gustafsson privTemplate, (CK_ULONG) 7,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews &pub, &priv),
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews DST_R_CRYPTOFAILURE);
aa23a35d81a9618a40c4a9b44be48009553e4777Andreas Gustafsson
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh));
df925e6c66d45d960fbac0383169763967d2111cEvan Hunt if (dh == NULL)
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson DST_RET(ISC_R_NOMEMORY);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson memset(dh, 0, sizeof(*dh));
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson key->keydata.pkey = dh;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson if (dh->repr == NULL)
aa23a35d81a9618a40c4a9b44be48009553e4777Andreas Gustafsson DST_RET(ISC_R_NOMEMORY);
e7220c9b841bbd3d16736726f786a86fec3c0e18Evan Hunt memset(dh->repr, 0, sizeof(*attr) * 4);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson dh->attrcnt = 4;
e7220c9b841bbd3d16736726f786a86fec3c0e18Evan Hunt
aa23a35d81a9618a40c4a9b44be48009553e4777Andreas Gustafsson attr = dh->repr;
aa23a35d81a9618a40c4a9b44be48009553e4777Andreas Gustafsson attr[0].type = CKA_PRIME;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson attr[0].pValue = pubTemplate[4].pValue;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson attr[0].ulValueLen = pubTemplate[4].ulValueLen;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson pubTemplate[4].pValue = NULL;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews attr[1].type = CKA_BASE;
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews attr[1].pValue = pubTemplate[5].pValue;
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews attr[1].ulValueLen = pubTemplate[5].ulValueLen;
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews pubTemplate[5].pValue =NULL;
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews attr += 2;
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews attr->type = CKA_VALUE;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews PK11_RET(pkcs_C_GetAttributeValue,
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews (pk11_ctx->session, pub, attr, 1),
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson DST_R_CRYPTOFAILURE);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt if (attr->pValue == NULL)
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt DST_RET(ISC_R_NOMEMORY);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt memset(attr->pValue, 0, attr->ulValueLen);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt PK11_RET(pkcs_C_GetAttributeValue,
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt (pk11_ctx->session, pub, attr, 1),
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt DST_R_CRYPTOFAILURE);
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt attr++;
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt attr->type = CKA_VALUE;
b0bf1ad5b0b1d29b4cdf5de9789405aec5e0844cEvan Hunt PK11_RET(pkcs_C_GetAttributeValue,
140a27777d6fba397720770b101967d5cf73f42bAutomatic Updater (pk11_ctx->session, priv, attr, 1),
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews DST_R_CRYPTOFAILURE);
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (attr->pValue == NULL)
140a27777d6fba397720770b101967d5cf73f42bAutomatic Updater DST_RET(ISC_R_NOMEMORY);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews memset(attr->pValue, 0, attr->ulValueLen);
140a27777d6fba397720770b101967d5cf73f42bAutomatic Updater PK11_RET(pkcs_C_GetAttributeValue,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews (pk11_ctx->session, priv, attr, 1),
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt DST_R_CRYPTOFAILURE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews attr->type = CKA_VALUE2;
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews (void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pk11_return_session(pk11_ctx);
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt memset(pk11_ctx, 0, sizeof(*pk11_ctx));
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_R_SUCCESS);
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson err:
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt pkcs11dh_destroy(key);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (priv != CK_INVALID_HANDLE)
262c39b2366bf79062f7f86b218947523dd1cbacEvan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews if (pub != CK_INVALID_HANDLE)
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson (void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson if (domainparams != CK_INVALID_HANDLE)
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt if (pubTemplate[4].pValue != NULL) {
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater memset(pubTemplate[4].pValue, 0, pubTemplate[4].ulValueLen);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt isc_mem_put(key->mctx,
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt pubTemplate[4].pValue,
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt pubTemplate[4].ulValueLen);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt }
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson if (pubTemplate[5].pValue != NULL) {
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews memset(pubTemplate[5].pValue, 0, pubTemplate[5].ulValueLen);
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson isc_mem_put(key->mctx,
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews pubTemplate[5].pValue,
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews pubTemplate[5].ulValueLen);
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews }
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews if (pTemplate[0].pValue != NULL) {
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews isc_mem_put(key->mctx,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pTemplate[0].pValue,
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews pTemplate[0].ulValueLen);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews }
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews if (pTemplate[1].pValue != NULL) {
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews isc_mem_put(key->mctx,
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews pTemplate[1].pValue,
69f3cb5abcb38f105c653c7b3df7cec33b87b292Mark Andrews pTemplate[1].ulValueLen);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews }
501941f0b6cce74c2ff75b10aff3f230d5d37e4cEvan Hunt
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater pk11_return_session(pk11_ctx);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews memset(pk11_ctx, 0, sizeof(*pk11_ctx));
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson return (ret);
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson}
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafssonstatic isc_boolean_t
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafssonpkcs11dh_isprivate(const dst_key_t *key) {
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson pk11_object_t *dh = key->keydata.pkey;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews CK_ATTRIBUTE *attr;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson if (dh == NULL)
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson return (ISC_FALSE);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews attr = pk11_attribute_bytype(dh, CKA_VALUE2);
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews return (ISC_TF((attr != NULL) || dh->ontoken));
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews}
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Huntstatic void
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrewspkcs11dh_destroy(dst_key_t *key) {
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson pk11_object_t *dh = key->keydata.pkey;
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson CK_ATTRIBUTE *attr;
604419a812b491cd35fb6fad129c3c39da7200a1Mark Andrews
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson if (dh == NULL)
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson return;
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson INSIST((dh->object == CK_INVALID_HANDLE) || dh->ontoken);
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson for (attr = pk11_attribute_first(dh);
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson attr != NULL;
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson attr = pk11_attribute_next(dh, attr))
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson switch (attr->type) {
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt case CKA_VALUE:
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt case CKA_VALUE2:
c7e266b7e5675e12d1ca3cc929f24b3e86d41f8eEvan Hunt case CKA_PRIME:
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson case CKA_BASE:
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if (attr->pValue != NULL) {
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson memset(attr->pValue, 0, attr->ulValueLen);
e7220c9b841bbd3d16736726f786a86fec3c0e18Evan Hunt isc_mem_put(key->mctx,
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson attr->pValue,
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson attr->ulValueLen);
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson }
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson break;
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson }
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson if (dh->repr != NULL) {
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson memset(dh->repr, 0, dh->attrcnt * sizeof(*attr));
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson isc_mem_put(key->mctx, dh->repr, dh->attrcnt * sizeof(*attr));
6eccf5bd07eb9abf65cc08fec4a8fc97b62c0e1bBrian Wellington }
501941f0b6cce74c2ff75b10aff3f230d5d37e4cEvan Hunt memset(dh, 0, sizeof(*dh));
501941f0b6cce74c2ff75b10aff3f230d5d37e4cEvan Hunt isc_mem_put(key->mctx, dh, sizeof(*dh));
501941f0b6cce74c2ff75b10aff3f230d5d37e4cEvan Hunt key->keydata.pkey = NULL;
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson}
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafssonstatic void
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafssonuint16_toregion(isc_uint16_t val, isc_region_t *region) {
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson *region->base = (val & 0xff00) >> 8;
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson isc_region_consume(region, 1);
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson *region->base = (val & 0x00ff);
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson isc_region_consume(region, 1);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence}
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafssonstatic isc_uint16_t
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafssonuint16_fromregion(isc_region_t *region) {
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson isc_uint16_t val;
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson unsigned char *cp = region->base;
6eccf5bd07eb9abf65cc08fec4a8fc97b62c0e1bBrian Wellington
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson val = ((unsigned int)(cp[0])) << 8;
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson val |= ((unsigned int)(cp[1]));
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence isc_region_consume(region, 2);
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson return (val);
a1747570262ed336c213aaf6bd31bc91993a46deAndreas Gustafsson}
static isc_result_t
pkcs11dh_todns(const dst_key_t *key, isc_buffer_t *data) {
pk11_object_t *dh;
CK_ATTRIBUTE *attr;
isc_region_t r;
isc_uint16_t dnslen, plen = 0, glen = 0, publen = 0;
CK_BYTE *prime = NULL, *base = NULL, *pub = NULL;
REQUIRE(key->keydata.pkey != NULL);
dh = key->keydata.pkey;
for (attr = pk11_attribute_first(dh);
attr != NULL;
attr = pk11_attribute_next(dh, attr))
switch (attr->type) {
case CKA_VALUE:
pub = (CK_BYTE *) attr->pValue;
publen = (isc_uint16_t) attr->ulValueLen;
break;
case CKA_PRIME:
prime = (CK_BYTE *) attr->pValue;
plen = (isc_uint16_t) attr->ulValueLen;
break;
case CKA_BASE:
base = (CK_BYTE *) attr->pValue;
glen = (isc_uint16_t) attr->ulValueLen;
break;
}
REQUIRE((prime != NULL) && (base != NULL) && (pub != NULL));
isc_buffer_availableregion(data, &r);
if ((glen == 1) && (memcmp(pk11_dh_bn2, base, glen) == 0) &&
(((plen == sizeof(pk11_dh_bn768)) &&
(memcmp(pk11_dh_bn768, prime, plen) == 0)) ||
((plen == sizeof(pk11_dh_bn1024)) &&
(memcmp(pk11_dh_bn1024, prime, plen) == 0)) ||
((plen == sizeof(pk11_dh_bn1536)) &&
(memcmp(pk11_dh_bn1536, prime, plen) == 0)))) {
plen = 1;
glen = 0;
}
dnslen = plen + glen + publen + 6;
if (r.length < (unsigned int) dnslen)
return (ISC_R_NOSPACE);
uint16_toregion(plen, &r);
if (plen == 1) {
if (memcmp(pk11_dh_bn768, prime, sizeof(pk11_dh_bn768)) == 0)
*r.base = 1;
else if (memcmp(pk11_dh_bn1024, prime,
sizeof(pk11_dh_bn1024)) == 0)
*r.base = 2;
else
*r.base = 3;
}
else
memmove(r.base, prime, plen);
isc_region_consume(&r, plen);
uint16_toregion(glen, &r);
if (glen > 0)
memmove(r.base, base, glen);
isc_region_consume(&r, glen);
uint16_toregion(publen, &r);
memmove(r.base, pub, publen);
isc_region_consume(&r, publen);
isc_buffer_add(data, dnslen);
return (ISC_R_SUCCESS);
}
static isc_result_t
pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) {
pk11_object_t *dh;
isc_region_t r;
isc_uint16_t plen, glen, plen_, glen_, publen;
CK_BYTE *prime = NULL, *base = NULL, *pub = NULL;
CK_ATTRIBUTE *attr;
int special = 0;
isc_buffer_remainingregion(data, &r);
if (r.length == 0)
return (ISC_R_SUCCESS);
dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh));
if (dh == NULL)
return (ISC_R_NOMEMORY);
memset(dh, 0, sizeof(*dh));
/*
* Read the prime length. 1 & 2 are table entries, > 16 means a
* prime follows, otherwise an error.
*/
if (r.length < 2) {
memset(dh, 0, sizeof(*dh));
isc_mem_put(key->mctx, dh, sizeof(*dh));
return (DST_R_INVALIDPUBLICKEY);
}
plen = uint16_fromregion(&r);
if (plen < 16 && plen != 1 && plen != 2) {
memset(dh, 0, sizeof(*dh));
isc_mem_put(key->mctx, dh, sizeof(*dh));
return (DST_R_INVALIDPUBLICKEY);
}
if (r.length < plen) {
memset(dh, 0, sizeof(*dh));
isc_mem_put(key->mctx, dh, sizeof(*dh));
return (DST_R_INVALIDPUBLICKEY);
}
plen_ = plen;
if (plen == 1 || plen == 2) {
if (plen == 1) {
special = *r.base;
isc_region_consume(&r, 1);
} else {
special = uint16_fromregion(&r);
}
switch (special) {
case 1:
prime = pk11_dh_bn768;
plen_ = sizeof(pk11_dh_bn768);
break;
case 2:
prime = pk11_dh_bn1024;
plen_ = sizeof(pk11_dh_bn1024);
break;
case 3:
prime = pk11_dh_bn1536;
plen_ = sizeof(pk11_dh_bn1536);
break;
default:
memset(dh, 0, sizeof(*dh));
isc_mem_put(key->mctx, dh, sizeof(*dh));
return (DST_R_INVALIDPUBLICKEY);
}
}
else {
prime = r.base;
isc_region_consume(&r, plen);
}
/*
* Read the generator length. This should be 0 if the prime was
* special, but it might not be. If it's 0 and the prime is not
* special, we have a problem.
*/
if (r.length < 2) {
memset(dh, 0, sizeof(*dh));
isc_mem_put(key->mctx, dh, sizeof(*dh));
return (DST_R_INVALIDPUBLICKEY);
}
glen = uint16_fromregion(&r);
if (r.length < glen) {
memset(dh, 0, sizeof(*dh));
isc_mem_put(key->mctx, dh, sizeof(*dh));
return (DST_R_INVALIDPUBLICKEY);
}
glen_ = glen;
if (special != 0) {
if (glen == 0) {
base = pk11_dh_bn2;
glen_ = sizeof(pk11_dh_bn2);
}
else {
base = r.base;
if (memcmp(base, pk11_dh_bn2, glen) == 0) {
base = pk11_dh_bn2;
glen_ = sizeof(pk11_dh_bn2);
}
else {
memset(dh, 0, sizeof(*dh));
isc_mem_put(key->mctx, dh, sizeof(*dh));
return (DST_R_INVALIDPUBLICKEY);
}
}
}
else {
if (glen == 0) {
memset(dh, 0, sizeof(*dh));
isc_mem_put(key->mctx, dh, sizeof(*dh));
return (DST_R_INVALIDPUBLICKEY);
}
base = r.base;
}
isc_region_consume(&r, glen);
if (r.length < 2) {
memset(dh, 0, sizeof(*dh));
isc_mem_put(key->mctx, dh, sizeof(*dh));
return (DST_R_INVALIDPUBLICKEY);
}
publen = uint16_fromregion(&r);
if (r.length < publen) {
memset(dh, 0, sizeof(*dh));
isc_mem_put(key->mctx, dh, sizeof(*dh));
return (DST_R_INVALIDPUBLICKEY);
}
pub = r.base;
isc_region_consume(&r, publen);
key->key_size = pk11_numbits(prime, plen_);
dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3);
if (dh->repr == NULL)
goto nomemory;
memset(dh->repr, 0, sizeof(*attr) * 3);
dh->attrcnt = 3;
attr = dh->repr;
attr[0].type = CKA_PRIME;
attr[0].pValue = isc_mem_get(key->mctx, plen_);
if (attr[0].pValue == NULL)
goto nomemory;
memmove(attr[0].pValue, prime, plen_);
attr[0].ulValueLen = (CK_ULONG) plen_;
attr[1].type = CKA_BASE;
attr[1].pValue = isc_mem_get(key->mctx, glen_);
if (attr[1].pValue == NULL)
goto nomemory;
memmove(attr[1].pValue, base, glen_);
attr[1].ulValueLen = (CK_ULONG) glen_;
attr[2].type = CKA_VALUE;
attr[2].pValue = isc_mem_get(key->mctx, publen);
if (attr[2].pValue == NULL)
goto nomemory;
memmove(attr[2].pValue, pub, publen);
attr[2].ulValueLen = (CK_ULONG) publen;
isc_buffer_forward(data, plen + glen + publen + 6);
key->keydata.pkey = dh;
return (ISC_R_SUCCESS);
nomemory:
for (attr = pk11_attribute_first(dh);
attr != NULL;
attr = pk11_attribute_next(dh, attr))
switch (attr->type) {
case CKA_VALUE:
case CKA_PRIME:
case CKA_BASE:
if (attr->pValue != NULL) {
memset(attr->pValue, 0, attr->ulValueLen);
isc_mem_put(key->mctx,
attr->pValue,
attr->ulValueLen);
}
break;
}
if (dh->repr != NULL) {
memset(dh->repr, 0, dh->attrcnt * sizeof(*attr));
isc_mem_put(key->mctx, dh->repr, dh->attrcnt * sizeof(*attr));
}
memset(dh, 0, sizeof(*dh));
isc_mem_put(key->mctx, dh, sizeof(*dh));
return (ISC_R_NOMEMORY);
}
static isc_result_t
pkcs11dh_tofile(const dst_key_t *key, const char *directory) {
int i;
pk11_object_t *dh;
CK_ATTRIBUTE *attr;
CK_ATTRIBUTE *prime = NULL, *base = NULL, *pub = NULL, *prv = NULL;
dst_private_t priv;
unsigned char *bufs[4];
isc_result_t result;
if (key->keydata.pkey == NULL)
return (DST_R_NULLKEY);
if (key->external)
return (DST_R_EXTERNALKEY);
dh = key->keydata.pkey;
for (attr = pk11_attribute_first(dh);
attr != NULL;
attr = pk11_attribute_next(dh, attr))
switch (attr->type) {
case CKA_VALUE:
pub = attr;
break;
case CKA_VALUE2:
prv = attr;
break;
case CKA_PRIME:
prime = attr;
break;
case CKA_BASE:
base = attr;
break;
}
if ((prime == NULL) || (base == NULL) ||
(pub == NULL) || (prv == NULL))
return (DST_R_NULLKEY);
memset(bufs, 0, sizeof(bufs));
for (i = 0; i < 4; i++) {
bufs[i] = isc_mem_get(key->mctx, prime->ulValueLen);
if (bufs[i] == NULL) {
result = ISC_R_NOMEMORY;
goto fail;
}
memset(bufs[i], 0, prime->ulValueLen);
}
i = 0;
priv.elements[i].tag = TAG_DH_PRIME;
priv.elements[i].length = (unsigned short) prime->ulValueLen;
memmove(bufs[i], prime->pValue, prime->ulValueLen);
priv.elements[i].data = bufs[i];
i++;
priv.elements[i].tag = TAG_DH_GENERATOR;
priv.elements[i].length = (unsigned short) base->ulValueLen;
memmove(bufs[i], base->pValue, base->ulValueLen);
priv.elements[i].data = bufs[i];
i++;
priv.elements[i].tag = TAG_DH_PRIVATE;
priv.elements[i].length = (unsigned short) prv->ulValueLen;
memmove(bufs[i], prv->pValue, prv->ulValueLen);
priv.elements[i].data = bufs[i];
i++;
priv.elements[i].tag = TAG_DH_PUBLIC;
priv.elements[i].length = (unsigned short) pub->ulValueLen;
memmove(bufs[i], pub->pValue, pub->ulValueLen);
priv.elements[i].data = bufs[i];
i++;
priv.nelements = i;
result = dst__privstruct_writefile(key, &priv, directory);
fail:
for (i = 0; i < 4; i++) {
if (bufs[i] == NULL)
break;
memset(bufs[i], 0, prime->ulValueLen);
isc_mem_put(key->mctx, bufs[i], prime->ulValueLen);
}
return (result);
}
static isc_result_t
pkcs11dh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t ret;
int i;
pk11_object_t *dh = NULL;
CK_ATTRIBUTE *attr;
isc_mem_t *mctx;
UNUSED(pub);
mctx = key->mctx;
/* read private key file */
ret = dst__privstruct_parse(key, DST_ALG_DH, lexer, mctx, &priv);
if (ret != ISC_R_SUCCESS)
return (ret);
if (key->external)
DST_RET(DST_R_EXTERNALKEY);
dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh));
if (dh == NULL)
DST_RET(ISC_R_NOMEMORY);
memset(dh, 0, sizeof(*dh));
key->keydata.pkey = dh;
dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4);
if (dh->repr == NULL)
DST_RET(ISC_R_NOMEMORY);
memset(dh->repr, 0, sizeof(*attr) * 4);
dh->attrcnt = 4;
attr = dh->repr;
attr[0].type = CKA_PRIME;
attr[1].type = CKA_BASE;
attr[2].type = CKA_VALUE;
attr[3].type = CKA_VALUE2;
for (i = 0; i < priv.nelements; i++) {
CK_BYTE *bn;
bn = isc_mem_get(key->mctx, priv.elements[i].length);
if (bn == NULL)
DST_RET(ISC_R_NOMEMORY);
memmove(bn, priv.elements[i].data, priv.elements[i].length);
switch (priv.elements[i].tag) {
case TAG_DH_PRIME:
attr = pk11_attribute_bytype(dh, CKA_PRIME);
INSIST(attr != NULL);
attr->pValue = bn;
attr->ulValueLen = priv.elements[i].length;
break;
case TAG_DH_GENERATOR:
attr = pk11_attribute_bytype(dh, CKA_BASE);
INSIST(attr != NULL);
attr->pValue = bn;
attr->ulValueLen = priv.elements[i].length;
break;
case TAG_DH_PRIVATE:
attr = pk11_attribute_bytype(dh, CKA_VALUE2);
INSIST(attr != NULL);
attr->pValue = bn;
attr->ulValueLen = priv.elements[i].length;
break;
case TAG_DH_PUBLIC:
attr = pk11_attribute_bytype(dh, CKA_VALUE);
INSIST(attr != NULL);
attr->pValue = bn;
attr->ulValueLen = priv.elements[i].length;
break;
}
}
dst__privstruct_free(&priv, mctx);
attr = pk11_attribute_bytype(dh, CKA_PRIME);
INSIST(attr != NULL);
key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
return (ISC_R_SUCCESS);
err:
pkcs11dh_destroy(key);
dst__privstruct_free(&priv, mctx);
memset(&priv, 0, sizeof(priv));
return (ret);
}
static dst_func_t pkcs11dh_functions = {
NULL, /*%< createctx */
NULL, /*%< createctx2 */
NULL, /*%< destroyctx */
NULL, /*%< adddata */
NULL, /*%< sign */
NULL, /*%< verify */
NULL, /*%< verify2 */
pkcs11dh_computesecret,
pkcs11dh_compare,
pkcs11dh_paramcompare,
pkcs11dh_generate,
pkcs11dh_isprivate,
pkcs11dh_destroy,
pkcs11dh_todns,
pkcs11dh_fromdns,
pkcs11dh_tofile,
pkcs11dh_parse,
NULL, /*%< cleanup */
NULL, /*%< fromlabel */
NULL, /*%< dump */
NULL, /*%< restore */
};
isc_result_t
dst__pkcs11dh_init(dst_func_t **funcp) {
REQUIRE(funcp != NULL);
if (*funcp == NULL)
*funcp = &pkcs11dh_functions;
return (ISC_R_SUCCESS);
}
#else /* PKCS11CRYPTO */
#include <isc/util.h>
EMPTY_TRANSLATION_UNIT
#endif /* PKCS11CRYPTO */
/*! \file */