Commit b83294fe authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Revision of custom extension code.



Move custom extension structures from SSL_CTX to CERT structure.

This change means the form can be revised in future without binary
compatibility issues. Also since CERT is part of SSL structures
so per-SSL custom extensions could be supported in future as well as
per SSL_CTX.
Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
Reviewed-by: default avatarEmilia Käsper <emilia@openssl.org>
parent 06f5d12f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -368,7 +368,7 @@ static int ssl23_client_hello(SSL *s)
		if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL)
			ssl2_compat = 0;
#endif
		if (s->ctx->custom_cli_ext_records_count != 0)
		if (s->cert->custom_cli_ext_records_count != 0)
			ssl2_compat = 0;
		}
#endif
+0 −19
Original line number Diff line number Diff line
@@ -425,20 +425,6 @@ typedef int (*custom_srv_ext_second_cb_fn)(SSL *s, unsigned short ext_type,
					   const unsigned char **out,
					   unsigned short *outlen, int *al, void *arg);

typedef struct {
	unsigned short ext_type;
	custom_cli_ext_first_cb_fn fn1; 
	custom_cli_ext_second_cb_fn fn2; 
	void *arg;
} custom_cli_ext_record;

typedef struct {
	unsigned short ext_type;
	custom_srv_ext_first_cb_fn fn1; 
	custom_srv_ext_second_cb_fn fn2; 
	void *arg;
} custom_srv_ext_record;

#endif

#ifndef OPENSSL_NO_SSL_INTERN
@@ -1160,11 +1146,6 @@ struct ssl_ctx_st
	size_t tlsext_ellipticcurvelist_length;
	unsigned char *tlsext_ellipticcurvelist;
# endif /* OPENSSL_NO_EC */
	/* Arrays containing the callbacks for custom TLS Extensions. */
	custom_cli_ext_record *custom_cli_ext_records;
	size_t custom_cli_ext_records_count;
	custom_srv_ext_record *custom_srv_ext_records;
	size_t custom_srv_ext_records_count;
	};

#endif
+34 −0
Original line number Diff line number Diff line
@@ -423,6 +423,27 @@ CERT *ssl_cert_dup(CERT *cert)
	ret->sec_level = cert->sec_level;
	ret->sec_ex = cert->sec_ex;

#ifndef OPENSSL_NO_TLSEXT
	if (cert->custom_cli_ext_records_count)
		{
		ret->custom_cli_ext_records = BUF_memdup(cert->custom_cli_ext_records, sizeof(custom_cli_ext_record) * cert->custom_cli_ext_records_count);
		if (ret->custom_cli_ext_records == NULL)
			goto err;
		ret->custom_cli_ext_records_count =
					cert->custom_cli_ext_records_count;
		}

	if (cert->custom_srv_ext_records_count)
		{
		ret->custom_srv_ext_records = BUF_memdup(cert->custom_srv_ext_records, sizeof(custom_srv_ext_record) * cert->custom_srv_ext_records_count);
		if (ret->custom_srv_ext_records == NULL)
			goto err;
		ret->custom_srv_ext_records_count =
					cert->custom_srv_ext_records_count;
		}

#endif

	return(ret);
	
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
@@ -441,6 +462,13 @@ err:
		EC_KEY_free(ret->ecdh_tmp);
#endif

#ifndef OPENSSL_NO_TLSEXT
	if (ret->custom_cli_ext_records)
		OPENSSL_free(ret->custom_cli_ext_records);
	if (ret->custom_srv_ext_records)
		OPENSSL_free(ret->custom_srv_ext_records);
#endif

	ssl_cert_clear_certs(ret);

	return NULL;
@@ -531,6 +559,12 @@ void ssl_cert_free(CERT *c)
		X509_STORE_free(c->chain_store);
	if (c->ciphers_raw)
		OPENSSL_free(c->ciphers_raw);
#ifndef OPENSSL_NO_TLSEXT
	if (c->custom_cli_ext_records)
		OPENSSL_free(c->custom_cli_ext_records);
	if (c->custom_srv_ext_records)
		OPENSSL_free(c->custom_srv_ext_records);
#endif
	OPENSSL_free(c);
	}

+32 −26
Original line number Diff line number Diff line
@@ -1751,7 +1751,7 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned
	}
# endif

int SSL_CTX_set_custom_cli_ext(SSL_CTX *ctx, unsigned short ext_type,
static int cert_set_custom_cli_ext(CERT *cert, unsigned short ext_type,
			       custom_cli_ext_first_cb_fn fn1, 
			       custom_cli_ext_second_cb_fn fn2, void* arg)
	{
@@ -1759,19 +1759,19 @@ int SSL_CTX_set_custom_cli_ext(SSL_CTX *ctx, unsigned short ext_type,
	custom_cli_ext_record* record;

	/* Check for duplicates */
	for (i=0; i < ctx->custom_cli_ext_records_count; i++)
		if (ext_type == ctx->custom_cli_ext_records[i].ext_type)
	for (i=0; i < cert->custom_cli_ext_records_count; i++)
		if (ext_type == cert->custom_cli_ext_records[i].ext_type)
			return 0;

	ctx->custom_cli_ext_records = OPENSSL_realloc(ctx->custom_cli_ext_records,
						      (ctx->custom_cli_ext_records_count + 1) * 
	cert->custom_cli_ext_records = OPENSSL_realloc(cert->custom_cli_ext_records,
						      (cert->custom_cli_ext_records_count + 1) * 
						      sizeof(custom_cli_ext_record));
	if (!ctx->custom_cli_ext_records) {
		ctx->custom_cli_ext_records_count = 0;
	if (!cert->custom_cli_ext_records) {
		cert->custom_cli_ext_records_count = 0;
		return 0;
	}
	ctx->custom_cli_ext_records_count++;
	record = &ctx->custom_cli_ext_records[ctx->custom_cli_ext_records_count - 1];
	cert->custom_cli_ext_records_count++;
	record = &cert->custom_cli_ext_records[cert->custom_cli_ext_records_count - 1];
	record->ext_type = ext_type;
	record->fn1 = fn1;
	record->fn2 = fn2;
@@ -1779,7 +1779,7 @@ int SSL_CTX_set_custom_cli_ext(SSL_CTX *ctx, unsigned short ext_type,
	return 1;
	}

int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned short ext_type,
static int cert_set_custom_srv_ext(CERT *cert, unsigned short ext_type,
			       custom_srv_ext_first_cb_fn fn1, 
			       custom_srv_ext_second_cb_fn fn2, void* arg)
	{
@@ -1787,19 +1787,19 @@ int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned short ext_type,
	custom_srv_ext_record* record;

	/* Check for duplicates */	
	for (i=0; i < ctx->custom_srv_ext_records_count; i++)
		if (ext_type == ctx->custom_srv_ext_records[i].ext_type)
	for (i=0; i < cert->custom_srv_ext_records_count; i++)
		if (ext_type == cert->custom_srv_ext_records[i].ext_type)
			return 0;

	ctx->custom_srv_ext_records = OPENSSL_realloc(ctx->custom_srv_ext_records,
						      (ctx->custom_srv_ext_records_count + 1) * 
	cert->custom_srv_ext_records = OPENSSL_realloc(cert->custom_srv_ext_records,
						      (cert->custom_srv_ext_records_count + 1) * 
						      sizeof(custom_srv_ext_record));
	if (!ctx->custom_srv_ext_records) {
		ctx->custom_srv_ext_records_count = 0;
	if (!cert->custom_srv_ext_records) {
		cert->custom_srv_ext_records_count = 0;
		return 0;
	}
	ctx->custom_srv_ext_records_count++;
	record = &ctx->custom_srv_ext_records[ctx->custom_srv_ext_records_count - 1];
	cert->custom_srv_ext_records_count++;
	record = &cert->custom_srv_ext_records[cert->custom_srv_ext_records_count - 1];
	record->ext_type = ext_type;
	record->fn1 = fn1;
	record->fn2 = fn2;
@@ -1807,6 +1807,20 @@ int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned short ext_type,
	return 1;
	}
 
int SSL_CTX_set_custom_cli_ext(SSL_CTX *ctx, unsigned short ext_type,
			       custom_cli_ext_first_cb_fn fn1, 
			       custom_cli_ext_second_cb_fn fn2, void *arg)
	{
	return cert_set_custom_cli_ext(ctx->cert, ext_type, fn1, fn2,arg);
	}

int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned short ext_type,
			       custom_srv_ext_first_cb_fn fn1, 
			       custom_srv_ext_second_cb_fn fn2, void *arg)
	{
	return cert_set_custom_srv_ext(ctx->cert, ext_type, fn1, fn2,arg);
	}

/* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
 * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
 * length-prefixed strings).
@@ -2078,10 +2092,6 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
#ifndef OPENSSL_NO_SRP
	SSL_CTX_SRP_CTX_init(ret);
#endif
	ret->custom_cli_ext_records = NULL;
	ret->custom_cli_ext_records_count = 0;
	ret->custom_srv_ext_records = NULL;
	ret->custom_srv_ext_records_count = 0;
#ifndef OPENSSL_NO_BUF_FREELISTS
	ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT;
	ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
@@ -2220,10 +2230,6 @@ void SSL_CTX_free(SSL_CTX *a)
#ifndef OPENSSL_NO_SRP
	SSL_CTX_SRP_CTX_free(a);
#endif
#ifndef OPENSSL_NO_TLSEXT
	OPENSSL_free(a->custom_cli_ext_records);
	OPENSSL_free(a->custom_srv_ext_records);
#endif
#ifndef OPENSSL_NO_ENGINE
	if (a->client_cert_engine)
		ENGINE_finish(a->client_cert_engine);
+20 −0
Original line number Diff line number Diff line
@@ -532,6 +532,20 @@ typedef struct cert_pkey_st
#define SSL_CERT_FLAGS_CHECK_TLS_STRICT \
	(SSL_CERT_FLAG_SUITEB_128_LOS|SSL_CERT_FLAG_TLS_STRICT)

typedef struct {
	unsigned short ext_type;
	custom_cli_ext_first_cb_fn fn1; 
	custom_cli_ext_second_cb_fn fn2; 
	void *arg;
} custom_cli_ext_record;

typedef struct {
	unsigned short ext_type;
	custom_srv_ext_first_cb_fn fn1; 
	custom_srv_ext_second_cb_fn fn2; 
	void *arg;
} custom_srv_ext_record;

typedef struct cert_st
	{
	/* Current active set */
@@ -628,6 +642,12 @@ typedef struct cert_st
	unsigned char *ciphers_raw;
	size_t ciphers_rawlen;

	/* Arrays containing the callbacks for custom TLS Extensions. */
	custom_cli_ext_record *custom_cli_ext_records;
	size_t custom_cli_ext_records_count;
	custom_srv_ext_record *custom_srv_ext_records;
	size_t custom_srv_ext_records_count;

	/* Security callback */
	int (*sec_cb)(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex);
	/* Security level */
Loading