Add support for nginx-1.25.0

- nginx: add necessary defines and function
- Implement Certificate Authorities for TLS 1.3
- Implement secret logging for TLS 1.3. Can be used for example with:
  ./configure CPPFLAGS="-DWOLFSSL_SSLKEYLOGFILE -DSHOW_SECRETS -DHAVE_SECRET_CALLBACK -DWOLFSSL_SSLKEYLOGFILE_OUTPUT='\"/tmp/secrets\"'"
- Implement session context checking for tickets
- Check for authorized responder in OCSP basic response
- Fix handling call to ocsp->statusCb
- compat: Translate SOCKET_PEER_CLOSED_E to WOLFSSL_ERROR_SYSCALL
- Fix wolfSSL_CTX_set_session_cache_mode
  - WOLFSSL_SESS_CACHE_OFF means nothing should be on
  - WOLFSSL_SESS_CACHE_NO_INTERNAL turns off only the internal cache
- Respect ssl->options.internalCacheOff
- Implement SSL_SESSION_set_time
- wolfSSL_SSL_in_init: fix detection for TLS 1.3
- Fix handling call to ssl->alpnSelect
- SendTls13NewSessionTicket: always generate new ID
  - When we send a new ticket for the same session (for example we resumed a connection and are sending a new ticket so that the client can resume in the future), we need to generate a new ID so that we don't overwrite the old session in the cache. Overwriting the session results in the `diff` calculation in `DoClientTicketCheck()` producing the wrong value and failing to resume.
Add nginx github action test
- Fix memory leaks
- wolfSSL_OCSP_basic_verify: implement OCSP_TRUSTOTHER flag
- AKID: implement matching on issuer name and serial number
- ocsp: check for a chain match for OCSP responder
- Split CreateTicket into CreateTicket and SetupTicket
- SendCertificateStatus: free response.buffer
- Use heap hint when allocating responseBuffer
- Remove responseBuffer from internal API's that don't use it anywhere
This commit is contained in:
Juliusz Sosinowicz 2023-07-06 16:48:41 +02:00
parent 52b5adb54a
commit 0abaa89787
15 changed files with 1187 additions and 235 deletions

View File

@ -26,6 +26,8 @@ jobs:
uses: ./.github/workflows/openvpn.yml
hostap:
uses: ./.github/workflows/hostap.yml
nginx:
uses: ./.github/workflows/nginx.yml
# TODO: Currently this test fails. Enable it once it becomes passing.
# haproxy:
# uses: ./.github/workflows/haproxy.yml

176
.github/workflows/nginx.yml vendored Normal file
View File

@ -0,0 +1,176 @@
name: nginx Tests
on:
push:
workflow_call:
jobs:
build_wolfssl:
name: Build wolfSSL
# Just to keep it the same as the testing target
runs-on: ubuntu-latest
steps:
- if: ${{ runner.debug }}
name: Enable wolfSSL debug logging
run: |
# We don't use --enable-debug since it makes the logs too loud
echo "wolf_debug_flags= CFLAGS='-g3 -O0'" >> $GITHUB_ENV
- name: Build wolfSSL
uses: wolfSSL/actions-build-autotools-project@v1
with:
path: wolfssl
configure: --enable-nginx ${{ env.wolf_debug_flags }}
install: true
- name: Upload built lib
uses: actions/upload-artifact@v3
with:
name: wolf-install-nginx
path: build-dir
retention-days: 1
nginx_check:
strategy:
fail-fast: false
matrix:
include:
# in general we want to pass all tests that match *ssl*
- ref: 1.25.0
test-ref: 5b2894ea1afd01a26c589ce11f310df118e42592
# Following tests pass with sanitizer on
sanitize-ok: >-
h2_ssl_proxy_cache.t h2_ssl.t h2_ssl_variables.t h2_ssl_verify_client.t
mail_imap_ssl.t mail_ssl_conf_command.t mail_ssl_session_reuse.t
mail_ssl.t proxy_ssl_certificate_empty.t proxy_ssl_certificate.t
proxy_ssl_certificate_vars.t proxy_ssl_conf_command.t proxy_ssl_name.t
ssl_certificate_chain.t ssl_certificate_perl.t ssl_certificates.t
ssl_certificate.t ssl_client_escaped_cert.t ssl_conf_command.t
ssl_crl.t ssl_curve.t ssl_engine_keys.t ssl_ocsp.t ssl_password_file.t
ssl_proxy_protocol.t ssl_proxy_upgrade.t ssl_reject_handshake.t
ssl_session_reuse.t ssl_session_ticket_key.t ssl_sni_reneg.t
ssl_sni_sessions.t ssl_sni.t ssl_stapling.t ssl.t ssl_verify_client.t
ssl_verify_depth.t stream_proxy_ssl_certificate.t stream_proxy_ssl_certificate_vars.t
stream_proxy_ssl_conf_command.t stream_proxy_ssl_name_complex.t
stream_proxy_ssl_name.t stream_ssl_certificate.t stream_ssl_conf_command.t
stream_ssl_preread_alpn.t stream_ssl_preread_protocol.t stream_ssl_preread.t
stream_ssl_realip.t stream_ssl_session_reuse.t stream_ssl.t stream_ssl_variables.t
stream_ssl_verify_client.t stream_upstream_zone_ssl.t upstream_zone_ssl.t
uwsgi_ssl_certificate.t uwsgi_ssl_certificate_vars.t uwsgi_ssl.t
uwsgi_ssl_verify.t
# Following tests do not pass with sanitizer on (with OpenSSL too)
sanitize-not-ok: >-
grpc_ssl.t h2_proxy_request_buffering_ssl.t h2_proxy_ssl.t
proxy_request_buffering_ssl.t proxy_ssl_keepalive.t proxy_ssl.t
proxy_ssl_verify.t stream_proxy_protocol_ssl.t stream_proxy_ssl.t
stream_proxy_ssl_verify.t stream_ssl_alpn.t
name: ${{ matrix.ref }}
runs-on: ubuntu-latest
needs: build_wolfssl
steps:
- name: Download lib
uses: actions/download-artifact@v3
with:
name: wolf-install-nginx
path: build-dir
- name: Install dependencies
run: |
sudo cpan -iT Proc::Find Net::SSLeay IO::Socket::SSL
- name: Checkout wolfssl-nginx
uses: actions/checkout@v3
with:
repository: wolfssl/wolfssl-nginx
path: wolfssl-nginx
- name: Checkout nginx
uses: actions/checkout@v3
with:
repository: nginx/nginx
path: nginx
ref: release-${{ matrix.ref }}
- name: Apply nginx patch
working-directory: nginx
run: patch -p1 < ../wolfssl-nginx/nginx-${{ matrix.ref }}-wolfssl.patch
- if: ${{ runner.debug }}
name: Apply nginx debug patch
working-directory: nginx
run: patch -p1 < ../wolfssl-nginx/nginx-${{ matrix.ref }}-wolfssl-debug.patch
- name: Checkout nginx-tests
uses: actions/checkout@v3
with:
repository: nginx/nginx-tests
path: nginx-tests
ref: ${{ matrix.test-ref }}
- name: Apply nginx-tests patch
working-directory: nginx-tests
run: patch -p1 < ../wolfssl-nginx/nginx-tests-patches/*${{ matrix.test-ref }}.patch
- name: Build nginx without sanitizer
working-directory: nginx
run: |
./auto/configure --with-wolfssl=$GITHUB_WORKSPACE/build-dir --with-http_ssl_module \
--with-stream --with-stream_ssl_module --with-stream_ssl_preread_module \
--with-http_v2_module --with-mail --with-mail_ssl_module
make -j
- name: Confirm nginx built with wolfSSL
working-directory: nginx
run: ldd objs/nginx | grep wolfssl
- if: ${{ runner.debug }}
name: Run nginx-tests without sanitizer (debug)
working-directory: nginx-tests
run: |
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GITHUB_WORKSPACE/build-dir/lib \
TMPDIR=$GITHUB_WORKSPACE TEST_NGINX_VERBOSE=y TEST_NGINX_CATLOG=y \
TEST_NGINX_BINARY=../nginx/objs/nginx prove -v ${{ matrix.sanitize-not-ok }}
- if: ${{ !runner.debug }}
name: Run nginx-tests without sanitizer
working-directory: nginx-tests
run: |
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GITHUB_WORKSPACE/build-dir/lib \
TMPDIR=$GITHUB_WORKSPACE TEST_NGINX_BINARY=../nginx/objs/nginx \
prove ${{ matrix.sanitize-not-ok }}
- if: ${{ runner.debug }}
name: Enable wolfSSL debug logging
run: |
echo "nginx_c_flags=-O0" >> $GITHUB_ENV
- name: Build nginx with sanitizer
working-directory: nginx
run: |
./auto/configure --with-wolfssl=$GITHUB_WORKSPACE/build-dir --with-http_ssl_module \
--with-stream --with-stream_ssl_module --with-stream_ssl_preread_module \
--with-http_v2_module --with-mail --with-mail_ssl_module \
--with-cc-opt='-fsanitize=address -DNGX_DEBUG_PALLOC=1 -g3 ${{ env.nginx_c_flags }}' \
--with-ld-opt='-fsanitize=address ${{ env.nginx_c_flags }}'
make -j
- name: Confirm nginx built with wolfSSL
working-directory: nginx
run: ldd objs/nginx | grep wolfssl
- if: ${{ runner.debug }}
name: Run nginx-tests with sanitizer (debug)
working-directory: nginx-tests
run: |
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GITHUB_WORKSPACE/build-dir/lib \
TMPDIR=$GITHUB_WORKSPACE TEST_NGINX_VERBOSE=y TEST_NGINX_CATLOG=y \
TEST_NGINX_BINARY=../nginx/objs/nginx prove -v ${{ matrix.sanitize-ok }}
- if: ${{ !runner.debug }}
name: Run nginx-tests with sanitizer
working-directory: nginx-tests
run: |
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GITHUB_WORKSPACE/build-dir/lib \
TMPDIR=$GITHUB_WORKSPACE TEST_NGINX_BINARY=../nginx/objs/nginx \
prove ${{ matrix.sanitize-ok }}

View File

@ -5844,6 +5844,8 @@ fi
if test "$ENABLED_NGINX" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NGINX -DWOLFSSL_SIGNER_DER_CERT"
AM_CFLAGS="$AM_CFLAGS -DOPENSSL_COMPATIBLE_DEFAULTS"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ERROR_CODE_OPENSSL"
fi
if test "$ENABLED_HAPROXY" = "yes"
@ -7836,6 +7838,8 @@ then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALT_CERT_CHAINS"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_PRIORITIZE_PSK"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CHECK_ALERT_ON_ERR"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_TICKET_HAVE_ID"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_OCSP_ISSUER_CHECK"
ENABLED_TRUSTED_PEER_CERT=yes
fi
@ -8855,8 +8859,14 @@ fi
if test "$ENABLED_REPRODUCIBLE_BUILD" != "yes"
then
echo "#define LIBWOLFSSL_CONFIGURE_ARGS \"$ac_configure_args\"" | sed 's/\\/\\\\/g' > "${output_objdir}/.build_params" &&
echo "#define LIBWOLFSSL_GLOBAL_CFLAGS \"$CPPFLAGS $AM_CPPFLAGS $CFLAGS $AM_CFLAGS\" LIBWOLFSSL_GLOBAL_EXTRA_CFLAGS" | sed 's/\\/\\\\/g' >> "${output_objdir}/.build_params" ||
ESCAPED_ARGS="$ac_configure_args"
ESCAPED_ARGS=$(echo "$ESCAPED_ARGS" | sed 's/\\/\\\\/g')
ESCAPED_ARGS=$(echo "$ESCAPED_ARGS" | sed 's/\"/\\\"/g')
ESCAPED_GLOBAL_ARGS="$CPPFLAGS $AM_CPPFLAGS $CFLAGS $AM_CFLAGS"
ESCAPED_GLOBAL_ARGS=$(echo "$ESCAPED_GLOBAL_ARGS" | sed 's/\\/\\\\/g')
ESCAPED_GLOBAL_ARGS=$(echo "$ESCAPED_GLOBAL_ARGS" | sed 's/\"/\\\"/g')
echo "#define LIBWOLFSSL_CONFIGURE_ARGS \"$ESCAPED_ARGS\"" > "${output_objdir}/.build_params" &&
echo "#define LIBWOLFSSL_GLOBAL_CFLAGS \"$ESCAPED_GLOBAL_ARGS\" LIBWOLFSSL_GLOBAL_EXTRA_CFLAGS" >> "${output_objdir}/.build_params" ||
AC_MSG_ERROR([Couldn't create ${output_objdir}/.build_params.])
else
rm -f "${output_objdir}/.build_params"

View File

@ -2541,8 +2541,8 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
wolfSSL_X509_STORE_free(ctx->x509_store_pt);
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) || defined(HAVE_LIGHTY)
wolfSSL_sk_X509_NAME_pop_free(ctx->ca_names, NULL);
ctx->ca_names = NULL;
wolfSSL_sk_X509_NAME_pop_free(ctx->client_ca_names, NULL);
ctx->client_ca_names = NULL;
#endif
#ifdef OPENSSL_EXTRA
if (ctx->x509Chain) {
@ -7416,6 +7416,11 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
return ret;
#endif
#if defined(HAVE_SECRET_CALLBACK) && defined(SHOW_SECRETS) && \
defined(WOLFSSL_SSLKEYLOGFILE)
(void)wolfSSL_set_tls13_secret_cb(ssl, tls13ShowSecrets, NULL);
#endif
return 0;
}
@ -8143,8 +8148,8 @@ void SSL_ResourceFree(WOLFSSL* ssl)
#endif
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) || defined(HAVE_LIGHTY)
wolfSSL_sk_X509_NAME_pop_free(ssl->ca_names, NULL);
ssl->ca_names = NULL;
wolfSSL_sk_X509_NAME_pop_free(ssl->client_ca_names, NULL);
ssl->client_ca_names = NULL;
#endif
#ifdef WOLFSSL_DTLS13
Dtls13FreeFsmResources(ssl);
@ -11927,7 +11932,7 @@ static void AddSessionCertToChain(WOLFSSL_X509_CHAIN* chain,
#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
static void CopyDecodedName(WOLFSSL_X509_NAME* name, DecodedCert* dCert, int nameType)
void CopyDecodedName(WOLFSSL_X509_NAME* name, DecodedCert* dCert, int nameType)
{
if (nameType == SUBJECT) {
XSTRNCPY(name->name, dCert->subject, ASN_NAME_MAX);
@ -13942,7 +13947,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
SSL_CM(ssl)->ocspCheckAll) {
WOLFSSL_MSG("Doing Non Leaf OCSP check");
ret = CheckCertOCSP_ex(SSL_CM(ssl)->ocsp,
args->dCert, NULL, ssl);
args->dCert, ssl);
#ifdef WOLFSSL_NONBLOCK_OCSP
if (ret == OCSP_WANT_READ) {
args->lastErr = ret;
@ -14331,7 +14336,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
if (doLookup && SSL_CM(ssl)->ocspEnabled) {
WOLFSSL_MSG("Doing Leaf OCSP check");
ret = CheckCertOCSP_ex(SSL_CM(ssl)->ocsp,
args->dCert, NULL, ssl);
args->dCert, ssl);
#ifdef WOLFSSL_NONBLOCK_OCSP
if (ret == OCSP_WANT_READ) {
goto exit_ppc;
@ -22078,7 +22083,8 @@ int CreateOcspResponse(WOLFSSL* ssl, OcspRequest** ocspRequest,
if (ret == 0) {
request->ssl = ssl;
ret = CheckOcspRequest(SSL_CM(ssl)->ocsp_stapling, request, response);
ret = CheckOcspRequest(SSL_CM(ssl)->ocsp_stapling, request, response,
ssl->heap);
/* Suppressing, not critical */
if (ret == OCSP_CERT_REVOKED ||
@ -22418,7 +22424,7 @@ int SendCertificateRequest(WOLFSSL* ssl)
int sendSz;
word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
word32 dnLen = 0;
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)
#ifndef WOLFSSL_NO_CA_NAMES
WOLF_STACK_OF(WOLFSSL_X509_NAME)* names;
#endif
const Suites* suites = WOLFSSL_SUITES(ssl);
@ -22432,7 +22438,7 @@ int SendCertificateRequest(WOLFSSL* ssl)
if (IsAtLeastTLSv1_2(ssl))
reqSz += LENGTH_SZ + suites->hashSigAlgoSz;
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)
#ifndef WOLFSSL_NO_CA_NAMES
/* Certificate Authorities */
names = SSL_CA_NAMES(ssl);
while (names != NULL) {
@ -22525,7 +22531,7 @@ int SendCertificateRequest(WOLFSSL* ssl)
/* Certificate Authorities */
c16toa((word16)dnLen, &output[i]); /* auth's */
i += REQ_HEADER_SZ;
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)
#ifndef WOLFSSL_NO_CA_NAMES
names = SSL_CA_NAMES(ssl);
while (names != NULL) {
byte seq[MAX_SEQ_SZ];
@ -22775,6 +22781,8 @@ int SendCertificateStatus(WOLFSSL* ssl)
if (ret == 0 && response.buffer) {
ret = BuildCertificateStatus(ssl, status_type, &response, 1);
}
if (response.buffer) {
XFREE(response.buffer, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
response.buffer = NULL;
}
@ -22851,7 +22859,7 @@ int SendCertificateStatus(WOLFSSL* ssl)
if (ret == 0) {
request->ssl = ssl;
ret = CheckOcspRequest(SSL_CM(ssl)->ocsp_stapling,
request, &responses[i + 1]);
request, &responses[i + 1], ssl->heap);
/* Suppressing, not critical */
if (ret == OCSP_CERT_REVOKED ||
@ -22877,7 +22885,7 @@ int SendCertificateStatus(WOLFSSL* ssl)
NULL != (request = ssl->ctx->chainOcspRequest[i])) {
request->ssl = ssl;
ret = CheckOcspRequest(SSL_CM(ssl)->ocsp_stapling,
request, &responses[++i]);
request, &responses[++i], ssl->heap);
/* Suppressing, not critical */
if (ret == OCSP_CERT_REVOKED ||
@ -28086,10 +28094,10 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
return BUFFER_ERROR;
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)
if (ssl->ca_names != ssl->ctx->ca_names)
wolfSSL_sk_X509_NAME_pop_free(ssl->ca_names, NULL);
ssl->ca_names = wolfSSL_sk_X509_NAME_new(NULL);
if (ssl->ca_names == NULL) {
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) {
return MEMORY_ERROR;
}
#endif
@ -28134,7 +28142,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
}
if (ret == 0) {
if (wolfSSL_sk_X509_NAME_push(ssl->ca_names, name)
if (wolfSSL_sk_X509_NAME_push(ssl->client_ca_names, name)
== WOLFSSL_FAILURE)
{
ret = MEMORY_ERROR;
@ -35441,7 +35449,61 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifdef HAVE_SESSION_TICKET
/* create a new session ticket, 0 on success */
#ifdef WOLFSSL_TICKET_HAVE_ID
static void GetRealSessionID(WOLFSSL* ssl, const byte** id, byte* idSz)
{
if (ssl->session->haveAltSessionID) {
*id = ssl->session->altSessionID;
*idSz = ID_LEN;
}
else if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL) {
*id = ssl->arrays->sessionID;
*idSz = ssl->arrays->sessionIDSz;
}
else {
*id = ssl->session->sessionID;
*idSz = ssl->session->sessionIDSz;
}
}
#endif
int SetupTicket(WOLFSSL* ssl)
{
int ret = 0;
(void)ssl;
#ifdef WOLFSSL_TLS13
{
/* Client adds to ticket age to obfuscate. */
byte ageAdd[AGEADD_LEN]; /* Obfuscation of age */
ret = wc_RNG_GenerateBlock(ssl->rng, ageAdd, AGEADD_LEN);
if (ret != 0)
return ret;
ato32(ageAdd, &ssl->session->ticketAdd);
}
#endif
#ifdef WOLFSSL_TICKET_HAVE_ID
{
const byte* id = NULL;
byte idSz = 0;
GetRealSessionID(ssl, &id, &idSz);
if (idSz == 0) {
ret = wc_RNG_GenerateBlock(ssl->rng, ssl->session->altSessionID,
ID_LEN);
if (ret != 0)
return ret;
ssl->session->haveAltSessionID = 1;
}
}
#endif
return ret;
}
/* create a new session ticket, 0 on success
* Do any kind of setup in SetupTicket */
int CreateTicket(WOLFSSL* ssl)
{
InternalTicket* it;
@ -35502,14 +35564,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
goto error;
}
/* Client adds to ticket age to obfuscate. */
ret = wc_RNG_GenerateBlock(ssl->rng, it->ageAdd,
sizeof(it->ageAdd));
if (ret != 0) {
ret = BAD_TICKET_ENCRYPT;
goto error;
}
ato32(it->ageAdd, &ssl->session->ticketAdd);
c32toa(ssl->session->ticketAdd, it->ageAdd);
c16toa(ssl->session->namedGroup, it->namedGroup);
#ifdef WOLFSSL_32BIT_MILLI_TIME
c32toa(now, it->timestamp);
@ -35530,31 +35585,16 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#endif
}
#ifdef OPENSSL_EXTRA
it->sessionCtxSz = ssl->sessionCtxSz;
XMEMCPY(it->sessionCtx, ssl->sessionCtx, ID_LEN);
#endif
#ifdef WOLFSSL_TICKET_HAVE_ID
{
const byte* id = NULL;
byte idSz = 0;
if (ssl->session->haveAltSessionID) {
id = ssl->session->altSessionID;
idSz = ID_LEN;
}
else if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL) {
id = ssl->arrays->sessionID;
idSz = ssl->arrays->sessionIDSz;
}
else {
id = ssl->session->sessionID;
idSz = ssl->session->sessionIDSz;
}
if (idSz == 0) {
ret = wc_RNG_GenerateBlock(ssl->rng, ssl->session->altSessionID,
ID_LEN);
if (ret != 0)
goto error;
ssl->session->haveAltSessionID = 1;
id = ssl->session->altSessionID;
idSz = ID_LEN;
}
GetRealSessionID(ssl, &id, &idSz);
/* make sure idSz is not larger than ID_LEN */
if (idSz > ID_LEN)
idSz = ID_LEN;
@ -35829,6 +35869,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
(void)suite;
if (!FindSuiteSSL(ssl, psk->it->suite))
return -1;
#endif
#ifdef OPENSSL_EXTRA
if (ssl->sessionCtxSz > 0 &&
(psk->it->sessionCtxSz != ssl->sessionCtxSz ||
XMEMCMP(psk->it->sessionCtx, ssl->sessionCtx,
ssl->sessionCtxSz) != 0))
return -1;
#endif
return 0;
}
@ -35961,6 +36008,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
XMEMCPY(it->id, sess->altSessionID, ID_LEN);
else
XMEMCPY(it->id, sess->sessionID, ID_LEN);
#endif
#ifdef OPENSSL_EXTRA
it->sessionCtxSz = sess->sessionCtxSz;
XMEMCPY(it->sessionCtx, sess->sessionCtx, sess->sessionCtxSz);
#endif
}
@ -36067,6 +36118,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
break;
default:
psk->decryptRet = PSK_DECRYPT_FAIL;
WOLFSSL_LEAVE("DoClientTicket_ex", decryptRet);
return decryptRet;
}
#ifdef WOLFSSL_CHECK_MEM_ZERO
@ -36082,8 +36134,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifdef WOLFSSL_CHECK_MEM_ZERO
wc_MemZero_Check(psk->it, sizeof(InternalTicket));
#endif
WOLFSSL_LEAVE("DoClientTicket_ex", ret);
return ret;
}
WOLFSSL_LEAVE("DoClientTicket_ex", decryptRet);
return decryptRet;
}
#endif /* WOLFSL_TLS13 */
@ -36186,6 +36240,9 @@ cleanup:
WOLFSSL_ENTER("SendTicket");
if (ssl->options.createTicket) {
ret = SetupTicket(ssl);
if (ret != 0)
return ret;
ret = CreateTicket(ssl);
if (ret != 0)
return ret;

View File

@ -28,6 +28,13 @@
#include <wolfssl/wolfcrypt/settings.h>
/*
* WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK:
* Disable looking for an authorized responder in the verification path of
* the issuer. This will make the authorized responder only look at the
* OCSP response signer and direct issuer.
*/
#ifndef WOLFCRYPT_ONLY
#ifdef HAVE_OCSP
@ -135,7 +142,7 @@ static int xstat2err(int st)
}
}
int CheckCertOCSP_ex(WOLFSSL_OCSP* ocsp, DecodedCert* cert, buffer* responseBuffer, WOLFSSL* ssl)
int CheckCertOCSP_ex(WOLFSSL_OCSP* ocsp, DecodedCert* cert, WOLFSSL* ssl)
{
int ret = OCSP_LOOKUP_FAIL;
@ -160,7 +167,7 @@ int CheckCertOCSP_ex(WOLFSSL_OCSP* ocsp, DecodedCert* cert, buffer* responseBuff
if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce,
ocsp->cm->heap) == 0) {
ocspRequest->ssl = ssl;
ret = CheckOcspRequest(ocsp, ocspRequest, responseBuffer);
ret = CheckOcspRequest(ocsp, ocspRequest, NULL, NULL);
FreeOcspRequest(ocspRequest);
}
@ -172,9 +179,9 @@ int CheckCertOCSP_ex(WOLFSSL_OCSP* ocsp, DecodedCert* cert, buffer* responseBuff
WOLFSSL_LEAVE("CheckCertOCSP", ret);
return ret;
}
int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert, buffer* responseBuffer)
int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert)
{
return CheckCertOCSP_ex(ocsp, cert, responseBuffer, NULL);
return CheckCertOCSP_ex(ocsp, cert, NULL);
}
static int GetOcspEntry(WOLFSSL_OCSP* ocsp, OcspRequest* request,
@ -217,12 +224,14 @@ static int GetOcspEntry(WOLFSSL_OCSP* ocsp, OcspRequest* request,
* Returns OCSP status
*/
static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
OcspEntry* entry, CertStatus** status, buffer* responseBuffer)
OcspEntry* entry, CertStatus** status, buffer* responseBuffer,
void* heap)
{
int ret = OCSP_INVALID_STATUS;
WOLFSSL_ENTER("GetOcspStatus");
(void)heap;
*status = NULL;
if (wc_LockMutex(&ocsp->ocspLock) != 0) {
@ -252,7 +261,8 @@ static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
if (responseBuffer) {
responseBuffer->buffer = (byte*)XMALLOC(
(*status)->rawOcspResponseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
(*status)->rawOcspResponseSz, heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (responseBuffer->buffer) {
responseBuffer->length = (*status)->rawOcspResponseSz;
@ -277,11 +287,13 @@ static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
* reponseBuffer Buffer object to return the response with.
* status The certificate status object.
* entry The OCSP entry for this certificate.
* ocspRequest Request corresponding to response.
* heap Heap hint used for responseBuffer
* returns OCSP_LOOKUP_FAIL when the response is bad and 0 otherwise.
*/
int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz,
WOLFSSL_BUFFER_INFO *responseBuffer, CertStatus *status,
OcspEntry *entry, OcspRequest *ocspRequest)
OcspEntry *entry, OcspRequest *ocspRequest, void* heap)
{
#ifdef WOLFSSL_SMALL_STACK
CertStatus* newStatus;
@ -295,6 +307,8 @@ int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz,
int ret;
int validated = 0; /* ocsp validation flag */
(void)heap;
#ifdef WOLFSSL_SMALL_STACK
newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
DYNAMIC_TYPE_OCSP_STATUS);
@ -336,7 +350,7 @@ int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz,
}
if (responseBuffer) {
responseBuffer->buffer = (byte*)XMALLOC(responseSz, ocsp->cm->heap,
responseBuffer->buffer = (byte*)XMALLOC(responseSz, heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (responseBuffer->buffer) {
@ -418,7 +432,7 @@ end:
#define OCSP_MAX_REQUEST_SZ 2048
#endif
int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
buffer* responseBuffer)
buffer* responseBuffer, void* heap)
{
OcspEntry* entry = NULL;
CertStatus* status = NULL;
@ -446,10 +460,16 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
if (ret != 0)
return ret;
ret = GetOcspStatus(ocsp, ocspRequest, entry, &status, responseBuffer);
ret = GetOcspStatus(ocsp, ocspRequest, entry, &status, responseBuffer,
heap);
if (ret != OCSP_INVALID_STATUS)
return ret;
if (responseBuffer) {
XFREE(responseBuffer->buffer, heap, DYNAMIC_TYPE_TMP_BUFFER);
responseBuffer->buffer = NULL;
}
/* get SSL and IOCtx */
ssl = (WOLFSSL*)ocspRequest->ssl;
ioCtx = (ssl && ssl->ocspIOCtx != NULL) ?
@ -457,16 +477,26 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
if (ocsp->statusCb != NULL && ssl != NULL) {
WOLFSSL_MSG("Calling ocsp->statusCb");
ret = ocsp->statusCb(ssl, ioCtx);
if (ret == 0) {
ret = wolfSSL_get_ocsp_response(ssl, &response);
ret = CheckOcspResponse(ocsp, response, ret, responseBuffer, status,
entry, NULL);
if (response != NULL)
XFREE(response, NULL, DYNAMIC_TYPE_OPENSSL);
return ret;
switch (ret) {
case SSL_TLSEXT_ERR_OK:
ret = wolfSSL_get_ocsp_response(ssl, &response);
ret = CheckOcspResponse(ocsp, response, ret, responseBuffer,
status, entry, NULL, heap);
if (response != NULL)
XFREE(response, NULL, DYNAMIC_TYPE_OPENSSL);
break;
case SSL_TLSEXT_ERR_NOACK:
ret = OCSP_LOOKUP_FAIL;
break;
case SSL_TLSEXT_ERR_ALERT_FATAL:
default:
WOLFSSL_LEAVE("CheckOcspRequest", ocsp->error);
ret = WOLFSSL_FATAL_ERROR;
break;
}
WOLFSSL_LEAVE("CheckOcspRequest", ocsp->error);
WOLFSSL_LEAVE("CheckOcspRequest", ret);
return ret;
}
#endif
@ -491,10 +521,6 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
request = (byte*)XMALLOC(requestSz, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
if (request == NULL) {
WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
if (responseBuffer) {
XFREE(responseBuffer->buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
responseBuffer->buffer = NULL;
}
return MEMORY_ERROR;
}
@ -511,7 +537,7 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
if (responseSz >= 0 && response) {
ret = CheckOcspResponse(ocsp, response, responseSz, responseBuffer, status,
entry, ocspRequest);
entry, ocspRequest, heap);
}
if (response != NULL && ocsp->cm->ocspRespFreeCb)
@ -523,9 +549,107 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
return ret;
}
#ifdef HAVE_OCSP
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK
static int CheckOcspResponderChain(OcspEntry* single, DecodedCert *cert,
void* vp) {
/* Attempt to build a chain up to cert's issuer */
WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
Signer* ca = NULL;
Signer* prev = NULL;
int passed = 0;
/*
* Relation between certs:
* CA
* / \
* intermediate(s) cert in OCSP response
* | with OCSP key usage ext
* issuer of cert
* in OCSP request
*/
/* End loop if no more issuers found or if we have found a self
* signed cert (ca == prev) */
for (ca = GetCAByName(cm, single->issuerHash); ca != NULL && ca != prev;
prev = ca, ca = GetCAByName(cm, ca->issuerNameHash)) {
if (XMEMCMP(cert->issuerHash, ca->issuerNameHash,
OCSP_DIGEST_SIZE) == 0) {
WOLFSSL_MSG("\tOCSP Response signed by authorized "
"responder delegated by issuer "
"(found in chain)");
passed = 1;
break;
}
}
return passed;
}
#endif
/**
* Enforce https://www.rfc-editor.org/rfc/rfc6960#section-4.2.2.2
* @param bs The basic response to verify
* @param cert The decoded bs->cert
* @return
*/
int CheckOcspResponder(OcspResponse *bs, DecodedCert *cert, void* vp)
{
int ret = 0;
OcspEntry* single;
/* Both evaluate to enum values so can't use a pre-processor check */
WOLFSSL_ASSERT_EQ(OCSP_DIGEST_SIZE, SIGNER_DIGEST_SIZE);
(void)vp;
WOLFSSL_ENTER("CheckOcspResponder");
/* In the future if this API is used more then it could be beneficial to
* implement calling InitDecodedCert and ParseCertRelative here
* automatically when cert == NULL. */
if (bs == NULL || cert == NULL)
return BAD_FUNC_ARG;
/* Traverse the list and check that the cert has the authority to provide
* an OCSP response for each entry. */
for (single = bs->single; single != NULL; single = single->next) {
int passed = 0;
if (XMEMCMP(cert->subjectHash, single->issuerHash, OCSP_DIGEST_SIZE)
== 0) {
WOLFSSL_MSG("\tOCSP Response signed by issuer");
passed = 1;
}
else if ((cert->extExtKeyUsage & EXTKEYUSE_OCSP_SIGN) != 0) {
if (XMEMCMP(cert->issuerHash, single->issuerHash,
OCSP_DIGEST_SIZE) == 0) {
WOLFSSL_MSG("\tOCSP Response signed by authorized responder "
"delegated by issuer");
passed = 1;
}
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK
else if (vp != NULL) {
passed = CheckOcspResponderChain(single, cert, vp);
}
#endif
}
if (!passed) {
WOLFSSL_MSG("\tOCSP Responder not authorized");
#ifdef OPENSSL_EXTRA
bs->verifyError = OCSP_BAD_ISSUER;
#endif
ret = BAD_OCSP_RESPONDER;
break;
}
}
return ret;
}
#endif /* HAVE_OCSP */
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
defined(WOLFSSL_APACHE_HTTPD) || defined(HAVE_LIGHTY)
int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs,
WOLFSSL_OCSP_CERTID* id, int* status, int* reason,
WOLFSSL_ASN1_TIME** revtime, WOLFSSL_ASN1_TIME** thisupd,
@ -706,38 +830,60 @@ void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse)
int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs,
WOLF_STACK_OF(WOLFSSL_X509) *certs, WOLFSSL_X509_STORE *st, unsigned long flags)
{
int ret;
int ret = WOLFSSL_FAILURE;
#ifdef WOLFSSL_SMALL_STACK
DecodedCert *cert = (DecodedCert *)
DecodedCert *cert;
#else
DecodedCert cert[1];
#endif
byte certInit = 0;
int idx;
(void)certs;
if (flags & OCSP_NOVERIFY)
return WOLFSSL_SUCCESS;
#ifdef WOLFSSL_SMALL_STACK
cert = (DecodedCert *)
XMALLOC(sizeof(*cert), (st && st->cm) ? st->cm->heap : NULL,
DYNAMIC_TYPE_DCERT);
if (cert == NULL)
return WOLFSSL_FAILURE;
#else
DecodedCert cert[1];
#endif
(void)certs;
if (flags & OCSP_NOVERIFY) {
ret = WOLFSSL_SUCCESS;
goto out;
}
#ifdef OPENSSL_EXTRA
if (bs->verifyError != OCSP_VERIFY_ERROR_NONE) {
ret = WOLFSSL_FAILURE;
if (bs->verifyError != OCSP_VERIFY_ERROR_NONE)
goto out;
}
#endif
ret = WOLFSSL_SUCCESS;
InitDecodedCert(cert, bs->cert, bs->certSz, NULL);
if (ParseCertRelative(cert, CERT_TYPE, VERIFY, st->cm) < 0)
ret = WOLFSSL_FAILURE;
FreeDecodedCert(cert);
if (flags & OCSP_TRUSTOTHER) {
for (idx = 0; idx < wolfSSL_sk_X509_num(certs); idx++) {
WOLFSSL_X509* x = wolfSSL_sk_X509_value(certs, idx);
int derSz = 0;
const byte* der = wolfSSL_X509_get_der(x, &derSz);
if (derSz == (int)bs->certSz && XMEMCMP(bs->cert, der, derSz) == 0) {
ret = WOLFSSL_SUCCESS;
goto out;
}
}
}
InitDecodedCert(cert, bs->cert, bs->certSz, NULL);
certInit = 1;
if (ParseCertRelative(cert, CERT_TYPE, VERIFY, st->cm) < 0)
goto out;
if (!(flags & OCSP_NOCHECKS)) {
if (CheckOcspResponder(bs, cert, st->cm) != 0)
goto out;
}
ret = WOLFSSL_SUCCESS;
out:
if (certInit)
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, (st && st->cm) ? st->cm->heap : NULL, DYNAMIC_TYPE_DCERT);
@ -990,6 +1136,11 @@ WOLFSSL_OCSP_ONEREQ* wolfSSL_OCSP_request_add0_id(OcspRequest *req,
if (req == NULL || cid == NULL || cid->status == NULL)
return NULL;
if (req->cid != NULL)
wolfSSL_OCSP_CERTID_free(req->cid);
/* Keep to free */
req->cid = (void*)cid;
XMEMCPY(req->issuerHash, cid->issuerHash, KEYID_SIZE);
XMEMCPY(req->issuerKeyHash, cid->issuerKeyHash, KEYID_SIZE);
if (cid->status->serialSz > req->serialSz) {

205
src/ssl.c
View File

@ -4519,6 +4519,10 @@ int wolfSSL_get_error(WOLFSSL* ssl, int ret)
return WOLFSSL_ERROR_WANT_WRITE; /* convert to OpenSSL type */
else if (ssl->error == ZERO_RETURN || ssl->options.shutdownDone)
return WOLFSSL_ERROR_ZERO_RETURN; /* convert to OpenSSL type */
#ifdef OPENSSL_EXTRA
else if (ssl->error == SOCKET_PEER_CLOSED_E)
return WOLFSSL_ERROR_SYSCALL; /* convert to OpenSSL type */
#endif
#if defined(WOLFSSL_HAPROXY)
return GetX509Error(ssl->error);
#else
@ -5803,6 +5807,46 @@ Signer* GetCA(void* vp, byte* hash)
return ret;
}
#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->subjectNameHash, 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. */
@ -6110,6 +6154,9 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
#ifdef WOLFSSL_SIGNER_DER_CERT
ret = AllocDer(&signer->derCert, der->length, der->type, NULL);
}
if (ret == 0 && signer != NULL) {
ret = CalcHashId(cert->serial, cert->serialSz, signer->serialHash);
}
if (ret == 0 && signer != NULL) {
XMEMCPY(signer->derCert->buffer, der->buffer, der->length);
#endif
@ -6137,7 +6184,10 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
XMEMCPY(signer->subjectNameHash, cert->subjectHash,
SIGNER_DIGEST_SIZE);
#ifdef HAVE_OCSP
XMEMCPY(signer->subjectKeyHash, cert->subjectKeyHash, KEYID_SIZE);
XMEMCPY(signer->issuerNameHash, cert->issuerHash,
SIGNER_DIGEST_SIZE);
XMEMCPY(signer->subjectKeyHash, cert->subjectKeyHash,
KEYID_SIZE);
#endif
signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
: 0xFFFF;
@ -8641,7 +8691,7 @@ int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm)) != 0) {
WOLFSSL_MSG("ParseCert failed");
}
else if ((ret = CheckCertOCSP(cm->ocsp, cert, NULL)) != 0) {
else if ((ret = CheckCertOCSP(cm->ocsp, cert)) != 0) {
WOLFSSL_MSG("CheckCertOCSP failed");
}
@ -8666,7 +8716,7 @@ int wolfSSL_CertManagerCheckOCSPResponse(WOLFSSL_CERT_MANAGER *cm,
return WOLFSSL_SUCCESS;
ret = CheckOcspResponse(cm->ocsp, response, responseSz, responseBuffer, status,
entry, ocspRequest);
entry, ocspRequest, NULL);
return ret == 0 ? WOLFSSL_SUCCESS : ret;
}
@ -12156,13 +12206,19 @@ long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX* ctx, long mode)
if (ctx == NULL)
return WOLFSSL_FAILURE;
if (mode == WOLFSSL_SESS_CACHE_OFF)
if (mode == WOLFSSL_SESS_CACHE_OFF) {
ctx->sessionCacheOff = 1;
#ifdef HAVE_EXT_CACHE
ctx->internalCacheOff = 1;
ctx->internalCacheLookupOff = 1;
#endif
}
if ((mode & WOLFSSL_SESS_CACHE_NO_AUTO_CLEAR) != 0)
ctx->sessionCacheFlushOff = 1;
#ifdef HAVE_EXT_CACHE
/* WOLFSSL_SESS_CACHE_NO_INTERNAL activates both if's */
if ((mode & WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE) != 0)
ctx->internalCacheOff = 1;
if ((mode & WOLFSSL_SESS_CACHE_NO_INTERNAL_LOOKUP) != 0)
@ -14965,6 +15021,22 @@ static int TlsSessionCacheGetAndLock(const byte *id,
return 0;
}
static int CheckSessionMatch(const WOLFSSL* ssl, const WOLFSSL_SESSION* sess)
{
if (ssl == NULL || sess == NULL)
return 0;
#ifdef OPENSSL_EXTRA
if (ssl->sessionCtxSz > 0 && (ssl->sessionCtxSz != sess->sessionCtxSz ||
XMEMCMP(ssl->sessionCtx, sess->sessionCtx, sess->sessionCtxSz) != 0))
return 0;
#endif
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
if (IsAtLeastTLSv1_3(ssl->version) != IsAtLeastTLSv1_3(sess->version))
return 0;
#endif
return 1;
}
int TlsSessionCacheGetAndRdLock(const byte *id, const WOLFSSL_SESSION **sess,
word32 *lockedRow, byte side)
{
@ -15040,37 +15112,38 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
#ifdef HAVE_EXT_CACHE
if (ssl->ctx->get_sess_cb != NULL) {
int copy = 0;
int found = 0;
WOLFSSL_SESSION* extSess;
/* Attempt to retrieve the session from the external cache. */
WOLFSSL_MSG("Calling external session cache");
extSess = ssl->ctx->get_sess_cb(ssl, (byte*)id, ID_LEN, &copy);
if ((extSess != NULL)
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
&& (IsAtLeastTLSv1_3(ssl->version) ==
IsAtLeastTLSv1_3(extSess->version))
#endif
&& CheckSessionMatch(ssl, extSess)
) {
WOLFSSL_MSG("Session found in external cache");
found = 1;
error = wolfSSL_DupSession(extSess, output, 0);
#ifdef HAVE_EX_DATA
extSess->ownExData = 1;
output->ownExData = 0;
#endif
/* If copy not set then free immediately */
if (!copy)
wolfSSL_FreeSession(ssl->ctx, extSess);
/* We want to restore the bogus ID for TLS compatibility */
if (ssl->session->haveAltSessionID &&
output == ssl->session) {
XMEMCPY(ssl->session->sessionID, bogusID, ID_LEN);
ssl->session->sessionIDSz = bogusIDSz;
}
return error;
}
/* If copy not set then free immediately */
if (extSess != NULL && !copy)
wolfSSL_FreeSession(ssl->ctx, extSess);
if (found)
return error;
WOLFSSL_MSG("Session not found in external cache");
}
if (ssl->ctx->internalCacheLookupOff) {
if (ssl->options.internalCacheLookupOff) {
WOLFSSL_MSG("Internal cache lookup turned off");
return WOLFSSL_FAILURE;
}
@ -15154,12 +15227,12 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
#endif
}
else {
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
if (IsAtLeastTLSv1_3(ssl->version) != IsAtLeastTLSv1_3(sess->version)) {
WOLFSSL_MSG("Invalid session: different protocol version");
if (!CheckSessionMatch(ssl, sess)) {
WOLFSSL_MSG("Invalid session: can't be used in this context");
TlsSessionCacheUnlockRow(row);
error = WOLFSSL_FAILURE;
}
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
else if (LowResTimer() >= (sess->bornOn + sess->timeout)) {
WOLFSSL_SESSION* wrSess = NULL;
WOLFSSL_MSG("Invalid session: timed out");
@ -15932,27 +16005,32 @@ void AddSession(WOLFSSL* ssl)
idSz = ID_LEN;
}
/* Try to add the session to internal cache or external cache
if a new_sess_cb is set. Its ok if we don't succeed. */
(void)AddSessionToCache(ssl->ctx, session, id, idSz,
#ifdef SESSION_INDEX
&ssl->sessionIndex,
#else
NULL,
#ifdef HAVE_EXT_CACHE
if (!ssl->options.internalCacheOff)
#endif
ssl->options.side,
#ifdef HAVE_SESSION_TICKET
ssl->options.useTicket,
{
/* Try to add the session to internal cache or external cache
if a new_sess_cb is set. Its ok if we don't succeed. */
(void)AddSessionToCache(ssl->ctx, session, id, idSz,
#ifdef SESSION_INDEX
&ssl->sessionIndex,
#else
0,
NULL,
#endif
ssl->options.side,
#ifdef HAVE_SESSION_TICKET
ssl->options.useTicket,
#else
0,
#endif
#ifdef NO_SESSION_CACHE_REF
NULL
NULL
#else
(ssl->options.side == WOLFSSL_CLIENT_END) ?
&ssl->clientSession : NULL
(ssl->options.side == WOLFSSL_CLIENT_END) ?
&ssl->clientSession : NULL
#endif
);
);
}
#ifdef HAVE_EXT_CACHE
if (error == 0 && ssl->ctx->new_sess_cb != NULL) {
@ -17337,8 +17415,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
{
WOLFSSL_ENTER("wolfSSL_CTX_set_client_CA_list");
if (ctx != NULL) {
wolfSSL_sk_X509_NAME_pop_free(ctx->ca_names, NULL);
ctx->ca_names = names;
wolfSSL_sk_X509_NAME_pop_free(ctx->client_ca_names, NULL);
ctx->client_ca_names = names;
}
}
@ -17347,9 +17425,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
{
WOLFSSL_ENTER("wolfSSL_set_client_CA_list");
if (ssl != NULL) {
if (ssl->ca_names != ssl->ctx->ca_names)
wolfSSL_sk_X509_NAME_pop_free(ssl->ca_names, NULL);
ssl->ca_names = names;
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 = names;
}
}
@ -17409,7 +17487,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
#endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || HAVE_WEBSERVER */
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
#ifndef WOLFSSL_NO_CA_NAMES
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get_client_CA_list(
const WOLFSSL_CTX *ctx)
{
@ -17420,7 +17498,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
return NULL;
}
return ctx->ca_names;
return ctx->client_ca_names;
}
/* returns the CA's set on server side or the CA's sent from server when
@ -17450,9 +17528,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
return WOLFSSL_FAILURE;
}
if (ctx->ca_names == NULL) {
ctx->ca_names = wolfSSL_sk_X509_NAME_new(NULL);
if (ctx->ca_names == NULL) {
if (ctx->client_ca_names == NULL) {
ctx->client_ca_names = wolfSSL_sk_X509_NAME_new(NULL);
if (ctx->client_ca_names == NULL) {
WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
return WOLFSSL_FAILURE;
}
@ -17464,7 +17542,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
return WOLFSSL_FAILURE;
}
if (wolfSSL_sk_X509_NAME_push(ctx->ca_names, nameCopy) != WOLFSSL_SUCCESS) {
if (wolfSSL_sk_X509_NAME_push(ctx->client_ca_names, nameCopy) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error");
wolfSSL_X509_NAME_free(nameCopy);
return WOLFSSL_FAILURE;
@ -22165,6 +22243,8 @@ const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
{
const char* cName = NULL;
WOLFSSL_ENTER("wolfSSL_get_curve_name");
if (ssl == NULL)
return NULL;
@ -23864,7 +23944,7 @@ long wolfSSL_set_tlsext_debug_arg(WOLFSSL* ssl, void *arg)
}
#endif /* HAVE_PK_CALLBACKS */
#if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)
#if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_NGINX)
const unsigned char *wolfSSL_SESSION_get0_id_context(
const WOLFSSL_SESSION *sess, unsigned int *sid_ctx_length)
{
@ -26069,17 +26149,6 @@ long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION* sess)
return timeout;
}
long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
{
long bornOn = 0;
WOLFSSL_ENTER("wolfSSL_SESSION_get_time");
sess = ClientSessionToSession(sess);
if (sess)
bornOn = sess->bornOn;
return bornOn;
}
long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t)
{
word32 tmptime;
@ -26095,6 +26164,27 @@ long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t)
return WOLFSSL_SUCCESS;
}
long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
{
long bornOn = 0;
WOLFSSL_ENTER("wolfSSL_SESSION_get_time");
sess = ClientSessionToSession(sess);
if (sess)
bornOn = sess->bornOn;
return bornOn;
}
long wolfSSL_SESSION_set_time(WOLFSSL_SESSION *ses, long t)
{
ses = ClientSessionToSession(ses);
if (ses == NULL || t < 0) {
return 0;
}
ses->bornOn = (word32)t;
return t;
}
#endif /* !NO_SESSION_CACHE && OPENSSL_EXTRA || HAVE_EXT_CACHE */
#ifdef OPENSSL_EXTRA
@ -33006,10 +33096,9 @@ int wolfSSL_SSL_in_init(WOLFSSL *ssl)
if (ssl == NULL)
return WOLFSSL_FAILURE;
if (ssl->options.side == WOLFSSL_CLIENT_END) {
return ssl->options.connectState < SECOND_REPLY_DONE;
}
return ssl->options.acceptState < ACCEPT_THIRD_REPLY_DONE;
/* Can't use ssl->options.connectState and ssl->options.acceptState because
* they differ in meaning for TLS <=1.2 and 1.3 */
return ssl->options.handShakeState != HANDSHAKE_DONE;
}
int wolfSSL_SSL_in_connect_init(WOLFSSL* ssl)

303
src/tls.c
View File

@ -114,13 +114,6 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions);
#endif
#endif
/* Optional Pre-Master-Secret logging for Wireshark */
#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_SSLKEYLOGFILE)
#ifndef WOLFSSL_SSLKEYLOGFILE_OUTPUT
#define WOLFSSL_SSLKEYLOGFILE_OUTPUT "sslkeylog.log"
#endif
#endif
#ifndef WOLFSSL_NO_TLS12
#ifdef WOLFSSL_SHA384
@ -1683,19 +1676,29 @@ int ALPN_Select(WOLFSSL *ssl)
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
if (ssl->alpnSelect != NULL && ssl->options.side == WOLFSSL_SERVER_END) {
if (ssl->alpnSelect(ssl, &sel, &sel_len, ssl->alpn_peer_requested,
ssl->alpn_peer_requested_length,
ssl->alpnSelectArg) == 0) {
WOLFSSL_MSG("ALPN protocol match");
}
else {
sel = NULL;
sel_len = 0;
r = ssl->alpnSelect(ssl, &sel, &sel_len, ssl->alpn_peer_requested,
ssl->alpn_peer_requested_length, ssl->alpnSelectArg);
switch (r) {
case SSL_TLSEXT_ERR_OK:
WOLFSSL_MSG("ALPN protocol match");
break;
case SSL_TLSEXT_ERR_NOACK:
WOLFSSL_MSG("ALPN cb no match but not fatal");
sel = NULL;
sel_len = 0;
break;
case SSL_TLSEXT_ERR_ALERT_FATAL:
default:
WOLFSSL_MSG("ALPN cb no match and fatal");
SendAlert(ssl, alert_fatal, no_application_protocol);
WOLFSSL_ERROR_VERBOSE(UNKNOWN_ALPN_PROTOCOL_NAME_E);
return UNKNOWN_ALPN_PROTOCOL_NAME_E;
break;
}
}
else
#endif
if (sel == NULL) {
{
r = ALPN_find_match(ssl, &extension, &sel, &sel_len,
ssl->alpn_peer_requested,
ssl->alpn_peer_requested_length);
@ -3013,6 +3016,12 @@ static void TLSX_CSR_Free(CertificateStatusRequest* csr, void* heap)
break;
}
#ifdef WOLFSSL_TLS13
if (csr->response.buffer != NULL) {
XFREE(csr->response.buffer, csr->ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
}
#endif
XFREE(csr, heap, DYNAMIC_TYPE_TLSX);
(void)heap;
}
@ -3144,7 +3153,7 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, const byte* input, word16 length,
csr->status_type, csr->options, ssl,
ssl->heap, ssl->devId);
if (ret != WOLFSSL_SUCCESS)
return ret;
return ret == 0 ? -1 : ret;
switch (csr->status_type) {
case WOLFSSL_CSR_OCSP:
@ -3187,7 +3196,13 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, const byte* input, word16 length,
ret = BUFFER_ERROR;
}
if (ret == 0) {
csr->response.buffer = (byte*)(input + offset);
csr->response.buffer = (byte*)XMALLOC(resp_length, ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (csr->response.buffer == NULL)
ret = MEMORY_ERROR;
}
if (ret == 0) {
XMEMCPY(csr->response.buffer, input + offset, resp_length);
csr->response.length = resp_length;
}
@ -3249,7 +3264,7 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, const byte* input, word16 length,
ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
0, ssl, ssl->heap, ssl->devId);
if (ret != WOLFSSL_SUCCESS)
return ret; /* throw error */
return ret == 0 ? -1 : ret; /* throw error */
#if defined(WOLFSSL_TLS13)
if (ssl->options.tls1_3) {
@ -3266,14 +3281,17 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, const byte* input, word16 length,
ssl->buffers.certificate->length, ssl->heap);
ret = ParseCert(cert, CERT_TYPE, 1, SSL_CM(ssl));
if (ret != 0 ) {
FreeDecodedCert(cert);
XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
return ret;
}
ret = TLSX_CSR_InitRequest(ssl->extensions, cert, ssl->heap);
if (ret != 0 ) {
FreeDecodedCert(cert);
XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
return ret;
}
FreeDecodedCert(cert);
XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
@ -3358,7 +3376,7 @@ int TLSX_CSR_ForceRequest(WOLFSSL* ssl)
if (SSL_CM(ssl)->ocspEnabled) {
csr->request.ocsp.ssl = ssl;
return CheckOcspRequest(SSL_CM(ssl)->ocsp,
&csr->request.ocsp, NULL);
&csr->request.ocsp, NULL, NULL);
}
else {
WOLFSSL_ERROR_VERBOSE(OCSP_LOOKUP_FAIL);
@ -3790,7 +3808,7 @@ int TLSX_CSR2_ForceRequest(WOLFSSL* ssl)
if (SSL_CM(ssl)->ocspEnabled) {
csr2->request.ocsp[0].ssl = ssl;
return CheckOcspRequest(SSL_CM(ssl)->ocsp,
&csr2->request.ocsp[0], NULL);
&csr2->request.ocsp[0], NULL, NULL);
}
else {
WOLFSSL_ERROR_VERBOSE(OCSP_LOOKUP_FAIL);
@ -6504,6 +6522,170 @@ int TLSX_Cookie_Use(const WOLFSSL* ssl, const byte* data, word16 len, byte* mac,
#define CKE_PARSE(a, b, c, d) 0
#endif
#if defined(WOLFSSL_TLS13) && !defined(NO_CERTS) && \
!defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
/* Currently only settable through compatibility API */
/******************************************************************************/
/* Certificate Authorities */
/******************************************************************************/
static word16 TLSX_CA_Names_GetSize(void* data)
{
WOLFSSL* ssl = (WOLFSSL*)data;
WOLF_STACK_OF(WOLFSSL_X509_NAME)* names;
word16 size = 0;
if (ssl->options.side == WOLFSSL_CLIENT_END) {
/* To add support use a different member like ssl->ca_names and
* add accessor functions:
* - *_set0_CA_list
* - *_get0_CA_list */
WOLFSSL_MSG("We don't currently support sending the client's list.");
return 0;
}
/* Length of names */
size += OPAQUE16_LEN;
for (names = SSL_CA_NAMES(ssl); names != NULL; names = names->next) {
byte seq[MAX_SEQ_SZ];
WOLFSSL_X509_NAME* name = names->data.name;
if (name != NULL) {
/* 16-bit length | SEQ | Len | DER of name */
size += (word16)(OPAQUE16_LEN + SetSequence(name->rawLen, seq) +
name->rawLen);
}
}
return size;
}
static word16 TLSX_CA_Names_Write(void* data, byte* output)
{
WOLFSSL* ssl = (WOLFSSL*)data;
WOLF_STACK_OF(WOLFSSL_X509_NAME)* names;
byte* len;
if (ssl->options.side == WOLFSSL_CLIENT_END) {
/* To add support use a different member like ssl->ca_names and
* add accessor functions:
* - *_set0_CA_list
* - *_get0_CA_list */
WOLFSSL_MSG("We don't currently support sending the client's list.");
return 0;
}
/* Reserve space for the length value */
len = output;
output += OPAQUE16_LEN;
for (names = SSL_CA_NAMES(ssl); names != NULL; names = names->next) {
byte seq[MAX_SEQ_SZ];
WOLFSSL_X509_NAME* name = names->data.name;
if (name != NULL) {
c16toa((word16)name->rawLen +
(word16)SetSequence(name->rawLen, seq), output);
output += OPAQUE16_LEN;
output += SetSequence(name->rawLen, output);
XMEMCPY(output, name->raw, name->rawLen);
output += name->rawLen;
}
}
/* Write the total length */
c16toa((word16)(output - len - OPAQUE16_LEN), len);
return (word16)(output - len);
}
static int TLSX_CA_Names_Parse(WOLFSSL *ssl, const byte* input,
word16 length, byte isRequest)
{
word16 extLen;
(void)isRequest;
if (ssl->options.side == WOLFSSL_SERVER_END) {
/* To add support use a different member like ssl->ca_names and
* add accessor functions:
* - *_set0_CA_list
* - *_get0_CA_list */
WOLFSSL_MSG("We don't currently support parsing the client's list.");
return 0;
}
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)
return MEMORY_ERROR;
ato16(input, &extLen);
input += OPAQUE16_LEN;
length -= OPAQUE16_LEN;
if (extLen != length)
return BUFFER_ERROR;
while (length) {
word32 idx = 0;
WOLFSSL_X509_NAME* name = NULL;
int ret = 0;
/* Use a DecodedCert struct to get access to GetName to
* parse DN name */
#ifdef WOLFSSL_SMALL_STACK
DecodedCert *cert = (DecodedCert *)XMALLOC(
sizeof(*cert), ssl->heap, DYNAMIC_TYPE_DCERT);
if (cert == NULL)
return MEMORY_ERROR;
#else
DecodedCert cert[1];
#endif
ato16(input, &extLen);
idx += OPAQUE16_LEN;
if (extLen > length)
return BUFFER_ERROR;
InitDecodedCert(cert, input + idx, extLen, ssl->heap);
idx += extLen;
ret = GetName(cert, SUBJECT, extLen);
if (ret == 0 && (name = wolfSSL_X509_NAME_new()) == NULL)
ret = MEMORY_ERROR;
if (ret == 0)
CopyDecodedName(name, cert, SUBJECT);
if (ret == 0 && wolfSSL_sk_X509_NAME_push(ssl->client_ca_names, name)
== WOLFSSL_FAILURE)
ret = MEMORY_ERROR;
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
#endif
if (ret != 0)
return ret;
input += idx;
length -= (word16)idx;
}
return 0;
}
#define CAN_GET_SIZE TLSX_CA_Names_GetSize
#define CAN_WRITE TLSX_CA_Names_Write
#define CAN_PARSE TLSX_CA_Names_Parse
#else
#define CAN_GET_SIZE(...) 0
#define CAN_WRITE(...) 0
#define CAN_PARSE(...) 0
#endif
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
/******************************************************************************/
/* Signature Algorithms */
@ -11351,6 +11533,10 @@ void TLSX_FreeAll(TLSX* list, void* heap)
case TLSX_KEY_SHARE:
KS_FREE_ALL((KeyShareEntry*)extension->data, heap);
break;
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
case TLSX_CERTIFICATE_AUTHORITIES:
break;
#endif
#endif
#ifdef WOLFSSL_SRTP
case TLSX_USE_SRTP:
@ -11376,8 +11562,8 @@ void TLSX_FreeAll(TLSX* list, void* heap)
ECH_FREE((WOLFSSL_ECH*)extension->data, heap);
break;
#endif
default:
break;
default:
break;
}
XFREE(extension, heap, DYNAMIC_TYPE_TLSX);
@ -11525,6 +11711,11 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
case TLSX_KEY_SHARE:
length += KS_GET_SIZE((KeyShareEntry*)extension->data, msgType);
break;
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
case TLSX_CERTIFICATE_AUTHORITIES:
length += CAN_GET_SIZE(extension->data);
break;
#endif
#endif
#ifdef WOLFSSL_SRTP
case TLSX_USE_SRTP:
@ -11731,6 +11922,12 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
offset += KS_WRITE((KeyShareEntry*)extension->data,
output + offset, msgType);
break;
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
case TLSX_CERTIFICATE_AUTHORITIES:
WOLFSSL_MSG("Certificate Authorities extension to write");
offset += CAN_WRITE(extension->data, output + offset);
break;
#endif
#endif
#ifdef WOLFSSL_SRTP
case TLSX_USE_SRTP:
@ -12082,6 +12279,17 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
ret = 0;
#endif
#ifdef WOLFSSL_TLS13
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
if (isServer && IsAtLeastTLSv1_3(ssl->version)) {
if (SSL_CA_NAMES(ssl) != NULL) {
WOLFSSL_MSG("Adding certificate authorities extension");
if ((ret = TLSX_Push(&ssl->extensions,
TLSX_CERTIFICATE_AUTHORITIES, ssl, ssl->heap)) != 0) {
return ret;
}
}
}
#endif
if (!isServer && IsAtLeastTLSv1_3(ssl->version)) {
/* Add mandatory TLS v1.3 extension: supported version */
WOLFSSL_MSG("Adding supported versions extension");
@ -12558,8 +12766,9 @@ int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word16* pLength)
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
#endif
#if defined(WOLFSSL_TLS13)
if (!IsAtLeastTLSv1_2(ssl))
if (!IsAtLeastTLSv1_2(ssl)) {
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
}
#if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
if (!IsAtLeastTLSv1_3(ssl->version)) {
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
@ -12576,6 +12785,10 @@ int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word16* pLength)
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH));
#endif
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
TURN_ON(semaphore,
TLSX_ToSemaphore(TLSX_CERTIFICATE_AUTHORITIES));
#endif
}
#endif
#endif /* WOLFSSL_TLS13 */
@ -12597,8 +12810,11 @@ int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word16* pLength)
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
#endif
/* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
* TLSX_CERTIFICATE_AUTHORITIES, OID_FILTERS
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
if (SSL_CA_NAMES(ssl) != NULL)
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_CERTIFICATE_AUTHORITIES));
#endif
/* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP, OID_FILTERS
* TLSX_STATUS_REQUEST
*/
}
@ -12801,6 +13017,10 @@ int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType, word16* pOffset)
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH));
#endif
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
TURN_ON(semaphore,
TLSX_ToSemaphore(TLSX_CERTIFICATE_AUTHORITIES));
#endif
}
#endif
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
@ -12828,8 +13048,13 @@ int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType, word16* pOffset)
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
#endif
/* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
* TLSX_CERTIFICATE_AUTHORITIES, TLSX_OID_FILTERS
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
if (SSL_CA_NAMES(ssl) != NULL) {
TURN_OFF(semaphore,
TLSX_ToSemaphore(TLSX_CERTIFICATE_AUTHORITIES));
}
#endif
/* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP, TLSX_OID_FILTERS
* TLSX_STATUS_REQUEST
*/
}
@ -13739,6 +13964,26 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
break;
#endif
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
case TLSX_CERTIFICATE_AUTHORITIES:
WOLFSSL_MSG("Certificate Authorities extension received");
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_BUFFER(input + offset, size);
#endif
if (!IsAtLeastTLSv1_3(ssl->version))
break;
if (msgType != client_hello &&
msgType != certificate_request) {
WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
return EXT_NOT_ALLOWED;
}
ret = CAN_PARSE(ssl, input + offset, size, isRequest);
break;
#endif
case TLSX_KEY_SHARE:
WOLFSSL_MSG("Key Share extension received");
#ifdef WOLFSSL_DEBUG_TLS

View File

@ -5763,6 +5763,8 @@ static int FindPsk(WOLFSSL* ssl, PreSharedKey* psk, const byte* suite, int* err)
int found = 0;
byte foundSuite[SUITE_LEN];
WOLFSSL_ENTER("FindPsk");
ret = FindPskSuite(ssl, psk, ssl->arrays->psk_key, &ssl->arrays->psk_keySz,
suite, &found, foundSuite);
if (ret == 0 && found) {
@ -5797,6 +5799,8 @@ static int FindPsk(WOLFSSL* ssl, PreSharedKey* psk, const byte* suite, int* err)
}
*err = ret;
WOLFSSL_LEAVE("FindPsk", found);
WOLFSSL_LEAVE("FindPsk", ret);
return found;
}
#endif /* !NO_PSK */
@ -10601,9 +10605,24 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl)
ssl->session->ticketNonce.data[0]++;
}
if (!ssl->options.noTicketTls13) {
if ((ret = CreateTicket(ssl)) != 0)
if ((ssl->options.mask & WOLFSSL_OP_NO_TICKET) != 0) {
/* In this case we only send the ID as the ticket. Let's generate a new
* ID for the new ticket so that we don't overwrite any old ones */
ret = wc_RNG_GenerateBlock(ssl->rng, ssl->session->altSessionID,
ID_LEN);
if (ret != 0)
return ret;
ssl->session->haveAltSessionID = 1;
}
if (!ssl->options.noTicketTls13) {
if ((ret = SetupTicket(ssl)) != 0)
return ret;
/* No need to create the ticket if we only send the ID */
if ((ssl->options.mask & WOLFSSL_OP_NO_TICKET) == 0) {
if ((ret = CreateTicket(ssl)) != 0)
return ret;
}
}
#ifdef WOLFSSL_EARLY_DATA
@ -10662,7 +10681,7 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl)
if (ssl->session->haveAltSessionID)
XMEMCPY(output + idx, ssl->session->altSessionID, ID_LEN);
else
XMEMCPY(output + idx, ssl->session->sessionID, ID_LEN);
return BAD_FUNC_ARG; /* Should not happen */
idx += ID_LEN;
}
else {
@ -13665,6 +13684,73 @@ int wolfSSL_set_tls13_secret_cb(WOLFSSL* ssl, Tls13SecretCb cb, void* ctx)
return WOLFSSL_SUCCESS;
}
#if defined(SHOW_SECRETS) && defined(WOLFSSL_SSLKEYLOGFILE)
int tls13ShowSecrets(WOLFSSL* ssl, int id, const unsigned char* secret,
int secretSz, void* ctx)
{
int i;
const char* str = NULL;
byte clientRandom[RAN_LEN];
int clientRandomSz;
XFILE fp;
(void) ctx;
#ifdef WOLFSSL_SSLKEYLOGFILE_OUTPUT
fp = XFOPEN(WOLFSSL_SSLKEYLOGFILE_OUTPUT, "ab");
if (fp == XBADFILE) {
return BAD_FUNC_ARG;
}
#else
fp = stderr;
#endif
clientRandomSz = (int)wolfSSL_get_client_random(ssl, clientRandom,
sizeof(clientRandom));
if (clientRandomSz <= 0) {
printf("Error getting server random %d\n", clientRandomSz);
}
#if 0
printf("TLS Server Secret CB: Rand %d, Secret %d\n",
serverRandomSz, secretSz);
#endif
switch (id) {
case CLIENT_EARLY_TRAFFIC_SECRET:
str = "CLIENT_EARLY_TRAFFIC_SECRET"; break;
case EARLY_EXPORTER_SECRET:
str = "EARLY_EXPORTER_SECRET"; break;
case CLIENT_HANDSHAKE_TRAFFIC_SECRET:
str = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"; break;
case SERVER_HANDSHAKE_TRAFFIC_SECRET:
str = "SERVER_HANDSHAKE_TRAFFIC_SECRET"; break;
case CLIENT_TRAFFIC_SECRET:
str = "CLIENT_TRAFFIC_SECRET_0"; break;
case SERVER_TRAFFIC_SECRET:
str = "SERVER_TRAFFIC_SECRET_0"; break;
case EXPORTER_SECRET:
str = "EXPORTER_SECRET"; break;
}
fprintf(fp, "%s ", str);
for (i = 0; i < (int)clientRandomSz; i++) {
fprintf(fp, "%02x", clientRandom[i]);
}
fprintf(fp, " ");
for (i = 0; i < secretSz; i++) {
fprintf(fp, "%02x", secret[i]);
}
fprintf(fp, "\n");
#ifdef WOLFSSL_SSLKEYLOGFILE_OUTPUT
XFCLOSE(fp);
#endif
return 0;
}
#endif
#endif
#undef ERROR_OUT

View File

@ -8275,7 +8275,8 @@ static int test_wolfSSL_CTX_add_session_ext(
/* (D)TLSv1.3 creates a new ticket,
* updates both internal and external cache */
ExpectIntEQ(twcase_new_session_called, 1);
ExpectIntEQ(twcase_remove_session_called, 1);
/* A new session ID is created for a new ticket */
ExpectIntEQ(twcase_remove_session_called, 2);
}
else {

View File

@ -63,7 +63,7 @@ ASN Options:
does not perform a PKI validation, so it is not a secure solution.
Only enabled for OCSP.
* WOLFSSL_NO_OCSP_ISSUER_CHECK: Can be defined for backwards compatibility to
disable checking of OCSP subject hash with issuer hash.
disable checking of https://www.rfc-editor.org/rfc/rfc6960#section-4.2.2.2.
* WOLFSSL_SMALL_CERT_VERIFY: Verify the certificate signature without using
DecodedCert. Doubles up on some code but allows smaller dynamic memory
usage.
@ -190,8 +190,8 @@ ASN Options:
#include <wolfssl/wolfcrypt/cryptocb.h>
#endif
#include <wolfssl/internal.h>
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
#include <wolfssl/internal.h>
#include <wolfssl/openssl/objects.h>
#endif
@ -18843,7 +18843,6 @@ static int DecodeAuthKeyId(const byte* input, word32 sz, DecodedCert* cert)
#else
DECL_ASNGETDATA(dataASN, authKeyIdASN_Length);
int ret = 0;
word32 idx = 0;
WOLFSSL_ENTER("DecodeAuthKeyId");
@ -18851,31 +18850,59 @@ static int DecodeAuthKeyId(const byte* input, word32 sz, DecodedCert* cert)
if (ret == 0) {
/* Parse an authority key identifier. */
word32 idx = 0;
ret = GetASN_Items(authKeyIdASN, dataASN, authKeyIdASN_Length, 1, input,
&idx, sz);
}
if (ret == 0) {
/* Key id is optional. */
if (dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data == NULL) {
WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
}
else {
/* Each field is optional */
if (ret == 0 && dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data != NULL) {
#ifdef OPENSSL_EXTRA
/* Store the authority key id. */
#ifdef WOLFSSL_AKID_NAME
cert->extRawAuthKeyIdSrc = input;
cert->extRawAuthKeyIdSz = sz;
#endif
GetASN_GetConstRef(&dataASN[AUTHKEYIDASN_IDX_KEYID], &cert->extAuthKeyIdSrc,
&cert->extAuthKeyIdSz);
GetASN_GetConstRef(&dataASN[AUTHKEYIDASN_IDX_KEYID],
&cert->extAuthKeyIdSrc, &cert->extAuthKeyIdSz);
#endif /* OPENSSL_EXTRA */
/* Get the hash or hash of the hash if wrong size. */
ret = GetHashId(dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
(int)dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
cert->extAuthKeyId, HashIdAlg(cert->signatureOID));
}
#ifdef WOLFSSL_AKID_NAME
if (ret == 0 && dataASN[AUTHKEYIDASN_IDX_ISSUER].data.ref.data != NULL) {
/* We only support using one (first) name. Parse the name to perform
* a sanity check. */
word32 idx = 0;
ASNGetData nameASN[altNameASN_Length];
XMEMSET(nameASN, 0, sizeof(nameASN));
/* Parse GeneralName with the choices supported. */
GetASN_Choice(&nameASN[ALTNAMEASN_IDX_GN], generalNameChoice);
/* Decode a GeneralName choice. */
ret = GetASN_Items(altNameASN, nameASN, altNameASN_Length, 0,
dataASN[AUTHKEYIDASN_IDX_ISSUER].data.ref.data, &idx,
dataASN[AUTHKEYIDASN_IDX_ISSUER].data.ref.length);
/* Get the hash or hash of the hash if wrong size. */
ret = GetHashId(dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
(int)dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
cert->extAuthKeyId, HashIdAlg((int)cert->signatureOID));
if (ret == 0) {
GetASN_GetConstRef(&nameASN[ALTNAMEASN_IDX_GN],
&cert->extAuthKeyIdIssuer, &cert->extAuthKeyIdIssuerSz);
}
}
if (ret == 0 && dataASN[AUTHKEYIDASN_IDX_SERIAL].data.ref.data != NULL) {
GetASN_GetConstRef(&dataASN[AUTHKEYIDASN_IDX_SERIAL],
&cert->extAuthKeyIdIssuerSN, &cert->extAuthKeyIdIssuerSNSz);
}
if (ret == 0) {
if ((cert->extAuthKeyIdIssuerSz > 0) ^
(cert->extAuthKeyIdIssuerSNSz > 0)) {
WOLFSSL_MSG("authorityCertIssuer and authorityCertSerialNumber MUST"
" both be present or both be absent");
}
}
#endif /* WOLFSSL_AKID_NAME */
if (ret == 0) {
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_AKID_NAME)
/* Store the raw authority key id. */
cert->extRawAuthKeyIdSrc = input;
cert->extRawAuthKeyIdSz = sz;
#endif /* OPENSSL_EXTRA */
}
FREE_ASNGETDATA(dataASN, cert->heap);
return ret;
@ -21454,6 +21481,19 @@ Signer* GetCAByName(void* signers, byte* hash)
}
#endif /* NO_SKID */
#ifdef WOLFSSL_AKID_NAME
Signer* GetCAByAKID(void* vp, const byte* issuer, word32 issuerSz,
const byte* serial, word32 serialSz)
{
(void)issuer;
(void)issuerSz;
(void)serial;
(void)serialSz;
return (Signer*)vp;
}
#endif
#endif /* WOLFCRYPT_ONLY */
#if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)
@ -22576,6 +22616,13 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
#ifndef NO_SKID
if (cert->extAuthKeyIdSet) {
cert->ca = GetCA(cm, cert->extAuthKeyId);
#ifdef WOLFSSL_AKID_NAME
if (cert->ca == NULL) {
cert->ca = GetCAByAKID(cm, cert->extAuthKeyIdIssuer,
cert->extAuthKeyIdIssuerSz, cert->extAuthKeyIdIssuerSN,
cert->extAuthKeyIdIssuerSNSz);
}
#endif
}
if (cert->ca == NULL && cert->extSubjKeyIdSet
&& verify != VERIFY_OCSP) {
@ -34140,6 +34187,9 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
if (ret == 0) {
/* Store serial size. */
cs->serialSz = serialSz;
/* Set the hash algorithm OID */
single->hashAlgoOID =
dataASN[SINGLERESPONSEASN_IDX_CID_HASHALGO_OID].data.oid.sum;
/* Determine status by which item was found. */
if (dataASN[SINGLERESPONSEASN_IDX_CS_GOOD].tag != 0) {
@ -34909,7 +34959,7 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
if ((ret == 0) &&
(dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
#endif
/* Initialize the crtificate object. */
/* Initialize the certificate object. */
InitDecodedCert(cert, resp->cert, resp->certSz, heap);
certInit = 1;
/* Parse the certificate and don't verify if we don't have access to
@ -34920,6 +34970,13 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
}
}
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
if ((ret == 0) &&
(dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL) &&
!noVerify) {
ret = CheckOcspResponder(resp, cert, cm);
}
#endif /* WOLFSSL_NO_OCSP_ISSUER_CHECK */
if ((ret == 0) &&
(dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
/* TODO: ConfirmSignature is blocking here */
@ -35587,6 +35644,14 @@ void FreeOcspRequest(OcspRequest* req)
if (req->url)
XFREE(req->url, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
req->url = NULL;
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_APACHE_HTTPD) || \
defined(HAVE_LIGHTY)
if (req->cid != NULL)
wolfSSL_OCSP_CERTID_free((WOLFSSL_OCSP_CERTID*)req->cid);
req->cid = NULL;
#endif
}
}

View File

@ -1030,6 +1030,13 @@
#undef WSSL_HARDEN_TLS
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) || defined(HAVE_LIGHTY)
#define SSL_CA_NAMES(ssl) ((ssl)->client_ca_names != NULL ? (ssl)->client_ca_names : \
(ssl)->ctx->client_ca_names)
#else
#define WOLFSSL_NO_CA_NAMES
#endif
/* actual cipher values, 2nd byte */
enum {
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x16,
@ -1991,11 +1998,19 @@ enum Misc {
#define MAX_ENCRYPT_SZ ENCRYPT_LEN
#define WOLFSSL_ASSERT_SIZEOF_GE(x, y) do { \
typedef char _args_test_[sizeof((x)) >= sizeof((y)) ? 1 : -1]; \
(void)sizeof(_args_test_); \
/* A static check to assert a relation between x and y */
#define WOLFSSL_ASSERT_TEST(x, y, op) do { \
typedef char _args_test_[(x) op (y) ? 1 : -1]; \
(void)sizeof(_args_test_); \
} while(0)
#define WOLFSSL_ASSERT_EQ(x, y) WOLFSSL_ASSERT_TEST(x, y, ==)
#define WOLFSSL_ASSERT_SIZEOF_TEST(x, y, op) \
WOLFSSL_ASSERT_TEST(sizeof((x)), sizeof((y)), op)
#define WOLFSSL_ASSERT_SIZEOF_GE(x, y) WOLFSSL_ASSERT_SIZEOF_TEST(x, y, >=)
/* states. Adding state before HANDSHAKE_DONE will break session importing */
enum states {
NULL_STATE = 0,
@ -2154,7 +2169,9 @@ WOLFSSL_LOCAL int MatchDomainName(const char* pattern, int len, const char* str
#ifndef NO_CERTS
WOLFSSL_LOCAL int CheckForAltNames(DecodedCert* dCert, const char* domain, int* checkCN);
WOLFSSL_LOCAL int CheckIPAddr(DecodedCert* dCert, const char* ipasc);
WOLFSSL_LOCAL void CopyDecodedName(WOLFSSL_X509_NAME* name, DecodedCert* dCert, int nameType);
#endif
WOLFSSL_LOCAL int SetupTicket(WOLFSSL* ssl);
WOLFSSL_LOCAL int CreateTicket(WOLFSSL* ssl);
WOLFSSL_LOCAL int HashRaw(WOLFSSL* ssl, const byte* output, int sz);
WOLFSSL_LOCAL int HashOutput(WOLFSSL* ssl, const byte* output, int sz,
@ -2779,6 +2796,9 @@ typedef enum {
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TLSX_PSK_KEY_EXCHANGE_MODES = 0x002d,
#endif
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
TLSX_CERTIFICATE_AUTHORITIES = 0x002f,
#endif
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
TLSX_POST_HANDSHAKE_AUTH = 0x0031,
#endif
@ -3008,7 +3028,7 @@ typedef struct {
union {
OcspRequest ocsp;
} request;
#if defined(WOLFSSL_TLS13)
#ifdef WOLFSSL_TLS13
buffer response;
#endif
} CertificateStatusRequest;
@ -3163,6 +3183,10 @@ typedef struct InternalTicket {
#ifdef WOLFSSL_TICKET_HAVE_ID
byte id[ID_LEN];
#endif
#ifdef OPENSSL_EXTRA
byte sessionCtxSz; /* sessionCtx length */
byte sessionCtx[ID_LEN]; /* app specific context id */
#endif /* OPENSSL_EXTRA */
} InternalTicket;
#ifndef WOLFSSL_TICKET_EXTRA_PADDING_SZ
@ -3449,8 +3473,8 @@ struct WOLFSSL_CTX {
DerBuffer* certificate;
DerBuffer* certChain;
/* chain after self, in DER, with leading size for each cert */
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) || defined(HAVE_LIGHTY)
WOLF_STACK_OF(WOLFSSL_X509_NAME)* ca_names;
#ifndef WOLFSSL_NO_CA_NAMES
WOLF_STACK_OF(WOLFSSL_X509_NAME)* client_ca_names;
#endif
#ifdef OPENSSL_EXTRA
WOLF_STACK_OF(WOLFSSL_X509)* x509Chain;
@ -4822,7 +4846,7 @@ struct WOLFSSL_X509_NAME {
WOLFSSL_X509_NAME_ENTRY entry[MAX_NAME_ENTRIES]; /* all entries i.e. CN */
WOLFSSL_X509* x509; /* x509 that struct belongs to */
#endif /* OPENSSL_EXTRA */
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)
#ifndef WOLFSSL_NO_CA_NAMES
byte raw[ASN_NAME_MAX];
int rawLen;
@ -5720,8 +5744,8 @@ struct WOLFSSL {
byte clientFinished_len;
byte serverFinished_len;
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) || defined(HAVE_LIGHTY)
WOLF_STACK_OF(WOLFSSL_X509_NAME)* ca_names;
#ifndef WOLFSSL_NO_CA_NAMES
WOLF_STACK_OF(WOLFSSL_X509_NAME)* client_ca_names;
#endif
#if defined(WOLFSSL_IOTSAFE) && defined(HAVE_PK_CALLBACKS)
IOTSAFE iotsafe;
@ -5792,9 +5816,6 @@ struct WOLFSSL {
} \
} while (0)
#define SSL_CA_NAMES(ssl) ((ssl)->ca_names != NULL ? (ssl)->ca_names : \
(ssl)->ctx->ca_names)
WOLFSSL_LOCAL int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup);
WOLFSSL_LOCAL int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup);
WOLFSSL_LOCAL int ReinitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup);
@ -6079,7 +6100,11 @@ WOLFSSL_LOCAL WC_RNG* WOLFSSL_RSA_GetRNG(WOLFSSL_RSA *rsa, WC_RNG **tmpRNG,
DecodedCert* cert);
#endif
WOLFSSL_LOCAL Signer* GetCA(void* cm, byte* hash);
WOLFSSL_LOCAL Signer* GetCA(void* vp, byte* hash);
#ifdef WOLFSSL_AKID_NAME
WOLFSSL_LOCAL Signer* GetCAByAKID(void* vp, const byte* issuer,
word32 issuerSz, const byte* serial, word32 serialSz);
#endif
#ifndef NO_SKID
WOLFSSL_LOCAL Signer* GetCAByName(void* cm, byte* hash);
#endif
@ -6508,6 +6533,17 @@ WOLFSSL_LOCAL int wolfSSL_quic_keys_active(WOLFSSL* ssl, enum encrypt_side side)
#define WOLFSSL_IS_QUIC(s) 0
#endif /* WOLFSSL_QUIC (else) */
#if defined(SHOW_SECRETS) && defined(WOLFSSL_SSLKEYLOGFILE)
WOLFSSL_LOCAL int tls13ShowSecrets(WOLFSSL* ssl, int id, const unsigned char* secret,
int secretSz, void* ctx);
#endif
/* Optional Pre-Master-Secret logging for Wireshark */
#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_SSLKEYLOGFILE)
#ifndef WOLFSSL_SSLKEYLOGFILE_OUTPUT
#define WOLFSSL_SSLKEYLOGFILE_OUTPUT "sslkeylog.log"
#endif
#endif
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK)
WOLFSSL_LOCAL int FindPskSuite(const WOLFSSL* ssl, PreSharedKey* psk,

View File

@ -53,15 +53,19 @@ typedef struct OcspRequest WOLFSSL_OCSP_REQUEST;
WOLFSSL_LOCAL int InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm);
WOLFSSL_LOCAL void FreeOCSP(WOLFSSL_OCSP* ocsp, int dynamic);
WOLFSSL_LOCAL int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert,
WOLFSSL_BUFFER_INFO* responseBuffer);
WOLFSSL_LOCAL int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert);
WOLFSSL_LOCAL int CheckCertOCSP_ex(WOLFSSL_OCSP* ocsp, DecodedCert* cert,
WOLFSSL_BUFFER_INFO* responseBuffer, WOLFSSL* ssl);
WOLFSSL* ssl);
WOLFSSL_LOCAL int CheckOcspRequest(WOLFSSL_OCSP* ocsp,
OcspRequest* ocspRequest, WOLFSSL_BUFFER_INFO* responseBuffer);
OcspRequest* ocspRequest, WOLFSSL_BUFFER_INFO* responseBuffer,
void* heap);
WOLFSSL_LOCAL int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz,
WOLFSSL_BUFFER_INFO *responseBuffer, CertStatus *status,
OcspEntry *entry, OcspRequest *ocspRequest);
OcspEntry *entry, OcspRequest *ocspRequest,
void* heap);
WOLFSSL_LOCAL int CheckOcspResponder(OcspResponse *bs, DecodedCert *cert,
void* vp);
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
defined(WOLFSSL_APACHE_HTTPD) || defined(HAVE_LIGHTY)

View File

@ -1083,6 +1083,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_
wolfSSL_SESSION_get_ticket_lifetime_hint
#define SSL_SESSION_set_timeout wolfSSL_SSL_SESSION_set_timeout
#define SSL_SESSION_get_timeout wolfSSL_SESSION_get_timeout
#define SSL_SESSION_set_time wolfSSL_SESSION_set_time
#define SSL_SESSION_get_time wolfSSL_SESSION_get_time
#define SSL_CTX_get_ex_new_index wolfSSL_CTX_get_ex_new_index
@ -1510,6 +1511,11 @@ typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE;
#define SSL_R_UNEXPECTED_MESSAGE OUT_OF_ORDER_E
#define SSL_R_UNEXPECTED_RECORD SANITY_MSG_E
#define SSL_R_UNKNOWN_ALERT_TYPE BUFFER_ERROR
#define SSL_R_BAD_DIGEST_LENGTH BUFFER_ERROR
#define SSL_R_BAD_PACKET_LENGTH BUFFER_ERROR
#define SSL_R_DATA_LENGTH_TOO_LONG BUFFER_ERROR
#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG BUFFER_ERROR
#define SSL_R_BAD_LENGTH BUFFER_ERROR
#define SSL_R_UNKNOWN_PROTOCOL VERSION_ERROR
#define SSL_R_WRONG_VERSION_NUMBER VERSION_ERROR
#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC ENCRYPT_ERROR
@ -1519,6 +1525,7 @@ typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE;
#define SSL_R_CERTIFICATE_VERIFY_FAILED VERIFY_CERT_ERROR
#define SSL_R_CERT_CB_ERROR CLIENT_CERT_CB_ERROR
#define SSL_R_NULL_SSL_METHOD_PASSED BAD_FUNC_ARG
#define SSL_R_CCS_RECEIVED_EARLY OUT_OF_ORDER_E
#ifdef HAVE_SESSION_TICKET
#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72

View File

@ -1233,6 +1233,7 @@ WOLFSSL_API int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *
WOLFSSL_ABI WOLFSSL_API int wolfSSL_set_session(WOLFSSL* ssl, WOLFSSL_SESSION* session);
WOLFSSL_API long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t);
WOLFSSL_API long wolfSSL_SESSION_set_time(WOLFSSL_SESSION *ses, long t);
WOLFSSL_ABI WOLFSSL_API WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl);
WOLFSSL_ABI WOLFSSL_API void wolfSSL_flush_sessions(WOLFSSL_CTX* ctx, long tm);
WOLFSSL_API void wolfSSL_CTX_flush_sessions(WOLFSSL_CTX* ctx, long tm);
@ -2251,25 +2252,25 @@ enum {
WOLFSSL_OP_TLS_BLOCK_PADDING_BUG = 0x00000100,
WOLFSSL_OP_TLS_ROLLBACK_BUG = 0x00000200,
WOLFSSL_OP_EPHEMERAL_RSA = 0x00000800,
WOLFSSL_OP_NO_SSLv3 = 0x00001000,
WOLFSSL_OP_NO_TLSv1 = 0x00002000,
WOLFSSL_OP_NO_SSLv3 = 0x00001000,
WOLFSSL_OP_NO_TLSv1 = 0x00002000,
WOLFSSL_OP_PKCS1_CHECK_1 = 0x00004000,
WOLFSSL_OP_PKCS1_CHECK_2 = 0x00008000,
WOLFSSL_OP_NETSCAPE_CA_DN_BUG = 0x00010000,
WOLFSSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = 0x00020000,
WOLFSSL_OP_SINGLE_DH_USE = 0x00040000,
WOLFSSL_OP_SINGLE_DH_USE = 0x00040000,
WOLFSSL_OP_NO_TICKET = 0x00080000,
WOLFSSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = 0x00100000,
WOLFSSL_OP_NO_QUERY_MTU = 0x00200000,
WOLFSSL_OP_COOKIE_EXCHANGE = 0x00400000,
WOLFSSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = 0x00800000,
WOLFSSL_OP_SINGLE_ECDH_USE = 0x01000000,
WOLFSSL_OP_CIPHER_SERVER_PREFERENCE = 0x02000000,
WOLFSSL_OP_NO_TLSv1_1 = 0x04000000,
WOLFSSL_OP_NO_TLSv1_2 = 0x08000000,
WOLFSSL_OP_NO_COMPRESSION = 0x10000000,
WOLFSSL_OP_NO_TLSv1_3 = 0x20000000,
WOLFSSL_OP_NO_SSLv2 = 0x40000000,
WOLFSSL_OP_SINGLE_ECDH_USE = 0x01000000,
WOLFSSL_OP_CIPHER_SERVER_PREFERENCE = 0x02000000,
WOLFSSL_OP_NO_TLSv1_1 = 0x04000000,
WOLFSSL_OP_NO_TLSv1_2 = 0x08000000,
WOLFSSL_OP_NO_COMPRESSION = 0x10000000,
WOLFSSL_OP_NO_TLSv1_3 = 0x20000000,
WOLFSSL_OP_NO_SSLv2 = 0x40000000,
WOLFSSL_OP_ALL =
(WOLFSSL_OP_MICROSOFT_SESS_ID_BUG
| WOLFSSL_OP_NETSCAPE_CHALLENGE_BUG
@ -2535,7 +2536,9 @@ enum { /* ssl Constants */
WOLFSSL_SESS_CACHE_NO_AUTO_CLEAR = 0x0008,
WOLFSSL_SESS_CACHE_NO_INTERNAL_LOOKUP = 0x0100,
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE = 0x0200,
WOLFSSL_SESS_CACHE_NO_INTERNAL = 0x0300,
WOLFSSL_SESS_CACHE_NO_INTERNAL =
(WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE |
WOLFSSL_SESS_CACHE_NO_INTERNAL_LOOKUP),
WOLFSSL_ERROR_WANT_READ = 2,
WOLFSSL_ERROR_WANT_WRITE = 3,

View File

@ -1660,6 +1660,12 @@ struct DecodedCert {
int extCrlInfoSz; /* length of the URI */
byte extSubjKeyId[KEYID_SIZE]; /* Subject Key ID */
byte extAuthKeyId[KEYID_SIZE]; /* Authority Key ID */
#ifdef WOLFSSL_AKID_NAME
const byte* extAuthKeyIdIssuer; /* Authority Key ID authorityCertIssuer */
word32 extAuthKeyIdIssuerSz; /* Authority Key ID authorityCertIssuer length */
const byte* extAuthKeyIdIssuerSN; /* Authority Key ID authorityCertSerialNumber */
word32 extAuthKeyIdIssuerSNSz; /* Authority Key ID authorityCertSerialNumber length */
#endif
byte pathLength; /* CA basic constraint path length */
byte maxPathLen; /* max_path_len see RFC 5280 section
* 6.1.2 "Initialization" - (k) for
@ -1947,13 +1953,22 @@ struct Signer {
#endif /* IGNORE_NAME_CONSTRAINTS */
byte subjectNameHash[SIGNER_DIGEST_SIZE];
/* sha hash of names in certificate */
#ifdef HAVE_OCSP
byte issuerNameHash[SIGNER_DIGEST_SIZE];
/* sha hash of issuer names in certificate.
* Used in OCSP to check for authorized
* responders. */
#endif
#ifndef NO_SKID
byte subjectKeyIdHash[SIGNER_DIGEST_SIZE];
/* sha hash of names in certificate */
/* sha hash of key in certificate */
#endif
#ifdef HAVE_OCSP
byte subjectKeyHash[KEYID_SIZE];
#endif
#ifdef WOLFSSL_AKID_NAME
byte serialHash[SIGNER_DIGEST_SIZE]; /* serial number hash */
#endif
#ifdef WOLFSSL_SIGNER_DER_CERT
DerBuffer* derCert;
#endif
@ -2450,6 +2465,11 @@ struct OcspRequest {
int serialSz;
#ifdef OPENSSL_EXTRA
WOLFSSL_ASN1_INTEGER* serialInt;
#endif
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_APACHE_HTTPD) || \
defined(HAVE_LIGHTY)
void* cid; /* WOLFSSL_OCSP_CERTID kept to free */
#endif
byte* url; /* copy of the extAuthInfo in source cert */
int urlSz;