Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
233 changes: 233 additions & 0 deletions doc/dox_comments/header_files/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -15257,6 +15257,239 @@ RFC 9146 and RFC 9147.
const unsigned char* wolfSSL_dtls_cid_parse(const unsigned char* msg,
unsigned int msgSz, unsigned int cidSz);

/*!
\ingroup TLS
\brief On the server, this sets a list of CA names to be sent to clients in
certificate requests as a hint for which CA's are supported by the server.

On the client, this function has no effect.

\param [in] ctx Pointer to the wolfSSL context
\param [in] names List of names to be set

\sa wolfSSL_set_client_CA_list
\sa wolfSSL_CTX_get_client_CA_list
\sa wolfSSL_get_client_CA_list
\sa wolfSSL_CTX_set0_CA_list
\sa wolfSSL_set0_CA_list
\sa wolfSSL_CTX_get0_CA_list
\sa wolfSSL_get0_CA_list
\sa wolfSSL_get0_peer_CA_list
*/
void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
WOLF_STACK_OF(WOLFSSL_X509_NAME)* names);

/*!
\ingroup TLS
\brief This retrieves the list previously set via
wolfSSL_CTX_set_client_CA_list, or NULL if no list has been set.

\param [in] ctx Pointer to the wolfSSL context
\return A stack of WOLFSSL_X509_NAMEs containing the CA names

\sa wolfSSL_set_client_CA_list
\sa wolfSSL_CTX_set_client_CA_list
\sa wolfSSL_get_client_CA_list
\sa wolfSSL_CTX_set0_CA_list
\sa wolfSSL_set0_CA_list
\sa wolfSSL_CTX_get0_CA_list
\sa wolfSSL_get0_CA_list
\sa wolfSSL_get0_peer_CA_list
*/
WOLFSSL_STACK *wolfSSL_CTX_get_client_CA_list(
const WOLFSSL_CTX *ctx);

/*!
\ingroup TLS
\brief Same as wolfSSL_CTX_set_client_CA_list, but specific to a session.
If a CA list is set on both the context and the session, the list on the
session is used.

\param [in] ssl Pointer to the WOLFSSL object
\param [in] names List of names to be set.

\sa wolfSSL_CTX_set_client_CA_list
\sa wolfSSL_CTX_get_client_CA_list
\sa wolfSSL_get_client_CA_list
\sa wolfSSL_CTX_set0_CA_list
\sa wolfSSL_set0_CA_list
\sa wolfSSL_CTX_get0_CA_list
\sa wolfSSL_get0_CA_list
\sa wolfSSL_get0_peer_CA_list
*/
void wolfSSL_set_client_CA_list(WOLFSSL* ssl,
WOLF_STACK_OF(WOLFSSL_X509_NAME)* names);

/*!
\ingroup TLS
\brief On the server, this retrieves the list previously set via
wolfSSL_set_client_CA_list. If none was set, returns the list previously
set via wolfSSL_CTX_set_client_CA_list. If no list at all was set, returns
NULL.

On the client, this retrieves the list that was received from the server,
or NULL if none was received. wolfSSL_CTX_set_cert_cb can be used to
register a callback to dynamically load certificates when a certificate
request is received from the server.

\param [in] ssl Pointer to the WOLFSSL object
\return A stack of WOLFSSL_X509_NAMEs containing the CA names

\sa wolfSSL_CTX_set_cert_cb
\sa wolfSSL_CTX_set_client_CA_list
\sa wolfSSL_CTX_get_client_CA_list
\sa wolfSSL_get_client_CA_list
\sa wolfSSL_CTX_set0_CA_list
\sa wolfSSL_set0_CA_list
\sa wolfSSL_CTX_get0_CA_list
\sa wolfSSL_get0_CA_list
\sa wolfSSL_get0_peer_CA_list
*/
WOLFSSL_STACK* wolfSSL_get_client_CA_list(
const WOLFSSL* ssl);

/*!
\ingroup TLS
\brief This function sets a list of CA names to be sent to the peer as a
hint for which CA's are supported for its authentication.

In TLS >= 1.3, this is supported in both directions between the client and
the server. On the server, the CA names will be sent as part of a
CertificateRequest, making this function an equivalent of *_set_client_CA_list;
on the client, these are sent as part of ClientHello.

In TLS < 1.3, sending CA names from the client to the server is not
supported, therefore this function is equivalent to
wolfSSL_CTX_set_client_CA_list.

Note that the lists set via *_set_client_CA_list and *_set0_CA_list are
separate internally, i.e. calling *_get_client_CA_list will not retrieve a
list set via *_set0_CA_list and vice versa. If both are set, the server will
ignore *_set0_CA_list when sending CA names to the client.

\param [in] ctx Pointer to the wolfSSL context
\param [in] names List of names to be set

\sa wolfSSL_CTX_set_client_CA_list
\sa wolfSSL_set_client_CA_list
\sa wolfSSL_CTX_get_client_CA_list
\sa wolfSSL_get_client_CA_list
\sa wolfSSL_set0_CA_list
\sa wolfSSL_CTX_get0_CA_list
\sa wolfSSL_get0_CA_list
\sa wolfSSL_get0_peer_CA_list
*/
void wolfSSL_CTX_set0_CA_list(WOLFSSL_CTX *ctx,
WOLF_STACK_OF(WOLFSSL_X509_NAME)* names);

/*!
\ingroup TLS
\brief This retrieves the list previously set via
wolfSSL_CTX_set0_CA_list, or NULL if no list has been set.

\param [in] ctx Pointer to the wolfSSL context
\return A stack of WOLFSSL_X509_NAMEs containing the CA names

\sa wolfSSL_CTX_set_client_CA_list
\sa wolfSSL_set_client_CA_list
\sa wolfSSL_CTX_get_client_CA_list
\sa wolfSSL_get_client_CA_list
\sa wolfSSL_CTX_set0_CA_list
\sa wolfSSL_set0_CA_list
\sa wolfSSL_get0_CA_list
\sa wolfSSL_get0_peer_CA_list
*/
WOLFSSL_STACK *wolfSSL_CTX_get0_CA_list(
const WOLFSSL_CTX *ctx);

/*!
\ingroup TLS
\brief Same as wolfSSL_CTX_set0_CA_list, but specific to a session.
If a CA list is set on both the context and the session, the list on the
session is used.

\param [in] ssl Pointer to the WOLFSSL object
\param [in] names List of names to be set.

\sa wolfSSL_CTX_set_client_CA_list
\sa wolfSSL_set_client_CA_list
\sa wolfSSL_CTX_get_client_CA_list
\sa wolfSSL_get_client_CA_list
\sa wolfSSL_CTX_set0_CA_list
\sa wolfSSL_CTX_get0_CA_list
\sa wolfSSL_get0_CA_list
\sa wolfSSL_get0_peer_CA_list
*/
void wolfSSL_set0_CA_list(WOLFSSL *ssl,
WOLF_STACK_OF(WOLFSSL_X509_NAME) *names);

/*!
\ingroup TLS
\brief This retrieves the list previously set via wolfSSL_set0_CA_list. If
none was set, returns the list previously set via
wolfSSL_CTX_set0_CA_list. If no list at all was set, returns NULL.

\param [in] ssl Pointer to the WOLFSSL object
\return A stack of WOLFSSL_X509_NAMEs containing the CA names

\sa wolfSSL_CTX_set_client_CA_list
\sa wolfSSL_set_client_CA_list
\sa wolfSSL_CTX_get_client_CA_list
\sa wolfSSL_get_client_CA_list
\sa wolfSSL_CTX_set0_CA_list
\sa wolfSSL_set0_CA_list
\sa wolfSSL_CTX_get0_CA_list
\sa wolfSSL_get0_peer_CA_list
*/
WOLFSSL_STACK *wolfSSL_get0_CA_list(
const WOLFSSL *ssl);

/*!
\ingroup TLS
\brief This returns the CA list received from the peer.

On the client, this is the list sent by the server in a CertificateRequest,
and this function is equivalent to wolfSSL_get_client_CA_list.

On the server, this is the list sent by the client in the ClientHello message
in TLS >= 1.3; in TLS < 1.3, the function always returns NULL on the server
side.

wolfSSL_CTX_set_cert_cb can be used to register a callback to dynamically
load certificates when a CA list is received from the peer.

\param [in] ssl Pointer to the WOLFSSL object
\return A stack of WOLFSSL_X509_NAMEs containing the CA names

\sa wolfSSL_CTX_set_cert_cb
\sa wolfSSL_CTX_set_client_CA_list
\sa wolfSSL_set_client_CA_list
\sa wolfSSL_CTX_get_client_CA_list
\sa wolfSSL_get_client_CA_list
\sa wolfSSL_CTX_set0_CA_list
\sa wolfSSL_set0_CA_list
\sa wolfSSL_CTX_get0_CA_list
\sa wolfSSL_get0_CA_list
*/
WOLFSSL_STACK *wolfSSL_get0_peer_CA_list(const WOLFSSL *ssl);

/*!
\ingroup TLS
\brief This function sets a callback that will be called whenever a
certificate is about to be used, to allow the application to inspect, set
or clear any certificates, for example to react to a CA list sent from the
peer.

\param [in] ctx Pointer to the wolfSSL context
\param [in] cb Function pointer to the callback
\param [in] arg Pointer that will be passed to the callback

\sa wolfSSL_get0_peer_CA_list
\sa wolfSSL_get_client_CA_list
*/
void wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX* ctx,
int (*cb)(WOLFSSL *, void *), void *arg);

/*!
\ingroup TLS

Expand Down
32 changes: 22 additions & 10 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -2877,6 +2877,8 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
#ifndef WOLFSSL_NO_CA_NAMES
wolfSSL_sk_X509_NAME_pop_free(ctx->client_ca_names, NULL);
ctx->client_ca_names = NULL;
wolfSSL_sk_X509_NAME_pop_free(ctx->ca_names, NULL);
ctx->ca_names = NULL;
#endif
#ifdef OPENSSL_EXTRA
if (ctx->x509Chain) {
Expand Down Expand Up @@ -6667,9 +6669,11 @@ int InitSSL_Suites(WOLFSSL* ssl)
byte haveAnon = 0;
byte haveRSA = 0;
byte haveMcast = 0;
byte haveCertSetupCb = 0;

(void)haveAnon; /* Squash unused var warnings */
(void)haveMcast;
(void)haveCertSetupCb;

if (!ssl)
return BAD_FUNC_ARG;
Expand All @@ -6688,6 +6692,10 @@ int InitSSL_Suites(WOLFSSL* ssl)
haveMcast = (byte)ssl->options.haveMcast;
#endif /* WOLFSSL_MULTICAST */
#endif /* !NO_CERTS && !WOLFSSL_SESSION_EXPORT */
#if defined(WOLFSSL_TLS13) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
if (ssl->ctx->certSetupCb != NULL)
haveCertSetupCb = 1;
#endif /* WOLFSSL_TLS13 && !NO_CERTS && OPENSSL_EXTRA */

#ifdef WOLFSSL_EARLY_DATA
if (ssl->options.side == WOLFSSL_SERVER_END)
Expand Down Expand Up @@ -6715,10 +6723,11 @@ int InitSSL_Suites(WOLFSSL* ssl)
}

#if !defined(NO_CERTS) && !defined(WOLFSSL_SESSION_EXPORT)
/* make sure server has cert and key unless using PSK, Anon, or
* Multicast. This should be true even if just switching ssl ctx */
/* make sure server has cert and key unless using PSK, Anon,
* Multicast or cert setup callback. This should be true even if just
* switching ssl ctx */
if (ssl->options.side == WOLFSSL_SERVER_END &&
!havePSK && !haveAnon && !haveMcast) {
!havePSK && !haveAnon && !haveMcast && !haveCertSetupCb) {

/* server certificate must be loaded */
if (!ssl->buffers.certificate || !ssl->buffers.certificate->buffer) {
Expand Down Expand Up @@ -8789,6 +8798,10 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl)
#ifndef WOLFSSL_NO_CA_NAMES
wolfSSL_sk_X509_NAME_pop_free(ssl->client_ca_names, NULL);
ssl->client_ca_names = NULL;
wolfSSL_sk_X509_NAME_pop_free(ssl->ca_names, NULL);
ssl->ca_names = NULL;
wolfSSL_sk_X509_NAME_pop_free(ssl->peer_ca_names, NULL);
ssl->peer_ca_names = NULL;
#endif
#ifdef WOLFSSL_DTLS13
Dtls13FreeFsmResources(ssl);
Expand Down Expand Up @@ -24823,7 +24836,7 @@ int SendCertificateRequest(WOLFSSL* ssl)

#ifndef WOLFSSL_NO_CA_NAMES
/* Certificate Authorities */
names = SSL_CA_NAMES(ssl);
names = SSL_PRIORITY_CA_NAMES(ssl);
while (names != NULL) {
byte seq[MAX_SEQ_SZ];
WOLFSSL_X509_NAME* name = names->data.name;
Expand Down Expand Up @@ -24915,7 +24928,7 @@ int SendCertificateRequest(WOLFSSL* ssl)
c16toa((word16)dnLen, &output[i]); /* auth's */
i += REQ_HEADER_SZ;
#ifndef WOLFSSL_NO_CA_NAMES
names = SSL_CA_NAMES(ssl);
names = SSL_PRIORITY_CA_NAMES(ssl);
while (names != NULL) {
byte seq[MAX_SEQ_SZ];
WOLFSSL_X509_NAME* name = names->data.name;
Expand Down Expand Up @@ -31745,10 +31758,9 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
return BUFFER_ERROR;

#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)
if (ssl->client_ca_names != ssl->ctx->client_ca_names)
wolfSSL_sk_X509_NAME_pop_free(ssl->client_ca_names, NULL);
ssl->client_ca_names = wolfSSL_sk_X509_NAME_new(NULL);
if (ssl->client_ca_names == NULL) {
wolfSSL_sk_X509_NAME_pop_free(ssl->peer_ca_names, NULL);
ssl->peer_ca_names = wolfSSL_sk_X509_NAME_new(NULL);
if (ssl->peer_ca_names == NULL) {
return MEMORY_ERROR;
}
#endif
Expand Down Expand Up @@ -31793,7 +31805,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
}

if (ret == 0) {
if (wolfSSL_sk_X509_NAME_push(ssl->client_ca_names, name)
if (wolfSSL_sk_X509_NAME_push(ssl->peer_ca_names, name)
<= 0)
{
ret = MEMORY_ERROR;
Expand Down
Loading
Loading