22// The .NET Foundation licenses this file to you under the MIT license.
33
44using System . Linq ;
5+ using System . Text ;
56using Test . Cryptography ;
67using Xunit ;
8+ using TempFileHolder = System . Security . Cryptography . X509Certificates . Tests . TempFileHolder ;
79
810namespace System . Security . Cryptography . Tests
911{
@@ -43,10 +45,13 @@ public class OpenSslNamedKeysTests
4345 private static string TpmRsaDecryptKeyHandleUri { get ; } = GetHandleKeyUri ( TpmRsaDecryptKeyHandle ) ;
4446
4547 public static bool ShouldRunEngineTests { get ; } = PlatformDetection . OpenSslPresentOnSystem && StringToBool ( Environment . GetEnvironmentVariable ( TestEngineEnabledEnvVarName ) ) ;
46- public static bool ShouldRunProviderEcDsaTests { get ; } = PlatformDetection . OpenSslPresentOnSystem && ! string . IsNullOrEmpty ( TpmEcDsaKeyHandleUri ) ;
47- public static bool ShouldRunProviderEcDhTests { get ; } = PlatformDetection . OpenSslPresentOnSystem && ! string . IsNullOrEmpty ( TpmEcDhKeyHandleUri ) ;
48- public static bool ShouldRunProviderRsaSignTests { get ; } = PlatformDetection . OpenSslPresentOnSystem && ! string . IsNullOrEmpty ( TpmRsaSignKeyHandleUri ) ;
49- public static bool ShouldRunProviderRsaDecryptTests { get ; } = PlatformDetection . OpenSslPresentOnSystem && ! string . IsNullOrEmpty ( TpmRsaDecryptKeyHandleUri ) ;
48+
49+ public static bool ProvidersSupported { get ; } = PlatformDetection . IsOpenSsl3 ;
50+ public static bool ProvidersNotSupported => ! ProvidersSupported ;
51+ public static bool ShouldRunProviderEcDsaTests { get ; } = ProvidersSupported && ! string . IsNullOrEmpty ( TpmEcDsaKeyHandleUri ) ;
52+ public static bool ShouldRunProviderEcDhTests { get ; } = ProvidersSupported && ! string . IsNullOrEmpty ( TpmEcDhKeyHandleUri ) ;
53+ public static bool ShouldRunProviderRsaSignTests { get ; } = ProvidersSupported && ! string . IsNullOrEmpty ( TpmRsaSignKeyHandleUri ) ;
54+ public static bool ShouldRunProviderRsaDecryptTests { get ; } = ProvidersSupported && ! string . IsNullOrEmpty ( TpmRsaDecryptKeyHandleUri ) ;
5055 public static bool ShouldRunAnyProviderTests => ShouldRunProviderEcDsaTests || ShouldRunProviderEcDhTests || ShouldRunProviderRsaSignTests || ShouldRunProviderRsaDecryptTests ;
5156
5257 public static bool ShouldRunTpmTssTests => ShouldRunEngineTests && ! string . IsNullOrEmpty ( TpmEcDsaKeyHandle ) ;
@@ -86,10 +91,15 @@ private static string GetHandleKeyUri(string handle)
8691 "B27434FA544BDAC679E1E16581D0E90203010001" ) . HexToByteArray ( ) ;
8792
8893 [ ConditionalFact ( typeof ( PlatformDetection ) , nameof ( PlatformDetection . OpenSslNotPresentOnSystem ) ) ]
89- public static void NotSupported ( )
94+ public static void EngineNotSupported_ThrowsPlatformNotSupported ( )
9095 {
9196 Assert . Throws < PlatformNotSupportedException > ( ( ) => SafeEvpPKeyHandle . OpenPublicKeyFromEngine ( TestEngineName , TestEngineKeyId ) ) ;
9297 Assert . Throws < PlatformNotSupportedException > ( ( ) => SafeEvpPKeyHandle . OpenPrivateKeyFromEngine ( TestEngineName , TestEngineKeyId ) ) ;
98+ }
99+
100+ [ ConditionalFact ( nameof ( ProvidersNotSupported ) ) ]
101+ public static void ProvidersNotSupported_ThrowsPlatformNotSupported ( )
102+ {
93103 Assert . Throws < PlatformNotSupportedException > ( ( ) => SafeEvpPKeyHandle . OpenKeyFromProvider ( Tpm2ProviderName , AnyProviderKeyUri ) ) ;
94104 }
95105
@@ -111,10 +121,14 @@ public static void EmptyNameThroughNullCharacter()
111121 {
112122 Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenPrivateKeyFromEngine ( "\0 " , "foo" ) ) ;
113123 Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenPublicKeyFromEngine ( "\0 " , "foo" ) ) ;
114- Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenKeyFromProvider ( "\0 " , "foo" ) ) ;
124+
125+ if ( ProvidersSupported )
126+ {
127+ Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenKeyFromProvider ( "\0 " , "foo" ) ) ;
128+ }
115129 }
116130
117- [ ConditionalFact ( typeof ( PlatformDetection ) , nameof ( PlatformDetection . OpenSslPresentOnSystem ) ) ]
131+ [ ConditionalFact ( nameof ( ProvidersSupported ) ) ]
118132 public static void EmptyUriThroughNullCharacter ( )
119133 {
120134 Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenKeyFromProvider ( "default" , "\0 " ) ) ;
@@ -127,7 +141,7 @@ public static void Engine_NonExisting()
127141 Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenPublicKeyFromEngine ( NonExistingEngineOrProviderKeyName , TestEngineKeyId ) ) ;
128142 }
129143
130- [ ConditionalFact ( typeof ( PlatformDetection ) , nameof ( PlatformDetection . OpenSslPresentOnSystem ) ) ]
144+ [ ConditionalFact ( nameof ( ProvidersSupported ) ) ]
131145 public static void Provider_NonExisting ( )
132146 {
133147 Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenKeyFromProvider ( NonExistingEngineOrProviderKeyName , AnyProviderKeyUri ) ) ;
@@ -146,6 +160,63 @@ public static void Provider_NonExistingKey()
146160 Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenKeyFromProvider ( Tpm2ProviderName , NonExistingEngineOrProviderKeyName ) ) ;
147161 }
148162
163+ [ ConditionalFact ( nameof ( ProvidersSupported ) ) ]
164+ public static void Provider_Default_RSASignAndDecrypt ( )
165+ {
166+ using RSA originalKey = RSA . Create ( ) ;
167+ string pem = originalKey . ExportRSAPrivateKeyPem ( ) ;
168+
169+ using TempFileHolder pemFile = new TempFileHolder ( Encoding . UTF8 . GetBytes ( pem ) ) ;
170+ Uri fileUri = new Uri ( pemFile . FilePath ) ;
171+ string keyUri = fileUri . AbsoluteUri ;
172+ using SafeEvpPKeyHandle priKeyHandle = SafeEvpPKeyHandle . OpenKeyFromProvider ( "default" , keyUri ) ;
173+ using RSA rsaPri = new RSAOpenSsl ( priKeyHandle ) ;
174+ byte [ ] data = new byte [ ] { 1 , 2 , 3 , 1 , 1 , 2 , 3 } ;
175+ byte [ ] signature = rsaPri . SignData ( data , HashAlgorithmName . SHA256 , RSASignaturePadding . Pss ) ;
176+ Assert . True ( originalKey . VerifyData ( data , signature , HashAlgorithmName . SHA256 , RSASignaturePadding . Pss ) , "signature does not verify with the right key" ) ;
177+
178+ byte [ ] encrypted = originalKey . Encrypt ( data , RSAEncryptionPadding . OaepSHA256 ) ;
179+ byte [ ] decrypted = rsaPri . Decrypt ( encrypted , RSAEncryptionPadding . OaepSHA256 ) ;
180+ Assert . Equal ( data , decrypted ) ;
181+ }
182+
183+ [ ConditionalFact ( nameof ( ProvidersSupported ) ) ]
184+ public static void Provider_Default_ECDsaSignAndVerify ( )
185+ {
186+ using ECDsa originalKey = ECDsa . Create ( ) ;
187+ string pem = originalKey . ExportECPrivateKeyPem ( ) ;
188+
189+ using TempFileHolder pemFile = new TempFileHolder ( Encoding . UTF8 . GetBytes ( pem ) ) ;
190+ Uri fileUri = new Uri ( pemFile . FilePath ) ;
191+ string keyUri = fileUri . AbsoluteUri ;
192+ using SafeEvpPKeyHandle priKeyHandle = SafeEvpPKeyHandle . OpenKeyFromProvider ( "default" , keyUri ) ;
193+ using ECDsa ecdsaPri = new ECDsaOpenSsl ( priKeyHandle ) ;
194+ byte [ ] data = new byte [ ] { 1 , 2 , 3 , 1 , 1 , 2 , 3 } ;
195+ byte [ ] signature = ecdsaPri . SignData ( data , HashAlgorithmName . SHA256 ) ;
196+ Assert . True ( originalKey . VerifyData ( data , signature , HashAlgorithmName . SHA256 ) , "signature does not verify with the right key" ) ;
197+ }
198+
199+ [ ConditionalFact ( nameof ( ProvidersSupported ) ) ]
200+ public static void Provider_Default_ECDHKeyExchange ( )
201+ {
202+ using ECDiffieHellman originalAliceKey = ECDiffieHellman . Create ( ) ;
203+ string pem = originalAliceKey . ExportECPrivateKeyPem ( ) ;
204+
205+ using TempFileHolder pemFile = new TempFileHolder ( Encoding . UTF8 . GetBytes ( pem ) ) ;
206+ Uri fileUri = new Uri ( pemFile . FilePath ) ;
207+ string keyUri = fileUri . AbsoluteUri ;
208+ using SafeEvpPKeyHandle priKeyHandle = SafeEvpPKeyHandle . OpenKeyFromProvider ( "default" , keyUri ) ;
209+ using ECDiffieHellman alicePri = new ECDiffieHellmanOpenSsl ( priKeyHandle ) ;
210+ using ECDiffieHellman bobPri = ECDiffieHellman . Create ( alicePri . ExportParameters ( false ) . Curve ) ;
211+
212+ byte [ ] sharedSecret1 = originalAliceKey . DeriveRawSecretAgreement ( bobPri . PublicKey ) ;
213+ byte [ ] sharedSecret2 = alicePri . DeriveRawSecretAgreement ( bobPri . PublicKey ) ;
214+ byte [ ] sharedSecret3 = bobPri . DeriveRawSecretAgreement ( alicePri . PublicKey ) ;
215+
216+ Assert . Equal ( sharedSecret1 , sharedSecret2 ) ;
217+ Assert . Equal ( sharedSecret1 , sharedSecret3 ) ;
218+ }
219+
149220 [ ConditionalFact ( nameof ( ShouldRunEngineTests ) ) ]
150221 public static void Engine_OpenExistingPrivateKey ( )
151222 {
0 commit comments