Browse Source

Promote max_cert_list and max_send_fragment to functions.

Also size them based on the limits in the quantities they control (after
checking bounds at the API boundary).

BUG=404754

Change-Id: Id56ba45465a473a1a793244904310ef747f29b63
Reviewed-on: https://boringssl-review.googlesource.com/4559
Reviewed-by: Adam Langley <agl@google.com>
kris/onging/CECPQ3_patch15
David Benjamin 9 years ago
committed by Adam Langley
parent
commit
1d0a194cc1
5 changed files with 92 additions and 57 deletions
  1. +44
    -22
      include/openssl/ssl.h
  2. +2
    -2
      ssl/d1_both.c
  3. +1
    -1
      ssl/s3_clnt.c
  4. +1
    -1
      ssl/s3_srvr.c
  5. +44
    -31
      ssl/ssl_lib.c

+ 44
- 22
include/openssl/ssl.h View File

@@ -877,7 +877,7 @@ struct ssl_ctx_st {

uint32_t options;
uint32_t mode;
long max_cert_list;
uint32_t max_cert_list;

struct cert_st /* CERT */ *cert;
int read_ahead;
@@ -917,7 +917,7 @@ struct ssl_ctx_st {

/* Maximum amount of data to send in one fragment. actual record size can be
* more than this due to padding and MAC overheads. */
unsigned int max_send_fragment;
uint16_t max_send_fragment;

/* TLS extensions servername callback */
int (*tlsext_servername_callback)(SSL *, int *, void *);
@@ -1360,10 +1360,10 @@ struct ssl_st {

uint32_t options; /* protocol behaviour */
uint32_t mode; /* API behaviour */
long max_cert_list;
uint32_t max_cert_list;
int client_version; /* what was passed, used for
* SSLv3/TLS rollback check */
unsigned int max_send_fragment;
uint16_t max_send_fragment;
char *tlsext_hostname;
/* should_ack_sni is true if the SNI extension should be acked. This is
* only used by a server. */
@@ -1605,11 +1605,6 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_SET_SESS_CACHE_MODE 44
#define SSL_CTRL_GET_SESS_CACHE_MODE 45

#define SSL_CTRL_GET_MAX_CERT_LIST 50
#define SSL_CTRL_SET_MAX_CERT_LIST 51

#define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52

/* see tls1.h for macros based on these */
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54
#define SSL_CTRL_SET_TLSEXT_HOSTNAME 55
@@ -2158,19 +2153,37 @@ OPENSSL_EXPORT int SSL_get_ex_data_X509_STORE_CTX_idx(void);
* is resolved. */
OPENSSL_EXPORT int SSL_CTX_get_read_ahead(const SSL_CTX *ctx);
OPENSSL_EXPORT void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes);
#define SSL_CTX_get_max_cert_list(ctx) \
SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MAX_CERT_LIST, 0, NULL)
#define SSL_CTX_set_max_cert_list(ctx, m) \
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_CERT_LIST, m, NULL)
#define SSL_get_max_cert_list(ssl) \
SSL_ctrl(ssl, SSL_CTRL_GET_MAX_CERT_LIST, 0, NULL)
#define SSL_set_max_cert_list(ssl, m) \
SSL_ctrl(ssl, SSL_CTRL_SET_MAX_CERT_LIST, m, NULL)

#define SSL_CTX_set_max_send_fragment(ctx, m) \
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_SEND_FRAGMENT, m, NULL)
#define SSL_set_max_send_fragment(ssl, m) \
SSL_ctrl(ssl, SSL_CTRL_SET_MAX_SEND_FRAGMENT, m, NULL)

/* SSL_CTX_get_max_cert_list returns the maximum length, in bytes, of a peer
* certificate chain accepted by |ctx|. */
OPENSSL_EXPORT size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx);

/* SSL_CTX_set_max_cert_list sets the maximum length, in bytes, of a peer
* certificate chain to |max_cert_list|. This affects how much memory may be
* consumed during the handshake. */
OPENSSL_EXPORT void SSL_CTX_set_max_cert_list(SSL_CTX *ctx,
size_t max_cert_list);

/* SSL_get_max_cert_list returns the maximum length, in bytes, of a peer
* certificate chain accepted by |ssl|. */
OPENSSL_EXPORT size_t SSL_get_max_cert_list(const SSL *ssl);

/* SSL_set_max_cert_list sets the maximum length, in bytes, of a peer
* certificate chain to |max_cert_list|. This affects how much memory may be
* consumed during the handshake. */
OPENSSL_EXPORT void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list);

/* SSL_CTX_set_max_send_fragment sets the maximum length, in bytes, of records
* sent by |ctx|. Beyond this length, handshake messages and application data
* will be split into multiple records. */
OPENSSL_EXPORT void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx,
size_t max_send_fragment);

/* SSL_set_max_send_fragment sets the maximum length, in bytes, of records
* sent by |ssl|. Beyond this length, handshake messages and application data
* will be split into multiple records. */
OPENSSL_EXPORT void SSL_set_max_send_fragment(SSL *ssl,
size_t max_send_fragment);

/* SSL_CTX_set_tmp_dh_callback configures |ctx| to use |callback| to determine
* the group for DHE ciphers. |callback| should ignore |is_export| and
@@ -2387,6 +2400,9 @@ OPENSSL_EXPORT const char *SSLeay_version(int unused);
#define SSL_CTRL_MODE doesnt_exist
#define SSL_CTRL_GET_READ_AHEAD doesnt_exist
#define SSL_CTRL_SET_READ_AHEAD doesnt_exist
#define SSL_CTRL_GET_MAX_CERT_LIST doesnt_exist
#define SSL_CTRL_SET_MAX_CERT_LIST doesnt_exist
#define SSL_CTRL_SET_MAX_SEND_FRAGMENT doesnt_exist
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB doesnt_exist
#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB doesnt_exist
#define DTLS_CTRL_GET_TIMEOUT doesnt_exist
@@ -2406,6 +2422,12 @@ OPENSSL_EXPORT const char *SSLeay_version(int unused);
#define SSL_set_mode SSL_set_mode
#define SSL_CTX_get_read_ahead SSL_CTX_get_read_ahead
#define SSL_CTX_set_read_ahead SSL_CTX_set_read_ahead
#define SSL_CTX_get_max_cert_list SSL_CTX_get_max_cert_list
#define SSL_get_max_cert_list SSL_get_max_cert_list
#define SSL_CTX_set_max_cert_list SSL_CTX_set_max_cert_list
#define SSL_set_max_cert_list SSL_set_max_cert_list
#define SSL_CTX_set_max_send_fragment SSL_CTX_set_max_send_fragment
#define SSL_set_max_send_fragment SSL_set_max_send_fragment
#define SSL_CTX_set_tlsext_servername_callback \
SSL_CTX_set_tlsext_servername_callback
#define SSL_CTX_set_tlsext_ticket_key_cb SSL_CTX_set_tlsext_ticket_key_cb


+ 2
- 2
ssl/d1_both.c View File

@@ -470,8 +470,8 @@ static hm_fragment *dtls1_get_buffered_message(
* be greater if the maximum certificate list size requires it. */
static size_t dtls1_max_handshake_message_len(const SSL *s) {
size_t max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
if (max_len < (size_t)s->max_cert_list) {
return (size_t)s->max_cert_list;
if (max_len < s->max_cert_list) {
return s->max_cert_list;
}
return max_len;
}


+ 1
- 1
ssl/s3_clnt.c View File

@@ -925,7 +925,7 @@ int ssl3_get_server_certificate(SSL *s) {
const uint8_t *data;

n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_A, SSL3_ST_CR_CERT_B,
SSL3_MT_CERTIFICATE, s->max_cert_list,
SSL3_MT_CERTIFICATE, (long)s->max_cert_list,
ssl_hash_message, &ok);

if (!ok) {


+ 1
- 1
ssl/s3_srvr.c View File

@@ -2220,7 +2220,7 @@ int ssl3_get_client_certificate(SSL *s) {
int is_first_certificate = 1;

n = s->method->ssl_get_message(s, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B, -1,
s->max_cert_list, ssl_hash_message, &ok);
(long)s->max_cert_list, ssl_hash_message, &ok);

if (!ok) {
return n;


+ 44
- 31
ssl/ssl_lib.c View File

@@ -161,6 +161,9 @@ OPENSSL_COMPILE_ASSERT(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION ==
SSL_AD_NO_RENEGOTIATION + SSL_AD_REASON_OFFSET,
ssl_alert_reason_code_mismatch);

/* kMaxHandshakeSize is the maximum size, in bytes, of a handshake message. */
static const size_t kMaxHandshakeSize = (1u << 24) - 1;

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;

@@ -1009,18 +1012,50 @@ uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx) { return ctx->mode; }

uint32_t SSL_get_mode(const SSL *ssl) { return ssl->mode; }

long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) {
long l;
size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx) {
return ctx->max_cert_list;
}

switch (cmd) {
case SSL_CTRL_GET_MAX_CERT_LIST:
return s->max_cert_list;
void SSL_CTX_set_max_cert_list(SSL_CTX *ctx, size_t max_cert_list) {
if (max_cert_list > kMaxHandshakeSize) {
max_cert_list = kMaxHandshakeSize;
}
ctx->max_cert_list = (uint32_t)max_cert_list;
}

case SSL_CTRL_SET_MAX_CERT_LIST:
l = s->max_cert_list;
s->max_cert_list = larg;
return l;
size_t SSL_get_max_cert_list(const SSL *ssl) {
return ssl->max_cert_list;
}

void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list) {
if (max_cert_list > kMaxHandshakeSize) {
max_cert_list = kMaxHandshakeSize;
}
ssl->max_cert_list = (uint32_t)max_cert_list;
}

void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, size_t max_send_fragment) {
if (max_send_fragment < 512) {
max_send_fragment = 512;
}
if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
}
ctx->max_send_fragment = (uint16_t)max_send_fragment;
}

void SSL_set_max_send_fragment(SSL *ssl, size_t max_send_fragment) {
if (max_send_fragment < 512) {
max_send_fragment = 512;
}
if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
}
ssl->max_send_fragment = (uint16_t)max_send_fragment;
}

long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) {
switch (cmd) {
case SSL_CTRL_SET_MTU:
if (larg < (long)dtls1_min_mtu()) {
return 0;
@@ -1031,13 +1066,6 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) {
}
return 0;

case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) {
return 0;
}
s->max_send_fragment = larg;
return 1;

case SSL_CTRL_GET_RI_SUPPORT:
if (s->s3) {
return s->s3->send_connection_binding;
@@ -1068,14 +1096,6 @@ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) {
long l;

switch (cmd) {
case SSL_CTRL_GET_MAX_CERT_LIST:
return ctx->max_cert_list;

case SSL_CTRL_SET_MAX_CERT_LIST:
l = ctx->max_cert_list;
ctx->max_cert_list = larg;
return l;

case SSL_CTRL_SET_SESS_CACHE_SIZE:
l = ctx->session_cache_size;
ctx->session_cache_size = larg;
@@ -1095,13 +1115,6 @@ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) {
case SSL_CTRL_SESS_NUMBER:
return lh_SSL_SESSION_num_items(ctx->sessions);

case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) {
return 0;
}
ctx->max_send_fragment = larg;
return 1;

default:
return ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg);
}


Loading…
Cancel
Save