11using System ;
22
33using Org . BouncyCastle . Asn1 . X9 ;
4- using Org . BouncyCastle . Crypto . Agreement ;
5- using Org . BouncyCastle . Crypto . Generators ;
6- using Org . BouncyCastle . Crypto . Parameters ;
7- using Org . BouncyCastle . Math . EC ;
84
9- using Renci . SshNet . Abstractions ;
105using Renci . SshNet . Common ;
116using Renci . SshNet . Messages . Transport ;
127
138namespace Renci . SshNet . Security
149{
15- internal abstract class KeyExchangeECDH : KeyExchangeEC
10+ internal abstract partial class KeyExchangeECDH : KeyExchangeEC
1611 {
12+ #if NET8_0_OR_GREATER
13+ private Impl _impl ;
14+
15+ /// <summary>
16+ /// Gets the curve.
17+ /// </summary>
18+ /// <value>
19+ /// The curve.
20+ /// </value>
21+ protected abstract System . Security . Cryptography . ECCurve Curve { get ; }
22+ #else
23+ private BouncyCastleImpl _impl ;
24+ #endif
25+
1726 /// <summary>
1827 /// Gets the parameter of the curve.
1928 /// </summary>
@@ -22,9 +31,6 @@ internal abstract class KeyExchangeECDH : KeyExchangeEC
2231 /// </value>
2332 protected abstract X9ECParameters CurveParameter { get ; }
2433
25- private ECDHCBasicAgreement _keyAgreement ;
26- private ECDomainParameters _domainParameters ;
27-
2834 /// <inheritdoc/>
2935 public override void Start ( Session session , KeyExchangeInitMessage message , bool sendClientInitMessage )
3036 {
@@ -34,19 +40,20 @@ public override void Start(Session session, KeyExchangeInitMessage message, bool
3440
3541 Session . KeyExchangeEcdhReplyMessageReceived += Session_KeyExchangeEcdhReplyMessageReceived ;
3642
37- _domainParameters = new ECDomainParameters ( CurveParameter . Curve ,
38- CurveParameter . G ,
39- CurveParameter . N ,
40- CurveParameter . H ,
41- CurveParameter . GetSeed ( ) ) ;
42-
43- var g = new ECKeyPairGenerator ( ) ;
44- g . Init ( new ECKeyGenerationParameters ( _domainParameters , CryptoAbstraction . SecureRandom ) ) ;
45-
46- var aKeyPair = g . GenerateKeyPair ( ) ;
47- _keyAgreement = new ECDHCBasicAgreement ( ) ;
48- _keyAgreement . Init ( aKeyPair . Private ) ;
49- _clientExchangeValue = ( ( ECPublicKeyParameters ) aKeyPair . Public ) . Q . GetEncoded ( ) ;
43+ #if NET8_0_OR_GREATER
44+ if ( ! OperatingSystem . IsWindows ( ) || OperatingSystem . IsWindowsVersionAtLeast ( 10 ) )
45+ {
46+ _impl = new BclImpl ( Curve ) ;
47+ }
48+ else
49+ {
50+ _impl = new BouncyCastleImpl ( CurveParameter ) ;
51+ }
52+ #else
53+ _impl = new BouncyCastleImpl ( CurveParameter ) ;
54+ #endif
55+
56+ _clientExchangeValue = _impl . GenerateClientECPoint ( ) ;
5057
5158 SendMessage ( new KeyExchangeEcdhInitMessage ( _clientExchangeValue ) ) ;
5259 }
@@ -86,18 +93,38 @@ private void HandleServerEcdhReply(byte[] hostKey, byte[] serverExchangeValue, b
8693 _hostKey = hostKey ;
8794 _signature = signature ;
8895
89- var cordSize = ( serverExchangeValue . Length - 1 ) / 2 ;
90- var x = new byte [ cordSize ] ;
91- Buffer . BlockCopy ( serverExchangeValue , 1 , x , 0 , x . Length ) ; // first byte is format. should be checked and passed to bouncy castle?
92- var y = new byte [ cordSize ] ;
93- Buffer . BlockCopy ( serverExchangeValue , cordSize + 1 , y , 0 , y . Length ) ;
96+ var agreement = _impl . CalculateAgreement ( serverExchangeValue ) ;
97+
98+ SharedKey = agreement . ToBigInteger2 ( ) . ToByteArray ( ) . Reverse ( ) ;
99+ }
100+
101+ /// <inheritdoc/>
102+ protected override void Dispose ( bool disposing )
103+ {
104+ base . Dispose ( disposing ) ;
105+
106+ if ( disposing )
107+ {
108+ _impl ? . Dispose ( ) ;
109+ }
110+ }
111+
112+ private abstract class Impl : IDisposable
113+ {
114+ public abstract byte [ ] GenerateClientECPoint ( ) ;
115+
116+ public abstract byte [ ] CalculateAgreement ( byte [ ] serverECPoint ) ;
94117
95- var c = ( FpCurve ) _domainParameters . Curve ;
96- var q = c . CreatePoint ( new Org . BouncyCastle . Math . BigInteger ( 1 , x ) , new Org . BouncyCastle . Math . BigInteger ( 1 , y ) ) ;
97- var publicKey = new ECPublicKeyParameters ( "ECDH" , q , _domainParameters ) ;
118+ protected virtual void Dispose ( bool disposing )
119+ {
120+ }
98121
99- var k1 = _keyAgreement . CalculateAgreement ( publicKey ) ;
100- SharedKey = k1 . ToByteArray ( ) . ToBigInteger2 ( ) . ToByteArray ( ) . Reverse ( ) ;
122+ public void Dispose ( )
123+ {
124+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
125+ Dispose ( disposing : true ) ;
126+ GC . SuppressFinalize ( this ) ;
127+ }
101128 }
102129 }
103130}
0 commit comments