|
| 1 | +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| 2 | +From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= < [email protected]> |
| 3 | +Date: Wed, 10 Jul 2024 12:21:17 +0200 |
| 4 | +Subject: [PATCH] Don't use obsolete X509Certificate2 constructor on net9.0 |
| 5 | + |
| 6 | +Fixes https://github.com/NuGet/Home/issues/13612 |
| 7 | +--- |
| 8 | + .../SignCommand/CertificateProvider.cs | 17 ++++++++++- |
| 9 | + .../Settings/Items/FileClientCertItem.cs | 4 +++ |
| 10 | + .../Utility/CertificateChainUtility.cs | 4 +++ |
| 11 | + .../ClientCertificateProviderTests.cs | 4 +++ |
| 12 | + .../HttpSource/ClientCertificatesTests.cs | 4 +++ |
| 13 | + .../SelfSignedCertificateMockServer.cs | 4 +++ |
| 14 | + .../Signing/CertificateUtilities.cs | 4 +++ |
| 15 | + .../Signing/SigningTestUtility.cs | 28 +++++++++++++++++++ |
| 16 | + .../TestServer/TcpListenerServer.cs | 4 +++ |
| 17 | + 9 files changed, 72 insertions(+), 1 deletion(-) |
| 18 | + |
| 19 | +diff --git a/src/NuGet.Core/NuGet.Commands/SignCommand/CertificateProvider.cs b/src/NuGet.Core/NuGet.Commands/SignCommand/CertificateProvider.cs |
| 20 | +index c6ea71243..b90c59742 100644 |
| 21 | +--- a/src/NuGet.Core/NuGet.Commands/SignCommand/CertificateProvider.cs |
| 22 | ++++ b/src/NuGet.Core/NuGet.Commands/SignCommand/CertificateProvider.cs |
| 23 | +@@ -32,6 +32,9 @@ internal static class CertificateProvider |
| 24 | + |
| 25 | + private const int MACOS_INVALID_CERT = -25257; |
| 26 | + |
| 27 | ++#if NET9_0_OR_GREATER |
| 28 | ++ private const int CRYPT_E_BAD_DECODE = unchecked((int)0x80092002); |
| 29 | ++#endif |
| 30 | + |
| 31 | + #if IS_SIGNING_SUPPORTED && IS_CORECLR |
| 32 | + //Generic exception ASN1 corrupted data |
| 33 | +@@ -83,6 +86,9 @@ public static async Task<X509Certificate2Collection> GetCertificatesAsync(Certif |
| 34 | + options.CertificatePath))); |
| 35 | + |
| 36 | + case CRYPT_E_NO_MATCH_HRESULT: |
| 37 | ++#if NET9_0_OR_GREATER |
| 38 | ++ case CRYPT_E_BAD_DECODE: |
| 39 | ++#endif |
| 40 | + #if IS_SIGNING_SUPPORTED && IS_CORECLR |
| 41 | + case OPENSSL_ASN1_CORRUPTED_DATA_ERROR: |
| 42 | + #else |
| 43 | +@@ -122,7 +128,12 @@ private static async Task<X509Certificate2> LoadCertificateFromFileAsync(Certifi |
| 44 | + |
| 45 | + if (!string.IsNullOrEmpty(options.CertificatePassword)) |
| 46 | + { |
| 47 | +- cert = new X509Certificate2(options.CertificatePath, options.CertificatePassword); // use the password if the user provided it. |
| 48 | ++ // use the password if the user provided it |
| 49 | ++#if NET9_0_OR_GREATER |
| 50 | ++ cert = X509CertificateLoader.LoadPkcs12FromFile(options.CertificatePath, options.CertificatePassword); |
| 51 | ++#else |
| 52 | ++ cert = new X509Certificate2(options.CertificatePath, options.CertificatePassword); |
| 53 | ++#endif |
| 54 | + } |
| 55 | + else |
| 56 | + { |
| 57 | +@@ -147,8 +158,12 @@ private static async Task<X509Certificate2> LoadCertificateFromFileAsync(Certifi |
| 58 | + throw; |
| 59 | + } |
| 60 | + } |
| 61 | ++#else |
| 62 | ++#if NET9_0_OR_GREATER |
| 63 | ++ cert = X509CertificateLoader.LoadPkcs12FromFile(options.CertificatePath, null); |
| 64 | + #else |
| 65 | + cert = new X509Certificate2(options.CertificatePath); |
| 66 | ++#endif |
| 67 | + #endif |
| 68 | + } |
| 69 | + |
| 70 | +diff --git a/src/NuGet.Core/NuGet.Configuration/Settings/Items/FileClientCertItem.cs b/src/NuGet.Core/NuGet.Configuration/Settings/Items/FileClientCertItem.cs |
| 71 | +index 774281b77..e2edb7330 100644 |
| 72 | +--- a/src/NuGet.Core/NuGet.Configuration/Settings/Items/FileClientCertItem.cs |
| 73 | ++++ b/src/NuGet.Core/NuGet.Configuration/Settings/Items/FileClientCertItem.cs |
| 74 | +@@ -167,7 +167,11 @@ public override IEnumerable<X509Certificate> Search() |
| 75 | + Resources.FileCertItemPathFileNotExist)); |
| 76 | + } |
| 77 | + |
| 78 | ++#if NET9_0_OR_GREATER |
| 79 | ++ return new[] { string.IsNullOrWhiteSpace(Password) ? X509CertificateLoader.LoadPkcs12FromFile(filePath, null) : X509CertificateLoader.LoadPkcs12FromFile(filePath, Password) }; |
| 80 | ++#else |
| 81 | + return new[] { string.IsNullOrWhiteSpace(Password) ? new X509Certificate2(filePath) : new X509Certificate2(filePath, Password) }; |
| 82 | ++#endif |
| 83 | + } |
| 84 | + |
| 85 | + public void Update(string filePath, string? password, bool storePasswordInClearText) |
| 86 | +diff --git a/src/NuGet.Core/NuGet.Packaging/Signing/Utility/CertificateChainUtility.cs b/src/NuGet.Core/NuGet.Packaging/Signing/Utility/CertificateChainUtility.cs |
| 87 | +index d23123a81..efbac7861 100644 |
| 88 | +--- a/src/NuGet.Core/NuGet.Packaging/Signing/Utility/CertificateChainUtility.cs |
| 89 | ++++ b/src/NuGet.Core/NuGet.Packaging/Signing/Utility/CertificateChainUtility.cs |
| 90 | +@@ -127,7 +127,11 @@ public static IX509CertificateChain GetCertificateChain(X509Chain x509Chain) |
| 91 | + // Return a new certificate object. |
| 92 | + // This allows the chain and its chain element certificates to be disposed |
| 93 | + // in both success and error cases. |
| 94 | ++#if NET9_0_OR_GREATER |
| 95 | ++ certs.Add(X509CertificateLoader.LoadCertificate(item.Certificate.RawData)); |
| 96 | ++#else |
| 97 | + certs.Add(new X509Certificate2(item.Certificate.RawData)); |
| 98 | ++#endif |
| 99 | + } |
| 100 | + |
| 101 | + return certs; |
| 102 | +diff --git a/test/NuGet.Core.Tests/NuGet.Configuration.Test/ClientCertificateProviderTests.cs b/test/NuGet.Core.Tests/NuGet.Configuration.Test/ClientCertificateProviderTests.cs |
| 103 | +index 3925f2953..7c383a3dc 100644 |
| 104 | +--- a/test/NuGet.Core.Tests/NuGet.Configuration.Test/ClientCertificateProviderTests.cs |
| 105 | ++++ b/test/NuGet.Core.Tests/NuGet.Configuration.Test/ClientCertificateProviderTests.cs |
| 106 | +@@ -147,7 +147,11 @@ private byte[] CreateCertificate() |
| 107 | + |
| 108 | + private X509Certificate2 GetCertificate() |
| 109 | + { |
| 110 | ++#if NET9_0_OR_GREATER |
| 111 | ++ return X509CertificateLoader.LoadPkcs12(CreateCertificate(), CertificatePassword); |
| 112 | ++#else |
| 113 | + return new X509Certificate2(CreateCertificate(), CertificatePassword); |
| 114 | ++#endif |
| 115 | + } |
| 116 | + |
| 117 | + private void RemoveCertificateFromStorage() |
| 118 | +diff --git a/test/NuGet.Core.Tests/NuGet.Protocol.Tests/HttpSource/ClientCertificatesTests.cs b/test/NuGet.Core.Tests/NuGet.Protocol.Tests/HttpSource/ClientCertificatesTests.cs |
| 119 | +index 83b3be6f4..51e1ac490 100644 |
| 120 | +--- a/test/NuGet.Core.Tests/NuGet.Protocol.Tests/HttpSource/ClientCertificatesTests.cs |
| 121 | ++++ b/test/NuGet.Core.Tests/NuGet.Protocol.Tests/HttpSource/ClientCertificatesTests.cs |
| 122 | +@@ -41,7 +41,11 @@ private X509Certificate2 GetCertificate() |
| 123 | + var end = start.AddYears(1); |
| 124 | + var cert = request.CreateSelfSigned(start, end); |
| 125 | + var data = cert.Export(X509ContentType.Pfx); |
| 126 | ++#if NET9_0_OR_GREATER |
| 127 | ++ return X509CertificateLoader.LoadPkcs12(data, null); |
| 128 | ++#else |
| 129 | + return new X509Certificate2(data); |
| 130 | ++#endif |
| 131 | + } |
| 132 | + } |
| 133 | + } |
| 134 | +diff --git a/test/TestUtilities/Test.Utility/SelfSignedCertificateMockServer.cs b/test/TestUtilities/Test.Utility/SelfSignedCertificateMockServer.cs |
| 135 | +index 330089ca7..3ba0611e8 100644 |
| 136 | +--- a/test/TestUtilities/Test.Utility/SelfSignedCertificateMockServer.cs |
| 137 | ++++ b/test/TestUtilities/Test.Utility/SelfSignedCertificateMockServer.cs |
| 138 | +@@ -198,7 +198,11 @@ private static X509Certificate2 GenerateSelfSignedCertificate() |
| 139 | + var end = DateTime.UtcNow.AddYears(1); |
| 140 | + var cert = request.CreateSelfSigned(start, end); |
| 141 | + var certBytes = cert.Export(X509ContentType.Pfx, "password"); |
| 142 | ++#if NET9_0_OR_GREATER |
| 143 | ++ return X509CertificateLoader.LoadPkcs12(certBytes, "password", X509KeyStorageFlags.Exportable); |
| 144 | ++#else |
| 145 | + return new X509Certificate2(certBytes, "password", X509KeyStorageFlags.Exportable); |
| 146 | ++#endif |
| 147 | + } |
| 148 | + } |
| 149 | + |
| 150 | +diff --git a/test/TestUtilities/Test.Utility/Signing/CertificateUtilities.cs b/test/TestUtilities/Test.Utility/Signing/CertificateUtilities.cs |
| 151 | +index 6e9232634..c4aa29fc7 100644 |
| 152 | +--- a/test/TestUtilities/Test.Utility/Signing/CertificateUtilities.cs |
| 153 | ++++ b/test/TestUtilities/Test.Utility/Signing/CertificateUtilities.cs |
| 154 | +@@ -60,7 +60,11 @@ public static X509Certificate2 GetCertificateWithPrivateKey(X509Certificate bcCe |
| 155 | + |
| 156 | + X509Certificate2 certificate; |
| 157 | + |
| 158 | ++#if NET9_0_OR_GREATER |
| 159 | ++ using (var certificateTmp = X509CertificateLoader.LoadCertificate(bcCertificate.GetEncoded())) |
| 160 | ++#else |
| 161 | + using (var certificateTmp = new X509Certificate2(bcCertificate.GetEncoded())) |
| 162 | ++#endif |
| 163 | + { |
| 164 | + certificate = RSACertificateExtensions.CopyWithPrivateKey(certificateTmp, privateKey); |
| 165 | + } |
| 166 | +diff --git a/test/TestUtilities/Test.Utility/Signing/SigningTestUtility.cs b/test/TestUtilities/Test.Utility/Signing/SigningTestUtility.cs |
| 167 | +index 2fd28b4e3..646d80f7d 100644 |
| 168 | +--- a/test/TestUtilities/Test.Utility/Signing/SigningTestUtility.cs |
| 169 | ++++ b/test/TestUtilities/Test.Utility/Signing/SigningTestUtility.cs |
| 170 | +@@ -458,7 +458,11 @@ public static IList<TrustedTestCert<TestCertificate>> GenerateCertificateChain(i |
| 171 | + } |
| 172 | + } |
| 173 | + |
| 174 | ++#if NET9_0_OR_GREATER |
| 175 | ++ return X509CertificateLoader.LoadPkcs12(certResult.Export(X509ContentType.Pkcs12), password: (string)null, keyStorageFlags: X509KeyStorageFlags.Exportable); |
| 176 | ++#else |
| 177 | + return new X509Certificate2(certResult.Export(X509ContentType.Pkcs12), password: (string)null, keyStorageFlags: X509KeyStorageFlags.Exportable); |
| 178 | ++#endif |
| 179 | + } |
| 180 | + |
| 181 | + private static RSASignaturePadding ToPadding(this RSASignaturePaddingMode mode) |
| 182 | +@@ -497,7 +501,11 @@ public static X509Certificate2 GenerateCertificate(string subjectName, RSA key) |
| 183 | + |
| 184 | + var certResult = request.CreateSelfSigned(notBefore: DateTime.UtcNow.Subtract(TimeSpan.FromHours(1)), notAfter: DateTime.UtcNow.Add(TimeSpan.FromHours(1))); |
| 185 | + |
| 186 | ++#if NET9_0_OR_GREATER |
| 187 | ++ return X509CertificateLoader.LoadPkcs12(certResult.Export(X509ContentType.Pkcs12), password: (string)null, keyStorageFlags: X509KeyStorageFlags.Exportable); |
| 188 | ++#else |
| 189 | + return new X509Certificate2(certResult.Export(X509ContentType.Pkcs12), password: (string)null, keyStorageFlags: X509KeyStorageFlags.Exportable); |
| 190 | ++#endif |
| 191 | + } |
| 192 | + |
| 193 | + public static X509Certificate2 GenerateCertificate( |
| 194 | +@@ -534,7 +542,11 @@ public static X509Certificate2 GenerateCertificate(string subjectName, RSA key) |
| 195 | + using (var temp = request.Create(issuerDN, generator, notBefore, notAfter, serialNumber)) |
| 196 | + { |
| 197 | + var certResult = temp.CopyWithPrivateKey(algorithm); |
| 198 | ++#if NET9_0_OR_GREATER |
| 199 | ++ return X509CertificateLoader.LoadPkcs12(certResult.Export(X509ContentType.Pkcs12), password: (string)null, keyStorageFlags: X509KeyStorageFlags.Exportable); |
| 200 | ++#else |
| 201 | + return new X509Certificate2(certResult.Export(X509ContentType.Pkcs12), password: (string)null, keyStorageFlags: X509KeyStorageFlags.Exportable); |
| 202 | ++#endif |
| 203 | + } |
| 204 | + } |
| 205 | + |
| 206 | +@@ -571,7 +583,11 @@ public static X509Certificate2 GenerateSelfIssuedCertificate(bool isCa) |
| 207 | + var now = DateTime.UtcNow; |
| 208 | + var certResult = request.CreateSelfSigned(notBefore: now, notAfter: now.AddHours(1)); |
| 209 | + |
| 210 | ++#if NET9_0_OR_GREATER |
| 211 | ++ return X509CertificateLoader.LoadPkcs12(certResult.Export(X509ContentType.Pkcs12), password: (string)null, keyStorageFlags: X509KeyStorageFlags.Exportable); |
| 212 | ++#else |
| 213 | + return new X509Certificate2(certResult.Export(X509ContentType.Pkcs12), password: (string)null, keyStorageFlags: X509KeyStorageFlags.Exportable); |
| 214 | ++#endif |
| 215 | + } |
| 216 | + } |
| 217 | + |
| 218 | +@@ -655,7 +671,11 @@ public static SignedCms GenerateRepositoryCountersignedSignedCms(X509Certificate |
| 219 | + /// </summary> |
| 220 | + public static X509Certificate2 GetPublicCert(X509Certificate2 cert) |
| 221 | + { |
| 222 | ++#if NET9_0_OR_GREATER |
| 223 | ++ return X509CertificateLoader.LoadCertificate(cert.Export(X509ContentType.Cert)); |
| 224 | ++#else |
| 225 | + return new X509Certificate2(cert.Export(X509ContentType.Cert)); |
| 226 | ++#endif |
| 227 | + } |
| 228 | + |
| 229 | + /// <summary> |
| 230 | +@@ -664,7 +684,11 @@ public static X509Certificate2 GetPublicCert(X509Certificate2 cert) |
| 231 | + public static X509Certificate2 GetPublicCertWithPrivateKey(X509Certificate2 cert) |
| 232 | + { |
| 233 | + var password = new Guid().ToString(); |
| 234 | ++#if NET9_0_OR_GREATER |
| 235 | ++ return X509CertificateLoader.LoadPkcs12(cert.Export(X509ContentType.Pfx, password), password, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); |
| 236 | ++#else |
| 237 | + return new X509Certificate2(cert.Export(X509ContentType.Pfx, password), password, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); |
| 238 | ++#endif |
| 239 | + } |
| 240 | + |
| 241 | + public static TrustedTestCert<TestCertificate> GenerateTrustedTestCertificate() |
| 242 | +@@ -761,7 +785,11 @@ public static X509Certificate2 GetCertificate(string name) |
| 243 | + { |
| 244 | + var bytes = GetResourceBytes(name); |
| 245 | + |
| 246 | ++#if NET9_0_OR_GREATER |
| 247 | ++ return X509CertificateLoader.LoadCertificate(bytes); |
| 248 | ++#else |
| 249 | + return new X509Certificate2(bytes); |
| 250 | ++#endif |
| 251 | + } |
| 252 | + |
| 253 | + public static byte[] GetHash(X509Certificate2 certificate, NuGet.Common.HashAlgorithmName hashAlgorithm) |
| 254 | +diff --git a/test/TestUtilities/Test.Utility/TestServer/TcpListenerServer.cs b/test/TestUtilities/Test.Utility/TestServer/TcpListenerServer.cs |
| 255 | +index db8034c08..36c1e08d0 100644 |
| 256 | +--- a/test/TestUtilities/Test.Utility/TestServer/TcpListenerServer.cs |
| 257 | ++++ b/test/TestUtilities/Test.Utility/TestServer/TcpListenerServer.cs |
| 258 | +@@ -83,7 +83,11 @@ private static X509Certificate2 GenerateSelfSignedCertificate() |
| 259 | + var cert = request.CreateSelfSigned(start, end); |
| 260 | + var certBytes = cert.Export(X509ContentType.Pfx, "password"); |
| 261 | + |
| 262 | ++#if NET9_0_OR_GREATER |
| 263 | ++ return X509CertificateLoader.LoadPkcs12(certBytes, "password", X509KeyStorageFlags.Exportable); |
| 264 | ++#else |
| 265 | + return new X509Certificate2(certBytes, "password", X509KeyStorageFlags.Exportable); |
| 266 | ++#endif |
| 267 | + } |
| 268 | + } |
| 269 | + |
0 commit comments