nginx 1.28.1

### `wolfssl/internal.h`

- **`InternalTicket` struct gains a flexible array member**: A new `peerCert[]` field (with a preceding `peerCertLen[2]`) is added to `InternalTicket`. This allows the peer's DER-encoded certificate to be stored directly inside the session ticket.
- **`ExternalTicket` struct becomes variable-length**: The `enc_ticket` field is changed from a fixed-size array to a flexible array member (`byte enc_ticket[]`). The `mac` field is removed from the struct — the MAC is now placed dynamically after the encrypted data in `enc_ticket`.

### `src/internal.c`

- The `GetRecordHeader` function now only adds `MAX_COMP_EXTRA` to the maximum allowed record size when `ssl->options.usingCompression` is true, tightening the length validation. The max fragment length extension check is now much stricter.
- **Peer certificate is serialized into the ticket**: During ticket creation, the code attempts to find the peer certificate from `ssl->peerCert` or from `ssl->session->chain` (fallback). If found and within `MAX_TICKET_PEER_CERT_SZ`, it's copied into `it->peerCert`. DTLS is explicitly excluded (peer cert length set to 0) to keep ticket size small for MTU constraints. If `HAVE_MAX_FRAGMENT` is defined and max fragment is not `MAX_RECORD_SIZE` for TLS 1.3, the cert is also skipped since `SendTls13NewSessionTicket` doesn't support fragmentation yet.
- **Peer certificate restoration from ticket**: On successful ticket decryption, if the ticket contains a peer certificate (`peerCertLen > 0`), it is decoded back into `ssl->peerCert` via `ParseCertRelative`/`CopyDecodedToX509`, and also added to `ssl->session->chain` via `AddSessionCertToChain`.
- The `CLEAR_ASN_NO_PEM_HEADER_ERROR` macro was rewritten to loop and remove all consecutive PEM no-start-line errors (not just the last one), wrapped in a `do { ... } while(0)` for safety.
- The `SendTicket` function is simplified to use `SendHandshakeMsg` to support fragmenting the larger ticket.

---

### `src/x509.c`

- `loadX509orX509REQFromPemBio` now accepts `TRUSTED_CERT_TYPE` in addition to `CERT_TYPE` and `CERTREQ_TYPE`.
- **Streaming BIO support**: When `wolfSSL_BIO_get_len()` returns ≤ 0 (e.g., pipes/FIFOs), the function no longer returns an error. Instead, it sets an initial buffer of `MAX_X509_SIZE` and dynamically grows (doubling) up to `MAX_BIO_READ_BUFFER` (`MAX_X509_SIZE * 16`) as data is read byte-by-byte.
- **Alternate footer detection**: For `TRUSTED_CERT_TYPE`, the PEM reader also checks for the regular `CERT_TYPE` footer (`-----END CERTIFICATE-----`) in addition to the trusted cert footer (`-----END TRUSTED CERTIFICATE-----`), so it can parse either format.
- Removed two lines that set `cert->srcIdx` to `SIGALGO_SEQ` offset. This makes `cert->srcIdx` reflect the end of parsed certificate data. This is used by `loadX509orX509REQFromBuffer` to detect where auxiliary trust data begins in trusted certificates.

---

### `src/ssl_sk.c`

- Added a `STACK_TYPE_X509_CRL` case to `wolfssl_sk_dup_data` that calls `wolfSSL_X509_CRL_dup` for deep-copying CRL stack elements. Previously, `STACK_TYPE_X509_CRL` fell through to the unsupported default case.

---

### `wolfssl/openssl/ssl.h`

- `sk_X509_dup` now maps to `wolfSSL_shallow_sk_dup` (was `wolfSSL_sk_dup`/deep copy). This matches OpenSSL's behavior where `sk_X509_dup` does a shallow copy.
- `sk_SSL_CIPHER_dup` similarly changed to `wolfSSL_shallow_sk_dup`.

---

### `src/ssl_api_cert.c`

- When `ssl->ourCert` is `NULL` and the SSL owns its cert, the function now checks if `ssl->ctx->ourCert` points to the same certificate (by comparing DER buffers). If so, it returns the ctx's `X509` pointer directly. This maintains pointer compatibility for applications (like nginx OCSP stapling) that use the `X509*` from `SSL_CTX_use_certificate` as a lookup key.

### `src/bio.c`

- When `wolfssl_file_len` returns `WOLFSSL_BAD_FILETYPE` (now returned for pipes/FIFOs), `wolfSSL_BIO_get_len` treats it as length 0 instead of propagating the error.

---

### `tests/test-maxfrag.conf` and `tests/test-maxfrag-dtls.conf`

- Removed `DHE-RSA-AES256-GCM-SHA384` test entries because the ClientKeyExchange doesn't fit in the selected max fragment length.
This commit is contained in:
Juliusz Sosinowicz
2026-01-20 13:51:44 +01:00
parent 47033c4b3e
commit 38b52d8079
20 changed files with 670 additions and 284 deletions
+54 -31
View File
@@ -12,6 +12,10 @@ concurrency:
cancel-in-progress: true
# END OF COMMON SECTION
# clang has better sanitizer support
env:
CC: clang
jobs:
build_wolfssl:
name: Build wolfSSL
@@ -31,7 +35,8 @@ jobs:
uses: wolfSSL/actions-build-autotools-project@v1
with:
path: wolfssl
configure: --enable-nginx ${{ env.wolf_debug_flags }}
configure: >-
--enable-nginx --enable-curve25519 --enable-ed25519 ${{ env.wolf_debug_flags }}
install: true
- name: tar build-dir
@@ -50,6 +55,41 @@ jobs:
matrix:
include:
# in general we want to pass all tests that match *ssl*
- ref: 1.28.1
test-ref: 0fccfcef1278263416043e0bbb3e0116b84026e4
# 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_session_reuse.t
mail_ssl.t proxy_ssl_certificate_cache.t
proxy_ssl_certificate_empty.t proxy_ssl_certificate.t
proxy_ssl_certificate_vars.t proxy_ssl_name.t ssl_cache_reload.t
ssl_certificate_aux.t ssl_certificate_cache.t
ssl_certificate_chain.t ssl_certificates.t ssl_certificate.t
ssl_client_escaped_cert.t ssl_crl.t ssl_curve.t ssl_ocsp.t
ssl_password_file.t ssl_proxy_upgrade.t ssl_reject_handshake.t
ssl_session_reuse.t ssl_session_ticket_key.t ssl_sni_protocols.t
ssl_sni_reneg.t ssl_sni_sessions.t ssl_sni.t ssl_stapling.t ssl.t
ssl_verify_client.t ssl_verify_client_trusted.t ssl_verify_depth.t
stream_proxy_ssl_certificate_cache.t stream_proxy_ssl_certificate.t
stream_proxy_ssl_certificate_vars.t
stream_proxy_ssl_name_complex.t stream_proxy_ssl_name.t
stream_ssl_alpn.t stream_ssl_certificate_cache.t
stream_ssl_certificate.t stream_ssl_ocsp.t stream_ssl_preread_alpn.t
stream_ssl_preread_protocol.t stream_ssl_preread.t
stream_ssl_reject_handshake.t stream_ssl_session_reuse.t
stream_ssl_sni_protocols.t stream_ssl_stapling.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
# 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_conf_command.t
proxy_ssl_keepalive.t proxy_ssl.t proxy_ssl_verify.t ssl_cache.t
stream_proxy_protocol_ssl.t stream_proxy_ssl_conf_command.t
stream_proxy_ssl.t stream_proxy_ssl_verify.t
- ref: 1.25.0
test-ref: 5b2894ea1afd01a26c589ce11f310df118e42592
# Following tests pass with sanitizer on
@@ -120,30 +160,19 @@ jobs:
- name: untar build-dir
run: tar -xf build-dir.tgz
- name: Install dependencies
run: |
sudo cpan -iT Proc::Find
- name: Openssl version
run: openssl version -a
# Locking in the version of SSLeay used with testing
- name: Download and install Net::SSLeay 1.94 manually
run: |
curl -LO https://www.cpan.org/modules/by-module/Net/CHRISN/Net-SSLeay-1.94.tar.gz
tar -xzf Net-SSLeay-1.94.tar.gz
cd Net-SSLeay-1.94
perl Makefile.PL
make
sudo make install
- name: Setup Perl environment
uses: shogo82148/actions-setup-perl@v1
with:
perl-version: '5.38.2'
# SSL version 2.091 changes '' return to undef causing test case to fail.
# Locking in the test version to use as 2.090
- name: Download and install IO::Socket::SSL 2.090 manually
- name: Install dependencies
run: |
curl -LO https://www.cpan.org/modules/by-module/IO/IO-Socket-SSL-2.090.tar.gz
tar -xzf IO-Socket-SSL-2.090.tar.gz
cd IO-Socket-SSL-2.090
perl Makefile.PL
make
sudo make install
cpanm --notest Proc::Find Net::SSLeay@1.94 IO::Socket::SSL@2.090
- name: Checkout wolfssl-nginx
uses: actions/checkout@v4
@@ -211,17 +240,14 @@ jobs:
run: |
echo "nginx_c_flags=-O0" >> $GITHUB_ENV
- name: workaround high-entropy ASLR
# not needed after either an update to llvm or runner is done
run: sudo sysctl vm.mmap_rnd_bits=28
- 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-cc-opt='-fsanitize=address -DNGX_DEBUG_PALLOC=1 -g3 \
${{ env.nginx_c_flags }}' \
--with-ld-opt='-fsanitize=address ${{ env.nginx_c_flags }}'
make -j
@@ -229,19 +255,16 @@ jobs:
working-directory: nginx
run: ldd objs/nginx | grep wolfssl
- if: ${{ runner.debug }}
name: Run nginx-tests with sanitizer (debug)
- name: Create LSAN suppression file
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 }}
echo "leak:ngx_worker_process_init" > lsan.supp
- 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 \
LSAN_OPTIONS=suppressions=$GITHUB_WORKSPACE/nginx-tests/lsan.supp \
TMPDIR=$GITHUB_WORKSPACE TEST_NGINX_BINARY=../nginx/objs/nginx \
prove ${{ matrix.sanitize-ok }}
+2
View File
@@ -220,6 +220,7 @@ ENABLED_BSDKM_REGISTER
ENABLE_SECURE_SOCKETS_LOGS
ESP32
ESP8266
ESPIPE
ESP_ENABLE_WOLFSSH
ESP_IDF_VERSION
ESP_IDF_VERSION_MAJOR
@@ -367,6 +368,7 @@ NO_ASM
NO_ASN_OLD_TYPE_NAMES
NO_CAMELLIA_CBC
NO_CERT
NO_CERT_IN_TICKET
NO_CIPHER_SUITE_ALIASES
NO_CLIENT_CACHE
NO_CLOCK_SPEEDUP
+2 -1
View File
@@ -2743,7 +2743,8 @@ if test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "$ENABLED_OPENVPN" = "yes" || \
test "$ENABLED_OPENRESTY" = "yes" || test "$ENABLED_RSYSLOG" = "yes" || \
test "$ENABLED_KRB" = "yes" || test "$ENABLED_CHRONY" = "yes" || \
test "$ENABLED_FFMPEG" = "yes" || test "$ENABLED_STRONGSWAN" = "yes" || \
test "$ENABLED_OPENLDAP" = "yes" || test "x$ENABLED_MOSQUITTO" = "xyes" || test "$ENABLED_HITCH" = "yes"
test "$ENABLED_OPENLDAP" = "yes" || test "x$ENABLED_MOSQUITTO" = "xyes" || \
test "$ENABLED_HITCH" = "yes" || test "$ENABLED_NGINX" = "yes"
then
ENABLED_OPENSSLALL="yes"
fi
+2
View File
@@ -1938,6 +1938,8 @@ int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio)
len = BAD_FUNC_ARG;
if (len == 0) {
len = wolfssl_file_len(file, &memSz);
if (len == WC_NO_ERR_TRACE(WOLFSSL_BAD_FILETYPE))
len = 0;
}
if (len == 0) {
len = (int)memSz;
+22
View File
@@ -1369,6 +1369,28 @@ WOLFSSL_X509_CRL* wolfSSL_X509_CRL_dup(const WOLFSSL_X509_CRL* crl)
return ret;
}
#ifdef OPENSSL_ALL
int wolfSSL_X509_CRL_up_ref(WOLFSSL_X509_CRL* crl)
{
int ret;
if (crl == NULL)
return WOLFSSL_FAILURE;
wolfSSL_RefInc(&crl->ref, &ret);
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
if (ret != 0) {
WOLFSSL_MSG("Failed to lock x509 mutex");
return WOLFSSL_FAILURE;
}
#else
(void)ret;
#endif
return WOLFSSL_SUCCESS;
}
#endif
/* returns WOLFSSL_SUCCESS on success. Does not take ownership of newcrl */
int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *store, WOLFSSL_X509_CRL *newcrl)
{
+3 -2
View File
@@ -403,8 +403,9 @@ static int TlsTicketIsValid(const WOLFSSL* ssl, WolfSSL_ConstVector exts,
if (!IsAtLeastTLSv1_3(it->pv))
*resume = TRUE;
}
if (it != NULL)
ForceZero(it, sizeof(InternalTicket));
/* `it` points into tempTicket on successful decryption so clearing it will
* also satisfy the WOLFSSL_CHECK_MEM_ZERO check. */
ForceZero(tempTicket, SESSION_TICKET_LEN);
return 0;
}
#endif /* HAVE_SESSION_TICKET */
+217 -113
View File
@@ -10756,7 +10756,9 @@ static void AddRecordHeader(byte* output, word32 length, byte type,
#if !defined(WOLFSSL_NO_TLS12) || (defined(HAVE_SESSION_TICKET) && \
!defined(NO_WOLFSSL_SERVER))
!defined(NO_WOLFSSL_SERVER)) || \
defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) || !defined(NO_CERTS)
/* add handshake header for message */
static void AddHandShakeHeader(byte* output, word32 length,
word32 fragOffset, word32 fragLength,
@@ -10791,7 +10793,7 @@ static void AddHandShakeHeader(byte* output, word32 length,
}
/* add both headers for handshake message */
static void AddHeaders(byte* output, word32 length, byte type, WOLFSSL* ssl)
WC_MAYBE_UNUSED static void AddHeaders(byte* output, word32 length, byte type, WOLFSSL* ssl)
{
word32 lengthAdj = HANDSHAKE_HEADER_SZ;
word32 outputAdj = RECORD_HEADER_SZ;
@@ -10806,17 +10808,14 @@ static void AddHeaders(byte* output, word32 length, byte type, WOLFSSL* ssl)
AddRecordHeader(output, length + lengthAdj, handshake, ssl, CUR_ORDER);
AddHandShakeHeader(output + outputAdj, length, 0, length, type, ssl);
}
#endif /* !WOLFSSL_NO_TLS12 || (HAVE_SESSION_TICKET && !NO_WOLFSSL_SERVER) */
#endif /* !WOLFSSL_NO_TLS12 || (HAVE_SESSION_TICKET && !NO_WOLFSSL_SERVER) ||
* HAVE_CERTIFICATE_STATUS_REQUEST ||
* HAVE_CERTIFICATE_STATUS_REQUEST_V2 || !NO_CERTS */
#ifndef WOLFSSL_NO_TLS12
#if (!defined(NO_CERTS) && (!defined(NO_WOLFSSL_SERVER) || \
!defined(WOLFSSL_NO_CLIENT_AUTH))) || \
((!defined(NO_WOLFSSL_SERVER) || \
(!defined(NO_WOLFSSL_CLIENT) && !defined(NO_CERTS) && \
!defined(WOLFSSL_NO_CLIENT_AUTH))) && defined(WOLFSSL_DTLS))
static void AddFragHeaders(byte* output, word32 fragSz, word32 fragOffset,
word32 length, byte type, WOLFSSL* ssl)
#if !defined(WOLFSSL_NO_TLS12) || (defined(WOLFSSL_DTLS) && defined(WOLFSSL_TLS13))
WC_MAYBE_UNUSED static void AddFragHeaders(byte* output, word32 fragSz,
word32 fragOffset, word32 length, byte type, WOLFSSL* ssl)
{
word32 lengthAdj = HANDSHAKE_HEADER_SZ;
word32 outputAdj = RECORD_HEADER_SZ;
@@ -10832,11 +10831,8 @@ static void AddFragHeaders(byte* output, word32 fragSz, word32 fragOffset,
AddRecordHeader(output, fragSz + lengthAdj, handshake, ssl, CUR_ORDER);
AddHandShakeHeader(output + outputAdj, length, fragOffset, fragSz, type, ssl);
}
#endif
#endif /* !WOLFSSL_NO_TLS12 || (WOLFSSL_DTLS && WOLFSSL_TLS13) */
#if !defined(NO_WOLFSSL_SERVER) || \
(!defined(NO_WOLFSSL_CLIENT) && !defined(NO_CERTS) && \
!defined(WOLFSSL_NO_CLIENT_AUTH))
/**
* Send the handshake message. This function handles fragmenting the message
* so that it will fit into the desired MTU or the max fragment size.
@@ -10850,8 +10846,8 @@ static void AddFragHeaders(byte* output, word32 fragSz, word32 fragOffset,
* @param type Type of message being sent
* @return 0 on success and negative otherwise
*/
static int SendHandshakeMsg(WOLFSSL* ssl, byte* input, word32 inputSz,
enum HandShakeType type, const char* packetName)
WC_MAYBE_UNUSED static int SendHandshakeMsg(WOLFSSL* ssl, byte* input,
word32 inputSz, enum HandShakeType type, const char* packetName)
{
int maxFrag;
int ret = 0;
@@ -11012,10 +11008,6 @@ static int SendHandshakeMsg(WOLFSSL* ssl, byte* input, word32 inputSz,
ssl->options.buildingMsg = 0;
return ret;
}
#endif /* !NO_WOLFSSL_SERVER || (!NO_WOLFSSL_CLIENT && !NO_CERTS &&
* !WOLFSSL_NO_CLIENT_AUTH) */
#endif /* !WOLFSSL_NO_TLS12 */
/* return bytes received, WOLFSSL_FATAL_ERROR on error,
@@ -12232,12 +12224,16 @@ static int GetRecordHeader(WOLFSSL* ssl, word32* inOutIdx,
/* record layer length check */
#ifdef HAVE_MAX_FRAGMENT
if (*size > (ssl->max_fragment + MAX_COMP_EXTRA + MAX_MSG_EXTRA)) {
if (*size > (ssl->max_fragment + MAX_MSG_EXTRA +
(ssl->options.usingCompression ? MAX_COMP_EXTRA : 0))) {
WOLFSSL_MSG_EX("Record length %d exceeds max fragment size", *size);
WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
return LENGTH_ERROR;
}
#else
if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA)) {
if (*size > (MAX_RECORD_SIZE + MAX_MSG_EXTRA +
(ssl->options.usingCompression ? MAX_COMP_EXTRA : 0))) {
WOLFSSL_MSG_EX("Record length %d exceeds max record size", *size);
WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
return LENGTH_ERROR;
}
@@ -13393,9 +13389,7 @@ int CheckIPAddr(DecodedCert* dCert, const char* ipasc)
}
#if defined(SESSION_CERTS) && (!defined(NO_WOLFSSL_CLIENT) || \
!defined(WOLFSSL_NO_CLIENT_AUTH))
static void AddSessionCertToChain(WOLFSSL_X509_CHAIN* chain,
WC_MAYBE_UNUSED static void AddSessionCertToChain(WOLFSSL_X509_CHAIN* chain,
byte* certBuf, word32 certSz)
{
if (chain->count < MAX_CHAIN_DEPTH &&
@@ -13408,7 +13402,6 @@ static void AddSessionCertToChain(WOLFSSL_X509_CHAIN* chain,
WOLFSSL_MSG("Couldn't store chain cert for session");
}
}
#endif
#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
@@ -38892,9 +38885,15 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
int error;
word32 itHash = 0;
byte zeros[WOLFSSL_TICKET_MAC_SZ]; /* biggest cmp size */
int internalTicketSz;
byte* mac;
#if defined(OPENSSL_ALL) && defined(KEEP_PEER_CERT) && \
!defined(NO_CERT_IN_TICKET)
word16 peerCertSz = 0;
#endif
WOLFSSL_ASSERT_GE(sizeof(ssl->session->staticTicket), WOLFSSL_TICKET_ENC_SZ);
WOLFSSL_ASSERT_SIZEOF_GE(ssl->session->staticTicket, *et);
WOLFSSL_ASSERT_SIZEOF_GE(et->enc_ticket, *it);
if (ssl->session->ticket != ssl->session->staticTicket) {
/* Always use the static ticket buffer */
@@ -38910,7 +38909,7 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
if (ssl->error != WC_NO_ERR_TRACE(WC_PENDING_E))
#endif
{
XMEMSET(et, 0, sizeof(*et));
XMEMSET(ssl->session->ticket, 0, SESSION_TICKET_LEN);
}
/* build internal */
@@ -38974,6 +38973,55 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
XMEMCPY(it->sessionCtx, ssl->sessionCtx, ID_LEN);
#endif
#if defined(OPENSSL_ALL) && defined(KEEP_PEER_CERT) && \
!defined(NO_CERT_IN_TICKET)
/* Store peer certificate in ticket for session resumption.
* Try ssl->peerCert first, then ssl->session->chain as fallback.
* Skip for DTLS to keep ticket size small for MTU constraints. */
if (ssl->options.dtls) {
c16toa(0, it->peerCertLen);
peerCertSz = 0;
}
else {
const byte* certDer = NULL;
word32 certDerSz = 0;
if (ssl->peerCert.derCert != NULL &&
ssl->peerCert.derCert->length > 0) {
/* Use current peer certificate */
certDer = ssl->peerCert.derCert->buffer;
certDerSz = ssl->peerCert.derCert->length;
}
#ifdef SESSION_CERTS
else if (ssl->session->chain.count > 0) {
/* Use peer certificate from session chain */
certDer = ssl->session->chain.certs[0].buffer;
certDerSz = ssl->session->chain.certs[0].length;
}
#endif
if (certDer != NULL && certDerSz > 0 &&
certDerSz <= MAX_TICKET_PEER_CERT_SZ
#ifdef HAVE_MAX_FRAGMENT
/* We don't support fragmentation in
* SendTls13NewSessionTicket yet. */
&& (!IsAtLeastTLSv1_3(ssl->version) ||
ssl->max_fragment == MAX_RECORD_SIZE)
#endif
) {
c16toa((word16)certDerSz, it->peerCertLen);
XMEMCPY(it->peerCert, certDer, certDerSz);
peerCertSz = (word16)certDerSz;
}
else {
if (certDerSz > MAX_TICKET_PEER_CERT_SZ)
WOLFSSL_MSG("Peer cert too large for ticket, skipping");
c16toa(0, it->peerCertLen);
peerCertSz = 0;
}
}
#endif
#ifdef WOLFSSL_TICKET_HAVE_ID
{
const byte* id = NULL;
@@ -38986,6 +39034,16 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
}
#endif
/* Calculate actual internal ticket size */
#if defined(OPENSSL_ALL) && defined(KEEP_PEER_CERT) && \
!defined(NO_CERT_IN_TICKET)
internalTicketSz = (int)(WOLFSSL_INTERNAL_TICKET_BASE_SZ + peerCertSz);
#else
internalTicketSz = (int)WOLFSSL_INTERNAL_TICKET_BASE_SZ;
#endif
/* MAC is placed after the encrypted data */
mac = et->enc_ticket + WOLFSSL_TICKET_ENC_SZ;
/* encrypt */
encLen = WOLFSSL_TICKET_ENC_SZ; /* max size user can use */
if (ssl->ctx->ticketEncCb == NULL
@@ -39002,10 +39060,10 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
ret = BAD_TICKET_ENCRYPT;
}
else {
itHash = HashObject((byte*)it, sizeof(*it), &error);
itHash = HashObject((byte*)it, (word32)internalTicketSz, &error);
if (error == 0) {
ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv, et->mac,
1, et->enc_ticket, WOLFSSL_INTERNAL_TICKET_LEN, &encLen,
ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv, mac,
1, et->enc_ticket, internalTicketSz, &encLen,
SSL_TICKET_CTX(ssl));
}
else {
@@ -39020,7 +39078,7 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
#endif
goto error;
}
if (encLen < (int)WOLFSSL_INTERNAL_TICKET_LEN ||
if (encLen < internalTicketSz ||
encLen > (int)WOLFSSL_TICKET_ENC_SZ) {
WOLFSSL_MSG("Bad user ticket encrypt size");
ret = BAD_TICKET_KEY_CB_SZ;
@@ -39029,7 +39087,8 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
/* sanity checks on encrypt callback */
/* internal ticket can't be the same if encrypted */
if (itHash == HashObject((byte*)it, sizeof(*it), &error) || error != 0)
if (itHash == HashObject((byte*)it, (word32)internalTicketSz, &error) ||
error != 0)
{
WOLFSSL_MSG("User ticket encrypt didn't encrypt or hash failed");
ret = BAD_TICKET_ENCRYPT;
@@ -39053,7 +39112,7 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
}
/* mac */
if (XMEMCMP(et->mac, zeros, WOLFSSL_TICKET_MAC_SZ) == 0) {
if (XMEMCMP(mac, zeros, WOLFSSL_TICKET_MAC_SZ) == 0) {
WOLFSSL_MSG("User ticket encrypt didn't set mac");
ret = BAD_TICKET_ENCRYPT;
goto error;
@@ -39063,7 +39122,7 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
c16toa((word16)encLen, et->enc_len);
if (encLen < (int)WOLFSSL_TICKET_ENC_SZ) {
/* move mac up since whole enc buffer not used */
XMEMMOVE(et->enc_ticket + encLen, et->mac,
XMEMMOVE(et->enc_ticket + encLen, mac,
WOLFSSL_TICKET_MAC_SZ);
}
ssl->session->ticketLen =
@@ -39073,11 +39132,12 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
error:
#ifdef WOLFSSL_CHECK_MEM_ZERO
/* Ticket has sensitive data in it now. */
wc_MemZero_Add("Create Ticket internal", it, sizeof(InternalTicket));
wc_MemZero_Add("Create Ticket internal", it,
WOLFSSL_INTERNAL_TICKET_MAX_SZ);
#endif
ForceZero(it, sizeof(*it));
ForceZero(it, WOLFSSL_INTERNAL_TICKET_MAX_SZ);
#ifdef WOLFSSL_CHECK_MEM_ZERO
wc_MemZero_Check(it, sizeof(InternalTicket));
wc_MemZero_Check(it, WOLFSSL_INTERNAL_TICKET_MAX_SZ);
#endif
WOLFSSL_ERROR_VERBOSE(ret);
return ret;
@@ -39128,7 +39188,7 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
}
else {
/* Callback uses ssl without const but for DTLS, it really shouldn't
* modify its state. */
* modify its state. MAC is located after encrypted data. */
ret = ssl->ctx->ticketEncCb((WOLFSSL*)ssl, et->key_name, et->iv,
et->enc_ticket + inLen, 0,
et->enc_ticket, inLen, &outLen,
@@ -39353,6 +39413,49 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
ato16(it->namedGroup, &ssl->session->namedGroup);
#endif
}
#if defined(OPENSSL_ALL) && defined(KEEP_PEER_CERT) && \
!defined(NO_CERT_IN_TICKET)
/* Restore peer certificate from ticket to session chain and peerCert */
{
word16 peerCertLen = 0;
ato16(it->peerCertLen, &peerCertLen);
if (peerCertLen > 0 && peerCertLen <= MAX_TICKET_PEER_CERT_SZ) {
#ifdef SESSION_CERTS
/* Clear existing chain and add the peer certificate */
ssl->session->chain.count = 0;
AddSessionCertToChain(&ssl->session->chain,
it->peerCert, peerCertLen);
#endif
/* Also decode into ssl->peerCert for direct access */
{
int ret;
DecodedCert* dCert;
dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
DYNAMIC_TYPE_DCERT);
if (dCert != NULL) {
InitDecodedCert(dCert, it->peerCert, peerCertLen, ssl->heap);
ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL, NULL);
if (ret == 0) {
FreeX509(&ssl->peerCert);
InitX509(&ssl->peerCert, 0, ssl->heap);
ret = CopyDecodedToX509(&ssl->peerCert, dCert);
if (ret != 0) {
/* Failed to copy - clear peerCert */
FreeX509(&ssl->peerCert);
InitX509(&ssl->peerCert, 0, ssl->heap);
}
}
FreeDecodedCert(dCert);
XFREE(dCert, ssl->heap, DYNAMIC_TYPE_DCERT);
}
}
}
}
#endif
ssl->version.minor = it->pv.minor;
}
@@ -39397,6 +39500,23 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
#ifdef OPENSSL_EXTRA
it->sessionCtxSz = sess->sessionCtxSz;
XMEMCPY(it->sessionCtx, sess->sessionCtx, sess->sessionCtxSz);
#endif
#if defined(OPENSSL_ALL) && defined(KEEP_PEER_CERT) && \
defined(SESSION_CERTS) && !defined(NO_CERT_IN_TICKET)
/* Store peer certificate from session chain */
if (sess->chain.count > 0) {
word32 certLen = sess->chain.certs[0].length;
if (certLen <= MAX_TICKET_PEER_CERT_SZ) {
c16toa((word16)certLen, it->peerCertLen);
XMEMCPY(it->peerCert, sess->chain.certs[0].buffer, certLen);
}
else {
c16toa(0, it->peerCertLen);
}
}
else {
c16toa(0, it->peerCertLen);
}
#endif
}
@@ -39467,9 +39587,10 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
byte* tmp;
WOLFSSL_MSG("Found session matching the session id"
" found in the ticket");
/* Allocate and populate an InternalTicket */
/* Allocate and populate an InternalTicket. Need max size
* because PopulateInternalTicketFromSession may write peer cert */
#ifdef WOLFSSL_NO_REALLOC
tmp = (byte*)XMALLOC(sizeof(InternalTicket), ssl->heap,
tmp = (byte*)XMALLOC(WOLFSSL_INTERNAL_TICKET_MAX_SZ, ssl->heap,
DYNAMIC_TYPE_TLSX);
if (tmp != NULL && psk->identity != NULL)
{
@@ -39478,13 +39599,13 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
psk->identity = NULL;
}
#else
tmp = (byte*)XREALLOC(psk->identity, sizeof(InternalTicket),
tmp = (byte*)XREALLOC(psk->identity, WOLFSSL_INTERNAL_TICKET_MAX_SZ,
ssl->heap, DYNAMIC_TYPE_TLSX);
#endif
if (tmp != NULL) {
XMEMSET(tmp, 0, sizeof(InternalTicket));
XMEMSET(tmp, 0, WOLFSSL_INTERNAL_TICKET_MAX_SZ);
psk->identity = tmp;
psk->identityLen = sizeof(InternalTicket);
psk->identityLen = WOLFSSL_INTERNAL_TICKET_MAX_SZ;
psk->it = (InternalTicket*)tmp;
PopulateInternalTicketFromSession(sess, psk->it);
decryptRet = WOLFSSL_TICKET_RET_OK;
@@ -39519,8 +39640,8 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
}
#ifdef WOLFSSL_CHECK_MEM_ZERO
/* Internal ticket successfully decrypted. */
wc_MemZero_Add("Do Client Ticket internal", psk->it,
sizeof(InternalTicket));
wc_MemZero_Add("Do Client Ticket internal", psk->identity,
psk->identityLen);
#endif
ret = DoClientTicketCheckVersion(ssl, psk->it);
@@ -39528,7 +39649,7 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
psk->decryptRet = PSK_DECRYPT_FAIL;
ForceZero(psk->identity, psk->identityLen);
#ifdef WOLFSSL_CHECK_MEM_ZERO
wc_MemZero_Check(psk->it, sizeof(InternalTicket));
wc_MemZero_Check(psk->it, psk->identityLen);
#endif
WOLFSSL_LEAVE("DoClientTicket_ex", ret);
return ret;
@@ -39545,7 +39666,13 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
int ret;
InternalTicket* it = NULL;
#ifdef WOLFSSL_TLS13
InternalTicket staticIt;
/* Static buffer for stateful tickets - need max size for peer cert */
#ifdef WOLFSSL_SMALL_STACK
byte* staticItBuf = NULL;
#else
byte staticItBuf[WOLFSSL_INTERNAL_TICKET_MAX_SZ];
#endif
InternalTicket* staticIt = NULL;
const WOLFSSL_SESSION* sess = NULL;
psk_sess_free_cb_ctx freeCtx;
@@ -39577,18 +39704,27 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
* stateless tickets are much longer. */
sess = GetSesionFromCacheOrExt(ssl, input, &freeCtx);
if (sess != NULL) {
it = &staticIt;
XMEMSET(it, 0, sizeof(InternalTicket));
#ifdef WOLFSSL_SMALL_STACK
staticItBuf = (byte*)XMALLOC(WOLFSSL_INTERNAL_TICKET_MAX_SZ,
ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (staticItBuf == NULL) {
decryptRet = WOLFSSL_TICKET_RET_FATAL;
goto cleanup;
}
#endif
staticIt = (InternalTicket*)staticItBuf;
it = staticIt;
XMEMSET(it, 0, WOLFSSL_INTERNAL_TICKET_MAX_SZ);
PopulateInternalTicketFromSession(sess, it);
decryptRet = WOLFSSL_TICKET_RET_OK;
}
}
else
#endif
if (len >= sizeof(*it))
if (len >= WOLFSSL_INTERNAL_TICKET_LEN + WOLFSSL_TICKET_FIXED_SZ)
decryptRet = DoDecryptTicket(ssl, input, len, &it);
else
WOLFSSL_MSG("Ticket is smaller than InternalTicket. Rejecting.");
WOLFSSL_MSG("Ticket is smaller than minimum size. Rejecting.");
if (decryptRet != WOLFSSL_TICKET_RET_OK &&
@@ -39597,8 +39733,10 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
goto cleanup;
}
#ifdef WOLFSSL_CHECK_MEM_ZERO
/* Internal ticket successfully decrypted. */
wc_MemZero_Add("Do Client Ticket internal", it, sizeof(InternalTicket));
/* Internal ticket successfully decrypted. Zero at least the minimum
* internal ticket size (contains master secret). */
wc_MemZero_Add("Do Client Ticket internal", it,
WOLFSSL_INTERNAL_TICKET_LEN);
#endif
ret = DoClientTicketCheckVersion(ssl, it);
@@ -39611,12 +39749,19 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
cleanup:
if (it != NULL) {
ForceZero(it, sizeof(*it));
/* Zero the minimum internal ticket size. The it pointer points into
* the input buffer which may be smaller than MAX_SZ. We use the
* minimum length (WOLFSSL_INTERNAL_TICKET_LEN) which is guaranteed
* to fit and contains the sensitive master secret. */
ForceZero(it, WOLFSSL_INTERNAL_TICKET_LEN);
#ifdef WOLFSSL_CHECK_MEM_ZERO
wc_MemZero_Check(it, sizeof(InternalTicket));
wc_MemZero_Check(it, WOLFSSL_INTERNAL_TICKET_LEN);
#endif
}
#ifdef WOLFSSL_TLS13
#ifdef WOLFSSL_SMALL_STACK
XFREE(staticItBuf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
if (sess != NULL)
FreeSessionFromCacheOrExt(ssl, sess, &freeCtx);
#endif
@@ -39632,10 +39777,7 @@ cleanup:
psk->decryptRet = PSK_DECRYPT_NONE;
ForceZero(psk->identity, psk->identityLen);
#ifdef WOLFSSL_CHECK_MEM_ZERO
/* We want to check the InternalTicket area since that is what
* we registered in DoClientTicket_ex */
wc_MemZero_Check((((ExternalTicket*)psk->identity)->enc_ticket),
sizeof(InternalTicket));
wc_MemZero_Check(psk->identity, psk->identityLen);
#endif
}
}
@@ -39651,11 +39793,15 @@ cleanup:
int sendSz;
word32 length = SESSION_HINT_SZ + LENGTH_SZ;
word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
word32 headerSz = 0;
WOLFSSL_START(WC_FUNC_TICKET_SEND);
WOLFSSL_ENTER("SendTicket");
if (ssl->options.createTicket) {
if (ssl->options.createTicket &&
/* This will be set when SendHandshakeMsg returns WANT_WRITE. Create
* a new ticket only once. */
!ssl->options.buildingMsg) {
ret = SetupTicket(ssl);
if (ret != 0)
return ret;
@@ -39677,20 +39823,13 @@ cleanup:
idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
#endif
}
headerSz = idx;
if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone)
sendSz += cipherExtraData(ssl);
/* Set this in case CheckAvailableSize returns a WANT_WRITE so that state
* is not advanced yet */
ssl->options.buildingMsg = 1;
/* check for available size */
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
return ret;
output = (byte*)XMALLOC(sendSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (output == NULL)
return MEMORY_E;
/* get output buffer */
output = GetOutputBuffer(ssl);
AddHeaders(output, length, session_ticket, ssl);
/* hint */
@@ -39705,45 +39844,9 @@ cleanup:
XMEMCPY(output + idx, ssl->session->ticket, ssl->session->ticketLen);
idx += ssl->session->ticketLen;
if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone) {
byte* input;
int inputSz = (int)idx; /* build msg adds rec hdr */
int recordHeaderSz = RECORD_HEADER_SZ;
if (ssl->options.dtls)
recordHeaderSz += DTLS_RECORD_EXTRA;
inputSz -= recordHeaderSz;
input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (input == NULL)
return MEMORY_E;
XMEMCPY(input, output + recordHeaderSz, inputSz);
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
handshake, 1, 0, 0, CUR_ORDER);
XFREE(input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (sendSz < 0)
return sendSz;
}
else {
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
if ((ret = DtlsMsgPoolSave(ssl, output, (word32)sendSz, session_ticket)) != 0)
return ret;
DtlsSEQIncrement(ssl, CUR_ORDER);
}
#endif
ret = HashOutput(ssl, output, sendSz, 0);
if (ret != 0)
return ret;
}
ssl->buffers.outputBuffer.length += sendSz;
ssl->options.buildingMsg = 0;
if (!ssl->options.groupMessages)
ret = SendBuffered(ssl);
ret = SendHandshakeMsg(ssl, output, idx - headerSz, session_ticket,
"Session Ticket");
XFREE(output, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
WOLFSSL_LEAVE("SendTicket", ret);
WOLFSSL_END(WC_FUNC_TICKET_SEND);
@@ -40241,7 +40344,8 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ],
WOLFSSL_ENTER("DefTicketEncCb");
if ((!enc) && (inLen != WOLFSSL_INTERNAL_TICKET_LEN)) {
/* For decryption, check minimum internal ticket size */
if ((!enc) && (inLen < (int)WOLFSSL_INTERNAL_TICKET_LEN)) {
return BUFFER_E;
}
+2
View File
@@ -15523,6 +15523,8 @@ WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
ssl->buffers.weOwnKey = 1;
}
else {
if (ssl->buffers.key != NULL && ssl->buffers.weOwnKey)
FreeDer(&ssl->buffers.key);
ssl->buffers.key = ctx->privateKey;
}
#else
+20 -2
View File
@@ -869,7 +869,8 @@ int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl)
if (ssl->buffers.weOwnKey) {
WOLFSSL_MSG("Unloading key");
ForceZero(ssl->buffers.key->buffer, ssl->buffers.key->length);
if (ssl->buffers.key != NULL && ssl->buffers.key->buffer != NULL)
ForceZero(ssl->buffers.key->buffer, ssl->buffers.key->length);
FreeDer(&ssl->buffers.key);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ssl->buffers.keyMask);
@@ -880,7 +881,8 @@ int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl)
#ifdef WOLFSSL_DUAL_ALG_CERTS
if (ssl->buffers.weOwnAltKey) {
WOLFSSL_MSG("Unloading alt key");
ForceZero(ssl->buffers.altKey->buffer, ssl->buffers.altKey->length);
if (ssl->buffers.altKey != NULL && ssl->buffers.altKey->buffer != NULL)
ForceZero(ssl->buffers.altKey->buffer, ssl->buffers.altKey->length);
FreeDer(&ssl->buffers.altKey);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ssl->buffers.altKeyMask);
@@ -1710,6 +1712,22 @@ WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl)
else if (ssl->buffers.weOwnCert) {
/* Check if we already have a certificate allocated. */
if (ssl->ourCert == NULL) {
/* Check if ctx has ourCert set - if so, use it instead of creating
* a new X509. This maintains pointer compatibility with
* applications (like nginx OCSP stapling) that use the X509 pointer
* from SSL_CTX_use_certificate as a lookup key. */
if (ssl->ctx != NULL && ssl->ctx->ourCert != NULL) {
/* Compare cert buffers to make sure they are the same */
if (ssl->buffers.certificate == NULL ||
ssl->buffers.certificate->buffer == NULL ||
(ssl->buffers.certificate->length ==
ssl->ctx->certificate->length &&
XMEMCMP(ssl->buffers.certificate->buffer,
ssl->ctx->certificate->buffer,
ssl->buffers.certificate->length) == 0)) {
return ssl->ctx->ourCert;
}
}
/* We own certificate so this should never happen. */
if (ssl->buffers.certificate == NULL) {
WOLFSSL_MSG("Certificate buffer not set!");
+9 -1
View File
@@ -230,7 +230,15 @@ static int wolfssl_file_len(XFILE fp, long* fileSz)
/* Get file offset at end of file. */
curr = (long)XFTELL(fp);
if (curr < 0) {
ret = WOLFSSL_BAD_FILE;
#ifdef ESPIPE
if (errno == ESPIPE) {
WOLFSSL_ERROR_MSG("wolfssl_file_len: file is a pipe");
*fileSz = 0;
ret = WOLFSSL_BAD_FILETYPE;
}
else
#endif
ret = WOLFSSL_BAD_FILE;
}
}
/* Move to end of file. */
+25 -6
View File
@@ -448,8 +448,24 @@ static int wolfssl_sk_dup_data(WOLFSSL_STACK* dst, WOLFSSL_STACK* src)
break;
}
break;
case STACK_TYPE_X509_CRL:
#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL)
if (src->data.crl == NULL) {
break;
}
dst->data.crl = wolfSSL_X509_CRL_dup(src->data.crl);
if (dst->data.crl == NULL) {
WOLFSSL_MSG("wolfSSL_X509_CRL_dup error");
err = 1;
break;
}
#else
WOLFSSL_MSG("CRL support not enabled");
err = 1;
#endif
break;
case STACK_TYPE_X509_OBJ:
#if defined(OPENSSL_ALL)
#if defined(OPENSSL_ALL)
if (src->data.x509_obj == NULL) {
break;
}
@@ -460,8 +476,11 @@ static int wolfssl_sk_dup_data(WOLFSSL_STACK* dst, WOLFSSL_STACK* src)
err = 1;
break;
}
#else
WOLFSSL_MSG("OPENSSL_ALL support not enabled");
err = 1;
#endif
break;
#endif
case STACK_TYPE_BIO:
case STACK_TYPE_STRING:
case STACK_TYPE_ACCESS_DESCRIPTION:
@@ -475,7 +494,6 @@ static int wolfssl_sk_dup_data(WOLFSSL_STACK* dst, WOLFSSL_STACK* src)
case STACK_TYPE_BY_DIR_entry:
case STACK_TYPE_BY_DIR_hash:
case STACK_TYPE_DIST_POINT:
case STACK_TYPE_X509_CRL:
case STACK_TYPE_GENERAL_SUBTREE:
default:
WOLFSSL_MSG("Unsupported stack type");
@@ -488,7 +506,8 @@ static int wolfssl_sk_dup_data(WOLFSSL_STACK* dst, WOLFSSL_STACK* src)
/* Duplicate the stack of nodes.
*
* TODO: OpenSSL does a shallow copy but we have wolfSSL_shallow_sk_dup().
* OpenSSL does a shallow copy but we map to wolfSSL_shallow_sk_dup()
* when we want a shallow copy.
*
* Data is copied/duplicated - deep copy.
*
@@ -683,7 +702,7 @@ void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i)
#if (!defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || \
defined(WOLFSSL_WPAS_SMALL))) || defined(WOLFSSL_QT) || \
defined(OPENSSL_ALL)
/* Put the data into a node at the top of the stack.
/* Put the data into a node at the end of the list.
*
* @param [in, out] stack Stack of objects.
* @param [in] data Data to store in stack.
@@ -698,7 +717,7 @@ int wolfSSL_sk_push(WOLFSSL_STACK* stack, const void *data)
return wolfSSL_sk_insert(stack, data, -1);
}
/* Put the data into a node at an index in the stack.
/* Put the data into a node at an index in the list.
*
* @param [in, out] stack Stack of objects.
* @param [in] data Data to store in stack.
+216 -77
View File
@@ -38,6 +38,8 @@
#include <wolfssl/wolfio.h>
#endif
#define MAX_BIO_READ_BUFFER (MAX_X509_SIZE * 16)
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
unsigned int wolfSSL_X509_get_extension_flags(WOLFSSL_X509* x509)
{
@@ -4672,6 +4674,14 @@ WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new(void)
return s;
}
WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new_null(void)
{
WOLFSSL_STACK* s = wolfSSL_sk_new_null();
if (s != NULL)
s->type = STACK_TYPE_X509_CRL;
return s;
}
void wolfSSL_sk_X509_CRL_pop_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk,
void (*f) (WOLFSSL_X509_CRL*))
{
@@ -6056,14 +6066,25 @@ static WOLFSSL_X509* loadX509orX509REQFromBuffer(
/* ready to be decoded. */
if (der != NULL && der->buffer != NULL) {
WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
/* For TRUSTED_CERT_TYPE, the DER buffer contains the certificate
* followed by auxiliary trust info. ParseCertRelative expects CERT_TYPE
* and will parse only the certificate portion, ignoring the rest. */
int parseType = (type == TRUSTED_CERT_TYPE) ? CERT_TYPE : type;
WC_ALLOC_VAR_EX(cert, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
ret=MEMORY_ERROR);
if (WC_VAR_OK(cert))
{
InitDecodedCert(cert, der->buffer, der->length, NULL);
ret = ParseCertRelative(cert, type, 0, NULL, NULL);
ret = ParseCertRelative(cert, parseType, 0, NULL, NULL);
if (ret == 0) {
/* For TRUSTED_CERT_TYPE, truncate the DER buffer to exclude
* auxiliary trust data. ParseCertRelative sets srcIdx to the
* end of the certificate, so we adjust cert->maxIdx accordingly. */
if (type == TRUSTED_CERT_TYPE && cert->srcIdx < cert->maxIdx) {
cert->maxIdx = cert->srcIdx;
}
x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
DYNAMIC_TYPE_X509);
if (x509 != NULL) {
@@ -12922,22 +12943,23 @@ static WOLFSSL_X509 *loadX509orX509REQFromPemBio(WOLFSSL_BIO *bp,
int pemSz;
long i = 0, l, footerSz;
const char* footer = NULL;
int streaming = 0; /* Flag to indicate if source is streaming (FIFO) */
const char* altFooter = NULL;
long altFooterSz = 0;
WOLFSSL_ENTER("loadX509orX509REQFromPemBio");
if (bp == NULL || (type != CERT_TYPE && type != CERTREQ_TYPE)) {
if (bp == NULL || (type != CERT_TYPE && type != CERTREQ_TYPE &&
type != TRUSTED_CERT_TYPE)) {
WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG);
return NULL;
}
if ((l = wolfSSL_BIO_get_len(bp)) <= 0) {
/* No certificate in buffer */
#if defined (WOLFSSL_HAPROXY)
WOLFSSL_ERROR(PEM_R_NO_START_LINE);
#else
WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
#endif
return NULL;
/* No certificate size available - could be FIFO or other streaming
* source. Use MAX_X509_SIZE as initial buffer, will resize if needed. */
l = MAX_X509_SIZE;
streaming = 1;
}
pemSz = (int)l;
@@ -12953,27 +12975,79 @@ static WOLFSSL_X509 *loadX509orX509REQFromPemBio(WOLFSSL_BIO *bp,
}
footerSz = (long)XSTRLEN(footer);
/* For TRUSTED_CERT_TYPE, also prepare to check for regular CERT footer
* as the file might contain regular certificates instead of TRUSTED
* format */
if (type == TRUSTED_CERT_TYPE) {
wc_PemGetHeaderFooter(CERT_TYPE, NULL, &altFooter);
if (altFooter != NULL) {
altFooterSz = (long)XSTRLEN(altFooter);
}
}
/* TODO: Inefficient
* reading in one byte at a time until see the footer
*/
while ((l = wolfSSL_BIO_read(bp, (char *)&pem[i], 1)) == 1) {
int foundFooter = 0;
i++;
if (i > footerSz && XMEMCMP((char *)&pem[i-footerSz], footer,
footerSz) == 0) {
if (wolfSSL_BIO_read(bp, (char *)&pem[i], 1) == 1) {
/* Check if buffer is full and we're reading from streaming source */
if (i >= pemSz && streaming) {
/* Double the buffer size for streaming sources */
int newSz = pemSz * 2;
unsigned char* newPem;
/* Sanity check: don't grow beyond reasonable limit */
if (newSz > MAX_BIO_READ_BUFFER) {
WOLFSSL_MSG("PEM data too large for streaming source");
XFREE(pem, 0, DYNAMIC_TYPE_PEM);
return NULL;
}
newPem = (unsigned char*)XREALLOC(pem, newSz, 0, DYNAMIC_TYPE_PEM);
if (newPem == NULL) {
WOLFSSL_MSG("Failed to resize PEM buffer");
XFREE(pem, 0, DYNAMIC_TYPE_PEM);
return NULL;
}
pem = newPem;
pemSz = newSz;
}
else if (i > pemSz) {
/* Buffer full for non-streaming source - this shouldn't happen */
break;
}
/* Check for the expected footer OR alternate footer (for
* TRUSTED_CERT_TYPE) */
if (i > footerSz &&
XMEMCMP((char *)&pem[i-footerSz], footer, footerSz) == 0) {
foundFooter = 1;
}
else if (i > altFooterSz && altFooter != NULL &&
XMEMCMP((char *)&pem[i-altFooterSz], altFooter, altFooterSz) == 0) {
foundFooter = 1;
}
if (foundFooter) {
if (i < pemSz && wolfSSL_BIO_read(bp, (char *)&pem[i], 1) == 1) {
/* attempt to read newline following footer */
i++;
if (pem[i-1] == '\r') {
if (i < pemSz && pem[i-1] == '\r') {
/* found \r , Windows line ending is \r\n so try to read one
* more byte for \n, ignoring return value */
(void)wolfSSL_BIO_read(bp, (char *)&pem[i++], 1);
if (i < pemSz) {
(void)wolfSSL_BIO_read(bp, (char *)&pem[i++], 1);
}
}
}
break;
}
}
if (l == 0)
if (l == 0 && i == 0) {
WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
}
if (i > pemSz) {
WOLFSSL_MSG("Error parsing PEM");
}
@@ -12985,6 +13059,12 @@ static WOLFSSL_X509 *loadX509orX509REQFromPemBio(WOLFSSL_BIO *bp,
CERTREQ_TYPE, cb, u);
else
#endif
/* Use TRUSTED_CERT_TYPE if input was TRUSTED CERTIFICATE format,
* otherwise use CERT_TYPE for regular certificates */
if (type == TRUSTED_CERT_TYPE)
x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM,
TRUSTED_CERT_TYPE, cb, u);
else
x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM,
CERT_TYPE, cb, u);
}
@@ -13005,6 +13085,86 @@ static WOLFSSL_X509 *loadX509orX509REQFromPemBio(WOLFSSL_BIO *bp,
}
WC_MAYBE_UNUSED
static unsigned char* ReadPemFromBioToBuffer(WOLFSSL_BIO *bp, int *pemSz)
{
unsigned char* pem = NULL;
WOLFSSL_ENTER("ReadPemFromBioToBuffer");
if (bp == NULL || pemSz == NULL) {
WOLFSSL_LEAVE("ReadPemFromBioToBuffer", BAD_FUNC_ARG);
return NULL;
}
if ((*pemSz = wolfSSL_BIO_get_len(bp)) <= 0) {
/* No certificate size available - could be FIFO or other streaming
* source. Use MAX_X509_SIZE as initial buffer, read in loop. */
int totalRead = 0;
int readSz;
*pemSz = MAX_X509_SIZE;
pem = (unsigned char*)XMALLOC(*pemSz, 0, DYNAMIC_TYPE_PEM);
if (pem == NULL) {
return NULL;
}
/* Read from streaming source until EOF or buffer full */
while ((readSz = wolfSSL_BIO_read(bp, pem + totalRead,
*pemSz - totalRead)) > 0) {
totalRead += readSz;
/* If buffer is full, try to grow it */
if (totalRead >= *pemSz) {
int newSz = *pemSz * 2;
unsigned char* newPem;
/* Sanity check */
if (newSz > MAX_BIO_READ_BUFFER) {
WOLFSSL_MSG("PEM data too large for streaming source");
XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
return NULL;
}
newPem = (unsigned char*)XREALLOC(pem, newSz, 0,
DYNAMIC_TYPE_PEM);
if (newPem == NULL) {
XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
return NULL;
}
pem = newPem;
*pemSz = newSz;
}
}
*pemSz = totalRead;
if (*pemSz <= 0) {
XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
return NULL;
}
}
else {
/* Known size - allocate and read */
pem = (unsigned char*)XMALLOC(*pemSz, 0, DYNAMIC_TYPE_PEM);
if (pem == NULL) {
return NULL;
}
XMEMSET(pem, 0, *pemSz);
*pemSz = wolfSSL_BIO_read(bp, pem, *pemSz);
if (*pemSz <= 0) {
XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
return NULL;
}
}
WOLFSSL_LEAVE("ReadPemFromBioToBuffer", 0);
return pem;
}
#if defined(WOLFSSL_ACERT)
WOLFSSL_X509_ACERT *wolfSSL_PEM_read_bio_X509_ACERT(WOLFSSL_BIO *bp,
WOLFSSL_X509_ACERT **x,
@@ -13019,29 +13179,14 @@ static WOLFSSL_X509 *loadX509orX509REQFromPemBio(WOLFSSL_BIO *bp,
WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_ACERT");
if (bp == NULL) {
WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509_ACERT", BAD_FUNC_ARG);
return NULL;
}
if ((pemSz = wolfSSL_BIO_get_len(bp)) <= 0) {
/* No certificate in buffer */
WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
return NULL;
}
pem = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM);
pem = ReadPemFromBioToBuffer(bp, &pemSz);
if (pem == NULL) {
return NULL;
}
XMEMSET(pem, 0, pemSz);
if (wolfSSL_BIO_read(bp, pem, pemSz) != pemSz) {
XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
return NULL;
}
x509 = wolfSSL_X509_ACERT_load_certificate_buffer(pem, pemSz,
WOLFSSL_FILETYPE_PEM);
@@ -13079,14 +13224,15 @@ static WOLFSSL_X509 *loadX509orX509REQFromPemBio(WOLFSSL_BIO *bp,
WOLFSSL_X509 **x, wc_pem_password_cb *cb,
void *u)
{
WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509");
WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_AUX");
/* AUX info is; trusted/rejected uses, friendly name, private key id,
* and potentially a stack of "other" info. wolfSSL does not store
* friendly name or private key id yet in WOLFSSL_X509 for human
* readability and does not support extra trusted/rejected uses for
* root CA. */
return wolfSSL_PEM_read_bio_X509(bp, x, cb, u);
* root CA. Use TRUSTED_CERT_TYPE to properly parse TRUSTED CERTIFICATE
* format and strip auxiliary data. */
return loadX509orX509REQFromPemBio(bp, x, cb, u, TRUSTED_CERT_TYPE);
}
#ifdef WOLFSSL_CERT_REQ
@@ -13139,21 +13285,14 @@ WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
{
#if defined(WOLFSSL_PEM_TO_DER) && defined(HAVE_CRL)
unsigned char* pem = NULL;
int pemSz;
int derSz;
int pemSz = 0;
int derSz = 0;
DerBuffer* der = NULL;
WOLFSSL_X509_CRL* crl = NULL;
if ((pemSz = wolfSSL_BIO_get_len(bp)) <= 0) {
goto err;
}
WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_CRL");
pem = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM);
if (pem == NULL) {
goto err;
}
if (wolfSSL_BIO_read(bp, pem, pemSz) != pemSz) {
if ((pem = ReadPemFromBioToBuffer(bp, &pemSz)) == NULL) {
goto err;
}
@@ -13166,6 +13305,9 @@ WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
}
err:
if (pemSz == 0) {
WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
}
XFREE(pem, 0, DYNAMIC_TYPE_PEM);
if (der != NULL) {
FreeDer(&der);
@@ -15393,48 +15535,39 @@ void wolfSSL_X509_email_free(WOLF_STACK_OF(WOLFSSL_STRING) *sk)
wolfSSL_sk_pop_free(sk, NULL);
}
static int x509_aia_append_string(WOLFSSL_STACK** head,
const byte* uri, word32 uriSz)
static int x509_aia_append_string(WOLFSSL_STACK* list, const byte* uri,
word32 uriSz)
{
WOLFSSL_STACK* node;
char* url;
url = (char*)XMALLOC(uriSz + 1, NULL, DYNAMIC_TYPE_OPENSSL);
WOLFSSL_STRING url = (WOLFSSL_STRING)XMALLOC(uriSz + 1, NULL,
DYNAMIC_TYPE_OPENSSL);
if (url == NULL)
return WOLFSSL_FAILURE;
return -1;
XMEMCPY(url, uri, uriSz);
url[uriSz] = '\0';
node = wolfSSL_sk_new_node(*head != NULL ? (*head)->heap : NULL);
if (node == NULL) {
if (wolfSSL_sk_push(list, url) <= 0) {
XFREE(url, NULL, DYNAMIC_TYPE_OPENSSL);
return WOLFSSL_FAILURE;
return -1;
}
node->type = STACK_TYPE_STRING;
node->data.string = url;
if (wolfSSL_sk_push_back_node(head, node) != WOLFSSL_SUCCESS) {
XFREE(url, NULL, DYNAMIC_TYPE_OPENSSL);
wolfSSL_sk_free_node(node);
return WOLFSSL_FAILURE;
}
return WOLFSSL_SUCCESS;
return 0;
}
static WOLFSSL_STACK* x509_get1_aia_by_method(WOLFSSL_X509* x, word32 method,
const byte* fallback, int fallbackSz)
{
WOLFSSL_STACK* head = NULL;
WOLFSSL_STACK* ret = NULL;
int i;
if (x == NULL)
return NULL;
/* Collect matching URIs from the multi-entry list into a new stack;
* fall back to the legacy single-entry field for compatibility. */
ret = wolfSSL_sk_WOLFSSL_STRING_new();
if (ret == NULL)
return NULL;
/* Build from multi-entry list when available; otherwise fall back to the
* legacy single-entry fields to preserve previous behavior. */
if (x->authInfoListSz > 0) {
for (i = 0; i < x->authInfoListSz; i++) {
if (x->authInfoList[i].method != method ||
@@ -15443,22 +15576,28 @@ static WOLFSSL_STACK* x509_get1_aia_by_method(WOLFSSL_X509* x, word32 method,
continue;
}
if (x509_aia_append_string(&head, x->authInfoList[i].uri,
x->authInfoList[i].uriSz) != WOLFSSL_SUCCESS) {
wolfSSL_sk_pop_free(head, NULL);
if (x509_aia_append_string(ret, x->authInfoList[i].uri,
x->authInfoList[i].uriSz) != 0) {
wolfSSL_X509_email_free(ret);
return NULL;
}
}
}
if (head == NULL && fallback != NULL && fallbackSz > 0) {
if (x509_aia_append_string(&head, fallback, (word32)fallbackSz)
!= WOLFSSL_SUCCESS) {
wolfSSL_sk_pop_free(head, NULL);
/* Only use fallback when nothing was found in the list */
if (wolfSSL_sk_num(ret) == 0 && fallback != NULL && fallbackSz > 0) {
if (x509_aia_append_string(ret, fallback, (word32)fallbackSz) != 0) {
wolfSSL_X509_email_free(ret);
return NULL;
}
}
return head;
/* Return NULL when empty */
if (wolfSSL_sk_num(ret) == 0) {
wolfSSL_X509_email_free(ret);
ret = NULL;
}
return ret;
}
WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 *x)
-11
View File
@@ -202,14 +202,3 @@
-v 3
-l ECDHE-RSA-AES256-GCM-SHA384
-F 6
# server DTLSv1.2 DHE-RSA-AES256-GCM-SHA384
-u
-v 3
-l DHE-RSA-AES256-GCM-SHA384
# client DTLSv1.2 DHE-RSA-AES256-GCM-SHA384
-u
-v 3
-l DHE-RSA-AES256-GCM-SHA384
-F 6
-9
View File
@@ -169,15 +169,6 @@
-l ECDHE-RSA-AES256-GCM-SHA384
-F 6
# server TLSv1.2 DHE-RSA-AES256-GCM-SHA384
-v 3
-l DHE-RSA-AES256-GCM-SHA384
# client TLSv1.2 DHE-RSA-AES256-GCM-SHA384
-v 3
-l DHE-RSA-AES256-GCM-SHA384
-F 6
# server TLSv1.2 DHE-RSA-AES256-GCM-SHA384
-v 3
-l DHE-RSA-AES256-GCM-SHA384
+21 -2
View File
@@ -24119,8 +24119,6 @@ static int DecodeCertInternal(DecodedCert* cert, int verify, int* criticalExt,
cert->extensionsSz = (int)GetASNItem_Length(
dataASN[X509CERTASN_IDX_TBS_EXT], cert->source);
cert->extensionsIdx = dataASN[X509CERTASN_IDX_TBS_EXT].offset;
/* Advance past extensions. */
cert->srcIdx = dataASN[X509CERTASN_IDX_SIGALGO_SEQ].offset;
}
}
@@ -27452,6 +27450,27 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
footer = END_X509_CRL;
}
#endif
else if (type == CERT_TYPE
|| type == CA_TYPE
|| type == CHAIN_CERT_TYPE
|| type == TRUSTED_PEER_TYPE) {
if (header == BEGIN_CERT) {
header = BEGIN_TRUSTED_CERT;
footer = END_TRUSTED_CERT;
}
else {
break;
}
}
else if (type == TRUSTED_CERT_TYPE) {
if (header == BEGIN_TRUSTED_CERT) {
header = BEGIN_CERT;
footer = END_CERT;
}
else {
break;
}
}
else {
break;
}
+1 -1
View File
@@ -20574,7 +20574,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void)
#ifdef WC_DRBG_BANKREF
WC_ALLOC_VAR_EX(rng, WC_RNG, 1, HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER,
return WC_TEST_RET_ENC_EC(MEMORY_E));
ERROR_OUT(WC_TEST_RET_ENC_EC(MEMORY_E), out));
XMEMSET(rng, 0, sizeof(*rng));
#endif
+66 -25
View File
@@ -1279,16 +1279,6 @@ enum {
#endif
#endif /* NO_DH */
#ifndef MAX_PSK_ID_LEN
/* max psk identity/hint supported */
#if defined(WOLFSSL_TLS13)
/* OpenSSL has a 1472 byte session ticket */
#define MAX_PSK_ID_LEN 1536
#else
#define MAX_PSK_ID_LEN 128
#endif
#endif
#ifndef MAX_PSK_KEY_LEN
#define MAX_PSK_KEY_LEN 64
#endif
@@ -2046,6 +2036,7 @@ WOLFSSL_LOCAL int NamedGroupIsPqcHybrid(int group);
#define MAX_ENCRYPT_SZ ENCRYPT_LEN
#define WOLFSSL_ASSERT_EQ(x, y) wc_static_assert((x) == (y))
#define WOLFSSL_ASSERT_GE(x, y) wc_static_assert((x) >= (y))
#define WOLFSSL_ASSERT_SIZEOF_GE(x, y) wc_static_assert(sizeof(x) >= sizeof(y))
@@ -3463,6 +3454,11 @@ WOLFSSL_LOCAL int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions, void* heap);
#endif /* HAVE_SECURE_RENEGOTIATION */
#ifdef HAVE_SESSION_TICKET
/* Max peer cert size for ticket: 2KB is reasonable for most RSA/ECC certs */
#ifndef MAX_TICKET_PEER_CERT_SZ
#define MAX_TICKET_PEER_CERT_SZ 2048
#endif
/* Our ticket format. All members need to be a byte or array of byte to
* avoid alignment issues */
typedef struct InternalTicket {
@@ -3488,21 +3484,40 @@ typedef struct InternalTicket {
byte sessionCtxSz; /* sessionCtx length */
byte sessionCtx[ID_LEN]; /* app specific context id */
#endif /* OPENSSL_EXTRA */
#if defined(OPENSSL_ALL) && defined(KEEP_PEER_CERT) && \
!defined(NO_CERT_IN_TICKET)
byte peerCertLen[OPAQUE16_LEN]; /* peer cert length */
byte peerCert[]; /* peer certificate DER - variable length */
#endif
} InternalTicket;
/* Base size of InternalTicket without the variable-length peerCert field */
#define WOLFSSL_INTERNAL_TICKET_BASE_SZ (sizeof(InternalTicket))
/* Minimum internal ticket length (no peer cert) */
#ifndef WOLFSSL_TICKET_ENC_CBC_HMAC
#define WOLFSSL_INTERNAL_TICKET_LEN sizeof(InternalTicket)
#define WOLFSSL_INTERNAL_TICKET_LEN WOLFSSL_INTERNAL_TICKET_BASE_SZ
#else
#define WOLFSSL_INTERNAL_TICKET_LEN \
(((sizeof(InternalTicket) + 15) / 16) * 16)
(((WOLFSSL_INTERNAL_TICKET_BASE_SZ + 15) / 16) * 16)
#endif
/* Maximum internal ticket length (with max peer cert) */
#if defined(OPENSSL_ALL) && defined(KEEP_PEER_CERT) && \
!defined(NO_CERT_IN_TICKET)
#define WOLFSSL_INTERNAL_TICKET_MAX_SZ \
(WOLFSSL_INTERNAL_TICKET_BASE_SZ + MAX_TICKET_PEER_CERT_SZ)
#else
#define WOLFSSL_INTERNAL_TICKET_MAX_SZ WOLFSSL_INTERNAL_TICKET_BASE_SZ
#endif
#ifndef WOLFSSL_TICKET_EXTRA_PADDING_SZ
#define WOLFSSL_TICKET_EXTRA_PADDING_SZ 32
#endif
/* Maximum encrypted ticket size */
#define WOLFSSL_TICKET_ENC_SZ \
(sizeof(InternalTicket) + WOLFSSL_TICKET_EXTRA_PADDING_SZ)
(WOLFSSL_INTERNAL_TICKET_MAX_SZ + WOLFSSL_TICKET_EXTRA_PADDING_SZ)
/* RFC 5077 defines this for session tickets. All members need to be a byte or
* array of byte to avoid alignment issues */
@@ -3510,14 +3525,18 @@ typedef struct ExternalTicket {
byte key_name[WOLFSSL_TICKET_NAME_SZ]; /* key context name - 16 */
byte iv[WOLFSSL_TICKET_IV_SZ]; /* this ticket's iv - 16 */
byte enc_len[OPAQUE16_LEN]; /* encrypted length - 2 */
byte enc_ticket[WOLFSSL_TICKET_ENC_SZ];
/* encrypted internal ticket */
byte mac[WOLFSSL_TICKET_MAC_SZ]; /* total mac - 32 */
byte enc_ticket[]; /* encrypted ticket - var length
* + total mac - 32 */
} ExternalTicket;
/* Cast to int to reduce amount of casts in code */
#define SESSION_TICKET_LEN ((int)sizeof(ExternalTicket))
#define WOLFSSL_TICKET_FIXED_SZ (SESSION_TICKET_LEN - WOLFSSL_TICKET_ENC_SZ)
/* Fixed portion of external ticket (key_name + iv + enc_len) */
#define WOLFSSL_TICKET_FIXED_SZ \
(WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + OPAQUE16_LEN + \
WOLFSSL_TICKET_MAC_SZ)
/* Maximum session ticket length */
#define SESSION_TICKET_LEN \
((int)(WOLFSSL_TICKET_FIXED_SZ + WOLFSSL_TICKET_ENC_SZ))
typedef struct SessionTicket {
word32 lifetime;
@@ -3559,6 +3578,20 @@ WOLFSSL_LOCAL void TLSX_SessionTicket_Free(SessionTicket* ticket, void* heap);
#endif /* HAVE_SESSION_TICKET */
#ifndef MAX_PSK_ID_LEN
/* max psk identity/hint supported */
#if defined(WOLFSSL_TLS13)
#ifdef SESSION_TICKET_LEN
#define MAX_PSK_ID_LEN SESSION_TICKET_LEN
#else
/* Previous value. Use as fallback for when tickets are disabled. */
#define MAX_PSK_ID_LEN 1536
#endif
#else
#define MAX_PSK_ID_LEN 128
#endif
#endif
#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
int TLSX_EncryptThenMac_Respond(WOLFSSL* ssl);
#endif
@@ -6411,12 +6444,20 @@ struct SystemCryptoPolicy {
* for the caller to find so we clear the last error.
*/
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_HAVE_ERROR_QUEUE)
#define CLEAR_ASN_NO_PEM_HEADER_ERROR(err) \
(err) = wolfSSL_ERR_peek_last_error(); \
if (wolfSSL_ERR_GET_LIB(err) == WOLFSSL_ERR_LIB_PEM && \
wolfSSL_ERR_GET_REASON(err) == -WOLFSSL_PEM_R_NO_START_LINE_E) { \
wc_RemoveErrorNode(-1); \
}
#define CLEAR_ASN_NO_PEM_HEADER_ERROR(err) \
do { \
(err) = wolfSSL_ERR_peek_last_error(); \
if (wolfSSL_ERR_GET_LIB(err) == WOLFSSL_ERR_LIB_PEM && \
wolfSSL_ERR_GET_REASON(err) == -WOLFSSL_PEM_R_NO_START_LINE_E) { \
unsigned long peekErr; \
do { \
wc_RemoveErrorNode(-1); \
peekErr = wolfSSL_ERR_peek_last_error(); \
} while (wolfSSL_ERR_GET_LIB(peekErr) == WOLFSSL_ERR_LIB_PEM && \
wolfSSL_ERR_GET_REASON(peekErr) == \
-WOLFSSL_PEM_R_NO_START_LINE_E); \
} \
} while(0)
#else
#define CLEAR_ASN_NO_PEM_HEADER_ERROR(err) (void)(err);
#endif
+5 -2
View File
@@ -632,16 +632,18 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
#define sk_X509_push wolfSSL_sk_X509_push
#define sk_X509_pop wolfSSL_sk_X509_pop
#define sk_X509_pop_free wolfSSL_sk_X509_pop_free
#define sk_X509_dup wolfSSL_sk_dup
#define sk_X509_dup wolfSSL_shallow_sk_dup
#define sk_X509_free wolfSSL_sk_X509_free
#define X509_chain_up_ref wolfSSL_X509_chain_up_ref
#define sk_X509_CRL_new wolfSSL_sk_X509_CRL_new
#define sk_X509_CRL_new_null wolfSSL_sk_X509_CRL_new_null
#define sk_X509_CRL_pop_free wolfSSL_sk_X509_CRL_pop_free
#define sk_X509_CRL_free wolfSSL_sk_X509_CRL_free
#define sk_X509_CRL_push wolfSSL_sk_X509_CRL_push
#define sk_X509_CRL_value wolfSSL_sk_X509_CRL_value
#define sk_X509_CRL_num wolfSSL_sk_X509_CRL_num
#define sk_X509_CRL_dup wolfSSL_shallow_sk_dup
#define sk_X509_OBJECT_new wolfSSL_sk_X509_OBJECT_new
#define sk_X509_OBJECT_free wolfSSL_sk_X509_OBJECT_free
@@ -824,6 +826,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_
#define X509_CRL_new wolfSSL_X509_CRL_new
#define X509_CRL_dup wolfSSL_X509_CRL_dup
#define X509_CRL_up_ref wolfSSL_X509_CRL_up_ref
#define X509_CRL_free wolfSSL_X509_CRL_free
#define X509_CRL_sign wolfSSL_X509_CRL_sign
#define X509_CRL_get_lastUpdate wolfSSL_X509_CRL_get_lastUpdate
@@ -1337,7 +1340,7 @@ typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE;
#define sk_SSL_COMP_zero wolfSSL_sk_SSL_COMP_zero
#define sk_SSL_CIPHER_value wolfSSL_sk_SSL_CIPHER_value
#endif /* OPENSSL_ALL || WOLFSSL_HAPROXY */
#define sk_SSL_CIPHER_dup wolfSSL_sk_dup
#define sk_SSL_CIPHER_dup wolfSSL_shallow_sk_dup
#define sk_SSL_CIPHER_free wolfSSL_sk_SSL_CIPHER_free
#define sk_SSL_CIPHER_find wolfSSL_sk_SSL_CIPHER_find
+2
View File
@@ -1952,6 +1952,7 @@ WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509)* sk);
WOLFSSL_API void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509)* sk);
WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new(void);
WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new_null(void);
WOLFSSL_API void wolfSSL_sk_X509_CRL_pop_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk,
void (*f) (WOLFSSL_X509_CRL*));
WOLFSSL_API void wolfSSL_sk_X509_CRL_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk);
@@ -3517,6 +3518,7 @@ WOLFSSL_API int wolfSSL_X509_REVOKED_get_serial_number(RevokedCert* rev,
#endif
#if defined(HAVE_CRL) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
WOLFSSL_API WOLFSSL_X509_CRL* wolfSSL_X509_CRL_dup(const WOLFSSL_X509_CRL* crl);
WOLFSSL_API int wolfSSL_X509_CRL_up_ref(WOLFSSL_X509_CRL* crl);
WOLFSSL_API void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl);
#endif
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA)
+1 -1
View File
@@ -104,7 +104,7 @@
#else
#define WC_DEPRECATED(msg) /* null expansion */
#endif
#endif /* !WC_MAYBE_UNUSED */
#endif /* !WC_DEPRECATED */
/* use inlining if compiler allows */
#ifndef WC_INLINE