pkcs11dh_link.c revision ce9f893e21d2ffc6f6a78bf226c038c396740aeb
/*
* Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
*
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef PKCS11CRYPTO
#include <config.h>
#include <ctype.h>
#include "dst_internal.h"
#include "dst_parse.h"
#include "dst_pkcs11.h"
#include <pk11/internal.h>
#define WANT_DH_PRIMES
#include <pk11/constants.h>
/*
* PKCS#3 DH keys:
* mechanisms:
* CKM_DH_PKCS_PARAMETER_GEN,
* CKM_DH_PKCS_KEY_PAIR_GEN,
* CKM_DH_PKCS_DERIVE
* domain parameters:
* object class CKO_DOMAIN_PARAMETERS
* key type CKK_DH
* attribute CKA_PRIME (prime p)
* attribute CKA_BASE (base g)
* optional attribute CKA_PRIME_BITS (p length in bits)
* public key:
* object class CKO_PUBLIC_KEY
* key type CKK_DH
* attribute CKA_PRIME (prime p)
* attribute CKA_BASE (base g)
* attribute CKA_VALUE (public value y)
* private key:
* object class CKO_PRIVATE_KEY
* key type CKK_DH
* attribute CKA_PRIME (prime p)
* attribute CKA_BASE (base g)
* attribute CKA_VALUE (private value x)
* optional attribute CKA_VALUE_BITS (x length in bits)
* reuse CKA_PRIVATE_EXPONENT for key pair private value
*/
#define CKA_VALUE2 CKA_PRIVATE_EXPONENT
static isc_result_t
{
{
};
const pk11_object_t *priv;
unsigned int i;
return (ISC_R_SUCCESS);
}
return (DST_R_INVALIDPRIVATEKEY);
ret = ISC_R_SUCCESS;
err:
for (i = 6; i <= 8; i++)
keyTemplate[i].ulValueLen);
keyTemplate[i].pValue,
keyTemplate[i].ulValueLen);
}
return (ret);
}
static isc_result_t
{
{
};
{
};
unsigned int i;
isc_region_t r;
return (DST_R_INVALIDPUBLICKEY);
return (DST_R_INVALIDPUBLICKEY);
if (ret != ISC_R_SUCCESS)
return (ret);
if (ret != ISC_R_SUCCESS)
goto err;
attr = valTemplate;
/* strip leading zeros */
for (i = 0; i < attr->ulValueLen; i++)
if (secValue[i] != 0)
break;
ret = ISC_R_SUCCESS;
err:
if (hDerived != CK_INVALID_HANDLE)
valTemplate[0].pValue,
valTemplate[0].ulValueLen);
}
}
return (ret);
}
static isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
}
static isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
}
static isc_result_t
{
};
{
};
{
};
{
};
sizeof(*pk11_ctx));
return (ISC_R_NOMEMORY);
if (ret != ISC_R_SUCCESS)
goto err;
if ((generator == 0) &&
if (bits == 768) {
pk11_dh_bn768, sizeof(pk11_dh_bn768));
} else if (bits == 1024) {
pk11_dh_bn1024, sizeof(pk11_dh_bn1024));
} else {
pk11_dh_bn1536, sizeof(pk11_dh_bn1536));
}
sizeof(pk11_dh_bn2));
sizeof(pk11_dh_bn2));
} else {
pTemplate[0].ulValueLen);
}
attr += 2;
attr++;
return (ISC_R_SUCCESS);
err:
if (priv != CK_INVALID_HANDLE)
if (pub != CK_INVALID_HANDLE)
if (domainparams != CK_INVALID_HANDLE)
}
}
pTemplate[0].ulValueLen);
}
}
return (ret);
}
static isc_boolean_t
return (ISC_FALSE);
}
static void
return;
case CKA_VALUE:
case CKA_VALUE2:
case CKA_PRIME:
case CKA_BASE:
attr->ulValueLen);
}
break;
}
}
}
static void
}
static isc_uint16_t
return (val);
}
static isc_result_t
isc_region_t r;
case CKA_VALUE:
break;
case CKA_PRIME:
break;
case CKA_BASE:
break;
}
(((plen == sizeof(pk11_dh_bn768)) &&
((plen == sizeof(pk11_dh_bn1024)) &&
((plen == sizeof(pk11_dh_bn1536)) &&
plen = 1;
glen = 0;
}
return (ISC_R_NOSPACE);
uint16_toregion(plen, &r);
if (plen == 1) {
*r.base = 1;
sizeof(pk11_dh_bn1024)) == 0)
*r.base = 2;
else
*r.base = 3;
}
else
isc_region_consume(&r, plen);
uint16_toregion(glen, &r);
if (glen > 0)
isc_region_consume(&r, glen);
uint16_toregion(publen, &r);
isc_region_consume(&r, publen);
return (ISC_R_SUCCESS);
}
static isc_result_t
isc_region_t r;
int special = 0;
if (r.length == 0)
return (ISC_R_SUCCESS);
return (ISC_R_NOMEMORY);
/*
* Read the prime length. 1 & 2 are table entries, > 16 means a
* prime follows, otherwise an error.
*/
if (r.length < 2) {
return (DST_R_INVALIDPUBLICKEY);
}
plen = uint16_fromregion(&r);
return (DST_R_INVALIDPUBLICKEY);
}
return (DST_R_INVALIDPUBLICKEY);
}
if (plen == 1) {
isc_region_consume(&r, 1);
} else {
special = uint16_fromregion(&r);
}
switch (special) {
case 1:
plen_ = sizeof(pk11_dh_bn768);
break;
case 2:
plen_ = sizeof(pk11_dh_bn1024);
break;
case 3:
plen_ = sizeof(pk11_dh_bn1536);
break;
default:
return (DST_R_INVALIDPUBLICKEY);
}
}
else {
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) {
return (DST_R_INVALIDPUBLICKEY);
}
glen = uint16_fromregion(&r);
return (DST_R_INVALIDPUBLICKEY);
}
if (special != 0) {
if (glen == 0) {
base = pk11_dh_bn2;
glen_ = sizeof(pk11_dh_bn2);
}
else {
base = pk11_dh_bn2;
glen_ = sizeof(pk11_dh_bn2);
}
else {
return (DST_R_INVALIDPUBLICKEY);
}
}
}
else {
if (glen == 0) {
return (DST_R_INVALIDPUBLICKEY);
}
}
isc_region_consume(&r, glen);
if (r.length < 2) {
return (DST_R_INVALIDPUBLICKEY);
}
publen = uint16_fromregion(&r);
return (DST_R_INVALIDPUBLICKEY);
}
isc_region_consume(&r, publen);
goto nomemory;
goto nomemory;
goto nomemory;
goto nomemory;
return (ISC_R_SUCCESS);
case CKA_VALUE:
case CKA_PRIME:
case CKA_BASE:
attr->ulValueLen);
}
break;
}
}
return (ISC_R_NOMEMORY);
}
static isc_result_t
int i;
unsigned char *bufs[4];
return (DST_R_NULLKEY);
return (DST_R_EXTERNALKEY);
case CKA_VALUE:
break;
case CKA_VALUE2:
break;
case CKA_PRIME:
break;
case CKA_BASE:
break;
}
return (DST_R_NULLKEY);
for (i = 0; i < 4; i++) {
goto fail;
}
}
i = 0;
i++;
i++;
i++;
i++;
fail:
for (i = 0; i < 4; i++) {
break;
}
return (result);
}
static isc_result_t
int i;
/* read private key file */
if (ret != ISC_R_SUCCESS)
return (ret);
case TAG_DH_PRIME:
break;
case TAG_DH_GENERATOR:
break;
case TAG_DH_PRIVATE:
break;
case TAG_DH_PUBLIC:
break;
}
}
return (ISC_R_SUCCESS);
err:
return (ret);
}
static dst_func_t pkcs11dh_functions = {
NULL, /*%< createctx */
NULL, /*%< createctx2 */
NULL, /*%< destroyctx */
NULL, /*%< adddata */
NULL, /*%< sign */
NULL, /*%< verify */
NULL, /*%< verify2 */
NULL, /*%< cleanup */
NULL, /*%< fromlabel */
NULL, /*%< dump */
NULL, /*%< restore */
};
*funcp = &pkcs11dh_functions;
return (ISC_R_SUCCESS);
}
#else /* PKCS11CRYPTO */
#endif /* PKCS11CRYPTO */
/*! \file */