4
4
using System . Collections . Generic ;
5
5
using System . IO ;
6
6
using System . Runtime . InteropServices ;
7
+ using System . Security . Cryptography . Dsa . Tests ;
8
+ using System . Security . Cryptography . X509Certificates . Tests . CertificateCreation ;
7
9
using System . Threading ;
8
10
using Microsoft . DotNet . XUnitExtensions ;
9
11
using Test . Cryptography ;
@@ -25,6 +27,155 @@ public CertTests(ITestOutputHelper output)
25
27
_log = output ;
26
28
}
27
29
30
+ [ Fact ]
31
+ public static void PublicPrivateKey_IndependentLifetimes_ECDsa ( )
32
+ {
33
+ X509Certificate2 loaded ;
34
+
35
+ using ( ECDsa ca = ECDsa . Create ( ECCurve . NamedCurves . nistP256 ) )
36
+ {
37
+ CertificateRequest req = new ( "CN=potatos" , ca , HashAlgorithmName . SHA256 ) ;
38
+
39
+ using ( X509Certificate2 cert = req . CreateSelfSigned ( DateTimeOffset . Now , DateTimeOffset . Now . AddDays ( 3 ) ) )
40
+ {
41
+ loaded = new X509Certificate2 ( cert . Export ( X509ContentType . Pkcs12 , "carrots" ) , "carrots" ) ;
42
+ }
43
+ }
44
+
45
+ using ( ECDsa verifyKey = loaded . GetECDsaPublicKey ( ) )
46
+ {
47
+ byte [ ] signature ;
48
+ byte [ ] data = RandomNumberGenerator . GetBytes ( 32 ) ;
49
+
50
+ using ( ECDsa signingKey = loaded . GetECDsaPrivateKey ( ) )
51
+ {
52
+ loaded . Dispose ( ) ;
53
+ signature = signingKey . SignHash ( data ) ;
54
+ }
55
+
56
+ Assert . True ( verifyKey . VerifyHash ( data , signature ) , nameof ( verifyKey . VerifyHash ) ) ;
57
+ }
58
+ }
59
+
60
+ [ Fact ]
61
+ public static void PublicPrivateKey_IndependentLifetimes_ECDiffieHellman ( )
62
+ {
63
+ X509Certificate2 loaded ;
64
+
65
+ using ( ECDsa ca = ECDsa . Create ( ECCurve . NamedCurves . nistP256 ) )
66
+ using ( ECDiffieHellman ecdh = ECDiffieHellman . Create ( ECCurve . NamedCurves . nistP256 ) )
67
+ {
68
+ CertificateRequest issuerRequest = new CertificateRequest (
69
+ new X500DistinguishedName ( "CN=root" ) ,
70
+ ca ,
71
+ HashAlgorithmName . SHA256 ) ;
72
+
73
+ issuerRequest . CertificateExtensions . Add (
74
+ new X509BasicConstraintsExtension ( true , false , 0 , true ) ) ;
75
+
76
+ CertificateRequest request = new CertificateRequest (
77
+ new X500DistinguishedName ( "CN=potato" ) ,
78
+ new PublicKey ( ecdh ) ,
79
+ HashAlgorithmName . SHA256 ) ;
80
+
81
+ request . CertificateExtensions . Add (
82
+ new X509BasicConstraintsExtension ( false , false , 0 , true ) ) ;
83
+ request . CertificateExtensions . Add (
84
+ new X509KeyUsageExtension ( X509KeyUsageFlags . KeyAgreement , true ) ) ;
85
+
86
+ DateTimeOffset notBefore = DateTimeOffset . UtcNow ;
87
+ DateTimeOffset notAfter = notBefore . AddDays ( 30 ) ;
88
+ byte [ ] serial = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ;
89
+
90
+ using ( X509Certificate2 issuer = issuerRequest . CreateSelfSigned ( notBefore , notAfter ) )
91
+ using ( X509Certificate2 cert = request . Create ( issuer , notBefore , notAfter , serial ) )
92
+ using ( X509Certificate2 certWithKey = cert . CopyWithPrivateKey ( ecdh ) )
93
+ {
94
+ loaded = new X509Certificate2 ( certWithKey . Export ( X509ContentType . Pkcs12 , "carrots" ) , "carrots" ) ; ;
95
+ }
96
+ }
97
+
98
+ using ( ECDiffieHellman partyB = ECDiffieHellman . Create ( ECCurve . NamedCurves . nistP256 ) )
99
+ using ( ECDiffieHellman partyAPrivateKey = loaded . GetECDiffieHellmanPrivateKey ( ) )
100
+ using ( ECDiffieHellman partyAPublicKey = loaded . GetECDiffieHellmanPublicKey ( ) )
101
+ {
102
+ loaded . Dispose ( ) ;
103
+ byte [ ] derivedB = partyB . DeriveKeyFromHash ( partyAPublicKey . PublicKey , HashAlgorithmName . SHA256 , null , null ) ;
104
+ byte [ ] derivedA = partyAPrivateKey . DeriveKeyFromHash ( partyB . PublicKey , HashAlgorithmName . SHA256 , null , null ) ;
105
+ Assert . Equal ( derivedB , derivedA ) ;
106
+ }
107
+ }
108
+
109
+ [ Fact ]
110
+ public static void PublicPrivateKey_IndependentLifetimes_RSA ( )
111
+ {
112
+ X509Certificate2 loaded ;
113
+
114
+ using ( RSA ca = RSA . Create ( 2048 ) )
115
+ {
116
+ CertificateRequest req = new ( "CN=potatos" , ca , HashAlgorithmName . SHA256 , RSASignaturePadding . Pkcs1 ) ;
117
+
118
+ using ( X509Certificate2 cert = req . CreateSelfSigned ( DateTimeOffset . Now , DateTimeOffset . Now . AddDays ( 3 ) ) )
119
+ {
120
+ loaded = new X509Certificate2 ( cert . Export ( X509ContentType . Pkcs12 , "carrots" ) , "carrots" ) ;
121
+ }
122
+ }
123
+
124
+ using ( RSA verifyKey = loaded . GetRSAPublicKey ( ) )
125
+ {
126
+ byte [ ] signature ;
127
+ byte [ ] data = RandomNumberGenerator . GetBytes ( 32 ) ;
128
+
129
+ using ( RSA signingKey = loaded . GetRSAPrivateKey ( ) )
130
+ {
131
+ loaded . Dispose ( ) ;
132
+ signature = signingKey . SignHash ( data , HashAlgorithmName . SHA256 , RSASignaturePadding . Pkcs1 ) ;
133
+ }
134
+
135
+ Assert . True ( verifyKey . VerifyHash ( data , signature , HashAlgorithmName . SHA256 , RSASignaturePadding . Pkcs1 ) , nameof ( verifyKey . VerifyHash ) ) ;
136
+ }
137
+ }
138
+
139
+ [ Fact ]
140
+ [ SkipOnPlatform ( PlatformSupport . MobileAppleCrypto , "DSA is not available" ) ]
141
+ public static void PublicPrivateKey_IndependentLifetimes_DSA ( )
142
+ {
143
+ X509Certificate2 loaded ;
144
+
145
+ using ( DSA ca = DSA . Create ( ) )
146
+ {
147
+ ca . ImportParameters ( DSATestData . GetDSA1024Params ( ) ) ;
148
+ DSAX509SignatureGenerator gen = new DSAX509SignatureGenerator ( ca ) ;
149
+ X500DistinguishedName dn = new X500DistinguishedName ( "CN=potatos" ) ;
150
+
151
+ CertificateRequest req = new CertificateRequest (
152
+ dn ,
153
+ gen . PublicKey ,
154
+ HashAlgorithmName . SHA1 ) ;
155
+
156
+ using ( X509Certificate2 cert = req . Create ( dn , gen , DateTimeOffset . Now , DateTimeOffset . Now . AddDays ( 3 ) , new byte [ ] { 1 , 2 , 3 } ) )
157
+ using ( X509Certificate2 certWithKey = cert . CopyWithPrivateKey ( ca ) )
158
+ {
159
+
160
+ loaded = new X509Certificate2 ( certWithKey . Export ( X509ContentType . Pkcs12 , "carrots" ) , "carrots" ) ;
161
+ }
162
+ }
163
+
164
+ using ( DSA verifyKey = loaded . GetDSAPublicKey ( ) )
165
+ {
166
+ byte [ ] signature ;
167
+ byte [ ] data = RandomNumberGenerator . GetBytes ( 20 ) ;
168
+
169
+ using ( DSA signingKey = loaded . GetDSAPrivateKey ( ) )
170
+ {
171
+ loaded . Dispose ( ) ;
172
+ signature = signingKey . CreateSignature ( data ) ;
173
+ }
174
+
175
+ Assert . True ( verifyKey . VerifySignature ( data , signature ) , nameof ( verifyKey . VerifySignature ) ) ;
176
+ }
177
+ }
178
+
28
179
[ Fact ]
29
180
public static void RaceDisposeAndKeyAccess ( )
30
181
{
0 commit comments