Loading apps/s_client.c +39 −2 Original line number Diff line number Diff line Loading @@ -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"); Loading Loading @@ -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]; Loading Loading @@ -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) { Loading Loading @@ -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) Loading Loading @@ -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; Loading @@ -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 { Loading apps/s_server.c +67 −3 Original line number Diff line number Diff line Loading @@ -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"); Loading Loading @@ -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 **); Loading Loading @@ -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 Loading Loading @@ -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) Loading Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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 Loading Loading @@ -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) Loading ssl/s3_lib.c +13 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading ssl/ssl.h +45 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 */ Loading Loading @@ -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 */ Loading ssl/ssl3.h +10 −1 Original line number Diff line number Diff line Loading @@ -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 Loading
apps/s_client.c +39 −2 Original line number Diff line number Diff line Loading @@ -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"); Loading Loading @@ -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]; Loading Loading @@ -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) { Loading Loading @@ -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) Loading Loading @@ -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; Loading @@ -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 { Loading
apps/s_server.c +67 −3 Original line number Diff line number Diff line Loading @@ -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"); Loading Loading @@ -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 **); Loading Loading @@ -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 Loading Loading @@ -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) Loading Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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 Loading Loading @@ -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) Loading
ssl/s3_lib.c +13 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading
ssl/ssl.h +45 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 */ Loading Loading @@ -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 */ Loading
ssl/ssl3.h +10 −1 Original line number Diff line number Diff line Loading @@ -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