Commit e27711cf authored by Trevor's avatar Trevor Committed by Ben Laurie
Browse files

Trying cherrypick:

Add support for arbitrary TLS extensions.

Contributed by Trevor Perrin.

Conflicts:

	CHANGES
	ssl/ssl.h
	ssl/ssltest.c
	test/testssl

Fix compilation due to #endif.

Cherrypicking more stuff.

Cleanup of custom extension stuff.

serverinfo rejects non-empty extensions.

Omit extension if no relevant serverinfo data.

Improve error-handling in serverinfo callback.

Cosmetic cleanups.

s_client documentation.

s_server documentation.

SSL_CTX_serverinfo documentation.

Cleaup -1 and NULL callback handling for custom extensions, add tests.

Cleanup ssl_rsa.c serverinfo code.

Whitespace cleanup.

Improve comments in ssl.h for serverinfo.

Whitespace.

Cosmetic cleanup.

Reject non-zero-len serverinfo extensions.

Whitespace.

Make it build.

Conflicts:

	test/testssl
parent 28c08222
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -4,6 +4,9 @@


 Changes between 1.0.1 and 1.0.2 [xx XXX xxxx]
 Changes between 1.0.1 and 1.0.2 [xx XXX xxxx]


  *) Add callbacks for arbitrary TLS extensions.
     [Trevor Perrin <trevp@trevp.net> and Ben Laurie]

  *) New option -crl_download in several openssl utilities to download CRLs
  *) New option -crl_download in several openssl utilities to download CRLs
     from CRLDP extension in certificates.
     from CRLDP extension in certificates.
     [Steve Henson]
     [Steve Henson]
+62 −0
Original line number Original line Diff line number Diff line
@@ -364,6 +364,9 @@ static void sc_usage(void)
# ifndef OPENSSL_NO_NEXTPROTONEG
# ifndef OPENSSL_NO_NEXTPROTONEG
	BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
	BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
# endif
# endif
#ifndef OPENSSL_NO_TLSEXT
	BIO_printf(bio_err," -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
#endif
#endif
#endif
	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
	BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
	BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
@@ -541,6 +544,26 @@ static int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, con
	return SSL_TLSEXT_ERR_OK;
	return SSL_TLSEXT_ERR_OK;
	}
	}
# endif  /* ndef OPENSSL_NO_NEXTPROTONEG */
# endif  /* ndef OPENSSL_NO_NEXTPROTONEG */

static int serverinfo_cli_cb(SSL* s, unsigned short ext_type,
			     const unsigned char* in, unsigned short inlen, 
			     int* al, void* arg)
	{
	char pem_name[100];
	unsigned char ext_buf[4 + 65536];

	/* Reconstruct the type/len fields prior to extension data */
	ext_buf[0] = ext_type >> 8;
	ext_buf[1] = ext_type & 0xFF;
	ext_buf[2] = inlen >> 8;
	ext_buf[3] = inlen & 0xFF;
	memcpy(ext_buf+4, in, inlen);

	BIO_snprintf(pem_name, sizeof(pem_name), "SERVER_INFO %d", ext_type);
	PEM_write_bio(bio_c_out, pem_name, "", ext_buf, 4 + inlen);
	return 1;
	}

#endif
#endif


enum
enum
@@ -613,6 +636,9 @@ int MAIN(int argc, char **argv)
# ifndef OPENSSL_NO_NEXTPROTONEG
# ifndef OPENSSL_NO_NEXTPROTONEG
	const char *next_proto_neg_in = NULL;
	const char *next_proto_neg_in = NULL;
# endif
# endif
# define MAX_SI_TYPES 100
	unsigned short serverinfo_types[MAX_SI_TYPES];
	int serverinfo_types_count = 0;
#endif
#endif
	char *sess_in = NULL;
	char *sess_in = NULL;
	char *sess_out = NULL;
	char *sess_out = NULL;
@@ -949,6 +975,29 @@ static char *jpake_secret = NULL;
			next_proto_neg_in = *(++argv);
			next_proto_neg_in = *(++argv);
			}
			}
# endif
# endif
		else if (strcmp(*argv,"-serverinfo") == 0)
			{
			char *c;
			int start = 0;
			int len;

			if (--argc < 1) goto bad;
			c = *(++argv);
			serverinfo_types_count = 0;
			len = strlen(c);
			for (i = 0; i <= len; ++i)
				{
				if (i == len || c[i] == ',')
					{
					serverinfo_types[serverinfo_types_count]
					    = atoi(c+start);
					serverinfo_types_count++;
					start = i+1;
					}
				if (serverinfo_types_count == MAX_SI_TYPES)
					break;
				}
			}
#endif
#endif
#ifdef FIONBIO
#ifdef FIONBIO
		else if (strcmp(*argv,"-nbio") == 0)
		else if (strcmp(*argv,"-nbio") == 0)
@@ -1242,6 +1291,19 @@ bad:
	if (next_proto.data)
	if (next_proto.data)
		SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
		SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
#endif
#endif
#ifndef OPENSSL_NO_TLSEXT
		if (serverinfo_types_count)
			{
			for (i = 0; i < serverinfo_types_count; i++)
				{
				SSL_CTX_set_custom_cli_ext(ctx,
							   serverinfo_types[i],
							   NULL, 
							   serverinfo_cli_cb,
							   NULL);
				}
			}
#endif


	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
#if 0
#if 0
+15 −0
Original line number Original line Diff line number Diff line
@@ -311,6 +311,8 @@ static int cert_chain = 0;
#ifndef OPENSSL_NO_TLSEXT
#ifndef OPENSSL_NO_TLSEXT
static BIO *authz_in = NULL;
static BIO *authz_in = NULL;
static const char *s_authz_file = NULL;
static const char *s_authz_file = NULL;
static BIO *serverinfo_in = NULL;
static const char *s_serverinfo_file = NULL;
#endif
#endif


#ifndef OPENSSL_NO_PSK
#ifndef OPENSSL_NO_PSK
@@ -471,6 +473,9 @@ static void sv_usage(void)
	BIO_printf(bio_err," -cert arg     - certificate file to use\n");
	BIO_printf(bio_err," -cert arg     - certificate file to use\n");
	BIO_printf(bio_err,"                 (default is %s)\n",TEST_CERT);
	BIO_printf(bio_err,"                 (default is %s)\n",TEST_CERT);
	BIO_printf(bio_err," -authz arg   -  binary authz file for certificate\n");
	BIO_printf(bio_err," -authz arg   -  binary authz file for certificate\n");
#ifndef OPENSSL_NO_TLSEXT
	BIO_printf(bio_err," -serverinfo arg - PEM serverinfo file for certificate\n");
#endif
	BIO_printf(bio_err," -crl_check    - check the peer certificate has not been revoked by its CA.\n" \
	BIO_printf(bio_err," -crl_check    - check the peer certificate has not been revoked by its CA.\n" \
	                   "                 The CRL(s) are appended to the certificate file\n");
	                   "                 The CRL(s) are appended to the certificate file\n");
	BIO_printf(bio_err," -crl_check_all - check the peer certificate has not been revoked by its CA\n" \
	BIO_printf(bio_err," -crl_check_all - check the peer certificate has not been revoked by its CA\n" \
@@ -1065,6 +1070,11 @@ int MAIN(int argc, char *argv[])
			if (--argc < 1) goto bad;
			if (--argc < 1) goto bad;
			s_authz_file = *(++argv);
			s_authz_file = *(++argv);
			}
			}
		else if	(strcmp(*argv,"-serverinfo") == 0)
			{
			if (--argc < 1) goto bad;
			s_serverinfo_file = *(++argv);
			}
#endif
#endif
		else if	(strcmp(*argv,"-certform") == 0)
		else if	(strcmp(*argv,"-certform") == 0)
			{
			{
@@ -1796,6 +1806,9 @@ bad:
#ifndef OPENSSL_NO_TLSEXT
#ifndef OPENSSL_NO_TLSEXT
	if (s_authz_file != NULL && !SSL_CTX_use_authz_file(ctx, s_authz_file))
	if (s_authz_file != NULL && !SSL_CTX_use_authz_file(ctx, s_authz_file))
		goto end;
		goto end;
	if (s_serverinfo_file != NULL
	    && !SSL_CTX_use_serverinfo_file(ctx, s_serverinfo_file))
		goto end;
#endif
#endif
#ifndef OPENSSL_NO_TLSEXT
#ifndef OPENSSL_NO_TLSEXT
	if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL, build_chain))
	if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL, build_chain))
@@ -1963,6 +1976,8 @@ end:
		EVP_PKEY_free(s_key2);
		EVP_PKEY_free(s_key2);
	if (authz_in != NULL)
	if (authz_in != NULL)
		BIO_free(authz_in);
		BIO_free(authz_in);
	if (serverinfo_in != NULL)
		BIO_free(serverinfo_in);
#endif
#endif
	ssl_excert_free(exc);
	ssl_excert_free(exc);
	if (ssl_args)
	if (ssl_args)
+8 −0
Original line number Original line Diff line number Diff line
@@ -43,6 +43,7 @@ B<openssl> B<s_client>
[B<-sess_out filename>]
[B<-sess_out filename>]
[B<-sess_in filename>]
[B<-sess_in filename>]
[B<-rand file(s)>]
[B<-rand file(s)>]
[B<-serverinfo types>]


=head1 DESCRIPTION
=head1 DESCRIPTION


@@ -237,6 +238,13 @@ Multiple files can be specified separated by a OS-dependent character.
The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
all others.
all others.


=item B<-serverinfo types>

a list of comma-separated TLS Extension Types (numbers between 0 and 
65535).  Each type will be sent as an empty ClientHello TLS Extension.
The server's response (if any) will be encoded and displayed as a PEM
file.

=back
=back


=head1 CONNECTED COMMANDS
=head1 CONNECTED COMMANDS
+9 −0
Original line number Original line Diff line number Diff line
@@ -54,6 +54,7 @@ B<openssl> B<s_server>
[B<-no_ticket>]
[B<-no_ticket>]
[B<-id_prefix arg>]
[B<-id_prefix arg>]
[B<-rand file(s)>]
[B<-rand file(s)>]
[B<-serverinfo file>]


=head1 DESCRIPTION
=head1 DESCRIPTION


@@ -276,6 +277,14 @@ Multiple files can be specified separated by a OS-dependent character.
The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
all others.
all others.


=item B<-serverinfo file>

a file containing one or more blocks of PEM data.  Each PEM block
must encode a TLS ServerHello extension (2 bytes type, 2 bytes length,
followed by "length" bytes of extension data).  If the client sends
an empty TLS ClientHello extension matching the type, the corresponding
ServerHello extension will be returned.

=back
=back


=head1 CONNECTED COMMANDS
=head1 CONNECTED COMMANDS
Loading