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:
parent
52b5adb54a
commit
0abaa89787
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -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
176
.github/workflows/nginx.yml
vendored
Normal 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 }}
|
||||
|
14
configure.ac
14
configure.ac
@ -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"
|
||||
|
153
src/internal.c
153
src/internal.c
@ -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;
|
||||
|
237
src/ocsp.c
237
src/ocsp.c
@ -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
205
src/ssl.c
@ -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, ©);
|
||||
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
303
src/tls.c
@ -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
|
||||
|
92
src/tls13.c
92
src/tls13.c
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user