1- // Licensed to the .NET Foundation under one or more agreements.
1+ // Licensed to the .NET Foundation under one or more agreements.
22// The .NET Foundation licenses this file to you under the MIT license.
33// See the LICENSE file in the project root for more information.
44
@@ -39,6 +39,7 @@ private readonly struct ECCPublicKeyBlob
3939 // => ECDiffieHellmanPublicKey.ToByteArray() is not supported in Unix
4040 internal static byte [ ] GetECDiffieHellmanPublicKeyBlob ( ECDiffieHellman ecDiffieHellman )
4141 {
42+ #if NET6_0_OR_GREATER
4243 byte [ ] keyBlob = new byte [ ECCPublicKeyBlob . Size ] ;
4344
4445 // Set magic number
@@ -53,6 +54,16 @@ internal static byte[] GetECDiffieHellmanPublicKeyBlob(ECDiffieHellman ecDiffieH
5354 Buffer . BlockCopy ( ecPoint . X , 0 , keyBlob , ECCPublicKeyBlob . HeaderSize , ECCPublicKeyBlob . KeySize ) ;
5455 Buffer . BlockCopy ( ecPoint . Y , 0 , keyBlob , ECCPublicKeyBlob . HeaderSize + ECCPublicKeyBlob . KeySize , ECCPublicKeyBlob . KeySize ) ;
5556 return keyBlob ;
57+ #else
58+ if ( ecDiffieHellman is ECDiffieHellmanCng cng )
59+ {
60+ return cng . Key . Export ( CngKeyBlobFormat . EccPublicBlob ) ;
61+ }
62+ else
63+ {
64+ throw new InvalidOperationException ( ) ;
65+ }
66+ #endif
5667 }
5768
5869 // The RSA public key blob is structured as follows:
@@ -75,6 +86,7 @@ private readonly struct RSAPublicKeyBlob
7586
7687 internal static RSA CreateRSAFromPublicKeyBlob ( byte [ ] keyBlob )
7788 {
89+ #if NET6_0_OR_GREATER
7890 Debug . Assert ( keyBlob . Length == RSAPublicKeyBlob . Size , $ "RSA public key blob was not the expected length. Actual: { keyBlob . Length } . Expected: { RSAPublicKeyBlob . Size } ") ;
7991
8092 byte [ ] exponent = new byte [ RSAPublicKeyBlob . ExponentSize ] ;
@@ -87,10 +99,15 @@ internal static RSA CreateRSAFromPublicKeyBlob(byte[] keyBlob)
8799 Modulus = modulus
88100 } ;
89101 return RSA . Create ( rsaParameters ) ;
102+ #else
103+ CngKey key = CngKey . Import ( keyBlob , CngKeyBlobFormat . GenericPublicBlob ) ;
104+ return new RSACng ( key ) ;
105+ #endif
90106 }
91107
92108 internal static ECDiffieHellman CreateECDiffieHellmanFromPublicKeyBlob ( byte [ ] keyBlob )
93109 {
110+ #if NET6_0_OR_GREATER
94111 Debug . Assert ( keyBlob . Length == ECCPublicKeyBlob . Size , $ "ECC public key blob was not the expected length. Actual: { keyBlob . Length } . Expected: { ECCPublicKeyBlob . Size } ") ;
95112
96113 byte [ ] x = new byte [ ECCPublicKeyBlob . KeySize ] ;
@@ -109,27 +126,61 @@ internal static ECDiffieHellman CreateECDiffieHellmanFromPublicKeyBlob(byte[] ke
109126 } ;
110127
111128 return ECDiffieHellman . Create ( parameters ) ;
129+ #else
130+ CngKey key = CngKey . Import ( keyBlob , CngKeyBlobFormat . GenericPublicBlob ) ;
131+ return new ECDiffieHellmanCng ( key ) ;
132+ #endif
112133 }
113134
114135 internal static ECDiffieHellman CreateECDiffieHellman ( int keySize )
115136 {
137+ #if NET6_0_OR_GREATER
116138 // platform agnostic creates a key of the correct size but does not
117139 // set the key derivation type or algorithm, these must be set by calling
118140 // DeriveKeyFromHash later in DeriveKey
119141 ECDiffieHellman clientDHKey = ECDiffieHellman . Create ( ) ;
120142 clientDHKey . KeySize = keySize ;
143+ #else
144+ // Cng sets the key size and hash algorithm at creation time and these
145+ // parameters are then used later when DeriveKeyMaterial is called
146+ ECDiffieHellmanCng clientDHKey = new ECDiffieHellmanCng ( keySize ) ;
147+ clientDHKey . KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction . Hash ;
148+ clientDHKey . HashAlgorithm = CngAlgorithm . Sha256 ;
149+ #endif
121150 return clientDHKey ;
122151 }
123152
124- internal static byte [ ] DeriveKey ( ECDiffieHellman ecd , ECDiffieHellmanPublicKey publicKey )
153+ internal static byte [ ] DeriveKey ( ECDiffieHellman ecDiffieHellman , ECDiffieHellmanPublicKey publicKey )
125154 {
155+ #if NET6_0_OR_GREATER
126156 // see notes in CreateECDDiffieHellman
127- return ecd . DeriveKeyFromHash ( publicKey , HashAlgorithmName . SHA256 ) ;
157+ return ecDiffieHellman . DeriveKeyFromHash ( publicKey , HashAlgorithmName . SHA256 ) ;
158+ #else
159+ if ( ecDiffieHellman is ECDiffieHellmanCng cng )
160+ {
161+ return cng . DeriveKeyMaterial ( publicKey ) ;
162+ }
163+ else
164+ {
165+ throw new InvalidOperationException ( ) ;
166+ }
167+ #endif
128168 }
129169
130170 internal static RSA GetRSAFromCertificate ( X509Certificate2 certificate )
131171 {
172+ #if NET6_0_OR_GREATER
132173 return certificate . GetRSAPublicKey ( ) ;
174+ #else
175+ RSAParameters parameters ;
176+ using ( RSA rsaCsp = certificate . GetRSAPublicKey ( ) )
177+ {
178+ parameters = rsaCsp . ExportParameters ( includePrivateParameters : false ) ;
179+ }
180+ RSACng rsaCng = new RSACng ( ) ;
181+ rsaCng . ImportParameters ( parameters ) ;
182+ return rsaCng ;
183+ #endif
133184 }
134185 }
135186}
0 commit comments