1- using Org . BouncyCastle . Crypto . Agreement ;
2- using Org . BouncyCastle . Crypto . Generators ;
3- using Org . BouncyCastle . Crypto . Parameters ;
4-
5- using Renci . SshNet . Abstractions ;
1+ using Renci . SshNet . Abstractions ;
62using Renci . SshNet . Common ;
73using Renci . SshNet . Messages . Transport ;
84
95namespace Renci . SshNet . Security
106{
11- internal sealed class KeyExchangeECCurve25519 : KeyExchangeEC
7+ internal partial class KeyExchangeECCurve25519 : KeyExchangeEC
128 {
13- private X25519Agreement _keyAgreement ;
9+ #pragma warning disable SA1401 // Fields should be private
10+ #if NET
11+ protected Impl _impl ;
12+ #else
13+ protected BouncyCastleImpl _impl ;
14+ #endif
15+ #pragma warning restore SA1401 // Fields should be private
1416
1517 /// <summary>
1618 /// Gets algorithm name.
@@ -35,29 +37,46 @@ protected override int HashSize
3537 public override void Start ( Session session , KeyExchangeInitMessage message , bool sendClientInitMessage )
3638 {
3739 base . Start ( session , message , sendClientInitMessage ) ;
40+ #if NET
41+ if ( System . OperatingSystem . IsWindowsVersionAtLeast ( 10 ) )
42+ {
43+ _impl = new BclImpl ( ) ;
44+ }
45+ else
46+ #endif
47+ {
48+ _impl = new BouncyCastleImpl ( ) ;
49+ }
50+
51+ StartImpl ( ) ;
52+ }
3853
54+ /// <summary>
55+ /// The implementation of start key exchange algorithm.
56+ /// </summary>
57+ protected virtual void StartImpl ( )
58+ {
3959 Session . RegisterMessage ( "SSH_MSG_KEX_ECDH_REPLY" ) ;
4060
4161 Session . KeyExchangeEcdhReplyMessageReceived += Session_KeyExchangeEcdhReplyMessageReceived ;
4262
43- var g = new X25519KeyPairGenerator ( ) ;
44- g . Init ( new X25519KeyGenerationParameters ( CryptoAbstraction . SecureRandom ) ) ;
45-
46- var aKeyPair = g . GenerateKeyPair ( ) ;
47- _keyAgreement = new X25519Agreement ( ) ;
48- _keyAgreement . Init ( aKeyPair . Private ) ;
49- _clientExchangeValue = ( ( X25519PublicKeyParameters ) aKeyPair . Public ) . GetEncoded ( ) ;
63+ _clientExchangeValue = _impl . GenerateClientPublicKey ( ) ;
5064
5165 SendMessage ( new KeyExchangeEcdhInitMessage ( _clientExchangeValue ) ) ;
5266 }
5367
54- /// <summary>
55- /// Finishes key exchange algorithm.
56- /// </summary>
68+ /// <inheritdoc/>
5769 public override void Finish ( )
5870 {
5971 base . Finish ( ) ;
72+ FinishImpl ( ) ;
73+ }
6074
75+ /// <summary>
76+ /// The implementation of finish key exchange algorithm.
77+ /// </summary>
78+ protected virtual void FinishImpl ( )
79+ {
6180 Session . KeyExchangeEcdhReplyMessageReceived -= Session_KeyExchangeEcdhReplyMessageReceived ;
6281 }
6382
@@ -98,11 +117,19 @@ private void HandleServerEcdhReply(byte[] hostKey, byte[] serverExchangeValue, b
98117 _hostKey = hostKey ;
99118 _signature = signature ;
100119
101- var publicKey = new X25519PublicKeyParameters ( serverExchangeValue ) ;
102-
103- var k1 = new byte [ _keyAgreement . AgreementSize ] ;
104- _keyAgreement . CalculateAgreement ( publicKey , k1 , 0 ) ;
120+ var k1 = _impl . CalculateAgreement ( serverExchangeValue ) ;
105121 SharedKey = k1 . ToBigInteger2 ( ) . ToByteArray ( isBigEndian : true ) ;
106122 }
123+
124+ /// <inheritdoc/>
125+ protected override void Dispose ( bool disposing )
126+ {
127+ base . Dispose ( disposing ) ;
128+
129+ if ( disposing )
130+ {
131+ _impl ? . Dispose ( ) ;
132+ }
133+ }
107134 }
108135}
0 commit comments