Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
3741-ssl-Enhance-documentation.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 3741-ssl-Enhance-documentation.patch of Package erlang
From 78989bdfe7970e4c62fae81e028a1be105a6d9cd Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin <ingela@erlang.org> Date: Fri, 22 Apr 2022 09:56:35 +0200 Subject: [PATCH] ssl: Enhance documentation Update users guide to use new option and encourage good option choices. Make default value clarification in refrence manual --- lib/ssl/doc/src/ssl.xml | 32 +++-- lib/ssl/doc/src/using_ssl.xml | 263 +++++++++++++++++----------------- 2 files changed, 149 insertions(+), 146 deletions(-) diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml index 3d3cc28a47..ef74c287e6 100644 --- a/lib/ssl/doc/src/ssl.xml +++ b/lib/ssl/doc/src/ssl.xml @@ -996,9 +996,14 @@ fun(srp, Username :: binary(), UserState :: term()) -> <datatype> <name name="client_verify_type"/> - <desc><p>In mode <c>verify_none</c> the default behavior is to allow - all x509-path validation errors. See also option <seetype marker="#custom_verify">verify_fun</seetype>.</p> - </desc> + <desc> + <p>Defaults to <c>verify_none</c> as additional options are needed to be able to perform the certificate verification. + A warning will be emitted unless <c>verify_none</c> is explicitly configured. Usually the applications will want to configure + <c>verify_peer</c> together with an appropriate <c>cacert</c> or <c>cacertfile</c> option. For example an <c>HTTPS</c> client would normally + use the option <c>{cacerts, public_key:cacerts_get()}</c> (available since OTP-25) to access the CA certificates + provided by the OS. Using verify_none means that all x509-certificate path validation errors will be ignored. + See also option <seetype marker="#custom_verify">verify_fun</seetype>.</p> + </desc> </datatype> <datatype> @@ -1009,7 +1014,7 @@ fun(srp, Username :: binary(), UserState :: term()) -> explicitly specified by its session id and associated data since OTP-22.3. See also <seeguide marker="ssl:using_ssl#session-reuse-pre-tls-1.3"> - SSL's Users Guide, Session Reuse pre TLS 1.3</seeguide> + SSL's Users Guide, Session Reuse pre TLS 1.3.</seeguide> </p> </desc> </datatype> @@ -1023,7 +1028,7 @@ fun(srp, Username :: binary(), UserState :: term()) -> and used with the client option <seetype marker="#client_reuse_session">reuse_session</seetype> The boolean value true specifies that if possible, automated session reuse will be performed. If a new session is created, and is unique in regard - to previous stored sessions, it will be saved for possible later reuse. Since OTP-21.3</p> + to previous stored sessions, it will be saved for possible later reuse. Since OTP-21.3.</p> </desc> </datatype> @@ -1033,7 +1038,7 @@ fun(srp, Username :: binary(), UserState :: term()) -> <p>If set to true, sends the certificate authorities extension in TLS-1.3 client hello. The default is false. Note that setting it to true may result in a big overhead if you have many trusted CA certificates. - Since OTP-24.3</p> + Since OTP-24.3.</p> </desc> </datatype> @@ -1278,12 +1283,13 @@ fun(srp, Username :: binary(), UserState :: term()) -> <datatype> <name name="server_verify_type"/> - <desc><p>A server only does x509-path validation in mode - <c>verify_peer</c>, as it then sends a certificate request to - the client (this message is not sent if the verify option is - <c>verify_none</c>). You can then also want to specify option - <c>fail_if_no_peer_cert</c>. </p> - </desc> + <desc><p> Client certificates are an optional part of the TLS protocol. + A server only does x509-certificate path validation in mode + <c>verify_peer</c>. By default the server is in <c>verify_none</c> mode + an hence will not send an certificate request to the client. + When using <c>verify_peer</c> you may also want to specify the option + <seetype marker="#fail_if_no_peer_cert">fail_if_no_peer_cert</seetype>.</p> + </desc> </datatype> <datatype> @@ -1302,7 +1308,7 @@ fun(srp, Username :: binary(), UserState :: term()) -> <desc><p>The boolean value true specifies that the server will agree to reuse sessions. Setting it to false will result in an empty session table, that is no sessions will be reused. - See also option <seetype marker="#server_reuse_session">reuse_session</seetype> + See also option <seetype marker="#server_reuse_session">reuse_session</seetype>. </p> </desc> </datatype> diff --git a/lib/ssl/doc/src/using_ssl.xml b/lib/ssl/doc/src/using_ssl.xml index 559b20dedd..318e367245 100644 --- a/lib/ssl/doc/src/using_ssl.xml +++ b/lib/ssl/doc/src/using_ssl.xml @@ -41,47 +41,53 @@ 'tlsv1.3')</c> </seemfa>. The available cipher suites for a connection depend on the TLS version and pre TLS-1.3 also on the certificate. To see the default cipher suite list change <c>all</c> - to <c>default</c>. Note that TLS 1.3 and previous versions does not + to <c>default</c>. Note that TLS 1.3 and previous versions do not have any cipher suites in common, for listing cipher suites for a specific version use <seemfa marker="ssl:ssl#cipher_suites/2"><c>ssl:cipher_suites(exclusive, 'tlsv1.3')</c> </seemfa>. Specific cipher suites that you want your connection to use can also be specified. Default is to use the strongest available.</p> - + + + <p>The following sections shows small examples of how to set up + client/server connections using the Erlang shell. The returned + value of the <c>sslsocket</c> is abbreviated with <c>[...]</c> as + it can be fairly large and is opaque to the user except for the + purpose of pattern matching.</p> + + + <note><p>Note that client certificate verification is optional for the server and needs additional conguration + on both sides to work. The Certificate and keys, in the examples, are provided using the <seetype marker="ssl:ssl#certs_keys">certs_keys</seetype> option + introduced in OTP-25. + </p> + </note> + <section> - <title>Setting up Connections</title> - - <p>This section shows a small example of how to set up - client/server connections using the Erlang shell. The returned - value of the <c>sslsocket</c> is abbreviated with <c>[...]</c> as - it can be fairly large and is opaque.</p> - - <section> - <title>Minimal Example</title> - - <note><p> The minimal setup is not the most secure setup of TLS/DTLS.</p> - </note> + <title>Basic Client</title> + <code type="erl"> 1 > ssl:start(), ssl:connect("google.com", 443, [{verify, verify_peer}, + {cacerts, public_key:cacerts_get()}]). + {ok,{sslsocket, [...]}}</code> + </section> - <p>To set up client/server connections:</p> + <section> + <title>Basic Connection</title> - <p><em>Step 1:</em> Start the server side:</p> - <code type="erl">1 server> ssl:start(). + <p><em>Step 1:</em> Start the server side:</p> + <code type="erl">1 server> ssl:start(). ok</code> - - <p><em>Step 2:</em> Create a TLS listen socket: (To run DTLS add the option {protocol, dtls})</p> - <code type="erl">2 server> {ok, ListenSocket} = -ssl:listen(9999, [{certfile, "cert.pem"}, - {keyfile, "key.pem"}, - {reuseaddr, true}]). -{ok,{sslsocket, [...]}}</code> - - <p><em>Step 2: From OTP-25 it is equivalent to</em> </p> + <p><em>Step 2:</em> with alternative certificates, + in this example the EDDSA certificate will be preferred if TLS-1.3 + is negotiated and the RSA certificate will always be used for TLS-1.2 + as it does not support the EDDSA algorithm: </p> <code type="erl">2 server> {ok, ListenSocket} = -ssl:listen(9999, [{certs_keys, [#{certfile => "cert.pem", - keyfile => "key.pem"}], - {reuseaddr, true}]). +ssl:listen(9999, [{certs_keys, [#{certfile => "eddsacert.pem", + keyfile => "eddsakey.pem"}, + #{certfile => "rsacert.pem", + keyfile => "rsakey.pem", + password => "foobar"} + ]},{reuseaddr, true}]). {ok,{sslsocket, [...]}}</code> @@ -98,8 +104,10 @@ connection</p> <p><em>Step 4:</em> Start the client side: </p> <code type="erl">1 client> ssl:start(). ok</code> - <p> To run DTLS add the option {protocol, dtls} to third argument.</p> - <code type="erl">2 client> {ok, Socket} = ssl:connect("localhost", 9999, [], infinity). + <p> Be sure to configure trusted certificates to use for server certificate verification.</p> + <code type="erl">2 client> {ok, Socket} = ssl:connect("localhost", 9999, + [{verify, verify_peer}, + {cacertfile, "cacerts.pem"}, {active, once}], infinity). {ok,{sslsocket, [...]}}</code> <p><em>Step 5:</em> Do the TLS handshake:</p> @@ -115,78 +123,83 @@ to avoid DoS attacks. In the example the timeout defaults to infinty.</p> ok</code> <p><em>Step 7:</em> Flush the shell message queue to see that the message - was sent on the server side:</p> + sent on the server side is recived by the client side:</p> <code type="erl">3 client> flush(). Shell got {ssl,{sslsocket,[...]},"foo"} ok</code> - </section> - - <section> - <title>Upgrade Example - TLS only </title> - - <note><p>To upgrade a TCP/IP connection to a TLS connection, the - client and server must agree to do so. The agreement - can be accomplished by using a protocol, for example, the one used by HTTP - specified in RFC 2817.</p></note> + </section> - <p>To upgrade to a TLS connection:</p> - - <p><em>Step 1:</em> Start the server side:</p> - <code type="erl">1 server> ssl:start(). -ok</code> - - <p><em>Step 2:</em> Create a normal TCP listen socket:</p> - <code type="erl">2 server> {ok, ListenSocket} = gen_tcp:listen(9999, [{reuseaddr, true}]). -{ok, #Port<0.475>}</code> - - <p><em>Step 3:</em> Accept client connection:</p> - <code type="erl">3 server> {ok, Socket} = gen_tcp:accept(ListenSocket). -{ok, #Port<0.476>}</code> - - <p><em>Step 4:</em> Start the client side:</p> - <code type="erl">1 client> ssl:start(). -ok</code> - - <code type="erl">2 client> {ok, Socket} = gen_tcp:connect("localhost", 9999, [], infinity).</code> - - <p><em>Step 5:</em> Ensure <c>active</c> is set to <c>false</c> - before trying to upgrade a connection to a TLS connection, - otherwise TLS handshake messages can be delivered to the wrong - process:</p> - <code type="erl">4 server> inet:setopts(Socket, [{active, false}]). -ok</code> + <section> + <title>Upgrade Example - TLS only</title> + + <p>Upgrading a a TCP/IP connection to a TLS connections is mostly + used when there is a desire have unencrypted communication first and + then later secure the communication channel by using TLS. Note that + the client and server need to agree to do the upgrade in the + protocol doing the communication. This is concept is often + referenced as <c>STARTLS</c> and used in many protocols such as + <c>SMTP</c>, <c>FTPS</c> and <c>HTTPS</c> via a proxy. + </p> + + <warning><p>Maximum security recommendations are however moving away from such solutions.</p></warning> - <p><em>Step 6:</em> Do the TLS handshake:</p> - <code type="erl">5 server> {ok, TLSSocket} = ssl:handshake(Socket, [{cacertfile, "cacerts.pem"}, -{certfile, "cert.pem"}, {keyfile, "key.pem"}]). -{ok,{sslsocket,[...]}}</code> + <p>To upgrade to a TLS connection:</p> + + <p><em>Step 1:</em> Start the server side:</p> + <code type="erl">1 server> ssl:start(). + ok</code> + + <p><em>Step 2:</em> Create a normal TCP listen socket and ensure + <c>active</c> is set to <c>false</c> and not set to any active mode + otherwise TLS handshake messages can be delivered to the + wrong process. + </p> + <code type="erl">2 server> {ok, ListenSocket} = gen_tcp:listen(9999, [{reuseaddr, true}, + {active, false}]). + {ok, #Port<0.475>}</code> + + <p><em>Step 3:</em> Accept client connection:</p> + <code type="erl">3 server> {ok, Socket} = gen_tcp:accept(ListenSocket). + {ok, #Port<0.476>}</code> + + <p><em>Step 4:</em> Start the client side:</p> + <code type="erl">1 client> ssl:start(). + ok</code> + + <code type="erl">2 client> {ok, Socket} = gen_tcp:connect("localhost", 9999, [], infinity).</code> + + <p><em>Step 5:</em> Do the TLS handshake:</p> + <code type="erl">4 server> {ok, TLSSocket} = ssl:handshake(Socket, [{verify, verify_peer}, + {fail_if_no_peer_cert, true}, + {cacertfile, "cacerts.pem"}, + {certs_keys, [#{certfile => "cert.pem", keyfile => "key.pem"}]}]). + {ok,{sslsocket,[...]}}</code> - <p><em>Step 7:</em> Upgrade to a TLS connection. The client and - server must agree upon the upgrade. The server must call - <c>ssl:handshake/2</c> before the client calls - <c>ssl:connect/3.</c></p> + <p><em>Step 6:</em> Upgrade to a TLS connection. The client and + server must agree upon the upgrade. The server must be prepared to be a TLS server before the client + can do a successful connect.</p> - <code type="erl">3 client>{ok, TLSSocket} = ssl:connect(Socket, [{cacertfile, "cacerts.pem"}, -{certfile, "cert.pem"}, {keyfile, "key.pem"}], infinity). + <code type="erl">3 client>{ok, TLSSocket} = ssl:connect(Socket, [{verify, verify_peer}, + {cacertfile, "cacerts.pem"}, + {certs_keys, [#{certfile => "cert.pem", keyfile => "key.pem"}]}], infinity). {ok,{sslsocket,[...]}}</code> - - <p><em>Step 8:</em> Send a message over TLS:</p> + + <p><em>Step 7:</em> Send a message over TLS:</p> <code type="erl">4 client> ssl:send(TLSSocket, "foo"). -ok</code> + ok</code> - <p><em>Step 9:</em> Set <c>active true</c> on the TLS socket:</p> - <code type="erl">4 server> ssl:setopts(TLSSocket, [{active, true}]). -ok</code> + <p><em>Step 8:</em> Set <c>active once</c> on the TLS socket:</p> + <code type="erl">5 server> ssl:setopts(TLSSocket, [{active, once}]). + ok</code> - <p><em>Step 10:</em> Flush the shell message queue to see that - the message was sent on the client side:</p> + <p><em>Step 9:</em> Flush the shell message queue to see that + the message sent on the client side is recived by the server side:</p> <code type="erl">5 server> flush(). -Shell got {ssl,{sslsocket,[...]},"foo"} -ok</code> - </section> - </section> + Shell got {ssl,{sslsocket,[...]},"foo"} + ok</code> +</section> <section> <title>Customizing cipher suites</title> @@ -265,17 +278,17 @@ crypto:engine_load(<<"dynamic">>, <code type="erl">4> {ok, SSLSocket} = ssl:connect("localhost", 9999, [{cacertfile, "cacerts.pem"}, - {certfile, "cert.pem"}, - {key, PrivKey}], infinity). + {certs_keys, [#{certfile => "cert.pem", key => PrivKey}]} + ], infinity). </code> <p>See also <seeguide marker="crypto:engine_load#engine_load"> crypto documentation</seeguide> </p> </section> - <section> <title>Session Reuse pre TLS 1.3</title> + <p>Clients can request to reuse a session established by a previous full handshake between that client and server by sending the id of the session in the initial handshake message. The server @@ -477,42 +490,16 @@ ssl:connect("localhost", 9999, [{verify, verify_peer}, <p>An example with automatic and manual session resumption:</p> - - <p><em>Step 1 (server):</em> Start the server: Note that from OTP-25 the - options certfile and keyfile can be replaced by - [{certs_keys, [#{certfile => "cert.pem", keyfile => "key.pem"}]}]</p> - - <code type="erl"> - {ok, _} = application:ensure_all_started(ssl). - LOpts = [{certfile, "cert.pem"}, - {keyfile, "key.pem"}, - {versions, ['tlsv1.2','tlsv1.3']}, - {session_tickets, stateless}]. - {ok, LSock} = ssl:listen(8001, LOpts). - {ok, CSock} = ssl:transport_accept(LSock). - </code> - - - <p><em>Step 1 (server):</em> with alternative certificates, - in this example the EDDSA certificate will be preferred if TLS-1.3 - is negotiated and the RSA certificate will always be used for TLS-1.2 - as it does not support the EDDSA algorithm: Added in OTP-25</p> - <code type="erl"> {ok, _} = application:ensure_all_started(ssl). - LOpts = [{certs_keys, [#{certfile => "eddsacert.pem", - keyfile => "eddsakey.pem"}, - #{certfile => "rsacert.pem", - keyfile => "rsakey.pem", - password => "foobar"} - ]}], + LOpts = [{certs_keys, [#{certfile => "cert.pem", + keyfile => "key.pem"}]}, {versions, ['tlsv1.2','tlsv1.3']}, {session_tickets, stateless}]. {ok, LSock} = ssl:listen(8001, LOpts). {ok, CSock} = ssl:transport_accept(LSock). </code> - <p><em>Step 2 (client):</em> Start the client and connect to server:</p> <code type="erl"> {ok, _} = application:ensure_all_started(ssl). @@ -623,7 +610,8 @@ ssl:connect("localhost", 9999, [{verify, verify_peer}, <code type="erl"> ssl:handshake(CSock3). </code> - </section> +</section> + <section> <title>Early Data in TLS 1.3</title> @@ -656,14 +644,13 @@ ssl:connect("localhost", 9999, [{verify, verify_peer}, application:load(ssl), {ok, _} = application:ensure_all_started(ssl), Port = 11029, - LOpts = [{certfile, ?SERVER_CERT}, - {keyfile, ?SERVER_KEY}, - {reuseaddr, true}, - {versions, ['tlsv1.2','tlsv1.3']}, - {session_tickets, stateless}, - {early_data, enabled}, - {keep_secrets, true} %% Enable NSS key log (debug option) - ], + LOpts = [{certs_keys, [#{certfile => "cert.pem", keyfile => "key.pem"}]}, + {reuseaddr, true}, + {versions, ['tlsv1.2','tlsv1.3']}, + {session_tickets, stateless}, + {early_data, enabled}, + {keep_secrets, true} %% Enable NSS key log (debug option) + ], {ok, LSock} = ssl:listen(Port, LOpts), %% Accept first connection {ok, CSock0} = ssl:transport_accept(LSock), @@ -686,7 +673,7 @@ ssl:connect("localhost", 9999, [{verify, verify_peer}, {ok, _} = application:ensure_all_started(ssl), Port = 11029, Data = <<"HEAD / HTTP/1.1\r\nHost: \r\nConnection: close\r\n">>, - COpts0 = [{cacertfile, ?CA_CERT}, + COpts0 = [{cacertfile, "cacerts.pem"}, {versions, ['tlsv1.2', 'tlsv1.3']}, {session_tickets, auto}], {ok, Sock0} = ssl:connect("localhost", Port, COpts0), @@ -698,7 +685,7 @@ ssl:connect("localhost", 9999, [{verify, verify_peer}, ssl:close(Sock0), %% Second handshake 0-RTT - COpts1 = [{cacertfile, ?CA_CERT}, + COpts1 = [{cacertfile, "cacerts.pem"}, {versions, ['tlsv1.2', 'tlsv1.3']}, {session_tickets, auto}, {early_data, Data}], @@ -713,7 +700,7 @@ ssl:connect("localhost", 9999, [{verify, verify_peer}, {ok, _} = application:ensure_all_started(ssl), Port = 11029, Data = <<"HEAD / HTTP/1.1\r\nHost: \r\nConnection: close\r\n">>, - COpts0 = [{cacertfile, ?CA_CERT}, + COpts0 = [{cacertfile, "cacerts.pem"}, {versions, ['tlsv1.2', 'tlsv1.3']}, {session_tickets, manual}], {ok, Sock0} = ssl:connect("localhost", Port, COpts0), @@ -730,7 +717,7 @@ ssl:connect("localhost", 9999, [{verify, verify_peer}, ssl:close(Sock0), %% Second handshake 0-RTT - COpts1 = [{cacertfile, ?CA_CERT}, + COpts1 = [{cacertfile, "cacerts.pem"}, {versions, ['tlsv1.2', 'tlsv1.3']}, {session_tickets, manual}, {use_ticket, [Ticket]}, @@ -798,4 +785,14 @@ ssl:connect("localhost", 9999, [{verify, verify_peer}, </list> </section> + + <section> + <title>Using DTLS</title> + + <p> Using DTLS has basically the same API as TLS. You need to add the option {protocol, dtls} to the connect and listen functions. For example</p> + + <code type="erl"> client> {ok, Socket} = ssl:connect("localhost", 9999, [{protocol, dtls}, +{verify, verify_peer},{cacertfile, "cacerts.pem"}], infinity). +{ok,{sslsocket, [...]}}</code> + </section> </chapter> -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor