From 8d7c2c33b3cdc978ec32ad503242c352c0e46690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Dimitrov?= Date: Fri, 7 Dec 2018 14:47:42 +0100 Subject: ssl: Create server 'Certificate' message Create a TLS 1.3 'Certificate' message in the 'negotiated' state. Change-Id: I03115de2353324f8533146ba19809064da6b0866 --- lib/ssl/src/tls_connection_1_3.erl | 9 +++++- lib/ssl/src/tls_handshake_1_3.erl | 40 +++++++++++++++++++++--- lib/ssl/src/tls_handshake_1_3.hrl | 4 +-- lib/ssl/test/property_test/ssl_eqc_handshake.erl | 7 +++-- 4 files changed, 51 insertions(+), 9 deletions(-) (limited to 'lib/ssl') 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, <>}; 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, <>}; @@ -119,14 +134,14 @@ decode_handshake(?CERTIFICATE, <>) - CertList = decode_cert_entries(Certs), #certificate_1_3{ certificate_request_context = <<>>, - entries = CertList + certificate_list = CertList }; decode_handshake(?CERTIFICATE, <>) -> CertList = decode_cert_entries(Certs), #certificate_1_3{ certificate_request_context = Context, - entries = CertList + certificate_list = CertList }; decode_handshake(?ENCRYPTED_EXTENSIONS, <>) -> #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) -> -- cgit v1.2.3