2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
4
using System . Linq ;
5
+ using System . Text ;
5
6
using Test . Cryptography ;
6
7
using Xunit ;
8
+ using TempFileHolder = System . Security . Cryptography . X509Certificates . Tests . TempFileHolder ;
7
9
8
10
namespace System . Security . Cryptography . Tests
9
11
{
@@ -43,10 +45,13 @@ public class OpenSslNamedKeysTests
43
45
private static string TpmRsaDecryptKeyHandleUri { get ; } = GetHandleKeyUri ( TpmRsaDecryptKeyHandle ) ;
44
46
45
47
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 ) ;
50
55
public static bool ShouldRunAnyProviderTests => ShouldRunProviderEcDsaTests || ShouldRunProviderEcDhTests || ShouldRunProviderRsaSignTests || ShouldRunProviderRsaDecryptTests ;
51
56
52
57
public static bool ShouldRunTpmTssTests => ShouldRunEngineTests && ! string . IsNullOrEmpty ( TpmEcDsaKeyHandle ) ;
@@ -86,11 +91,30 @@ private static string GetHandleKeyUri(string handle)
86
91
"B27434FA544BDAC679E1E16581D0E90203010001" ) . HexToByteArray ( ) ;
87
92
88
93
[ ConditionalFact ( typeof ( PlatformDetection ) , nameof ( PlatformDetection . OpenSslNotPresentOnSystem ) ) ]
89
- public static void NotSupported ( )
94
+ public static void EngineNotSupported_ThrowsPlatformNotSupported ( )
90
95
{
91
96
Assert . Throws < PlatformNotSupportedException > ( ( ) => SafeEvpPKeyHandle . OpenPublicKeyFromEngine ( TestEngineName , TestEngineKeyId ) ) ;
92
97
Assert . Throws < PlatformNotSupportedException > ( ( ) => SafeEvpPKeyHandle . OpenPrivateKeyFromEngine ( TestEngineName , TestEngineKeyId ) ) ;
93
- Assert . Throws < PlatformNotSupportedException > ( ( ) => SafeEvpPKeyHandle . OpenKeyFromProvider ( Tpm2ProviderName , AnyProviderKeyUri ) ) ;
98
+ }
99
+
100
+ [ ConditionalFact ( nameof ( ProvidersNotSupported ) ) ]
101
+ public static void ProvidersNotSupported_ThrowsPlatformNotSupported ( )
102
+ {
103
+ try
104
+ {
105
+ using SafeEvpPKeyHandle key = SafeEvpPKeyHandle . OpenKeyFromProvider ( "default" , NonExistingEngineOrProviderKeyName ) ;
106
+ Assert . Fail ( "We expected an exception to be thrown" ) ;
107
+ }
108
+ catch ( PlatformNotSupportedException )
109
+ {
110
+ // Expected
111
+ }
112
+ catch ( CryptographicException ) when ( PlatformDetection . IsApplePlatform )
113
+ {
114
+ // Our tests detect providers using PlatformDetection.IsOpenSsl3 which is always false for Apple platforms.
115
+ // Product on the other hand does feature detection and that might end up working
116
+ // in which case we should still throw any CryptographicException because the keyUri does not exist.
117
+ }
94
118
}
95
119
96
120
[ ConditionalFact ( typeof ( PlatformDetection ) , nameof ( PlatformDetection . OpenSslPresentOnSystem ) ) ]
@@ -111,10 +135,14 @@ public static void EmptyNameThroughNullCharacter()
111
135
{
112
136
Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenPrivateKeyFromEngine ( "\0 " , "foo" ) ) ;
113
137
Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenPublicKeyFromEngine ( "\0 " , "foo" ) ) ;
114
- Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenKeyFromProvider ( "\0 " , "foo" ) ) ;
138
+
139
+ if ( ProvidersSupported )
140
+ {
141
+ Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenKeyFromProvider ( "\0 " , "foo" ) ) ;
142
+ }
115
143
}
116
144
117
- [ ConditionalFact ( typeof ( PlatformDetection ) , nameof ( PlatformDetection . OpenSslPresentOnSystem ) ) ]
145
+ [ ConditionalFact ( nameof ( ProvidersSupported ) ) ]
118
146
public static void EmptyUriThroughNullCharacter ( )
119
147
{
120
148
Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenKeyFromProvider ( "default" , "\0 " ) ) ;
@@ -127,7 +155,7 @@ public static void Engine_NonExisting()
127
155
Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenPublicKeyFromEngine ( NonExistingEngineOrProviderKeyName , TestEngineKeyId ) ) ;
128
156
}
129
157
130
- [ ConditionalFact ( typeof ( PlatformDetection ) , nameof ( PlatformDetection . OpenSslPresentOnSystem ) ) ]
158
+ [ ConditionalFact ( nameof ( ProvidersSupported ) ) ]
131
159
public static void Provider_NonExisting ( )
132
160
{
133
161
Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenKeyFromProvider ( NonExistingEngineOrProviderKeyName , AnyProviderKeyUri ) ) ;
@@ -146,6 +174,63 @@ public static void Provider_NonExistingKey()
146
174
Assert . ThrowsAny < CryptographicException > ( ( ) => SafeEvpPKeyHandle . OpenKeyFromProvider ( Tpm2ProviderName , NonExistingEngineOrProviderKeyName ) ) ;
147
175
}
148
176
177
+ [ ConditionalFact ( nameof ( ProvidersSupported ) ) ]
178
+ public static void Provider_Default_RSASignAndDecrypt ( )
179
+ {
180
+ using RSA originalKey = RSA . Create ( ) ;
181
+ string pem = originalKey . ExportRSAPrivateKeyPem ( ) ;
182
+
183
+ using TempFileHolder pemFile = new TempFileHolder ( Encoding . UTF8 . GetBytes ( pem ) ) ;
184
+ Uri fileUri = new Uri ( pemFile . FilePath ) ;
185
+ string keyUri = fileUri . AbsoluteUri ;
186
+ using SafeEvpPKeyHandle priKeyHandle = SafeEvpPKeyHandle . OpenKeyFromProvider ( "default" , keyUri ) ;
187
+ using RSA rsaPri = new RSAOpenSsl ( priKeyHandle ) ;
188
+ byte [ ] data = new byte [ ] { 1 , 2 , 3 , 1 , 1 , 2 , 3 } ;
189
+ byte [ ] signature = rsaPri . SignData ( data , HashAlgorithmName . SHA256 , RSASignaturePadding . Pss ) ;
190
+ Assert . True ( originalKey . VerifyData ( data , signature , HashAlgorithmName . SHA256 , RSASignaturePadding . Pss ) , "signature does not verify with the right key" ) ;
191
+
192
+ byte [ ] encrypted = originalKey . Encrypt ( data , RSAEncryptionPadding . OaepSHA256 ) ;
193
+ byte [ ] decrypted = rsaPri . Decrypt ( encrypted , RSAEncryptionPadding . OaepSHA256 ) ;
194
+ Assert . Equal ( data , decrypted ) ;
195
+ }
196
+
197
+ [ ConditionalFact ( nameof ( ProvidersSupported ) ) ]
198
+ public static void Provider_Default_ECDsaSignAndVerify ( )
199
+ {
200
+ using ECDsa originalKey = ECDsa . Create ( ) ;
201
+ string pem = originalKey . ExportECPrivateKeyPem ( ) ;
202
+
203
+ using TempFileHolder pemFile = new TempFileHolder ( Encoding . UTF8 . GetBytes ( pem ) ) ;
204
+ Uri fileUri = new Uri ( pemFile . FilePath ) ;
205
+ string keyUri = fileUri . AbsoluteUri ;
206
+ using SafeEvpPKeyHandle priKeyHandle = SafeEvpPKeyHandle . OpenKeyFromProvider ( "default" , keyUri ) ;
207
+ using ECDsa ecdsaPri = new ECDsaOpenSsl ( priKeyHandle ) ;
208
+ byte [ ] data = new byte [ ] { 1 , 2 , 3 , 1 , 1 , 2 , 3 } ;
209
+ byte [ ] signature = ecdsaPri . SignData ( data , HashAlgorithmName . SHA256 ) ;
210
+ Assert . True ( originalKey . VerifyData ( data , signature , HashAlgorithmName . SHA256 ) , "signature does not verify with the right key" ) ;
211
+ }
212
+
213
+ [ ConditionalFact ( nameof ( ProvidersSupported ) ) ]
214
+ public static void Provider_Default_ECDHKeyExchange ( )
215
+ {
216
+ using ECDiffieHellman originalAliceKey = ECDiffieHellman . Create ( ) ;
217
+ string pem = originalAliceKey . ExportECPrivateKeyPem ( ) ;
218
+
219
+ using TempFileHolder pemFile = new TempFileHolder ( Encoding . UTF8 . GetBytes ( pem ) ) ;
220
+ Uri fileUri = new Uri ( pemFile . FilePath ) ;
221
+ string keyUri = fileUri . AbsoluteUri ;
222
+ using SafeEvpPKeyHandle priKeyHandle = SafeEvpPKeyHandle . OpenKeyFromProvider ( "default" , keyUri ) ;
223
+ using ECDiffieHellman alicePri = new ECDiffieHellmanOpenSsl ( priKeyHandle ) ;
224
+ using ECDiffieHellman bobPri = ECDiffieHellman . Create ( alicePri . ExportParameters ( false ) . Curve ) ;
225
+
226
+ byte [ ] sharedSecret1 = originalAliceKey . DeriveRawSecretAgreement ( bobPri . PublicKey ) ;
227
+ byte [ ] sharedSecret2 = alicePri . DeriveRawSecretAgreement ( bobPri . PublicKey ) ;
228
+ byte [ ] sharedSecret3 = bobPri . DeriveRawSecretAgreement ( alicePri . PublicKey ) ;
229
+
230
+ Assert . Equal ( sharedSecret1 , sharedSecret2 ) ;
231
+ Assert . Equal ( sharedSecret1 , sharedSecret3 ) ;
232
+ }
233
+
149
234
[ ConditionalFact ( nameof ( ShouldRunEngineTests ) ) ]
150
235
public static void Engine_OpenExistingPrivateKey ( )
151
236
{
0 commit comments