mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 19:24:42 +02:00
Initial implementation for using PKCS11 to retrieve certificate for SSL CTX
This commit is contained in:
@@ -4146,6 +4146,84 @@ int wolfSSL_CTX_use_AltPrivateKey_Label(WOLFSSL_CTX* ctx, const char* label,
|
|||||||
#endif /* WOLFSSL_DUAL_ALG_CERTS */
|
#endif /* WOLFSSL_DUAL_ALG_CERTS */
|
||||||
#endif /* WOLF_PRIVATE_KEY_ID */
|
#endif /* WOLF_PRIVATE_KEY_ID */
|
||||||
|
|
||||||
|
#if defined(WOLF_CRYPTO_CB) && !defined(NO_CERTS)
|
||||||
|
|
||||||
|
static int wolfSSL_CTX_use_certificate_ex(WOLFSSL_CTX* ctx,
|
||||||
|
const char *label, const unsigned char *id, int idLen, int devId);
|
||||||
|
|
||||||
|
static int wolfSSL_CTX_use_certificate_ex(WOLFSSL_CTX* ctx,
|
||||||
|
const char *label, const unsigned char *id, int idLen, int devId)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
byte *certData = NULL;
|
||||||
|
word32 certDataLen = 0;
|
||||||
|
word32 labelLen = 0;
|
||||||
|
|
||||||
|
WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_label_ex");
|
||||||
|
|
||||||
|
if (label != NULL) {
|
||||||
|
labelLen = (word32)XSTRLEN(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = wc_CryptoCb_GetCert(devId, (const sword8 *)label,
|
||||||
|
labelLen, id, idLen, &certData, &certDataLen, ctx->heap);
|
||||||
|
if (ret != 0) {
|
||||||
|
ret = WOLFSSL_FAILURE;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ProcessBuffer(ctx, certData, certDataLen, WOLFSSL_FILETYPE_ASN1,
|
||||||
|
CERT_TYPE, NULL, NULL, 0, GET_VERIFY_SETTING_CTX(ctx));
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (certData != NULL) {
|
||||||
|
XFREE(certData, ctx->heap, DYNAMIC_TYPE_CERT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the label name of a certificate into the SSL context.
|
||||||
|
*
|
||||||
|
* @param [in, out] ctx SSL context object.
|
||||||
|
* @param [in] label Buffer holding label.
|
||||||
|
* @param [in] devId Device identifier.
|
||||||
|
* @return 1 on success.
|
||||||
|
* @return 0 on failure.
|
||||||
|
*/
|
||||||
|
int wolfSSL_CTX_use_certificate_label(WOLFSSL_CTX* ctx,
|
||||||
|
const char *label, int devId)
|
||||||
|
{
|
||||||
|
if ((ctx == NULL) || (label == NULL)) {
|
||||||
|
WOLFSSL_MSG("Bad Argument");
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wolfSSL_CTX_use_certificate_ex(ctx, label, NULL, 0, devId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the id of a certificate into SSL context.
|
||||||
|
*
|
||||||
|
* @param [in, out] ctx SSL context object.
|
||||||
|
* @param [in] id Buffer holding id.
|
||||||
|
* @param [in] idLen Size of data in bytes.
|
||||||
|
* @param [in] devId Device identifier.
|
||||||
|
* @return 1 on success.
|
||||||
|
* @return 0 on failure.
|
||||||
|
*/
|
||||||
|
int wolfSSL_CTX_use_certificate_id(WOLFSSL_CTX* ctx,
|
||||||
|
const unsigned char *id, int idLen, int devId)
|
||||||
|
{
|
||||||
|
if ((ctx == NULL) || (id == NULL) || (idLen <= 0)) {
|
||||||
|
WOLFSSL_MSG("Bad Argument");
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wolfSSL_CTX_use_certificate_ex(ctx, NULL, id, idLen, devId);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* if defined(WOLF_CRYPTO_CB) && !defined(NO_CERTS) */
|
||||||
|
|
||||||
/* Load a certificate chain in a buffer into SSL context.
|
/* Load a certificate chain in a buffer into SSL context.
|
||||||
*
|
*
|
||||||
* @param [in, out] ctx SSL context object.
|
* @param [in, out] ctx SSL context object.
|
||||||
|
@@ -85,6 +85,7 @@ static const char* GetAlgoTypeStr(int algo)
|
|||||||
case WC_ALGO_TYPE_SEED: return "Seed";
|
case WC_ALGO_TYPE_SEED: return "Seed";
|
||||||
case WC_ALGO_TYPE_HMAC: return "HMAC";
|
case WC_ALGO_TYPE_HMAC: return "HMAC";
|
||||||
case WC_ALGO_TYPE_CMAC: return "CMAC";
|
case WC_ALGO_TYPE_CMAC: return "CMAC";
|
||||||
|
case WC_ALGO_TYPE_CERT: return "Cert";
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -1799,6 +1800,36 @@ int wc_CryptoCb_RandomSeed(OS_Seed* os, byte* seed, word32 sz)
|
|||||||
}
|
}
|
||||||
#endif /* !WC_NO_RNG */
|
#endif /* !WC_NO_RNG */
|
||||||
|
|
||||||
|
#ifndef NO_CERTS
|
||||||
|
int wc_CryptoCb_GetCert(int devId, const sword8 *label, word32 labelLen,
|
||||||
|
const byte *id, word32 idLen, byte** out,
|
||||||
|
word32* outSz, void *heap)
|
||||||
|
{
|
||||||
|
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||||
|
CryptoCb* dev;
|
||||||
|
|
||||||
|
/* locate registered callback */
|
||||||
|
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_CERT);
|
||||||
|
if (dev && dev->cb) {
|
||||||
|
wc_CryptoInfo cryptoInfo;
|
||||||
|
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
|
||||||
|
cryptoInfo.algo_type = WC_ALGO_TYPE_CERT;
|
||||||
|
cryptoInfo.cert.label = label;
|
||||||
|
cryptoInfo.cert.labelLen = labelLen;
|
||||||
|
cryptoInfo.cert.id = id;
|
||||||
|
cryptoInfo.cert.idLen = idLen;
|
||||||
|
cryptoInfo.cert.heap = heap;
|
||||||
|
cryptoInfo.cert.certDataOut = out;
|
||||||
|
cryptoInfo.cert.certSz = outSz;
|
||||||
|
cryptoInfo.cert.heap = heap;
|
||||||
|
|
||||||
|
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return wc_CryptoCb_TranslateErrorCode(ret);
|
||||||
|
}
|
||||||
|
#endif /* ifndef NO_CERTS */
|
||||||
|
|
||||||
#if defined(WOLFSSL_CMAC)
|
#if defined(WOLFSSL_CMAC)
|
||||||
int wc_CryptoCb_Cmac(Cmac* cmac, const byte* key, word32 keySz,
|
int wc_CryptoCb_Cmac(Cmac* cmac, const byte* key, word32 keySz,
|
||||||
const byte* in, word32 inSz, byte* out, word32* outSz, int type,
|
const byte* in, word32 inSz, byte* out, word32* outSz, int type,
|
||||||
|
@@ -108,6 +108,8 @@ static CK_OBJECT_CLASS privKeyClass = CKO_PRIVATE_KEY;
|
|||||||
static CK_OBJECT_CLASS secretKeyClass = CKO_SECRET_KEY;
|
static CK_OBJECT_CLASS secretKeyClass = CKO_SECRET_KEY;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
|
||||||
|
|
||||||
#ifdef WOLFSSL_DEBUG_PKCS11
|
#ifdef WOLFSSL_DEBUG_PKCS11
|
||||||
/* Enable logging of PKCS#11 calls and return value. */
|
/* Enable logging of PKCS#11 calls and return value. */
|
||||||
#define PKCS11_RV(op, rv) pkcs11_rv(op, rv)
|
#define PKCS11_RV(op, rv) pkcs11_rv(op, rv)
|
||||||
@@ -240,6 +242,10 @@ static void pkcs11_dump_template(const char* name, CK_ATTRIBUTE* templ,
|
|||||||
XSNPRINTF(line, sizeof(line), "%25s: SECRET", type);
|
XSNPRINTF(line, sizeof(line), "%25s: SECRET", type);
|
||||||
WOLFSSL_MSG(line);
|
WOLFSSL_MSG(line);
|
||||||
}
|
}
|
||||||
|
else if (keyClass == CKO_CERTIFICATE) {
|
||||||
|
XSNPRINTF(line, sizeof(line), "%25s: CERTIFICATE", type);
|
||||||
|
WOLFSSL_MSG(line);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
XSNPRINTF(line, sizeof(line), "%25s: UNKNOWN (%p)", type,
|
XSNPRINTF(line, sizeof(line), "%25s: UNKNOWN (%p)", type,
|
||||||
@@ -1463,7 +1469,8 @@ int wc_Pkcs11StoreKey(Pkcs11Token* token, int type, int clear, void* key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(NO_RSA) || defined(HAVE_ECC) || (!defined(NO_AES) && \
|
#if !defined(NO_RSA) || defined(HAVE_ECC) || (!defined(NO_AES) && \
|
||||||
(defined(HAVE_AESGCM) || defined(HAVE_AES_CBC))) || !defined(NO_HMAC)
|
(defined(HAVE_AESGCM) || defined(HAVE_AES_CBC))) || \
|
||||||
|
!defined(NO_HMAC) || !defined(NO_CERTS)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the PKCS#11 object containing key data using template.
|
* Find the PKCS#11 object containing key data using template.
|
||||||
@@ -3965,6 +3972,84 @@ static int Pkcs11RandomSeed(Pkcs11Session* session, wc_CryptoInfo* info)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_CERTS
|
||||||
|
|
||||||
|
static int Pkcs11GetCert(Pkcs11Session* session, wc_CryptoInfo* info) {
|
||||||
|
int ret = 0;
|
||||||
|
CK_RV rv = 0;
|
||||||
|
CK_ULONG count = 0;
|
||||||
|
CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
|
||||||
|
byte *certData = NULL;
|
||||||
|
CK_ATTRIBUTE certTemplate[2] = {
|
||||||
|
{ CKA_CLASS, &certClass, sizeof(certClass) }
|
||||||
|
};
|
||||||
|
CK_ATTRIBUTE tmpl[] = {
|
||||||
|
{ CKA_VALUE, NULL_PTR, 0 }
|
||||||
|
};
|
||||||
|
CK_ULONG certTmplCnt = sizeof(certTemplate) / sizeof(*certTemplate);
|
||||||
|
CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl);
|
||||||
|
|
||||||
|
WOLFSSL_MSG("PKCS#11: Retrieve certificate");
|
||||||
|
if (info->cert.labelLen > 0) {
|
||||||
|
certTemplate[1].type = CKA_LABEL;
|
||||||
|
certTemplate[1].pValue = (CK_VOID_PTR)info->cert.label;
|
||||||
|
certTemplate[1].ulValueLen = info->cert.labelLen;
|
||||||
|
}
|
||||||
|
else if (info->cert.idLen > 0) {
|
||||||
|
certTemplate[1].type = CKA_ID;
|
||||||
|
certTemplate[1].pValue = (CK_VOID_PTR)info->cert.id;
|
||||||
|
certTemplate[1].ulValueLen = info->cert.idLen;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = BAD_FUNC_ARG;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = Pkcs11FindKeyByTemplate(
|
||||||
|
&certHandle, session, certTemplate, certTmplCnt, &count);
|
||||||
|
if (ret == 0 && count == 0) {
|
||||||
|
ret = WC_HW_E;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
PKCS11_DUMP_TEMPLATE("Get Certificate Length", tmpl, tmplCnt);
|
||||||
|
rv = session->func->C_GetAttributeValue(
|
||||||
|
session->handle, certHandle, tmpl, tmplCnt);
|
||||||
|
PKCS11_RV("C_GetAttributeValue", rv);
|
||||||
|
if (rv != CKR_OK) {
|
||||||
|
ret = WC_HW_E;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
certData = XMALLOC(
|
||||||
|
(int)tmpl[0].ulValueLen, info->cert.heap, DYNAMIC_TYPE_CERT);
|
||||||
|
if (certData == NULL) {
|
||||||
|
ret = MEMORY_E;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl[0].pValue = certData;
|
||||||
|
rv = session->func->C_GetAttributeValue(
|
||||||
|
session->handle, certHandle, tmpl, tmplCnt);
|
||||||
|
PKCS11_RV("C_GetAttributeValue", rv);
|
||||||
|
if (rv != CKR_OK) {
|
||||||
|
ret = WC_HW_E;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
*info->cert.certDataOut = certData;
|
||||||
|
*info->cert.certSz = (word32)tmpl[0].ulValueLen;
|
||||||
|
certData = NULL;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (certData != NULL) {
|
||||||
|
XFREE(certData, info->cert.heap, DYNAMIC_TYPE_CERT);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ifndef NO_CERTS */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform a cryptographic operation using PKCS#11 device.
|
* Perform a cryptographic operation using PKCS#11 device.
|
||||||
*
|
*
|
||||||
@@ -4157,6 +4242,17 @@ int wc_Pkcs11_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
ret = NOT_COMPILED_IN;
|
ret = NOT_COMPILED_IN;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (info->algo_type == WC_ALGO_TYPE_CERT) {
|
||||||
|
#ifndef NO_CERTS
|
||||||
|
ret = Pkcs11OpenSession(token, &session, readWrite);
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = Pkcs11GetCert(&session, info);
|
||||||
|
Pkcs11CloseSession(token, &session);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
ret = NOT_COMPILED_IN;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -3545,6 +3545,12 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* key, unsigned int len,
|
|||||||
const unsigned char* in, long sz, int format);
|
const unsigned char* in, long sz, int format);
|
||||||
WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
|
WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
|
||||||
const unsigned char* in, long sz);
|
const unsigned char* in, long sz);
|
||||||
|
#if defined(WOLF_CRYPTO_CB)
|
||||||
|
WOLFSSL_API int wolfSSL_CTX_use_certificate_label(WOLFSSL_CTX* ctx,
|
||||||
|
const char *label, int devId);
|
||||||
|
WOLFSSL_API int wolfSSL_CTX_use_certificate_id(WOLFSSL_CTX* ctx,
|
||||||
|
const unsigned char *id, int idLen, int devId);
|
||||||
|
#endif
|
||||||
#ifdef WOLFSSL_DUAL_ALG_CERTS
|
#ifdef WOLFSSL_DUAL_ALG_CERTS
|
||||||
WOLFSSL_API int wolfSSL_CTX_use_AltPrivateKey_buffer(WOLFSSL_CTX* ctx,
|
WOLFSSL_API int wolfSSL_CTX_use_AltPrivateKey_buffer(WOLFSSL_CTX* ctx,
|
||||||
const unsigned char* in, long sz, int format);
|
const unsigned char* in, long sz, int format);
|
||||||
|
@@ -448,6 +448,17 @@ typedef struct wc_CryptoInfo {
|
|||||||
int type;
|
int type;
|
||||||
} cmac;
|
} cmac;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef NO_CERTS
|
||||||
|
struct {
|
||||||
|
const byte *id;
|
||||||
|
word32 idLen;
|
||||||
|
const sword8 *label;
|
||||||
|
word32 labelLen;
|
||||||
|
byte **certDataOut;
|
||||||
|
word32 *certSz;
|
||||||
|
void *heap;
|
||||||
|
} cert;
|
||||||
|
#endif
|
||||||
#ifdef WOLF_CRYPTO_CB_CMD
|
#ifdef WOLF_CRYPTO_CB_CMD
|
||||||
struct { /* uses wc_AlgoType=ALGO_NONE */
|
struct { /* uses wc_AlgoType=ALGO_NONE */
|
||||||
int type; /* enum wc_CryptoCbCmdType */
|
int type; /* enum wc_CryptoCbCmdType */
|
||||||
@@ -657,6 +668,12 @@ WOLFSSL_LOCAL int wc_CryptoCb_Cmac(Cmac* cmac, const byte* key, word32 keySz,
|
|||||||
void* ctx);
|
void* ctx);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_CERTS
|
||||||
|
WOLFSSL_LOCAL int wc_CryptoCb_GetCert(int devId, const sword8 *label,
|
||||||
|
word32 labelLen, const byte *id, word32 idLen, byte** out,
|
||||||
|
word32* outSz, void *heap);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* WOLF_CRYPTO_CB */
|
#endif /* WOLF_CRYPTO_CB */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@@ -71,10 +71,12 @@ extern "C" {
|
|||||||
#define CKF_RW_SESSION 0x00000002UL
|
#define CKF_RW_SESSION 0x00000002UL
|
||||||
#define CKF_SERIAL_SESSION 0x00000004UL
|
#define CKF_SERIAL_SESSION 0x00000004UL
|
||||||
|
|
||||||
|
#define CKO_CERTIFICATE 0x00000001UL
|
||||||
#define CKO_PUBLIC_KEY 0x00000002UL
|
#define CKO_PUBLIC_KEY 0x00000002UL
|
||||||
#define CKO_PRIVATE_KEY 0x00000003UL
|
#define CKO_PRIVATE_KEY 0x00000003UL
|
||||||
#define CKO_SECRET_KEY 0x00000004UL
|
#define CKO_SECRET_KEY 0x00000004UL
|
||||||
|
|
||||||
|
|
||||||
#define CKK_RSA 0x00000000UL
|
#define CKK_RSA 0x00000000UL
|
||||||
#define CKK_DH 0x00000002UL
|
#define CKK_DH 0x00000002UL
|
||||||
#define CKK_EC 0x00000003UL
|
#define CKK_EC 0x00000003UL
|
||||||
|
@@ -1138,8 +1138,9 @@ typedef struct w64wrapper {
|
|||||||
WC_ALGO_TYPE_SEED = 5,
|
WC_ALGO_TYPE_SEED = 5,
|
||||||
WC_ALGO_TYPE_HMAC = 6,
|
WC_ALGO_TYPE_HMAC = 6,
|
||||||
WC_ALGO_TYPE_CMAC = 7,
|
WC_ALGO_TYPE_CMAC = 7,
|
||||||
|
WC_ALGO_TYPE_CERT = 8,
|
||||||
|
|
||||||
WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_CMAC
|
WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_CERT
|
||||||
};
|
};
|
||||||
|
|
||||||
/* hash types */
|
/* hash types */
|
||||||
|
Reference in New Issue
Block a user