@@ -7,19 +7,11 @@ namespace DotNet.Testcontainers.Builders
7
7
using Docker . DotNet . X509 ;
8
8
using DotNet . Testcontainers . Configurations ;
9
9
using JetBrains . Annotations ;
10
- using Org . BouncyCastle . Crypto ;
11
- using Org . BouncyCastle . Crypto . Parameters ;
12
- using Org . BouncyCastle . OpenSsl ;
13
- using Org . BouncyCastle . Pkcs ;
14
- using Org . BouncyCastle . Security ;
15
- using Org . BouncyCastle . X509 ;
16
10
17
11
/// <inheritdoc cref="IDockerRegistryAuthenticationProvider" />
18
12
[ PublicAPI ]
19
13
internal sealed class MTlsEndpointAuthenticationProvider : TlsEndpointAuthenticationProvider
20
14
{
21
- private static readonly X509CertificateParser CertificateParser = new X509CertificateParser ( ) ;
22
-
23
15
/// <summary>
24
16
/// Initializes a new instance of the <see cref="MTlsEndpointAuthenticationProvider" /> class.
25
17
/// </summary>
@@ -57,57 +49,15 @@ protected override X509Certificate2 GetClientCertificate()
57
49
{
58
50
var clientCertificateFilePath = Path . Combine ( CertificatesDirectoryPath , ClientCertificateFileName ) ;
59
51
var clientCertificateKeyFilePath = Path . Combine ( CertificatesDirectoryPath , ClientCertificateKeyFileName ) ;
60
- return CreateFromPemFile ( clientCertificateFilePath , clientCertificateKeyFilePath ) ;
61
- }
62
-
63
- private static X509Certificate2 CreateFromPemFile ( string certPemFilePath , string keyPemFilePath )
64
- {
65
- if ( ! File . Exists ( certPemFilePath ) )
66
- {
67
- throw new FileNotFoundException ( certPemFilePath ) ;
68
- }
69
-
70
- if ( ! File . Exists ( keyPemFilePath ) )
71
- {
72
- throw new FileNotFoundException ( keyPemFilePath ) ;
73
- }
74
-
75
- using ( var keyPairStream = new StreamReader ( keyPemFilePath ) )
76
- {
77
- var store = new Pkcs12StoreBuilder ( ) . Build ( ) ;
78
-
79
- var certificate = CertificateParser . ReadCertificate ( File . ReadAllBytes ( certPemFilePath ) ) ;
80
-
81
- var password = Guid . NewGuid ( ) . ToString ( "D" ) ;
82
52
83
- var keyObject = new PemReader ( keyPairStream ) . ReadObject ( ) ;
84
-
85
- var certificateEntry = new X509CertificateEntry ( certificate ) ;
86
-
87
- var keyParameter = ResolveKeyParameter ( keyObject ) ;
88
-
89
- var keyEntry = new AsymmetricKeyEntry ( keyParameter ) ;
90
- store . SetKeyEntry ( certificate . SubjectDN + "_key" , keyEntry , new [ ] { certificateEntry } ) ;
91
-
92
- using ( var certificateStream = new MemoryStream ( ) )
93
- {
94
- store . Save ( certificateStream , password . ToCharArray ( ) , new SecureRandom ( ) ) ;
95
- return new X509Certificate2 ( Pkcs12Utilities . ConvertToDefiniteLength ( certificateStream . ToArray ( ) ) , password ) ;
96
- }
97
- }
98
- }
99
-
100
- private static AsymmetricKeyParameter ResolveKeyParameter ( object keyObject )
101
- {
102
- switch ( keyObject )
103
- {
104
- case AsymmetricCipherKeyPair ackp :
105
- return ackp . Private ;
106
- case RsaPrivateCrtKeyParameters rpckp :
107
- return rpckp ;
108
- default :
109
- throw new ArgumentOutOfRangeException ( nameof ( keyObject ) , $ "Unsupported asymmetric key entry encountered while trying to resolve key from input object '{ keyObject . GetType ( ) } '.") ;
110
- }
53
+ #if NETSTANDARD
54
+ return Polyfills . X509Certificate2 . CreateFromPemFile ( clientCertificateFilePath , clientCertificateKeyFilePath ) ;
55
+ #else
56
+ var certificate = X509Certificate2 . CreateFromPemFile ( clientCertificateFilePath , clientCertificateKeyFilePath ) ;
57
+ // The certificate must be exported to PFX on Windows to avoid "No credentials are available in the security package":
58
+ // https://stackoverflow.com/questions/72096812/loading-x509certificate2-from-pem-file-results-in-no-credentials-are-available/72101855#72101855.
59
+ return OperatingSystem . IsWindows ( ) ? new X509Certificate2 ( certificate . Export ( X509ContentType . Pfx ) ) : certificate ;
60
+ #endif
111
61
}
112
62
}
113
63
}
0 commit comments