mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-10-24 04:09:07 +03:00
OpenResty 1.31.1.1 support and CI
Fixes needed by the OSP OpenResty 1.31.1.1 port, plus a workflow that runs the bundled SSL tests against wolfSSL. d2i_X509_bio(): read one DER object per call, as OpenSSL does. ngx_lua's set_der_cert() decodes a chain from one BIO one certificate at a time. MAX_EX_DATA: default to 10 slots for --enable-nginx unless --enable-context-extra-user-data gives a number. nginx 1.31 allocates six SSL_CTX ex_data indexes and the OpenResty Lua modules use five SSL ones. wolfSSL_OCSP_resp_find_status() and wolfSSL_OCSP_single_get0_status(): return NULL for an absent thisUpdate or nextUpdate instead of a pointer to a zeroed WOLFSSL_ASN1_TIME. ngx.ocsp.validate_ocsp_response() failed with "invalid nextUpdate time" for responses without nextUpdate. Session cache: with WOLFSSL_TICKET_HAVE_ID, DoClientTicketFinalize() called the external cache callback on every ticket resumption because useTicket is only set after DoClientTicket() returns. Add wolfSSL_GetSessionFromInternalCache() and use it unless the server accepts early data (maxEarlyDataSz > 0), where the external cache takes part in the 0-RTT anti-replay eviction. OpenSSL does the same: stateful tickets and a cache lookup only with max_early_data set. ngx_lua expects ssl_session_fetch_by_lua* to be skipped for ticket resumptions. .github/workflows/openresty.yml: build OpenResty 1.31.1.1 with the OSP port and tests patches against --enable-openresty and run the SSL test files of ngx_lua, ngx_stream_lua and lua-resty-core, plus the encrypted-session and set-misc suites, with Test::Nginx. Files that need APIs wolfSSL does not provide or the network are not run. The OSP checkout points at julek-dev/osp openresty-1.31.1.1 until the patches are merged into wolfSSL/osp. memcached is a new test dependency. Tests: d2i_X509_bio chain decoding, absent OCSP times, session cache callback counts with tickets and early data.
This commit is contained in:
@@ -81,6 +81,7 @@ libuv1-dev
|
||||
linux-libc-dev
|
||||
make
|
||||
man2html
|
||||
memcached
|
||||
meson
|
||||
mono-complete
|
||||
nghttp2
|
||||
|
||||
230
.github/workflows/openresty.yml
vendored
Normal file
230
.github/workflows/openresty.yml
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
name: OpenResty Tests
|
||||
|
||||
# START OF COMMON SECTION
|
||||
on:
|
||||
push:
|
||||
branches: [ 'release/**' ]
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
branches: [ '*' ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
# END OF COMMON SECTION
|
||||
|
||||
jobs:
|
||||
build_wolfssl:
|
||||
name: Build wolfSSL
|
||||
if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }}
|
||||
# Just to keep it the same as the testing target
|
||||
runs-on: ubuntu-24.04
|
||||
# This should be a safe limit for the tests to run.
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- name: Build wolfSSL
|
||||
uses: wolfSSL/actions-build-autotools-project@v1
|
||||
with:
|
||||
path: wolfssl
|
||||
configure: >-
|
||||
--enable-openresty --enable-curve25519 --enable-ed25519
|
||||
install: true
|
||||
|
||||
- name: tar build-dir
|
||||
run: tar -zcf build-dir.tgz build-dir
|
||||
|
||||
- name: Upload built lib
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: wolf-install-openresty
|
||||
path: build-dir.tgz
|
||||
retention-days: 5
|
||||
|
||||
openresty_check:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# The SSL test files of the bundled Lua modules. The port patch and
|
||||
# the tests patch come from the OSP repo.
|
||||
#
|
||||
# Not run (cannot work with wolfSSL, the tests patch makes them
|
||||
# skip): ssl_client_hello_by_lua* files (ngx_lua 166, 187; stream
|
||||
# 162, 163; lua-resty-core ssl-client-hello.t) need
|
||||
# SSL_CTX_set_client_hello_cb; proxy_ssl_*_by_lua* files (ngx_lua
|
||||
# 169, 170-proxy-ssl-cert; stream 164, 165-proxy-ssl-cert-by;
|
||||
# lua-resty-core proxy-ssl*.t) need SSL_set_retry_verify; FFI into
|
||||
# libcrypto (ngx_lua 193, stream 171, lua-resty-core
|
||||
# socket-tcp-settrustedstore.t) needs OpenSSL symbol names.
|
||||
# Not run (need the network): ngx_lua and stream 129-ssl-socket.t
|
||||
# and 170-ssl-session-reuse.t.
|
||||
- ref: 1.31.1.1
|
||||
sha256: 65b78baadd3f0984055de89bf13f4a1932e5bfe9c31932037a134ea2b1a0ce42
|
||||
osp-repo: julek-dev/osp
|
||||
osp-ref: openresty-1.31.1.1
|
||||
ngx-lua-tests: >-
|
||||
139-ssl-cert-by.t 140-ssl-c-api.t 142-ssl-session-store.t
|
||||
143-ssl-session-fetch.t 155-tls13.t 162-socket-tls-handshake.t
|
||||
stream-lua-tests: >-
|
||||
139-ssl-cert-by.t 140-ssl-c-api.t 165-serversslhandshake.t
|
||||
166-serversslhandshake-starttls.t
|
||||
167-serversslhandshake-errors.t
|
||||
resty-core-tests: >-
|
||||
ssl.t stream/ssl.t ocsp.t ssl-session-store.t
|
||||
ssl-session-fetch.t
|
||||
name: ${{ matrix.ref }}
|
||||
if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }}
|
||||
runs-on: ubuntu-24.04
|
||||
# Test::Nginx restarts nginx for every block, so the suites take a while.
|
||||
timeout-minutes: 45
|
||||
needs: build_wolfssl
|
||||
env:
|
||||
OR_PREFIX: ${{ github.workspace }}/or-install
|
||||
TEST_NGINX_BINARY: ${{ github.workspace }}/or-install/nginx/sbin/nginx
|
||||
TEST_NGINX_USE_WOLFSSL: 1
|
||||
TEST_NGINX_NO_SHUFFLE: 1
|
||||
TEST_NGINX_SLEEP: 0.05
|
||||
TEST_NGINX_MEMCACHED_PORT: 11211
|
||||
steps:
|
||||
- name: Checkout wolfSSL CI actions
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
sparse-checkout: .github/actions
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Install test dependencies
|
||||
uses: ./.github/actions/install-apt-deps
|
||||
with:
|
||||
packages: libpcre2-dev zlib1g-dev memcached
|
||||
ghcr-debs-tag: ubuntu-24.04-full
|
||||
|
||||
- name: Download lib
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: wolf-install-openresty
|
||||
|
||||
- name: untar build-dir
|
||||
run: tar -xf build-dir.tgz
|
||||
|
||||
- name: Setup Perl environment
|
||||
uses: shogo82148/actions-setup-perl@v1
|
||||
with:
|
||||
perl-version: '5.38.2'
|
||||
|
||||
- name: Install Test::Nginx
|
||||
run: cpanm --notest Test::Nginx@0.32
|
||||
|
||||
- name: Checkout OSP
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: ${{ matrix.osp-repo }}
|
||||
ref: ${{ matrix.osp-ref }}
|
||||
path: osp
|
||||
sparse-checkout: openresty
|
||||
|
||||
- name: Download OpenResty
|
||||
run: |
|
||||
curl -fsSL -o openresty.tar.gz \
|
||||
https://openresty.org/download/openresty-${{ matrix.ref }}.tar.gz
|
||||
echo "${{ matrix.sha256 }} openresty.tar.gz" | sha256sum -c
|
||||
tar -xf openresty.tar.gz
|
||||
|
||||
- name: Apply OSP patches
|
||||
working-directory: openresty-${{ matrix.ref }}
|
||||
run: |
|
||||
patch -p1 < ../osp/openresty/${{ matrix.ref }}.patch
|
||||
patch -p1 < ../osp/openresty/${{ matrix.ref }}-tests.patch
|
||||
|
||||
# --with-debug: the tests check the debug log.
|
||||
- name: Build OpenResty
|
||||
working-directory: openresty-${{ matrix.ref }}
|
||||
run: |
|
||||
./configure --prefix=$OR_PREFIX \
|
||||
--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-debug -j$(nproc)
|
||||
make -j$(nproc)
|
||||
make install
|
||||
|
||||
- name: Confirm OpenResty built with wolfSSL
|
||||
run: |
|
||||
ldd $TEST_NGINX_BINARY | grep wolfssl
|
||||
$TEST_NGINX_BINARY -V 2>&1 | grep 'built with wolfSSL'
|
||||
|
||||
# Short paths: the tests listen on unix sockets under t/servroot.
|
||||
# lua-resty-core expects its sibling lua-resty-lrucache by that name.
|
||||
- name: Prepare test directories
|
||||
working-directory: openresty-${{ matrix.ref }}/bundle
|
||||
run: |
|
||||
mkdir -p /tmp/ort
|
||||
mv ngx_lua-* /tmp/ort/ngx_lua
|
||||
mv ngx_stream_lua-* /tmp/ort/ngx_stream_lua
|
||||
mv lua-resty-core-* /tmp/ort/lua-resty-core
|
||||
mv lua-resty-lrucache-* /tmp/ort/lua-resty-lrucache
|
||||
mv encrypted-session-nginx-module-* /tmp/ort/encrypted-session
|
||||
mv set-misc-nginx-module-* /tmp/ort/set-misc
|
||||
|
||||
# Some blocks talk to memcached over UDP.
|
||||
- name: Start memcached
|
||||
run: |
|
||||
pkill -x memcached || true
|
||||
memcached -d -p 11211 -U 11211 -l 127.0.0.1
|
||||
|
||||
- if: ${{ runner.debug }}
|
||||
name: Verbose prove
|
||||
run: echo "prove_flags=-v" >> $GITHUB_ENV
|
||||
|
||||
- name: Run ngx_lua tests
|
||||
working-directory: /tmp/ort/ngx_lua
|
||||
env:
|
||||
LD_LIBRARY_PATH: ${{ github.workspace }}/build-dir/lib:${{ github.workspace }}/or-install/luajit/lib
|
||||
run: |
|
||||
prove ${{ env.prove_flags }} -I. \
|
||||
$(for t in ${{ matrix.ngx-lua-tests }}; do echo t/$t; done)
|
||||
|
||||
- if: ${{ !cancelled() }}
|
||||
name: Run ngx_stream_lua tests
|
||||
working-directory: /tmp/ort/ngx_stream_lua
|
||||
env:
|
||||
LD_LIBRARY_PATH: ${{ github.workspace }}/build-dir/lib:${{ github.workspace }}/or-install/luajit/lib
|
||||
run: |
|
||||
prove ${{ env.prove_flags }} -I. \
|
||||
$(for t in ${{ matrix.stream-lua-tests }}; do echo t/$t; done)
|
||||
|
||||
- if: ${{ !cancelled() }}
|
||||
name: Run lua-resty-core tests
|
||||
working-directory: /tmp/ort/lua-resty-core
|
||||
env:
|
||||
LD_LIBRARY_PATH: ${{ github.workspace }}/build-dir/lib:${{ github.workspace }}/or-install/luajit/lib
|
||||
run: |
|
||||
prove ${{ env.prove_flags }} -I. \
|
||||
$(for t in ${{ matrix.resty-core-tests }}; do echo t/$t; done)
|
||||
|
||||
# These two modules use the OpenSSL compatibility layer directly.
|
||||
- if: ${{ !cancelled() }}
|
||||
name: Run encrypted-session tests
|
||||
working-directory: /tmp/ort/encrypted-session
|
||||
env:
|
||||
LD_LIBRARY_PATH: ${{ github.workspace }}/build-dir/lib:${{ github.workspace }}/or-install/luajit/lib
|
||||
run: prove ${{ env.prove_flags }} -I. t/sanity.t
|
||||
|
||||
- if: ${{ !cancelled() }}
|
||||
name: Run set-misc tests
|
||||
working-directory: /tmp/ort/set-misc
|
||||
env:
|
||||
LD_LIBRARY_PATH: ${{ github.workspace }}/build-dir/lib:${{ github.workspace }}/or-install/luajit/lib
|
||||
run: prove ${{ env.prove_flags }} -I. t/hmac.t
|
||||
|
||||
- if: ${{ failure() }}
|
||||
name: Upload nginx logs
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: openresty-${{ matrix.ref }}-logs
|
||||
path: |
|
||||
/tmp/ort/*/t/servroot*/logs/*.log
|
||||
/tmp/ort/*/t/servroot*/conf/nginx.conf
|
||||
retention-days: 5
|
||||
@@ -3891,6 +3891,13 @@ if(NOT WOLFSSL_CONTEXT_EXTRA_USER_DATA STREQUAL "no")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# nginx 1.31 and the OpenResty Lua modules need six ex_data slots per object.
|
||||
if((WOLFSSL_NGINX OR WOLFSSL_OPENRESTY) AND
|
||||
(WOLFSSL_CONTEXT_EXTRA_USER_DATA STREQUAL "no" OR
|
||||
WOLFSSL_CONTEXT_EXTRA_USER_DATA STREQUAL "yes"))
|
||||
list(APPEND WOLFSSL_DEFINITIONS "-DMAX_EX_DATA=10")
|
||||
endif()
|
||||
|
||||
# ECC minimum key size (bits)
|
||||
if(WOLFSSL_FIPS)
|
||||
set(WOLFSSL_ECC_MIN_KEY_SZ_DEFAULT "192")
|
||||
|
||||
@@ -12308,6 +12308,13 @@ yes) AM_CFLAGS="$AM_CFLAGS -DHAVE_EX_DATA"
|
||||
;;
|
||||
esac
|
||||
|
||||
# nginx 1.31 and the OpenResty Lua modules need six ex_data slots per object.
|
||||
if test "$ENABLED_NGINX" = "yes" && \
|
||||
(test "$ENABLED_EX_DATA" = "no" || test "$ENABLED_EX_DATA" = "yes")
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DMAX_EX_DATA=10"
|
||||
fi
|
||||
|
||||
# IoT-Safe support
|
||||
AC_ARG_ENABLE([iotsafe],
|
||||
[AS_HELP_STRING([--enable-iotsafe],[Enables support for IoT-Safe secure applet (default: disabled)])],
|
||||
|
||||
@@ -43738,9 +43738,18 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
|
||||
XMEMCPY(ssl->session->sessionID, bogusID, ID_LEN);
|
||||
ssl->session->sessionIDSz= bogusIDSz;
|
||||
}
|
||||
#ifdef WOLFSSL_TICKET_HAVE_ID
|
||||
#if defined(WOLFSSL_TICKET_HAVE_ID) && !defined(NO_SESSION_CACHE)
|
||||
else {
|
||||
if (wolfSSL_GetSession(ssl, NULL, 1) != NULL) {
|
||||
int found;
|
||||
/* The external cache takes part in the 0-RTT anti-replay
|
||||
* eviction, so it is only skipped when early data is off. */
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if (ssl->options.maxEarlyDataSz > 0)
|
||||
found = wolfSSL_GetSessionFromCache(ssl, ssl->session);
|
||||
else
|
||||
#endif
|
||||
found = wolfSSL_GetSessionFromInternalCache(ssl, ssl->session);
|
||||
if (found == WOLFSSL_SUCCESS) {
|
||||
WOLFSSL_MSG("Found session matching the session id"
|
||||
" found in the ticket");
|
||||
}
|
||||
|
||||
26
src/ocsp.c
26
src/ocsp.c
@@ -730,10 +730,15 @@ int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs,
|
||||
if (status != NULL)
|
||||
*status = single->status->status;
|
||||
#ifdef WOLFSSL_OCSP_PARSE_STATUS
|
||||
if (thisupd != NULL)
|
||||
*thisupd = &single->status->thisDateParsed;
|
||||
if (nextupd != NULL)
|
||||
*nextupd = &single->status->nextDateParsed;
|
||||
/* NULL when the response has no such field, as with OpenSSL. */
|
||||
if (thisupd != NULL) {
|
||||
*thisupd = (single->status->thisDateParsed.length > 0) ?
|
||||
&single->status->thisDateParsed : NULL;
|
||||
}
|
||||
if (nextupd != NULL) {
|
||||
*nextupd = (single->status->nextDateParsed.length > 0) ?
|
||||
&single->status->nextDateParsed : NULL;
|
||||
}
|
||||
#else
|
||||
if (thisupd != NULL)
|
||||
*thisupd = NULL;
|
||||
@@ -1636,10 +1641,15 @@ int wolfSSL_OCSP_single_get0_status(WOLFSSL_OCSP_SINGLERESP *single,
|
||||
return -1;
|
||||
|
||||
#ifdef WOLFSSL_OCSP_PARSE_STATUS
|
||||
if (thisupd != NULL)
|
||||
*thisupd = &single->status->thisDateParsed;
|
||||
if (nextupd != NULL)
|
||||
*nextupd = &single->status->nextDateParsed;
|
||||
/* NULL when the response has no such field, as with OpenSSL. */
|
||||
if (thisupd != NULL) {
|
||||
*thisupd = (single->status->thisDateParsed.length > 0) ?
|
||||
&single->status->thisDateParsed : NULL;
|
||||
}
|
||||
if (nextupd != NULL) {
|
||||
*nextupd = (single->status->nextDateParsed.length > 0) ?
|
||||
&single->status->nextDateParsed : NULL;
|
||||
}
|
||||
#else
|
||||
if (thisupd != NULL)
|
||||
*thisupd = NULL;
|
||||
|
||||
@@ -1217,7 +1217,8 @@ int TlsSessionCacheGetAndWrLock(const byte *id, WOLFSSL_SESSION **sess,
|
||||
lockedRow, 0, side);
|
||||
}
|
||||
|
||||
int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
||||
static int GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output,
|
||||
byte internalOnly)
|
||||
{
|
||||
const WOLFSSL_SESSION* sess = NULL;
|
||||
const byte* id = NULL;
|
||||
@@ -1235,7 +1236,9 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
||||
byte bogusID[ID_LEN];
|
||||
byte bogusIDSz = 0;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_GetSessionFromCache");
|
||||
WOLFSSL_ENTER("GetSessionFromCache");
|
||||
|
||||
(void)internalOnly;
|
||||
|
||||
if (output == NULL) {
|
||||
WOLFSSL_MSG("NULL output");
|
||||
@@ -1270,7 +1273,7 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
||||
|
||||
|
||||
#ifdef HAVE_EXT_CACHE
|
||||
if (ssl->ctx->get_sess_cb != NULL) {
|
||||
if (!internalOnly && ssl->ctx->get_sess_cb != NULL) {
|
||||
int copy = 0;
|
||||
int found = 0;
|
||||
WOLFSSL_SESSION* extSess;
|
||||
@@ -1499,6 +1502,18 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
||||
return error;
|
||||
}
|
||||
|
||||
int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
||||
{
|
||||
return GetSessionFromCache(ssl, output, 0);
|
||||
}
|
||||
|
||||
/* Lookup by the ID carried in a decrypted ticket without calling the
|
||||
* external cache callback. */
|
||||
int wolfSSL_GetSessionFromInternalCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
||||
{
|
||||
return GetSessionFromCache(ssl, output, 1);
|
||||
}
|
||||
|
||||
WOLFSSL_SESSION* wolfSSL_GetSession(WOLFSSL* ssl, byte* masterSecret,
|
||||
byte restoreSessionCerts)
|
||||
{
|
||||
|
||||
38
src/x509.c
38
src/x509.c
@@ -8937,6 +8937,11 @@ static WOLFSSL_X509* d2i_X509orX509REQ_bio(WOLFSSL_BIO* bio,
|
||||
WOLFSSL_X509* localX509 = NULL;
|
||||
byte* mem = NULL;
|
||||
int size;
|
||||
int derSz;
|
||||
int hdrSz = 2;
|
||||
int len = 0;
|
||||
word32 idx = 1;
|
||||
byte hdr[6];
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_d2i_X509_bio");
|
||||
|
||||
@@ -8952,12 +8957,35 @@ static WOLFSSL_X509* d2i_X509orX509REQ_bio(WOLFSSL_BIO* bio,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(mem = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL))) {
|
||||
/* Consume only the first DER object. A BIO holding a chain is then
|
||||
* decoded one certificate per call, as with OpenSSL. */
|
||||
if (wolfSSL_BIO_read(bio, hdr, hdrSz) != hdrSz) {
|
||||
WOLFSSL_MSG("wolfSSL_BIO_read error");
|
||||
return NULL;
|
||||
}
|
||||
if (hdr[1] & ASN_LONG_LENGTH) {
|
||||
int n = hdr[1] & 0x7F;
|
||||
if (n < 1 || n > 4 || wolfSSL_BIO_read(bio, hdr + hdrSz, n) != n) {
|
||||
WOLFSSL_MSG("Bad DER length");
|
||||
return NULL;
|
||||
}
|
||||
hdrSz += n;
|
||||
}
|
||||
if (hdr[0] != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
|
||||
GetLength_ex(hdr, &idx, &len, (word32)hdrSz, 0) < 0 ||
|
||||
len < 0 || (int)idx + len > size) {
|
||||
WOLFSSL_MSG("Bad DER header");
|
||||
return NULL;
|
||||
}
|
||||
derSz = (int)idx + len;
|
||||
|
||||
if (!(mem = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL))) {
|
||||
WOLFSSL_MSG("malloc error");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((size = wolfSSL_BIO_read(bio, mem, size)) == 0) {
|
||||
XMEMCPY(mem, hdr, hdrSz);
|
||||
if (derSz > hdrSz && wolfSSL_BIO_read(bio, mem + hdrSz, derSz - hdrSz) !=
|
||||
derSz - hdrSz) {
|
||||
WOLFSSL_MSG("wolfSSL_BIO_read error");
|
||||
XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
return NULL;
|
||||
@@ -8965,13 +8993,13 @@ static WOLFSSL_X509* d2i_X509orX509REQ_bio(WOLFSSL_BIO* bio,
|
||||
|
||||
if (req) {
|
||||
#ifdef WOLFSSL_CERT_REQ
|
||||
localX509 = wolfSSL_X509_REQ_d2i(NULL, mem, size);
|
||||
localX509 = wolfSSL_X509_REQ_d2i(NULL, mem, derSz);
|
||||
#else
|
||||
WOLFSSL_MSG("CSR not compiled in");
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
localX509 = wolfSSL_X509_d2i_ex(NULL, mem, size, bio->heap);
|
||||
localX509 = wolfSSL_X509_d2i_ex(NULL, mem, derSz, bio->heap);
|
||||
}
|
||||
if (localX509 == NULL) {
|
||||
WOLFSSL_MSG("wolfSSL_X509_d2i error");
|
||||
|
||||
13
tests/api.c
13
tests/api.c
@@ -25111,6 +25111,8 @@ static int test_wolfSSL_OCSP_single_get0_status(void)
|
||||
certStatus.thisDateParsed.data[i] = i;
|
||||
certStatus.nextDateParsed.data[i] = i;
|
||||
}
|
||||
certStatus.thisDateParsed.length = CTC_DATE_SIZE;
|
||||
certStatus.nextDateParsed.length = CTC_DATE_SIZE;
|
||||
certStatus.status = CERT_GOOD;
|
||||
single.status = &certStatus;
|
||||
|
||||
@@ -25120,6 +25122,16 @@ static int test_wolfSSL_OCSP_single_get0_status(void)
|
||||
ExpectPtrEq(thisDate, &certStatus.thisDateParsed);
|
||||
ExpectPtrEq(nextDate, &certStatus.nextDateParsed);
|
||||
|
||||
/* nextUpdate is optional. Absent gives NULL like OpenSSL. */
|
||||
certStatus.nextDateParsed.length = 0;
|
||||
thisDate = NULL;
|
||||
nextDate = &certStatus.nextDateParsed;
|
||||
ret = wolfSSL_OCSP_single_get0_status(&single, NULL, NULL, &thisDate,
|
||||
&nextDate);
|
||||
ExpectIntEQ(ret, CERT_GOOD);
|
||||
ExpectPtrEq(thisDate, &certStatus.thisDateParsed);
|
||||
ExpectNull(nextDate);
|
||||
|
||||
ExpectIntEQ(wolfSSL_OCSP_single_get0_status(NULL, NULL, NULL, NULL, NULL),
|
||||
-1);
|
||||
ExpectIntEQ(wolfSSL_OCSP_single_get0_status(&single, NULL, NULL, NULL,
|
||||
@@ -42714,6 +42726,7 @@ TEST_CASE testCases[] = {
|
||||
TEST_DECL_GROUP("ocsp", test_ocsp_certid_enc_dec),
|
||||
TEST_DECL_GROUP("ocsp", test_ocsp_certid_dup),
|
||||
TEST_DECL_GROUP("ocsp", test_ocsp_resp_find_status_serial_prefix),
|
||||
TEST_DECL_GROUP("ocsp", test_ocsp_resp_times),
|
||||
TEST_DECL(test_ocsp_tls_cert_cb),
|
||||
TEST_DECL_GROUP("ocsp", test_ocsp_status_request_v2_multi_revoked_single),
|
||||
TEST_DECL_GROUP("ocsp", test_ocsp_cert_unknown_crl_fallback),
|
||||
|
||||
@@ -976,6 +976,8 @@ int test_ocsp_resp_find_status_serial_prefix(void)
|
||||
OcspEntry requestedId;
|
||||
CertStatus requestedStatus;
|
||||
int status;
|
||||
WOLFSSL_ASN1_TIME* thisupd = NULL;
|
||||
WOLFSSL_ASN1_TIME* nextupd = NULL;
|
||||
|
||||
XMEMSET(&response, 0, sizeof(response));
|
||||
XMEMSET(&single, 0, sizeof(single));
|
||||
@@ -1008,6 +1010,21 @@ int test_ocsp_resp_find_status_serial_prefix(void)
|
||||
NULL, NULL, NULL, NULL), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(status, CERT_GOOD);
|
||||
|
||||
/* No update times parsed: both must come back NULL. */
|
||||
ExpectIntEQ(wolfSSL_OCSP_resp_find_status(&response, &requestedId, &status,
|
||||
NULL, NULL, &thisupd, &nextupd), WOLFSSL_SUCCESS);
|
||||
ExpectNull(thisupd);
|
||||
ExpectNull(nextupd);
|
||||
#ifdef WOLFSSL_OCSP_PARSE_STATUS
|
||||
/* thisUpdate present, nextUpdate absent. */
|
||||
responseStatus.thisDateParsed.length = 15;
|
||||
nextupd = &responseStatus.nextDateParsed;
|
||||
ExpectIntEQ(wolfSSL_OCSP_resp_find_status(&response, &requestedId, &status,
|
||||
NULL, NULL, &thisupd, &nextupd), WOLFSSL_SUCCESS);
|
||||
ExpectPtrEq(thisupd, &responseStatus.thisDateParsed);
|
||||
ExpectNull(nextupd);
|
||||
#endif
|
||||
|
||||
/* Request serial 01:02:03 (3 bytes) shares the 01:02 prefix of the
|
||||
* response serial.
|
||||
* The lookup must not bind the good response to this longer and
|
||||
@@ -1023,6 +1040,43 @@ int test_ocsp_resp_find_status_serial_prefix(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* The test responses carry thisUpdate only. */
|
||||
int test_ocsp_resp_times(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_OCSP) && defined(OPENSSL_EXTRA) && !defined(NO_SHA) && \
|
||||
!defined(NO_RSA)
|
||||
const unsigned char* ptr = (const unsigned char*)resp;
|
||||
OcspResponse* response = NULL;
|
||||
WOLFSSL_OCSP_BASICRESP* bs = NULL;
|
||||
WOLFSSL_OCSP_SINGLERESP* single = NULL;
|
||||
WOLFSSL_ASN1_TIME* thisupd = NULL;
|
||||
WOLFSSL_ASN1_TIME* nextupd = NULL;
|
||||
int reason = -1;
|
||||
|
||||
ExpectNotNull(response = wolfSSL_d2i_OCSP_RESPONSE(NULL, &ptr,
|
||||
sizeof(resp)));
|
||||
ExpectNotNull(bs = wolfSSL_OCSP_response_get1_basic(response));
|
||||
ExpectNotNull(single = wolfSSL_OCSP_resp_get0(bs, 0));
|
||||
ExpectIntEQ(wolfSSL_OCSP_single_get0_status(single, &reason, NULL,
|
||||
&thisupd, &nextupd), CERT_GOOD);
|
||||
#ifdef WOLFSSL_OCSP_PARSE_STATUS
|
||||
ExpectNotNull(thisupd);
|
||||
if (thisupd != NULL) {
|
||||
ExpectIntEQ(thisupd->type, ASN_GENERALIZED_TIME);
|
||||
ExpectIntGT(thisupd->length, 0);
|
||||
}
|
||||
#else
|
||||
ExpectNull(thisupd);
|
||||
#endif
|
||||
ExpectNull(nextupd);
|
||||
|
||||
wolfSSL_OCSP_BASICRESP_free(bs);
|
||||
wolfSSL_OCSP_RESPONSE_free(response);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(HAVE_OCSP) && defined(WOLFSSL_CERT_SETUP_CB) && \
|
||||
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && !defined(NO_RSA) && \
|
||||
(defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
int test_ocsp_certid_enc_dec(void);
|
||||
int test_ocsp_certid_dup(void);
|
||||
int test_ocsp_resp_find_status_serial_prefix(void);
|
||||
int test_ocsp_resp_times(void);
|
||||
int test_ocsp_status_callback(void);
|
||||
int test_ocsp_basic_verify(void);
|
||||
int test_ocsp_responder_keyhash_binding(void);
|
||||
|
||||
@@ -640,6 +640,50 @@ int test_wolfSSL_X509(void)
|
||||
X509_free(x509);
|
||||
BIO_free(bio);
|
||||
bio = NULL;
|
||||
|
||||
/* d2i_X509_bio reads one certificate per call and leaves the rest. */
|
||||
{
|
||||
byte chain[4096];
|
||||
int svrSz = 0;
|
||||
int caSz = 0;
|
||||
X509* x509b = NULL;
|
||||
|
||||
ExpectTrue((fp = XFOPEN("certs/server-cert.der", "rb")) != XBADFILE);
|
||||
if (fp != XBADFILE) {
|
||||
svrSz = (int)XFREAD(chain, 1, sizeof(chain), fp);
|
||||
XFCLOSE(fp);
|
||||
fp = XBADFILE;
|
||||
}
|
||||
ExpectIntGT(svrSz, 0);
|
||||
ExpectTrue((fp = XFOPEN(der, "rb")) != XBADFILE);
|
||||
if (fp != XBADFILE && svrSz > 0) {
|
||||
caSz = (int)XFREAD(chain + svrSz, 1, sizeof(chain) - svrSz, fp);
|
||||
}
|
||||
if (fp != XBADFILE) {
|
||||
XFCLOSE(fp);
|
||||
fp = XBADFILE;
|
||||
}
|
||||
ExpectIntGT(caSz, 0);
|
||||
|
||||
ExpectNotNull(bio = BIO_new_mem_buf(chain, svrSz + caSz));
|
||||
ExpectNotNull(x509 = d2i_X509_bio(bio, NULL));
|
||||
ExpectIntEQ(BIO_pending(bio), caSz);
|
||||
ExpectNotNull(x509b = d2i_X509_bio(bio, NULL));
|
||||
ExpectIntEQ(BIO_pending(bio), 0);
|
||||
ExpectNull(d2i_X509_bio(bio, NULL));
|
||||
ExpectIntNE(X509_cmp(x509, x509b), 0);
|
||||
X509_free(x509);
|
||||
x509 = NULL;
|
||||
X509_free(x509b);
|
||||
BIO_free(bio);
|
||||
bio = NULL;
|
||||
|
||||
/* Truncated DER is rejected. */
|
||||
ExpectNotNull(bio = BIO_new_mem_buf(chain, svrSz - 1));
|
||||
ExpectNull(d2i_X509_bio(bio, NULL));
|
||||
BIO_free(bio);
|
||||
bio = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* X509_up_ref test */
|
||||
|
||||
@@ -490,6 +490,16 @@ static int twcase_cache_intOn_extOn_noTicket(WOLFSSL_CTX* ctx)
|
||||
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
|
||||
return TEST_SUCCESS;
|
||||
}
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
/* Early data on: ticket resumption consults the external cache. */
|
||||
static int twcase_cache_intOn_extOn_earlyData(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
ExpectIntEQ(twcase_cache_intOn_extOn(ctx), TEST_SUCCESS);
|
||||
ExpectIntGE(wolfSSL_CTX_set_max_early_data(ctx, MAX_EARLY_DATA_SZ), 0);
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
#endif
|
||||
static int twcase_server_sess_ctx_pre_shutdown(WOLFSSL* ssl)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
@@ -575,6 +585,20 @@ static int twcase_client_sess_ctx_pre_shutdown(WOLFSSL* ssl)
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
/* Client asks for a ticket so TLS 1.2 also resumes with one. */
|
||||
static int twcase_client_use_ticket(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
ExpectIntEQ(twcase_cache_intOff_extOff(ctx), TEST_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_CTX_UseSessionTicket(ctx), WOLFSSL_SUCCESS);
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
static int twcase_resume_on_result(WOLFSSL* ssl)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
ExpectIntEQ(wolfSSL_session_reused(ssl), 1);
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
static int twcase_client_set_sess_ssl_ready(WOLFSSL* ssl)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
@@ -602,6 +626,14 @@ static WC_MAYBE_UNUSED int test_wolfSSL_CTX_add_session_ext(
|
||||
EXPECT_DECLS;
|
||||
/* Test the default 33 sessions */
|
||||
int j;
|
||||
int tls13 = XSTRSTR(param->tls_version, "TLSv1_3") != NULL;
|
||||
int dtls = XSTRSTR(param->tls_version, "DTLS") != NULL;
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
/* Case 6 enables early data, which is TLS 1.3 only. */
|
||||
const int cases = tls13 ? 7 : 6;
|
||||
#else
|
||||
const int cases = 6;
|
||||
#endif
|
||||
|
||||
/* Clear cache before starting */
|
||||
wolfSSL_CTX_flush_sessions(NULL, -1);
|
||||
@@ -612,15 +644,13 @@ static WC_MAYBE_UNUSED int test_wolfSSL_CTX_add_session_ext(
|
||||
server_sessionCache.capacity = SESSION_CACHE_SIZE;
|
||||
|
||||
fprintf(stderr, "\tBegin %s\n", param->tls_version);
|
||||
for (j = 0; j < 5; j++) {
|
||||
int tls13 = XSTRSTR(param->tls_version, "TLSv1_3") != NULL;
|
||||
int dtls = XSTRSTR(param->tls_version, "DTLS") != NULL;
|
||||
for (j = 0; j < cases; j++) {
|
||||
test_ssl_cbf client_cb;
|
||||
test_ssl_cbf server_cb;
|
||||
|
||||
(void)dtls;
|
||||
|
||||
/* Test five cache configurations */
|
||||
/* Test the cache configurations */
|
||||
twcase_client_first_session_ptr = NULL;
|
||||
twcase_server_first_session_ptr = NULL;
|
||||
twcase_server_current_ctx_ptr = NULL;
|
||||
@@ -657,8 +687,20 @@ static WC_MAYBE_UNUSED int test_wolfSSL_CTX_add_session_ext(
|
||||
case 4:
|
||||
server_cb.ctx_ready = twcase_cache_intOff_extOff;
|
||||
break;
|
||||
case 5:
|
||||
/* ticket resumption for all versions */
|
||||
server_cb.ctx_ready = twcase_cache_intOn_extOn;
|
||||
break;
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
case 6:
|
||||
server_cb.ctx_ready = twcase_cache_intOn_extOn_earlyData;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
client_cb.ctx_ready = twcase_cache_intOff_extOff;
|
||||
if (j == 5)
|
||||
client_cb.ctx_ready = twcase_client_use_ticket;
|
||||
else
|
||||
client_cb.ctx_ready = twcase_cache_intOff_extOff;
|
||||
|
||||
/* Add session to internal cache and save SSL session for testing */
|
||||
server_cb.on_result = twcase_server_sess_ctx_pre_shutdown;
|
||||
@@ -684,6 +726,8 @@ static WC_MAYBE_UNUSED int test_wolfSSL_CTX_add_session_ext(
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 5:
|
||||
case 6:
|
||||
/* cache cannot be searched with out a connection */
|
||||
/* Add a new session */
|
||||
ExpectIntEQ(twcase_new_session_called, 1);
|
||||
@@ -705,8 +749,8 @@ static WC_MAYBE_UNUSED int test_wolfSSL_CTX_add_session_ext(
|
||||
twcase_new_session_called = 0;
|
||||
twcase_remove_session_called = 0;
|
||||
twcase_get_session_called = 0;
|
||||
server_cb.on_result = 0;
|
||||
client_cb.on_result = 0;
|
||||
server_cb.on_result = twcase_resume_on_result;
|
||||
client_cb.on_result = twcase_resume_on_result;
|
||||
server_cb.ticNoInit = 1; /* Use default builtin */
|
||||
|
||||
server_cb.ctx = twcase_server_current_ctx_ptr;
|
||||
@@ -754,8 +798,9 @@ static WC_MAYBE_UNUSED int test_wolfSSL_CTX_add_session_ext(
|
||||
case 1:
|
||||
if (tls13) {
|
||||
/* (D)TLSv1.3 case */
|
||||
/* cache hit */
|
||||
ExpectIntEQ(twcase_get_session_called, 1);
|
||||
/* Ticket resumption. The external cache is not
|
||||
* consulted, as in OpenSSL. */
|
||||
ExpectIntEQ(twcase_get_session_called, 0);
|
||||
/* (D)TLSv1.3 creates a new ticket,
|
||||
* updates both internal and external cache */
|
||||
ExpectIntEQ(twcase_new_session_called, 1);
|
||||
@@ -764,7 +809,7 @@ static WC_MAYBE_UNUSED int test_wolfSSL_CTX_add_session_ext(
|
||||
ExpectIntEQ(twcase_remove_session_called, 1);
|
||||
}
|
||||
else {
|
||||
/* non (D)TLSv1.3 case */
|
||||
/* non (D)TLSv1.3 case, session ID resumption */
|
||||
/* cache hit */
|
||||
/* DTLS accesses cache once for stateless parsing and
|
||||
* once for stateful parsing */
|
||||
@@ -782,8 +827,9 @@ static WC_MAYBE_UNUSED int test_wolfSSL_CTX_add_session_ext(
|
||||
case 2:
|
||||
if (tls13) {
|
||||
/* (D)TLSv1.3 case */
|
||||
/* cache hit */
|
||||
ExpectIntEQ(twcase_get_session_called, 1);
|
||||
/* Ticket resumption. The external cache is not
|
||||
* consulted, as in OpenSSL. */
|
||||
ExpectIntEQ(twcase_get_session_called, 0);
|
||||
/* (D)TLSv1.3 creates a new ticket,
|
||||
* updates both internal and external cache */
|
||||
ExpectIntEQ(twcase_new_session_called, 1);
|
||||
@@ -792,7 +838,7 @@ static WC_MAYBE_UNUSED int test_wolfSSL_CTX_add_session_ext(
|
||||
ExpectIntEQ(twcase_remove_session_called, 1);
|
||||
}
|
||||
else {
|
||||
/* non (D)TLSv1.3 case */
|
||||
/* non (D)TLSv1.3 case, session ID resumption */
|
||||
/* cache hit */
|
||||
/* DTLS accesses cache once for stateless parsing and
|
||||
* once for stateful parsing */
|
||||
@@ -814,6 +860,29 @@ static WC_MAYBE_UNUSED int test_wolfSSL_CTX_add_session_ext(
|
||||
ExpectIntEQ(twcase_new_session_called, 0);
|
||||
ExpectIntEQ(twcase_remove_session_called, 0);
|
||||
break;
|
||||
case 5:
|
||||
/* Ticket resumption. The external cache is not consulted,
|
||||
* as in OpenSSL. */
|
||||
ExpectIntEQ(twcase_get_session_called, 0);
|
||||
if (tls13) {
|
||||
ExpectIntEQ(twcase_new_session_called, 1);
|
||||
ExpectIntEQ(twcase_remove_session_called, 1);
|
||||
}
|
||||
else {
|
||||
/* The ticket is reused, no new session */
|
||||
ExpectIntEQ(twcase_new_session_called, 0);
|
||||
ExpectIntEQ(twcase_remove_session_called, 1);
|
||||
}
|
||||
break;
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
case 6:
|
||||
/* Ticket resumption with early data on. The external cache
|
||||
* takes part in anti-replay, so it is consulted. */
|
||||
ExpectIntEQ(twcase_get_session_called, 1);
|
||||
ExpectIntEQ(twcase_new_session_called, 1);
|
||||
ExpectIntEQ(twcase_remove_session_called, 1);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
wolfSSL_SESSION_free(twcase_client_first_session_ptr);
|
||||
wolfSSL_SESSION_free(twcase_server_first_session_ptr);
|
||||
|
||||
@@ -5193,6 +5193,8 @@ WOLFSSL_LOCAL int TlsSessionCacheGetAndWrLock(const byte *id,
|
||||
WOLFSSL_SESSION **sess, word32 *lockedRow, byte side);
|
||||
WOLFSSL_LOCAL void EvictSessionFromCache(WOLFSSL_SESSION* session);
|
||||
WOLFSSL_TEST_VIS int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output);
|
||||
WOLFSSL_LOCAL int wolfSSL_GetSessionFromInternalCache(WOLFSSL* ssl,
|
||||
WOLFSSL_SESSION* output);
|
||||
WOLFSSL_LOCAL int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session);
|
||||
WOLFSSL_LOCAL void wolfSSL_FreeSession(WOLFSSL_CTX* ctx,
|
||||
WOLFSSL_SESSION* session);
|
||||
|
||||
Reference in New Issue
Block a user