@@ -90,6 +90,57 @@ public static void DisplayCertificate(params X509Certificate2[] certificates)
9090 AnsiConsole . WriteLine ( ) ;
9191 }
9292
93+ /// <summary>
94+ /// Imports a PFX file and returns a collection of certificates.
95+ /// </summary>
96+ /// <param name="filePath">
97+ /// The path to the PFX file.
98+ /// </param>
99+ /// <param name="password">
100+ /// The password for the PFX file. If null, no password is used.
101+ /// </param>
102+ /// <returns>
103+ /// A collection of X509Certificate2 objects representing the certificates in the PFX file.
104+ /// </returns>
105+ public static X509Certificate2Collection ImportPFX ( string filePath , string ? password = null )
106+ {
107+ byte [ ] buffer ;
108+
109+ using ( FileStream fs = new FileStream ( filePath , FileMode . Open , FileAccess . Read ) )
110+ {
111+ buffer = new byte [ fs . Length ] ;
112+ fs . Read ( buffer , 0 , buffer . Length ) ;
113+ }
114+
115+ return ImportPFX ( buffer , password ) ;
116+ }
117+
118+ /// <summary>
119+ /// Imports a PFX file from a byte array and returns a collection of certificates.
120+ /// </summary>
121+ /// <param name="data">
122+ /// The byte array containing the PFX data.
123+ /// </param>
124+ /// <param name="password">
125+ /// The password for the PFX file. If null, no password is used.
126+ /// </param>
127+ /// <returns>
128+ /// A collection of X509Certificate2 objects representing the certificates in the PFX data.
129+ /// </returns>
130+ public static X509Certificate2Collection ImportPFX ( byte [ ] data , string ? password = null )
131+ {
132+ X509Certificate2Collection collection = new X509Certificate2Collection ( ) ;
133+
134+ #if NET9_0_OR_GREATER
135+ collection . AddRange ( X509CertificateLoader . LoadPkcs12Collection ( data , password , X509KeyStorageFlags . EphemeralKeySet | X509KeyStorageFlags . Exportable ) ) ;
136+ #else
137+ collection . Import ( data , password , X509KeyStorageFlags . EphemeralKeySet | X509KeyStorageFlags . Exportable ) ;
138+ #endif
139+
140+ return collection ;
141+ }
142+
143+
93144 /// <summary>
94145 /// Prompts the user for certificate subject information and generates a standardized subject name.
95146 /// </summary>
@@ -187,12 +238,7 @@ private static X509Certificate2Collection LoadCertificatesFromPfx(string pfxFile
187238
188239 string pfpass = ! string . IsNullOrEmpty ( pfxFilePassword ) ? pfxFilePassword : ! pfxNoPasswordPrompt ? Utilities . SecurePrompt ( "Enter PFX File password (if needed): " ) : "" ;
189240
190- #if NET9_0_OR_GREATER
191- X509Certificate2Collection tempCollection = X509CertificateLoader . LoadPkcs12CollectionFromFile ( pfxFilePath , pfpass , X509KeyStorageFlags . EphemeralKeySet ) ;
192- #else
193- X509Certificate2Collection tempCollection = [ ] ;
194- tempCollection . Import ( pfxFilePath , pfpass , X509KeyStorageFlags . EphemeralKeySet ) ;
195- #endif
241+ X509Certificate2Collection tempCollection = ImportPFX ( pfxFilePath , pfpass ) ;
196242
197243 IEnumerable < X509Certificate2 > cond = tempCollection . Where ( x => x . HasPrivateKey ) ;
198244 if ( cond . Any ( ) )
@@ -236,11 +282,7 @@ public static X509Certificate2 CreateSelfSignedCACertificate(string subjectName)
236282 DateTimeOffset . UtcNow . AddYears ( 100 ) ) ;
237283
238284 // Export and re-import to mark the key as exportable (if needed for further signing).
239- #if NET9_0_OR_GREATER
240- var cert = X509CertificateLoader . LoadPkcs12 ( rootCert . Export ( X509ContentType . Pfx ) , null , X509KeyStorageFlags . EphemeralKeySet | X509KeyStorageFlags . Exportable ) ;
241- #else
242- var cert = new X509Certificate2 ( rootCert . Export ( X509ContentType . Pfx ) , "" , X509KeyStorageFlags . EphemeralKeySet | X509KeyStorageFlags . Exportable ) ;
243- #endif
285+ var cert = ImportPFX ( rootCert . Export ( X509ContentType . Pfx ) ) . Single ( ) ;
244286
245287 return cert ;
246288 }
0 commit comments