Current section

Files

Jump to
grisp_cryptoauth grisp grisp2 23 build patches 01000-cryptoauth_ssl.patch
Raw

grisp/grisp2/23/build/patches/01000-cryptoauth_ssl.patch

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.
Remember to use SSL options for server and client properly:
* {signature_algs, [{sha256, ecdsa}]} %% TLS 1.2
* {signature_algs_cert, [ecdsa_secp256r1_sha256]} %% TLS 1.3
The reason is that the Secure Element only supports sha256 and ECDSA with the P-256 curve.
Tested with OTP 23.3.4.5, cowboy 2.9.0 and gun 1.3.3 (latest hex versions in August 2021).
diff --git a/lib/ssl/src/ssl_config.erl b/lib/ssl/src/ssl_config.erl
index 2832d76d42..3a12274ad2 100644
--- a/lib/ssl/src/ssl_config.erl
+++ b/lib/ssl/src/ssl_config.erl
@@ -150,6 +150,9 @@ init_certificates(undefined, #{pem_cache := PemCache} = Config, CertFile, server
end;
init_certificates(OwnCerts, Config, _, _) ->
{ok, Config#{own_certificates => 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 6ea5ba0820..94d28e8a76 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -1994,6 +1994,12 @@ digitally_signed(Version, Hashes, 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}, Hash, _,
#{algorithm := rsa} = Engine, rsa) when Minor =< 2->
crypto:private_encrypt(rsa, Hash, maps:remove(algorithm, Engine),