Skip to content

Commit 72891bf

Browse files
committed
Add unified pfx import method
1 parent 649b76e commit 72891bf

File tree

2 files changed

+57
-24
lines changed

2 files changed

+57
-24
lines changed

src/EasySign.CommandLine/CertificateUtilities.cs

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

src/EasySign.CommandLine/CommandProvider.cs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -221,11 +221,7 @@ public Command Sign
221221
{
222222
certs = [];
223223
var certFilePath = Path.Combine(AppDirectory, "certs", Configuration.IssuedCertificates[selectedCert]);
224-
#if NET9_0_OR_GREATER
225-
certs.AddRange(X509CertificateLoader.LoadPkcs12CollectionFromFile(certFilePath, null, X509KeyStorageFlags.EphemeralKeySet | X509KeyStorageFlags.Exportable));
226-
#else
227-
certs.Import(certFilePath, null, X509KeyStorageFlags.EphemeralKeySet | X509KeyStorageFlags.Exportable);
228-
#endif
224+
certs.AddRange(CertificateUtilities.ImportPFX(certFilePath));
229225
}
230226
}
231227
else
@@ -421,14 +417,9 @@ public virtual void RunSelfSign(string? commonName, string? email, string? organ
421417

422418
if (File.Exists(rootCAPath))
423419
{
424-
#if NET9_0_OR_GREATER
425-
X509Certificate2Collection collection = X509CertificateLoader.LoadPkcs12CollectionFromFile(rootCAPath, null, X509KeyStorageFlags.EphemeralKeySet);
426-
#else
427-
X509Certificate2Collection collection = new();
428-
collection.Import(rootCAPath, null, X509KeyStorageFlags.EphemeralKeySet);
429-
#endif
430-
431-
return collection.First();
420+
X509Certificate2Collection collection = CertificateUtilities.ImportPFX(rootCAPath);
421+
422+
return collection.Single();
432423
}
433424

434425
return null;

0 commit comments

Comments
 (0)