<commit_before>%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2004-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%%     http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% %CopyrightEnd%
%%

%%

%%% Description: SSH transport protocol

-module(ssh_transport).

-include_lib("public_key/include/public_key.hrl").
-include_lib("kernel/include/inet.hrl").

-include("ssh_transport.hrl").
-include("ssh.hrl").

-export([versions/2, hello_version_msg/1]).
-export([next_seqnum/1, 
	 supported_algorithms/0, supported_algorithms/1,
	 default_algorithms/0, default_algorithms/1,
         algo_classes/0, algo_class/1,
         algo_two_spec_classes/0, algo_two_spec_class/1,
	 handle_packet_part/4,
	 handle_hello_version/1,
	 key_exchange_init_msg/1,
	 key_init/3, new_keys_message/1,
         ext_info_message/1,
	 handle_kexinit_msg/3, handle_kexdh_init/2,
	 handle_kex_dh_gex_group/2, handle_kex_dh_gex_init/2, handle_kex_dh_gex_reply/2,
	 handle_new_keys/2, handle_kex_dh_gex_request/2,
	 handle_kexdh_reply/2, 
	 handle_kex_ecdh_init/2,
	 handle_kex_ecdh_reply/2,
         parallell_gen_key/1,
	 extract_public_key/1,
	 ssh_packet/2, pack/2,
         valid_key_sha_alg/2,
	 sha/1, sign/3, verify/5]).

-export([dbg_trace/3]).

%%% For test suites
-export([pack/3, adjust_algs_for_peer_version/2]).
-export([decompress/2,  decrypt_blocks/3, is_valid_mac/3 ]). % FIXME: remove

-define(Estring(X), ?STRING((if is_binary(X) -> X;
				is_list(X) -> list_to_binary(X);
				X==undefined -> <<>>
			     end))).
-define(Empint(X),     (ssh_bits:mpint(X))/binary ).
-define(Ebinary(X),    ?STRING(X) ).
-define(Euint32(X),   ?UINT32(X) ).

%%%----------------------------------------------------------------------------
%%%
%%% There is a difference between supported and default algorithms. The
%%% SUPPORTED algorithms can be handled (maybe untested...). The DEFAULT ones
%%% are announced in ssh_msg_kexinit and in ssh:default_algorithms/0 to the
%%% user.
%%%
%%% A supported algorithm can be requested in the option 'preferred_algorithms',
%%% but may give unexpected results before being promoted to default.
%%%
%%% This makes it possible to add experimental algorithms (in supported_algorithms)
%%% and test them without letting the default users know about them.
%%%

default_algorithms() -> [{K,default_algorithms(K)} || K <- algo_classes()].

algo_classes() -> [kex, public_key, cipher, mac, compression].

algo_class(kex) -> true;
algo_class(public_key) -> true;
algo_class(cipher) -> true;
algo_class(mac) -> true;
algo_class(compression) -> true;
algo_class(_) -> false.


algo_two_spec_classes() -> [cipher, mac, compression].

algo_two_spec_class(cipher) -> true;
algo_two_spec_class(mac) -> true;
algo_two_spec_class(compression) -> true;
algo_two_spec_class(_) -> false.

    

default_algorithms(kex) ->
    supported_algorithms(kex, [
                               %% Under devolpment:
                               'curve25519-sha256',
                               'curve25519-sha25<EMAIL>',
                               'curve448-sha512',
                               %%  Gone in OpenSSH 7.3.p1:
                               'diffie-hellman-group1-sha1'
                              ]);

default_algorithms(cipher) ->
    supported_algorithms(cipher, same(['AEAD_AES_128_GCM',
				       'AEAD_AES_256_GCM']));
default_algorithms(mac) ->
    supported_algorithms(mac, same(['AEAD_AES_128_GCM',
				    'AEAD_AES_256_GCM']));

default_algorithms(Alg) ->
    supported_algorithms(Alg, []).


supported_algorithms() -> [{K,supported_algorithms(K)} || K <- algo_classes()].

supported_algorithms(kex) ->
    select_crypto_supported(
      [
       {'ecdh-sha2-nistp384',                   [{public_keys,ecdh}, {curves,secp384r1}, {hashs,sha384}]},
       {'ecdh-sha2-nistp521',                   [{public_keys,ecdh}, {curves,secp521r1}, {hashs,sha512}]},
       {'ecdh-sha2-nistp256',                   [{public_keys,ecdh}, {curves,secp256r1}, {hashs,sha256}]},
       %% https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves
       %% Secure Shell (SSH) Key Exchange Method using Curve25519 and Curve448
       {'curve25519-sha256',                    [{public_keys,eddh}, {curves,x25519}, {hashs,sha256}]},
       {'curve25519-sha256@libssh.org',         [{public_keys,eddh}, {curves,x25519}, {hashs,sha256}]},
       {'curve448-sha512',                      [{public_keys,eddh}, {curves,x448},   {hashs,sha512}]},
       {'diffie-hellman-group-exchange-sha256', [{public_keys,dh},   {hashs,sha256}]},
       {'diffie-hellman-group16-sha512',        [{public_keys,dh},   {hashs,sha512}]}, % In OpenSSH 7.3.p1
       {'diffie-hellman-group18-sha512',        [{public_keys,dh},   {hashs,sha512}]}, % In OpenSSH 7.3.p1
       {'diffie-hellman-group14-sha256',        [{public_keys,dh},   {hashs,sha256}]}, % In OpenSSH 7.3.p1
       {'diffie-hellman-group14-sha1',          [{public_keys,dh},   {hashs,sha}]},
       {'diffie-hellman-group-exchange-sha1',   [{public_keys,dh},   {hashs,sha}]},
       {'diffie-hellman-group1-sha1',           [{public_keys,dh},   {hashs,sha}]}
      ]);
supported_algorithms(public_key) ->
    select_crypto_supported(
      [
       {'ecdsa-sha2-nistp384',  [{public_keys,ecdsa}, {hashs,sha384}, {curves,secp384r1}]},
       {'ecdsa-sha2-nistp521',  [{public_keys,ecdsa}, {hashs,sha512}, {curves,secp521r1}]},
       {'ecdsa-sha2-nistp256',  [{public_keys,ecdsa}, {hashs,sha256}, {curves,secp256r1}]},
       {'ssh-rsa',              [{public_keys,rsa},   {hashs,sha}                         ]},
       {'rsa-sha2-256',         [{public_keys,rsa},   {hashs,sha256}                      ]},
       {'rsa-sha2-512',         [{public_keys,rsa},   {hashs,sha512}                      ]},
       {'ssh-dss',              [{public_keys,dss},   {hashs,sha}                         ]} % Gone in OpenSSH 7.3.p1
      ]);
 
supported_algorithms(cipher) ->
    same(
      select_crypto_supported(
	[
         {'<EMAIL>', [{ciphers,{aes_gcm,256}}]},
         {'aes256-ctr',       [{ciphers,{aes_ctr,256}}]},
         {'aes192-ctr',       [{ciphers,{aes_ctr,192}}]},
	 {'<EMAIL>', [{ciphers,{aes_gcm,128}}]},
	 {'aes128-ctr',       [{ciphers,{aes_ctr,128}}]},
	 {'AEAD_AES_256_GCM', [{ciphers,{aes_gcm,256}}]},
	 {'AEAD_AES_128_GCM', [{ciphers,{aes_gcm,128}}]},
	 {'aes128-cbc',       [{ciphers,aes_cbc128}]},
	 {'3des-cbc',         [{ciphers,des3_cbc}]}
	]
       ));
supported_algorithms(mac) ->
    same(
      select_crypto_supported(
	[{'hmac-sha2-256',    [{hashs,sha256}]},
	 {'hmac-sha2-512',    [{hashs,sha512}]},
	 {'hmac-sha1',        [{hashs,sha}]},
	 {'AEAD_AES_128_GCM', [{ciphers,{aes_gcm,128}}]},
	 {'AEAD_AES_256_GCM', [{ciphers,{aes_gcm,256}}]}
	]
       ));
supported_algorithms(compression) ->
    same(['none',
 	  '<EMAIL>',
	  'zlib'
	 ]).

%%%----------------------------------------------------------------------------
versions(client, Options)-><commit_msg>ssh: Use the 'macs' tag in crypto:supports/0<commit_after>%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2004-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%%     http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% %CopyrightEnd%
%%

%%

%%% Description: SSH transport protocol

-module(ssh_transport).

-include_lib("public_key/include/public_key.hrl").
-include_lib("kernel/include/inet.hrl").

-include("ssh_transport.hrl").
-include("ssh.hrl").

-export([versions/2, hello_version_msg/1]).
-export([next_seqnum/1, 
	 supported_algorithms/0, supported_algorithms/1,
	 default_algorithms/0, default_algorithms/1,
         algo_classes/0, algo_class/1,
         algo_two_spec_classes/0, algo_two_spec_class/1,
	 handle_packet_part/4,
	 handle_hello_version/1,
	 key_exchange_init_msg/1,
	 key_init/3, new_keys_message/1,
         ext_info_message/1,
	 handle_kexinit_msg/3, handle_kexdh_init/2,
	 handle_kex_dh_gex_group/2, handle_kex_dh_gex_init/2, handle_kex_dh_gex_reply/2,
	 handle_new_keys/2, handle_kex_dh_gex_request/2,
	 handle_kexdh_reply/2, 
	 handle_kex_ecdh_init/2,
	 handle_kex_ecdh_reply/2,
         parallell_gen_key/1,
	 extract_public_key/1,
	 ssh_packet/2, pack/2,
         valid_key_sha_alg/2,
	 sha/1, sign/3, verify/5]).

-export([dbg_trace/3]).

%%% For test suites
-export([pack/3, adjust_algs_for_peer_version/2]).
-export([decompress/2,  decrypt_blocks/3, is_valid_mac/3 ]). % FIXME: remove

-define(Estring(X), ?STRING((if is_binary(X) -> X;
				is_list(X) -> list_to_binary(X);
				X==undefined -> <<>>
			     end))).
-define(Empint(X),     (ssh_bits:mpint(X))/binary ).
-define(Ebinary(X),    ?STRING(X) ).
-define(Euint32(X),   ?UINT32(X) ).

%%%----------------------------------------------------------------------------
%%%
%%% There is a difference between supported and default algorithms. The
%%% SUPPORTED algorithms can be handled (maybe untested...). The DEFAULT ones
%%% are announced in ssh_msg_kexinit and in ssh:default_algorithms/0 to the
%%% user.
%%%
%%% A supported algorithm can be requested in the option 'preferred_algorithms',
%%% but may give unexpected results before being promoted to default.
%%%
%%% This makes it possible to add experimental algorithms (in supported_algorithms)
%%% and test them without letting the default users know about them.
%%%

default_algorithms() -> [{K,default_algorithms(K)} || K <- algo_classes()].

algo_classes() -> [kex, public_key, cipher, mac, compression].

algo_class(kex) -> true;
algo_class(public_key) -> true;
algo_class(cipher) -> true;
algo_class(mac) -> true;
algo_class(compression) -> true;
algo_class(_) -> false.


algo_two_spec_classes() -> [cipher, mac, compression].

algo_two_spec_class(cipher) -> true;
algo_two_spec_class(mac) -> true;
algo_two_spec_class(compression) -> true;
algo_two_spec_class(_) -> false.

    

default_algorithms(kex) ->
    supported_algorithms(kex, [
                               %% Under devolpment:
                               'curve25519-sha256',
                               'curve25519-sha256@libssh.org',
                               'curve448-sha512',
                               %%  Gone in OpenSSH 7.3.p1:
                               'diffie-hellman-group1-sha1'
                              ]);

default_algorithms(cipher) ->
    supported_algorithms(cipher, same(['AEAD_AES_128_GCM',
				       'AEAD_AES_256_GCM']));
default_algorithms(mac) ->
    supported_algorithms(mac, same(['AEAD_AES_128_GCM',
				    'AEAD_AES_256_GCM']));

default_algorithms(Alg) ->
    supported_algorithms(Alg, []).


supported_algorithms() -> [{K,supported_algorithms(K)} || K <- algo_classes()].

supported_algorithms(kex) ->
    select_crypto_supported(
      [
       {'ecdh-sha2-nistp384',                   [{public_keys,ecdh}, {curves,secp384r1}, {hashs,sha384}]},
       {'ecdh-sha2-nistp521',                   [{public_keys,ecdh}, {curves,secp521r1}, {hashs,sha512}]},
       {'ecdh-sha2-nistp256',                   [{public_keys,ecdh}, {curves,secp256r1}, {hashs,sha256}]},
       %% https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves
       %% Secure Shell (SSH) Key Exchange Method using Curve25519 and Curve448
       {'curve25519-sha256',                    [{public_keys,eddh}, {curves,x25519}, {hashs,sha256}]},
       {'curve25519-sha256@libssh.<EMAIL>',         [{public_keys,eddh}, {curves,x25519}, {hashs,sha256}]},
       {'curve448-sha512',                      [{public_keys,eddh}, {curves,x448},   {hashs,sha512}]},
       {'diffie-hellman-group-exchange-sha256', [{public_keys,dh},   {hashs,sha256}]},
       {'diffie-hellman-group16-sha512',        [{public_keys,dh},   {hashs,sha512}]}, % In OpenSSH 7.3.p1
       {'diffie-hellman-group18-sha512',        [{public_keys,dh},   {hashs,sha512}]}, % In OpenSSH 7.3.p1
       {'diffie-hellman-group14-sha256',        [{public_keys,dh},   {hashs,sha256}]}, % In OpenSSH 7.3.p1
       {'diffie-hellman-group14-sha1',          [{public_keys,dh},   {hashs,sha}]},
       {'diffie-hellman-group-exchange-sha1',   [{public_keys,dh},   {hashs,sha}]},
       {'diffie-hellman-group1-sha1',           [{public_keys,dh},   {hashs,sha}]}
      ]);
supported_algorithms(public_key) ->
    select_crypto_supported(
      [
       {'ecdsa-sha2-nistp384',  [{public_keys,ecdsa}, {hashs,sha384}, {curves,secp384r1}]},
       {'ecdsa-sha2-nistp521',  [{public_keys,ecdsa}, {hashs,sha512}, {curves,secp521r1}]},
       {'ecdsa-sha2-nistp256',  [{public_keys,ecdsa}, {hashs,sha256}, {curves,secp256r1}]},
       {'ssh-rsa',              [{public_keys,rsa},   {hashs,sha}                         ]},
       {'rsa-sha2-256',         [{public_keys,rsa},   {hashs,sha256}                      ]},
       {'rsa-sha2-512',         [{public_keys,rsa},   {hashs,sha512}                      ]},
       {'ssh-dss',              [{public_keys,dss},   {hashs,sha}                         ]} % Gone in OpenSSH 7.3.p1
      ]);
 
supported_algorithms(cipher) ->
    same(
      select_crypto_supported(
	[
         {'<EMAIL>', [{ciphers,{aes_gcm,256}}]},
         {'aes256-ctr',       [{ciphers,{aes_ctr,256}}]},
         {'aes192-ctr',       [{ciphers,{aes_ctr,192}}]},
	 {'<EMAIL>', [{ciphers,{aes_gcm,128}}]},
	 {'aes128-ctr',       [{ciphers,{aes_ctr,128}}]},
	 {'AEAD_AES_256_GCM', [{ciphers,{aes_gcm,256}}]},
	 {'AEAD_AES_128_GCM', [{ciphers,{aes_gcm,128}}]},
	 {'aes128-cbc',       [{ciphers,aes_cbc128}]},
	 {'3des-cbc',         [{ciphers,des3_cbc}]}
	]
       ));
supported_algorithms(mac) ->
    same(
      select_crypto_supported(
	[{'hmac-sha2-256',    [{macs,hmac}, {hashs,sha256}]},
	 {'hmac-sha2-512',    [{macs,hmac}, {hashs,sha512}]},
	 {'hmac-sha1',        [{macs,hmac}, {hashs,sha}]},
	 {'AEAD_AES_128_GCM', [{ciphers,{aes_gcm,128}}]},
	 {'AEAD_AES_256_GCM', [{ciphers,{aes_gcm,256}}]}
	]
       ));
supported_algorithms(compression) ->
    same(['none',
 	  '<EMAIL>',
	  'zlib'
	 ]).

%%%----------------------------------------------------------------------------
versions(client, Options)->
{'fraction_non_alphanumeric': 0.18299470260846243, 'fraction_numerical': 0.04667069000201167, 'mean_word_length': 2.8838541666666666, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 69, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2335976', 'n_tokens_mistral': 5843, 'n_tokens_neox': 5223, 'n_words': 858}