Commit ee2ffc27 authored by Ben Laurie's avatar Ben Laurie
Browse files

Add Next Protocol Negotiation.

parent b122e482
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -4,6 +4,12 @@

 Changes between 1.0.0 and 1.1.0  [xx XXX xxxx]

  *) Add Next Protocol Negotiation,
     http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-00. Can be
     disabled with a no-npn flag to config or Configure. Code donated
     by Google.
     [Adam Langley <agl@google.com> and Ben Laurie]

  *) Use type ossl_ssize_t instad of ssize_t which isn't available on
     all platforms. Move ssize_t definition from e_os.h to the public
     header file e_os2.h as it now appears in public header file cms.h
+1 −1
Original line number Diff line number Diff line
@@ -168,7 +168,7 @@ my %table=(
"debug-ben",	"gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown):::::bn86-elf.o co86-elf.o",
"debug-ben-openbsd","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown)::::",
"debug-ben-openbsd-debug","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -g3 -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown)::::",
"debug-ben-debug",	"gcc:$gcc_devteam_warn -DBN_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DDEBUG_SAFESTACK -g3 -O2 -pipe::(unknown)::::::",
"debug-ben-debug",	"gcc:$gcc_devteam_warn -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -g3 -O2 -pipe::(unknown)::::::",
"debug-ben-no-opt",	"gcc: -Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -DDEBUG_SAFESTACK -DCRYPTO_MDEBUG -Werror -DL_ENDIAN -DTERMIOS -Wall -g3::(unknown)::::::",
"debug-ben-strict",	"gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DCONST_STRICT -O2 -Wall -Wshadow -Werror -Wpointer-arith -Wcast-qual -Wwrite-strings -pipe::(unknown)::::::",
"debug-rse","cc:-DTERMIOS -DL_ENDIAN -pipe -O -g -ggdb3 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}",
+43 −0
Original line number Diff line number Diff line
@@ -3031,3 +3031,46 @@ int raw_write_stdout(const void *buf,int siz)
int raw_write_stdout(const void *buf,int siz)
	{	return write(fileno(stdout),buf,siz);	}
#endif

#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NPN)
/* next_protos_parse parses a comma separated list of strings into a string
 * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
 *   outlen: (output) set to the length of the resulting buffer on success.
 *   in: a NUL termianted string like "abc,def,ghi"
 *
 *   returns: a malloced buffer or NULL on failure.
 */
unsigned char *next_protos_parse(unsigned short *outlen, const char *in)
	{
	size_t len;
	unsigned char *out;
	size_t i, start = 0;

	len = strlen(in);
	if (len > 65535)
		return NULL;

	out = OPENSSL_malloc(strlen(in) + 1);
	if (!out)
		return NULL;

	for (i = 0; i <= len; ++i)
		{
		if (i == len || in[i] == ',')
			{
			if (i - start > 255)
				{
				OPENSSL_free(out);
				return NULL;
				}
			out[start] = i - start;
			start = i + 1;
			}
		else
			out[i+1] = in[i];
		}

	*outlen = len + 1;
	return out;
	}
#endif  /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NPN */
+4 −0
Original line number Diff line number Diff line
@@ -364,3 +364,7 @@ int raw_write_stdout(const void *,int);
#define TM_STOP		1
double app_tminterval (int stop,int usertime);
#endif

#ifndef OPENSSL_NO_NPN
unsigned char *next_protos_parse(unsigned short *outlen, const char *in);
#endif
+79 −0
Original line number Diff line number Diff line
@@ -343,6 +343,9 @@ static void sc_usage(void)
	BIO_printf(bio_err," -tlsextdebug      - hex dump of all TLS extensions received\n");
	BIO_printf(bio_err," -status           - request certificate status from server\n");
	BIO_printf(bio_err," -no_ticket        - disable use of RFC4507bis session tickets\n");
# ifndef OPENSSL_NO_NPN
	BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
# endif
#endif
	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
	}
@@ -367,6 +370,40 @@ static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
	
	return SSL_TLSEXT_ERR_OK;
	}

# ifndef OPENSSL_NO_NPN
/* This the context that we pass to next_proto_cb */
typedef struct tlsextnextprotoctx_st {
	unsigned char *data;
	unsigned short len;
	int status;
} tlsextnextprotoctx;

static tlsextnextprotoctx next_proto;

static int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
	{
	tlsextnextprotoctx *ctx = arg;

	if (!c_quiet)
		{
		/* We can assume that |in| is syntactically valid. */
		unsigned i;
		BIO_printf(bio_c_out, "Protocols advertised by server: ");
		for (i = 0; i < inlen; )
			{
			if (i)
				BIO_write(bio_c_out, ", ", 2);
			BIO_write(bio_c_out, &in[i + 1], in[i]);
			i += in[i] + 1;
			}
		BIO_write(bio_c_out, "\n", 1);
		}

	ctx->status = SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
	return SSL_TLSEXT_ERR_OK;
	}
# endif  /* ndef OPENSSL_NO_NPN */
#endif

enum
@@ -430,6 +467,9 @@ int MAIN(int argc, char **argv)
	char *servername = NULL; 
        tlsextctx tlsextcbp = 
        {NULL,0};
# ifndef OPENSSL_NO_NPN
	const char *next_proto_neg_in = NULL;
# endif
#endif
	char *sess_in = NULL;
	char *sess_out = NULL;
@@ -661,6 +701,13 @@ int MAIN(int argc, char **argv)
#ifndef OPENSSL_NO_TLSEXT
		else if	(strcmp(*argv,"-no_ticket") == 0)
			{ off|=SSL_OP_NO_TICKET; }
# ifndef OPENSSL_NO_NPN
		else if (strcmp(*argv,"-nextprotoneg") == 0)
			{
			if (--argc < 1) goto bad;
			next_proto_neg_in = *(++argv);
			}
# endif
#endif
		else if (strcmp(*argv,"-serverpref") == 0)
			off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
@@ -767,6 +814,21 @@ bad:
	OpenSSL_add_ssl_algorithms();
	SSL_load_error_strings();

#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NPN)
	next_proto.status = -1;
	if (next_proto_neg_in)
		{
		next_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in);
		if (next_proto.data == NULL)
			{
			BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n");
			goto end;
			}
		}
	else
		next_proto.data = NULL;
#endif

#ifndef OPENSSL_NO_ENGINE
        e = setup_engine(bio_err, engine_id, 1);
	if (ssl_client_engine_id)
@@ -888,6 +950,11 @@ bad:
	 */
	if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);

#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NPN)
	if (next_proto.data)
		SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
#endif

	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
	if (cipher != NULL)
		if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
@@ -1747,6 +1814,18 @@ static void print_stuff(BIO *bio, SSL *s, int full)
	BIO_printf(bio,"Expansion: %s\n",
		expansion ? SSL_COMP_get_name(expansion) : "NONE");
#endif

#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NPN)
	if (next_proto.status != -1) {
		const unsigned char *proto;
		unsigned int proto_len;
		SSL_get0_next_proto_negotiated(s, &proto, &proto_len);
		BIO_printf(bio, "Next protocol: (%d) ", next_proto.status);
		BIO_write(bio, proto, proto_len);
		BIO_write(bio, "\n", 1);
	}
#endif

	SSL_SESSION_print(bio,SSL_get_session(s));
	BIO_printf(bio,"---\n");
	if (peer != NULL)
Loading