Support in Erlang's SSL library for GRiSP's Secure Element without using OpenSSL crypto engines. Usage: Key = #{algorithm => ecdsa, sign_fun => {my_module, my_sign_fun}}. Then add {key, Key} to the SSL options (server and/or client possible). The sign_fun has arity one and will get the to be signed Message (TLS 1.3) or {digest, Digest} (TLS 1.2), analogous to ssl:sign/3. The intended use here is providing a callback for grisp_cryptoauth:sign/2. While this patch makes heavy use of the existing infrastructure for crypto engines it is completely backwards compatible, e.g. crypto engines still work. diff --git a/lib/ssl/src/ssl_config.erl b/lib/ssl/src/ssl_config.erl index 91bd03decf..e0debffdb5 100644 --- a/lib/ssl/src/ssl_config.erl +++ b/lib/ssl/src/ssl_config.erl @@ -163,6 +163,10 @@ init_certificates(undefined, #{pem_cache := PemCache} = Config, CertFile, server end; init_certificates(OwnCerts, Config, _, _) -> {ok, Config, OwnCerts}. + +%% HACK: allow callbacks for signing using the GRiSP Secure Element +init_private_key(_, #{algorithm := ecdsa, sign_fun := _SignFun} = Key, _, _, _) -> + Key; init_private_key(_, #{algorithm := Alg} = Key, _, _Password, _Client) when Alg == ecdsa; Alg == rsa; Alg == dss -> diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index 9462607193..d80703a7fe 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -2093,6 +2093,12 @@ digitally_signed(Version, Msg, HashAlgo, PrivateKey, SignAlgo) -> throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, bad_key(PrivateKey))) end. +%% HACK: allow callbacks for signing using the GRiSP Secure Element +%% We only care here for sha256 + ecdsa for TLS 1.2 and 1.3 (SSL 3.3 and 3.4) +do_digitally_signed({3, 4}, Msg, sha256, #{algorithm := ecdsa, sign_fun := {Mod, Fun}}, ecdsa) -> + Mod:Fun(Msg); +do_digitally_signed({3, 3}, Hash, sha256, #{algorithm := ecdsa, sign_fun := {Mod, Fun}}, ecdsa) -> + Mod:Fun({digest, Hash}); do_digitally_signed({3, Minor}, Msg, HashAlgo, {#'RSAPrivateKey'{} = Key, #'RSASSA-PSS-params'{}}, SignAlgo) when Minor >= 3 -> Options = signature_options(SignAlgo, HashAlgo),