Skip to content
Draft
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
54 changes: 54 additions & 0 deletions doc/dox_comments/header_files/asn_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -4405,3 +4405,57 @@ int wc_Asn1_PrintAll(Asn1* asn1, Asn1PrintOptions* opts, unsigned char* data,
*/
int wc_Asn1_SetOidToNameCb(Asn1* asn1, Asn1OidToNameCb nameCb);

/*!
\ingroup ASN

\brief Retrieves the raw DER-encoded subject Name content from a parsed
DecodedCert.

The returned pointer and size reference the inner content of the subject
Name SEQUENCE (i.e. the bytes after the SEQUENCE tag and length). The
pointer aliases memory inside the DecodedCert and must not be freed by
the caller. The data remains valid until the DecodedCert is freed.

This function is intended for use with wolfSSL_UseCertificateAuthority(),
which expects the subject content without the outer SEQUENCE header.

Requires IGNORE_NAME_CONSTRAINTS to be undefined or WOLFSSL_CERT_EXT to
be defined.

\param cert Pointer to the DecodedCert (must have been parsed).
\param subjectRaw Output pointer that receives the address of the raw
DER subject content.
\param subjectRawSz Output pointer that receives the size in bytes of the
raw subject content.

\return 0 on success.
\return BAD_FUNC_ARG if any argument is NULL.
\return ASN_PARSE_E if the subject was not populated during parsing.
\return NOT_COMPILED_IN if the required build options are not enabled.

_Example_
\code
DecodedCert decoded;
const byte* subject = NULL;
int subjectSz = 0;

wc_InitDecodedCert(&decoded, certDer, certDerSz, NULL);
if (wc_ParseCert(&decoded, CERT_TYPE, NO_VERIFY, NULL) == 0) {
if (wc_GetDecodedCertSubjectRaw(&decoded, &subject,
&subjectSz) == 0) {
// subject and subjectSz now reference the raw DER content
}
}
wc_FreeDecodedCert(&decoded);
\endcode

\sa wc_InitDecodedCert
\sa wc_ParseCert
\sa wc_FreeDecodedCert
\sa wc_GetDecodedCertSubject
\sa wolfSSL_UseCertificateAuthority
*/
int wc_GetDecodedCertSubjectRaw(const struct DecodedCert* cert,
const byte** subjectRaw,
int* subjectRawSz);

220 changes: 220 additions & 0 deletions doc/dox_comments/header_files/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -17128,3 +17128,223 @@ int wolfSSL_get_scr_check_enabled(const WOLFSSL* ssl);
\sa wolfSSL_get_scr_check_enabled
*/
int wolfSSL_set_scr_check_enabled(WOLFSSL* ssl, byte enabled);

/*!
\ingroup TLS

\brief Adds a CA distinguished name to the list of certificate authorities
announced via the TLS 1.3 certificate_authorities extension (RFC 8446
section 4.2.4) on the given SSL session. The DN must be the inner content
of a DER-encoded X.509 Name (the bytes after the SEQUENCE tag and length),
as returned by wc_GetDecodedCertSubjectRaw(). The library copies the
bytes and prepends the SEQUENCE header on the wire automatically.

Multiple DNs may be added; each call appends to the list. Use
wolfSSL_ClearCertificateAuthorities() to reset the list.
Comment on lines +17142 to +17143

Requires WOLFSSL_TLS13 and !NO_CERTS and !WOLFSSL_NO_CA_NAMES.

\return 0 on success.
\return BAD_FUNC_ARG if ssl or dn is NULL, dnSz is 0, or dnSz exceeds
the maximum content size.
\return MEMORY_E if memory allocation fails.
Comment on lines +17147 to +17150

\param ssl pointer to a WOLFSSL object, created with wolfSSL_new().
\param dn pointer to the DER-encoded subject Name content.
\param dnSz size in bytes of the DN content.

_Example_
\code
DecodedCert decoded;
const byte* subject = NULL;
int subjectSz = 0;

wc_InitDecodedCert(&decoded, certDer, certDerSz, NULL);
wc_ParseCert(&decoded, CERT_TYPE, NO_VERIFY, NULL);
wc_GetDecodedCertSubjectRaw(&decoded, &subject, &subjectSz);

ret = wolfSSL_UseCertificateAuthority(ssl, subject,
(unsigned int)subjectSz);
if (ret != 0) {
// error adding CA DN
}
wc_FreeDecodedCert(&decoded);
\endcode

\sa wolfSSL_CTX_UseCertificateAuthority
\sa wolfSSL_ClearCertificateAuthorities
\sa wolfSSL_GetPeerCertificateAuthorityCount
\sa wolfSSL_GetPeerCertificateAuthority
\sa wc_GetDecodedCertSubjectRaw
*/
int wolfSSL_UseCertificateAuthority(WOLFSSL* ssl,
const unsigned char* dn, unsigned int dnSz);

/*!
\ingroup TLS

\brief Adds a CA distinguished name to the list of certificate authorities
announced via the TLS 1.3 certificate_authorities extension (RFC 8446
section 4.2.4) on all SSL sessions created from this context. The DN
format and requirements are identical to wolfSSL_UseCertificateAuthority().

Per-session lists set via wolfSSL_UseCertificateAuthority() take
precedence; if the SSL object has its own list, the CTX list is not sent.

Requires WOLFSSL_TLS13 and !NO_CERTS and !WOLFSSL_NO_CA_NAMES.

\return 0 on success.
\return BAD_FUNC_ARG if ctx or dn is NULL, dnSz is 0, or dnSz exceeds
the maximum content size.
\return MEMORY_E if memory allocation fails.
Comment on lines +17196 to +17199

\param ctx pointer to a WOLFSSL_CTX object, created with
wolfSSL_CTX_new().
\param dn pointer to the DER-encoded subject Name content.
\param dnSz size in bytes of the DN content.

_Example_
\code
ret = wolfSSL_CTX_UseCertificateAuthority(ctx, subject,
(unsigned int)subjectSz);
if (ret != 0) {
// error adding CA DN
}
\endcode

\sa wolfSSL_UseCertificateAuthority
\sa wolfSSL_CTX_ClearCertificateAuthorities
\sa wc_GetDecodedCertSubjectRaw
*/
int wolfSSL_CTX_UseCertificateAuthority(WOLFSSL_CTX* ctx,
const unsigned char* dn, unsigned int dnSz);

/*!
\ingroup TLS

\brief Frees and removes all CA distinguished names previously added to
the SSL session via wolfSSL_UseCertificateAuthority(). After this call
the session-level native CA list is empty; the CTX-level list (if any) is
not affected.

Requires WOLFSSL_TLS13 and !NO_CERTS and !WOLFSSL_NO_CA_NAMES.

\return none No return value.

\param ssl pointer to a WOLFSSL object, created with wolfSSL_new().

_Example_
\code
wolfSSL_UseCertificateAuthority(ssl, dn1, dn1Sz);
wolfSSL_UseCertificateAuthority(ssl, dn2, dn2Sz);
// Clear all session-level CA DNs:
wolfSSL_ClearCertificateAuthorities(ssl);
\endcode

\sa wolfSSL_UseCertificateAuthority
\sa wolfSSL_CTX_ClearCertificateAuthorities
*/
void wolfSSL_ClearCertificateAuthorities(WOLFSSL* ssl);

/*!
\ingroup TLS

\brief Frees and removes all CA distinguished names previously added to
the context via wolfSSL_CTX_UseCertificateAuthority(). After this call
the CTX-level native CA list is empty.

Requires WOLFSSL_TLS13 and !NO_CERTS and !WOLFSSL_NO_CA_NAMES.

\return none No return value.

\param ctx pointer to a WOLFSSL_CTX object, created with
wolfSSL_CTX_new().

_Example_
\code
wolfSSL_CTX_UseCertificateAuthority(ctx, dn, dnSz);
// Clear all CTX-level CA DNs:
wolfSSL_CTX_ClearCertificateAuthorities(ctx);
\endcode

\sa wolfSSL_CTX_UseCertificateAuthority
\sa wolfSSL_ClearCertificateAuthorities
*/
void wolfSSL_CTX_ClearCertificateAuthorities(WOLFSSL_CTX* ctx);

/*!
\ingroup TLS

\brief Returns the number of CA distinguished names received from the peer
in the TLS 1.3 certificate_authorities extension. This is typically called
inside a cert_cb (WOLFSSL_CERT_SETUP_CB) on the server side to inspect
which CAs the client trusts.

Requires WOLFSSL_TLS13 and !NO_CERTS and !WOLFSSL_NO_CA_NAMES.

\return >= 0 The number of peer CA DNs. Returns 0 if ssl is NULL or no
certificate_authorities extension was received.

\param ssl pointer to a WOLFSSL object, created with wolfSSL_new().

_Example_
\code
int count = wolfSSL_GetPeerCertificateAuthorityCount(ssl);
for (int i = 0; i < count; i++) {
int sz = wolfSSL_GetPeerCertificateAuthority(ssl, i, NULL, 0);
// sz is the DN size in bytes
}
\endcode

\sa wolfSSL_GetPeerCertificateAuthority
\sa wolfSSL_UseCertificateAuthority
*/
int wolfSSL_GetPeerCertificateAuthorityCount(const WOLFSSL* ssl);

/*!
\ingroup TLS

\brief Copies the idx-th CA distinguished name received from the peer in
the TLS 1.3 certificate_authorities extension into the caller's buffer.
The DN is the inner content of the DER-encoded Name (without the SEQUENCE
header), matching the format accepted by wolfSSL_UseCertificateAuthority().

If outDn is NULL, returns the size of the DN in bytes (allowing the caller
to allocate the right amount of memory). If outDn is non-NULL and outDnSz
is large enough, copies the DN bytes and returns the number of bytes
written. If outDnSz is too small, returns BUFFER_E.

Requires WOLFSSL_TLS13 and !NO_CERTS and !WOLFSSL_NO_CA_NAMES.

\return > 0 The number of bytes written to outDn, or the DN size if
outDn is NULL.
\return BAD_FUNC_ARG if ssl is NULL or idx is out of range.
\return BUFFER_E if outDnSz is smaller than the DN.

\param ssl pointer to a WOLFSSL object, created with wolfSSL_new().
\param idx zero-based index of the peer CA DN to retrieve. Must be less
than the count returned by wolfSSL_GetPeerCertificateAuthorityCount().
\param outDn output buffer to receive the DN bytes, or NULL to query size.
\param outDnSz size of the output buffer in bytes.

_Example_
\code
int count = wolfSSL_GetPeerCertificateAuthorityCount(ssl);
for (int i = 0; i < count; i++) {
int sz = wolfSSL_GetPeerCertificateAuthority(ssl, i, NULL, 0);
if (sz > 0) {
unsigned char* dn = malloc(sz);
wolfSSL_GetPeerCertificateAuthority(ssl, i, dn,
(unsigned int)sz);
// use dn[0..sz-1]
free(dn);
}
}
\endcode

\sa wolfSSL_GetPeerCertificateAuthorityCount
\sa wolfSSL_UseCertificateAuthority
\sa wc_GetDecodedCertSubjectRaw
*/
int wolfSSL_GetPeerCertificateAuthority(const WOLFSSL* ssl, int idx,
unsigned char* outDn, unsigned int outDnSz);
22 changes: 17 additions & 5 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -3100,12 +3100,17 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
defined(WOLFSSL_WPAS_SMALL)
wolfSSL_X509_STORE_free(ctx->x509_store_pt);
#endif
#ifndef WOLFSSL_NO_CA_NAMES
#if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
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
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES) && \
defined(WOLFSSL_TLS13)
TLSX_CertificateAuthorities_FreeAll(ctx->ws_ca_names, ctx->heap);
ctx->ws_ca_names = NULL;
#endif
#ifdef OPENSSL_EXTRA
if (ctx->x509Chain) {
wolfSSL_sk_X509_pop_free(ctx->x509Chain, NULL);
Expand Down Expand Up @@ -9822,14 +9827,21 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl)
wolfSSL_sk_X509_pop_free(ssl->ourCertChain, NULL);
#endif
#endif
#ifndef WOLFSSL_NO_CA_NAMES
#if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
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
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES) && \
defined(WOLFSSL_TLS13)
TLSX_CertificateAuthorities_FreeAll(ssl->ws_ca_names, ssl->heap);
ssl->ws_ca_names = NULL;
TLSX_CertificateAuthorities_FreeAll(ssl->ws_peer_ca_names, ssl->heap);
ssl->ws_peer_ca_names = NULL;
#endif
#ifdef WOLFSSL_DTLS13
Dtls13FreeFsmResources(ssl);

Expand Down Expand Up @@ -27712,7 +27724,7 @@ int SendCertificateRequest(WOLFSSL* ssl)
int sendSz;
word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
word32 dnLen = 0;
#ifndef WOLFSSL_NO_CA_NAMES
#if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
WOLF_STACK_OF(WOLFSSL_X509_NAME)* names;
#endif
byte certTypes[MAX_CERT_REQ_CERT_TYPE_CNT];
Expand All @@ -27734,7 +27746,7 @@ int SendCertificateRequest(WOLFSSL* ssl)
if (IsAtLeastTLSv1_2(ssl))
reqSz += LENGTH_SZ + localHashSigAlgoSz;

#ifndef WOLFSSL_NO_CA_NAMES
#if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
/* Certificate Authorities */
names = SSL_PRIORITY_CA_NAMES(ssl);
while (names != NULL) {
Expand Down Expand Up @@ -27800,7 +27812,7 @@ int SendCertificateRequest(WOLFSSL* ssl)
/* Certificate Authorities */
c16toa((word16)dnLen, &output[i]); /* auth's */
i += REQ_HEADER_SZ;
#ifndef WOLFSSL_NO_CA_NAMES
#if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
names = SSL_PRIORITY_CA_NAMES(ssl);
while (names != NULL) {
byte seq[MAX_SEQ_SZ];
Expand Down
2 changes: 1 addition & 1 deletion src/ssl_api_cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -1135,7 +1135,7 @@ int wolfSSL_Unload_trust_peers(WOLFSSL* ssl)
#endif /* WOLFSSL_LOCAL_X509_STORE */
#endif /* WOLFSSL_TRUST_PEER_CERT */

#ifndef WOLFSSL_NO_CA_NAMES
#if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
/* Add a CA certificate to the list of CA names.
*
* @param [in, out] ca_names List of CA certificate subject names.
Expand Down
Loading
Loading