44using  System . Collections . Generic ; 
55using  System . IO ; 
66using  System . Runtime . InteropServices ; 
7+ using  System . Security . Cryptography . Dsa . Tests ; 
8+ using  System . Security . Cryptography . X509Certificates . Tests . CertificateCreation ; 
79using  System . Threading ; 
810using  Microsoft . DotNet . XUnitExtensions ; 
911using  Test . Cryptography ; 
@@ -25,6 +27,155 @@ public CertTests(ITestOutputHelper output)
2527            _log  =  output ; 
2628        } 
2729
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+ 
28179        [ Fact ] 
29180        public  static   void  RaceDisposeAndKeyAccess ( ) 
30181        { 
0 commit comments