Ditch enacl, support DH448 and Blake2s, and fix types (#14)
* Remove get_stacktrace (deprecated since OTP-24) * Add DH448 support and switch to crypto:generate_key for DH25519 * Switch to crypto:hash/2 for Blake2b and support Blake2s * Switch last enacl calls to crypto - no more enacl * Eqwalizer fixes Ewqalizer fix Eqwalizer fix Eqwalizer fix Eqwalizer fix Eqwalizer support Eqwalizer fix Fix tests to follow types (remote keys) * More error handling on setup * Dialyzer fix * Write CHANGELOG * Note about type-checking in README
This commit is contained in:
parent
91916908a0
commit
2b5f08e156
@ -6,8 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- Support for 448 DH function and Blake2s hash function.
|
||||
### Changed
|
||||
- Using `crypto` over `enacl` (and removing a call to `get_stacktrace/1`) makes `enoise`
|
||||
up to date for (at least) OTP-27.
|
||||
- Added test dependency `eqwalizer_support` to enable checking types with Eqwalizer.
|
||||
### Removed
|
||||
- The dependency on `enacl` is not needed anymore, OTP's `crypto` library now cover all
|
||||
necessary operations.
|
||||
|
||||
## [1.2.0] - 2021-10-28
|
||||
### Added
|
||||
|
@ -39,3 +39,9 @@ Test
|
||||
----
|
||||
|
||||
$ rebar3 eunit
|
||||
|
||||
Typecheck
|
||||
---------
|
||||
|
||||
$ rebar3 dialyzer
|
||||
$ elp --eqwalize-all --rebar
|
||||
|
@ -1,8 +1,10 @@
|
||||
{erl_opts, [debug_info]}.
|
||||
{plugins, [rebar3_hex]}.
|
||||
{deps, [{enacl, "1.1.1"}]}.
|
||||
|
||||
{profiles, [{test, [{deps, [{jsx, {git, "https://github.com/talentdeficit/jsx.git", {tag, "2.8.0"}}}]}]}
|
||||
{profiles, [{test, [{deps, [ {jsx, {git, "https://github.com/talentdeficit/jsx.git", {tag, "2.8.0"}}}
|
||||
, {eqwalizer_support, {git_subdir, "https://github.com/whatsapp/eqwalizer.git", {branch, "main"}, "eqwalizer_support"}}
|
||||
]}
|
||||
]}
|
||||
]}.
|
||||
|
||||
{xref_checks, [undefined_function_calls, undefined_functions,
|
||||
|
@ -1,6 +1 @@
|
||||
{"1.2.0",
|
||||
[{<<"enacl">>,{pkg,<<"enacl">>,<<"1.1.1">>},0}]}.
|
||||
[
|
||||
{pkg_hash,[
|
||||
{<<"enacl">>, <<"F65DC64D9BFF2D8A534CB77AEF14DA5E7A2FA148987D87856F79A4745C9C2627">>}]}
|
||||
].
|
||||
[].
|
||||
|
@ -5,7 +5,7 @@
|
||||
{applications,
|
||||
[kernel,
|
||||
stdlib,
|
||||
enacl
|
||||
crypto
|
||||
]},
|
||||
{env,[]},
|
||||
{modules, []},
|
||||
|
@ -87,8 +87,7 @@ binary().
|
||||
Role :: enoise_hs_state:noise_role()) ->
|
||||
{ok, enoise_hs_state:state()} | {error, term()}.
|
||||
handshake(Options, Role) ->
|
||||
HState = create_hstate(Options, Role),
|
||||
{ok, HState}.
|
||||
create_hstate(Options, Role).
|
||||
|
||||
%% @doc Do a step (either `{send, Payload}', `{rcvd, EncryptedData}',
|
||||
%% or `done')
|
||||
@ -109,10 +108,13 @@ step_handshake(HState, Data) ->
|
||||
ComState :: noise_com_state()) ->
|
||||
{ok, noise_split_state(), noise_com_state()} | {error, term()}.
|
||||
handshake(Options, Role, ComState) ->
|
||||
HState = create_hstate(Options, Role),
|
||||
Timeout = proplists:get_value(timeout, Options, infinity),
|
||||
do_handshake(HState, ComState, Timeout).
|
||||
|
||||
case create_hstate(Options, Role) of
|
||||
{ok, HState} ->
|
||||
Timeout = proplists:get_value(timeout, Options, infinity),
|
||||
do_handshake(HState, ComState, Timeout);
|
||||
Err = {error, _} ->
|
||||
Err
|
||||
end.
|
||||
|
||||
%% @doc Upgrades a gen_tcp, or equivalent, connected socket to a Noise socket,
|
||||
%% that is, performs the client-side noise handshake.
|
||||
@ -270,15 +272,16 @@ create_hstate(Options, Role) ->
|
||||
enoise_protocol:from_name(X);
|
||||
_ -> NoiseProtocol0
|
||||
end,
|
||||
|
||||
DH = enoise_protocol:dh(NoiseProtocol),
|
||||
S = proplists:get_value(s, Options, undefined),
|
||||
E = proplists:get_value(e, Options, undefined),
|
||||
RS = proplists:get_value(rs, Options, undefined),
|
||||
RE = proplists:get_value(re, Options, undefined),
|
||||
RS = remote_keypair(DH, proplists:get_value(rs, Options, undefined)),
|
||||
RE = remote_keypair(DH, proplists:get_value(re, Options, undefined)),
|
||||
|
||||
enoise_hs_state:init(NoiseProtocol, Role,
|
||||
Prologue, {S, E, RS, RE}).
|
||||
|
||||
|
||||
check_gen_tcp(TcpSock) ->
|
||||
case inet:getopts(TcpSock, [mode, packet, active, header, packet_size]) of
|
||||
{ok, TcpOpts} ->
|
||||
@ -321,3 +324,5 @@ gen_tcp_rcv_msg({TcpSock, Active, Buf}, Timeout) ->
|
||||
{error, timeout}
|
||||
end.
|
||||
|
||||
remote_keypair(_DH, undefined) -> undefined;
|
||||
remote_keypair(DH, RemotePub) when is_binary(RemotePub) -> enoise_keypair:new(DH, RemotePub).
|
||||
|
@ -54,12 +54,8 @@ set_nonce(CState = #noise_cs{}, Nonce) ->
|
||||
encrypt_with_ad(CState = #noise_cs{ k = empty }, _AD, PlainText) ->
|
||||
{ok, CState, PlainText};
|
||||
encrypt_with_ad(CState = #noise_cs{ k = K, n = N, cipher = Cipher }, AD, PlainText) ->
|
||||
case enoise_crypto:encrypt(Cipher, K, N, AD, PlainText) of
|
||||
Encrypted when is_binary(Encrypted) ->
|
||||
{ok, CState#noise_cs{ n = N+1 }, Encrypted};
|
||||
Err = {error, _} ->
|
||||
Err
|
||||
end.
|
||||
CipherText = enoise_crypto:encrypt(Cipher, K, N, AD, PlainText),
|
||||
{ok, CState#noise_cs{ n = N+1 }, CipherText}.
|
||||
|
||||
-spec decrypt_with_ad(CState :: state(), AD :: binary(), CipherText :: binary()) ->
|
||||
{ok, state(), binary()} | {error, term()}.
|
||||
@ -74,6 +70,8 @@ decrypt_with_ad(CState = #noise_cs{ k = K, n = N, cipher = Cipher }, AD, CipherT
|
||||
end.
|
||||
|
||||
-spec rekey(CState :: state()) -> state().
|
||||
rekey(CState = #noise_cs{ k = empty }) ->
|
||||
CState;
|
||||
rekey(CState = #noise_cs{ k = K, cipher = Cipher }) ->
|
||||
CState#noise_cs{ k = enoise_crypto:rekey(Cipher, K) }.
|
||||
|
||||
|
@ -29,13 +29,18 @@
|
||||
%% @doc Perform a Diffie-Hellman calculation with the secret key from `Key1'
|
||||
%% and the public key from `Key2' with algorithm `Algo'.
|
||||
-spec dh(Algo :: enoise_hs_state:noise_dh(),
|
||||
Key1:: keypair(), Key2 :: keypair()) -> binary().
|
||||
dh(dh25519, Key1, Key2) ->
|
||||
enacl:curve25519_scalarmult( enoise_keypair:seckey(Key1)
|
||||
, enoise_keypair:pubkey(Key2));
|
||||
Key1:: keypair(), Key2 :: keypair()) -> binary().
|
||||
dh(Type, Key1, Key2) when Type == dh25519; Type == dh448 ->
|
||||
dh_(ecdh_type(Type), enoise_keypair:pubkey(Key2), enoise_keypair:seckey(Key1));
|
||||
dh(Type, _Key1, _Key2) ->
|
||||
error({unsupported_diffie_hellman, Type}).
|
||||
|
||||
ecdh_type(dh25519) -> x25519;
|
||||
ecdh_type(dh448) -> x448.
|
||||
|
||||
dh_(DHType, OtherPub, MyPriv) ->
|
||||
crypto:compute_key(ecdh, OtherPub, MyPriv, DHType).
|
||||
|
||||
-spec hmac(Hash :: enoise_sym_state:noise_hash(),
|
||||
Key :: binary(), Data :: binary()) -> binary().
|
||||
hmac(Hash, Key, Data) ->
|
||||
@ -54,47 +59,42 @@ hkdf(Hash, Key, Data) ->
|
||||
Output3 = hmac(Hash, TempKey, <<Output2/binary, 3:8>>),
|
||||
[Output1, Output2, Output3].
|
||||
|
||||
-spec rekey(Cipher :: enoise_cipher_state:noise_cipher(),
|
||||
Key :: binary()) -> binary() | {error, term()}.
|
||||
-spec rekey(Cipher :: enoise_cipher_state:noise_cipher(), Key :: binary()) -> binary().
|
||||
rekey('ChaChaPoly', K0) ->
|
||||
KLen = enacl:aead_chacha20poly1305_ietf_KEYBYTES(),
|
||||
KLen = 32,
|
||||
<<K:KLen/binary, _/binary>> = encrypt('ChaChaPoly', K0, ?MAX_NONCE, <<>>, <<0:(32*8)>>),
|
||||
K;
|
||||
rekey(Cipher, K) ->
|
||||
encrypt(Cipher, K, ?MAX_NONCE, <<>>, <<0:(32*8)>>).
|
||||
|
||||
-spec encrypt(Cipher :: enoise_cipher_state:noise_cipher(),
|
||||
Key :: binary(), Nonce :: non_neg_integer(),
|
||||
Ad :: binary(), PlainText :: binary()) ->
|
||||
binary() | {error, term()}.
|
||||
encrypt('ChaChaPoly', K, N, Ad, PlainText) ->
|
||||
Nonce = <<0:32, N:64/little-unsigned-integer>>,
|
||||
enacl:aead_chacha20poly1305_ietf_encrypt(PlainText, Ad, Nonce, K);
|
||||
encrypt('AESGCM', K, N, Ad, PlainText) ->
|
||||
Nonce = <<0:32, N:64>>,
|
||||
{CipherText, CipherTag} = crypto:crypto_one_time_aead(aes_256_gcm, K, Nonce, PlainText, Ad, true),
|
||||
<<CipherText/binary, CipherTag/binary>>.
|
||||
-spec encrypt(Cipher :: enoise_cipher_state:noise_cipher(), Key :: binary(),
|
||||
Nonce :: non_neg_integer(), Ad :: binary(), PlainText :: binary()) -> binary().
|
||||
encrypt(Cipher, K, N, Ad, PlainText) ->
|
||||
{CText, CTag} = crypto:crypto_one_time_aead(cipher(Cipher), K, nonce(Cipher, N), PlainText, Ad, true),
|
||||
<<CText/binary, CTag/binary>>.
|
||||
|
||||
-spec decrypt(Cipher ::enoise_cipher_state:noise_cipher(),
|
||||
Key :: binary(), Nonce :: non_neg_integer(),
|
||||
AD :: binary(), CipherText :: binary()) ->
|
||||
binary() | {error, term()}.
|
||||
decrypt('ChaChaPoly', K, N, Ad, CipherText) ->
|
||||
Nonce = <<0:32, N:64/little-unsigned-integer>>,
|
||||
enacl:aead_chacha20poly1305_ietf_decrypt(CipherText, Ad, Nonce, K);
|
||||
decrypt('AESGCM', K, N, Ad, CipherText0) ->
|
||||
-spec decrypt(Cipher ::enoise_cipher_state:noise_cipher(), Key :: binary(),
|
||||
Nonce :: non_neg_integer(), AD :: binary(),
|
||||
CipherText :: binary()) -> binary() | {error, term()}.
|
||||
decrypt(Cipher, K, N, Ad, CipherText0) ->
|
||||
CTLen = byte_size(CipherText0) - ?MAC_LEN,
|
||||
<<CipherText:CTLen/binary, MAC:?MAC_LEN/binary>> = CipherText0,
|
||||
Nonce = <<0:32, N:64>>,
|
||||
case crypto:crypto_one_time_aead(aes_256_gcm, K, Nonce, CipherText, Ad, MAC, false) of
|
||||
<<CText:CTLen/binary, MAC:?MAC_LEN/binary>> = CipherText0,
|
||||
case crypto:crypto_one_time_aead(cipher(Cipher), K, nonce(Cipher, N), CText, Ad, MAC, false) of
|
||||
error -> {error, decrypt_failed};
|
||||
Data -> Data
|
||||
end.
|
||||
|
||||
nonce('ChaChaPoly', N) -> <<0:32, N:64/little-unsigned-integer>>;
|
||||
nonce('AESGCM', N) -> <<0:32, N:64/big-unsigned-integer>>.
|
||||
|
||||
cipher('ChaChaPoly') -> chacha20_poly1305;
|
||||
cipher('AESGCM') -> aes_256_gcm.
|
||||
|
||||
-spec hash(Hash :: enoise_sym_state:noise_hash(), Data :: binary()) -> binary().
|
||||
hash(blake2s, Data) ->
|
||||
crypto:hash(blake2s, Data);
|
||||
hash(blake2b, Data) ->
|
||||
Hash = enacl:generichash(64, Data), Hash;
|
||||
crypto:hash(blake2b, Data);
|
||||
hash(sha256, Data) ->
|
||||
crypto:hash(sha256, Data);
|
||||
hash(sha512, Data) ->
|
||||
|
@ -26,6 +26,8 @@
|
||||
hs_hash := binary(),
|
||||
final_state => state() }.
|
||||
|
||||
-type optional_key() :: undefined | keypair().
|
||||
-type initial_keys() :: {optional_key(), optional_key(), optional_key(), optional_key()}.
|
||||
|
||||
-record(noise_hs, { ss :: enoise_sym_state:state()
|
||||
, s :: keypair() | undefined
|
||||
@ -39,11 +41,8 @@
|
||||
-opaque state() :: #noise_hs{}.
|
||||
-export_type([noise_dh/0, noise_role/0, noise_split_state/0, noise_token/0, state/0]).
|
||||
|
||||
-spec init(Protocol :: string() | enoise_protocol:protocol(),
|
||||
Role :: noise_role(), Prologue :: binary(),
|
||||
Keys :: term()) -> state().
|
||||
init(ProtocolName, Role, Prologue, Keys) when is_list(ProtocolName) ->
|
||||
init(enoise_protocol:from_name(ProtocolName), Role, Prologue, Keys);
|
||||
-spec init(Protocol :: enoise_protocol:protocol(), Role :: noise_role(),
|
||||
Prologue :: binary(), Keys :: initial_keys()) -> {ok, state()} | {error, term()}.
|
||||
init(Protocol, Role, Prologue, {S, E, RS, RE}) ->
|
||||
SS0 = enoise_sym_state:init(Protocol),
|
||||
SS1 = enoise_sym_state:mix_hash(SS0, Prologue),
|
||||
@ -53,11 +52,19 @@ init(Protocol, Role, Prologue, {S, E, RS, RE}) ->
|
||||
, dh = enoise_protocol:dh(Protocol)
|
||||
, msgs = enoise_protocol:msgs(Role, Protocol) },
|
||||
PreMsgs = enoise_protocol:pre_msgs(Role, Protocol),
|
||||
lists:foldl(fun({out, [s]}, HS0) -> mix_hash(HS0, enoise_keypair:pubkey(S));
|
||||
({out, [e]}, HS0) -> mix_hash(HS0, enoise_keypair:pubkey(E));
|
||||
({in, [s]}, HS0) -> mix_hash(HS0, enoise_keypair:pubkey(RS));
|
||||
({in, [e]}, HS0) -> mix_hash(HS0, enoise_keypair:pubkey(RE))
|
||||
end, HS, PreMsgs).
|
||||
pre_mix(PreMsgs, HS).
|
||||
|
||||
pre_mix([], HS) -> {ok, HS};
|
||||
pre_mix([{out, [s]} | Msgs], HS = #noise_hs{ s = S }) when S /= undefined ->
|
||||
pre_mix(Msgs, mix_hash(HS, enoise_keypair:pubkey(S)));
|
||||
pre_mix([{out, [e]} | Msgs], HS = #noise_hs{ e = E }) when E /= undefined ->
|
||||
pre_mix(Msgs, mix_hash(HS, enoise_keypair:pubkey(E)));
|
||||
pre_mix([{in, [s]} | Msgs], HS = #noise_hs{ rs = RS }) when RS /= undefined ->
|
||||
pre_mix(Msgs, mix_hash(HS, enoise_keypair:pubkey(RS)));
|
||||
pre_mix([{in, [e]} | Msgs], HS = #noise_hs{ re = RE }) when RE /= undefined ->
|
||||
pre_mix(Msgs, mix_hash(HS, enoise_keypair:pubkey(RE)));
|
||||
pre_mix(_Msg, _HS) ->
|
||||
{error, invalid_noise_setup}.
|
||||
|
||||
-spec finalize(HS :: state()) -> {ok, noise_split_state()} | {error, term()}.
|
||||
finalize(HS = #noise_hs{ msgs = [], ss = SS, role = Role }) ->
|
||||
@ -90,7 +97,7 @@ read_message(HS = #noise_hs{ msgs = [{in, Msg} | Msgs] }, Message) ->
|
||||
Err = {error, _} -> Err
|
||||
end.
|
||||
|
||||
-spec remote_keys(HS :: state()) -> keypair().
|
||||
-spec remote_keys(HS :: state()) -> undefined | keypair().
|
||||
remote_keys(#noise_hs{ rs = RS }) ->
|
||||
RS.
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
%% @doc Generate a new keypair of type `Type'.
|
||||
-spec new(Type :: key_type()) -> keypair().
|
||||
new(Type) ->
|
||||
{Sec, Pub} = new_key_pair(Type),
|
||||
{Pub, Sec} = new_key_pair(Type),
|
||||
#kp{ type = Type, sec = Sec, pub = Pub }.
|
||||
|
||||
%% @doc Create a new keypair of type `Type'. If `Public' is `undefined'
|
||||
@ -69,12 +69,14 @@ seckey(#kp{ sec = S }) ->
|
||||
S.
|
||||
|
||||
%% -- Local functions --------------------------------------------------------
|
||||
new_key_pair(dh25519) ->
|
||||
KeyPair = enacl:crypto_sign_ed25519_keypair(),
|
||||
{enacl:crypto_sign_ed25519_secret_to_curve25519(maps:get(secret, KeyPair)),
|
||||
enacl:crypto_sign_ed25519_public_to_curve25519(maps:get(public, KeyPair))};
|
||||
new_key_pair(Type) when Type == dh25519; Type == dh448 ->
|
||||
crypto:generate_key(ecdh, ecdh_type(Type));
|
||||
new_key_pair(Type) ->
|
||||
error({unsupported_key_type, Type}).
|
||||
|
||||
pubkey_from_secret(dh25519, Secret) ->
|
||||
enacl:curve25519_scalarmult_base(Secret).
|
||||
pubkey_from_secret(Type, Secret) when Type == dh25519; Type == dh448 ->
|
||||
{Public, Secret} = crypto:generate_key(ecdh, ecdh_type(Type), Secret),
|
||||
Public.
|
||||
|
||||
ecdh_type(dh25519) -> x25519;
|
||||
ecdh_type(dh448) -> x448.
|
||||
|
@ -19,7 +19,7 @@
|
||||
, to_name/1]).
|
||||
|
||||
-ifdef(TEST).
|
||||
-export([to_name/4]).
|
||||
-export([to_name/4, from_name_pattern/1, to_name_pattern/1]).
|
||||
-endif.
|
||||
|
||||
-type noise_pattern() :: nn | kn | nk | kk | nx | kx | xn | in | xk | ik | xx | ix.
|
||||
@ -137,9 +137,9 @@ supported_dh(Dh) ->
|
||||
-spec supported() -> map().
|
||||
supported() ->
|
||||
#{ hs_pattern => [nn, kn, nk, kk, nx, kx, xn, in, xk, ik, xx, ix]
|
||||
, hash => [blake2b, sha256, sha512]
|
||||
, hash => [blake2s, blake2b, sha256, sha512]
|
||||
, cipher => ['ChaChaPoly', 'AESGCM']
|
||||
, dh => [dh25519]
|
||||
, dh => [dh25519, dh448]
|
||||
}.
|
||||
|
||||
to_name(Pattern, Dh, Cipher, Hash) ->
|
||||
@ -148,16 +148,16 @@ to_name(Pattern, Dh, Cipher, Hash) ->
|
||||
|
||||
to_name_pattern(Atom) ->
|
||||
[Simple | Rest] = string:lexemes(atom_to_list(Atom), "_"),
|
||||
string:uppercase(Simple) ++ lists:join("+", Rest).
|
||||
lists:flatten(string:uppercase(Simple) ++ lists:join("+", Rest)).
|
||||
|
||||
from_name_pattern(String) ->
|
||||
[Init | Mod2] = string:lexemes(String, "+"),
|
||||
{Simple, Mod1} = lists:splitwith(fun(C) -> C >= $A andalso C =< $Z end, Init),
|
||||
list_to_atom(string:lowercase(Simple) ++
|
||||
list_to_atom(lists:flatten(string:lowercase(Simple) ++
|
||||
case Mod1 of
|
||||
"" -> "";
|
||||
_ -> "_" ++ lists:join([Mod1 | Mod2], "_")
|
||||
end).
|
||||
_ -> "_" ++ lists:join("_", [Mod1 | Mod2])
|
||||
end)).
|
||||
|
||||
to_name_dh(dh25519) -> "25519";
|
||||
to_name_dh(dh448) -> "448".
|
||||
|
@ -43,7 +43,8 @@ noise_test(_Name, Protocol, Init, Resp, Messages, HSHash) ->
|
||||
SecK = fun(undefined) -> undefined; (Sec) -> enoise_keypair:new(DH, Sec, undefined) end,
|
||||
PubK = fun(undefined) -> undefined; (Pub) -> enoise_keypair:new(DH, Pub) end,
|
||||
HSInit = fun(P, R, #{ e := E, s := S, rs := RS, prologue := PL }) ->
|
||||
enoise_hs_state:init(P, R, PL, {SecK(S), SecK(E), PubK(RS), undefined})
|
||||
{ok, HS} = enoise_hs_state:init(P, R, PL, {SecK(S), SecK(E), PubK(RS), undefined}),
|
||||
HS
|
||||
end,
|
||||
|
||||
InitHS = HSInit(Protocol, initiator, Init),
|
||||
|
@ -7,5 +7,18 @@
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
name_test() ->
|
||||
?assertMatch(<<"Noise_XK_25519_ChaChaPoly_SHA512">>,
|
||||
enoise_protocol:to_name(enoise_protocol:from_name("Noise_XK_25519_ChaChaPoly_SHA512"))).
|
||||
roundtrip("Noise_XK_25519_ChaChaPoly_SHA512"),
|
||||
roundtrip("Noise_NN_25519_AESGCM_BLAKE2b").
|
||||
|
||||
name2_test() ->
|
||||
Name = "Noise_NXpsk2_25519_AESGCM_SHA512",
|
||||
?assertError({name_not_recognized, Name}, enoise_protocol:from_name(Name)).
|
||||
|
||||
name_pattern_test() ->
|
||||
Pat = "XKfallback+psk0",
|
||||
RoundPat = enoise_protocol:to_name_pattern(enoise_protocol:from_name_pattern(Pat)),
|
||||
?assertEqual(Pat, RoundPat).
|
||||
|
||||
roundtrip(Name) ->
|
||||
ExpectedName = iolist_to_binary(Name),
|
||||
?assertMatch(ExpectedName, enoise_protocol:to_name(enoise_protocol:from_name(Name))).
|
||||
|
@ -41,10 +41,9 @@ noise_interactive(V = #{ protocol_name := Name }) ->
|
||||
noise_interactive(_Name, Protocol, Init, Resp, Messages, HSHash) ->
|
||||
DH = enoise_protocol:dh(Protocol),
|
||||
SecK = fun(undefined) -> undefined; (Sec) -> enoise_keypair:new(DH, Sec, undefined) end,
|
||||
PubK = fun(undefined) -> undefined; (Pub) -> enoise_keypair:new(DH, Pub) end,
|
||||
|
||||
HSInit = fun(#{ e := E, s := S, rs := RS, prologue := PL }, R) ->
|
||||
Opts = [{noise, Protocol}, {s, SecK(S)}, {e, SecK(E)}, {rs, PubK(RS)}, {prologue, PL}],
|
||||
Opts = [{noise, Protocol}, {s, SecK(S)}, {e, SecK(E)}, {rs, RS}, {prologue, PL}],
|
||||
enoise:handshake(Opts, R)
|
||||
end,
|
||||
{ok, InitHS} = HSInit(Init, initiator),
|
||||
@ -149,12 +148,12 @@ noise_test_run_(Conf, SKP, CKP) ->
|
||||
Protocol = enoise_protocol:from_name(Conf),
|
||||
Port = 4556,
|
||||
|
||||
SrvOpts = [{echos, 2}, {cpub, CKP}],
|
||||
SrvOpts = [{echos, 2}, {cpub, enoise_keypair:pubkey(CKP)}],
|
||||
EchoSrv = enoise_utils:echo_srv_start(Port, Protocol, SKP, SrvOpts),
|
||||
|
||||
{ok, TcpSock} = gen_tcp:connect("localhost", Port, [{active, once}, binary, {reuseaddr, true}], 100),
|
||||
|
||||
Opts = [{noise, Protocol}, {s, CKP}] ++ [{rs, SKP} || enoise_utils:need_rs(initiator, Conf) ],
|
||||
Opts = [{noise, Protocol}, {s, CKP}] ++ [{rs, enoise_keypair:pubkey(SKP)} || enoise_utils:need_rs(initiator, Conf) ],
|
||||
{ok, EConn, _} = enoise:connect(TcpSock, Opts),
|
||||
|
||||
ok = enoise:send(EConn, <<"Hello World!">>),
|
||||
|
@ -26,7 +26,7 @@ echo_srv(Port, Protocol, SKP, SrvOpts) ->
|
||||
AcceptRes =
|
||||
try
|
||||
enoise:accept(TcpSock, Opts)
|
||||
catch _:R -> gen_tcp:close(TcpSock), {error, {R, erlang:get_stacktrace()}} end,
|
||||
catch _:R:S -> gen_tcp:close(TcpSock), {error, {R, S}} end,
|
||||
|
||||
gen_tcp:close(LSock),
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user