diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index af036a3ff8..07d69315c1 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -1892,6 +1892,8 @@ check_cert_key(UserOpts, CertKeys, LogLevel) -> CertKeys0#{key => Key}; {_, #{engine := _, key_id := _, algorithm := _} = Key} -> CertKeys0#{key => Key}; + {_, #{sign_fun := _, algorithm := ecdsa} = Key} -> + CertKeys0#{key => Key}; {new, Err1} -> option_error(key, Err1) end, diff --git a/lib/ssl/src/ssl_config.erl b/lib/ssl/src/ssl_config.erl index 761a4f4315..7a828ce6dc 100644 --- a/lib/ssl/src/ssl_config.erl +++ b/lib/ssl/src/ssl_config.erl @@ -87,6 +87,9 @@ group_pairs([#{private_key := #'DSAPrivateKey'{}} = Pair | Rest], #{dsa := DSA} group_pairs([#{private_key := #{algorithm := dss, engine := _}} = Pair | Rest], Group) -> Pairs = maps:get(dsa, Group), group_pairs(Rest, Group#{dsa => [Pair | Pairs]}); +group_pairs([#{private_key := #{algorithm := Alg, sign_fun := _}} = Pair | Rest], Group) -> + Pairs = maps:get(Alg, Group), + group_pairs(Rest, Group#{Alg => [Pair | Pairs]}); group_pairs([#{private_key := #{algorithm := Alg, engine := _}} = Pair | Rest], Group) -> Pairs = maps:get(Alg, Group), group_pairs(Rest, Group#{Alg => [Pair | Pairs]}); @@ -110,7 +113,10 @@ prio_eddsa(EDDSA) -> using_curve({namedCurve, ?'id-Ed25519'}, EDDSA, []) ++ using_curve({namedCurve, ?'id-Ed448'}, EDDSA, []). prio_ecdsa(ECDSA) -> - EnginePairs = [Pair || Pair = #{private_key := #{engine := _}} <- ECDSA], + EnginePairs = lists:filter(fun(#{private_key := #{engine := _}}) -> true; + (#{private_key := #{sign_fun := _}}) -> true; + (_) -> false + end, ECDSA), Curves = tls_v1:ecc_curves(all), EnginePairs ++ lists:foldr(fun(Curve, AccIn) -> CurveOid = pubkey_cert_records:namedCurves(Curve), @@ -265,6 +271,9 @@ init_certificate_file(CertFile, PemCache, Role) -> file_error(CertFile, {certfile, Reason}) end. +%% 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, _, _PemCache) when Alg =:= ecdsa; Alg =:= rsa; Alg =:= dss -> case maps:is_key(engine, Key) andalso maps:is_key(key_id, Key) of diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index dbbf0a4496..1120a2db62 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -2148,6 +2148,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(?TLS_1_3, Msg, sha256, #{algorithm := ecdsa, sign_fun := {Mod, Fun}}, ecdsa) -> + Mod:Fun(Msg); +do_digitally_signed(?TLS_1_2, Hash, sha256, #{algorithm := ecdsa, sign_fun := {Mod, Fun}}, ecdsa) -> + Mod:Fun({digest, Hash}); do_digitally_signed(Version, Msg, HashAlgo, {#'RSAPrivateKey'{} = Key, #'RSASSA-PSS-params'{}}, SignAlgo) when ?TLS_GTE(Version, ?TLS_1_2) -> Options = signature_options(SignAlgo, HashAlgo),