#endif
#include <stdio.h>
#include "ssl_locl.h"
-#include "kssl_lcl.h"
#include <openssl/objects.h>
#include <openssl/lhash.h>
#include <openssl/x509v3.h>
int SSL_clear(SSL *s)
{
-
if (s->method == NULL) {
SSLerr(SSL_F_SSL_CLEAR, SSL_R_NO_METHOD_SPECIFIED);
return (0);
s->hit = 0;
s->shutdown = 0;
-#if 0
- /*
- * Disabled since version 1.10 of this file (early return not
- * needed because SSL_clear is not called when doing renegotiation)
- */
- /*
- * This is set if we are doing dynamic renegotiation so keep
- * the old cipher. It is sort of a SSL_clear_lite :-)
- */
- if (s->renegotiate)
- return (1);
-#else
if (s->renegotiate) {
SSLerr(SSL_F_SSL_CLEAR, ERR_R_INTERNAL_ERROR);
return 0;
}
-#endif
s->type = 0;
s->version = s->method->version;
s->client_version = s->version;
s->rwstate = SSL_NOTHING;
- s->rstate = SSL_ST_READ_HEADER;
-#if 0
- s->read_ahead = s->ctx->read_ahead;
-#endif
-
- if (s->init_buf != NULL) {
- BUF_MEM_free(s->init_buf);
- s->init_buf = NULL;
- }
+ BUF_MEM_free(s->init_buf);
+ s->init_buf = NULL;
ssl_clear_cipher_ctx(s);
ssl_clear_hash_ctx(&s->read_hash);
ssl_clear_hash_ctx(&s->write_hash);
-
s->first_packet = 0;
-#if 1
/*
* Check to see if we were changed into a different method, if so, revert
* back if we are not doing session-id reuse.
if (!s->method->ssl_new(s))
return (0);
} else
-#endif
s->method->ssl_clear(s);
+
+ RECORD_LAYER_clear(&s->rlayer);
+
return (1);
}
return (NULL);
}
- s = (SSL *)OPENSSL_malloc(sizeof(SSL));
+ s = OPENSSL_malloc(sizeof(*s));
if (s == NULL)
goto err;
- memset(s, 0, sizeof(SSL));
+ memset(s, 0, sizeof(*s));
-#ifndef OPENSSL_NO_KRB5
- s->kssl_ctx = kssl_ctx_new();
-#endif /* OPENSSL_NO_KRB5 */
+ RECORD_LAYER_init(&s->rlayer, s);
s->options = ctx->options;
s->mode = ctx->mode;
s->max_cert_list = ctx->max_cert_list;
- if (ctx->cert != NULL) {
- /*
- * Earlier library versions used to copy the pointer to the CERT, not
- * its contents; only when setting new parameters for the per-SSL
- * copy, ssl_cert_new would be called (and the direct reference to
- * the per-SSL_CTX settings would be lost, but those still were
- * indirectly accessed for various purposes, and for that reason they
- * used to be known as s->ctx->default_cert). Now we don't look at the
- * SSL_CTX's CERT after having duplicated it once.
- */
-
- s->cert = ssl_cert_dup(ctx->cert);
- if (s->cert == NULL)
- goto err;
- } else
- s->cert = NULL; /* Cannot really happen (see SSL_CTX_new) */
+ /*
+ * Earlier library versions used to copy the pointer to the CERT, not
+ * its contents; only when setting new parameters for the per-SSL
+ * copy, ssl_cert_new would be called (and the direct reference to
+ * the per-SSL_CTX settings would be lost, but those still were
+ * indirectly accessed for various purposes, and for that reason they
+ * used to be known as s->ctx->default_cert). Now we don't look at the
+ * SSL_CTX's CERT after having duplicated it once.
+ */
+ s->cert = ssl_cert_dup(ctx->cert);
+ if (s->cert == NULL)
+ goto err;
- s->read_ahead = ctx->read_ahead;
+ RECORD_LAYER_set_read_ahead(&s->rlayer, ctx->read_ahead);
s->msg_callback = ctx->msg_callback;
s->msg_callback_arg = ctx->msg_callback_arg;
s->verify_mode = ctx->verify_mode;
s->not_resumable_session_cb = ctx->not_resumable_session_cb;
-#if 0
- s->verify_depth = ctx->verify_depth;
-#endif
s->sid_ctx_length = ctx->sid_ctx_length;
OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx);
memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx));
if (!s->param)
goto err;
X509_VERIFY_PARAM_inherit(s->param, ctx->param);
-#if 0
- s->purpose = ctx->purpose;
- s->trust = ctx->trust;
-#endif
s->quiet_shutdown = ctx->quiet_shutdown;
s->max_send_fragment = ctx->max_send_fragment;
CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
s->ctx = ctx;
-#ifndef OPENSSL_NO_TLSEXT
s->tlsext_debug_cb = 0;
s->tlsext_debug_arg = NULL;
s->tlsext_ticket_expected = 0;
s->ctx->alpn_client_proto_list_len);
s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
}
-#endif
s->verify_result = X509_V_OK;
s->references = 1;
s->server = (ctx->method->ssl_accept == ssl_undefined_function) ? 0 : 1;
- SSL_clear(s);
+ if (!SSL_clear(s))
+ goto err;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
return (s);
err:
- if (s != NULL)
- SSL_free(s);
+ SSL_free(s);
SSLerr(SSL_F_SSL_NEW, ERR_R_MALLOC_FAILURE);
return (NULL);
}
}
#endif
- if (s->param)
- X509_VERIFY_PARAM_free(s->param);
-
+ X509_VERIFY_PARAM_free(s->param);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
if (s->bbio != NULL) {
BIO_free(s->bbio);
s->bbio = NULL;
}
- if (s->rbio != NULL)
- BIO_free_all(s->rbio);
- if ((s->wbio != NULL) && (s->wbio != s->rbio))
+ BIO_free_all(s->rbio);
+ if (s->wbio != s->rbio)
BIO_free_all(s->wbio);
- if (s->init_buf != NULL)
- BUF_MEM_free(s->init_buf);
+ BUF_MEM_free(s->init_buf);
/* add extra stuff */
- if (s->cipher_list != NULL)
- sk_SSL_CIPHER_free(s->cipher_list);
- if (s->cipher_list_by_id != NULL)
- sk_SSL_CIPHER_free(s->cipher_list_by_id);
+ sk_SSL_CIPHER_free(s->cipher_list);
+ sk_SSL_CIPHER_free(s->cipher_list_by_id);
/* Make the next call work :-) */
if (s->session != NULL) {
ssl_clear_hash_ctx(&s->read_hash);
ssl_clear_hash_ctx(&s->write_hash);
- if (s->cert != NULL)
- ssl_cert_free(s->cert);
+ ssl_cert_free(s->cert);
/* Free up if allocated */
-#ifndef OPENSSL_NO_TLSEXT
- if (s->tlsext_hostname)
- OPENSSL_free(s->tlsext_hostname);
- if (s->initial_ctx)
- SSL_CTX_free(s->initial_ctx);
-# ifndef OPENSSL_NO_EC
- if (s->tlsext_ecpointformatlist)
- OPENSSL_free(s->tlsext_ecpointformatlist);
- if (s->tlsext_ellipticcurvelist)
- OPENSSL_free(s->tlsext_ellipticcurvelist);
-# endif /* OPENSSL_NO_EC */
- if (s->tlsext_ocsp_exts)
- sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free);
- if (s->tlsext_ocsp_ids)
- sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
- if (s->tlsext_ocsp_resp)
- OPENSSL_free(s->tlsext_ocsp_resp);
- if (s->alpn_client_proto_list)
- OPENSSL_free(s->alpn_client_proto_list);
-#endif
+ OPENSSL_free(s->tlsext_hostname);
+ SSL_CTX_free(s->initial_ctx);
+#ifndef OPENSSL_NO_EC
+ OPENSSL_free(s->tlsext_ecpointformatlist);
+ OPENSSL_free(s->tlsext_ellipticcurvelist);
+#endif /* OPENSSL_NO_EC */
+ sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free);
+ sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
+ OPENSSL_free(s->tlsext_ocsp_resp);
+ OPENSSL_free(s->alpn_client_proto_list);
- if (s->client_CA != NULL)
- sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
+ sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
if (s->method != NULL)
s->method->ssl_free(s);
- if (s->ctx)
- SSL_CTX_free(s->ctx);
+ RECORD_LAYER_release(&s->rlayer);
-#ifndef OPENSSL_NO_KRB5
- if (s->kssl_ctx != NULL)
- kssl_ctx_free(s->kssl_ctx);
-#endif /* OPENSSL_NO_KRB5 */
+ SSL_CTX_free(s->ctx);
-#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
- if (s->next_proto_negotiated)
- OPENSSL_free(s->next_proto_negotiated);
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
+ OPENSSL_free(s->next_proto_negotiated);
#endif
#ifndef OPENSSL_NO_SRTP
- if (s->srtp_profiles)
- sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
+ sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
#endif
OPENSSL_free(s);
}
-void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio)
+void SSL_set_rbio(SSL *s, BIO *rbio)
+{
+ if (s->rbio != rbio)
+ BIO_free_all(s->rbio);
+ s->rbio = rbio;
+}
+
+void SSL_set_wbio(SSL *s, BIO *wbio)
{
/*
* If the output buffering BIO is still in place, remove it
s->bbio->next_bio = NULL;
}
}
- if ((s->rbio != NULL) && (s->rbio != rbio))
- BIO_free_all(s->rbio);
- if ((s->wbio != NULL) && (s->wbio != wbio) && (s->rbio != s->wbio))
+ if (s->wbio != wbio && s->rbio != s->wbio)
BIO_free_all(s->wbio);
- s->rbio = rbio;
s->wbio = wbio;
}
+void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio)
+{
+ SSL_set_wbio(s, wbio);
+ SSL_set_rbio(s, rbio);
+}
+
BIO *SSL_get_rbio(const SSL *s)
{
return (s->rbio);
void SSL_set_read_ahead(SSL *s, int yes)
{
- s->read_ahead = yes;
+ RECORD_LAYER_set_read_ahead(&s->rlayer, yes);
}
int SSL_get_read_ahead(const SSL *s)
{
- return (s->read_ahead);
+ return RECORD_LAYER_get_read_ahead(&s->rlayer);
}
int SSL_pending(const SSL *s)
* Now in theory, since the calling process own 't' it should be safe to
* modify. We need to be able to read f without being hassled
*/
-void SSL_copy_session_id(SSL *t, const SSL *f)
+int SSL_copy_session_id(SSL *t, const SSL *f)
{
- CERT *tmp;
-
/* Do we need to to SSL locking? */
- SSL_set_session(t, SSL_get_session(f));
+ if (!SSL_set_session(t, SSL_get_session(f))) {
+ return 0;
+ }
/*
* what if we are setup as SSLv2 but want to talk SSLv3 or vice-versa
t->method->ssl_new(t); /* setup new */
}
- tmp = t->cert;
- if (f->cert != NULL) {
- CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT);
- t->cert = f->cert;
- } else
- t->cert = NULL;
- if (tmp != NULL)
- ssl_cert_free(tmp);
- SSL_set_session_id_context(t, f->sid_ctx, f->sid_ctx_length);
+ CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT);
+ ssl_cert_free(t->cert);
+ t->cert = f->cert;
+ if (!SSL_set_session_id_context(t, f->sid_ctx, f->sid_ctx_length)) {
+ return 0;
+ }
+
+ return 1;
}
/* Fix this so it checks all the valid key/cert options */
int SSL_CTX_check_private_key(const SSL_CTX *ctx)
{
if ((ctx == NULL) ||
- (ctx->cert == NULL) || (ctx->cert->key->x509 == NULL)) {
+ (ctx->cert->key->x509 == NULL)) {
SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY,
SSL_R_NO_CERTIFICATE_ASSIGNED);
return (0);
SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
return (0);
}
- if (ssl->cert == NULL) {
- SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED);
- return 0;
- }
if (ssl->cert->key->x509 == NULL) {
SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED);
return (0);
switch (cmd) {
case SSL_CTRL_GET_READ_AHEAD:
- return (s->read_ahead);
+ return (RECORD_LAYER_get_read_ahead(&s->rlayer));
case SSL_CTRL_SET_READ_AHEAD:
- l = s->read_ahead;
- s->read_ahead = larg;
+ l = RECORD_LAYER_get_read_ahead(&s->rlayer);
+ RECORD_LAYER_set_read_ahead(&s->rlayer, larg);
return (l);
case SSL_CTRL_SET_MSG_CALLBACK_ARG:
case SSL_CTRL_GET_RAW_CIPHERLIST:
if (parg) {
- if (s->cert->ciphers_raw == NULL)
+ if (s->s3->tmp.ciphers_raw == NULL)
return 0;
- *(unsigned char **)parg = s->cert->ciphers_raw;
- return (int)s->cert->ciphers_rawlen;
+ *(unsigned char **)parg = s->s3->tmp.ciphers_raw;
+ return (int)s->s3->tmp.ciphers_rawlen;
} else
return ssl_put_cipher_by_char(s, NULL, NULL);
case SSL_CTRL_GET_EXTMS_SUPPORT:
- if (s->session && s->session->flags & SSL_SESS_FLAG_EXTMS)
+ if (!s->session || SSL_in_init(s) || s->in_handshake)
+ return -1;
+ if (s->session->flags & SSL_SESS_FLAG_EXTMS)
return 1;
else
return 0;
return (NULL);
}
+STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s)
+{
+ if ((s == NULL) || (s->session == NULL) || !s->server)
+ return NULL;
+ return s->session->ciphers;
+}
+
STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s)
{
STACK_OF(SSL_CIPHER) *sk = NULL, *ciphers;
return (buf);
}
-int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk,
- unsigned char *p,
- int (*put_cb) (const SSL_CIPHER *,
- unsigned char *))
-{
- int i, j = 0;
- SSL_CIPHER *c;
- unsigned char *q;
- int empty_reneg_info_scsv = !s->renegotiate;
- /* Set disabled masks for this session */
- ssl_set_client_disabled(s);
-
- if (sk == NULL)
- return (0);
- q = p;
- if (put_cb == NULL)
- put_cb = s->method->put_cipher_by_char;
-
- for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
- c = sk_SSL_CIPHER_value(sk, i);
- /* Skip disabled ciphers */
- if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED))
- continue;
-#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
- if (c->id == SSL3_CK_SCSV) {
- if (!empty_reneg_info_scsv)
- continue;
- else
- empty_reneg_info_scsv = 0;
- }
-#endif
- j = put_cb(c, p);
- p += j;
- }
- /*
- * If p == q, no ciphers; caller indicates an error. Otherwise, add
- * applicable SCSVs.
- */
- if (p != q) {
- if (empty_reneg_info_scsv) {
- static SSL_CIPHER scsv = {
- 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- j = put_cb(&scsv, p);
- p += j;
-#ifdef OPENSSL_RI_DEBUG
- fprintf(stderr,
- "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n");
-#endif
- }
- if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) {
- static SSL_CIPHER scsv = {
- 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- j = put_cb(&scsv, p);
- p += j;
- }
- }
-
- return (p - q);
-}
-
-STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p,
- int num,
- STACK_OF(SSL_CIPHER) **skp)
-{
- const SSL_CIPHER *c;
- STACK_OF(SSL_CIPHER) *sk;
- int i, n;
-
- if (s->s3)
- s->s3->send_connection_binding = 0;
-
- n = ssl_put_cipher_by_char(s, NULL, NULL);
- if (n == 0 || (num % n) != 0) {
- SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
- SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
- return (NULL);
- }
- if ((skp == NULL) || (*skp == NULL))
- sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */
- else {
- sk = *skp;
- sk_SSL_CIPHER_zero(sk);
- }
-
- if (s->cert->ciphers_raw)
- OPENSSL_free(s->cert->ciphers_raw);
- s->cert->ciphers_raw = BUF_memdup(p, num);
- if (s->cert->ciphers_raw == NULL) {
- SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- s->cert->ciphers_rawlen = (size_t)num;
-
- for (i = 0; i < num; i += n) {
- /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
- if (s->s3 && (n != 3 || !p[0]) &&
- (p[n - 2] == ((SSL3_CK_SCSV >> 8) & 0xff)) &&
- (p[n - 1] == (SSL3_CK_SCSV & 0xff))) {
- /* SCSV fatal if renegotiating */
- if (s->renegotiate) {
- SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
- SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
- goto err;
- }
- s->s3->send_connection_binding = 1;
- p += n;
-#ifdef OPENSSL_RI_DEBUG
- fprintf(stderr, "SCSV received by server\n");
-#endif
- continue;
- }
-
- /* Check for TLS_FALLBACK_SCSV */
- if ((n != 3 || !p[0]) &&
- (p[n - 2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) &&
- (p[n - 1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) {
- /*
- * The SCSV indicates that the client previously tried a higher
- * version. Fail if the current version is an unexpected
- * downgrade.
- */
- if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) {
- SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
- SSL_R_INAPPROPRIATE_FALLBACK);
- if (s->s3)
- ssl3_send_alert(s, SSL3_AL_FATAL,
- SSL_AD_INAPPROPRIATE_FALLBACK);
- goto err;
- }
- p += n;
- continue;
- }
-
- c = ssl_get_cipher_by_char(s, p);
- p += n;
- if (c != NULL) {
- if (!sk_SSL_CIPHER_push(sk, c)) {
- SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
- }
-
- if (skp != NULL)
- *skp = sk;
- return (sk);
- err:
- if ((skp == NULL) || (*skp == NULL))
- sk_SSL_CIPHER_free(sk);
- return (NULL);
-}
-
-#ifndef OPENSSL_NO_TLSEXT
/** return a servername extension value if provided in Client Hello, or NULL.
* So far, only host_name types are defined (RFC 3546).
*/
return status;
}
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#ifndef OPENSSL_NO_NEXTPROTONEG
/*
* SSL_get0_next_proto_negotiated sets *data and *len to point to the
* client's requested protocol for this connection and returns 0. If the
ctx->next_proto_select_cb = cb;
ctx->next_proto_select_cb_arg = arg;
}
-# endif
+#endif
/*
* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
unsigned protos_len)
{
- if (ctx->alpn_client_proto_list)
- OPENSSL_free(ctx->alpn_client_proto_list);
-
+ OPENSSL_free(ctx->alpn_client_proto_list);
ctx->alpn_client_proto_list = OPENSSL_malloc(protos_len);
if (!ctx->alpn_client_proto_list)
return 1;
int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos,
unsigned protos_len)
{
- if (ssl->alpn_client_proto_list)
- OPENSSL_free(ssl->alpn_client_proto_list);
-
+ OPENSSL_free(ssl->alpn_client_proto_list);
ssl->alpn_client_proto_list = OPENSSL_malloc(protos_len);
if (!ssl->alpn_client_proto_list)
return 1;
*len = ssl->s3->alpn_selected_len;
}
-#endif /* !OPENSSL_NO_TLSEXT */
int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
const char *label, size_t llen,
SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
goto err;
}
- ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
+ ret = OPENSSL_malloc(sizeof(*ret));
if (ret == NULL)
goto err;
- memset(ret, 0, sizeof(SSL_CTX));
+ memset(ret, 0, sizeof(*ret));
ret->method = meth;
ret->get_session_cb = 0;
ret->generate_session_id = 0;
- memset((char *)&ret->stats, 0, sizeof(ret->stats));
+ memset(&ret->stats, 0, sizeof(ret->stats));
ret->references = 1;
ret->quiet_shutdown = 0;
-
-/* ret->cipher=NULL;*/
-/*-
- ret->s2->challenge=NULL;
- ret->master_key=NULL;
- ret->s2->conn_id=NULL; */
-
ret->info_callback = NULL;
-
ret->app_verify_callback = 0;
ret->app_verify_arg = NULL;
-
ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
ret->read_ahead = 0;
ret->msg_callback = 0;
ret->msg_callback_arg = NULL;
ret->verify_mode = SSL_VERIFY_NONE;
-#if 0
- ret->verify_depth = -1; /* Don't impose a limit (but x509_lu.c does) */
-#endif
ret->sid_ctx_length = 0;
ret->default_verify_callback = NULL;
if ((ret->cert = ssl_cert_new()) == NULL)
if (ret->cert_store == NULL)
goto err;
- ssl_create_cipher_list(ret->method,
+ if (!ssl_create_cipher_list(ret->method,
&ret->cipher_list, &ret->cipher_list_by_id,
- SSL_DEFAULT_CIPHER_LIST, ret->cert);
- if (ret->cipher_list == NULL || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) {
+ SSL_DEFAULT_CIPHER_LIST, ret->cert)
+ || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) {
SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_LIBRARY_HAS_NO_CIPHERS);
goto err2;
}
ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
-#ifndef OPENSSL_NO_TLSEXT
ret->tlsext_servername_callback = 0;
ret->tlsext_servername_arg = NULL;
/* Setup RFC4507 ticket keys */
- if ((RAND_pseudo_bytes(ret->tlsext_tick_key_name, 16) <= 0)
+ if ((RAND_bytes(ret->tlsext_tick_key_name, 16) <= 0)
|| (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0)
|| (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0))
ret->options |= SSL_OP_NO_TICKET;
ret->tlsext_status_cb = 0;
ret->tlsext_status_arg = NULL;
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#ifndef OPENSSL_NO_NEXTPROTONEG
ret->next_protos_advertised_cb = 0;
ret->next_proto_select_cb = 0;
-# endif
#endif
#ifndef OPENSSL_NO_PSK
ret->psk_identity_hint = NULL;
ret->psk_server_callback = NULL;
#endif
#ifndef OPENSSL_NO_SRP
- SSL_CTX_SRP_CTX_init(ret);
+ if (!SSL_CTX_SRP_CTX_init(ret))
+ goto err;
#endif
#ifndef OPENSSL_NO_ENGINE
ret->client_cert_engine = NULL;
err:
SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE);
err2:
- if (ret != NULL)
- SSL_CTX_free(ret);
+ SSL_CTX_free(ret);
return (NULL);
}
}
#endif
- if (a->param)
- X509_VERIFY_PARAM_free(a->param);
+ X509_VERIFY_PARAM_free(a->param);
/*
* Free internal session cache. However: the remove_cb() may reference
SSL_CTX_flush_sessions(a, 0);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data);
-
- if (a->sessions != NULL)
- lh_SSL_SESSION_free(a->sessions);
-
- if (a->cert_store != NULL)
- X509_STORE_free(a->cert_store);
- if (a->cipher_list != NULL)
- sk_SSL_CIPHER_free(a->cipher_list);
- if (a->cipher_list_by_id != NULL)
- sk_SSL_CIPHER_free(a->cipher_list_by_id);
- if (a->cert != NULL)
- ssl_cert_free(a->cert);
- if (a->client_CA != NULL)
- sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free);
- if (a->extra_certs != NULL)
- sk_X509_pop_free(a->extra_certs, X509_free);
-#if 0 /* This should never be done, since it
- * removes a global database */
- if (a->comp_methods != NULL)
- sk_SSL_COMP_pop_free(a->comp_methods, SSL_COMP_free);
-#else
+ lh_SSL_SESSION_free(a->sessions);
+ X509_STORE_free(a->cert_store);
+ sk_SSL_CIPHER_free(a->cipher_list);
+ sk_SSL_CIPHER_free(a->cipher_list_by_id);
+ ssl_cert_free(a->cert);
+ sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free);
+ sk_X509_pop_free(a->extra_certs, X509_free);
a->comp_methods = NULL;
-#endif
-
#ifndef OPENSSL_NO_SRTP
- if (a->srtp_profiles)
- sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
+ sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
#endif
-
#ifndef OPENSSL_NO_PSK
- if (a->psk_identity_hint)
- OPENSSL_free(a->psk_identity_hint);
+ OPENSSL_free(a->psk_identity_hint);
#endif
#ifndef OPENSSL_NO_SRP
SSL_CTX_SRP_CTX_free(a);
ENGINE_finish(a->client_cert_engine);
#endif
-#ifndef OPENSSL_NO_TLSEXT
-# ifndef OPENSSL_NO_EC
- if (a->tlsext_ecpointformatlist)
- OPENSSL_free(a->tlsext_ecpointformatlist);
- if (a->tlsext_ellipticcurvelist)
- OPENSSL_free(a->tlsext_ellipticcurvelist);
-# endif /* OPENSSL_NO_EC */
- if (a->alpn_client_proto_list != NULL)
- OPENSSL_free(a->alpn_client_proto_list);
+#ifndef OPENSSL_NO_EC
+ OPENSSL_free(a->tlsext_ecpointformatlist);
+ OPENSSL_free(a->tlsext_ellipticcurvelist);
#endif
+ OPENSSL_free(a->alpn_client_proto_list);
OPENSSL_free(a);
}
ssl_cert_set_cert_cb(s->cert, cb, arg);
}
-void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
+void ssl_set_masks(SSL *s, const SSL_CIPHER *cipher)
{
CERT_PKEY *cpk;
+ CERT *c = s->cert;
+ int *pvalid = s->s3->tmp.valid_flags;
int rsa_enc, rsa_tmp, rsa_sign, dh_tmp, dh_rsa, dh_dsa, dsa_sign;
int rsa_enc_export, dh_rsa_export, dh_dsa_export;
int rsa_tmp_export, dh_tmp_export, kl;
unsigned long mask_k, mask_a, emask_k, emask_a;
-#ifndef OPENSSL_NO_ECDSA
+#ifndef OPENSSL_NO_EC
int have_ecc_cert, ecdsa_ok, ecc_pkey_size;
-#endif
-#ifndef OPENSSL_NO_ECDH
int have_ecdh_tmp, ecdh_ok;
-#endif
-#ifndef OPENSSL_NO_EC
X509 *x = NULL;
EVP_PKEY *ecc_pkey = NULL;
int signature_nid = 0, pk_nid = 0, md_nid = 0;
dh_tmp = dh_tmp_export = 0;
#endif
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
have_ecdh_tmp = (c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto);
#endif
cpk = &(c->pkeys[SSL_PKEY_RSA_ENC]);
- rsa_enc = cpk->valid_flags & CERT_PKEY_VALID;
+ rsa_enc = pvalid[SSL_PKEY_RSA_ENC] & CERT_PKEY_VALID;
rsa_enc_export = (rsa_enc && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
cpk = &(c->pkeys[SSL_PKEY_RSA_SIGN]);
- rsa_sign = cpk->valid_flags & CERT_PKEY_SIGN;
+ rsa_sign = pvalid[SSL_PKEY_RSA_SIGN] & CERT_PKEY_SIGN;
cpk = &(c->pkeys[SSL_PKEY_DSA_SIGN]);
- dsa_sign = cpk->valid_flags & CERT_PKEY_SIGN;
+ dsa_sign = pvalid[SSL_PKEY_DSA_SIGN] & CERT_PKEY_SIGN;
cpk = &(c->pkeys[SSL_PKEY_DH_RSA]);
- dh_rsa = cpk->valid_flags & CERT_PKEY_VALID;
+ dh_rsa = pvalid[SSL_PKEY_DH_RSA] & CERT_PKEY_VALID;
dh_rsa_export = (dh_rsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
cpk = &(c->pkeys[SSL_PKEY_DH_DSA]);
-/* FIX THIS EAY EAY EAY */
- dh_dsa = cpk->valid_flags & CERT_PKEY_VALID;
+ dh_dsa = pvalid[SSL_PKEY_DH_DSA] & CERT_PKEY_VALID;
dh_dsa_export = (dh_dsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
cpk = &(c->pkeys[SSL_PKEY_ECC]);
#ifndef OPENSSL_NO_EC
- have_ecc_cert = cpk->valid_flags & CERT_PKEY_VALID;
+ have_ecc_cert = pvalid[SSL_PKEY_ECC] & CERT_PKEY_VALID;
#endif
mask_k = 0;
mask_a = 0;
if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc)))
emask_k |= SSL_kRSA;
-#if 0
- /* The match needs to be both kDHE and aRSA or aDSA, so don't worry */
- if ((dh_tmp || dh_rsa || dh_dsa) && (rsa_enc || rsa_sign || dsa_sign))
- mask_k |= SSL_kDHE;
- if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) &&
- (rsa_enc || rsa_sign || dsa_sign))
- emask_k |= SSL_kDHE;
-#endif
-
if (dh_tmp_export)
emask_k |= SSL_kDHE;
if (dh_dsa_export)
emask_k |= SSL_kDHd;
- if (emask_k & (SSL_kDHr | SSL_kDHd))
+ if (mask_k & (SSL_kDHr | SSL_kDHd))
mask_a |= SSL_aDH;
if (rsa_enc || rsa_sign) {
mask_a |= SSL_aNULL;
emask_a |= SSL_aNULL;
-#ifndef OPENSSL_NO_KRB5
- mask_k |= SSL_kKRB5;
- mask_a |= SSL_aKRB5;
- emask_k |= SSL_kKRB5;
- emask_a |= SSL_aKRB5;
-#endif
-
/*
* An ECC certificate may be usable for ECDH and/or ECDSA cipher suites
* depending on the key usage extension.
x = cpk->x509;
/* This call populates extension flags (ex_flags) */
X509_check_purpose(x, -1, 0);
-# ifndef OPENSSL_NO_ECDH
ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
(x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1;
-# endif
ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
(x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1;
- if (!(cpk->valid_flags & CERT_PKEY_SIGN))
+ if (!(pvalid[SSL_PKEY_ECC] & CERT_PKEY_SIGN))
ecdsa_ok = 0;
ecc_pkey = X509_get_pubkey(x);
ecc_pkey_size = (ecc_pkey != NULL) ? EVP_PKEY_bits(ecc_pkey) : 0;
signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
}
-# ifndef OPENSSL_NO_ECDH
if (ecdh_ok) {
if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa) {
}
}
}
-# endif
-# ifndef OPENSSL_NO_ECDSA
if (ecdsa_ok) {
mask_a |= SSL_aECDSA;
emask_a |= SSL_aECDSA;
}
-# endif
}
#endif
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
if (have_ecdh_tmp) {
mask_k |= SSL_kECDHE;
emask_k |= SSL_kECDHE;
emask_a |= SSL_aPSK;
#endif
- c->mask_k = mask_k;
- c->mask_a = mask_a;
- c->export_mask_k = emask_k;
- c->export_mask_a = emask_a;
- c->valid = 1;
+ s->s3->tmp.mask_k = mask_k;
+ s->s3->tmp.mask_a = mask_a;
+ s->s3->tmp.export_mask_k = emask_k;
+ s->s3->tmp.export_mask_a = emask_a;
}
/* This handy macro borrowed from crypto/x509v3/v3_purp.c */
return idx;
}
-CERT_PKEY *ssl_get_server_send_pkey(const SSL *s)
+CERT_PKEY *ssl_get_server_send_pkey(SSL *s)
{
CERT *c;
int i;
c = s->cert;
if (!s->s3 || !s->s3->tmp.new_cipher)
return NULL;
- ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
+ ssl_set_masks(s, s->s3->tmp.new_cipher);
#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
/*
return (NULL);
}
if (pmd)
- *pmd = c->pkeys[idx].digest;
+ *pmd = s->s3->tmp.md[idx];
return c->pkeys[idx].privatekey;
}
-#ifndef OPENSSL_NO_TLSEXT
int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
size_t *serverinfo_length)
{
*serverinfo_length = c->pkeys[i].serverinfo_length;
return 1;
}
-#endif
void ssl_update_cache(SSL *s, int mode)
{
return ("TLSv1");
else if (s->version == SSL3_VERSION)
return ("SSLv3");
+ else if (s->version == DTLS1_BAD_VER)
+ return ("DTLSv0.9");
+ else if (s->version == DTLS1_VERSION)
+ return ("DTLSv1");
+ else if (s->version == DTLS1_2_VERSION)
+ return ("DTLSv1.2");
else
return ("unknown");
}
if (s->session != NULL) {
/* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */
- SSL_copy_session_id(ret, s);
+ if (!SSL_copy_session_id(ret, s))
+ goto err;
} else {
/*
* No session has been established yet, so we have to expect that
ret->method->ssl_new(ret);
if (s->cert != NULL) {
- if (ret->cert != NULL) {
- ssl_cert_free(ret->cert);
- }
+ ssl_cert_free(ret->cert);
ret->cert = ssl_cert_dup(s->cert);
if (ret->cert == NULL)
goto err;
}
- SSL_set_session_id_context(ret, s->sid_ctx, s->sid_ctx_length);
+ if (!SSL_set_session_id_context(ret, s->sid_ctx, s->sid_ctx_length))
+ goto err;
}
ret->options = s->options;
ret->shutdown = s->shutdown;
ret->state = s->state; /* SSL_dup does not really work at any state,
* though */
- ret->rstate = s->rstate;
+ RECORD_LAYER_dup(&ret->rlayer, &s->rlayer);
ret->init_num = 0; /* would have to copy ret->init_buf,
* ret->init_msg, ret->init_num,
* ret->init_off */
}
}
}
+ return ret;
- if (0) {
err:
- if (ret != NULL)
- SSL_free(ret);
- ret = NULL;
- }
- return (ret);
+ SSL_free(ret);
+ return NULL;
}
void ssl_clear_cipher_ctx(SSL *s)
s->enc_write_ctx = NULL;
}
#ifndef OPENSSL_NO_COMP
- if (s->expand != NULL) {
- COMP_CTX_free(s->expand);
- s->expand = NULL;
- }
- if (s->compress != NULL) {
- COMP_CTX_free(s->compress);
- s->compress = NULL;
- }
+ COMP_CTX_free(s->expand);
+ s->expand = NULL;
+ COMP_CTX_free(s->compress);
+ s->compress = NULL;
#endif
}
return (NULL);
}
-#ifdef OPENSSL_NO_COMP
-const void *SSL_get_current_compression(SSL *s)
-{
- return NULL;
-}
-
-const void *SSL_get_current_expansion(SSL *s)
-{
- return NULL;
-}
-#else
-
const COMP_METHOD *SSL_get_current_compression(SSL *s)
{
- if (s->compress != NULL)
- return (s->compress->meth);
- return (NULL);
+#ifndef OPENSSL_NO_COMP
+ return s->compress ? COMP_CTX_get_method(s->compress) : NULL;
+#else
+ return NULL;
+#endif
}
const COMP_METHOD *SSL_get_current_expansion(SSL *s)
{
- if (s->expand != NULL)
- return (s->expand->meth);
- return (NULL);
-}
+#ifndef OPENSSL_NO_COMP
+ return s->expand ? COMP_CTX_get_method(s->expand) : NULL;
+#else
+ return NULL;
#endif
+}
int ssl_init_wbio_buffer(SSL *s, int push)
{
void ssl_free_wbio_buffer(SSL *s)
{
+ /* callers ensure s is never null */
if (s->bbio == NULL)
return;
SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
{
- CERT *ocert = ssl->cert;
+ CERT *new_cert;
if (ssl->ctx == ctx)
return ssl->ctx;
-#ifndef OPENSSL_NO_TLSEXT
if (ctx == NULL)
ctx = ssl->initial_ctx;
-#endif
- ssl->cert = ssl_cert_dup(ctx->cert);
- if (ocert) {
- /* Preserve any already negotiated parameters */
- if (ssl->server) {
- ssl->cert->peer_sigalgs = ocert->peer_sigalgs;
- ssl->cert->peer_sigalgslen = ocert->peer_sigalgslen;
- ocert->peer_sigalgs = NULL;
- ssl->cert->ciphers_raw = ocert->ciphers_raw;
- ssl->cert->ciphers_rawlen = ocert->ciphers_rawlen;
- ocert->ciphers_raw = NULL;
- }
- ssl_cert_free(ocert);
+ new_cert = ssl_cert_dup(ctx->cert);
+ if (new_cert == NULL) {
+ return NULL;
}
+ ssl_cert_free(ssl->cert);
+ ssl->cert = new_cert;
/*
* Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH),
}
CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
- if (ssl->ctx != NULL)
- SSL_CTX_free(ssl->ctx); /* decrement reference count */
+ SSL_CTX_free(ssl->ctx); /* decrement reference count */
ssl->ctx = ctx;
return (ssl->ctx);
return (ssl->verify_result);
}
+size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, size_t outlen)
+{
+ if (outlen == 0)
+ return sizeof(ssl->s3->client_random);
+ if (outlen > sizeof(ssl->s3->client_random))
+ outlen = sizeof(ssl->s3->client_random);
+ memcpy(out, ssl->s3->client_random, outlen);
+ return outlen;
+}
+
+size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, size_t outlen)
+{
+ if (outlen == 0)
+ return sizeof(ssl->s3->server_random);
+ if (outlen > sizeof(ssl->s3->server_random))
+ outlen = sizeof(ssl->s3->server_random);
+ memcpy(out, ssl->s3->server_random, outlen);
+ return outlen;
+}
+
+size_t SSL_SESSION_get_master_key(const SSL_SESSION *session,
+ unsigned char *out, size_t outlen)
+{
+ if (session->master_key_length < 0) {
+ /* Should never happen */
+ return 0;
+ }
+ if (outlen == 0)
+ return session->master_key_length;
+ if (outlen > (size_t)session->master_key_length)
+ outlen = session->master_key_length;
+ memcpy(out, session->master_key, outlen);
+ return outlen;
+}
+
int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
{
void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store)
{
- if (ctx->cert_store != NULL)
- X509_STORE_free(ctx->cert_store);
+ X509_STORE_free(ctx->cert_store);
ctx->cert_store = store;
}
}
#endif
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
EC_KEY *(*ecdh) (SSL *ssl, int is_export,
int keylength))
SSL_R_DATA_LENGTH_TOO_LONG);
return 0;
}
- if (ctx->psk_identity_hint != NULL)
- OPENSSL_free(ctx->psk_identity_hint);
+ OPENSSL_free(ctx->psk_identity_hint);
if (identity_hint != NULL) {
ctx->psk_identity_hint = BUF_strdup(identity_hint);
if (ctx->psk_identity_hint == NULL)
SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG);
return 0;
}
- if (s->session->psk_identity_hint != NULL)
- OPENSSL_free(s->session->psk_identity_hint);
+ OPENSSL_free(s->session->psk_identity_hint);
if (identity_hint != NULL) {
s->session->psk_identity_hint = BUF_strdup(identity_hint);
if (s->session->psk_identity_hint == NULL)
return ctx->cert->sec_ex;
}
-IMPLEMENT_STACK_OF(SSL_CIPHER)
-
-IMPLEMENT_STACK_OF(SSL_COMP)
-
IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id);