Commit 63fe3221 authored by Ben Laurie's avatar Ben Laurie
Browse files

Merge remote-tracking branch 'agl/1.0.2alpn' into agl-alpn

Conflicts:
	ssl/ssl3.h
	ssl/t1_lib.c
parents c8087980 8ae78c6b
Loading
Loading
Loading
Loading
+39 −2
Original line number Diff line number Diff line
@@ -368,6 +368,7 @@ static void sc_usage(void)
	BIO_printf(bio_err," -proof_debug      - request an audit proof and print its hex dump\n");
# 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," -alpn arg         - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
# endif
#ifndef OPENSSL_NO_TLSEXT
	BIO_printf(bio_err," -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
@@ -641,6 +642,7 @@ int MAIN(int argc, char **argv)
        {NULL,0};
# ifndef OPENSSL_NO_NEXTPROTONEG
	const char *next_proto_neg_in = NULL;
	const char *alpn_in = NULL;
# endif
# define MAX_SI_TYPES 100
	unsigned short serverinfo_types[MAX_SI_TYPES];
@@ -999,6 +1001,11 @@ static char *jpake_secret = NULL;
			if (--argc < 1) goto bad;
			next_proto_neg_in = *(++argv);
			}
		else if (strcmp(*argv,"-alpn") == 0)
			{
			if (--argc < 1) goto bad;
			alpn_in = *(++argv);
			}
# endif
		else if (strcmp(*argv,"-serverinfo") == 0)
			{
@@ -1312,9 +1319,24 @@ bad:
	 */
	if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);

#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
#if !defined(OPENSSL_NO_TLSEXT)
# if !defined(OPENSSL_NO_NEXTPROTONEG)
	if (next_proto.data)
		SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
# endif
	if (alpn_in)
		{
		unsigned short alpn_len;
		unsigned char *alpn = next_protos_parse(&alpn_len, alpn_in);

		if (alpn == NULL)
			{
			BIO_printf(bio_err, "Error parsing -alpn argument\n");
			goto end;
			}
		SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len);
		OPENSSL_free(alpn);
		}
#endif
#ifndef OPENSSL_NO_TLSEXT
		if (serverinfo_types_count)
@@ -2273,7 +2295,8 @@ static void print_stuff(BIO *bio, SSL *s, int full)
	}
#endif

#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
#if !defined(OPENSSL_NO_TLSEXT)
# if !defined(OPENSSL_NO_NEXTPROTONEG)
	if (next_proto.status != -1) {
		const unsigned char *proto;
		unsigned int proto_len;
@@ -2282,6 +2305,20 @@ static void print_stuff(BIO *bio, SSL *s, int full)
		BIO_write(bio, proto, proto_len);
		BIO_write(bio, "\n", 1);
	}
	{
		const unsigned char *proto;
		unsigned int proto_len;
		SSL_get0_alpn_selected(s, &proto, &proto_len);
		if (proto_len > 0)
			{
			BIO_printf(bio, "ALPN protocol: ");
			BIO_write(bio, proto, proto_len);
			BIO_write(bio, "\n", 1);
			}
		else
			BIO_printf(bio, "No ALPN negotiated\n");
	}
# endif
#endif

 	{
+67 −3
Original line number Diff line number Diff line
@@ -579,6 +579,7 @@ static void sv_usage(void)
	BIO_printf(bio_err," -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n");
# endif
        BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
	BIO_printf(bio_err," -alpn arg  - set the advertised protocols for the ALPN extension (comma-separated list)\n");
#endif
	BIO_printf(bio_err," -keymatexport label   - Export keying material using label\n");
	BIO_printf(bio_err," -keymatexportlen len  - Export len bytes of keying material (default 20)\n");
@@ -934,8 +935,47 @@ static int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len,
	}
# endif  /* ndef OPENSSL_NO_NEXTPROTONEG */

/* This the context that we pass to alpn_cb */
typedef struct tlsextalpnctx_st {
	unsigned char *data;
	unsigned short len;
} tlsextalpnctx;

#endif
static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
	{
	tlsextalpnctx *alpn_ctx = arg;

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

	if (SSL_select_next_proto((unsigned char**) out, outlen, alpn_ctx->data, alpn_ctx->len, in, inlen) !=
	    OPENSSL_NPN_NEGOTIATED)
		{
		return SSL_TLSEXT_ERR_NOACK;
		}

	if (!s_quiet)
		{
		BIO_printf(bio_s_out, "ALPN protocols selected: ");
		BIO_write(bio_s_out, *out, *outlen);
		BIO_write(bio_s_out, "\n", 1);
		}

	return SSL_TLSEXT_ERR_OK;
	}
#endif  /* ndef OPENSSL_NO_TLSEXT */

int MAIN(int, char **);

@@ -984,7 +1024,9 @@ int MAIN(int argc, char *argv[])
        tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
# ifndef OPENSSL_NO_NEXTPROTONEG
	const char *next_proto_neg_in = NULL;
	tlsextnextprotoctx next_proto;
	tlsextnextprotoctx next_proto = { NULL, 0};
	const char *alpn_in = NULL;
	tlsextalpnctx alpn_ctx = { NULL, 0};
# endif
#endif
#ifndef OPENSSL_NO_PSK
@@ -1435,6 +1477,11 @@ int MAIN(int argc, char *argv[])
			if (--argc < 1) goto bad;
			next_proto_neg_in = *(++argv);
			}
		else if	(strcmp(*argv,"-alpn") == 0)
			{
			if (--argc < 1) goto bad;
			alpn_in = *(++argv);
			}
# endif
#endif
#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
@@ -1562,7 +1609,8 @@ bad:
#endif /* OPENSSL_NO_TLSEXT */
		}

#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) 
#if !defined(OPENSSL_NO_TLSEXT)
# if !defined(OPENSSL_NO_NEXTPROTONEG) 
	if (next_proto_neg_in)
		{
		unsigned short len;
@@ -1576,6 +1624,16 @@ bad:
		next_proto.data = NULL;
		}
# endif
	alpn_ctx.data = NULL;
	if (alpn_in)
		{
		unsigned short len;
		alpn_ctx.data = next_protos_parse(&len, alpn_in);
		if (alpn_ctx.data == NULL)
			goto end;
		alpn_ctx.len = len;
		}
#endif

	if (crl_file)
		{
@@ -1812,6 +1870,8 @@ bad:
	if (next_proto.data)
		SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &next_proto);
# endif
	if (alpn_ctx.data)
		SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx);
#endif 

#ifndef OPENSSL_NO_DH
@@ -2041,6 +2101,10 @@ end:
		BIO_free(authz_in);
	if (serverinfo_in != NULL)
		BIO_free(serverinfo_in);
	if (next_proto.data)
		OPENSSL_free(next_proto.data);
	if (alpn_ctx.data)
		OPENSSL_free(alpn_ctx.data);
#endif
	ssl_excert_free(exc);
	if (ssl_args)
+13 −0
Original line number Diff line number Diff line
@@ -3020,6 +3020,11 @@ void ssl3_free(SSL *s)
		BIO_free(s->s3->handshake_buffer);
	}
	if (s->s3->handshake_dgst) ssl3_free_digest_list(s);
#ifndef OPENSSL_NO_TLSEXT
	if (s->s3->alpn_selected)
		OPENSSL_free(s->s3->alpn_selected);
#endif

#ifndef OPENSSL_NO_SRP
	SSL_SRP_CTX_free(s);
#endif
@@ -3101,6 +3106,14 @@ void ssl3_clear(SSL *s)
	if (s->s3->handshake_dgst) {
		ssl3_free_digest_list(s);
	}	

#if !defined(OPENSSL_NO_TLSEXT)
	if (s->s3->alpn_selected)
		{
		free(s->s3->alpn_selected);
		s->s3->alpn_selected = NULL;
		}
#endif
	memset(s->s3,0,sizeof *s->s3);
	s->s3->rbuf.buf = rp;
	s->s3->wbuf.buf = wp;
+45 −0
Original line number Diff line number Diff line
@@ -1100,6 +1100,31 @@ struct ssl_ctx_st
				    void *arg);
	void *next_proto_select_cb_arg;
# endif

	/* ALPN information
	 * (we are in the process of transitioning from NPN to ALPN.) */

	/* For a server, this contains a callback function that allows the
	 * server to select the protocol for the connection.
	 *   out: on successful return, this must point to the raw protocol
	 *        name (without the length prefix).
	 *   outlen: on successful return, this contains the length of |*out|.
	 *   in: points to the client's list of supported protocols in
	 *       wire-format.
	 *   inlen: the length of |in|. */
	int (*alpn_select_cb)(SSL *s,
			      const unsigned char **out,
			      unsigned char *outlen,
			      const unsigned char* in,
			      unsigned int inlen,
			      void *arg);
	void *alpn_select_cb_arg;

	/* For a client, this contains the list of supported protocols in wire
	 * format. */
	unsigned char* alpn_client_proto_list;
	unsigned alpn_client_proto_list_len;

        /* SRTP profiles we are willing to do from RFC 5764 */
	STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
# ifndef OPENSSL_NO_EC
@@ -1198,6 +1223,21 @@ void SSL_get0_next_proto_negotiated(const SSL *s,
#define OPENSSL_NPN_NO_OVERLAP	2
#endif

int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char* protos,
			    unsigned protos_len);
int SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos,
			unsigned protos_len);
void SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx,
				int (*cb) (SSL *ssl,
					   const unsigned char **out,
					   unsigned char *outlen,
					   const unsigned char *in,
					   unsigned int inlen,
					   void *arg),
				void *arg);
void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
			    unsigned *len);

#ifndef OPENSSL_NO_PSK
/* the maximum length of the buffer given to callbacks containing the
 * resulting identity/psk */
@@ -1504,6 +1544,11 @@ struct ssl_st
	                                 */
	unsigned int tlsext_hb_pending; /* Indicates if a HeartbeatRequest is in flight */
	unsigned int tlsext_hb_seq;     /* HeartbeatRequest sequence number */

	/* For a client, this contains the list of supported protocols in wire
	 * format. */
	unsigned char* alpn_client_proto_list;
	unsigned alpn_client_proto_list_len;
#else
#define session_ctx ctx
#endif /* OPENSSL_NO_TLSEXT */
+10 −1
Original line number Diff line number Diff line
@@ -590,7 +590,16 @@ typedef struct ssl3_state_st
	char is_probably_safari;
#endif /* !OPENSSL_NO_EC */

#endif /* !OPENSSL_NO_TLSEXT */
	/* ALPN information
	 * (we are in the process of transitioning from NPN to ALPN.) */

	/* In a server these point to the selected ALPN protocol after the
	 * ClientHello has been processed. In a client these contain the
	 * protocol that the server selected once the ServerHello has been
	 * processed. */
	unsigned char *alpn_selected;
	unsigned alpn_selected_len;
#endif	/* OPENSSL_NO_TLSEXT */
	} SSL3_STATE;

#endif
Loading