forked from wolfSSL/wolfssl
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 /* 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.
|
||||
*
|
||||
* @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_HMAC: return "HMAC";
|
||||
case WC_ALGO_TYPE_CMAC: return "CMAC";
|
||||
case WC_ALGO_TYPE_CERT: return "Cert";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -1799,6 +1800,36 @@ int wc_CryptoCb_RandomSeed(OS_Seed* os, byte* seed, word32 sz)
|
||||
}
|
||||
#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)
|
||||
int wc_CryptoCb_Cmac(Cmac* cmac, const byte* key, word32 keySz,
|
||||
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;
|
||||
#endif
|
||||
|
||||
static CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
|
||||
|
||||
#ifdef WOLFSSL_DEBUG_PKCS11
|
||||
/* Enable logging of PKCS#11 calls and return value. */
|
||||
#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);
|
||||
WOLFSSL_MSG(line);
|
||||
}
|
||||
else if (keyClass == CKO_CERTIFICATE) {
|
||||
XSNPRINTF(line, sizeof(line), "%25s: CERTIFICATE", type);
|
||||
WOLFSSL_MSG(line);
|
||||
}
|
||||
else
|
||||
{
|
||||
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) && \
|
||||
(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.
|
||||
@ -3965,6 +3972,84 @@ static int Pkcs11RandomSeed(Pkcs11Session* session, wc_CryptoInfo* info)
|
||||
}
|
||||
#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.
|
||||
*
|
||||
@ -4157,6 +4242,17 @@ int wc_Pkcs11_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
|
||||
}
|
||||
#else
|
||||
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
|
||||
}
|
||||
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);
|
||||
WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
|
||||
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
|
||||
WOLFSSL_API int wolfSSL_CTX_use_AltPrivateKey_buffer(WOLFSSL_CTX* ctx,
|
||||
const unsigned char* in, long sz, int format);
|
||||
|
@ -448,6 +448,17 @@ typedef struct wc_CryptoInfo {
|
||||
int type;
|
||||
} cmac;
|
||||
#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
|
||||
struct { /* uses wc_AlgoType=ALGO_NONE */
|
||||
int type; /* enum wc_CryptoCbCmdType */
|
||||
@ -657,6 +668,12 @@ WOLFSSL_LOCAL int wc_CryptoCb_Cmac(Cmac* cmac, const byte* key, word32 keySz,
|
||||
void* ctx);
|
||||
#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 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -71,10 +71,12 @@ extern "C" {
|
||||
#define CKF_RW_SESSION 0x00000002UL
|
||||
#define CKF_SERIAL_SESSION 0x00000004UL
|
||||
|
||||
#define CKO_CERTIFICATE 0x00000001UL
|
||||
#define CKO_PUBLIC_KEY 0x00000002UL
|
||||
#define CKO_PRIVATE_KEY 0x00000003UL
|
||||
#define CKO_SECRET_KEY 0x00000004UL
|
||||
|
||||
|
||||
#define CKK_RSA 0x00000000UL
|
||||
#define CKK_DH 0x00000002UL
|
||||
#define CKK_EC 0x00000003UL
|
||||
|
@ -1138,8 +1138,9 @@ typedef struct w64wrapper {
|
||||
WC_ALGO_TYPE_SEED = 5,
|
||||
WC_ALGO_TYPE_HMAC = 6,
|
||||
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 */
|
||||
|
Reference in New Issue
Block a user