Skip to content

Commit

Permalink
Merge pull request #8267 from ColtonWilley/pkcs11_cert_support
Browse files Browse the repository at this point in the history
PKCS11 cert support
  • Loading branch information
douzzer authored Dec 11, 2024
2 parents ee4366a + 2039d63 commit 88241f1
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 2 deletions.
71 changes: 71 additions & 0 deletions src/ssl_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -4146,6 +4146,77 @@ 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)
{
int ret;
byte *certData = NULL;
word32 certDataLen = 0;
word32 labelLen = 0;
int certFormat = 0;

WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_ex");

if (label != NULL) {
labelLen = (word32)XSTRLEN(label);
}

ret = wc_CryptoCb_GetCert(devId, label, labelLen, id, idLen,
&certData, &certDataLen, &certFormat, ctx->heap);
if (ret != 0) {
ret = WOLFSSL_FAILURE;
goto exit;
}

ret = ProcessBuffer(ctx, certData, certDataLen, certFormat,
CERT_TYPE, NULL, NULL, 0, GET_VERIFY_SETTING_CTX(ctx));

exit:
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)) {
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)) {
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.
Expand Down
32 changes: 32 additions & 0 deletions wolfcrypt/src/cryptocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -1799,6 +1800,37 @@ 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 char *label, word32 labelLen,
const byte *id, word32 idLen, byte** out,
word32* outSz, int *format, 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.certFormatOut = format;
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,
Expand Down
104 changes: 103 additions & 1 deletion wolfcrypt/src/wc_pkcs11.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -3965,6 +3972,90 @@ 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;
}

if (tmpl[0].ulValueLen <= 0) {
ret = WC_HW_E;
goto exit;
}

certData = (byte *)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;
if (info->cert.certFormatOut != NULL) {
*info->cert.certFormatOut = CTC_FILETYPE_ASN1;
}
certData = NULL;

exit:
XFREE(certData, info->cert.heap, DYNAMIC_TYPE_CERT);
return ret;
}

#endif /* !NO_CERTS */

/**
* Perform a cryptographic operation using PKCS#11 device.
*
Expand Down Expand Up @@ -4157,6 +4248,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
Expand Down
6 changes: 6 additions & 0 deletions wolfssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
18 changes: 18 additions & 0 deletions wolfssl/wolfcrypt/cryptocb.h
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,18 @@ typedef struct wc_CryptoInfo {
int type;
} cmac;
#endif
#ifndef NO_CERTS
struct {
const byte *id;
word32 idLen;
const char *label;
word32 labelLen;
byte **certDataOut;
word32 *certSz;
int *certFormatOut;
void *heap;
} cert;
#endif
#ifdef WOLF_CRYPTO_CB_CMD
struct { /* uses wc_AlgoType=ALGO_NONE */
int type; /* enum wc_CryptoCbCmdType */
Expand Down Expand Up @@ -657,6 +669,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 char *label,
word32 labelLen, const byte *id, word32 idLen, byte** out,
word32* outSz, int *format, void *heap);
#endif

#endif /* WOLF_CRYPTO_CB */

#ifdef __cplusplus
Expand Down
2 changes: 2 additions & 0 deletions wolfssl/wolfcrypt/pkcs11.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion wolfssl/wolfcrypt/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1142,8 +1142,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 */
Expand Down

0 comments on commit 88241f1

Please sign in to comment.