Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -10997,6 +10997,70 @@ const WOLFSSL_CIPHER* wolfSSL_get_cipher_by_value(word16 value)
return cipher;
}

#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
/* Locate a cipher in the SSL's cipher list by 2-byte wire-format suite id.
*
* Mirrors OpenSSL's SSL_CIPHER_find(): the SSL's configured cipher list is
* searched first, then all cipher suites known to the library are searched as
* a fallback. This lets callers decode a suite id seen on the wire even when
* it is not enabled on the SSL object.
*
* A match found in the SSL's cipher list returns storage owned by that list.
* A match found only in the library fallback is stored in the SSL object's
* scratch cipher (ssl->cipher), as wolfSSL_get_current_cipher does. In either
* case callers must not free the returned pointer; it remains valid until the
* next call that updates ssl->cipher, or until SSL_free.
*
* @param [in] ssl SSL/TLS object whose cipher list is searched.
* @param [in] ptr Pointer to a 2-byte cipher suite identifier.
* @return Matching cipher on success.
* @return NULL if ssl or ptr is NULL, or no cipher matches.
*/
const WOLFSSL_CIPHER* wolfSSL_SSL_CIPHER_find(WOLFSSL* ssl,
const unsigned char* ptr)
{
WOLF_STACK_OF(WOLFSSL_CIPHER)* sk;
WOLFSSL_STACK* node;
const CipherSuiteInfo* cipher_names;
int cipherSz;
int i;

WOLFSSL_ENTER("wolfSSL_SSL_CIPHER_find");

if (ssl == NULL || ptr == NULL)
return NULL;

sk = wolfSSL_get_ciphers_compat(ssl);
for (node = sk; node != NULL; node = node->next) {
if (node->data.cipher.cipherSuite0 == ptr[0] &&
node->data.cipher.cipherSuite == ptr[1]) {
return &node->data.cipher;
}
}

/* Not enabled on this SSL - fall back to a library-wide lookup so suite
* ids seen on the wire can still be decoded, matching OpenSSL. */
cipher_names = GetCipherNames();
cipherSz = GetCipherNamesSize();
for (i = 0; i < cipherSz; i++) {
if (cipher_names[i].cipherSuite0 == ptr[0] &&
cipher_names[i].cipherSuite == ptr[1]) {
XMEMSET(&ssl->cipher, 0, sizeof(ssl->cipher));
ssl->cipher.cipherSuite0 = ptr[0];
ssl->cipher.cipherSuite = ptr[1];
ssl->cipher.ssl = ssl;
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
ssl->cipher.offset = (unsigned long)i;
#endif
return &ssl->cipher;
}
}

return NULL;
}
Comment thread
Roy-Carter marked this conversation as resolved.
#endif


#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
!defined(NO_DH) || (defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_MLKEM))
Expand Down
38 changes: 38 additions & 0 deletions src/ssl_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -5220,6 +5220,8 @@ int wolfSSL_add0_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509)
if (ret == 1) {
/* We now own cert chain. */
ssl->buffers.weOwnCertChain = 1;
/* Account for the certificate just added to the chain. */
ssl->buffers.certChainCnt++;
/* Create a stack to put certificate into. */
if (ssl->ourCertChain == NULL) {
ssl->ourCertChain = wolfSSL_sk_X509_new_null();
Expand Down Expand Up @@ -5270,6 +5272,42 @@ int wolfSSL_add1_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509)

return ret;
}

/* Clear all extra chain certificates set on the SSL object.
*
* Mirrors OpenSSL's SSL_clear_chain_certs(): frees any chain certificates
* previously added via SSL_add0_chain_cert / SSL_add1_chain_cert (or set via
* SSL_set0_chain / SSL_set1_chain) on this SSL. Does not affect the leaf
* certificate, the private key, or chain certificates inherited from the
* WOLFSSL_CTX.
*
* @param [in, out] ssl SSL object.
* @return 1 on success.
* @return 0 when ssl is NULL.
*/
int wolfSSL_clear_chain_certs(WOLFSSL* ssl)
{
WOLFSSL_ENTER("wolfSSL_clear_chain_certs");

if (ssl == NULL)
return 0;

/* Free the DER-encoded chain buffer if this SSL owns it. */
if (ssl->buffers.weOwnCertChain) {
FreeDer(&ssl->buffers.certChain);
ssl->buffers.weOwnCertChain = 0;
}
ssl->buffers.certChain = NULL;
ssl->buffers.certChainCnt = 0;

/* Free the X509 stack used to track ownership of added chain certs. */
if (ssl->ourCertChain != NULL) {
wolfSSL_sk_X509_pop_free(ssl->ourCertChain, NULL);
ssl->ourCertChain = NULL;
}

return 1;
}
Comment thread
julek-wolfssl marked this conversation as resolved.
#endif /* KEEP_OUR_CERT */
#endif /* OPENSSL_EXTRA, HAVE_LIGHTY, WOLFSSL_MYSQL_COMPATIBLE, HAVE_STUNNEL,
WOLFSSL_NGINX, HAVE_POCO_LIB, WOLFSSL_HAPROXY */
Expand Down
38 changes: 38 additions & 0 deletions src/ssl_sk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,44 @@ void wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_free");
wolfSSL_sk_free(sk);
}

/* Remove the cipher at the given index from the stack.
*
* @param [in,out] sk Stack of ciphers.
* @param [in] idx Index of cipher to remove.
* @return Heap copy of removed cipher on success.
* @return NULL on failure.
*/
WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_delete(
WOLF_STACK_OF(WOLFSSL_CIPHER)* sk, int idx)
{
WOLFSSL_CIPHER* ret = NULL;
WOLFSSL_CIPHER* cipher;

WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_delete");

if (sk == NULL || idx < 0)
return NULL;

/* Capture the inline cipher value before the pop_node call frees the
* underlying memory. */
cipher = wolfSSL_sk_SSL_CIPHER_value(sk, idx);
if (cipher == NULL)
return NULL;

ret = (WOLFSSL_CIPHER*)XMALLOC(sizeof(WOLFSSL_CIPHER), NULL,
DYNAMIC_TYPE_OPENSSL);
if (ret == NULL)
return NULL;

*ret = *cipher;

/* pop_node returns NULL for STACK_TYPE_CIPHER (data is static/inline),
* but it still performs the unlink and node free that we need. */
(void)wolfSSL_sk_pop_node(sk, idx);

return ret;
}
#endif /* OPENSSL_ALL || OPENSSL_EXTRA */

/*******************************************************************************
Expand Down
Loading
Loading