From 1e0d466f198842cfed14f4fae906381c39bd2050 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Wed, 19 Sep 2012 12:14:20 +0200 Subject: ssl: Changed default behaviour of next protocol negotiation to make more "sense" (be true to the specification). --- lib/ssl/src/ssl.erl | 26 ++++++++++++++++---------- lib/ssl/src/ssl_handshake.erl | 8 ++++---- lib/ssl/src/ssl_handshake.hrl | 2 ++ 3 files changed, 22 insertions(+), 14 deletions(-) (limited to 'lib/ssl/src') diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index 9ed6acd43a..c72c4d7a93 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -39,6 +39,7 @@ -include("ssl_internal.hrl"). -include("ssl_record.hrl"). -include("ssl_cipher.hrl"). +-include("ssl_handshake.hrl"). -include_lib("public_key/include/public_key.hrl"). @@ -745,11 +746,16 @@ validate_option(hibernate_after, Value) when is_integer(Value), Value >= 0 -> validate_option(erl_dist,Value) when Value == true; Value == false -> Value; -validate_option(client_preferred_next_protocols, {FallbackProtocol, Order, PreferredProtocols} = Value) - when is_list(PreferredProtocols), is_binary(FallbackProtocol), - byte_size(FallbackProtocol) > 0, byte_size(FallbackProtocol) < 256 -> +validate_option(client_preferred_next_protocols, {Precedence, PreferredProtocols}) + when is_list(PreferredProtocols) -> validate_binary_list(client_preferred_next_protocols, PreferredProtocols), - validate_npn_ordering(Order), + validate_npn_ordering(Precedence), + {Precedence, PreferredProtocols, ?NO_PROTOCOL}; +validate_option(client_preferred_next_protocols, {Precedence, PreferredProtocols, Default} = Value) + when is_list(PreferredProtocols), is_binary(Default), + byte_size(Default) > 0, byte_size(Default) < 256 -> + validate_binary_list(client_preferred_next_protocols, PreferredProtocols), + validate_npn_ordering(Precedence), Value; validate_option(client_preferred_next_protocols, undefined) -> undefined; @@ -766,7 +772,7 @@ validate_npn_ordering(client) -> validate_npn_ordering(server) -> ok; validate_npn_ordering(Value) -> - throw({error, {eoptions, {client_preferred_next_protocols, Value}}}). + throw({error, {eoptions, {client_preferred_next_protocols, {invalid_precedence, Value}}}}). validate_binary_list(Opt, List) -> lists:foreach( @@ -775,7 +781,7 @@ validate_binary_list(Opt, List) -> byte_size(Bin) < 256 -> ok; (Bin) -> - throw({error, {eoptions, {Opt, Bin}}}) + throw({error, {eoptions, {Opt, {invalid_protocol, Bin}}}}) end, List). validate_versions([], Versions) -> @@ -896,18 +902,18 @@ detect(Pred, [H|T]) -> make_next_protocol_selector(undefined) -> undefined; -make_next_protocol_selector({FallbackProtocol, client, AllProtocols}) -> +make_next_protocol_selector({client, AllProtocols, DefaultProtocol}) -> fun(AdvertisedProtocols) -> case detect(fun(PreferredProtocol) -> lists:member(PreferredProtocol, AdvertisedProtocols) end, AllProtocols) of - undefined -> FallbackProtocol; + undefined -> DefaultProtocol; PreferredProtocol -> PreferredProtocol end end; -make_next_protocol_selector({FallbackProtocol, server, AllProtocols}) -> +make_next_protocol_selector({server, AllProtocols, DefaultProtocol}) -> fun(AdvertisedProtocols) -> case detect(fun(PreferredProtocol) -> lists:member(PreferredProtocol, AllProtocols) end, AdvertisedProtocols) of - undefined -> FallbackProtocol; + undefined -> DefaultProtocol; PreferredProtocol -> PreferredProtocol end end. diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index 3b114c1f9c..695721d51a 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -741,10 +741,10 @@ select_next_protocol({error, _Reason}, _NextProtocolSelector) -> ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); select_next_protocol(Protocols, NextProtocolSelector) -> case NextProtocolSelector(Protocols) of - Protocol when is_binary(Protocol), byte_size(Protocol) > 0 -> - Protocol; - _ -> - ?ALERT_REC(?FATAL, ?INTERNAL_ERROR) % we are broken internally :( api presently stops this but we might let it happen in future + ?NO_PROTOCOL -> + ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE); + Protocol when is_binary(Protocol) -> + Protocol end. handle_renegotiation_info(_, #renegotiation_info{renegotiated_connection = ?byte(0)}, diff --git a/lib/ssl/src/ssl_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl index bd583e5d92..a4ce48c291 100644 --- a/lib/ssl/src/ssl_handshake.hrl +++ b/lib/ssl/src/ssl_handshake.hrl @@ -33,6 +33,8 @@ -type public_key_info() :: {algo_oid(), #'RSAPublicKey'{} | integer() , public_key_params()}. -type tls_handshake_history() :: {[binary()], [binary()]}. +-define(NO_PROTOCOL, <<>>). + %% Signature algorithms -define(ANON, 0). -define(RSA, 1). -- cgit v1.2.3