* evil casts, but these functions are only called if there's a library
* bug
*/
- (int (*)(SSL *, SSL3_RECORD *, unsigned int, int))ssl_undefined_function,
+ (int (*)(SSL *, SSL3_RECORD *, size_t, int))ssl_undefined_function,
(int (*)(SSL *, SSL3_RECORD *, unsigned char *, int))ssl_undefined_function,
ssl_undefined_function,
- (int (*)(SSL *, unsigned char *, unsigned char *, int))
+ (int (*)(SSL *, unsigned char *, unsigned char *, size_t, size_t *))
ssl_undefined_function,
(int (*)(SSL *, int))ssl_undefined_function,
- (int (*)(SSL *, const char *, int, unsigned char *))
+ (size_t (*)(SSL *, const char *, size_t, unsigned char *))
ssl_undefined_function,
0, /* finish_mac_length */
NULL, /* client_finished_label */
SSL *s;
void *buf;
int num;
- enum { READFUNC, WRITEFUNC, OTHERFUNC} type;
+ enum { READFUNC, WRITEFUNC, OTHERFUNC } type;
union {
- int (*func_read)(SSL *, void *, int);
- int (*func_write)(SSL *, const void *, int);
- int (*func_other)(SSL *);
+ int (*func_read) (SSL *, void *, size_t, size_t *);
+ int (*func_write) (SSL *, const void *, size_t, size_t *);
+ int (*func_other) (SSL *);
} f;
};
static const struct {
uint8_t mtype;
uint8_t ord;
- int nid;
+ int nid;
} dane_mds[] = {
- { DANETLS_MATCHING_FULL, 0, NID_undef },
- { DANETLS_MATCHING_2256, 1, NID_sha256 },
- { DANETLS_MATCHING_2512, 2, NID_sha512 },
+ {
+ DANETLS_MATCHING_FULL, 0, NID_undef
+ },
+ {
+ DANETLS_MATCHING_2256, 1, NID_sha256
+ },
+ {
+ DANETLS_MATCHING_2512, 2, NID_sha512
+ },
};
static int dane_ctx_enable(struct dane_ctx_st *dctx)
const EVP_MD **mdevp;
uint8_t *mdord;
uint8_t mdmax = DANETLS_MATCHING_LAST;
- int n = ((int) mdmax) + 1; /* int to handle PrivMatch(255) */
+ int n = ((int)mdmax) + 1; /* int to handle PrivMatch(255) */
size_t i;
+ if (dctx->mdevp != NULL)
+ return 1;
+
mdevp = OPENSSL_zalloc(n * sizeof(*mdevp));
mdord = OPENSSL_zalloc(n * sizeof(*mdord));
return 1;
dane_final(&to->dane);
+ to->dane.flags = from->dane.flags;
to->dane.dctx = &to->ctx->dane;
to->dane.trecs = sk_danetls_record_new_null();
return 0;
}
- num = sk_danetls_record_num(from->dane.trecs);
+ num = sk_danetls_record_num(from->dane.trecs);
for (i = 0; i < num; ++i) {
danetls_record *t = sk_danetls_record_value(from->dane.trecs, i);
return 1;
}
-static int dane_mtype_set(
- struct dane_ctx_st *dctx,
- const EVP_MD *md,
- uint8_t mtype,
- uint8_t ord)
+static int dane_mtype_set(struct dane_ctx_st *dctx,
+ const EVP_MD *md, uint8_t mtype, uint8_t ord)
{
int i;
if (mtype == DANETLS_MATCHING_FULL && md != NULL) {
- SSLerr(SSL_F_DANE_MTYPE_SET,
- SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL);
+ SSLerr(SSL_F_DANE_MTYPE_SET, SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL);
return 0;
}
if (mtype > dctx->mdmax) {
const EVP_MD **mdevp;
uint8_t *mdord;
- int n = ((int) mtype) + 1;
+ int n = ((int)mtype) + 1;
mdevp = OPENSSL_realloc(dctx->mdevp, n * sizeof(*mdevp));
if (mdevp == NULL) {
dctx->mdord = mdord;
/* Zero-fill any gaps */
- for (i = dctx->mdmax+1; i < mtype; ++i) {
+ for (i = dctx->mdmax + 1; i < mtype; ++i) {
mdevp[i] = NULL;
mdord[i] = 0;
}
return dane->dctx->mdevp[mtype];
}
-static int dane_tlsa_add(
- SSL_DANE *dane,
- uint8_t usage,
- uint8_t selector,
- uint8_t mtype,
- unsigned char *data,
- size_t dlen)
+static int dane_tlsa_add(SSL_DANE *dane,
+ uint8_t usage,
+ uint8_t selector,
+ uint8_t mtype, unsigned char *data, size_t dlen)
{
danetls_record *t;
const EVP_MD *md = NULL;
&(ctx->cipher_list_by_id),
SSL_DEFAULT_CIPHER_LIST, ctx->cert);
if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) {
- SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION,
- SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS);
+ SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS);
return (0);
}
return (1);
RECORD_LAYER_init(&s->rlayer, s);
s->options = ctx->options;
+ s->dane.flags = ctx->dane.flags;
s->min_proto_version = ctx->min_proto_version;
s->max_proto_version = ctx->max_proto_version;
s->mode = ctx->mode;
s->tlsext_ocsp_resplen = -1;
SSL_CTX_up_ref(ctx);
s->initial_ctx = ctx;
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
if (ctx->tlsext_ecpointformatlist) {
s->tlsext_ecpointformatlist =
OPENSSL_memdup(ctx->tlsext_ecpointformatlist,
s->tlsext_ellipticcurvelist_length =
ctx->tlsext_ellipticcurvelist_length;
}
-# endif
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#endif
+#ifndef OPENSSL_NO_NEXTPROTONEG
s->next_proto_negotiated = NULL;
-# endif
+#endif
if (s->ctx->alpn_client_proto_list) {
s->alpn_client_proto_list =
#ifndef OPENSSL_NO_CT
if (!SSL_set_ct_validation_callback(s, ctx->ct_validation_callback,
- ctx->ct_validation_callback_arg))
+ ctx->ct_validation_callback_arg))
goto err;
#endif
return dane_ctx_enable(&ctx->dane);
}
+unsigned long SSL_CTX_dane_set_flags(SSL_CTX *ctx, unsigned long flags)
+{
+ unsigned long orig = ctx->dane.flags;
+
+ ctx->dane.flags |= flags;
+ return orig;
+}
+
+unsigned long SSL_CTX_dane_clear_flags(SSL_CTX *ctx, unsigned long flags)
+{
+ unsigned long orig = ctx->dane.flags;
+
+ ctx->dane.flags &= ~flags;
+ return orig;
+}
+
int SSL_dane_enable(SSL *s, const char *basedomain)
{
SSL_DANE *dane = &s->dane;
return 1;
}
+unsigned long SSL_dane_set_flags(SSL *ssl, unsigned long flags)
+{
+ unsigned long orig = ssl->dane.flags;
+
+ ssl->dane.flags |= flags;
+ return orig;
+}
+
+unsigned long SSL_dane_clear_flags(SSL *ssl, unsigned long flags)
+{
+ unsigned long orig = ssl->dane.flags;
+
+ ssl->dane.flags &= ~flags;
+ return orig;
+}
+
int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki)
{
SSL_DANE *dane = &s->dane;
return dane_tlsa_add(&s->dane, usage, selector, mtype, data, dlen);
}
-int SSL_CTX_dane_mtype_set(SSL_CTX *ctx, const EVP_MD *md, uint8_t mtype, uint8_t ord)
+int SSL_CTX_dane_mtype_set(SSL_CTX *ctx, const EVP_MD *md, uint8_t mtype,
+ uint8_t ord)
{
return dane_mtype_set(&ctx->dane, md, mtype, ord);
}
dane_final(&s->dane);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
- if (s->bbio != NULL) {
- /* If the buffering BIO is in place, pop it off */
- if (s->bbio == s->wbio) {
- s->wbio = BIO_pop(s->wbio);
- }
- BIO_free(s->bbio);
- s->bbio = NULL;
- }
- if (s->wbio != s->rbio)
- BIO_free_all(s->wbio);
+ ssl_free_wbio_buffer(s);
+
+ BIO_free_all(s->wbio);
BIO_free_all(s->rbio);
BUF_MEM_free(s->init_buf);
#ifndef OPENSSL_NO_EC
OPENSSL_free(s->tlsext_ecpointformatlist);
OPENSSL_free(s->tlsext_ellipticcurvelist);
-#endif /* OPENSSL_NO_EC */
+#endif /* OPENSSL_NO_EC */
sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free);
#ifndef OPENSSL_NO_OCSP
sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
OPENSSL_free(s);
}
-void SSL_set_rbio(SSL *s, BIO *rbio)
+void SSL_set0_rbio(SSL *s, BIO *rbio)
{
- if (s->rbio != rbio)
- BIO_free_all(s->rbio);
+ BIO_free_all(s->rbio);
s->rbio = rbio;
}
-void SSL_set_wbio(SSL *s, BIO *wbio)
+void SSL_set0_wbio(SSL *s, BIO *wbio)
{
/*
* If the output buffering BIO is still in place, remove it
*/
- if (s->bbio != NULL) {
- if (s->wbio == s->bbio) {
- s->wbio = BIO_next(s->wbio);
- BIO_set_next(s->bbio, NULL);
- }
- }
- if (s->wbio != wbio && s->rbio != s->wbio)
- BIO_free_all(s->wbio);
+ if (s->bbio != NULL)
+ s->wbio = BIO_pop(s->wbio);
+
+ BIO_free_all(s->wbio);
s->wbio = wbio;
+
+ /* Re-attach |bbio| to the new |wbio|. */
+ if (s->bbio != NULL)
+ s->wbio = BIO_push(s->bbio, s->wbio);
}
void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio)
{
- SSL_set_wbio(s, wbio);
- SSL_set_rbio(s, rbio);
+ /*
+ * For historical reasons, this function has many different cases in
+ * ownership handling.
+ */
+
+ /* If nothing has changed, do nothing */
+ if (rbio == SSL_get_rbio(s) && wbio == SSL_get_wbio(s))
+ return;
+
+ /*
+ * If the two arguments are equal then one fewer reference is granted by the
+ * caller than we want to take
+ */
+ if (rbio != NULL && rbio == wbio)
+ BIO_up_ref(rbio);
+
+ /*
+ * If only the wbio is changed only adopt one reference.
+ */
+ if (rbio == SSL_get_rbio(s)) {
+ SSL_set0_wbio(s, wbio);
+ return;
+ }
+ /*
+ * There is an asymmetry here for historical reasons. If only the rbio is
+ * changed AND the rbio and wbio were originally different, then we only
+ * adopt one reference.
+ */
+ if (wbio == SSL_get_wbio(s) && SSL_get_rbio(s) != SSL_get_wbio(s)) {
+ SSL_set0_rbio(s, rbio);
+ return;
+ }
+
+ /* Otherwise, adopt both references. */
+ SSL_set0_rbio(s, rbio);
+ SSL_set0_wbio(s, wbio);
}
BIO *SSL_get_rbio(const SSL *s)
{
- return (s->rbio);
+ return s->rbio;
}
BIO *SSL_get_wbio(const SSL *s)
{
- return (s->wbio);
+ if (s->bbio != NULL) {
+ /*
+ * If |bbio| is active, the true caller-configured BIO is its
+ * |next_bio|.
+ */
+ return BIO_next(s->bbio);
+ }
+ return s->wbio;
}
int SSL_get_fd(const SSL *s)
{
- return (SSL_get_rfd(s));
+ return SSL_get_rfd(s);
}
int SSL_get_rfd(const SSL *s)
int SSL_set_wfd(SSL *s, int fd)
{
- int ret = 0;
- BIO *bio = NULL;
+ BIO *rbio = SSL_get_rbio(s);
- if ((s->rbio == NULL) || (BIO_method_type(s->rbio) != BIO_TYPE_SOCKET)
- || ((int)BIO_get_fd(s->rbio, NULL) != fd)) {
- bio = BIO_new(BIO_s_socket());
+ if (rbio == NULL || BIO_method_type(rbio) != BIO_TYPE_SOCKET
+ || (int)BIO_get_fd(rbio, NULL) != fd) {
+ BIO *bio = BIO_new(BIO_s_socket());
if (bio == NULL) {
SSLerr(SSL_F_SSL_SET_WFD, ERR_R_BUF_LIB);
- goto err;
+ return 0;
}
BIO_set_fd(bio, fd, BIO_NOCLOSE);
- SSL_set_bio(s, SSL_get_rbio(s), bio);
- } else
- SSL_set_bio(s, SSL_get_rbio(s), SSL_get_rbio(s));
- ret = 1;
- err:
- return (ret);
+ SSL_set0_wbio(s, bio);
+ } else {
+ BIO_up_ref(rbio);
+ SSL_set0_wbio(s, rbio);
+ }
+ return 1;
}
int SSL_set_rfd(SSL *s, int fd)
{
- int ret = 0;
- BIO *bio = NULL;
+ BIO *wbio = SSL_get_wbio(s);
- if ((s->wbio == NULL) || (BIO_method_type(s->wbio) != BIO_TYPE_SOCKET)
- || ((int)BIO_get_fd(s->wbio, NULL) != fd)) {
- bio = BIO_new(BIO_s_socket());
+ if (wbio == NULL || BIO_method_type(wbio) != BIO_TYPE_SOCKET
+ || ((int)BIO_get_fd(wbio, NULL) != fd)) {
+ BIO *bio = BIO_new(BIO_s_socket());
if (bio == NULL) {
SSLerr(SSL_F_SSL_SET_RFD, ERR_R_BUF_LIB);
- goto err;
+ return 0;
}
BIO_set_fd(bio, fd, BIO_NOCLOSE);
- SSL_set_bio(s, bio, SSL_get_wbio(s));
- } else
- SSL_set_bio(s, SSL_get_wbio(s), SSL_get_wbio(s));
- ret = 1;
- err:
- return (ret);
+ SSL_set0_rbio(s, bio);
+ } else {
+ BIO_up_ref(wbio);
+ SSL_set0_rbio(s, wbio);
+ }
+
+ return 1;
}
#endif
/* 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->key->x509 == NULL)) {
- SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY,
- SSL_R_NO_CERTIFICATE_ASSIGNED);
+ if ((ctx == NULL) || (ctx->cert->key->x509 == NULL)) {
+ SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED);
return (0);
}
if (ctx->cert->key->privatekey == NULL) {
- SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY,
- SSL_R_NO_PRIVATE_KEY_ASSIGNED);
+ SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
return (0);
}
return (X509_check_private_key
int SSL_waiting_for_async(SSL *s)
{
- if(s->job)
+ if (s->job)
return 1;
return 0;
}
static int ssl_start_async_job(SSL *s, struct ssl_async_args *args,
- int (*func)(void *)) {
+ int (*func) (void *))
+{
int ret;
if (s->waitctx == NULL) {
s->waitctx = ASYNC_WAIT_CTX_new();
if (s->waitctx == NULL)
return -1;
}
- switch(ASYNC_start_job(&s->job, s->waitctx, &ret, func, args,
- sizeof(struct ssl_async_args))) {
+ switch (ASYNC_start_job(&s->job, s->waitctx, &ret, func, args,
+ sizeof(struct ssl_async_args))) {
case ASYNC_ERR:
s->rwstate = SSL_NOTHING;
SSLerr(SSL_F_SSL_START_ASYNC_JOB, SSL_R_FAILED_TO_INIT_ASYNC);
num = args->num;
switch (args->type) {
case READFUNC:
- return args->f.func_read(s, buf, num);
+ return args->f.func_read(s, buf, num, &s->asyncrw);
case WRITEFUNC:
- return args->f.func_write(s, buf, num);
+ return args->f.func_write(s, buf, num, &s->asyncrw);
case OTHERFUNC:
return args->f.func_other(s);
}
}
int SSL_read(SSL *s, void *buf, int num)
+{
+ int ret;
+ size_t read;
+
+ if (num < 0) {
+ SSLerr(SSL_F_SSL_READ, SSL_R_BAD_LENGTH);
+ return -1;
+ }
+
+ ret = SSL_read_ex(s, buf, (size_t)num, &read);
+
+ /*
+ * The cast is safe here because ret should be <= INT_MAX because num is
+ * <= INT_MAX
+ */
+ if (ret > 0)
+ ret = (int)read;
+
+ return ret;
+}
+
+int SSL_read_ex(SSL *s, void *buf, size_t num, size_t *read)
{
if (s->handshake_func == NULL) {
- SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED);
+ SSLerr(SSL_F_SSL_READ_EX, SSL_R_UNINITIALIZED);
return -1;
}
return (0);
}
- if((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
+ if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
struct ssl_async_args args;
+ int ret;
args.s = s;
args.buf = buf;
args.type = READFUNC;
args.f.func_read = s->method->ssl_read;
- return ssl_start_async_job(s, &args, ssl_io_intern);
+ ret = ssl_start_async_job(s, &args, ssl_io_intern);
+ *read = s->asyncrw;
+ return ret;
} else {
- return s->method->ssl_read(s, buf, num);
+ return s->method->ssl_read(s, buf, num, read);
}
}
int SSL_peek(SSL *s, void *buf, int num)
+{
+ int ret;
+ size_t read;
+
+ if (num < 0) {
+ SSLerr(SSL_F_SSL_PEEK, SSL_R_BAD_LENGTH);
+ return -1;
+ }
+
+ ret = SSL_peek_ex(s, buf, (size_t)num, &read);
+
+ /*
+ * The cast is safe here because ret should be <= INT_MAX because num is
+ * <= INT_MAX
+ */
+ if (ret > 0)
+ ret = (int)read;
+
+ return ret;
+}
+
+int SSL_peek_ex(SSL *s, void *buf, size_t num, size_t *read)
{
if (s->handshake_func == NULL) {
- SSLerr(SSL_F_SSL_PEEK, SSL_R_UNINITIALIZED);
+ SSLerr(SSL_F_SSL_PEEK_EX, SSL_R_UNINITIALIZED);
return -1;
}
if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
return (0);
}
- if((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
+ if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
struct ssl_async_args args;
+ int ret;
args.s = s;
args.buf = buf;
args.type = READFUNC;
args.f.func_read = s->method->ssl_peek;
- return ssl_start_async_job(s, &args, ssl_io_intern);
+ ret = ssl_start_async_job(s, &args, ssl_io_intern);
+ *read = s->asyncrw;
+ return ret;
} else {
- return s->method->ssl_peek(s, buf, num);
+ return s->method->ssl_peek(s, buf, num, read);
}
}
int SSL_write(SSL *s, const void *buf, int num)
+{
+ int ret;
+ size_t written;
+
+ if (num < 0) {
+ SSLerr(SSL_F_SSL_WRITE, SSL_R_BAD_LENGTH);
+ return -1;
+ }
+
+ ret = SSL_write_ex(s, buf, (size_t)num, &written);
+
+ /*
+ * The cast is safe here because ret should be <= INT_MAX because num is
+ * <= INT_MAX
+ */
+ if (ret > 0)
+ ret = (int)written;
+
+ return ret;
+}
+
+int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written)
{
if (s->handshake_func == NULL) {
- SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED);
+ SSLerr(SSL_F_SSL_WRITE_EX, SSL_R_UNINITIALIZED);
return -1;
}
if (s->shutdown & SSL_SENT_SHUTDOWN) {
s->rwstate = SSL_NOTHING;
- SSLerr(SSL_F_SSL_WRITE, SSL_R_PROTOCOL_IS_SHUTDOWN);
+ SSLerr(SSL_F_SSL_WRITE_EX, SSL_R_PROTOCOL_IS_SHUTDOWN);
return (-1);
}
- if((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
+ if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
+ int ret;
struct ssl_async_args args;
args.s = s;
args.type = WRITEFUNC;
args.f.func_write = s->method->ssl_write;
- return ssl_start_async_job(s, &args, ssl_io_intern);
+ ret = ssl_start_async_job(s, &args, ssl_io_intern);
+ *written = s->asyncrw;
+ return ret;
} else {
- return s->method->ssl_write(s, buf, num);
+ return s->method->ssl_write(s, buf, num, written);
}
}
}
if (!SSL_in_init(s)) {
- if((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
+ if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
struct ssl_async_args args;
args.s = s;
s->split_send_fragment = s->max_send_fragment;
return 1;
case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT:
- if ((unsigned int)larg > s->max_send_fragment || larg == 0)
+ if ((size_t)larg > s->max_send_fragment || larg == 0)
return 0;
s->split_send_fragment = larg;
return 1;
}
case SSL_CTRL_GET_EXTMS_SUPPORT:
if (!s->session || SSL_in_init(s) || ossl_statem_get_in_handshake(s))
- return -1;
+ return -1;
if (s->session->flags & SSL_SESS_FLAG_EXTMS)
return 1;
else
ctx->split_send_fragment = ctx->max_send_fragment;
return 1;
case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT:
- if ((unsigned int)larg > ctx->max_send_fragment || larg == 0)
+ if ((size_t)larg > ctx->max_send_fragment || larg == 0)
return 0;
ctx->split_send_fragment = larg;
return 1;
int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
const unsigned char *server,
unsigned int server_len,
- const unsigned char *client,
- unsigned int client_len)
+ const unsigned char *client, unsigned int client_len)
{
unsigned int i, j;
const unsigned char *result;
*len = ssl->s3->alpn_selected_len;
}
-
int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
const char *label, size_t llen,
const unsigned char *p, size_t plen,
int use_context)
{
- if (s->version < TLS1_VERSION)
+ if (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER)
return -1;
return s->method->ssl3_enc->export_keying_material(s, out, olen, label,
goto err;
#endif
if (!ssl_create_cipher_list(ret->method,
- &ret->cipher_list, &ret->cipher_list_by_id,
- SSL_DEFAULT_CIPHER_LIST, ret->cert)
- || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) {
+ &ret->cipher_list, &ret->cipher_list_by_id,
+ 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->split_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
/* Setup RFC5077 ticket keys */
- if ((RAND_bytes(ret->tlsext_tick_key_name, sizeof(ret->tlsext_tick_key_name)) <= 0)
- || (RAND_bytes(ret->tlsext_tick_hmac_key, sizeof(ret->tlsext_tick_hmac_key)) <= 0)
- || (RAND_bytes(ret->tlsext_tick_aes_key, sizeof(ret->tlsext_tick_aes_key)) <= 0))
+ if ((RAND_bytes(ret->tlsext_tick_key_name,
+ sizeof(ret->tlsext_tick_key_name)) <= 0)
+ || (RAND_bytes(ret->tlsext_tick_hmac_key,
+ sizeof(ret->tlsext_tick_hmac_key)) <= 0)
+ || (RAND_bytes(ret->tlsext_tick_aes_key,
+ sizeof(ret->tlsext_tick_aes_key)) <= 0))
ret->options |= SSL_OP_NO_TICKET;
#ifndef OPENSSL_NO_SRP
X509_VERIFY_PARAM_set_depth(ctx->param, depth);
}
-void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg),
- void *arg)
+void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg), void *arg)
{
ssl_cert_set_cert_cb(c->cert, cb, arg);
}
alg_a = cipher->algorithm_auth;
c = s->cert;
- if ((alg_a & SSL_aDSS) &&
- (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL))
+ if ((alg_a & SSL_aDSS) && (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL))
idx = SSL_PKEY_DSA_SIGN;
else if (alg_a & SSL_aRSA) {
if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL)
if (s->method != meth) {
const SSL_METHOD *sm = s->method;
- int (*hf)(SSL *) = s->handshake_func;
+ int (*hf) (SSL *) = s->handshake_func;
if (sm->version == meth->version)
s->method = meth;
}
if (SSL_want_write(s)) {
- bio = SSL_get_wbio(s);
+ /*
+ * Access wbio directly - in order to use the buffered bio if
+ * present
+ */
+ bio = s->wbio;
if (BIO_should_write(bio))
return (SSL_ERROR_WANT_WRITE);
else if (BIO_should_read(bio))
s->method->ssl_renegotiate_check(s);
if (SSL_in_init(s) || SSL_in_before(s)) {
- if((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
+ if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
struct ssl_async_args args;
args.s = s;
const char *ssl_protocol_to_string(int version)
{
- if (version == TLS1_2_VERSION)
+ switch(version)
+ {
+ case TLS1_3_VERSION:
+ return "TLSv1.3";
+
+ case TLS1_2_VERSION:
return "TLSv1.2";
- else if (version == TLS1_1_VERSION)
+
+ case TLS1_1_VERSION:
return "TLSv1.1";
- else if (version == TLS1_VERSION)
+
+ case TLS1_VERSION:
return "TLSv1";
- else if (version == SSL3_VERSION)
+
+ case SSL3_VERSION:
return "SSLv3";
- else if (version == DTLS1_BAD_VER)
+
+ case DTLS1_BAD_VER:
return "DTLSv0.9";
- else if (version == DTLS1_VERSION)
+
+ case DTLS1_VERSION:
return "DTLSv1";
- else if (version == DTLS1_2_VERSION)
+
+ case DTLS1_2_VERSION:
return "DTLSv1.2";
- else
- return ("unknown");
+
+ default:
+ return "unknown";
+ }
}
const char *SSL_get_version(const SSL *s)
if (s->wbio != s->rbio) {
if (!BIO_dup_state(s->wbio, (char *)&ret->wbio))
goto err;
- } else
+ } else {
+ BIO_up_ref(ret->rbio);
ret->wbio = ret->rbio;
+ }
}
ret->server = s->server;
{
BIO *bbio;
- if (s->bbio == NULL) {
- bbio = BIO_new(BIO_f_buffer());
- if (bbio == NULL)
- return 0;
- s->bbio = bbio;
- s->wbio = BIO_push(bbio, s->wbio);
- } else {
- bbio = s->bbio;
- (void)BIO_reset(bbio);
+ if (s->bbio != NULL) {
+ /* Already buffered. */
+ return 1;
}
- if (!BIO_set_read_buffer_size(bbio, 1)) {
+ bbio = BIO_new(BIO_f_buffer());
+ if (bbio == NULL || !BIO_set_read_buffer_size(bbio, 1)) {
+ BIO_free(bbio);
SSLerr(SSL_F_SSL_INIT_WBIO_BUFFER, ERR_R_BUF_LIB);
return 0;
}
+ s->bbio = bbio;
+ s->wbio = BIO_push(bbio, s->wbio);
return 1;
}
if (s->bbio == NULL)
return;
- if (s->bbio == s->wbio) {
- /* remove buffering */
- s->wbio = BIO_pop(s->wbio);
- assert(s->wbio != NULL);
- }
+ s->wbio = BIO_pop(s->wbio);
+ assert(s->wbio != NULL);
BIO_free(s->bbio);
s->bbio = NULL;
}
}
SSL_CTX_up_ref(ctx);
- SSL_CTX_free(ssl->ctx); /* decrement reference count */
+ SSL_CTX_free(ssl->ctx); /* decrement reference count */
ssl->ctx = ctx;
return ssl->ctx;
}
size_t SSL_SESSION_get_master_key(const SSL_SESSION *session,
- unsigned char *out, size_t outlen)
+ 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)
+ if (outlen > session->master_key_length)
outlen = session->master_key_length;
memcpy(out, session->master_key, outlen);
return outlen;
ctx->cert_store = store;
}
+void SSL_CTX_set1_cert_store(SSL_CTX *ctx, X509_STORE *store)
+{
+ if (store != NULL)
+ X509_STORE_up_ref(store);
+ SSL_CTX_set_cert_store(ctx, store);
+}
+
int SSL_want(const SSL *s)
{
return (s->rwstate);
int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint)
{
if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
- SSLerr(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT,
- SSL_R_DATA_LENGTH_TOO_LONG);
+ SSLerr(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG);
return 0;
}
OPENSSL_free(ctx->cert->psk_identity_hint);
unsigned int
max_identity_len,
unsigned char *psk,
- unsigned int
- max_psk_len))
+ unsigned int max_psk_len))
{
s->psk_client_callback = cb;
}
unsigned int (*cb) (SSL *ssl,
const char *identity,
unsigned char *psk,
- unsigned int
- max_psk_len))
+ unsigned int max_psk_len))
{
s->psk_server_callback = cb;
}
}
/* Retrieve handshake hashes */
-int ssl_handshake_hash(SSL *s, unsigned char *out, int outlen)
+int ssl_handshake_hash(SSL *s, unsigned char *out, size_t outlen,
+ size_t *hashlen)
{
EVP_MD_CTX *ctx = NULL;
EVP_MD_CTX *hdgst = s->s3->handshake_dgst;
- int ret = EVP_MD_CTX_size(hdgst);
- if (ret < 0 || ret > outlen) {
- ret = 0;
+ int hashleni = EVP_MD_CTX_size(hdgst);
+ int ret = 0;
+
+ if (hashleni < 0 || (size_t)hashleni > outlen)
goto err;
- }
+
ctx = EVP_MD_CTX_new();
- if (ctx == NULL) {
- ret = 0;
+ if (ctx == NULL)
goto err;
- }
+
if (!EVP_MD_CTX_copy_ex(ctx, hdgst)
|| EVP_DigestFinal_ex(ctx, out, NULL) <= 0)
- ret = 0;
+ goto err;
+
+ *hashlen = hashleni;
+
+ ret = 1;
err:
EVP_MD_CTX_free(ctx);
return ret;
}
#endif
-
void SSL_set_security_level(SSL *s, int level)
{
s->cert->sec_level = level;
}
void SSL_set_security_callback(SSL *s,
- int (*cb) (const SSL *s, const SSL_CTX *ctx, int op,
- int bits, int nid, void *other,
- void *ex))
+ int (*cb) (const SSL *s, const SSL_CTX *ctx,
+ int op, int bits, int nid,
+ void *other, void *ex))
{
s->cert->sec_cb = cb;
}
-int (*SSL_get_security_callback(const SSL *s)) (const SSL *s, const SSL_CTX *ctx, int op,
- int bits, int nid,
- void *other, void *ex) {
+int (*SSL_get_security_callback(const SSL *s)) (const SSL *s,
+ const SSL_CTX *ctx, int op,
+ int bits, int nid, void *other,
+ void *ex) {
return s->cert->sec_cb;
}
}
void SSL_CTX_set_security_callback(SSL_CTX *ctx,
- int (*cb) (const SSL *s, const SSL_CTX *ctx, int op,
- int bits, int nid, void *other,
- void *ex))
+ int (*cb) (const SSL *s, const SSL_CTX *ctx,
+ int op, int bits, int nid,
+ void *other, void *ex))
{
ctx->cert->sec_cb = cb;
}
return ctx->cert->sec_ex;
}
-
/*
* Get/Set/Clear options in SSL_CTX or SSL, formerly macros, now functions that
* can return unsigned long, instead of the generic long return value from the
{
return ctx->options;
}
-unsigned long SSL_get_options(const SSL* s)
+
+unsigned long SSL_get_options(const SSL *s)
{
return s->options;
}
+
unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op)
{
return ctx->options |= op;
}
+
unsigned long SSL_set_options(SSL *s, unsigned long op)
{
return s->options |= op;
}
+
unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op)
{
return ctx->options &= ~op;
}
+
unsigned long SSL_clear_options(SSL *s, unsigned long op)
{
return s->options &= ~op;
* the caller.
* Returns the number of SCTs moved, or a negative integer if an error occurs.
*/
-static int ct_move_scts(STACK_OF(SCT) **dst, STACK_OF(SCT) *src, sct_source_t origin)
+static int ct_move_scts(STACK_OF(SCT) **dst, STACK_OF(SCT) *src,
+ sct_source_t origin)
{
int scts_moved = 0;
SCT *sct = NULL;
}
return scts_moved;
-err:
+ err:
if (sct != NULL)
- sk_SCT_push(src, sct); /* Put the SCT back */
+ sk_SCT_push(src, sct); /* Put the SCT back */
return -1;
}
/*
-* Look for data collected during ServerHello and parse if found.
-* Return 1 on success, 0 on failure.
-*/
+ * Look for data collected during ServerHello and parse if found.
+ * Returns the number of SCTs extracted.
+ */
static int ct_extract_tls_extension_scts(SSL *s)
{
int scts_extracted = 0;
*/
static int ct_extract_ocsp_response_scts(SSL *s)
{
-#ifndef OPENSSL_NO_OCSP
+# ifndef OPENSSL_NO_OCSP
int scts_extracted = 0;
const unsigned char *p;
OCSP_BASICRESP *br = NULL;
if (single == NULL)
continue;
- scts = OCSP_SINGLERESP_get1_ext_d2i(single, NID_ct_cert_scts, NULL, NULL);
- scts_extracted = ct_move_scts(&s->scts, scts,
- SCT_SOURCE_OCSP_STAPLED_RESPONSE);
+ scts =
+ OCSP_SINGLERESP_get1_ext_d2i(single, NID_ct_cert_scts, NULL, NULL);
+ scts_extracted =
+ ct_move_scts(&s->scts, scts, SCT_SOURCE_OCSP_STAPLED_RESPONSE);
if (scts_extracted < 0)
goto err;
}
-err:
+ err:
SCT_LIST_free(scts);
OCSP_BASICRESP_free(br);
OCSP_RESPONSE_free(rsp);
return scts_extracted;
-#else
+# else
/* Behave as if no OCSP response exists */
return 0;
-#endif
+# endif
}
/*
s->scts_parsed = 1;
}
return s->scts;
-err:
+ err:
return NULL;
}
-static int ct_permissive(const CT_POLICY_EVAL_CTX *ctx,
+static int ct_permissive(const CT_POLICY_EVAL_CTX * ctx,
const STACK_OF(SCT) *scts, void *unused_arg)
{
return 1;
}
-static int ct_strict(const CT_POLICY_EVAL_CTX *ctx,
+static int ct_strict(const CT_POLICY_EVAL_CTX * ctx,
const STACK_OF(SCT) *scts, void *unused_arg)
{
int count = scts != NULL ? sk_SCT_num(scts) : 0;
* for this and throw an error if they have already registered to use CT.
*/
if (callback != NULL && SSL_CTX_has_client_custom_ext(s->ctx,
- TLSEXT_TYPE_signed_certificate_timestamp)) {
+ TLSEXT_TYPE_signed_certificate_timestamp))
+ {
SSLerr(SSL_F_SSL_SET_CT_VALIDATION_CALLBACK,
SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED);
return 0;
}
if (callback != NULL) {
- /* If we are validating CT, then we MUST accept SCTs served via OCSP */
+ /*
+ * If we are validating CT, then we MUST accept SCTs served via OCSP
+ */
if (!SSL_set_tlsext_status_type(s, TLSEXT_STATUSTYPE_ocsp))
return 0;
}
}
int SSL_CTX_set_ct_validation_callback(SSL_CTX *ctx,
- ssl_ct_validation_cb callback,
- void *arg)
+ ssl_ct_validation_cb callback, void *arg)
{
/*
* Since code exists that uses the custom extension handler for CT, look for
* this and throw an error if they have already registered to use CT.
*/
if (callback != NULL && SSL_CTX_has_client_custom_ext(ctx,
- TLSEXT_TYPE_signed_certificate_timestamp)) {
+ TLSEXT_TYPE_signed_certificate_timestamp))
+ {
SSLerr(SSL_F_SSL_CTX_SET_CT_VALIDATION_CALLBACK,
SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED);
return 0;
*/
if (s->ct_validation_callback == NULL || cert == NULL ||
s->verify_result != X509_V_OK ||
- s->verified_chain == NULL ||
- sk_X509_num(s->verified_chain) <= 1)
+ s->verified_chain == NULL || sk_X509_num(s->verified_chain) <= 1)
return 1;
/*
}
issuer = sk_X509_value(s->verified_chain, 1);
- CT_POLICY_EVAL_CTX_set0_cert(ctx, cert);
- CT_POLICY_EVAL_CTX_set0_issuer(ctx, issuer);
- CT_POLICY_EVAL_CTX_set0_log_store(ctx, s->ctx->ctlog_store);
+ CT_POLICY_EVAL_CTX_set1_cert(ctx, cert);
+ CT_POLICY_EVAL_CTX_set1_issuer(ctx, issuer);
+ CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(ctx, s->ctx->ctlog_store);
scts = SSL_get0_peer_scts(s);
ret = s->ct_validation_callback(ctx, scts, s->ct_validation_callback_arg);
if (ret < 0)
- ret = 0; /* This function returns 0 on failure */
+ ret = 0; /* This function returns 0 on failure */
-end:
+ end:
CT_POLICY_EVAL_CTX_free(ctx);
/*
* With SSL_VERIFY_NONE the session may be cached and re-used despite a
return CTLOG_STORE_load_file(ctx->ctlog_store, path);
}
-void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE *logs)
+void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE * logs)
{
CTLOG_STORE_free(ctx->ctlog_store);
ctx->ctlog_store = logs;