1
1
using System ;
2
2
3
3
using 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 ;
8
4
9
- using Renci . SshNet . Abstractions ;
10
5
using Renci . SshNet . Common ;
11
6
using Renci . SshNet . Messages . Transport ;
12
7
13
8
namespace Renci . SshNet . Security
14
9
{
15
- internal abstract class KeyExchangeECDH : KeyExchangeEC
10
+ internal abstract partial class KeyExchangeECDH : KeyExchangeEC
16
11
{
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
+
17
26
/// <summary>
18
27
/// Gets the parameter of the curve.
19
28
/// </summary>
@@ -22,9 +31,6 @@ internal abstract class KeyExchangeECDH : KeyExchangeEC
22
31
/// </value>
23
32
protected abstract X9ECParameters CurveParameter { get ; }
24
33
25
- private ECDHCBasicAgreement _keyAgreement ;
26
- private ECDomainParameters _domainParameters ;
27
-
28
34
/// <inheritdoc/>
29
35
public override void Start ( Session session , KeyExchangeInitMessage message , bool sendClientInitMessage )
30
36
{
@@ -34,19 +40,20 @@ public override void Start(Session session, KeyExchangeInitMessage message, bool
34
40
35
41
Session . KeyExchangeEcdhReplyMessageReceived += Session_KeyExchangeEcdhReplyMessageReceived ;
36
42
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 ( ) ;
50
57
51
58
SendMessage ( new KeyExchangeEcdhInitMessage ( _clientExchangeValue ) ) ;
52
59
}
@@ -86,18 +93,38 @@ private void HandleServerEcdhReply(byte[] hostKey, byte[] serverExchangeValue, b
86
93
_hostKey = hostKey ;
87
94
_signature = signature ;
88
95
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 ) ;
94
117
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
+ }
98
121
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
+ }
101
128
}
102
129
}
103
130
}
0 commit comments