aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl
diff options
context:
space:
mode:
authorPéter Dimitrov <[email protected]>2018-12-07 14:47:42 +0100
committerPéter Dimitrov <[email protected]>2019-01-11 09:59:12 +0100
commit8d7c2c33b3cdc978ec32ad503242c352c0e46690 (patch)
treea8aa93e31ec157fefd6f5351d6006d70ac98eecf /lib/ssl
parent40a832093a95aac9bc171616b9f11adf108419c0 (diff)
downloadotp-8d7c2c33b3cdc978ec32ad503242c352c0e46690.tar.gz
otp-8d7c2c33b3cdc978ec32ad503242c352c0e46690.tar.bz2
otp-8d7c2c33b3cdc978ec32ad503242c352c0e46690.zip
ssl: Create server 'Certificate' message
Create a TLS 1.3 'Certificate' message in the 'negotiated' state. Change-Id: I03115de2353324f8533146ba19809064da6b0866
Diffstat (limited to 'lib/ssl')
-rw-r--r--lib/ssl/src/tls_connection_1_3.erl9
-rw-r--r--lib/ssl/src/tls_handshake_1_3.erl40
-rw-r--r--lib/ssl/src/tls_handshake_1_3.hrl4
-rw-r--r--lib/ssl/test/property_test/ssl_eqc_handshake.erl7
4 files changed, 51 insertions, 9 deletions
diff --git a/lib/ssl/src/tls_connection_1_3.erl b/lib/ssl/src/tls_connection_1_3.erl
index d9203de556..42ae784222 100644
--- a/lib/ssl/src/tls_connection_1_3.erl
+++ b/lib/ssl/src/tls_connection_1_3.erl
@@ -157,7 +157,10 @@ update_state(#state{connection_states = ConnectionStates0,
negotiated(internal,
Map,
#state{connection_states = ConnectionStates0,
- session = #session{session_id = SessionId},
+ session = #session{session_id = SessionId,
+ own_certificate = OwnCert},
+ cert_db = CertDbHandle,
+ cert_db_ref = CertDbRef,
ssl_options = #ssl_options{} = SslOpts,
key_share = KeyShare,
tls_handshake_history = HHistory0,
@@ -227,6 +230,10 @@ negotiated(internal,
pending_write => PendingWrite},
%% Create Certificate, CertificateVerify
+ Certificate = tls_handshake_1_3:certificate(OwnCert, CertDbHandle, CertDbRef, <<>>, server),
+ io:format("### Certificate: ~p~n", [Certificate]),
+
+ %% CertificateVerify = tls_handshake_1_3:certificate_verify(),
%% Send Certificate, CertifricateVerify
diff --git a/lib/ssl/src/tls_handshake_1_3.erl b/lib/ssl/src/tls_handshake_1_3.erl
index 0d6ebe953f..8c302d8d57 100644
--- a/lib/ssl/src/tls_handshake_1_3.erl
+++ b/lib/ssl/src/tls_handshake_1_3.erl
@@ -38,7 +38,8 @@
-export([handle_client_hello/3]).
%% Create handshake messages
--export([server_hello/4]).
+-export([certificate/5,
+ server_hello/4]).
%%====================================================================
%% Create handshake messages
@@ -62,6 +63,20 @@ server_hello_extensions(KeyShare) ->
ssl_handshake:add_server_share(Extensions, KeyShare).
+%% TODO: use maybe monad for error handling!
+certificate(OwnCert, CertDbHandle, CertDbRef, _CRContext, server) ->
+ case ssl_certificate:certificate_chain(OwnCert, CertDbHandle, CertDbRef) of
+ {ok, _, Chain} ->
+ CertList = chain_to_cert_list(Chain),
+ %% If this message is in response to a CertificateRequest, the value of
+ %% certificate_request_context in that message. Otherwise (in the case
+ %%of server authentication), this field SHALL be zero length.
+ #certificate_1_3{
+ certificate_request_context = <<>>,
+ certificate_list = CertList};
+ {error, Error} ->
+ ?ALERT_REC(?FATAL, ?INTERNAL_ERROR, {server_has_no_suitable_certificates, Error})
+ end.
%%====================================================================
%% Encode handshake
@@ -75,7 +90,7 @@ encode_handshake(#certificate_request_1_3{
{?CERTIFICATE_REQUEST, <<EncContext/binary, BinExts/binary>>};
encode_handshake(#certificate_1_3{
certificate_request_context = Context,
- entries = Entries}) ->
+ certificate_list = Entries}) ->
EncContext = encode_cert_req_context(Context),
EncEntries = encode_cert_entries(Entries),
{?CERTIFICATE, <<EncContext/binary, EncEntries/binary>>};
@@ -119,14 +134,14 @@ decode_handshake(?CERTIFICATE, <<?BYTE(0), ?UINT24(Size), Certs:Size/binary>>) -
CertList = decode_cert_entries(Certs),
#certificate_1_3{
certificate_request_context = <<>>,
- entries = CertList
+ certificate_list = CertList
};
decode_handshake(?CERTIFICATE, <<?BYTE(CSize), Context:CSize/binary,
?UINT24(Size), Certs:Size/binary>>) ->
CertList = decode_cert_entries(Certs),
#certificate_1_3{
certificate_request_context = Context,
- entries = CertList
+ certificate_list = CertList
};
decode_handshake(?ENCRYPTED_EXTENSIONS, <<?UINT16(Size), EncExts:Size/binary>>) ->
#encrypted_extensions{
@@ -192,6 +207,23 @@ extensions_list(HelloExtensions) ->
[Ext || {_, Ext} <- maps:to_list(HelloExtensions)].
+%% TODO: add extensions!
+chain_to_cert_list(L) ->
+ chain_to_cert_list(L, []).
+%%
+chain_to_cert_list([], Acc) ->
+ lists:reverse(Acc);
+chain_to_cert_list([H|T], Acc) ->
+ chain_to_cert_list(T, [certificate_entry(H)|Acc]).
+
+
+certificate_entry(DER) ->
+ #certificate_entry{
+ data = DER,
+ extensions = #{} %% Extensions not supported.
+ }.
+
+
%%====================================================================
%% Handle handshake messages
%%====================================================================
diff --git a/lib/ssl/src/tls_handshake_1_3.hrl b/lib/ssl/src/tls_handshake_1_3.hrl
index 6ef5364399..42f4766f1a 100644
--- a/lib/ssl/src/tls_handshake_1_3.hrl
+++ b/lib/ssl/src/tls_handshake_1_3.hrl
@@ -191,7 +191,7 @@
%% case RawPublicKey:
%% /* From RFC 7250 ASN.1_subjectPublicKeyInfo */
%% opaque ASN1_subjectPublicKeyInfo<1..2^24-1>;
-
+ %%
%% case X509:
%% opaque cert_data<1..2^24-1>;
%% };
@@ -200,7 +200,7 @@
-record(certificate_1_3, {
certificate_request_context, % opaque certificate_request_context<0..2^8-1>;
- entries % CertificateEntry certificate_list<0..2^24-1>;
+ certificate_list % CertificateEntry certificate_list<0..2^24-1>;
}).
%% RFC 8446 B.3.4. Ticket Establishment
diff --git a/lib/ssl/test/property_test/ssl_eqc_handshake.erl b/lib/ssl/test/property_test/ssl_eqc_handshake.erl
index 20a581328e..e4c4c89021 100644
--- a/lib/ssl/test/property_test/ssl_eqc_handshake.erl
+++ b/lib/ssl/test/property_test/ssl_eqc_handshake.erl
@@ -160,7 +160,7 @@ certificate_1_3() ->
?LET(Certs, certificate_chain(),
#certificate_1_3{
certificate_request_context = certificate_request_context(),
- entries = certificate_entries(Certs, [])
+ certificate_list = certificate_entries(Certs, [])
}).
finished() ->
@@ -545,7 +545,10 @@ choose_certificate_chain(#{server_config := ServerConf,
oneof([certificate_chain(ServerConf), certificate_chain(ClientConf)]).
certificate_request_context() ->
- <<>>.
+ oneof([<<>>,
+ <<1>>,
+ <<"foobar">>
+ ]).
certificate_entries([], Acc) ->
lists:reverse(Acc);
certificate_entries([Cert | Rest], Acc) ->