/*
* Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifdef PKCS11CRYPTO
#include <config.h>
#include "dst_internal.h"
#include "dst_parse.h"
#include "dst_pkcs11.h"
#include <pk11/internal.h>
/*
* Limit the size of public exponents.
*/
#ifndef RSA_MAX_PUBEXP_BITS
#endif
#ifndef PK11_RSA_PKCS_REPLACE
static isc_result_t
{
{ CKA_MODULUS, NULL, 0 },
{ CKA_PUBLIC_EXPONENT, NULL, 0 },
{ CKA_PRIVATE_EXPONENT, NULL, 0 },
{ CKA_PRIME_1, NULL, 0 },
{ CKA_PRIME_2, NULL, 0 },
{ CKA_EXPONENT_1, NULL, 0 },
{ CKA_EXPONENT_2, NULL, 0 },
{ CKA_COEFFICIENT, NULL, 0 }
};
unsigned int i;
#ifndef PK11_MD5_DISABLE
#else
#endif
/*
* Reject incorrect RSA key lengths.
*/
case DST_ALG_RSAMD5:
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
/* From RFC 3110 */
return (ISC_R_FAILURE);
break;
case DST_ALG_RSASHA256:
/* From RFC 5702 */
return (ISC_R_FAILURE);
break;
case DST_ALG_RSASHA512:
/* From RFC 5702 */
return (ISC_R_FAILURE);
break;
default:
INSIST(0);
}
sizeof(*pk11_ctx));
return (ISC_R_NOMEMORY);
else
if (ret != ISC_R_SUCCESS)
goto err;
goto token_key;
}
case CKA_MODULUS:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_PUBLIC_EXPONENT:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_PRIVATE_EXPONENT:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_PRIME_1:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_PRIME_2:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_EXPONENT_1:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_EXPONENT_2:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_COEFFICIENT:
attr->ulValueLen);
attr->ulValueLen);
break;
}
#ifndef PK11_MD5_DISABLE
case DST_ALG_RSAMD5:
break;
#endif
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
break;
case DST_ALG_RSASHA256:
break;
case DST_ALG_RSASHA512:
break;
default:
INSIST(0);
}
for (i = 6; i <= 13; i++)
keyTemplate[i].ulValueLen);
keyTemplate[i].pValue,
keyTemplate[i].ulValueLen);
}
return (ISC_R_SUCCESS);
err:
for (i = 6; i <= 13; i++)
keyTemplate[i].ulValueLen);
keyTemplate[i].pValue,
keyTemplate[i].ulValueLen);
}
return (ret);
}
static isc_result_t
dst_context_t *dctx) {
{
{ CKA_MODULUS, NULL, 0 },
{ CKA_PUBLIC_EXPONENT, NULL, 0 },
};
unsigned int i;
#ifndef PK11_MD5_DISABLE
#else
#endif
/*
* Reject incorrect RSA key lengths.
*/
case DST_ALG_RSAMD5:
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
/* From RFC 3110 */
return (ISC_R_FAILURE);
break;
case DST_ALG_RSASHA256:
/* From RFC 5702 */
return (ISC_R_FAILURE);
break;
case DST_ALG_RSASHA512:
/* From RFC 5702 */
return (ISC_R_FAILURE);
break;
default:
INSIST(0);
}
sizeof(*pk11_ctx));
return (ISC_R_NOMEMORY);
if (ret != ISC_R_SUCCESS)
goto err;
case CKA_MODULUS:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_PUBLIC_EXPONENT:
attr->ulValueLen);
attr->ulValueLen);
maxbits != 0)
break;
}
#ifndef PK11_MD5_DISABLE
case DST_ALG_RSAMD5:
break;
#endif
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
break;
case DST_ALG_RSASHA256:
break;
case DST_ALG_RSASHA512:
break;
default:
INSIST(0);
}
for (i = 5; i <= 6; i++)
keyTemplate[i].ulValueLen);
keyTemplate[i].pValue,
keyTemplate[i].ulValueLen);
}
return (ISC_R_SUCCESS);
err:
for (i = 5; i <= 6; i++)
keyTemplate[i].ulValueLen);
keyTemplate[i].pValue,
keyTemplate[i].ulValueLen);
}
return (ret);
}
static isc_result_t
else
}
static isc_result_t
else
return (pkcs11rsa_createctx_verify(key,
}
static void
}
}
static isc_result_t
else
return (ret);
}
static isc_result_t
isc_region_t r;
return (ISC_R_NOSPACE);
err:
return (ret);
}
static isc_result_t
return (ret);
}
#else
/*
* CKM_<hash>_RSA_PKCS mechanisms are not available so fall back
* to CKM_RSA_PKCS and do the EMSA-PKCS#1-v1.5 encapsulation by hand.
*/
{ 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00,
0x04, 0x10 };
{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
{ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
0x00, 0x04, 0x20 };
{ 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
0x00, 0x04, 0x40 };
static isc_result_t
#ifndef PK11_MD5_DISABLE
#else
#endif
/*
* Reject incorrect RSA key lengths.
*/
case DST_ALG_RSAMD5:
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
/* From RFC 3110 */
return (ISC_R_FAILURE);
break;
case DST_ALG_RSASHA256:
/* From RFC 5702 */
return (ISC_R_FAILURE);
break;
case DST_ALG_RSASHA512:
/* From RFC 5702 */
return (ISC_R_FAILURE);
break;
default:
INSIST(0);
}
#ifndef PK11_MD5_DISABLE
case DST_ALG_RSAMD5:
break;
#endif
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
break;
case DST_ALG_RSASHA256:
break;
case DST_ALG_RSASHA512:
break;
default:
INSIST(0);
}
sizeof(*pk11_ctx));
return (ISC_R_NOMEMORY);
else
if (ret != ISC_R_SUCCESS)
goto err;
return (ISC_R_SUCCESS);
err:
return (ret);
}
static void
}
}
static isc_result_t
return (ret);
}
static isc_result_t
{
{ CKA_MODULUS, NULL, 0 },
{ CKA_PUBLIC_EXPONENT, NULL, 0 },
{ CKA_PRIVATE_EXPONENT, NULL, 0 },
{ CKA_PRIME_1, NULL, 0 },
{ CKA_PRIME_2, NULL, 0 },
{ CKA_EXPONENT_1, NULL, 0 },
{ CKA_EXPONENT_2, NULL, 0 },
{ CKA_COEFFICIENT, NULL, 0 }
};
isc_region_t r;
unsigned int i;
#ifndef PK11_MD5_DISABLE
#else
#endif
/*
* Reject incorrect RSA key lengths.
*/
case DST_ALG_RSAMD5:
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
/* From RFC 3110 */
return (ISC_R_FAILURE);
break;
case DST_ALG_RSASHA256:
/* From RFC 5702 */
return (ISC_R_FAILURE);
break;
case DST_ALG_RSASHA512:
/* From RFC 5702 */
return (ISC_R_FAILURE);
break;
default:
INSIST(0);
}
#ifndef PK11_MD5_DISABLE
case DST_ALG_RSAMD5:
break;
#endif
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
break;
case DST_ALG_RSASHA256:
der = sha256_der;
derlen = sizeof(sha256_der);
break;
case DST_ALG_RSASHA512:
der = sha512_der;
derlen = sizeof(sha512_der);
break;
default:
INSIST(0);
}
return (ISC_R_NOSPACE);
goto token_key;
}
case CKA_MODULUS:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_PUBLIC_EXPONENT:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_PRIVATE_EXPONENT:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_PRIME_1:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_PRIME_2:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_EXPONENT_1:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_EXPONENT_2:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_COEFFICIENT:
attr->ulValueLen);
attr->ulValueLen);
break;
}
&hKey),
return (ISC_R_NOSPACE);
err:
if (hKey != CK_INVALID_HANDLE)
for (i = 6; i <= 13; i++)
keyTemplate[i].ulValueLen);
keyTemplate[i].pValue,
keyTemplate[i].ulValueLen);
}
return (ret);
}
static isc_result_t
{
{ CKA_MODULUS, NULL, 0 },
{ CKA_PUBLIC_EXPONENT, NULL, 0 },
};
unsigned int i;
#ifndef PK11_MD5_DISABLE
#else
#endif
#ifndef PK11_MD5_DISABLE
case DST_ALG_RSAMD5:
break;
#endif
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
break;
case DST_ALG_RSASHA256:
der = sha256_der;
derlen = sizeof(sha256_der);
break;
case DST_ALG_RSASHA512:
der = sha512_der;
derlen = sizeof(sha512_der);
break;
default:
INSIST(0);
}
case CKA_MODULUS:
attr->ulValueLen);
attr->ulValueLen);
break;
case CKA_PUBLIC_EXPONENT:
attr->ulValueLen);
attr->ulValueLen);
break;
}
&hKey),
err:
if (hKey != CK_INVALID_HANDLE)
for (i = 5; i <= 6; i++)
keyTemplate[i].ulValueLen);
keyTemplate[i].pValue,
keyTemplate[i].ulValueLen);
}
return (ret);
}
#endif
static isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
attr1->ulValueLen))
return (ISC_FALSE);
return (ISC_TRUE);
attr1->ulValueLen))
return (ISC_FALSE);
attr1->ulValueLen)))
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
}
static isc_result_t
{
};
{
};
unsigned int i;
/*
* Reject incorrect RSA key lengths.
*/
case DST_ALG_RSAMD5:
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
/* From RFC 3110 */
return (ISC_R_FAILURE);
break;
case DST_ALG_RSASHA256:
/* From RFC 5702 */
return (ISC_R_FAILURE);
break;
case DST_ALG_RSASHA512:
/* From RFC 5702 */
return (ISC_R_FAILURE);
break;
default:
INSIST(0);
}
sizeof(*pk11_ctx));
return (ISC_R_NOMEMORY);
if (ret != ISC_R_SUCCESS)
goto err;
if (exp == 0) {
/* RSA_F4 0x10001 */
pubexp[0] = 1;
pubexp[1] = 0;
} else {
/* F5 0x100000001 */
pubexp[0] = 1;
pubexp[1] = 0;
pubexp[2] = 0;
pubexp[3] = 0;
}
for (i = 0; i <= 1; i++) {
}
attr += 2;
for (i = 0; i <= 5; i++) {
}
return (ISC_R_SUCCESS);
err:
if (priv != CK_INVALID_HANDLE)
if (pub != CK_INVALID_HANDLE)
return (ret);
}
static isc_boolean_t
return (ISC_FALSE);
}
static void
return;
case CKA_LABEL:
case CKA_ID:
case CKA_MODULUS:
case CKA_PUBLIC_EXPONENT:
case CKA_PRIVATE_EXPONENT:
case CKA_PRIME_1:
case CKA_PRIME_2:
case CKA_EXPONENT_1:
case CKA_EXPONENT_2:
case CKA_COEFFICIENT:
attr->ulValueLen);
attr->ulValueLen);
}
break;
}
}
}
static isc_result_t
isc_region_t r;
case CKA_PUBLIC_EXPONENT:
break;
case CKA_MODULUS:
break;
}
if (r.length < 1)
return (ISC_R_NOSPACE);
isc_region_consume(&r, 1);
} else {
if (r.length < 3)
return (ISC_R_NOSPACE);
isc_buffer_putuint8(data, 0);
isc_region_consume(&r, 3);
}
return (ISC_R_NOSPACE);
isc_region_consume(&r, e_bytes);
return (ISC_R_SUCCESS);
}
static isc_result_t
isc_region_t r;
unsigned int length;
if (r.length == 0)
return (ISC_R_SUCCESS);
return (ISC_R_NOMEMORY);
isc_region_consume(&r, 1);
if (e_bytes == 0) {
if (r.length < 2) {
return (DST_R_INVALIDPUBLICKEY);
}
isc_region_consume(&r, 1);
isc_region_consume(&r, 1);
}
return (DST_R_INVALIDPUBLICKEY);
}
isc_region_consume(&r, e_bytes);
goto nomemory;
goto nomemory;
goto nomemory;
return (ISC_R_SUCCESS);
case CKA_MODULUS:
case CKA_PUBLIC_EXPONENT:
attr->ulValueLen);
attr->ulValueLen);
}
break;
}
}
return (ISC_R_NOMEMORY);
}
static isc_result_t
int i;
return (DST_R_NULLKEY);
}
case CKA_MODULUS:
break;
case CKA_PUBLIC_EXPONENT:
break;
case CKA_PRIVATE_EXPONENT:
d = attr;
break;
case CKA_PRIME_1:
p = attr;
break;
case CKA_PRIME_2:
q = attr;
break;
case CKA_EXPONENT_1:
break;
case CKA_EXPONENT_2:
break;
case CKA_COEFFICIENT:
break;
}
return (DST_R_NULLKEY);
for (i = 0; i < 10; i++) {
goto fail;
}
}
i = 0;
i++;
i++;
if (d != NULL) {
i++;
}
if (p != NULL) {
i++;
}
if (q != NULL) {
i++;
}
i++;
}
i++;
}
i++;
}
i++;
}
i++;
}
fail:
for (i = 0; i < 10; i++) {
break;
}
return (result);
}
static isc_result_t
{
{
};
return (DST_R_NOENGINE);
return (ISC_R_NOMEMORY);
attr++;
if (ret != ISC_R_SUCCESS)
goto err;
sizeof(*pk11_ctx));
if (ret != ISC_R_SUCCESS)
goto err;
}
if (cnt == 0)
if (cnt > 1)
}
return (ISC_R_SUCCESS);
err:
}
return (ret);
}
static isc_result_t
if (priv_explen != pub_explen)
return (DST_R_INVALIDPRIVATEKEY);
return (DST_R_INVALIDPRIVATEKEY);
} else {
pubattr->ulValueLen = 0;
}
return (DST_R_INVALIDPRIVATEKEY);
if (priv_modlen != pub_modlen)
return (DST_R_INVALIDPRIVATEKEY);
return (DST_R_INVALIDPRIVATEKEY);
} else {
pubattr->ulValueLen = 0;
}
return (DST_R_INVALIDPRIVATEKEY);
return (ISC_R_SUCCESS);
}
static isc_result_t
int i;
/* read private key file */
if (ret != ISC_R_SUCCESS)
return (ret);
return (ISC_R_SUCCESS);
}
case TAG_RSA_ENGINE:
break;
case TAG_RSA_LABEL:
break;
default:
break;
}
}
/* Is this key is stored in a HSM? See if we can fetch it. */
if (ret != ISC_R_SUCCESS)
goto err;
return (ret);
}
case TAG_RSA_ENGINE:
continue;
case TAG_RSA_LABEL:
continue;
default:
}
case TAG_RSA_MODULUS:
break;
case TAG_RSA_PUBLICEXPONENT:
break;
case TAG_RSA_PRIVATEEXPONENT:
break;
case TAG_RSA_PRIME1:
break;
case TAG_RSA_PRIME2:
break;
case TAG_RSA_EXPONENT1:
break;
case TAG_RSA_EXPONENT2:
break;
case TAG_RSA_COEFFICIENT:
break;
}
}
return (ISC_R_SUCCESS);
err:
return (ret);
}
static isc_result_t
const char *pin)
{
{
};
unsigned int i;
return (ISC_R_NOMEMORY);
if (ret != ISC_R_SUCCESS)
goto err;
sizeof(*pk11_ctx));
if (ret != ISC_R_SUCCESS)
goto err;
}
if (cnt == 0)
if (cnt > 1)
for (i = 0; i <= 1; i++) {
}
if (cnt == 0)
if (cnt > 1)
}
return (ISC_R_SUCCESS);
err:
}
return (ret);
}
#ifndef PK11_RSA_PKCS_REPLACE
#else
NULL, /*%< createctx2 */
#endif
NULL, /*%< verify2 */
NULL, /*%< computesecret */
NULL, /*%< paramcompare */
NULL, /*%< cleanup */
NULL, /*%< dump */
NULL, /*%< restore */
};
*funcp = &pkcs11rsa_functions;
return (ISC_R_SUCCESS);
}
#else /* PKCS11CRYPTO */
#endif /* PKCS11CRYPTO */
/*! \file */