Remove |X509| things from SSL_SESSION.
|SSL_SESSION_from_bytes| now takes an |SSL_CTX*|, from which it uses the
|X509_METHOD| and buffer pool. This is our API so we can do this.
This also requires adding an |SSL_CTX*| argument to |SSL_SESSION_new|
for the same reason. However, |SSL_SESSION_new| already has very few
callers (and none in third-party code that I can see) so I think we can
get away with this.
Change-Id: I1337cd2bd8cff03d4b9405ea3146b3b59584aa72
Reviewed-on: https://boringssl-review.googlesource.com/13584
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: Adam Langley <alangley@gmail.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/handshake_client.c b/ssl/handshake_client.c
index 66c0142..427213c 100644
--- a/ssl/handshake_client.c
+++ b/ssl/handshake_client.c
@@ -1077,7 +1077,7 @@
if (sk_CRYPTO_BUFFER_num(ssl->s3->new_session->certs) == 0 ||
CBS_len(&cbs) != 0 ||
- !ssl_session_x509_cache_objects(ssl->s3->new_session)) {
+ !ssl->ctx->x509_method->session_cache_objects(ssl->s3->new_session)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return -1;
diff --git a/ssl/handshake_server.c b/ssl/handshake_server.c
index 5e921b6..c352dd9 100644
--- a/ssl/handshake_server.c
+++ b/ssl/handshake_server.c
@@ -483,10 +483,10 @@
* now. */
if (ssl->s3->new_session != NULL &&
ssl->retain_only_sha256_of_client_certs) {
- X509_free(ssl->s3->new_session->x509_peer);
- ssl->s3->new_session->x509_peer = NULL;
- sk_X509_pop_free(ssl->s3->new_session->x509_chain, X509_free);
- ssl->s3->new_session->x509_chain = NULL;
+ sk_CRYPTO_BUFFER_pop_free(ssl->s3->new_session->certs,
+ CRYPTO_BUFFER_free);
+ ssl->s3->new_session->certs = NULL;
+ ssl->ctx->x509_method->session_clear(ssl->s3->new_session);
}
SSL_SESSION_free(ssl->s3->established_session);
@@ -1472,7 +1472,7 @@
}
if (CBS_len(&certificate_msg) != 0 ||
- !ssl_session_x509_cache_objects(ssl->s3->new_session)) {
+ !ssl->ctx->x509_method->session_cache_objects(ssl->s3->new_session)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return -1;
diff --git a/ssl/internal.h b/ssl/internal.h
index 06bdd04..5b93f47 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -804,12 +804,6 @@
* configured and zero otherwise. */
int ssl_has_certificate(const SSL *ssl);
-/* ssl_session_x509_cache_objects fills out |sess->x509_peer| and
- * |sess->x509_chain| from |sess->certs| and erases
- * |sess->x509_chain_without_leaf|. It returns one on success or zero on
- * error. */
-int ssl_session_x509_cache_objects(SSL_SESSION *sess);
-
/* ssl_parse_cert_chain parses a certificate list from |cbs| in the format used
* by a TLS Certificate message. On success, it returns a newly-allocated
* |CRYPTO_BUFFER| list and advances |cbs|. Otherwise, it returns NULL and sets
@@ -1433,8 +1427,22 @@
/* cert_flush_cached_chain drops any cached |X509|-based leaf certificate
* from |cert|. */
void (*cert_flush_cached_leaf)(CERT *cert);
+
+ /* session_cache_objects fills out |sess->x509_peer| and |sess->x509_chain|
+ * from |sess->certs| and erases |sess->x509_chain_without_leaf|. It returns
+ * one on success or zero on error. */
+ int (*session_cache_objects)(SSL_SESSION *session);
+ /* session_dup duplicates any needed fields from |session| to |new_session|.
+ * It returns one on success or zero on error. */
+ int (*session_dup)(SSL_SESSION *new_session, const SSL_SESSION *session);
+ /* session_clear frees any X509-related state from |session|. */
+ void (*session_clear)(SSL_SESSION *session);
};
+/* ssl_noop_x509_method is implements the |ssl_x509_method_st| functions by
+ * doing nothing. */
+extern const struct ssl_x509_method_st ssl_noop_x509_method;
+
/* ssl_crypto_x509_method provides the |ssl_x509_method_st| functions using
* crypto/x509. */
extern const struct ssl_x509_method_st ssl_crypto_x509_method;
@@ -1911,6 +1919,15 @@
int ssl_get_new_session(SSL_HANDSHAKE *hs, int is_server);
int ssl_encrypt_ticket(SSL *ssl, CBB *out, const SSL_SESSION *session);
+/* ssl_session_new returns a newly-allocated blank |SSL_SESSION| or NULL on
+ * error. */
+SSL_SESSION *ssl_session_new(const SSL_X509_METHOD *x509_method);
+
+/* SSL_SESSION_parse parses an |SSL_SESSION| from |cbs| and advances |cbs| over
+ * the parsed data. */
+SSL_SESSION *SSL_SESSION_parse(CBS *cbs, const SSL_X509_METHOD *x509_method,
+ CRYPTO_BUFFER_POOL *pool);
+
/* ssl_session_is_context_valid returns one if |session|'s session ID context
* matches the one set on |ssl| and zero otherwise. */
int ssl_session_is_context_valid(const SSL *ssl, const SSL_SESSION *session);
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index 4c1ee89..3582864 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -575,8 +575,9 @@
return 1;
}
-static SSL_SESSION *SSL_SESSION_parse(CBS *cbs) {
- SSL_SESSION *ret = SSL_SESSION_new();
+SSL_SESSION *SSL_SESSION_parse(CBS *cbs, const SSL_X509_METHOD *x509_method,
+ CRYPTO_BUFFER_POOL *pool) {
+ SSL_SESSION *ret = ssl_session_new(x509_method);
if (ret == NULL) {
goto err;
}
@@ -738,7 +739,7 @@
if (has_peer) {
/* TODO(agl): this should use the |SSL_CTX|'s pool. */
- CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new_from_CBS(&peer, NULL);
+ CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new_from_CBS(&peer, pool);
if (buffer == NULL ||
!sk_CRYPTO_BUFFER_push(ret->certs, buffer)) {
CRYPTO_BUFFER_free(buffer);
@@ -756,7 +757,7 @@
}
/* TODO(agl): this should use the |SSL_CTX|'s pool. */
- CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new_from_CBS(&cert, NULL);
+ CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new_from_CBS(&cert, pool);
if (buffer == NULL ||
!sk_CRYPTO_BUFFER_push(ret->certs, buffer)) {
CRYPTO_BUFFER_free(buffer);
@@ -766,7 +767,7 @@
}
}
- if (!ssl_session_x509_cache_objects(ret)) {
+ if (!x509_method->session_cache_objects(ret)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
@@ -811,10 +812,11 @@
return NULL;
}
-SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in, size_t in_len) {
+SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in, size_t in_len,
+ const SSL_CTX *ctx) {
CBS cbs;
CBS_init(&cbs, in, in_len);
- SSL_SESSION *ret = SSL_SESSION_parse(&cbs);
+ SSL_SESSION *ret = SSL_SESSION_parse(&cbs, ctx->x509_method, ctx->pool);
if (ret == NULL) {
return NULL;
}
@@ -825,25 +827,3 @@
}
return ret;
}
-
-SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, long length) {
- if (length < 0) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
-
- CBS cbs;
- CBS_init(&cbs, *pp, length);
-
- SSL_SESSION *ret = SSL_SESSION_parse(&cbs);
- if (ret == NULL) {
- return NULL;
- }
-
- if (a) {
- SSL_SESSION_free(*a);
- *a = ret;
- }
- *pp = CBS_data(&cbs);
- return ret;
-}
diff --git a/ssl/ssl_file.c b/ssl/ssl_file.c
index e1ebaa6..59351a3 100644
--- a/ssl/ssl_file.c
+++ b/ssl/ssl_file.c
@@ -573,14 +573,3 @@
void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *data) {
ctx->default_passwd_callback_userdata = data;
}
-
-SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out) {
- return ASN1_d2i_bio_of(SSL_SESSION, SSL_SESSION_new, d2i_SSL_SESSION, bio,
- out);
-}
-
-int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session) {
- return ASN1_i2d_bio_of(SSL_SESSION, i2d_SSL_SESSION, bio, session);
-}
-
-IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
diff --git a/ssl/ssl_session.c b/ssl/ssl_session.c
index 908d5dc..b71b994 100644
--- a/ssl/ssl_session.c
+++ b/ssl/ssl_session.c
@@ -160,7 +160,7 @@
static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session);
static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock);
-SSL_SESSION *SSL_SESSION_new(void) {
+SSL_SESSION *ssl_session_new(const SSL_X509_METHOD *x509_method) {
SSL_SESSION *session = OPENSSL_malloc(sizeof(SSL_SESSION));
if (session == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
@@ -168,6 +168,7 @@
}
OPENSSL_memset(session, 0, sizeof(SSL_SESSION));
+ session->x509_method = x509_method;
session->verify_result = X509_V_ERR_INVALID_CALL;
session->references = 1;
session->timeout = SSL_DEFAULT_SESSION_TIMEOUT;
@@ -177,8 +178,12 @@
return session;
}
+SSL_SESSION *SSL_SESSION_new(const SSL_CTX *ctx) {
+ return ssl_session_new(ctx->x509_method);
+}
+
SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *session, int dup_flags) {
- SSL_SESSION *new_session = SSL_SESSION_new();
+ SSL_SESSION *new_session = ssl_session_new(session->x509_method);
if (new_session == NULL) {
goto err;
}
@@ -214,16 +219,11 @@
CRYPTO_BUFFER_up_ref(buffer);
}
}
- if (session->x509_peer != NULL) {
- X509_up_ref(session->x509_peer);
- new_session->x509_peer = session->x509_peer;
+
+ if (!session->x509_method->session_dup(new_session, session)) {
+ goto err;
}
- if (session->x509_chain != NULL) {
- new_session->x509_chain = X509_chain_up_ref(session->x509_chain);
- if (new_session->x509_chain == NULL) {
- goto err;
- }
- }
+
new_session->verify_result = session->verify_result;
new_session->ocsp_response_length = session->ocsp_response_length;
@@ -367,9 +367,7 @@
OPENSSL_cleanse(session->master_key, sizeof(session->master_key));
OPENSSL_cleanse(session->session_id, sizeof(session->session_id));
sk_CRYPTO_BUFFER_pop_free(session->certs, CRYPTO_BUFFER_free);
- X509_free(session->x509_peer);
- sk_X509_pop_free(session->x509_chain, X509_free);
- sk_X509_pop_free(session->x509_chain_without_leaf, X509_free);
+ session->x509_method->session_clear(session);
OPENSSL_free(session->tlsext_hostname);
OPENSSL_free(session->tlsext_tick);
OPENSSL_free(session->tlsext_signed_cert_timestamp_list);
@@ -511,7 +509,7 @@
return 0;
}
- SSL_SESSION *session = SSL_SESSION_new();
+ SSL_SESSION *session = ssl_session_new(ssl->ctx->x509_method);
if (session == NULL) {
return 0;
}
@@ -573,53 +571,6 @@
return 0;
}
-int ssl_session_x509_cache_objects(SSL_SESSION *sess) {
- STACK_OF(X509) *chain = NULL;
- const size_t num_certs = sk_CRYPTO_BUFFER_num(sess->certs);
-
- if (num_certs > 0) {
- chain = sk_X509_new_null();
- if (chain == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
-
- X509 *leaf = NULL;
- for (size_t i = 0; i < num_certs; i++) {
- X509 *x509 = X509_parse_from_buffer(sk_CRYPTO_BUFFER_value(sess->certs, i));
- if (x509 == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- goto err;
- }
- if (!sk_X509_push(chain, x509)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- X509_free(x509);
- goto err;
- }
- if (i == 0) {
- leaf = x509;
- }
- }
-
- sk_X509_pop_free(sess->x509_chain, X509_free);
- sess->x509_chain = chain;
- sk_X509_pop_free(sess->x509_chain_without_leaf, X509_free);
- sess->x509_chain_without_leaf = NULL;
-
- X509_free(sess->x509_peer);
- if (leaf != NULL) {
- X509_up_ref(leaf);
- }
- sess->x509_peer = leaf;
-
- return 1;
-
-err:
- sk_X509_pop_free(chain, X509_free);
- return 0;
-}
-
int ssl_encrypt_ticket(SSL *ssl, CBB *out, const SSL_SESSION *session) {
int ret = 0;
@@ -753,7 +704,8 @@
/* If the session contains a client certificate (either the full
* certificate or just the hash) then require that the form of the
* certificate matches the current configuration. */
- ((session->x509_peer == NULL && !session->peer_sha256_valid) ||
+ ((sk_CRYPTO_BUFFER_num(session->certs) == 0 &&
+ !session->peer_sha256_valid) ||
session->peer_sha256_valid ==
ssl->retain_only_sha256_of_client_certs);
}
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc
index aaad1bc..e12c613 100644
--- a/ssl/ssl_test.cc
+++ b/ssl/ssl_test.cc
@@ -634,7 +634,12 @@
}
// Verify the SSL_SESSION decodes.
- bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
+ bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
+ if (!ssl_ctx) {
+ return false;
+ }
+ bssl::UniquePtr<SSL_SESSION> session(
+ SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
if (!session) {
fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
return false;
@@ -703,7 +708,12 @@
}
// Verify that the SSL_SESSION fails to decode.
- bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
+ bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
+ if (!ssl_ctx) {
+ return false;
+ }
+ bssl::UniquePtr<SSL_SESSION> session(
+ SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
if (session) {
fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
return false;
@@ -795,8 +805,13 @@
if (!DecodeBase64(&der, kOpenSSLSession)) {
return nullptr;
}
+
+ bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
+ if (!ssl_ctx) {
+ return nullptr;
+ }
bssl::UniquePtr<SSL_SESSION> session(
- SSL_SESSION_from_bytes(der.data(), der.size()));
+ SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
if (!session) {
return nullptr;
}
@@ -989,7 +1004,11 @@
}
static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
- bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
+ bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
+ if (!ssl_ctx) {
+ return nullptr;
+ }
+ bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
if (!ret) {
return nullptr;
}
@@ -2166,8 +2185,12 @@
len = static_cast<size_t>(len1 + len2);
#endif
+ bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
+ if (!ssl_ctx) {
+ return false;
+ }
bssl::UniquePtr<SSL_SESSION> server_session(
- SSL_SESSION_from_bytes(plaintext.get(), len));
+ SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
if (!server_session) {
return false;
}
diff --git a/ssl/ssl_x509.c b/ssl/ssl_x509.c
index 9077b61..2955c21 100644
--- a/ssl/ssl_x509.c
+++ b/ssl/ssl_x509.c
@@ -142,6 +142,10 @@
#include <assert.h>
+#include <openssl/asn1.h>
+#include <openssl/bytestring.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
#include <openssl/stack.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
@@ -334,10 +338,85 @@
cert->x509_stash = NULL;
}
+static int ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) {
+ STACK_OF(X509) *chain = NULL;
+ const size_t num_certs = sk_CRYPTO_BUFFER_num(sess->certs);
+
+ if (num_certs > 0) {
+ chain = sk_X509_new_null();
+ if (chain == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ X509 *leaf = NULL;
+ for (size_t i = 0; i < num_certs; i++) {
+ X509 *x509 = X509_parse_from_buffer(sk_CRYPTO_BUFFER_value(sess->certs, i));
+ if (x509 == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ goto err;
+ }
+ if (!sk_X509_push(chain, x509)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ X509_free(x509);
+ goto err;
+ }
+ if (i == 0) {
+ leaf = x509;
+ }
+ }
+
+ sk_X509_pop_free(sess->x509_chain, X509_free);
+ sess->x509_chain = chain;
+ sk_X509_pop_free(sess->x509_chain_without_leaf, X509_free);
+ sess->x509_chain_without_leaf = NULL;
+
+ X509_free(sess->x509_peer);
+ if (leaf != NULL) {
+ X509_up_ref(leaf);
+ }
+ sess->x509_peer = leaf;
+
+ return 1;
+
+err:
+ sk_X509_pop_free(chain, X509_free);
+ return 0;
+}
+
+static int ssl_crypto_x509_session_dup(SSL_SESSION *new_session,
+ const SSL_SESSION *session) {
+ if (session->x509_peer != NULL) {
+ X509_up_ref(session->x509_peer);
+ new_session->x509_peer = session->x509_peer;
+ }
+ if (session->x509_chain != NULL) {
+ new_session->x509_chain = X509_chain_up_ref(session->x509_chain);
+ if (new_session->x509_chain == NULL) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static void ssl_crypto_x509_session_clear(SSL_SESSION *session) {
+ X509_free(session->x509_peer);
+ session->x509_peer = NULL;
+ sk_X509_pop_free(session->x509_chain, X509_free);
+ session->x509_chain = NULL;
+ sk_X509_pop_free(session->x509_chain_without_leaf, X509_free);
+ session->x509_chain_without_leaf = NULL;
+}
+
const SSL_X509_METHOD ssl_crypto_x509_method = {
ssl_crypto_x509_clear,
ssl_crypto_x509_flush_cached_chain,
ssl_crypto_x509_flush_cached_leaf,
+ ssl_crypto_x509_session_cache_objects,
+ ssl_crypto_x509_session_dup,
+ ssl_crypto_x509_session_clear,
};
/* x509_to_buffer returns a |CRYPTO_BUFFER| that contains the serialised
@@ -696,3 +775,41 @@
*out_chain = ssl->cert->x509_chain;
return 1;
}
+
+static SSL_SESSION *ssl_session_new_with_crypto_x509(void) {
+ return ssl_session_new(&ssl_crypto_x509_method);
+}
+
+SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out) {
+ return ASN1_d2i_bio_of(SSL_SESSION, ssl_session_new_with_crypto_x509,
+ d2i_SSL_SESSION, bio, out);
+}
+
+int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session) {
+ return ASN1_i2d_bio_of(SSL_SESSION, i2d_SSL_SESSION, bio, session);
+}
+
+IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
+
+SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, long length) {
+ if (length < 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ CBS cbs;
+ CBS_init(&cbs, *pp, length);
+
+ SSL_SESSION *ret = SSL_SESSION_parse(&cbs, &ssl_crypto_x509_method,
+ NULL /* no buffer pool */);
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ if (a) {
+ SSL_SESSION_free(*a);
+ *a = ret;
+ }
+ *pp = CBS_data(&cbs);
+ return ret;
+}
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index b3ba546..7723ccd 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -3213,7 +3213,8 @@
#endif
/* Decode the session. */
- SSL_SESSION *session = SSL_SESSION_from_bytes(plaintext, plaintext_len);
+ SSL_SESSION *session =
+ SSL_SESSION_from_bytes(plaintext, plaintext_len, ssl->ctx);
if (session == NULL) {
ERR_clear_error(); /* Don't leave an error on the queue. */
goto done;
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 66a71a0..381f4c2 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -1477,7 +1477,7 @@
}
if (expected_sha256_client_cert &&
- SSL_get_session(ssl)->x509_peer != nullptr) {
+ SSL_get_session(ssl)->certs != nullptr) {
fprintf(stderr, "Have both client cert and SHA-256 hash: is_resume:%d.\n",
is_resume);
return false;
diff --git a/ssl/tls13_both.c b/ssl/tls13_both.c
index 134dfd2..19dd555 100644
--- a/ssl/tls13_both.c
+++ b/ssl/tls13_both.c
@@ -307,7 +307,7 @@
ssl->s3->new_session->certs = certs;
certs = NULL;
- if (!ssl_session_x509_cache_objects(ssl->s3->new_session)) {
+ if (!ssl->ctx->x509_method->session_cache_objects(ssl->s3->new_session)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
goto err;
diff --git a/ssl/tls13_client.c b/ssl/tls13_client.c
index a85f6b3..50f7e5a 100644
--- a/ssl/tls13_client.c
+++ b/ssl/tls13_client.c
@@ -615,9 +615,8 @@
int tls13_process_new_session_ticket(SSL *ssl) {
int ret = 0;
- SSL_SESSION *session =
- SSL_SESSION_dup(ssl->s3->established_session,
- SSL_SESSION_INCLUDE_NONAUTH);
+ SSL_SESSION *session = SSL_SESSION_dup(ssl->s3->established_session,
+ SSL_SESSION_INCLUDE_NONAUTH);
if (session == NULL) {
return 0;
}
diff --git a/ssl/tls13_server.c b/ssl/tls13_server.c
index 3ef0c15..0278b50 100644
--- a/ssl/tls13_server.c
+++ b/ssl/tls13_server.c
@@ -495,7 +495,7 @@
static enum ssl_hs_wait_t do_process_client_certificate_verify(
SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (ssl->s3->new_session->x509_peer == NULL) {
+ if (sk_CRYPTO_BUFFER_num(ssl->s3->new_session->certs) == 0) {
/* Skip this state. */
hs->tls13_state = state_process_channel_id;
return ssl_hs_ok;
diff --git a/ssl/tls_method.c b/ssl/tls_method.c
index 5533dfd..eaad2ca 100644
--- a/ssl/tls_method.c
+++ b/ssl/tls_method.c
@@ -257,3 +257,24 @@
const SSL_METHOD *TLS_client_method(void) {
return TLS_method();
}
+
+static void ssl_noop_x509_clear(CERT *cert) {}
+static void ssl_noop_x509_flush_cached_leaf(CERT *cert) {}
+static void ssl_noop_x509_flush_cached_chain(CERT *cert) {}
+static int ssl_noop_x509_session_cache_objects(SSL_SESSION *sess) {
+ return 1;
+}
+static int ssl_noop_x509_session_dup(SSL_SESSION *new_session,
+ const SSL_SESSION *session) {
+ return 1;
+}
+static void ssl_noop_x509_session_clear(SSL_SESSION *session) {}
+
+const SSL_X509_METHOD ssl_noop_x509_method = {
+ ssl_noop_x509_clear,
+ ssl_noop_x509_flush_cached_chain,
+ ssl_noop_x509_flush_cached_leaf,
+ ssl_noop_x509_session_cache_objects,
+ ssl_noop_x509_session_dup,
+ ssl_noop_x509_session_clear,
+};