Current section
Files
Jump to
Current section
Files
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),