diff options
Diffstat (limited to 'lib/ssl/src')
-rw-r--r-- | lib/ssl/src/ssl.erl | 36 | ||||
-rw-r--r-- | lib/ssl/src/ssl_connection.erl | 56 | ||||
-rw-r--r-- | lib/ssl/src/ssl_internal.hrl | 3 | ||||
-rw-r--r-- | lib/ssl/src/ssl_ssl3.erl | 5 | ||||
-rw-r--r-- | lib/ssl/src/ssl_tls1.erl | 5 |
5 files changed, 57 insertions, 48 deletions
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index 7e5929d708..0e108c430f 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% Copyright Ericsson AB 1999-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -49,6 +49,27 @@ inet_ssl, %% inet options for internal ssl socket cb %% Callback info }). +-type option() :: socketoption() | ssloption() | transportoption(). +-type socketoption() :: [{property(), term()}]. %% See gen_tcp and inet +-type property() :: atom(). + +-type ssloption() :: {verify, verify_type()} | + {verify_fun, {fun(), InitialUserState::term()}} | + {fail_if_no_peer_cert, boolean()} | {depth, integer()} | + {cert, der_encoded()} | {certfile, path()} | {key, der_encoded()} | + {keyfile, path()} | {password, string()} | {cacerts, [der_encoded()]} | + {cacertfile, path()} | {dh, der_encoded()} | {dhfile, path()} | + {ciphers, ciphers()} | {ssl_imp, ssl_imp()} | {reuse_sessions, boolean()} | + {reuse_session, fun()}. + +-type verify_type() :: verify_none | verify_peer. +-type path() :: string(). +-type ciphers() :: [erl_cipher_suite()] | + string(). % (according to old API) +-type ssl_imp() :: new | old. + +-type transportoption() :: {CallbackModule::atom(), DataTag::atom(), ClosedTag::atom()}. + %%-------------------------------------------------------------------- -spec start() -> ok. @@ -77,8 +98,8 @@ stop() -> application:stop(ssl). %%-------------------------------------------------------------------- --spec connect(host() | port(), list()) -> {ok, #sslsocket{}}. --spec connect(host() | port(), list() | port_num(), timeout() | list()) -> {ok, #sslsocket{}}. +-spec connect(host() | port(), [option()]) -> {ok, #sslsocket{}}. +-spec connect(host() | port(), [option()] | port_num(), timeout() | list()) -> {ok, #sslsocket{}}. -spec connect(host() | port(), port_num(), list(), timeout()) -> {ok, #sslsocket{}}. %% @@ -126,7 +147,7 @@ connect(Host, Port, Options0, Timeout) -> end. %%-------------------------------------------------------------------- --spec listen(port_num(), list()) ->{ok, #sslsocket{}} | {error, reason()}. +-spec listen(port_num(), [option()]) ->{ok, #sslsocket{}} | {error, reason()}. %% %% Description: Creates a ssl listen socket. @@ -189,9 +210,10 @@ transport_accept(#sslsocket{} = ListenSocket, Timeout) -> ssl_broker:transport_accept(Pid, ListenSocket, Timeout). %%-------------------------------------------------------------------- --spec ssl_accept(#sslsocket{}) -> {ok, #sslsocket{}} | {error, reason()}. --spec ssl_accept(#sslsocket{}, list() | timeout()) -> {ok, #sslsocket{}} | {error, reason()}. --spec ssl_accept(port(), list(), timeout()) -> {ok, #sslsocket{}} | {error, reason()}. +-spec ssl_accept(#sslsocket{}) -> ok | {error, reason()}. +-spec ssl_accept(#sslsocket{} | port(), timeout()| [option()]) -> + ok | {ok, #sslsocket{}} | {error, reason()}. +-spec ssl_accept(port(), [option()], timeout()) -> {ok, #sslsocket{}} | {error, reason()}. %% %% Description: Performs accept on a ssl listen socket. e.i. performs %% ssl handshake. diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 675e5e44bd..489895cf29 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2010. All Rights Reserved. +%% Copyright Ericsson AB 2007-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -70,7 +70,6 @@ %% {{md5_hash, sha_hash}, {prev_md5, prev_sha}} (binary()) tls_handshake_hashes, % see above tls_cipher_texts, % list() received but not deciphered yet - own_cert, % binary() | undefined session, % #session{} from ssl_handshake.hrl session_cache, % session_cache_cb, % @@ -307,7 +306,6 @@ init([Role, Host, Port, Socket, {SSLOpts0, _} = Options, {ok, Ref, CacheRef, OwnCert, Key, DHParams} -> Session = State0#state.session, State = State0#state{tls_handshake_hashes = Hashes0, - own_cert = OwnCert, session = Session#session{own_certificate = OwnCert}, cert_db_ref = Ref, session_cache = CacheRef, @@ -334,12 +332,10 @@ init([Role, Host, Port, Socket, {SSLOpts0, _} = Options, %%-------------------------------------------------------------------- hello(start, #state{host = Host, port = Port, role = client, ssl_options = SslOpts, - own_cert = Cert, + session = #session{own_certificate = Cert} = Session0, transport_cb = Transport, socket = Socket, connection_states = ConnectionStates, - renegotiation = {Renegotiation, _}} - = State0) -> - + renegotiation = {Renegotiation, _}} = State0) -> Hello = ssl_handshake:client_hello(Host, Port, ConnectionStates, SslOpts, Renegotiation, Cert), @@ -351,13 +347,13 @@ hello(start, #state{host = Host, port = Port, role = client, Transport:send(Socket, BinMsg), State1 = State0#state{connection_states = CS2, negotiated_version = Version, %% Requested version - session = - #session{session_id = Hello#client_hello.session_id, - is_resumable = false}, + session = + Session0#session{session_id = Hello#client_hello.session_id, + is_resumable = false}, tls_handshake_hashes = Hashes1}, {Record, State} = next_record(State1), next_state(hello, Record, State); - + hello(start, #state{role = server} = State0) -> {Record, State} = next_record(State0), next_state(hello, Record, State); @@ -374,7 +370,6 @@ hello(#server_hello{cipher_suite = CipherSuite, negotiated_version = ReqVersion, renegotiation = {Renegotiation, _}, ssl_options = SslOptions} = State0) -> - case ssl_handshake:hello(Hello, SslOptions, ConnectionStates0, Renegotiation) of {Version, NewId, ConnectionStates} -> {KeyAlgorithm, _, _} = @@ -400,13 +395,11 @@ hello(#server_hello{cipher_suite = CipherSuite, hello(Hello = #client_hello{client_version = ClientVersion}, State = #state{connection_states = ConnectionStates0, - port = Port, session = Session0, + port = Port, session = #session{own_certificate = Cert} = Session0, renegotiation = {Renegotiation, _}, session_cache = Cache, session_cache_cb = CacheCb, - ssl_options = SslOpts, - own_cert = Cert}) -> - + ssl_options = SslOpts}) -> case ssl_handshake:hello(Hello, SslOpts, {Port, Session0, Cache, CacheCb, ConnectionStates0, Cert}, Renegotiation) of {Version, {Type, Session}, ConnectionStates} -> @@ -540,7 +533,7 @@ certify(#server_hello_done{}, connection_states = ConnectionStates0, negotiated_version = Version, premaster_secret = undefined, - role = client} = State0) -> + role = client} = State0) -> case ssl_handshake:master_secret(Version, Session, ConnectionStates0, client) of {MasterSecret, ConnectionStates1} -> @@ -617,7 +610,6 @@ certify_client_key_exchange(#client_diffie_hellman_public{dh_public = ClientPubl diffie_hellman_params = #'DHParameter'{prime = P, base = G}, diffie_hellman_keys = {_, ServerDhPrivateKey}} = State0) -> - case dh_master_secret(crypto:mpint(P), crypto:mpint(G), ClientPublicDhKey, ServerDhPrivateKey, State0) of #state{} = State1 -> {Record, State} = next_record(State1), @@ -660,8 +652,7 @@ cipher(#finished{verify_data = Data} = Finished, role = Role, session = #session{master_secret = MasterSecret} = Session0, - tls_handshake_hashes = Hashes0} = State) -> - + tls_handshake_hashes = Hashes0} = State) -> case ssl_handshake:verify_connection(Version, Finished, opposite_role(Role), MasterSecret, Hashes0) of @@ -682,14 +673,13 @@ cipher(Msg, State) -> %%-------------------------------------------------------------------- connection(#hello_request{}, #state{host = Host, port = Port, socket = Socket, - own_cert = Cert, + session = #session{own_certificate = Cert}, ssl_options = SslOpts, negotiated_version = Version, transport_cb = Transport, connection_states = ConnectionStates0, renegotiation = {Renegotiation, _}, tls_handshake_hashes = Hashes0} = State0) -> - Hello = ssl_handshake:client_hello(Host, Port, ConnectionStates0, SslOpts, Renegotiation, Cert), @@ -1096,6 +1086,7 @@ init_private_key({rsa, PrivateKey}, _, _,_) -> init_private_key({dsa, PrivateKey},_,_,_) -> public_key:der_decode('DSAPrivateKey', PrivateKey). +-spec(handle_file_error/6 :: (_,_,_,_,_,_) -> no_return()). handle_file_error(Line, Error, {badmatch, Reason}, File, Throw, Stack) -> file_error(Line, Error, Reason, File, Throw, Stack); handle_file_error(Line, Error, Reason, File, Throw, Stack) -> @@ -1161,7 +1152,7 @@ certify_client(#state{client_certificate_requested = true, role = client, transport_cb = Transport, negotiated_version = Version, cert_db_ref = CertDbRef, - own_cert = OwnCert, + session = #session{own_certificate = OwnCert}, socket = Socket, tls_handshake_hashes = Hashes0} = State) -> Certificate = ssl_handshake:certificate(OwnCert, CertDbRef, client), @@ -1177,10 +1168,10 @@ verify_client_cert(#state{client_certificate_requested = true, role = client, connection_states = ConnectionStates0, transport_cb = Transport, negotiated_version = Version, - own_cert = OwnCert, socket = Socket, private_key = PrivateKey, - session = #session{master_secret = MasterSecret}, + session = #session{master_secret = MasterSecret, + own_certificate = OwnCert}, tls_handshake_hashes = Hashes0} = State) -> case ssl_handshake:client_certificate_verify(OwnCert, MasterSecret, @@ -1346,7 +1337,7 @@ certify_server(#state{transport_cb = Transport, connection_states = ConnectionStates, tls_handshake_hashes = Hashes, cert_db_ref = CertDbRef, - own_cert = OwnCert} = State) -> + session = #session{own_certificate = OwnCert}} = State) -> case ssl_handshake:certificate(OwnCert, CertDbRef, server) of CertMsg = #certificate{} -> {BinCertMsg, NewConnectionStates, NewHashes} = @@ -1373,7 +1364,6 @@ key_exchange(#state{role = server, key_algorithm = Algo, when Algo == dhe_dss; Algo == dhe_rsa; Algo == dh_anon -> - Keys = crypto:dh_generate_key([crypto:mpint(P), crypto:mpint(G)]), ConnectionState = ssl_record:pending_connection_state(ConnectionStates0, read), @@ -1925,14 +1915,22 @@ next_state_connection(StateName, #state{send_queue = Queue0, next_state_is_connection(State) end. +%% In next_state_is_connection/1: clear tls_handshake_hashes, +%% premaster_secret and public_key_info (only needed during handshake) +%% to reduce memory foot print of a connection. next_state_is_connection(State = #state{recv_during_renegotiation = true, socket_options = #socket_options{active = false}}) -> - passive_receive(State#state{recv_during_renegotiation = false}, connection); + passive_receive(State#state{recv_during_renegotiation = false, + premaster_secret = undefined, + public_key_info = undefined, + tls_handshake_hashes = {<<>>, <<>>}}, connection); next_state_is_connection(State0) -> {Record, State} = next_record_if_active(State0), - next_state(connection, Record, State). + next_state(connection, Record, State#state{premaster_secret = undefined, + public_key_info = undefined, + tls_handshake_hashes = {<<>>, <<>>}}). register_session(_, _, _, #session{is_resumable = true} = Session) -> Session; %% Already registered diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl index 43a85c2d9d..715941e3ad 100644 --- a/lib/ssl/src/ssl_internal.hrl +++ b/lib/ssl/src/ssl_internal.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2010. All Rights Reserved. +%% Copyright Ericsson AB 2007-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -19,7 +19,6 @@ %% - -ifndef(ssl_internal). -define(ssl_internal, true). diff --git a/lib/ssl/src/ssl_ssl3.erl b/lib/ssl/src/ssl_ssl3.erl index c49f9f1e6d..f2926b2d2f 100644 --- a/lib/ssl/src/ssl_ssl3.erl +++ b/lib/ssl/src/ssl_ssl3.erl @@ -102,11 +102,6 @@ mac_hash(Method, Mac_write_secret, Seq_num, Type, Length, Fragment) -> %% hash(MAC_write_secret + pad_1 + seq_num + %% SSLCompressed.type + SSLCompressed.length + %% SSLCompressed.fragment)); - case Method of - ?NULL -> ok; - _ -> - ok - end, Mac = mac_hash(Method, Mac_write_secret, [<<?UINT64(Seq_num), ?BYTE(Type), ?UINT16(Length)>>, Fragment]), diff --git a/lib/ssl/src/ssl_tls1.erl b/lib/ssl/src/ssl_tls1.erl index 3784483e9c..5f9850c386 100644 --- a/lib/ssl/src/ssl_tls1.erl +++ b/lib/ssl/src/ssl_tls1.erl @@ -128,11 +128,6 @@ mac_hash(Method, Mac_write_secret, Seq_num, Type, {Major, Minor}, %% HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type + %% TLSCompressed.version + TLSCompressed.length + %% TLSCompressed.fragment)); - case Method of - ?NULL -> ok; - _ -> - ok - end, Mac = hmac_hash(Method, Mac_write_secret, [<<?UINT64(Seq_num), ?BYTE(Type), ?BYTE(Major), ?BYTE(Minor), ?UINT16(Length)>>, |