diff --git a/src/Tmds.Ssh/Curve25519KeyExchange.cs b/src/Tmds.Ssh/Curve25519KeyExchange.cs index eb859738..63e9f151 100644 --- a/src/Tmds.Ssh/Curve25519KeyExchange.cs +++ b/src/Tmds.Ssh/Curve25519KeyExchange.cs @@ -62,7 +62,7 @@ public override async Task TryExchangeAsync(KeyExchangeContex return CalculateKeyExchangeOutput(input, sequencePool, sharedSecret, exchangeHash, _hashAlgorithmName); } - private static byte[] CalculateExchangeHash(SequencePool sequencePool, SshConnectionInfo connectionInfo, ReadOnlyPacket clientKexInitMsg, ReadOnlyPacket serverKexInitMsg, byte[] public_host_key, byte[] q_c, byte[] q_s, byte[] sharedSecret, HashAlgorithmName hashAlgorithmName) + protected static byte[] CalculateExchangeHash(SequencePool sequencePool, SshConnectionInfo connectionInfo, ReadOnlyPacket clientKexInitMsg, ReadOnlyPacket serverKexInitMsg, byte[] public_host_key, byte[] q_c, byte[] q_s, byte[] sharedSecret, HashAlgorithmName hashAlgorithmName) { /* string V_C, client's identification string (CR and LF excluded) @@ -105,7 +105,7 @@ private static byte[] DeriveSharedSecret(AsymmetricKeyParameter privateKey, Asym return sharedSecret.ToMPIntByteArray(); } - private static Packet CreateEcdhInitMessage(SequencePool sequencePool, ReadOnlySpan q_c) + protected static Packet CreateEcdhInitMessage(SequencePool sequencePool, ReadOnlySpan q_c) { using var packet = sequencePool.RentPacket(); var writer = packet.GetWriter(); @@ -114,7 +114,7 @@ private static Packet CreateEcdhInitMessage(SequencePool sequencePool, ReadOnlyS return packet.Move(); } - private static ( + protected static ( SshKey public_host_key, byte[] q_s, ReadOnlySequence exchange_hash_signature) diff --git a/src/Tmds.Ssh/SNtruPrime761X25519Sha512KeyExchange.cs b/src/Tmds.Ssh/SNtruPrime761X25519Sha512KeyExchange.cs index 9f8b6d67..d8bf68c8 100644 --- a/src/Tmds.Ssh/SNtruPrime761X25519Sha512KeyExchange.cs +++ b/src/Tmds.Ssh/SNtruPrime761X25519Sha512KeyExchange.cs @@ -1,4 +1,6 @@ -using System.Buffers; +// This file is part of Tmds.Ssh which is released under MIT. +// See file LICENSE for full license details. + using System.Security.Cryptography; using Microsoft.Extensions.Logging; using Org.BouncyCastle.Crypto; @@ -11,7 +13,7 @@ namespace Tmds.Ssh; -sealed class SNtruPrime761X25519Sha512KeyExchange : KeyExchange +sealed class SNtruPrime761X25519Sha512KeyExchange : Curve25519KeyExchange { private readonly SNtruPrimeParameters _sntruPrimeParameters = SNtruPrimeParameters.sntrup761; private readonly HashAlgorithmName _hashAlgorithmName = HashAlgorithmName.SHA512; @@ -68,38 +70,6 @@ public override async Task TryExchangeAsync(KeyExchangeContex return CalculateKeyExchangeOutput(input, sequencePool, sharedSecret, exchangeHash, _hashAlgorithmName); } - private static byte[] CalculateExchangeHash(SequencePool sequencePool, SshConnectionInfo connectionInfo, ReadOnlyPacket clientKexInitMsg, ReadOnlyPacket serverKexInitMsg, byte[] public_host_key, byte[] q_c, byte[] q_s, byte[] sharedSecret, HashAlgorithmName hashAlgorithmName) - { - /* - string V_C, client's identification string (CR and LF excluded) - string V_S, server's identification string (CR and LF excluded) - string I_C, payload of the client's SSH_MSG_KEXINIT - string I_S, payload of the server's SSH_MSG_KEXINIT - string K_S, server's public host key - string Q_C, client's ephemeral public key octet string - string Q_S, server's ephemeral public key octet string - string K, shared secret - */ - using Sequence sequence = sequencePool.RentSequence(); - var writer = new SequenceWriter(sequence); - writer.WriteString(connectionInfo.ClientIdentificationString!); - writer.WriteString(connectionInfo.ServerIdentificationString!); - writer.WriteString(clientKexInitMsg.Payload); - writer.WriteString(serverKexInitMsg.Payload); - writer.WriteString(public_host_key); - writer.WriteString(q_c); - writer.WriteString(q_s); - writer.WriteString(sharedSecret); - - using IncrementalHash hash = IncrementalHash.CreateHash(hashAlgorithmName); - foreach (var segment in sequence.AsReadOnlySequence()) - { - hash.AppendData(segment.Span); - } - return hash.GetHashAndReset(); - } - - private static byte[] DeriveSharedSecret(AsymmetricKeyParameter sntrup761PrivateKey, AsymmetricKeyParameter x25519PrivateKey, byte[] q_s) { var sntrup761Extractor = new SNtruPrimeKemExtractor((SNtruPrimePrivateKeyParameters)sntrup761PrivateKey); @@ -118,31 +88,4 @@ private static byte[] DeriveSharedSecret(AsymmetricKeyParameter sntrup761Private rawSecretAgreement.AsSpan().Clear(); return sharedSecret; } - - private static Packet CreateEcdhInitMessage(SequencePool sequencePool, ReadOnlySpan q_c) - { - using var packet = sequencePool.RentPacket(); - var writer = packet.GetWriter(); - writer.WriteMessageId(MessageId.SSH_MSG_KEX_ECDH_INIT); - writer.WriteString(q_c); - return packet.Move(); - } - - private static ( - SshKey public_host_key, - byte[] q_s, - ReadOnlySequence exchange_hash_signature) - ParceEcdhReply(ReadOnlyPacket packet) - { - var reader = packet.GetReader(); - reader.ReadMessageId(MessageId.SSH_MSG_KEX_ECDH_REPLY); - SshKey public_host_key = reader.ReadSshKey(); - byte[] q_s = reader.ReadStringAsByteArray(); - ReadOnlySequence exchange_hash_signature = reader.ReadStringAsBytes(); - reader.ReadEnd(); - return ( - public_host_key, - q_s, - exchange_hash_signature); - } }