Merge pull request #9723 from SparkiDev/ssl_split_cert

Split out code form ssl.c and pk.c
This commit is contained in:
Daniel Pouzzner
2026-02-05 18:21:36 -06:00
committed by GitHub
19 changed files with 17053 additions and 15322 deletions
+6
View File
@@ -17,10 +17,16 @@ MAINTAINERCLEANFILES+= $(FIPS_FILES)
EXTRA_DIST += src/bio.c
EXTRA_DIST += src/conf.c
EXTRA_DIST += src/pk.c
EXTRA_DIST += src/pk_rsa.c
EXTRA_DIST += src/pk_ec.c
EXTRA_DIST += src/ssl_api_cert.c
EXTRA_DIST += src/ssl_api_crl_ocsp.c
EXTRA_DIST += src/ssl_api_pk.c
EXTRA_DIST += src/ssl_asn1.c
EXTRA_DIST += src/ssl_bn.c
EXTRA_DIST += src/ssl_certman.c
EXTRA_DIST += src/ssl_crypto.c
EXTRA_DIST += src/ssl_ech.c
EXTRA_DIST += src/ssl_load.c
EXTRA_DIST += src/ssl_misc.c
EXTRA_DIST += src/ssl_p7p12.c
+10 -9425
View File
File diff suppressed because it is too large Load Diff
+5558
View File
File diff suppressed because it is too large Load Diff
+3943
View File
File diff suppressed because it is too large Load Diff
+13 -5846
View File
File diff suppressed because it is too large Load Diff
+1740
View File
File diff suppressed because it is too large Load Diff
+634
View File
@@ -0,0 +1,634 @@
/* ssl_api_crl_ocsp.c
*
* Copyright (C) 2006-2025 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#if !defined(WOLFSSL_SSL_API_CRL_OCSP_INCLUDED)
#ifndef WOLFSSL_IGNORE_FILE_WARN
#warning ssl_api_crl_ocsp.c is not compiled separately from ssl.c
#endif
#else
#ifndef NO_CERTS
#ifdef HAVE_CRL
int wolfSSL_CTX_LoadCRLBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
long sz, int type)
{
WOLFSSL_ENTER("wolfSSL_CTX_LoadCRLBuffer");
if (ctx == NULL)
return BAD_FUNC_ARG;
return wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, buff, sz, type);
}
int wolfSSL_LoadCRLBuffer(WOLFSSL* ssl, const unsigned char* buff,
long sz, int type)
{
WOLFSSL_ENTER("wolfSSL_LoadCRLBuffer");
if (ssl == NULL || ssl->ctx == NULL)
return BAD_FUNC_ARG;
SSL_CM_WARNING(ssl);
return wolfSSL_CertManagerLoadCRLBuffer(SSL_CM(ssl), buff, sz, type);
}
int wolfSSL_EnableCRL(WOLFSSL* ssl, int options)
{
WOLFSSL_ENTER("wolfSSL_EnableCRL");
if (ssl) {
SSL_CM_WARNING(ssl);
return wolfSSL_CertManagerEnableCRL(SSL_CM(ssl), options);
}
else
return BAD_FUNC_ARG;
}
int wolfSSL_DisableCRL(WOLFSSL* ssl)
{
WOLFSSL_ENTER("wolfSSL_DisableCRL");
if (ssl) {
SSL_CM_WARNING(ssl);
return wolfSSL_CertManagerDisableCRL(SSL_CM(ssl));
}
else
return BAD_FUNC_ARG;
}
#ifndef NO_FILESYSTEM
int wolfSSL_LoadCRL(WOLFSSL* ssl, const char* path, int type, int monitor)
{
WOLFSSL_ENTER("wolfSSL_LoadCRL");
if (ssl) {
SSL_CM_WARNING(ssl);
return wolfSSL_CertManagerLoadCRL(SSL_CM(ssl), path, type, monitor);
}
else
return BAD_FUNC_ARG;
}
int wolfSSL_LoadCRLFile(WOLFSSL* ssl, const char* file, int type)
{
WOLFSSL_ENTER("wolfSSL_LoadCRLFile");
if (ssl) {
SSL_CM_WARNING(ssl);
return wolfSSL_CertManagerLoadCRLFile(SSL_CM(ssl), file, type);
}
else
return BAD_FUNC_ARG;
}
#endif
int wolfSSL_SetCRL_Cb(WOLFSSL* ssl, CbMissingCRL cb)
{
WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
if (ssl) {
SSL_CM_WARNING(ssl);
return wolfSSL_CertManagerSetCRL_Cb(SSL_CM(ssl), cb);
}
else
return BAD_FUNC_ARG;
}
int wolfSSL_SetCRL_ErrorCb(WOLFSSL* ssl, crlErrorCb cb, void* ctx)
{
WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
if (ssl) {
SSL_CM_WARNING(ssl);
return wolfSSL_CertManagerSetCRL_ErrorCb(SSL_CM(ssl), cb, ctx);
}
else
return BAD_FUNC_ARG;
}
#ifdef HAVE_CRL_IO
int wolfSSL_SetCRL_IOCb(WOLFSSL* ssl, CbCrlIO cb)
{
WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
if (ssl) {
SSL_CM_WARNING(ssl);
return wolfSSL_CertManagerSetCRL_IOCb(SSL_CM(ssl), cb);
}
else
return BAD_FUNC_ARG;
}
#endif
int wolfSSL_CTX_EnableCRL(WOLFSSL_CTX* ctx, int options)
{
WOLFSSL_ENTER("wolfSSL_CTX_EnableCRL");
if (ctx)
return wolfSSL_CertManagerEnableCRL(ctx->cm, options);
else
return BAD_FUNC_ARG;
}
int wolfSSL_CTX_DisableCRL(WOLFSSL_CTX* ctx)
{
WOLFSSL_ENTER("wolfSSL_CTX_DisableCRL");
if (ctx)
return wolfSSL_CertManagerDisableCRL(ctx->cm);
else
return BAD_FUNC_ARG;
}
#ifndef NO_FILESYSTEM
int wolfSSL_CTX_LoadCRL(WOLFSSL_CTX* ctx, const char* path,
int type, int monitor)
{
WOLFSSL_ENTER("wolfSSL_CTX_LoadCRL");
if (ctx)
return wolfSSL_CertManagerLoadCRL(ctx->cm, path, type, monitor);
else
return BAD_FUNC_ARG;
}
int wolfSSL_CTX_LoadCRLFile(WOLFSSL_CTX* ctx, const char* file,
int type)
{
WOLFSSL_ENTER("wolfSSL_CTX_LoadCRL");
if (ctx)
return wolfSSL_CertManagerLoadCRLFile(ctx->cm, file, type);
else
return BAD_FUNC_ARG;
}
#endif
int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX* ctx, CbMissingCRL cb)
{
WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_Cb");
if (ctx)
return wolfSSL_CertManagerSetCRL_Cb(ctx->cm, cb);
else
return BAD_FUNC_ARG;
}
int wolfSSL_CTX_SetCRL_ErrorCb(WOLFSSL_CTX* ctx, crlErrorCb cb, void* cbCtx)
{
WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_ErrorCb");
if (ctx)
return wolfSSL_CertManagerSetCRL_ErrorCb(ctx->cm, cb, cbCtx);
else
return BAD_FUNC_ARG;
}
#ifdef HAVE_CRL_IO
int wolfSSL_CTX_SetCRL_IOCb(WOLFSSL_CTX* ctx, CbCrlIO cb)
{
WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_IOCb");
if (ctx)
return wolfSSL_CertManagerSetCRL_IOCb(ctx->cm, cb);
else
return BAD_FUNC_ARG;
}
#endif
#endif /* HAVE_CRL */
#ifdef HAVE_OCSP
int wolfSSL_EnableOCSP(WOLFSSL* ssl, int options)
{
WOLFSSL_ENTER("wolfSSL_EnableOCSP");
if (ssl) {
SSL_CM_WARNING(ssl);
return wolfSSL_CertManagerEnableOCSP(SSL_CM(ssl), options);
}
else
return BAD_FUNC_ARG;
}
int wolfSSL_DisableOCSP(WOLFSSL* ssl)
{
WOLFSSL_ENTER("wolfSSL_DisableOCSP");
if (ssl) {
SSL_CM_WARNING(ssl);
return wolfSSL_CertManagerDisableOCSP(SSL_CM(ssl));
}
else
return BAD_FUNC_ARG;
}
int wolfSSL_EnableOCSPStapling(WOLFSSL* ssl)
{
WOLFSSL_ENTER("wolfSSL_EnableOCSPStapling");
if (ssl) {
SSL_CM_WARNING(ssl);
return wolfSSL_CertManagerEnableOCSPStapling(SSL_CM(ssl));
}
else
return BAD_FUNC_ARG;
}
int wolfSSL_DisableOCSPStapling(WOLFSSL* ssl)
{
WOLFSSL_ENTER("wolfSSL_DisableOCSPStapling");
if (ssl) {
SSL_CM_WARNING(ssl);
return wolfSSL_CertManagerDisableOCSPStapling(SSL_CM(ssl));
}
else
return BAD_FUNC_ARG;
}
int wolfSSL_SetOCSP_OverrideURL(WOLFSSL* ssl, const char* url)
{
WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
if (ssl) {
SSL_CM_WARNING(ssl);
return wolfSSL_CertManagerSetOCSPOverrideURL(SSL_CM(ssl), url);
}
else
return BAD_FUNC_ARG;
}
int wolfSSL_SetOCSP_Cb(WOLFSSL* ssl,
CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
{
WOLFSSL_ENTER("wolfSSL_SetOCSP_Cb");
if (ssl) {
SSL_CM_WARNING(ssl);
ssl->ocspIOCtx = ioCbCtx; /* use SSL specific ioCbCtx */
return wolfSSL_CertManagerSetOCSP_Cb(SSL_CM(ssl),
ioCb, respFreeCb, NULL);
}
else
return BAD_FUNC_ARG;
}
int wolfSSL_CTX_EnableOCSP(WOLFSSL_CTX* ctx, int options)
{
WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSP");
if (ctx)
return wolfSSL_CertManagerEnableOCSP(ctx->cm, options);
else
return BAD_FUNC_ARG;
}
int wolfSSL_CTX_DisableOCSP(WOLFSSL_CTX* ctx)
{
WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSP");
if (ctx)
return wolfSSL_CertManagerDisableOCSP(ctx->cm);
else
return BAD_FUNC_ARG;
}
int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX* ctx, const char* url)
{
WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
if (ctx)
return wolfSSL_CertManagerSetOCSPOverrideURL(ctx->cm, url);
else
return BAD_FUNC_ARG;
}
int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx, CbOCSPIO ioCb,
CbOCSPRespFree respFreeCb, void* ioCbCtx)
{
WOLFSSL_ENTER("wolfSSL_CTX_SetOCSP_Cb");
if (ctx)
return wolfSSL_CertManagerSetOCSP_Cb(ctx->cm, ioCb,
respFreeCb, ioCbCtx);
else
return BAD_FUNC_ARG;
}
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX* ctx)
{
WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPStapling");
if (ctx)
return wolfSSL_CertManagerEnableOCSPStapling(ctx->cm);
else
return BAD_FUNC_ARG;
}
int wolfSSL_CTX_DisableOCSPStapling(WOLFSSL_CTX* ctx)
{
WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSPStapling");
if (ctx)
return wolfSSL_CertManagerDisableOCSPStapling(ctx->cm);
else
return BAD_FUNC_ARG;
}
int wolfSSL_CTX_EnableOCSPMustStaple(WOLFSSL_CTX* ctx)
{
WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPMustStaple");
if (ctx)
return wolfSSL_CertManagerEnableOCSPMustStaple(ctx->cm);
else
return BAD_FUNC_ARG;
}
int wolfSSL_CTX_DisableOCSPMustStaple(WOLFSSL_CTX* ctx)
{
WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSPMustStaple");
if (ctx)
return wolfSSL_CertManagerDisableOCSPMustStaple(ctx->cm);
else
return BAD_FUNC_ARG;
}
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST || \
* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
/* Not an OpenSSL API. */
int wolfSSL_get_ocsp_response(WOLFSSL* ssl, byte** response)
{
*response = ssl->ocspCsrResp[0].buffer;
return ssl->ocspCsrResp[0].length;
}
/* Not an OpenSSL API. */
char* wolfSSL_get_ocsp_url(WOLFSSL* ssl)
{
return ssl->url;
}
/* Not an OpenSSL API. */
int wolfSSL_set_ocsp_url(WOLFSSL* ssl, char* url)
{
if (ssl == NULL)
return WOLFSSL_FAILURE;
ssl->url = url;
return WOLFSSL_SUCCESS;
}
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
#if !defined(NO_ASN_TIME)
int wolfSSL_get_ocsp_producedDate(
WOLFSSL *ssl,
byte *producedDate,
size_t producedDate_space,
int *producedDateFormat)
{
if ((ssl->ocspProducedDateFormat != ASN_UTC_TIME) &&
(ssl->ocspProducedDateFormat != ASN_GENERALIZED_TIME))
return BAD_FUNC_ARG;
if ((producedDate == NULL) || (producedDateFormat == NULL))
return BAD_FUNC_ARG;
if (XSTRLEN((char *)ssl->ocspProducedDate) >= producedDate_space)
return BUFFER_E;
XSTRNCPY((char *)producedDate, (const char *)ssl->ocspProducedDate,
producedDate_space);
*producedDateFormat = ssl->ocspProducedDateFormat;
return 0;
}
int wolfSSL_get_ocsp_producedDate_tm(WOLFSSL *ssl, struct tm *produced_tm) {
int idx = 0;
if ((ssl->ocspProducedDateFormat != ASN_UTC_TIME) &&
(ssl->ocspProducedDateFormat != ASN_GENERALIZED_TIME))
return BAD_FUNC_ARG;
if (produced_tm == NULL)
return BAD_FUNC_ARG;
if (ExtractDate(ssl->ocspProducedDate,
(unsigned char)ssl->ocspProducedDateFormat, produced_tm, &idx,
MAX_DATE_SZ))
return 0;
else
return ASN_PARSE_E;
}
#endif /* !NO_ASN_TIME */
#endif /* HAVE_OCSP */
#if !defined(NO_TLS) && !defined(NO_WOLFSSL_CLIENT)
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
int wolfSSL_UseOCSPStapling(WOLFSSL* ssl, byte status_type, byte options)
{
WOLFSSL_ENTER("wolfSSL_UseOCSPStapling");
if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
return BAD_FUNC_ARG;
return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
options, NULL, ssl->heap, ssl->devId);
}
int wolfSSL_CTX_UseOCSPStapling(WOLFSSL_CTX* ctx, byte status_type,
byte options)
{
WOLFSSL_ENTER("wolfSSL_CTX_UseOCSPStapling");
if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
return BAD_FUNC_ARG;
return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type,
options, NULL, ctx->heap, ctx->devId);
}
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
int wolfSSL_UseOCSPStaplingV2(WOLFSSL* ssl, byte status_type, byte options)
{
if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
return BAD_FUNC_ARG;
return TLSX_UseCertificateStatusRequestV2(&ssl->extensions, status_type,
options, ssl->heap, ssl->devId);
}
int wolfSSL_CTX_UseOCSPStaplingV2(WOLFSSL_CTX* ctx, byte status_type,
byte options)
{
if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
return BAD_FUNC_ARG;
return TLSX_UseCertificateStatusRequestV2(&ctx->extensions, status_type,
options, ctx->heap, ctx->devId);
}
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
#endif /* !NO_TLS && !NO_WOLFSSL_CLIENT */
#ifdef OPENSSL_EXTRA
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
long wolfSSL_set_tlsext_status_type(WOLFSSL *s, int type)
{
WOLFSSL_ENTER("wolfSSL_set_tlsext_status_type");
if (s == NULL){
return BAD_FUNC_ARG;
}
if (type == WOLFSSL_TLSEXT_STATUSTYPE_ocsp){
int r = TLSX_UseCertificateStatusRequest(&s->extensions, (byte)type, 0,
s, s->heap, s->devId);
return (long)r;
} else {
WOLFSSL_MSG(
"SSL_set_tlsext_status_type only supports TLSEXT_STATUSTYPE_ocsp type.");
return WOLFSSL_FAILURE;
}
}
long wolfSSL_get_tlsext_status_type(WOLFSSL *s)
{
TLSX* extension;
if (s == NULL)
return WOLFSSL_FATAL_ERROR;
extension = TLSX_Find(s->extensions, TLSX_STATUS_REQUEST);
return (extension != NULL) ? WOLFSSL_TLSEXT_STATUSTYPE_ocsp :
WOLFSSL_FATAL_ERROR;
}
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
#endif /* OPENSSL_EXTRA */
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
int wolfSSL_CTX_get_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb* cb)
{
if (ctx == NULL || ctx->cm == NULL || cb == NULL)
return WOLFSSL_FAILURE;
#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
if (ctx->cm->ocsp_stapling == NULL)
return WOLFSSL_FAILURE;
*cb = ctx->cm->ocsp_stapling->statusCb;
#else
(void)cb;
*cb = NULL;
#endif
return WOLFSSL_SUCCESS;
}
int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb cb)
{
if (ctx == NULL || ctx->cm == NULL)
return WOLFSSL_FAILURE;
#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
/* Ensure stapling is on for callback to be used. */
wolfSSL_CTX_EnableOCSPStapling(ctx);
if (ctx->cm->ocsp_stapling == NULL)
return WOLFSSL_FAILURE;
ctx->cm->ocsp_stapling->statusCb = cb;
#else
(void)cb;
#endif
return WOLFSSL_SUCCESS;
}
long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX* ctx, void* arg)
{
if (ctx == NULL || ctx->cm == NULL)
return WOLFSSL_FAILURE;
#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
/* Ensure stapling is on for callback to be used. */
wolfSSL_CTX_EnableOCSPStapling(ctx);
if (ctx->cm->ocsp_stapling == NULL)
return WOLFSSL_FAILURE;
ctx->cm->ocsp_stapling->statusCbArg = arg;
#else
(void)arg;
#endif
return WOLFSSL_SUCCESS;
}
long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *ssl, unsigned char **resp)
{
if (ssl == NULL || resp == NULL)
return 0;
*resp = ssl->ocspCsrResp[0].buffer;
return (long)ssl->ocspCsrResp[0].length;
}
long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *ssl, unsigned char *resp,
int len)
{
return wolfSSL_set_tlsext_status_ocsp_resp_multi(ssl, resp, len, 0);
}
int wolfSSL_set_tlsext_status_ocsp_resp_multi(WOLFSSL* ssl, unsigned char *resp,
int len, word32 idx)
{
if (ssl == NULL || idx >= XELEM_CNT(ssl->ocspCsrResp) || len < 0)
return WOLFSSL_FAILURE;
if (!((resp == NULL) ^ (len > 0)))
return WOLFSSL_FAILURE;
XFREE(ssl->ocspCsrResp[idx].buffer, NULL, 0);
ssl->ocspCsrResp[idx].buffer = resp;
ssl->ocspCsrResp[idx].length = (word32)len;
return WOLFSSL_SUCCESS;
}
#ifndef NO_WOLFSSL_SERVER
void wolfSSL_CTX_set_ocsp_status_verify_cb(WOLFSSL_CTX* ctx,
ocspVerifyStatusCb cb, void* cbArg)
{
if (ctx != NULL) {
ctx->ocspStatusVerifyCb = cb;
ctx->ocspStatusVerifyCbArg = cbArg;
}
}
#endif /* NO_WOLFSSL_SERVER */
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST ||
* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
#endif /* !NO_CERTS */
#endif /* !WOLFSSL_SSL_API_CRL_OCSP_INCLUDED */
+1611
View File
File diff suppressed because it is too large Load Diff
+8 -4
View File
@@ -3334,7 +3334,8 @@ const char* wolfSSL_ASN1_tag2str(int tag)
const char* str = "(unknown)";
/* Clear negative flag. */
if ((tag == WOLFSSL_V_ASN1_NEG_INTEGER) || (tag == WOLFSSL_V_ASN1_NEG_ENUMERATED)) {
if ((tag == WOLFSSL_V_ASN1_NEG_INTEGER) ||
(tag == WOLFSSL_V_ASN1_NEG_ENUMERATED)) {
tag &= ~WOLFSSL_V_ASN1_NEG;
}
/* Check for known basic types. */
@@ -4194,7 +4195,8 @@ char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* t, char* buf, int len)
}
/* Get time as human readable string. */
if ((buf != NULL) && !GetTimeString(t->data, t->type, buf, len, t->length)) {
if ((buf != NULL) && !GetTimeString(t->data, t->type, buf, len,
t->length)) {
buf = NULL;
}
@@ -4717,9 +4719,11 @@ void wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE *a, int type, void *value)
int wolfSSL_ASN1_TYPE_get(const WOLFSSL_ASN1_TYPE *a)
{
if (a != NULL && (a->type == WOLFSSL_V_ASN1_BOOLEAN || a->type == WOLFSSL_V_ASN1_NULL
|| a->value.ptr != NULL))
if (a != NULL && (a->type == WOLFSSL_V_ASN1_BOOLEAN ||
a->type == WOLFSSL_V_ASN1_NULL ||
a->value.ptr != NULL)) {
return a->type;
}
return 0;
}
+818 -3
View File
@@ -25,7 +25,7 @@
#if !defined(WOLFSSL_SSL_CERTMAN_INCLUDED)
#ifndef WOLFSSL_IGNORE_FILE_WARN
#warning ssl_certman.c does not need to be compiled separately from ssl.c
#warning ssl_certman.c not to be compiled separately from ssl.c
#endif
#else
@@ -2142,8 +2142,8 @@ int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options)
/* Initialize the OCSP object. */
if (InitOCSP(cm->ocsp, cm) != 0) {
WOLFSSL_MSG("Init OCSP failed");
/* Dispose of OCSP object - indicating dynamically allocated.
*/
/* Dispose of OCSP object - indicating dynamically
* allocated. */
FreeOCSP(cm->ocsp, 1);
cm->ocsp = NULL;
ret = 0;
@@ -2533,6 +2533,821 @@ int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm, CbOCSPIO ioCb,
#endif /* HAVE_OCSP */
/******************************************************************************
* Internal APIs that use WOLFSSL_CERT_MANAGER
******************************************************************************/
/* hash is the SHA digest of name, just use first 32 bits as hash */
static WC_INLINE word32 HashSigner(const byte* hash)
{
return MakeWordFromHash(hash) % CA_TABLE_SIZE;
}
/* does CA already exist on signer list */
int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash)
{
Signer* signers;
int ret = 0;
word32 row;
if (cm == NULL || hash == NULL) {
return ret;
}
row = HashSigner(hash);
if (wc_LockMutex(&cm->caLock) != 0) {
return ret;
}
signers = cm->caTable[row];
while (signers) {
byte* subjectHash;
#ifndef NO_SKID
subjectHash = signers->subjectKeyIdHash;
#else
subjectHash = signers->subjectNameHash;
#endif
if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
ret = 1; /* success */
break;
}
signers = signers->next;
}
wc_UnLockMutex(&cm->caLock);
return ret;
}
#ifdef WOLFSSL_TRUST_PEER_CERT
/* hash is the SHA digest of name, just use first 32 bits as hash */
static WC_INLINE word32 TrustedPeerHashSigner(const byte* hash)
{
return MakeWordFromHash(hash) % TP_TABLE_SIZE;
}
/* does trusted peer already exist on signer list */
int AlreadyTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DecodedCert* cert)
{
TrustedPeerCert* tp;
int ret = 0;
word32 row = TrustedPeerHashSigner(cert->subjectHash);
if (wc_LockMutex(&cm->tpLock) != 0)
return ret;
tp = cm->tpTable[row];
while (tp) {
if ((XMEMCMP(cert->subjectHash, tp->subjectNameHash,
SIGNER_DIGEST_SIZE) == 0)
#ifndef WOLFSSL_NO_ISSUERHASH_TDPEER
&& (XMEMCMP(cert->issuerHash, tp->issuerHash,
SIGNER_DIGEST_SIZE) == 0)
#endif
)
ret = 1;
#ifndef NO_SKID
if (cert->extSubjKeyIdSet) {
/* Compare SKID as well if available */
if (ret == 1 && XMEMCMP(cert->extSubjKeyId, tp->subjectKeyIdHash,
SIGNER_DIGEST_SIZE) != 0)
ret = 0;
}
#endif
if (ret == 1)
break;
tp = tp->next;
}
wc_UnLockMutex(&cm->tpLock);
return ret;
}
/* return Trusted Peer if found, otherwise NULL
type is what to match on
*/
TrustedPeerCert* GetTrustedPeer(void* vp, DecodedCert* cert)
{
WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
TrustedPeerCert* ret = NULL;
TrustedPeerCert* tp = NULL;
word32 row;
if (cm == NULL || cert == NULL)
return NULL;
row = TrustedPeerHashSigner(cert->subjectHash);
if (wc_LockMutex(&cm->tpLock) != 0)
return ret;
tp = cm->tpTable[row];
while (tp) {
if ((XMEMCMP(cert->subjectHash, tp->subjectNameHash,
SIGNER_DIGEST_SIZE) == 0)
#ifndef WOLFSSL_NO_ISSUERHASH_TDPEER
&& (XMEMCMP(cert->issuerHash, tp->issuerHash,
SIGNER_DIGEST_SIZE) == 0)
#endif
)
ret = tp;
#ifndef NO_SKID
if (cert->extSubjKeyIdSet) {
/* Compare SKID as well if available */
if (ret != NULL && XMEMCMP(cert->extSubjKeyId, tp->subjectKeyIdHash,
SIGNER_DIGEST_SIZE) != 0)
ret = NULL;
}
#endif
if (ret != NULL)
break;
tp = tp->next;
}
wc_UnLockMutex(&cm->tpLock);
return ret;
}
int MatchTrustedPeer(TrustedPeerCert* tp, DecodedCert* cert)
{
if (tp == NULL || cert == NULL)
return BAD_FUNC_ARG;
/* subject key id or subject hash has been compared when searching
tpTable for the cert from function GetTrustedPeer */
/* compare signatures */
if (tp->sigLen == cert->sigLength) {
if (XMEMCMP(tp->sig, cert->signature, cert->sigLength)) {
return WOLFSSL_FAILURE;
}
}
else {
return WOLFSSL_FAILURE;
}
return WOLFSSL_SUCCESS;
}
#endif /* WOLFSSL_TRUST_PEER_CERT */
/* return CA if found, otherwise NULL */
Signer* GetCA(void* vp, byte* hash)
{
WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
Signer* ret = NULL;
Signer* signers;
word32 row = 0;
if (cm == NULL || hash == NULL)
return NULL;
row = HashSigner(hash);
if (wc_LockMutex(&cm->caLock) != 0)
return ret;
signers = cm->caTable[row];
while (signers) {
byte* subjectHash;
#ifndef NO_SKID
subjectHash = signers->subjectKeyIdHash;
#else
subjectHash = signers->subjectNameHash;
#endif
if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
ret = signers;
break;
}
signers = signers->next;
}
wc_UnLockMutex(&cm->caLock);
return ret;
}
#if defined(HAVE_OCSP)
Signer* GetCAByKeyHash(void* vp, const byte* keyHash)
{
WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
Signer* ret = NULL;
Signer* signers;
int row;
if (cm == NULL || keyHash == NULL)
return NULL;
/* try lookup using keyHash as subjKeyID first */
ret = GetCA(vp, (byte*)keyHash);
if (ret != NULL && XMEMCMP(ret->subjectKeyHash, keyHash, KEYID_SIZE) == 0) {
return ret;
}
/* if we can't find the cert, we have to scan the full table */
if (wc_LockMutex(&cm->caLock) != 0)
return NULL;
/* Unfortunately we need to look through the entire table */
for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
for (signers = cm->caTable[row]; signers != NULL;
signers = signers->next) {
if (XMEMCMP(signers->subjectKeyHash, keyHash, KEYID_SIZE) == 0) {
ret = signers;
break;
}
}
}
wc_UnLockMutex(&cm->caLock);
return ret;
}
#endif
#ifdef WOLFSSL_AKID_NAME
Signer* GetCAByAKID(void* vp, const byte* issuer, word32 issuerSz,
const byte* serial, word32 serialSz)
{
WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
Signer* ret = NULL;
Signer* signers;
byte nameHash[SIGNER_DIGEST_SIZE];
byte serialHash[SIGNER_DIGEST_SIZE];
word32 row;
if (cm == NULL || issuer == NULL || issuerSz == 0 ||
serial == NULL || serialSz == 0)
return NULL;
if (CalcHashId(issuer, issuerSz, nameHash) != 0 ||
CalcHashId(serial, serialSz, serialHash) != 0)
return NULL;
if (wc_LockMutex(&cm->caLock) != 0)
return ret;
/* Unfortunately we need to look through the entire table */
for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
for (signers = cm->caTable[row]; signers != NULL;
signers = signers->next) {
if (XMEMCMP(signers->issuerNameHash, nameHash, SIGNER_DIGEST_SIZE)
== 0 && XMEMCMP(signers->serialHash, serialHash,
SIGNER_DIGEST_SIZE) == 0) {
ret = signers;
break;
}
}
}
wc_UnLockMutex(&cm->caLock);
return ret;
}
#endif
#ifndef NO_SKID
/* return CA if found, otherwise NULL. Walk through hash table. */
Signer* GetCAByName(void* vp, byte* hash)
{
WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
Signer* ret = NULL;
Signer* signers;
word32 row;
if (cm == NULL)
return NULL;
if (wc_LockMutex(&cm->caLock) != 0)
return ret;
for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
signers = cm->caTable[row];
while (signers && ret == NULL) {
if (XMEMCMP(hash, signers->subjectNameHash,
SIGNER_DIGEST_SIZE) == 0) {
ret = signers;
}
signers = signers->next;
}
}
wc_UnLockMutex(&cm->caLock);
return ret;
}
#endif
#ifdef WOLFSSL_TRUST_PEER_CERT
/* add a trusted peer cert to linked list */
int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
{
int ret = 0;
int row = 0;
TrustedPeerCert* peerCert;
DecodedCert* cert;
DerBuffer* der = *pDer;
WOLFSSL_MSG("Adding a Trusted Peer Cert");
cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
DYNAMIC_TYPE_DCERT);
if (cert == NULL) {
FreeDer(&der);
return MEMORY_E;
}
InitDecodedCert(cert, der->buffer, der->length, cm->heap);
if ((ret = ParseCert(cert, TRUSTED_PEER_TYPE, verify, cm)) != 0) {
FreeDecodedCert(cert);
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
FreeDer(&der);
return ret;
}
WOLFSSL_MSG("\tParsed new trusted peer cert");
peerCert = (TrustedPeerCert*)XMALLOC(sizeof(TrustedPeerCert), cm->heap,
DYNAMIC_TYPE_CERT);
if (peerCert == NULL) {
FreeDecodedCert(cert);
XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
FreeDer(&der);
return MEMORY_E;
}
XMEMSET(peerCert, 0, sizeof(TrustedPeerCert));
#ifndef IGNORE_NAME_CONSTRAINTS
if (peerCert->permittedNames)
FreeNameSubtrees(peerCert->permittedNames, cm->heap);
if (peerCert->excludedNames)
FreeNameSubtrees(peerCert->excludedNames, cm->heap);
#endif
if (AlreadyTrustedPeer(cm, cert)) {
WOLFSSL_MSG("\tAlready have this CA, not adding again");
FreeTrustedPeer(peerCert, cm->heap);
(void)ret;
}
else {
/* add trusted peer signature */
peerCert->sigLen = cert->sigLength;
peerCert->sig = (byte *)XMALLOC(cert->sigLength, cm->heap,
DYNAMIC_TYPE_SIGNATURE);
if (peerCert->sig == NULL) {
FreeDecodedCert(cert);
XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
FreeTrustedPeer(peerCert, cm->heap);
FreeDer(&der);
return MEMORY_E;
}
XMEMCPY(peerCert->sig, cert->signature, cert->sigLength);
/* add trusted peer name */
peerCert->nameLen = cert->subjectCNLen;
peerCert->name = cert->subjectCN;
#ifndef IGNORE_NAME_CONSTRAINTS
peerCert->permittedNames = cert->permittedNames;
peerCert->excludedNames = cert->excludedNames;
#endif
/* add SKID when available and hash of name */
#ifndef NO_SKID
XMEMCPY(peerCert->subjectKeyIdHash, cert->extSubjKeyId,
SIGNER_DIGEST_SIZE);
#endif
XMEMCPY(peerCert->subjectNameHash, cert->subjectHash,
SIGNER_DIGEST_SIZE);
#ifndef WOLFSSL_NO_ISSUERHASH_TDPEER
XMEMCPY(peerCert->issuerHash, cert->issuerHash,
SIGNER_DIGEST_SIZE);
#endif
/* If Key Usage not set, all uses valid. */
peerCert->next = NULL;
cert->subjectCN = 0;
#ifndef IGNORE_NAME_CONSTRAINTS
cert->permittedNames = NULL;
cert->excludedNames = NULL;
#endif
row = (int)TrustedPeerHashSigner(peerCert->subjectNameHash);
if (wc_LockMutex(&cm->tpLock) == 0) {
peerCert->next = cm->tpTable[row];
cm->tpTable[row] = peerCert; /* takes ownership */
wc_UnLockMutex(&cm->tpLock);
}
else {
WOLFSSL_MSG("\tTrusted Peer Cert Mutex Lock failed");
FreeDecodedCert(cert);
XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
FreeTrustedPeer(peerCert, cm->heap);
FreeDer(&der);
return BAD_MUTEX_E;
}
}
WOLFSSL_MSG("\tFreeing parsed trusted peer cert");
FreeDecodedCert(cert);
XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
WOLFSSL_MSG("\tFreeing der trusted peer cert");
FreeDer(&der);
WOLFSSL_MSG("\t\tOK Freeing der trusted peer cert");
WOLFSSL_LEAVE("AddTrustedPeer", ret);
return WOLFSSL_SUCCESS;
}
#endif /* WOLFSSL_TRUST_PEER_CERT */
int AddSigner(WOLFSSL_CERT_MANAGER* cm, Signer *s)
{
byte* subjectHash;
Signer* signers;
word32 row;
if (cm == NULL || s == NULL)
return BAD_FUNC_ARG;
#ifndef NO_SKID
subjectHash = s->subjectKeyIdHash;
#else
subjectHash = s->subjectNameHash;
#endif
if (AlreadySigner(cm, subjectHash)) {
FreeSigner(s, cm->heap);
return 0;
}
row = HashSigner(subjectHash);
if (wc_LockMutex(&cm->caLock) != 0)
return BAD_MUTEX_E;
signers = cm->caTable[row];
s->next = signers;
cm->caTable[row] = s;
wc_UnLockMutex(&cm->caLock);
return 0;
}
/* owns der, internal now uses too */
/* type flag ids from user or from chain received during verify
don't allow chain ones to be added w/o isCA extension */
int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
{
int ret;
Signer* signer = NULL;
word32 row;
byte* subjectHash;
WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
DerBuffer* der = *pDer;
WOLFSSL_MSG_CERT_LOG("Adding a CA");
if (cm == NULL) {
FreeDer(pDer);
return BAD_FUNC_ARG;
}
#ifdef WOLFSSL_SMALL_STACK
cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
if (cert == NULL) {
FreeDer(pDer);
return MEMORY_E;
}
#endif
InitDecodedCert(cert, der->buffer, der->length, cm->heap);
#ifdef WC_ASN_UNKNOWN_EXT_CB
if (cm->unknownExtCallback != NULL) {
wc_SetUnknownExtCallback(cert, cm->unknownExtCallback);
}
#endif
WOLFSSL_MSG_CERT("\tParsing new CA");
ret = ParseCert(cert, CA_TYPE, verify, cm);
WOLFSSL_MSG("\tParsed new CA");
#ifdef WOLFSSL_DEBUG_CERTS
{
const char* err_msg;
if (ret == 0) {
WOLFSSL_MSG_CERT_EX(WOLFSSL_MSG_CERT_INDENT "issuer: '%s'",
cert->issuer);
WOLFSSL_MSG_CERT_EX(WOLFSSL_MSG_CERT_INDENT "subject: '%s'",
cert->subject);
}
else {
WOLFSSL_MSG_CERT(
WOLFSSL_MSG_CERT_INDENT "Failed during parse of new CA");
err_msg = wc_GetErrorString(ret);
WOLFSSL_MSG_CERT_EX(WOLFSSL_MSG_CERT_INDENT "error ret: %d; %s",
ret, err_msg);
}
}
#endif /* WOLFSSL_DEBUG_CERTS */
#ifndef NO_SKID
subjectHash = cert->extSubjKeyId;
#else
subjectHash = cert->subjectHash;
#endif
/* check CA key size */
if (verify && (ret == 0 )) {
switch (cert->keyOID) {
#ifndef NO_RSA
#ifdef WC_RSA_PSS
case RSAPSSk:
#endif
case RSAk:
if (cm->minRsaKeySz < 0 ||
cert->pubKeySize < (word16)cm->minRsaKeySz) {
ret = RSA_KEY_SIZE_E;
WOLFSSL_MSG_CERT_LOG("\tCA RSA key size error");
WOLFSSL_MSG_CERT_EX("\tCA RSA pubKeySize = %d; "
"minRsaKeySz = %d",
cert->pubKeySize, cm->minRsaKeySz);
}
break;
#endif /* !NO_RSA */
#ifdef HAVE_ECC
case ECDSAk:
if (cm->minEccKeySz < 0 ||
cert->pubKeySize < (word16)cm->minEccKeySz) {
ret = ECC_KEY_SIZE_E;
WOLFSSL_MSG_CERT_LOG("\tCA ECC key size error");
WOLFSSL_MSG_CERT_EX("\tCA ECC pubKeySize = %d; "
"minEccKeySz = %d",
cert->pubKeySize, cm->minEccKeySz);
}
break;
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case ED25519k:
if (cm->minEccKeySz < 0 ||
ED25519_KEY_SIZE < (word16)cm->minEccKeySz) {
ret = ECC_KEY_SIZE_E;
WOLFSSL_MSG("\tCA ECC key size error");
}
break;
#endif /* HAVE_ED25519 */
#ifdef HAVE_ED448
case ED448k:
if (cm->minEccKeySz < 0 ||
ED448_KEY_SIZE < (word16)cm->minEccKeySz) {
ret = ECC_KEY_SIZE_E;
WOLFSSL_MSG("\tCA ECC key size error");
}
break;
#endif /* HAVE_ED448 */
#if defined(HAVE_FALCON)
case FALCON_LEVEL1k:
if (cm->minFalconKeySz < 0 ||
FALCON_LEVEL1_KEY_SIZE < (word16)cm->minFalconKeySz) {
ret = FALCON_KEY_SIZE_E;
WOLFSSL_MSG("\tCA Falcon level 1 key size error");
}
break;
case FALCON_LEVEL5k:
if (cm->minFalconKeySz < 0 ||
FALCON_LEVEL5_KEY_SIZE < (word16)cm->minFalconKeySz) {
ret = FALCON_KEY_SIZE_E;
WOLFSSL_MSG("\tCA Falcon level 5 key size error");
}
break;
#endif /* HAVE_FALCON */
#if defined(HAVE_DILITHIUM)
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
case DILITHIUM_LEVEL2k:
if (cm->minDilithiumKeySz < 0 ||
DILITHIUM_LEVEL2_KEY_SIZE < (word16)cm->minDilithiumKeySz) {
ret = DILITHIUM_KEY_SIZE_E;
WOLFSSL_MSG("\tCA Dilithium level 2 key size error");
}
break;
case DILITHIUM_LEVEL3k:
if (cm->minDilithiumKeySz < 0 ||
DILITHIUM_LEVEL3_KEY_SIZE < (word16)cm->minDilithiumKeySz) {
ret = DILITHIUM_KEY_SIZE_E;
WOLFSSL_MSG("\tCA Dilithium level 3 key size error");
}
break;
case DILITHIUM_LEVEL5k:
if (cm->minDilithiumKeySz < 0 ||
DILITHIUM_LEVEL5_KEY_SIZE < (word16)cm->minDilithiumKeySz) {
ret = DILITHIUM_KEY_SIZE_E;
WOLFSSL_MSG("\tCA Dilithium level 5 key size error");
}
break;
#endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */
case ML_DSA_LEVEL2k:
if (cm->minDilithiumKeySz < 0 ||
ML_DSA_LEVEL2_KEY_SIZE < (word16)cm->minDilithiumKeySz) {
ret = DILITHIUM_KEY_SIZE_E;
WOLFSSL_MSG("\tCA Dilithium level 2 key size error");
}
break;
case ML_DSA_LEVEL3k:
if (cm->minDilithiumKeySz < 0 ||
ML_DSA_LEVEL3_KEY_SIZE < (word16)cm->minDilithiumKeySz) {
ret = DILITHIUM_KEY_SIZE_E;
WOLFSSL_MSG("\tCA Dilithium level 3 key size error");
}
break;
case ML_DSA_LEVEL5k:
if (cm->minDilithiumKeySz < 0 ||
ML_DSA_LEVEL5_KEY_SIZE < (word16)cm->minDilithiumKeySz) {
ret = DILITHIUM_KEY_SIZE_E;
WOLFSSL_MSG("\tCA Dilithium level 5 key size error");
}
break;
#endif /* HAVE_DILITHIUM */
default:
WOLFSSL_MSG("\tNo key size check done on CA");
break; /* no size check if key type is not in switch */
}
}
if (ret == 0 && cert->isCA == 0 && type != WOLFSSL_USER_CA &&
type != WOLFSSL_TEMP_CA) {
WOLFSSL_MSG("\tCan't add as CA if not actually one");
ret = NOT_CA_ERROR;
}
#ifndef ALLOW_INVALID_CERTSIGN
else if (ret == 0 && cert->isCA == 1 && type != WOLFSSL_USER_CA &&
type != WOLFSSL_TEMP_CA && !cert->selfSigned &&
(cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) == 0) {
/* Intermediate CA certs are required to have the keyCertSign
* extension set. User loaded root certs are not. */
WOLFSSL_MSG("\tDoesn't have key usage certificate signing");
ret = NOT_CA_ERROR;
}
#endif
else if (ret == 0 && AlreadySigner(cm, subjectHash)) {
WOLFSSL_MSG("\tAlready have this CA, not adding again");
(void)ret;
}
else if (ret == 0) {
/* take over signer parts */
signer = MakeSigner(cm->heap);
if (!signer)
ret = MEMORY_ERROR;
}
if (ret == 0 && signer != NULL) {
ret = FillSigner(signer, cert, type, der);
if (ret == 0){
#ifndef NO_SKID
row = HashSigner(signer->subjectKeyIdHash);
#else
row = HashSigner(signer->subjectNameHash);
#endif
}
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS)
/* Verify CA by TSIP so that generated tsip key is going to */
/* be able to be used for peer's cert verification */
/* TSIP is only able to handle USER CA, and only one CA. */
/* Therefore, it doesn't need to call TSIP again if there is already */
/* verified CA. */
if ( ret == 0 && signer != NULL ) {
signer->cm_idx = row;
if (type == WOLFSSL_USER_CA) {
if ((ret = wc_Renesas_cmn_RootCertVerify(cert->source,
cert->maxIdx,
cert->sigCtx.CertAtt.pubkey_n_start,
cert->sigCtx.CertAtt.pubkey_n_len - 1,
cert->sigCtx.CertAtt.pubkey_e_start,
cert->sigCtx.CertAtt.pubkey_e_len - 1,
row/* cm index */))
< 0)
WOLFSSL_MSG("Renesas_RootCertVerify() failed");
else
WOLFSSL_MSG("Renesas_RootCertVerify() succeed or skipped");
}
}
#endif /* TSIP or SCE */
if (ret == 0 && wc_LockMutex(&cm->caLock) == 0) {
signer->next = cm->caTable[row];
cm->caTable[row] = signer; /* takes ownership */
wc_UnLockMutex(&cm->caLock);
if (cm->caCacheCallback)
cm->caCacheCallback(der->buffer, (int)der->length, type);
}
else {
WOLFSSL_MSG("\tCA Mutex Lock failed");
ret = BAD_MUTEX_E;
}
}
WOLFSSL_MSG("\tFreeing Parsed CA");
FreeDecodedCert(cert);
if (ret != 0 && signer != NULL)
FreeSigner(signer, cm->heap);
WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
WOLFSSL_MSG("\tFreeing der CA");
FreeDer(pDer);
WOLFSSL_MSG("\t\tOK Freeing der CA");
WOLFSSL_LEAVE("AddCA", ret);
return ret == 0 ? WOLFSSL_SUCCESS : ret;
}
/* Removes the CA with the passed in subject hash from the
cert manager's CA cert store. */
int RemoveCA(WOLFSSL_CERT_MANAGER* cm, byte* hash, int type)
{
Signer* current;
Signer** prev;
int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
word32 row;
WOLFSSL_MSG("Removing a CA");
if (cm == NULL || hash == NULL) {
return BAD_FUNC_ARG;
}
row = HashSigner(hash);
if (wc_LockMutex(&cm->caLock) != 0) {
return BAD_MUTEX_E;
}
current = cm->caTable[row];
prev = &cm->caTable[row];
while (current) {
byte* subjectHash;
#ifndef NO_SKID
subjectHash = current->subjectKeyIdHash;
#else
subjectHash = current->subjectNameHash;
#endif
if ((current->type == type) &&
(XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0)) {
*prev = current->next;
FreeSigner(current, cm->heap);
ret = WOLFSSL_SUCCESS;
break;
}
prev = &current->next;
current = current->next;
}
wc_UnLockMutex(&cm->caLock);
WOLFSSL_LEAVE("RemoveCA", ret);
return ret;
}
/* Sets the CA with the passed in subject hash
to the provided type. */
int SetCAType(WOLFSSL_CERT_MANAGER* cm, byte* hash, int type)
{
Signer* current;
int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
word32 row;
WOLFSSL_MSG_EX("Setting CA to type %d", type);
if (cm == NULL || hash == NULL ||
type < WOLFSSL_USER_CA || type > WOLFSSL_USER_INTER) {
return ret;
}
row = HashSigner(hash);
if (wc_LockMutex(&cm->caLock) != 0) {
return ret;
}
current = cm->caTable[row];
while (current) {
byte* subjectHash;
#ifndef NO_SKID
subjectHash = current->subjectKeyIdHash;
#else
subjectHash = current->subjectNameHash;
#endif
if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
current->type = (byte)type;
ret = WOLFSSL_SUCCESS;
break;
}
current = current->next;
}
wc_UnLockMutex(&cm->caLock);
WOLFSSL_LEAVE("SetCAType", ret);
return ret;
}
#endif /* NO_CERTS */
#endif /* !WOLFSSL_SSL_CERTMAN_INCLUDED */
+8 -5
View File
@@ -3071,8 +3071,8 @@ void wolfSSL_AES_decrypt(const unsigned char* input, unsigned char* output,
WOLFSSL_MSG("Null argument passed in");
}
else
#if !defined(HAVE_SELFTEST) && \
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION3_GE(5,3,0)))
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
(defined(FIPS_VERSION_GE) && FIPS_VERSION3_GE(5,3,0)))
/* Decrypt a block with wolfCrypt AES. */
if (wc_AesDecryptDirect((Aes*)key, output, input) != 0) {
WOLFSSL_MSG("wc_AesDecryptDirect failed");
@@ -3203,7 +3203,8 @@ void wolfSSL_AES_cbc_encrypt(const unsigned char *in, unsigned char* out,
* AES_ENCRPT for encryption, AES_DECRYPTION for decryption.
*/
void wolfSSL_AES_cfb128_encrypt(const unsigned char *in, unsigned char* out,
size_t len, WOLFSSL_AES_KEY *key, unsigned char* iv, int* num, const int enc)
size_t len, WOLFSSL_AES_KEY *key, unsigned char* iv, int* num,
const int enc)
{
#ifndef WOLFSSL_AES_CFB
WOLFSSL_MSG("CFB mode not enabled please use macro WOLFSSL_AES_CFB");
@@ -3435,13 +3436,15 @@ size_t wolfSSL_CRYPTO_cts128_decrypt(const unsigned char *in,
* Use 0 buffer as IV to do straight decryption.
* This places the Cn-1 block at lastBlk */
XMEMSET(lastBlk, 0, WOLFSSL_CTS128_BLOCK_SZ);
(*cbc)(in, prevBlk, WOLFSSL_CTS128_BLOCK_SZ, key, lastBlk, AES_DECRYPTION);
(*cbc)(in, prevBlk, WOLFSSL_CTS128_BLOCK_SZ, key, lastBlk,
AES_DECRYPTION);
/* RFC2040: Append the tail (BB minus Ln) bytes of Xn to Cn
* to create En. */
XMEMCPY(prevBlk, in + WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen);
/* Cn and Cn-1 can now be decrypted */
(*cbc)(prevBlk, out, WOLFSSL_CTS128_BLOCK_SZ, key, iv, AES_DECRYPTION);
(*cbc)(lastBlk, lastBlk, WOLFSSL_CTS128_BLOCK_SZ, key, iv, AES_DECRYPTION);
(*cbc)(lastBlk, lastBlk, WOLFSSL_CTS128_BLOCK_SZ, key, iv,
AES_DECRYPTION);
XMEMCPY(out + WOLFSSL_CTS128_BLOCK_SZ, lastBlk, lastBlkLen);
}
+738
View File
@@ -0,0 +1,738 @@
/* ssl_ech.c
*
* Copyright (C) 2006-2025 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#if !defined(WOLFSSL_SSL_ECH_INCLUDED)
#ifndef WOLFSSL_IGNORE_FILE_WARN
#warning ssl_ech.c does not need to be compiled separately from ssl.c
#endif
#else
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
/* create the hpke key and ech config to send to clients */
int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx, const char* publicName,
word16 kemId, word16 kdfId, word16 aeadId)
{
int ret = 0;
word16 encLen = DHKEM_X25519_ENC_LEN;
WOLFSSL_EchConfig* newConfig;
WOLFSSL_EchConfig* parentConfig;
#ifdef WOLFSSL_SMALL_STACK
Hpke* hpke = NULL;
WC_RNG* rng;
#else
Hpke hpke[1];
WC_RNG rng[1];
#endif
if (ctx == NULL || publicName == NULL)
return BAD_FUNC_ARG;
WC_ALLOC_VAR_EX(rng, WC_RNG, 1, ctx->heap, DYNAMIC_TYPE_RNG,
return MEMORY_E);
ret = wc_InitRng(rng);
if (ret != 0) {
WC_FREE_VAR_EX(rng, ctx->heap, DYNAMIC_TYPE_RNG);
return ret;
}
newConfig = (WOLFSSL_EchConfig*)XMALLOC(sizeof(WOLFSSL_EchConfig),
ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (newConfig == NULL)
ret = MEMORY_E;
else
XMEMSET(newConfig, 0, sizeof(WOLFSSL_EchConfig));
/* set random config id */
if (ret == 0)
ret = wc_RNG_GenerateByte(rng, &newConfig->configId);
/* if 0 is selected for algorithms use default, may change with draft */
if (kemId == 0)
kemId = DHKEM_X25519_HKDF_SHA256;
if (kdfId == 0)
kdfId = HKDF_SHA256;
if (aeadId == 0)
aeadId = HPKE_AES_128_GCM;
if (ret == 0) {
/* set the kem id */
newConfig->kemId = kemId;
/* set the cipher suite, only 1 for now */
newConfig->numCipherSuites = 1;
newConfig->cipherSuites =
(EchCipherSuite*)XMALLOC(sizeof(EchCipherSuite), ctx->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (newConfig->cipherSuites == NULL) {
ret = MEMORY_E;
}
else {
newConfig->cipherSuites[0].kdfId = kdfId;
newConfig->cipherSuites[0].aeadId = aeadId;
}
}
#ifdef WOLFSSL_SMALL_STACK
if (ret == 0) {
hpke = (Hpke*)XMALLOC(sizeof(Hpke), ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (hpke == NULL)
ret = MEMORY_E;
}
#endif
if (ret == 0)
ret = wc_HpkeInit(hpke, kemId, kdfId, aeadId, ctx->heap);
/* generate the receiver private key */
if (ret == 0)
ret = wc_HpkeGenerateKeyPair(hpke, &newConfig->receiverPrivkey, rng);
/* done with RNG */
wc_FreeRng(rng);
/* serialize the receiver key */
if (ret == 0)
ret = wc_HpkeSerializePublicKey(hpke, newConfig->receiverPrivkey,
newConfig->receiverPubkey, &encLen);
if (ret == 0) {
newConfig->publicName = (char*)XMALLOC(XSTRLEN(publicName) + 1,
ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (newConfig->publicName == NULL) {
ret = MEMORY_E;
}
else {
XMEMCPY(newConfig->publicName, publicName,
XSTRLEN(publicName) + 1);
}
}
if (ret != 0) {
if (newConfig) {
XFREE(newConfig->cipherSuites, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(newConfig->publicName, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(newConfig, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
}
else {
parentConfig = ctx->echConfigs;
if (parentConfig == NULL) {
ctx->echConfigs = newConfig;
}
else {
while (parentConfig->next != NULL) {
parentConfig = parentConfig->next;
}
parentConfig->next = newConfig;
}
}
if (ret == 0)
ret = WOLFSSL_SUCCESS;
WC_FREE_VAR_EX(hpke, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
WC_FREE_VAR_EX(rng, ctx->heap, DYNAMIC_TYPE_RNG);
return ret;
}
int wolfSSL_CTX_SetEchConfigsBase64(WOLFSSL_CTX* ctx, const char* echConfigs64,
word32 echConfigs64Len)
{
int ret = 0;
word32 decodedLen = echConfigs64Len * 3 / 4 + 1;
byte* decodedConfigs;
if (ctx == NULL || echConfigs64 == NULL || echConfigs64Len == 0)
return BAD_FUNC_ARG;
decodedConfigs = (byte*)XMALLOC(decodedLen, ctx->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (decodedConfigs == NULL)
return MEMORY_E;
decodedConfigs[decodedLen - 1] = 0;
/* decode the echConfigs */
ret = Base64_Decode((const byte*)echConfigs64, echConfigs64Len,
decodedConfigs, &decodedLen);
if (ret != 0) {
XFREE(decodedConfigs, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
ret = wolfSSL_CTX_SetEchConfigs(ctx, decodedConfigs, decodedLen);
XFREE(decodedConfigs, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
int wolfSSL_CTX_SetEchConfigs(WOLFSSL_CTX* ctx, const byte* echConfigs,
word32 echConfigsLen)
{
int ret;
if (ctx == NULL || echConfigs == NULL || echConfigsLen == 0)
return BAD_FUNC_ARG;
FreeEchConfigs(ctx->echConfigs, ctx->heap);
ctx->echConfigs = NULL;
ret = SetEchConfigsEx(&ctx->echConfigs, ctx->heap, echConfigs,
echConfigsLen);
if (ret == 0)
return WOLFSSL_SUCCESS;
return ret;
}
/* get the ech configs that the server context is using */
int wolfSSL_CTX_GetEchConfigs(WOLFSSL_CTX* ctx, byte* output,
word32* outputLen) {
if (ctx == NULL || outputLen == NULL)
return BAD_FUNC_ARG;
/* if we don't have ech configs */
if (ctx->echConfigs == NULL)
return WOLFSSL_FATAL_ERROR;
return GetEchConfigsEx(ctx->echConfigs, output, outputLen);
}
void wolfSSL_CTX_SetEchEnable(WOLFSSL_CTX* ctx, byte enable)
{
if (ctx != NULL) {
ctx->disableECH = !enable;
if (ctx->disableECH) {
TLSX_Remove(&ctx->extensions, TLSX_ECH, ctx->heap);
FreeEchConfigs(ctx->echConfigs, ctx->heap);
ctx->echConfigs = NULL;
}
}
}
/* set the ech config from base64 for our client ssl object, base64 is the
* format ech configs are sent using dns records */
int wolfSSL_SetEchConfigsBase64(WOLFSSL* ssl, char* echConfigs64,
word32 echConfigs64Len)
{
int ret = 0;
word32 decodedLen = echConfigs64Len * 3 / 4 + 1;
byte* decodedConfigs;
if (ssl == NULL || echConfigs64 == NULL || echConfigs64Len == 0)
return BAD_FUNC_ARG;
/* already have ech configs */
if (ssl->options.useEch == 1) {
return WOLFSSL_FATAL_ERROR;
}
decodedConfigs = (byte*)XMALLOC(decodedLen, ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (decodedConfigs == NULL)
return MEMORY_E;
decodedConfigs[decodedLen - 1] = 0;
/* decode the echConfigs */
ret = Base64_Decode((byte*)echConfigs64, echConfigs64Len,
decodedConfigs, &decodedLen);
if (ret != 0) {
XFREE(decodedConfigs, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
ret = wolfSSL_SetEchConfigs(ssl, decodedConfigs, decodedLen);
XFREE(decodedConfigs, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
/* set the ech config from a raw buffer, this is the format ech configs are
* sent using retry_configs from the ech server */
int wolfSSL_SetEchConfigs(WOLFSSL* ssl, const byte* echConfigs,
word32 echConfigsLen)
{
int ret;
if (ssl == NULL || echConfigs == NULL || echConfigsLen == 0)
return BAD_FUNC_ARG;
/* already have ech configs */
if (ssl->options.useEch == 1) {
return WOLFSSL_FATAL_ERROR;
}
ret = SetEchConfigsEx(&ssl->echConfigs, ssl->heap, echConfigs,
echConfigsLen);
/* if we found valid configs */
if (ret == 0) {
ssl->options.useEch = 1;
return WOLFSSL_SUCCESS;
}
return ret;
}
/* get the raw ech config from our struct */
int GetEchConfig(WOLFSSL_EchConfig* config, byte* output, word32* outputLen)
{
int i;
word16 totalLen = 0;
if (config == NULL || (output == NULL && outputLen == NULL))
return BAD_FUNC_ARG;
/* 2 for version */
totalLen += 2;
/* 2 for length */
totalLen += 2;
/* 1 for configId */
totalLen += 1;
/* 2 for kemId */
totalLen += 2;
/* 2 for hpke_len */
totalLen += 2;
/* hpke_pub_key */
switch (config->kemId) {
case DHKEM_P256_HKDF_SHA256:
totalLen += DHKEM_P256_ENC_LEN;
break;
case DHKEM_P384_HKDF_SHA384:
totalLen += DHKEM_P384_ENC_LEN;
break;
case DHKEM_P521_HKDF_SHA512:
totalLen += DHKEM_P521_ENC_LEN;
break;
case DHKEM_X25519_HKDF_SHA256:
totalLen += DHKEM_X25519_ENC_LEN;
break;
case DHKEM_X448_HKDF_SHA512:
totalLen += DHKEM_X448_ENC_LEN;
break;
}
/* cipherSuitesLen */
totalLen += 2;
/* cipherSuites */
totalLen += config->numCipherSuites * 4;
/* public name len */
totalLen += 2;
/* public name */
totalLen += XSTRLEN(config->publicName);
/* trailing zeros */
totalLen += 2;
if (output == NULL) {
*outputLen = totalLen;
return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
}
if (totalLen > *outputLen) {
*outputLen = totalLen;
return INPUT_SIZE_E;
}
/* version */
c16toa(TLSX_ECH, output);
output += 2;
/* length - 4 for version and length itself */
c16toa(totalLen - 4, output);
output += 2;
/* configId */
*output = config->configId;
output++;
/* kemId */
c16toa(config->kemId, output);
output += 2;
/* length and key itself */
switch (config->kemId) {
case DHKEM_P256_HKDF_SHA256:
c16toa(DHKEM_P256_ENC_LEN, output);
output += 2;
XMEMCPY(output, config->receiverPubkey, DHKEM_P256_ENC_LEN);
output += DHKEM_P256_ENC_LEN;
break;
case DHKEM_P384_HKDF_SHA384:
c16toa(DHKEM_P384_ENC_LEN, output);
output += 2;
XMEMCPY(output, config->receiverPubkey, DHKEM_P384_ENC_LEN);
output += DHKEM_P384_ENC_LEN;
break;
case DHKEM_P521_HKDF_SHA512:
c16toa(DHKEM_P521_ENC_LEN, output);
output += 2;
XMEMCPY(output, config->receiverPubkey, DHKEM_P521_ENC_LEN);
output += DHKEM_P521_ENC_LEN;
break;
case DHKEM_X25519_HKDF_SHA256:
c16toa(DHKEM_X25519_ENC_LEN, output);
output += 2;
XMEMCPY(output, config->receiverPubkey, DHKEM_X25519_ENC_LEN);
output += DHKEM_X25519_ENC_LEN;
break;
case DHKEM_X448_HKDF_SHA512:
c16toa(DHKEM_X448_ENC_LEN, output);
output += 2;
XMEMCPY(output, config->receiverPubkey, DHKEM_X448_ENC_LEN);
output += DHKEM_X448_ENC_LEN;
break;
}
/* cipherSuites len */
c16toa(config->numCipherSuites * 4, output);
output += 2;
/* cipherSuites */
for (i = 0; i < config->numCipherSuites; i++) {
c16toa(config->cipherSuites[i].kdfId, output);
output += 2;
c16toa(config->cipherSuites[i].aeadId, output);
output += 2;
}
/* set maximum name length to 0 */
*output = 0;
output++;
/* publicName len */
*output = XSTRLEN(config->publicName);
output++;
/* publicName */
XMEMCPY(output, config->publicName,
XSTRLEN(config->publicName));
output += XSTRLEN(config->publicName);
/* terminating zeros */
c16toa(0, output);
/* output += 2; */
*outputLen = totalLen;
return 0;
}
/* wrapper function to get ech configs from application code */
int wolfSSL_GetEchConfigs(WOLFSSL* ssl, byte* output, word32* outputLen)
{
if (ssl == NULL || outputLen == NULL)
return BAD_FUNC_ARG;
/* if we don't have ech configs */
if (ssl->options.useEch != 1) {
return WOLFSSL_FATAL_ERROR;
}
return GetEchConfigsEx(ssl->echConfigs, output, outputLen);
}
void wolfSSL_SetEchEnable(WOLFSSL* ssl, byte enable)
{
if (ssl != NULL) {
ssl->options.disableECH = !enable;
if (ssl->options.disableECH) {
TLSX_Remove(&ssl->extensions, TLSX_ECH, ssl->heap);
FreeEchConfigs(ssl->echConfigs, ssl->heap);
ssl->echConfigs = NULL;
}
}
}
int SetEchConfigsEx(WOLFSSL_EchConfig** outputConfigs, void* heap,
const byte* echConfigs, word32 echConfigsLen)
{
int ret = 0;
int i;
int j;
word16 totalLength;
word16 version;
word16 length;
word16 hpkePubkeyLen;
word16 cipherSuitesLen;
word16 publicNameLen;
WOLFSSL_EchConfig* configList = NULL;
WOLFSSL_EchConfig* workingConfig = NULL;
WOLFSSL_EchConfig* lastConfig = NULL;
byte* echConfig = NULL;
if (outputConfigs == NULL || echConfigs == NULL || echConfigsLen == 0)
return BAD_FUNC_ARG;
/* check that the total length is well formed */
ato16(echConfigs, &totalLength);
if (totalLength != echConfigsLen - 2) {
return WOLFSSL_FATAL_ERROR;
}
/* skip the total length uint16_t */
i = 2;
do {
echConfig = (byte*)echConfigs + i;
ato16(echConfig, &version);
ato16(echConfig + 2, &length);
/* if the version does not match */
if (version != TLSX_ECH) {
/* we hit the end of the configs */
if ( (word32)i + 2 >= echConfigsLen ) {
break;
}
/* skip this config, +4 for version and length */
i += length + 4;
continue;
}
/* check if the length will overrun the buffer */
if ((word32)i + length + 4 > echConfigsLen) {
break;
}
if (workingConfig == NULL) {
workingConfig =
(WOLFSSL_EchConfig*)XMALLOC(sizeof(WOLFSSL_EchConfig), heap,
DYNAMIC_TYPE_TMP_BUFFER);
configList = workingConfig;
if (workingConfig != NULL) {
workingConfig->next = NULL;
}
}
else {
lastConfig = workingConfig;
workingConfig->next =
(WOLFSSL_EchConfig*)XMALLOC(sizeof(WOLFSSL_EchConfig),
heap, DYNAMIC_TYPE_TMP_BUFFER);
workingConfig = workingConfig->next;
}
if (workingConfig == NULL) {
ret = MEMORY_E;
break;
}
XMEMSET(workingConfig, 0, sizeof(WOLFSSL_EchConfig));
/* rawLen */
workingConfig->rawLen = length + 4;
/* raw body */
workingConfig->raw = (byte*)XMALLOC(workingConfig->rawLen,
heap, DYNAMIC_TYPE_TMP_BUFFER);
if (workingConfig->raw == NULL) {
ret = MEMORY_E;
break;
}
XMEMCPY(workingConfig->raw, echConfig, workingConfig->rawLen);
/* skip over version and length */
echConfig += 4;
/* configId, 1 byte */
workingConfig->configId = *(echConfig);
echConfig++;
/* kemId, 2 bytes */
ato16(echConfig, &workingConfig->kemId);
echConfig += 2;
/* hpke public_key length, 2 bytes */
ato16(echConfig, &hpkePubkeyLen);
echConfig += 2;
/* hpke public_key */
XMEMCPY(workingConfig->receiverPubkey, echConfig, hpkePubkeyLen);
echConfig += hpkePubkeyLen;
/* cipherSuitesLen */
ato16(echConfig, &cipherSuitesLen);
workingConfig->cipherSuites = (EchCipherSuite*)XMALLOC(cipherSuitesLen,
heap, DYNAMIC_TYPE_TMP_BUFFER);
if (workingConfig->cipherSuites == NULL) {
ret = MEMORY_E;
break;
}
echConfig += 2;
workingConfig->numCipherSuites = cipherSuitesLen / 4;
/* cipherSuites */
for (j = 0; j < workingConfig->numCipherSuites; j++) {
ato16(echConfig + j * 4, &workingConfig->cipherSuites[j].kdfId);
ato16(echConfig + j * 4 + 2,
&workingConfig->cipherSuites[j].aeadId);
}
echConfig += cipherSuitesLen;
/* ignore the maximum name length */
echConfig++;
/* publicNameLen */
publicNameLen = *(echConfig);
workingConfig->publicName = (char*)XMALLOC(publicNameLen + 1,
heap, DYNAMIC_TYPE_TMP_BUFFER);
if (workingConfig->publicName == NULL) {
ret = MEMORY_E;
break;
}
echConfig++;
/* publicName */
XMEMCPY(workingConfig->publicName, echConfig, publicNameLen);
/* null terminated */
workingConfig->publicName[publicNameLen] = 0;
/* add length to go to next config, +4 for version and length */
i += length + 4;
/* check that we support this config */
for (j = 0; j < HPKE_SUPPORTED_KEM_LEN; j++) {
if (hpkeSupportedKem[j] == workingConfig->kemId)
break;
}
/* if we don't support the kem or at least one cipher suite */
if (j >= HPKE_SUPPORTED_KEM_LEN ||
EchConfigGetSupportedCipherSuite(workingConfig) < 0)
{
XFREE(workingConfig->cipherSuites, heap,
DYNAMIC_TYPE_TMP_BUFFER);
XFREE(workingConfig->publicName, heap,
DYNAMIC_TYPE_TMP_BUFFER);
XFREE(workingConfig->raw, heap, DYNAMIC_TYPE_TMP_BUFFER);
workingConfig = lastConfig;
}
} while ((word32)i < echConfigsLen);
/* if we found valid configs */
if (ret == 0 && configList != NULL) {
*outputConfigs = configList;
return ret;
}
workingConfig = configList;
while (workingConfig != NULL) {
lastConfig = workingConfig;
workingConfig = workingConfig->next;
XFREE(lastConfig->cipherSuites, heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(lastConfig->publicName, heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(lastConfig->raw, heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(lastConfig, heap, DYNAMIC_TYPE_TMP_BUFFER);
}
if (ret == 0)
return WOLFSSL_FATAL_ERROR;
return ret;
}
/* get the raw ech configs from our linked list of ech config structs */
int GetEchConfigsEx(WOLFSSL_EchConfig* configs, byte* output, word32* outputLen)
{
int ret = 0;
WOLFSSL_EchConfig* workingConfig = NULL;
byte* outputStart = output;
word32 totalLen = 2;
word32 workingOutputLen = 0;
if (configs == NULL || outputLen == NULL ||
(output != NULL && *outputLen < totalLen)) {
return BAD_FUNC_ARG;
}
/* skip over total length which we fill in later */
if (output != NULL) {
workingOutputLen = *outputLen - totalLen;
output += 2;
}
else {
/* caller getting the size only, set current 2 byte length size */
*outputLen = totalLen;
}
workingConfig = configs;
while (workingConfig != NULL) {
/* get this config */
ret = GetEchConfig(workingConfig, output, &workingOutputLen);
if (output != NULL)
output += workingOutputLen;
/* add this config's length to the total length */
totalLen += workingOutputLen;
if (totalLen > *outputLen)
workingOutputLen = 0;
else
workingOutputLen = *outputLen - totalLen;
/* only error we break on, other 2 we need to keep finding length */
if (ret == WC_NO_ERR_TRACE(BAD_FUNC_ARG))
return BAD_FUNC_ARG;
workingConfig = workingConfig->next;
}
if (output == NULL) {
*outputLen = totalLen;
return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
}
if (totalLen > *outputLen) {
*outputLen = totalLen;
return INPUT_SIZE_E;
}
/* total size -2 for size itself */
c16toa(totalLen - 2, outputStart);
*outputLen = totalLen;
return WOLFSSL_SUCCESS;
}
#endif /* WOLFSSL_TLS13 && HAVE_ECH */
#endif /* !WOLFSSL_SSL_ECH_INCLUDED */
+25 -18
View File
@@ -928,7 +928,8 @@ static int ProcessBufferTryDecodeDilithium(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
if (ret == 0) {
/* Decode as a Dilithium private key. */
idx = 0;
ret = wc_Dilithium_PrivateKeyDecode(der->buffer, &idx, key, der->length);
ret = wc_Dilithium_PrivateKeyDecode(der->buffer, &idx, key,
der->length);
if (ret == 0) {
ret = dilithium_get_oid_sum(key, &keyFormatTemp);
if (ret == 0) {
@@ -1079,11 +1080,9 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
}
#ifdef WC_RSA_PSS
if((ret == 0) && (*keyFormat == RSAPSSk)) {
/*
Require logic to verify that the der is RSAPSSk (when *keyFormat == RSAPSSK),
and to detect that the der is RSAPSSk (when *keyFormat == 0).
*/
/* Require logic to verify that the der is RSAPSSk
* (when *keyFormat == RSAPSSK), and to detect that the der is RSAPSSk
* (when *keyFormat == 0). */
matchAnyKey = 1;
}
#endif /* WC_RSA_PSS */
@@ -2138,7 +2137,8 @@ static int ProcessBufferCertHandleDer(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
* certificates so we can inject them at verification time */
if (ret == 1 && ctx->doAppleNativeCertValidationFlag == 1) {
WOLFSSL_MSG("ANCV Test: Appending CA to cert list");
ret = wolfSSL_TestAppleNativeCertValidation_AppendCA(ctx, derBuf, (int)derLen);
ret = wolfSSL_TestAppleNativeCertValidation_AppendCA(ctx, derBuf,
(int)derLen);
if (ret == WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ANCV Test: Clearing CA table");
/* Clear the CA table so we can ensure they won't be used for
@@ -2949,8 +2949,8 @@ int wolfSSL_CTX_load_verify_locations_ex(WOLFSSL_CTX* ctx, const char* file,
NULL, verify);
#else
/* Load the DER formatted CA file */
ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_ASN1, CA_TYPE, NULL, 0,
NULL, verify);
ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_ASN1, CA_TYPE, NULL,
0, NULL, verify);
#endif
#ifndef NO_WOLFSSL_DIR
if (ret == 1) {
@@ -3234,8 +3234,8 @@ int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX* ctx, const char* file)
ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CERT_TYPE, NULL, 1, NULL,
GET_VERIFY_SETTING_CTX(ctx));
#else
ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_ASN1, CERT_TYPE, NULL, 1, NULL,
GET_VERIFY_SETTING_CTX(ctx));
ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_ASN1, CERT_TYPE, NULL, 1,
NULL, GET_VERIFY_SETTING_CTX(ctx));
#endif
/* Return 1 on success or 0 on failure. */
@@ -4893,7 +4893,8 @@ static int wolfssl_ctx_add_to_chain(WOLFSSL_CTX* ctx, const byte* der,
if (res == 1) {
/* Add chain to DER buffer. */
res = wolfssl_add_to_chain(&ctx->certChain, 1, der, (word32)derSz, ctx->heap);
res = wolfssl_add_to_chain(&ctx->certChain, 1, der, (word32)derSz,
ctx->heap);
#ifdef WOLFSSL_TLS13
/* Update count of certificates. */
ctx->certChainCnt++;
@@ -5439,7 +5440,8 @@ int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX* ctx)
}
#else
/* OpenSSL's implementation of this API does not require loading the
system CA cert directory. Allow skipping this without erroring out. */
* system CA cert directory. Allow skipping this without erroring out.
*/
ret = 1;
#endif
}
@@ -5560,8 +5562,10 @@ int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
if (ret == 1) {
/* Allocate buffers for p and g to be assigned into SSL. */
pAlloc = (byte*)XMALLOC((size_t)pSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
gAlloc = (byte*)XMALLOC((size_t)gSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
pAlloc = (byte*)XMALLOC((size_t)pSz, ssl->heap,
DYNAMIC_TYPE_PUBLIC_KEY);
gAlloc = (byte*)XMALLOC((size_t)gSz, ssl->heap,
DYNAMIC_TYPE_PUBLIC_KEY);
if ((pAlloc == NULL) || (gAlloc == NULL)) {
/* Memory will be freed below in the (ret != 1) block */
ret = MEMORY_E;
@@ -5612,7 +5616,8 @@ static int wolfssl_check_dh_key(unsigned char* p, int pSz, unsigned char* g,
/* Initialize a DH object. */
if ((ret = wc_InitDhKey(checkKey)) == 0) {
/* Check DH parameters. */
ret = wc_DhSetCheckKey(checkKey, p, (word32)pSz, g, (word32)gSz, NULL, 0, 0, &rng);
ret = wc_DhSetCheckKey(checkKey, p, (word32)pSz, g, (word32)gSz,
NULL, 0, 0, &rng);
/* Dispose of DH object. */
wc_FreeDhKey(checkKey);
}
@@ -5708,8 +5713,10 @@ int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
if (ret == 1) {
/* Allocate buffers for p and g to be assigned into SSL context. */
pAlloc = (byte*)XMALLOC((size_t)pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
gAlloc = (byte*)XMALLOC((size_t)gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
pAlloc = (byte*)XMALLOC((size_t)pSz, ctx->heap,
DYNAMIC_TYPE_PUBLIC_KEY);
gAlloc = (byte*)XMALLOC((size_t)gSz, ctx->heap,
DYNAMIC_TYPE_PUBLIC_KEY);
if ((pAlloc == NULL) || (gAlloc == NULL)) {
ret = MEMORY_E;
}
+6 -4
View File
@@ -1029,7 +1029,8 @@ int wolfSSL_PEM_write_bio_PKCS7(WOLFSSL_BIO* bio, PKCS7* p7)
XMEMSET(pem, 0, pemSz);
if (wc_DerToPemEx(output, outputSz, pem, (word32)pemSz, NULL, CERT_TYPE) < 0) {
if (wc_DerToPemEx(output, outputSz, pem, (word32)pemSz, NULL,CERT_TYPE)
< 0) {
goto error;
}
if ((wolfSSL_BIO_write(bio, pem, pemSz) == pemSz)) {
@@ -1368,8 +1369,8 @@ PKCS7* wolfSSL_SMIME_read_PKCS7(WOLFSSL_BIO* in,
WOLFSSL_MSG("Error base64 decoding S/MIME message.");
goto error;
}
pkcs7 = wolfSSL_d2i_PKCS7_only(NULL, (const unsigned char**)&out, (int)outLen,
bcontMem, (word32)bcontMemSz);
pkcs7 = wolfSSL_d2i_PKCS7_only(NULL, (const unsigned char**)&out,
(int)outLen, bcontMem, (word32)bcontMemSz);
wc_MIME_free_hdrs(allHdrs);
XFREE(outHead, NULL, DYNAMIC_TYPE_PKCS7);
@@ -1912,7 +1913,8 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
DYNAMIC_TYPE_X509);
InitX509(x509, 1, heap);
InitDecodedCert(DeCert, current->buffer, current->bufferSz, heap);
if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL, NULL) != 0) {
if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL, NULL)
!= 0) {
WOLFSSL_MSG("Issue with parsing certificate");
FreeDecodedCert(DeCert);
wolfSSL_X509_free(x509);
+18 -12
View File
@@ -968,7 +968,8 @@ WOLFSSL_SESSION* wolfSSL_GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
}
/* start from most recently used */
count = (int)min((word32)ClientCache[row].totalCount, CLIENT_SESSIONS_PER_ROW);
count = (int)min((word32)ClientCache[row].totalCount,
CLIENT_SESSIONS_PER_ROW);
idx = ClientCache[row].nextIdx - 1;
if (idx < 0 || idx >= CLIENT_SESSIONS_PER_ROW) {
/* if back to front, the previous was end */
@@ -997,7 +998,8 @@ WOLFSSL_SESSION* wolfSSL_GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
#else
current = &sessRow->Sessions[clSess[idx].serverIdx];
#endif
if (current && XMEMCMP(current->serverID, id, (unsigned long)len) == 0) {
if (current && XMEMCMP(current->serverID, id,
(unsigned long)len) == 0) {
WOLFSSL_MSG("Found a serverid match for client");
if (LowResTimer() < (current->bornOn + current->timeout)) {
WOLFSSL_MSG("Session valid");
@@ -1265,8 +1267,8 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
#endif
if (output->ticketLenAlloc)
XFREE(output->ticket, output->heap, DYNAMIC_TYPE_SESSION_TICK);
output->ticket = tmpTicket; /* cppcheck-suppress autoVariables
*/
/* cppcheck-suppress autoVariables */
output->ticket = tmpTicket;
output->ticketLenAlloc = PREALLOC_SESSION_TICKET_LEN;
output->ticketLen = 0;
tmpBufSet = 1;
@@ -1394,7 +1396,8 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
output->ticketLen = 0;
}
if (error == WOLFSSL_SUCCESS) {
XMEMCPY(output->ticket, tmpTicket, output->ticketLen); /* cppcheck-suppress uninitvar */
/* cppcheck-suppress uninitvar */
XMEMCPY(output->ticket, tmpTicket, output->ticketLen);
}
}
WC_FREE_VAR_EX(tmpTicket, output->heap, DYNAMIC_TYPE_TMP_BUFFER);
@@ -1839,8 +1842,9 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
if (SESSION_ROW_WR_LOCK(sessRow) != 0) {
#ifdef HAVE_SESSION_TICKET
XFREE(ticBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && \
FIPS_VERSION_GE(5,3)))
XFREE(preallocNonce, addSession->heap, DYNAMIC_TYPE_SESSION_TICK);
#endif
#endif
@@ -1879,8 +1883,9 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
if (cacheSession == NULL) {
#ifdef HAVE_SESSION_TICKET
XFREE(ticBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && \
FIPS_VERSION_GE(5,3)))
XFREE(preallocNonce, addSession->heap, DYNAMIC_TYPE_SESSION_TICK);
#endif
#endif
@@ -2028,8 +2033,8 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
#ifndef NO_CLIENT_CACHE
if (ret == 0 && clientCacheEntry != NULL) {
ClientSession* clientCache = AddSessionToClientCache(side, row, (int)idx,
addSession->serverID, addSession->idLen, id, useTicket);
ClientSession* clientCache = AddSessionToClientCache(side, row,
(int)idx, addSession->serverID, addSession->idLen, id, useTicket);
if (clientCache != NULL)
*clientCacheEntry = clientCache;
}
@@ -4088,7 +4093,8 @@ void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
ForceZero(session->sessionID, ID_LEN);
if (session->type == WOLFSSL_SESSION_TYPE_HEAP) {
XFREE(session, session->heap, DYNAMIC_TYPE_SESSION); /* // NOLINT(clang-analyzer-unix.Malloc) */
/* // NOLINTNEXTLINE(clang-analyzer-unix.Malloc) */
XFREE(session, session->heap, DYNAMIC_TYPE_SESSION);
}
}
+3 -5
View File
@@ -36,9 +36,8 @@
#include <tests/api/api.h>
#include <tests/api/test_ossl_x509_str.h>
#if defined(OPENSSL_ALL) && \
!defined(NO_RSA) && !defined(NO_FILESYSTEM)
#if defined(OPENSSL_ALL) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) && \
!defined(NO_ASN_TIME)
static int last_errcodes[10];
static int last_errdepths[10];
static int err_index = 0;
@@ -187,8 +186,7 @@ int test_wolfSSL_X509_STORE_check_time(void)
wolfSSL_X509_free(cert);
cert = NULL;
#if defined(OPENSSL_ALL) && \
!defined(NO_RSA) && !defined(NO_FILESYSTEM)
#if defined(OPENSSL_ALL) && !defined(NO_RSA) && !defined(NO_FILESYSTEM)
err_index = 0;
File diff suppressed because it is too large Load Diff
+1
View File
@@ -12,6 +12,7 @@ MAINTAINERCLEANFILES+= $(ASYNC_FILES)
EXTRA_DIST += wolfcrypt/src/misc.c
EXTRA_DIST += wolfcrypt/src/evp.c
EXTRA_DIST += wolfcrypt/src/evp_pk.c
EXTRA_DIST += wolfcrypt/src/asm.c
EXTRA_DIST += wolfcrypt/src/aes_asm.asm
EXTRA_DIST += wolfcrypt/src/aes_gcm_asm.asm
+4
View File
@@ -4990,6 +4990,10 @@ extern void uITRON4_free(void *p) ;
#error "If TLS is enabled please make sure either client or server is enabled."
#endif
#if defined(WC_RNG_BANK_SUPPORT) && defined(NO_ASN_TIME)
#undef WC_RNG_BANK_SUPPORT
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif