diff --git a/src/KubernetesClient.Classic/CertUtils.cs b/src/KubernetesClient.Classic/CertUtils.cs
new file mode 100644
index 000000000..60805cd93
--- /dev/null
+++ b/src/KubernetesClient.Classic/CertUtils.cs
@@ -0,0 +1,157 @@
+using k8s.Exceptions;
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.OpenSsl;
+using Org.BouncyCastle.Pkcs;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.X509;
+using System.IO;
+using System.Security.Cryptography.X509Certificates;
+
+namespace k8s
+{
+ internal static class CertUtils
+ {
+ ///
+ /// Load pem encoded cert file
+ ///
+ /// Path to pem encoded cert file
+ /// List of x509 instances.
+ public static X509Certificate2Collection LoadPemFileCert(string file)
+ {
+ var certCollection = new X509Certificate2Collection();
+ using (var stream = FileSystem.Current.OpenRead(file))
+ {
+ var certs = new X509CertificateParser().ReadCertificates(stream);
+
+ // Convert BouncyCastle X509Certificates to the .NET cryptography implementation and add
+ // it to the certificate collection
+ //
+ foreach (Org.BouncyCastle.X509.X509Certificate cert in certs)
+ {
+ // This null password is to change the constructor to fix this KB:
+ // https://support.microsoft.com/en-us/topic/kb5025823-change-in-how-net-applications-import-x-509-certificates-bf81c936-af2b-446e-9f7a-016f4713b46b
+ string nullPassword = null;
+ certCollection.Add(new X509Certificate2(cert.GetEncoded(), nullPassword));
+ }
+ }
+
+ return certCollection;
+ }
+
+ ///
+ /// Generates pfx from client configuration
+ ///
+ /// Kubernetes Client Configuration
+ /// Generated Pfx Path
+ public static X509Certificate2 GeneratePfx(KubernetesClientConfiguration config)
+ {
+ if (config == null)
+ {
+ throw new ArgumentNullException(nameof(config));
+ }
+
+ byte[] keyData = null;
+ byte[] certData = null;
+
+ if (!string.IsNullOrWhiteSpace(config.ClientCertificateKeyData))
+ {
+ keyData = Convert.FromBase64String(config.ClientCertificateKeyData);
+ }
+
+ if (!string.IsNullOrWhiteSpace(config.ClientKeyFilePath))
+ {
+ keyData = File.ReadAllBytes(config.ClientKeyFilePath);
+ }
+
+ if (keyData == null)
+ {
+ throw new KubeConfigException("keyData is empty");
+ }
+
+ if (!string.IsNullOrWhiteSpace(config.ClientCertificateData))
+ {
+ certData = Convert.FromBase64String(config.ClientCertificateData);
+ }
+
+ if (!string.IsNullOrWhiteSpace(config.ClientCertificateFilePath))
+ {
+ certData = File.ReadAllBytes(config.ClientCertificateFilePath);
+ }
+
+ if (certData == null)
+ {
+ throw new KubeConfigException("certData is empty");
+ }
+
+ var cert = new X509CertificateParser().ReadCertificate(new MemoryStream(certData));
+ // key usage is a bit string, zero-th bit is 'digitalSignature'
+ // See https://www.alvestrand.no/objectid/2.5.29.15.html for more details.
+ if (cert != null && cert.GetKeyUsage() != null && !cert.GetKeyUsage()[0])
+ {
+ throw new Exception(
+ "Client certificates must be marked for digital signing. " +
+ "See https://github.com/kubernetes-client/csharp/issues/319");
+ }
+
+ object obj;
+ using (var reader = new StreamReader(new MemoryStream(keyData)))
+ {
+ obj = new PemReader(reader).ReadObject();
+ if (obj is AsymmetricCipherKeyPair key)
+ {
+ var cipherKey = key;
+ obj = cipherKey.Private;
+ }
+ }
+
+ var keyParams = (AsymmetricKeyParameter)obj;
+
+ var store = new Pkcs12StoreBuilder()
+ .SetKeyAlgorithm(NistObjectIdentifiers.IdAes128Cbc, PkcsObjectIdentifiers.IdHmacWithSha1)
+ .Build();
+ store.SetKeyEntry("K8SKEY", new AsymmetricKeyEntry(keyParams), new[] { new X509CertificateEntry(cert) });
+
+ using var pkcs = new MemoryStream();
+
+ store.Save(pkcs, new char[0], new SecureRandom());
+
+ // This null password is to change the constructor to fix this KB:
+ // https://support.microsoft.com/en-us/topic/kb5025823-change-in-how-net-applications-import-x-509-certificates-bf81c936-af2b-446e-9f7a-016f4713b46b
+ string nullPassword = null;
+
+ if (config.ClientCertificateKeyStoreFlags.HasValue)
+ {
+ return new X509Certificate2(pkcs.ToArray(), nullPassword, config.ClientCertificateKeyStoreFlags.Value);
+ }
+ else
+ {
+ return new X509Certificate2(pkcs.ToArray(), nullPassword);
+ }
+ }
+
+ ///
+ /// Retrieves Client Certificate PFX from configuration
+ ///
+ /// Kubernetes Client Configuration
+ /// Client certificate PFX
+ public static X509Certificate2 GetClientCert(KubernetesClientConfiguration config)
+ {
+ if (config == null)
+ {
+ throw new ArgumentNullException(nameof(config));
+ }
+
+ if ((!string.IsNullOrWhiteSpace(config.ClientCertificateData) ||
+ !string.IsNullOrWhiteSpace(config.ClientCertificateFilePath)) &&
+ (!string.IsNullOrWhiteSpace(config.ClientCertificateKeyData) ||
+ !string.IsNullOrWhiteSpace(config.ClientKeyFilePath)))
+ {
+ return GeneratePfx(config);
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/KubernetesClient.Classic/KubernetesClient.Classic.csproj b/src/KubernetesClient.Classic/KubernetesClient.Classic.csproj
index 7ea498c10..d6c21edfa 100644
--- a/src/KubernetesClient.Classic/KubernetesClient.Classic.csproj
+++ b/src/KubernetesClient.Classic/KubernetesClient.Classic.csproj
@@ -6,8 +6,8 @@
-
-
+
+
@@ -18,7 +18,6 @@
-
diff --git a/src/KubernetesClient/CertUtils.cs b/src/KubernetesClient/CertUtils.cs
index 347771417..04a8245e4 100644
--- a/src/KubernetesClient/CertUtils.cs
+++ b/src/KubernetesClient/CertUtils.cs
@@ -1,14 +1,6 @@
using k8s.Exceptions;
-#if !NET5_0_OR_GREATER
-using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.OpenSsl;
-using Org.BouncyCastle.Pkcs;
-using Org.BouncyCastle.Security;
-using Org.BouncyCastle.X509;
-#else
using System.Runtime.InteropServices;
using System.Text;
-#endif
using System.IO;
using System.Security.Cryptography.X509Certificates;
@@ -26,22 +18,7 @@ public static X509Certificate2Collection LoadPemFileCert(string file)
var certCollection = new X509Certificate2Collection();
using (var stream = FileSystem.Current.OpenRead(file))
{
-#if NET5_0_OR_GREATER
certCollection.ImportFromPem(new StreamReader(stream).ReadToEnd());
-#else
- var certs = new X509CertificateParser().ReadCertificates(stream);
-
- // Convert BouncyCastle X509Certificates to the .NET cryptography implementation and add
- // it to the certificate collection
- //
- foreach (Org.BouncyCastle.X509.X509Certificate cert in certs)
- {
- // This null password is to change the constructor to fix this KB:
- // https://support.microsoft.com/en-us/topic/kb5025823-change-in-how-net-applications-import-x-509-certificates-bf81c936-af2b-446e-9f7a-016f4713b46b
- string nullPassword = null;
- certCollection.Add(new X509Certificate2(cert.GetEncoded(), nullPassword));
- }
-#endif
}
return certCollection;
@@ -59,7 +36,6 @@ public static X509Certificate2 GeneratePfx(KubernetesClientConfiguration config)
throw new ArgumentNullException(nameof(config));
}
-#if NET5_0_OR_GREATER
string keyData = null;
string certData = null;
@@ -114,84 +90,6 @@ public static X509Certificate2 GeneratePfx(KubernetesClientConfiguration config)
}
return cert;
-#else
-
- byte[] keyData = null;
- byte[] certData = null;
-
- if (!string.IsNullOrWhiteSpace(config.ClientCertificateKeyData))
- {
- keyData = Convert.FromBase64String(config.ClientCertificateKeyData);
- }
-
- if (!string.IsNullOrWhiteSpace(config.ClientKeyFilePath))
- {
- keyData = File.ReadAllBytes(config.ClientKeyFilePath);
- }
-
- if (keyData == null)
- {
- throw new KubeConfigException("keyData is empty");
- }
-
- if (!string.IsNullOrWhiteSpace(config.ClientCertificateData))
- {
- certData = Convert.FromBase64String(config.ClientCertificateData);
- }
-
- if (!string.IsNullOrWhiteSpace(config.ClientCertificateFilePath))
- {
- certData = File.ReadAllBytes(config.ClientCertificateFilePath);
- }
-
- if (certData == null)
- {
- throw new KubeConfigException("certData is empty");
- }
-
- var cert = new X509CertificateParser().ReadCertificate(new MemoryStream(certData));
- // key usage is a bit string, zero-th bit is 'digitalSignature'
- // See https://www.alvestrand.no/objectid/2.5.29.15.html for more details.
- if (cert != null && cert.GetKeyUsage() != null && !cert.GetKeyUsage()[0])
- {
- throw new Exception(
- "Client certificates must be marked for digital signing. " +
- "See https://github.com/kubernetes-client/csharp/issues/319");
- }
-
- object obj;
- using (var reader = new StreamReader(new MemoryStream(keyData)))
- {
- obj = new PemReader(reader).ReadObject();
- if (obj is AsymmetricCipherKeyPair key)
- {
- var cipherKey = key;
- obj = cipherKey.Private;
- }
- }
-
- var keyParams = (AsymmetricKeyParameter)obj;
-
- var store = new Pkcs12StoreBuilder().Build();
- store.SetKeyEntry("K8SKEY", new AsymmetricKeyEntry(keyParams), new[] { new X509CertificateEntry(cert) });
-
- using var pkcs = new MemoryStream();
-
- store.Save(pkcs, new char[0], new SecureRandom());
-
- // This null password is to change the constructor to fix this KB:
- // https://support.microsoft.com/en-us/topic/kb5025823-change-in-how-net-applications-import-x-509-certificates-bf81c936-af2b-446e-9f7a-016f4713b46b
- string nullPassword = null;
-
- if (config.ClientCertificateKeyStoreFlags.HasValue)
- {
- return new X509Certificate2(pkcs.ToArray(), nullPassword, config.ClientCertificateKeyStoreFlags.Value);
- }
- else
- {
- return new X509Certificate2(pkcs.ToArray(), nullPassword);
- }
-#endif
}
///