* evil casts, but these functions are only called if there's a library
* bug
*/
- (int (*)(SSL *, int))ssl_undefined_function,
- (int (*)(SSL *, unsigned char *, int))ssl_undefined_function,
+ (int (*)(SSL *, SSL3_RECORD *, unsigned int, int))ssl_undefined_function,
+ (int (*)(SSL *, SSL3_RECORD *, unsigned char *, int))ssl_undefined_function,
ssl_undefined_function,
(int (*)(SSL *, unsigned char *, unsigned char *, int))
ssl_undefined_function,
X509_VERIFY_PARAM_inherit(s->param, ctx->param);
s->quiet_shutdown = ctx->quiet_shutdown;
s->max_send_fragment = ctx->max_send_fragment;
+ s->split_send_fragment = ctx->split_send_fragment;
+ s->max_pipelines = ctx->max_pipelines;
+ if (s->max_pipelines > 1)
+ RECORD_LAYER_set_read_ahead(&s->rlayer, 1);
+ if (ctx->default_read_buf_len > 0)
+ SSL_set_default_read_buffer_len(s, ctx->default_read_buf_len);
CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
s->ctx = ctx;
return (s->method->ssl_pending(s));
}
+int SSL_has_pending(const SSL *s)
+{
+ /*
+ * Similar to SSL_pending() but returns a 1 to indicate that we have
+ * unprocessed data available or 0 otherwise (as opposed to the number of
+ * bytes available). Unlike SSL_pending() this will take into account
+ * read_ahead data. A 1 return simply indicates that we have unprocessed
+ * data. That data may not result in any application data, or we may fail
+ * to parse the records for some reason.
+ */
+ if (SSL_pending(s))
+ return 1;
+
+ return RECORD_LAYER_read_pending(&s->rlayer);
+}
+
X509 *SSL_get_peer_certificate(const SSL *s)
{
X509 *r;
if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
return 0;
s->max_send_fragment = larg;
+ if (s->max_send_fragment < s->split_send_fragment)
+ s->split_send_fragment = s->max_send_fragment;
+ return 1;
+ case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT:
+ if (larg > s->max_send_fragment || larg == 0)
+ return 0;
+ s->split_send_fragment = larg;
+ return 1;
+ case SSL_CTRL_SET_MAX_PIPELINES:
+ if (larg < 1 || larg > SSL_MAX_PIPELINES)
+ return 0;
+ s->max_pipelines = larg;
+ if (larg > 1)
+ RECORD_LAYER_set_read_ahead(&s->rlayer, 1);
return 1;
case SSL_CTRL_GET_RI_SUPPORT:
if (s->s3)
if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
return 0;
ctx->max_send_fragment = larg;
+ if (ctx->max_send_fragment < ctx->split_send_fragment)
+ ctx->split_send_fragment = ctx->split_send_fragment;
+ return 1;
+ case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT:
+ if (larg > ctx->max_send_fragment || larg == 0)
+ return 0;
+ ctx->split_send_fragment = larg;
+ return 1;
+ case SSL_CTRL_SET_MAX_PIPELINES:
+ if (larg < 1 || larg > SSL_MAX_PIPELINES)
+ return 0;
+ ctx->max_pipelines = larg;
return 1;
case SSL_CTRL_CERT_FLAGS:
return (ctx->cert->cert_flags |= larg);
* length-prefixed strings). Returns 0 on success.
*/
int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
- unsigned protos_len)
+ unsigned int protos_len)
{
OPENSSL_free(ctx->alpn_client_proto_list);
- ctx->alpn_client_proto_list = OPENSSL_malloc(protos_len);
+ ctx->alpn_client_proto_list = OPENSSL_memdup(protos, protos_len);
if (ctx->alpn_client_proto_list == NULL) {
SSLerr(SSL_F_SSL_CTX_SET_ALPN_PROTOS, ERR_R_MALLOC_FAILURE);
return 1;
}
- memcpy(ctx->alpn_client_proto_list, protos, protos_len);
ctx->alpn_client_proto_list_len = protos_len;
return 0;
* length-prefixed strings). Returns 0 on success.
*/
int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos,
- unsigned protos_len)
+ unsigned int protos_len)
{
OPENSSL_free(ssl->alpn_client_proto_list);
- ssl->alpn_client_proto_list = OPENSSL_malloc(protos_len);
+ ssl->alpn_client_proto_list = OPENSSL_memdup(protos, protos_len);
if (ssl->alpn_client_proto_list == NULL) {
SSLerr(SSL_F_SSL_SET_ALPN_PROTOS, ERR_R_MALLOC_FAILURE);
return 1;
}
- memcpy(ssl->alpn_client_proto_list, protos, protos_len);
ssl->alpn_client_proto_list_len = protos_len;
return 0;
* respond with a negotiated protocol then |*len| will be zero.
*/
void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
- unsigned *len)
+ unsigned int *len)
{
*data = NULL;
if (ssl->s3)
ret->comp_methods = SSL_COMP_get_compression_methods();
ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
+ ret->split_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
/* Setup RFC4507 ticket keys */
if ((RAND_bytes(ret->tlsext_tick_key_name, 16) <= 0)
static int ct_extract_x509v3_extension_scts(SSL *s)
{
int scts_extracted = 0;
- X509 *cert = SSL_get_peer_certificate(s);
+ X509 *cert = s->session != NULL ? s->session->peer : NULL;
if (cert != NULL) {
STACK_OF(SCT) *scts =
return ctx->ct_validation_callback;
}
-int SSL_validate_ct(SSL *s)
+int ssl_validate_ct(SSL *s)
{
int ret = 0;
- X509 *cert = SSL_get_peer_certificate(s);
+ X509 *cert = s->session != NULL ? s->session->peer : NULL;
X509 *issuer = NULL;
CT_POLICY_EVAL_CTX *ctx = NULL;
const STACK_OF(SCT) *scts;