mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-01-29 12:22:11 +01:00
Change to allow setting of devId for private key
This commit is contained in:
@@ -4413,10 +4413,11 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
||||
#ifdef WOLFSSL_TLS13
|
||||
ssl->buffers.certChainCnt = ctx->certChainCnt;
|
||||
#endif
|
||||
ssl->buffers.key = ctx->privateKey;
|
||||
ssl->buffers.keyType = ctx->privateKeyType;
|
||||
ssl->buffers.keyId = ctx->privateKeyId;
|
||||
ssl->buffers.keySz = ctx->privateKeySz;
|
||||
ssl->buffers.key = ctx->privateKey;
|
||||
ssl->buffers.keyType = ctx->privateKeyType;
|
||||
ssl->buffers.keyId = ctx->privateKeyId;
|
||||
ssl->buffers.keySz = ctx->privateKeySz;
|
||||
ssl->buffers.keyDevId = ctx->privateKeyDevId;
|
||||
#endif
|
||||
#if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \
|
||||
!defined(NO_ED25519_CLIENT_AUTH)
|
||||
@@ -16929,7 +16930,11 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
|
||||
}
|
||||
|
||||
#ifdef HAVE_PKCS11
|
||||
if (ssl->devId != INVALID_DEVID && ssl->buffers.keyId) {
|
||||
if (ssl->buffers.keyDevId != INVALID_DEVID && ssl->buffers.keyId) {
|
||||
if (ssl->buffers.keyType == rsa_sa_algo)
|
||||
ssl->hsType = DYNAMIC_TYPE_RSA;
|
||||
else if (ssl->buffers.keyType == ecc_dsa_sa_algo)
|
||||
ssl->hsType = DYNAMIC_TYPE_ECC;
|
||||
ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
|
||||
if (ret != 0) {
|
||||
goto exit_dpk;
|
||||
@@ -16938,7 +16943,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
|
||||
if (ssl->buffers.keyType == rsa_sa_algo) {
|
||||
ret = wc_InitRsaKey_Id((RsaKey*)ssl->hsKey,
|
||||
ssl->buffers.key->buffer, ssl->buffers.key->length,
|
||||
ssl->heap, ssl->devId);
|
||||
ssl->heap, ssl->buffers.keyDevId);
|
||||
if (ret == 0) {
|
||||
if (ssl->buffers.keySz < ssl->options.minRsaKeySz) {
|
||||
WOLFSSL_MSG("RSA key size too small");
|
||||
@@ -16951,7 +16956,8 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
|
||||
}
|
||||
else if (ssl->buffers.keyType == ecc_dsa_sa_algo) {
|
||||
ret = wc_ecc_init_id((ecc_key*)ssl->hsKey, ssl->buffers.key->buffer,
|
||||
ssl->buffers.key->length, ssl->heap, ssl->devId);
|
||||
ssl->buffers.key->length, ssl->heap,
|
||||
ssl->buffers.keyDevId);
|
||||
if (ret == 0) {
|
||||
if (ssl->buffers.keySz < ssl->options.minEccKeySz) {
|
||||
WOLFSSL_MSG("ECC key size too small");
|
||||
@@ -22053,19 +22059,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
{
|
||||
word16 keySz;
|
||||
|
||||
ssl->hsType = DYNAMIC_TYPE_RSA;
|
||||
if (ssl->buffers.keyType == 0)
|
||||
ssl->buffers.keyType = rsa_sa_algo;
|
||||
ssl->buffers.keyType = rsa_sa_algo;
|
||||
ret = DecodePrivateKey(ssl, &keySz);
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(keySz, exit_sske);
|
||||
goto exit_sske;
|
||||
}
|
||||
|
||||
args->tmpSigSz = (word32)keySz;
|
||||
if (keySz < ssl->options.minRsaKeySz) {
|
||||
WOLFSSL_MSG("RSA signature key size too small");
|
||||
ERROR_OUT(RSA_KEY_SIZE_E, exit_sske);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* !NO_RSA */
|
||||
@@ -22074,21 +22074,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
{
|
||||
word16 keySz;
|
||||
|
||||
ssl->hsType = DYNAMIC_TYPE_ECC;
|
||||
if (ssl->buffers.keyType == 0)
|
||||
ssl->buffers.keyType = ecc_dsa_sa_algo;
|
||||
ssl->buffers.keyType = ecc_dsa_sa_algo;
|
||||
ret = DecodePrivateKey(ssl, &keySz);
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(keySz, exit_sske);
|
||||
goto exit_sske;
|
||||
}
|
||||
/* worst case estimate */
|
||||
args->tmpSigSz = keySz;
|
||||
|
||||
/* check the minimum ECC key size */
|
||||
if (keySz < ssl->options.minEccKeySz) {
|
||||
WOLFSSL_MSG("ECC key size too small");
|
||||
ERROR_OUT(ECC_KEY_SIZE_E, exit_sske);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -22097,23 +22089,14 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
{
|
||||
word16 keySz;
|
||||
|
||||
ssl->hsType = DYNAMIC_TYPE_ED25519;
|
||||
if (ssl->buffers.keyType == 0)
|
||||
ssl->buffers.keyType = ed25519_sa_algo;
|
||||
ssl->buffers.keyType = ed25519_sa_algo;
|
||||
ret = DecodePrivateKey(ssl, &keySz);
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(keySz, exit_sske);
|
||||
goto exit_sske;
|
||||
}
|
||||
|
||||
/* worst case estimate */
|
||||
args->tmpSigSz = ED25519_SIG_SIZE;
|
||||
|
||||
/* check the minimum ECC key size */
|
||||
if (ED25519_KEY_SIZE <
|
||||
ssl->options.minEccKeySz) {
|
||||
WOLFSSL_MSG("Ed25519 key size too small");
|
||||
ERROR_OUT(ECC_KEY_SIZE_E, exit_sske);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* HAVE_ED25519 */
|
||||
@@ -22333,12 +22316,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
}
|
||||
else
|
||||
{
|
||||
ssl->hsType = DYNAMIC_TYPE_RSA;
|
||||
if (ssl->buffers.keyType == 0)
|
||||
ssl->buffers.keyType = rsa_sa_algo;
|
||||
ret = DecodePrivateKey(ssl, &keySz);
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(keySz, exit_sske);
|
||||
goto exit_sske;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22349,11 +22331,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
args->tmpSigSz = (word32)keySz;
|
||||
args->length += args->tmpSigSz;
|
||||
|
||||
if (keySz < ssl->options.minRsaKeySz) {
|
||||
WOLFSSL_MSG("RSA key size too small");
|
||||
ERROR_OUT(RSA_KEY_SIZE_E, exit_sske);
|
||||
}
|
||||
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
args->length += HASH_SIG_SIZE;
|
||||
}
|
||||
@@ -25018,19 +24995,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
{
|
||||
word16 keySz;
|
||||
|
||||
ssl->hsType = DYNAMIC_TYPE_RSA;
|
||||
if (ssl->buffers.keyType == 0)
|
||||
ssl->buffers.keyType = rsa_sa_algo;
|
||||
ssl->buffers.keyType = rsa_sa_algo;
|
||||
ret = DecodePrivateKey(ssl, &keySz);
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(keySz, exit_dcke);
|
||||
goto exit_dcke;
|
||||
}
|
||||
args->length = (word32)keySz;
|
||||
|
||||
if (keySz < ssl->options.minRsaKeySz) {
|
||||
WOLFSSL_MSG("Peer RSA key is too small");
|
||||
ERROR_OUT(RSA_KEY_SIZE_E, exit_dcke);
|
||||
}
|
||||
ssl->arrays->preMasterSz = SECRET_LEN;
|
||||
|
||||
if (ssl->options.tls) {
|
||||
@@ -25167,16 +25137,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
ssl->ecdhCurveOID != ECC_X25519_OID) {
|
||||
word16 keySz;
|
||||
|
||||
ssl->hsType = DYNAMIC_TYPE_ECC;
|
||||
if (ssl->buffers.keyType == 0)
|
||||
ssl->buffers.keyType = rsa_sa_algo;
|
||||
ssl->buffers.keyType = ecc_dsa_sa_algo;
|
||||
ret = DecodePrivateKey(ssl, &keySz);
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(keySz, exit_dcke);
|
||||
}
|
||||
if (keySz < ssl->options.minEccKeySz) {
|
||||
WOLFSSL_MSG("ECC key too small");
|
||||
ERROR_OUT(ECC_KEY_SIZE_E, exit_dcke);
|
||||
goto exit_dcke;
|
||||
}
|
||||
private_key = (ecc_key*)ssl->hsKey;
|
||||
}
|
||||
|
||||
12
src/ssl.c
12
src/ssl.c
@@ -11158,7 +11158,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
|
||||
|
||||
#ifdef HAVE_PKCS11
|
||||
int wolfSSL_CTX_use_PrivateKey_id(WOLFSSL_CTX* ctx, const unsigned char* id,
|
||||
long sz, long keySz)
|
||||
long sz, int devId, long keySz)
|
||||
{
|
||||
int ret = WOLFSSL_FAILURE;
|
||||
|
||||
@@ -11167,6 +11167,10 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
|
||||
XMEMCPY(ctx->privateKey->buffer, id, sz);
|
||||
ctx->privateKeyId = 1;
|
||||
ctx->privateKeySz = keySz;
|
||||
if (devId != INVALID_DEVID)
|
||||
ctx->privateKeyDevId = devId;
|
||||
else
|
||||
ctx->privateKeyDevId = ctx->devId;
|
||||
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
}
|
||||
@@ -11311,7 +11315,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
|
||||
|
||||
#ifdef HAVE_PKCS11
|
||||
int wolfSSL_use_PrivateKey_id(WOLFSSL* ssl, const unsigned char* id,
|
||||
long sz, long keySz)
|
||||
long sz, int devId, long keySz)
|
||||
{
|
||||
int ret = WOLFSSL_FAILURE;
|
||||
|
||||
@@ -11321,6 +11325,10 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
|
||||
ssl->buffers.weOwnKey = 1;
|
||||
ssl->buffers.keyId = 1;
|
||||
ssl->buffers.keySz = keySz;
|
||||
if (devId != INVALID_DEVID)
|
||||
ssl->buffers.keyId = devId;
|
||||
else
|
||||
ssl->buffers.keyId = ssl->devId;
|
||||
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -4351,6 +4351,10 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
||||
key->state = ECC_STATE_SIGN_DO;
|
||||
|
||||
if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
|
||||
#if !defined(WOLFSSL_ASYNC_CRYPT) && defined(WOLFSSL_SMALL_STACK)
|
||||
XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
|
||||
XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4361,6 +4365,10 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
||||
err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
|
||||
#endif
|
||||
if (err < 0) {
|
||||
#if !defined(WOLFSSL_ASYNC_CRYPT) && defined(WOLFSSL_SMALL_STACK)
|
||||
XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
|
||||
XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -660,78 +660,6 @@ static int Pkcs11FindKeyById(CK_OBJECT_HANDLE* key, CK_OBJECT_CLASS keyClass,
|
||||
#endif
|
||||
|
||||
#ifndef NO_RSA
|
||||
/**
|
||||
* Exponentiate the input with the public part of the RSA key.
|
||||
* Used in public encrypt and decrypt.
|
||||
*
|
||||
* @param session [in] Session object.
|
||||
* @param info [in] Cryptographic operation data.
|
||||
* @return WC_HW_E when a PKCS#11 library call fails.
|
||||
* 0 on success.
|
||||
*/
|
||||
static int Pkcs11RsaPublic(Pkcs11Session* session, wc_CryptoInfo* info)
|
||||
{
|
||||
int ret = 0;
|
||||
CK_RV rv;
|
||||
CK_MECHANISM mech;
|
||||
CK_ULONG outLen;
|
||||
CK_OBJECT_HANDLE publicKey = NULL_PTR;
|
||||
CK_ATTRIBUTE keyTemplate[] = {
|
||||
{ CKA_CLASS, &pubKeyClass, sizeof(pubKeyClass) },
|
||||
{ CKA_KEY_TYPE, &rsaKeyType, sizeof(rsaKeyType) },
|
||||
{ CKA_ENCRYPT, &ckTrue, sizeof(ckTrue) },
|
||||
{ CKA_MODULUS, NULL, 0 },
|
||||
{ CKA_PUBLIC_EXPONENT, NULL, 0 }
|
||||
};
|
||||
CK_ULONG keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate);
|
||||
|
||||
WOLFSSL_MSG("PKCS#11: RSA Public Key Operation");
|
||||
|
||||
if (ret == 0 && info->pk.rsa.outLen == NULL) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Set the modulus and public exponent data. */
|
||||
keyTemplate[3].pValue = info->pk.rsa.key->n.raw.buf;
|
||||
keyTemplate[3].ulValueLen = info->pk.rsa.key->n.raw.len;
|
||||
keyTemplate[4].pValue = info->pk.rsa.key->e.raw.buf;
|
||||
keyTemplate[4].ulValueLen = info->pk.rsa.key->e.raw.len;
|
||||
|
||||
/* Create an object containing public key data for device to use. */
|
||||
rv = session->func->C_CreateObject(session->handle, keyTemplate,
|
||||
keyTmplCnt, &publicKey);
|
||||
if (rv != CKR_OK)
|
||||
ret = WC_HW_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Raw RSA encrypt/decrypt operation. */
|
||||
mech.mechanism = CKM_RSA_X_509;
|
||||
mech.ulParameterLen = 0;
|
||||
mech.pParameter = NULL;
|
||||
|
||||
rv = session->func->C_EncryptInit(session->handle, &mech, publicKey);
|
||||
if (rv != CKR_OK)
|
||||
ret = WC_HW_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
outLen = (CK_ULONG)*info->pk.rsa.outLen;
|
||||
rv = session->func->C_Encrypt(session->handle,
|
||||
(CK_BYTE_PTR)info->pk.rsa.in, info->pk.rsa.inLen,
|
||||
info->pk.rsa.out, &outLen);
|
||||
if (rv != CKR_OK)
|
||||
ret = WC_HW_E;
|
||||
}
|
||||
if (ret == 0)
|
||||
*info->pk.rsa.outLen = (word32)outLen;
|
||||
|
||||
if (publicKey != NULL_PTR)
|
||||
session->func->C_DestroyObject(session->handle, publicKey);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the PKCS#11 object containing the RSA public or private key data with
|
||||
* the modulus specified.
|
||||
@@ -774,6 +702,86 @@ static int Pkcs11FindRsaKey(CK_OBJECT_HANDLE* key, CK_OBJECT_CLASS keyClass,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exponentiate the input with the public part of the RSA key.
|
||||
* Used in public encrypt and decrypt.
|
||||
*
|
||||
* @param session [in] Session object.
|
||||
* @param info [in] Cryptographic operation data.
|
||||
* @return WC_HW_E when a PKCS#11 library call fails.
|
||||
* 0 on success.
|
||||
*/
|
||||
static int Pkcs11RsaPublic(Pkcs11Session* session, wc_CryptoInfo* info)
|
||||
{
|
||||
int ret = 0;
|
||||
CK_RV rv;
|
||||
CK_MECHANISM mech;
|
||||
CK_ULONG outLen;
|
||||
CK_OBJECT_HANDLE publicKey = NULL_PTR;
|
||||
int sessionKey = 0;
|
||||
CK_ATTRIBUTE keyTemplate[] = {
|
||||
{ CKA_CLASS, &pubKeyClass, sizeof(pubKeyClass) },
|
||||
{ CKA_KEY_TYPE, &rsaKeyType, sizeof(rsaKeyType) },
|
||||
{ CKA_ENCRYPT, &ckTrue, sizeof(ckTrue) },
|
||||
{ CKA_MODULUS, NULL, 0 },
|
||||
{ CKA_PUBLIC_EXPONENT, NULL, 0 }
|
||||
};
|
||||
CK_ULONG keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate);
|
||||
|
||||
WOLFSSL_MSG("PKCS#11: RSA Public Key Operation");
|
||||
|
||||
if (ret == 0 && info->pk.rsa.outLen == NULL) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if ((sessionKey = !mp_iszero(&info->pk.rsa.key->e))) {
|
||||
/* Set the modulus and public exponent data. */
|
||||
keyTemplate[3].pValue = info->pk.rsa.key->n.raw.buf;
|
||||
keyTemplate[3].ulValueLen = info->pk.rsa.key->n.raw.len;
|
||||
keyTemplate[4].pValue = info->pk.rsa.key->e.raw.buf;
|
||||
keyTemplate[4].ulValueLen = info->pk.rsa.key->e.raw.len;
|
||||
|
||||
/* Create an object containing public key data for device to use. */
|
||||
rv = session->func->C_CreateObject(session->handle, keyTemplate,
|
||||
keyTmplCnt, &publicKey);
|
||||
if (rv != CKR_OK)
|
||||
ret = WC_HW_E;
|
||||
}
|
||||
else {
|
||||
ret = Pkcs11FindKeyById(&publicKey, CKO_PUBLIC_KEY, CKK_RSA,
|
||||
session, info->pk.rsa.key->id,
|
||||
info->pk.rsa.key->idLen);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Raw RSA encrypt/decrypt operation. */
|
||||
mech.mechanism = CKM_RSA_X_509;
|
||||
mech.ulParameterLen = 0;
|
||||
mech.pParameter = NULL;
|
||||
|
||||
rv = session->func->C_EncryptInit(session->handle, &mech, publicKey);
|
||||
if (rv != CKR_OK)
|
||||
ret = WC_HW_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
outLen = (CK_ULONG)*info->pk.rsa.outLen;
|
||||
rv = session->func->C_Encrypt(session->handle,
|
||||
(CK_BYTE_PTR)info->pk.rsa.in, info->pk.rsa.inLen,
|
||||
info->pk.rsa.out, &outLen);
|
||||
if (rv != CKR_OK)
|
||||
ret = WC_HW_E;
|
||||
}
|
||||
if (ret == 0)
|
||||
*info->pk.rsa.outLen = (word32)outLen;
|
||||
|
||||
if (sessionKey)
|
||||
session->func->C_DestroyObject(session->handle, publicKey);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exponentiate the input with the private part of the RSA key.
|
||||
* Used in private encrypt and decrypt.
|
||||
|
||||
@@ -2500,6 +2500,7 @@ struct WOLFSSL_CTX {
|
||||
byte privateKeyType:7;
|
||||
byte privateKeyId:1;
|
||||
int privateKeySz;
|
||||
int privateKeyDevId;
|
||||
WOLFSSL_CERT_MANAGER* cm; /* our cert manager, ctx owns SSL will use */
|
||||
#endif
|
||||
#ifdef KEEP_OUR_CERT
|
||||
@@ -3082,6 +3083,7 @@ typedef struct Buffers {
|
||||
byte keyType:7; /* Type of key: RSA, ECC, Ed25519 */
|
||||
byte keyId:1; /* Key data is an id not data */
|
||||
int keySz; /* Size of RSA key */
|
||||
int keyDevId; /* Device Id for key */
|
||||
DerBuffer* certChain; /* WOLFSSL_CTX owns, unless we own */
|
||||
/* chain after self, in DER, with leading size for each cert */
|
||||
#ifdef WOLFSSL_TLS13
|
||||
|
||||
@@ -1734,7 +1734,7 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL*, void* key, unsigned int len,
|
||||
WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX*,
|
||||
const unsigned char*, long, int);
|
||||
WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_id(WOLFSSL_CTX*,
|
||||
const unsigned char*, long, long);
|
||||
const unsigned char*, long, int, long);
|
||||
WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX*,
|
||||
const unsigned char*, long, int);
|
||||
WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX*,
|
||||
@@ -1748,7 +1748,7 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL*, void* key, unsigned int len,
|
||||
WOLFSSL_API int wolfSSL_use_PrivateKey_buffer(WOLFSSL*, const unsigned char*,
|
||||
long, int);
|
||||
WOLFSSL_API int wolfSSL_use_PrivateKey_id(WOLFSSL*, const unsigned char*,
|
||||
long, long);
|
||||
long, int, long);
|
||||
WOLFSSL_API int wolfSSL_use_certificate_chain_buffer_format(WOLFSSL*,
|
||||
const unsigned char*, long, int);
|
||||
WOLFSSL_API int wolfSSL_use_certificate_chain_buffer(WOLFSSL*,
|
||||
|
||||
Reference in New Issue
Block a user