Document some core SSL_CTX and SSL methods.
Current thought is to organize this by:
- Core SSL_CTX APIs (creating, destroying)
- Core SSL APIs (creating destroying, maybe handshake, read, write as
well)
- APIs to configure SSL_CTX/SSL, roughly grouped by feature. Probably
options and modes are the first two sections. SSL_TXT_* constants can
be part of documenting cipher suite configuration.
- APIs to query state from SSL_CTX/SSL, roughly grouped by feature. (Or
perhaps these should be folded into the configuration sections?)
The functions themselves aren't reordered or reorganized to match the
eventual header order yet. Though I did do the s -> ssl rename on the
ones I've touched.
Also formally deprecate SSL_clear. It would be a core SSL API
except it's horrible.
Change-Id: Ia7e4fdcb7bad4e9ccdee8cf8c3136dc63aaaa772
Reviewed-on: https://boringssl-review.googlesource.com/4784
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 092d1de..7385468 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -272,6 +272,47 @@
int *out_alg_bits);
+/* SSL contexts. */
+
+/* An SSL_METHOD selects whether to use TLS or DTLS. */
+typedef struct ssl_method_st SSL_METHOD;
+
+/* TLS_method is the |SSL_METHOD| used for TLS (and SSLv3) connections. */
+OPENSSL_EXPORT const SSL_METHOD *TLS_method(void);
+
+/* DTLS_method is the |SSL_METHOD| used for DTLS connections. */
+OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void);
+
+/* SSL_CTX_new returns a newly-allocated |SSL_CTX| with default settings or NULL
+ * on error. An |SSL_CTX| manages shared state and configuration between
+ * multiple TLS or DTLS connections. */
+OPENSSL_EXPORT SSL_CTX *SSL_CTX_new(const SSL_METHOD *method);
+
+/* SSL_CTX_free releases memory associated with |ctx|. */
+OPENSSL_EXPORT void SSL_CTX_free(SSL_CTX *ctx);
+
+
+/* SSL connections. */
+
+/* SSL_new returns a newly-allocated |SSL| using |ctx| or NULL on error. An
+ * |SSL| object represents a single TLS or DTLS connection. It inherits settings
+ * from |ctx| at the time of creation. Settings may also be individually
+ * configured on the connection.
+ *
+ * On creation, an |SSL| is not configured to be either a client or server. Call
+ * |SSL_set_connect_state| or |SSL_set_accept_state| to set this. */
+OPENSSL_EXPORT SSL *SSL_new(SSL_CTX *ctx);
+
+/* SSL_free releases memory associated with |ssl|. */
+OPENSSL_EXPORT void SSL_free(SSL *ssl);
+
+/* SSL_set_connect_state configures |ssl| to be a client. */
+OPENSSL_EXPORT void SSL_set_connect_state(SSL *ssl);
+
+/* SSL_set_accept_state configures |ssl| to be a server. */
+OPENSSL_EXPORT void SSL_set_accept_state(SSL *ssl);
+
+
/* Underdocumented functions.
*
* Functions below here haven't been touched up and may be underdocumented. */
@@ -364,7 +405,6 @@
#define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1
#define SSL_FILETYPE_PEM X509_FILETYPE_PEM
-typedef struct ssl_method_st SSL_METHOD;
typedef struct ssl_protocol_method_st SSL_PROTOCOL_METHOD;
typedef struct ssl_session_st SSL_SESSION;
typedef struct tls_sigalgs_st TLS_SIGALGS;
@@ -1795,14 +1835,11 @@
OPENSSL_EXPORT int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str);
OPENSSL_EXPORT int SSL_CTX_set_cipher_list_tls11(SSL_CTX *, const char *str);
-OPENSSL_EXPORT SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);
-OPENSSL_EXPORT void SSL_CTX_free(SSL_CTX *);
OPENSSL_EXPORT long SSL_CTX_set_timeout(SSL_CTX *ctx, long t);
OPENSSL_EXPORT long SSL_CTX_get_timeout(const SSL_CTX *ctx);
OPENSSL_EXPORT X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
OPENSSL_EXPORT void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *);
OPENSSL_EXPORT int SSL_want(const SSL *s);
-OPENSSL_EXPORT int SSL_clear(SSL *s);
OPENSSL_EXPORT void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm);
@@ -1977,7 +2014,6 @@
const uint8_t *sid_ctx,
unsigned int sid_ctx_len);
-OPENSSL_EXPORT SSL *SSL_new(SSL_CTX *ctx);
OPENSSL_EXPORT int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
unsigned int sid_ctx_len);
@@ -1993,7 +2029,6 @@
OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl);
OPENSSL_EXPORT void SSL_certs_clear(SSL *s);
-OPENSSL_EXPORT void SSL_free(SSL *ssl);
OPENSSL_EXPORT int SSL_accept(SSL *ssl);
OPENSSL_EXPORT int SSL_connect(SSL *ssl);
OPENSSL_EXPORT int SSL_read(SSL *ssl, void *buf, int num);
@@ -2010,12 +2045,6 @@
* |sess|. For example, "TLSv1.2" or "SSLv3". */
OPENSSL_EXPORT const char *SSL_SESSION_get_version(const SSL_SESSION *sess);
-/* TLS_method is the SSL_METHOD used for TLS (and SSLv3) connections. */
-OPENSSL_EXPORT const SSL_METHOD *TLS_method(void);
-
-/* DTLS_method is the SSL_METHOD used for DTLS connections. */
-OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void);
-
OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
OPENSSL_EXPORT int SSL_do_handshake(SSL *s);
@@ -2038,9 +2067,6 @@
OPENSSL_EXPORT int SSL_add_client_CA(SSL *ssl, X509 *x);
OPENSSL_EXPORT int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x);
-OPENSSL_EXPORT void SSL_set_connect_state(SSL *s);
-OPENSSL_EXPORT void SSL_set_accept_state(SSL *s);
-
OPENSSL_EXPORT long SSL_get_default_timeout(const SSL *s);
OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
@@ -2302,6 +2328,13 @@
OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void);
OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void);
+/* SSL_clear resets |ssl| to allow another connection and returns one on success
+ * or zero on failure. It returns most configuration state but releases memory
+ * associated with the current connection.
+ *
+ * Free |ssl| and create a new one instead. */
+OPENSSL_EXPORT int SSL_clear(SSL *ssl);
+
/* SSL_CTX_set_tmp_rsa_callback does nothing. */
OPENSSL_EXPORT void SSL_CTX_set_tmp_rsa_callback(
SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, int keylength));
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index d0c52b6..c0e1315 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -167,80 +167,80 @@
static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl = CRYPTO_EX_DATA_CLASS_INIT;
static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl_ctx = CRYPTO_EX_DATA_CLASS_INIT;
-int SSL_clear(SSL *s) {
- if (s->method == NULL) {
+int SSL_clear(SSL *ssl) {
+ if (ssl->method == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_clear, SSL_R_NO_METHOD_SPECIFIED);
return 0;
}
- if (ssl_clear_bad_session(s)) {
- SSL_SESSION_free(s->session);
- s->session = NULL;
+ if (ssl_clear_bad_session(ssl)) {
+ SSL_SESSION_free(ssl->session);
+ ssl->session = NULL;
}
- s->hit = 0;
- s->shutdown = 0;
+ ssl->hit = 0;
+ ssl->shutdown = 0;
- if (s->renegotiate) {
+ if (ssl->renegotiate) {
OPENSSL_PUT_ERROR(SSL, SSL_clear, ERR_R_INTERNAL_ERROR);
return 0;
}
- /* SSL_clear may be called before or after the |s| is initialized in either
+ /* SSL_clear may be called before or after the |ssl| is initialized in either
* accept or connect state. In the latter case, SSL_clear should preserve the
- * half and reset |s->state| accordingly. */
- if (s->handshake_func != NULL) {
- if (s->server) {
- SSL_set_accept_state(s);
+ * half and reset |ssl->state| accordingly. */
+ if (ssl->handshake_func != NULL) {
+ if (ssl->server) {
+ SSL_set_accept_state(ssl);
} else {
- SSL_set_connect_state(s);
+ SSL_set_connect_state(ssl);
}
} else {
- assert(s->state == 0);
+ assert(ssl->state == 0);
}
/* TODO(davidben): Some state on |s| is reset both in |SSL_new| and
* |SSL_clear| because it is per-connection state rather than configuration
- * state. Per-connection state should be on |s->s3| and |s->d1| so it is
+ * state. Per-connection state should be on |ssl->s3| and |ssl->d1| so it is
* naturally reset at the right points between |SSL_new|, |SSL_clear|, and
* |ssl3_new|. */
- s->rwstate = SSL_NOTHING;
- s->rstate = SSL_ST_READ_HEADER;
+ ssl->rwstate = SSL_NOTHING;
+ ssl->rstate = SSL_ST_READ_HEADER;
- BUF_MEM_free(s->init_buf);
- s->init_buf = NULL;
+ BUF_MEM_free(ssl->init_buf);
+ ssl->init_buf = NULL;
- s->packet = NULL;
- s->packet_length = 0;
+ ssl->packet = NULL;
+ ssl->packet_length = 0;
- ssl_clear_cipher_ctx(s);
+ ssl_clear_cipher_ctx(ssl);
- OPENSSL_free(s->next_proto_negotiated);
- s->next_proto_negotiated = NULL;
- s->next_proto_negotiated_len = 0;
+ OPENSSL_free(ssl->next_proto_negotiated);
+ ssl->next_proto_negotiated = NULL;
+ ssl->next_proto_negotiated_len = 0;
- /* The s->d1->mtu is simultaneously configuration (preserved across
+ /* The ssl->d1->mtu is simultaneously configuration (preserved across
* clear) and connection-specific state (gets reset).
*
* TODO(davidben): Avoid this. */
unsigned mtu = 0;
- if (s->d1 != NULL) {
- mtu = s->d1->mtu;
+ if (ssl->d1 != NULL) {
+ mtu = ssl->d1->mtu;
}
- s->method->ssl_free(s);
- if (!s->method->ssl_new(s)) {
+ ssl->method->ssl_free(ssl);
+ if (!ssl->method->ssl_new(ssl)) {
return 0;
}
- s->enc_method = ssl3_get_enc_method(s->version);
- assert(s->enc_method != NULL);
+ ssl->enc_method = ssl3_get_enc_method(ssl->version);
+ assert(ssl->enc_method != NULL);
- if (SSL_IS_DTLS(s) && (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
- s->d1->mtu = mtu;
+ if (SSL_IS_DTLS(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
+ ssl->d1->mtu = mtu;
}
- s->client_version = s->version;
+ ssl->client_version = ssl->version;
return 1;
}
@@ -523,60 +523,60 @@
void SSL_certs_clear(SSL *s) { ssl_cert_clear_certs(s->cert); }
-void SSL_free(SSL *s) {
- if (s == NULL) {
+void SSL_free(SSL *ssl) {
+ if (ssl == NULL) {
return;
}
- X509_VERIFY_PARAM_free(s->param);
+ X509_VERIFY_PARAM_free(ssl->param);
- CRYPTO_free_ex_data(&g_ex_data_class_ssl, s, &s->ex_data);
+ CRYPTO_free_ex_data(&g_ex_data_class_ssl, ssl, &ssl->ex_data);
- if (s->bbio != NULL) {
+ if (ssl->bbio != NULL) {
/* If the buffering BIO is in place, pop it off */
- if (s->bbio == s->wbio) {
- s->wbio = BIO_pop(s->wbio);
+ if (ssl->bbio == ssl->wbio) {
+ ssl->wbio = BIO_pop(ssl->wbio);
}
- BIO_free(s->bbio);
- s->bbio = NULL;
+ BIO_free(ssl->bbio);
+ ssl->bbio = NULL;
}
- int free_wbio = s->wbio != s->rbio;
- BIO_free_all(s->rbio);
+ int free_wbio = ssl->wbio != ssl->rbio;
+ BIO_free_all(ssl->rbio);
if (free_wbio) {
- BIO_free_all(s->wbio);
+ BIO_free_all(ssl->wbio);
}
- BUF_MEM_free(s->init_buf);
+ BUF_MEM_free(ssl->init_buf);
/* add extra stuff */
- ssl_cipher_preference_list_free(s->cipher_list);
- sk_SSL_CIPHER_free(s->cipher_list_by_id);
+ ssl_cipher_preference_list_free(ssl->cipher_list);
+ sk_SSL_CIPHER_free(ssl->cipher_list_by_id);
- ssl_clear_bad_session(s);
- SSL_SESSION_free(s->session);
+ ssl_clear_bad_session(ssl);
+ SSL_SESSION_free(ssl->session);
- ssl_clear_cipher_ctx(s);
+ ssl_clear_cipher_ctx(ssl);
- ssl_cert_free(s->cert);
+ ssl_cert_free(ssl->cert);
- OPENSSL_free(s->tlsext_hostname);
- SSL_CTX_free(s->initial_ctx);
- OPENSSL_free(s->tlsext_ecpointformatlist);
- OPENSSL_free(s->tlsext_ellipticcurvelist);
- OPENSSL_free(s->alpn_client_proto_list);
- EVP_PKEY_free(s->tlsext_channel_id_private);
- OPENSSL_free(s->psk_identity_hint);
- sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
- OPENSSL_free(s->next_proto_negotiated);
- sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
+ OPENSSL_free(ssl->tlsext_hostname);
+ SSL_CTX_free(ssl->initial_ctx);
+ OPENSSL_free(ssl->tlsext_ecpointformatlist);
+ OPENSSL_free(ssl->tlsext_ellipticcurvelist);
+ OPENSSL_free(ssl->alpn_client_proto_list);
+ EVP_PKEY_free(ssl->tlsext_channel_id_private);
+ OPENSSL_free(ssl->psk_identity_hint);
+ sk_X509_NAME_pop_free(ssl->client_CA, X509_NAME_free);
+ OPENSSL_free(ssl->next_proto_negotiated);
+ sk_SRTP_PROTECTION_PROFILE_free(ssl->srtp_profiles);
- if (s->method != NULL) {
- s->method->ssl_free(s);
+ if (ssl->method != NULL) {
+ ssl->method->ssl_free(ssl);
}
- SSL_CTX_free(s->ctx);
+ SSL_CTX_free(ssl->ctx);
- OPENSSL_free(s);
+ OPENSSL_free(ssl);
}
void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) {
@@ -1626,10 +1626,10 @@
return memcmp(a->session_id, b->session_id, a->session_id_length);
}
-SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) {
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
SSL_CTX *ret = NULL;
- if (meth == NULL) {
+ if (method == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_NULL_SSL_METHOD_PASSED);
return NULL;
}
@@ -1646,7 +1646,7 @@
memset(ret, 0, sizeof(SSL_CTX));
- ret->method = meth->method;
+ ret->method = method->method;
CRYPTO_MUTEX_init(&ret->lock);
@@ -1742,9 +1742,9 @@
/* Lock the SSL_CTX to the specified version, for compatibility with legacy
* uses of SSL_METHOD. */
- if (meth->version != 0) {
- SSL_CTX_set_max_version(ret, meth->version);
- SSL_CTX_set_min_version(ret, meth->version);
+ if (method->version != 0) {
+ SSL_CTX_set_max_version(ret, method->version);
+ SSL_CTX_set_min_version(ret, method->version);
}
return ret;
@@ -2132,22 +2132,22 @@
return ret;
}
-void SSL_set_accept_state(SSL *s) {
- s->server = 1;
- s->shutdown = 0;
- s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE;
- s->handshake_func = s->method->ssl_accept;
+void SSL_set_accept_state(SSL *ssl) {
+ ssl->server = 1;
+ ssl->shutdown = 0;
+ ssl->state = SSL_ST_ACCEPT | SSL_ST_BEFORE;
+ ssl->handshake_func = ssl->method->ssl_accept;
/* clear the current cipher */
- ssl_clear_cipher_ctx(s);
+ ssl_clear_cipher_ctx(ssl);
}
-void SSL_set_connect_state(SSL *s) {
- s->server = 0;
- s->shutdown = 0;
- s->state = SSL_ST_CONNECT | SSL_ST_BEFORE;
- s->handshake_func = s->method->ssl_connect;
+void SSL_set_connect_state(SSL *ssl) {
+ ssl->server = 0;
+ ssl->shutdown = 0;
+ ssl->state = SSL_ST_CONNECT | SSL_ST_BEFORE;
+ ssl->handshake_func = ssl->method->ssl_connect;
/* clear the current cipher */
- ssl_clear_cipher_ctx(s);
+ ssl_clear_cipher_ctx(ssl);
}
static const char *ssl_get_version(int version) {