Skip RC2 encrypted PKCS12 files on Android for iteration counting
authorKevin Jones <kevin@vcsjones.com>
Thu, 13 Jul 2023 14:28:52 +0000 (10:28 -0400)
committerGitHub <noreply@github.com>
Thu, 13 Jul 2023 14:28:52 +0000 (10:28 -0400)
src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxIterationCountTests.CustomAppContextDataLimit.cs
src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxIterationCountTests.cs
src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxTests.cs

index 88d5f34..bed1264 100644 (file)
@@ -5,6 +5,7 @@ using Microsoft.DotNet.RemoteExecutor;
 using Microsoft.DotNet.XUnitExtensions;
 using System.Collections.Generic;
 using System.Linq;
+using Test.Cryptography;
 using Xunit;
 
 namespace System.Security.Cryptography.X509Certificates.Tests
@@ -20,7 +21,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
 
         [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
         [MemberData(memberName: nameof(PfxIterationCountTests.GetCertsWith_IterationCountNotExceedingDefaultLimit_AndNullOrEmptyPassword_MemberData), MemberType = typeof(PfxIterationCountTests))]
-        public void Import_AppContextDataWithValueMinusTwo_ActsAsDefaultLimit_IterationCountNotExceedingDefaultLimit(string name, bool usesPbes2, byte[] blob, long iterationCount)
+        public void Import_AppContextDataWithValueMinusTwo_ActsAsDefaultLimit_IterationCountNotExceedingDefaultLimit(string name, bool usesPbes2, byte[] blob, long iterationCount, bool usesRC2)
         {
             _ = iterationCount;
             _ = blob;
@@ -30,6 +31,11 @@ namespace System.Security.Cryptography.X509Certificates.Tests
                 throw new SkipTestException(name + " uses PBES2, which is not supported on this version.");
             }
 
+            if (usesRC2 && !PlatformSupport.IsRC2Supported)
+            {
+                throw new SkipTestException(name + " uses RC2, which is not supported on this platform.");
+            }
+
             RemoteExecutor.Invoke((certName) =>
             {
                 AppContext.SetData("System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit", -2);
@@ -43,7 +49,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
 
         [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
         [MemberData(memberName: nameof(PfxIterationCountTests.GetCertsWith_IterationCountExceedingDefaultLimit_MemberData), MemberType = typeof(PfxIterationCountTests))]
-        public void Import_AppContextDataWithValueMinusTwo_ActsAsDefaultLimit_IterationCountLimitExceeded_Throws(string name, string password, bool usesPbes2, byte[] blob, long iterationCount)
+        public void Import_AppContextDataWithValueMinusTwo_ActsAsDefaultLimit_IterationCountLimitExceeded_Throws(string name, string password, bool usesPbes2, byte[] blob, long iterationCount, bool usesRC2)
         {
             _ = password;
             _ = iterationCount;
@@ -54,6 +60,11 @@ namespace System.Security.Cryptography.X509Certificates.Tests
                 throw new SkipTestException(name + " uses PBES2, which is not supported on this version.");
             }
 
+            if (usesRC2 && !PlatformSupport.IsRC2Supported)
+            {
+                throw new SkipTestException(name + " uses RC2, which is not supported on this platform.");
+            }
+
             RemoteExecutor.Invoke((certName) =>
             {
                 AppContext.SetData("System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit", -2);
@@ -67,7 +78,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
 
         [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
         [MemberData(memberName: nameof(PfxIterationCountTests.GetCertsWith_IterationCountNotExceedingDefaultLimit_AndNullOrEmptyPassword_MemberData), MemberType = typeof(PfxIterationCountTests))]
-        public void Import_AppContextDataWithValueZero_IterationCountNotExceedingDefaultLimit_Throws(string name, bool usesPbes2, byte[] blob, long iterationCount)
+        public void Import_AppContextDataWithValueZero_IterationCountNotExceedingDefaultLimit_Throws(string name, bool usesPbes2, byte[] blob, long iterationCount, bool usesRC2)
         {
             _ = iterationCount;
             _ = blob;
@@ -77,6 +88,11 @@ namespace System.Security.Cryptography.X509Certificates.Tests
                 throw new SkipTestException(name + " uses PBES2, which is not supported on this version.");
             }
 
+            if (usesRC2 && !PlatformSupport.IsRC2Supported)
+            {
+                throw new SkipTestException(name + " uses RC2, which is not supported on this platform.");
+            }
+
             RemoteExecutor.Invoke((certName) =>
             {
                 AppContext.SetData("System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit", 0);
@@ -90,7 +106,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
 
         [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
         [MemberData(memberName: nameof(PfxIterationCountTests.GetCertsWith_IterationCountExceedingDefaultLimit_MemberData), MemberType = typeof(PfxIterationCountTests))]
-        public void Import_AppContextDataWithValueMinusOne_IterationCountExceedingDefaultLimit(string name, string password, bool usesPbes2, byte[] blob, long iterationCount)
+        public void Import_AppContextDataWithValueMinusOne_IterationCountExceedingDefaultLimit(string name, string password, bool usesPbes2, byte[] blob, long iterationCount, bool usesRC2)
         {
             _ = password;
             _ = blob;
@@ -101,6 +117,11 @@ namespace System.Security.Cryptography.X509Certificates.Tests
                 throw new SkipTestException(name + " uses PBES2, which is not supported on this version.");
             }
 
+            if (usesRC2 && !PlatformSupport.IsRC2Supported)
+            {
+                throw new SkipTestException(name + " uses RC2, which is not supported on this platform.");
+            }
+
             RemoteExecutor.Invoke((certName) =>
             {
                 AppContext.SetData("System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit", -1);
index 59339ab..3d3cc12 100644 (file)
@@ -24,13 +24,18 @@ namespace System.Security.Cryptography.X509Certificates.Tests
 
         [ConditionalTheory]
         [MemberData(nameof(GetCertsWith_IterationCountNotExceedingDefaultLimit_AndNullOrEmptyPassword_MemberData))]
-        public void Import_IterationCounLimitNotExceeded_Succeeds(string name, bool usesPbes2, byte[] blob, long iterationCount)
+        public void Import_IterationCounLimitNotExceeded_Succeeds(string name, bool usesPbes2, byte[] blob, long iterationCount, bool usesRC2)
         {
             if (usesPbes2 && !PfxTests.Pkcs12PBES2Supported)
             {
                 throw new SkipTestException(name + " uses PBES2, which is not supported on this version.");
             }
 
+            if (usesRC2 && !PlatformSupport.IsRC2Supported)
+            {
+                throw new SkipTestException(name + " uses RC2, which is not supported on this platform.");
+            }
+
             if (PfxTests.IsPkcs12IterationCountAllowed(iterationCount, PfxTests.DefaultIterations))
             {
                 X509Certificate cert = Import(blob);
@@ -40,7 +45,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
 
         [ConditionalTheory]
         [MemberData(nameof(GetCertsWith_IterationCountExceedingDefaultLimit_MemberData))]
-        public void Import_IterationCountLimitExceeded_Throws(string name, string password, bool usesPbes2, byte[] blob, long iterationCount)
+        public void Import_IterationCountLimitExceeded_Throws(string name, string password, bool usesPbes2, byte[] blob, long iterationCount, bool usesRC2)
         {
             _ = password;
             _ = iterationCount;
@@ -50,13 +55,18 @@ namespace System.Security.Cryptography.X509Certificates.Tests
                 throw new SkipTestException(name + " uses PBES2, which is not supported on this version.");
             }
 
+            if (usesRC2 && !PlatformSupport.IsRC2Supported)
+            {
+                throw new SkipTestException(name + " uses RC2, which is not supported on this platform.");
+            }
+
             CryptographicException ce = Assert.Throws<CryptographicException>(() => Import(blob));
             Assert.Contains(FwlinkId, ce.Message);
         }
 
         [ConditionalTheory]
         [MemberData(nameof(GetCertsWith_IterationCountExceedingDefaultLimit_MemberData))]
-        public void ImportWithPasswordOrFileName_IterationCountLimitExceeded(string name, string password, bool usesPbes2, byte[] blob, long iterationCount)
+        public void ImportWithPasswordOrFileName_IterationCountLimitExceeded(string name, string password, bool usesPbes2, byte[] blob, long iterationCount, bool usesRC2)
         {
             _ = iterationCount;
 
@@ -65,6 +75,11 @@ namespace System.Security.Cryptography.X509Certificates.Tests
                 throw new SkipTestException(name + " uses PBES2, which is not supported on this version.");
             }
 
+            if (usesRC2 && !PlatformSupport.IsRC2Supported)
+            {
+                throw new SkipTestException(name + " uses RC2, which is not supported on this platform.");
+            }
+
             using (TempFileHolder tempFile = new TempFileHolder(blob))
             {
                 string fileName = tempFile.FilePath;
@@ -100,13 +115,18 @@ namespace System.Security.Cryptography.X509Certificates.Tests
 
         [ConditionalTheory]
         [MemberData(nameof(GetCertsWith_NonNullOrEmptyPassword_MemberData))]
-        public void Import_NonNullOrEmptyPasswordExpected_Throws(string name, string password, bool usesPbes2, byte[] blob, long iterationCount)
+        public void Import_NonNullOrEmptyPasswordExpected_Throws(string name, string password, bool usesPbes2, byte[] blob, long iterationCount, bool usesRC2)
         {
             if (usesPbes2 && !PfxTests.Pkcs12PBES2Supported)
             {
                 throw new SkipTestException(name + " uses PBES2, which is not supported on this version.");
             }
 
+            if (usesRC2 && !PlatformSupport.IsRC2Supported)
+            {
+                throw new SkipTestException(name + " uses RC2, which is not supported on this platform.");
+            }
+
             CryptographicException ce = Assert.ThrowsAny<CryptographicException>(() => Import(blob));
 
             if (PfxTests.IsPkcs12IterationCountAllowed(iterationCount, PfxTests.DefaultIterations))
@@ -123,7 +143,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
             }
         }
 
-        [Fact]
+        [ConditionalFact(typeof(PlatformSupport), nameof(PlatformSupport.IsRC2Supported))]
         public void ExportedPfxWithNullPassword_DecryptReturnsValidPaddingWithEmptyPassword()
         {
             Assert.NotNull(Import(TestData.MsCertificateExportedToPfx_NullPassword));
@@ -160,7 +180,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
             certificates.Add(new PfxInfo(
                 nameof(TestData.Pkcs12WindowsDotnetExportEmptyPassword), "", 6000, false, TestData.Pkcs12WindowsDotnetExportEmptyPassword));
             certificates.Add(new PfxInfo(
-                nameof(TestData.Pkcs12MacosKeychainCreated), null, 4097, false, TestData.Pkcs12MacosKeychainCreated));
+                nameof(TestData.Pkcs12MacosKeychainCreated), null, 4097, false, TestData.Pkcs12MacosKeychainCreated, usesRC2: true));
             certificates.Add(new PfxInfo(
                 nameof(TestData.Pkcs12BuilderSaltWithMacNullPassword), null, 120000, true, TestData.Pkcs12BuilderSaltWithMacNullPassword));
             certificates.Add(new PfxInfo(
@@ -183,7 +203,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
             {
                 if (p.IterationCount <= DefaultIterationLimit && string.IsNullOrEmpty(p.Password))
                 {
-                    yield return new object[] { p.Name, p.UsesPbes2, p.Blob, p.IterationCount };
+                    yield return new object[] { p.Name, p.UsesPbes2, p.Blob, p.IterationCount, p.UsesRC2 };
                 }
             }
         }
@@ -194,7 +214,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
             {
                 if (p.IterationCount > DefaultIterationLimit)
                 {
-                    yield return new object[] { p.Name, p.Password, p.UsesPbes2, p.Blob, p.IterationCount };
+                    yield return new object[] { p.Name, p.Password, p.UsesPbes2, p.Blob, p.IterationCount, p.UsesRC2 };
                 }
             }
         }
@@ -205,7 +225,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
             {
                 if (!string.IsNullOrEmpty(p.Password))
                 {
-                    yield return new object[] { p.Name, p.Password, p.UsesPbes2, p.Blob, p.IterationCount };
+                    yield return new object[] { p.Name, p.Password, p.UsesPbes2, p.Blob, p.IterationCount, p.UsesRC2 };
                 }
             }
         }
@@ -218,14 +238,16 @@ namespace System.Security.Cryptography.X509Certificates.Tests
         internal long IterationCount { get; set; }
         internal bool UsesPbes2 { get; set; }
         internal byte[] Blob { get; set; }
+        internal bool UsesRC2 { get; set; }
 
-        internal PfxInfo(string name, string password, long iterationCount, bool usesPbes2, byte[] blob)
+        internal PfxInfo(string name, string password, long iterationCount, bool usesPbes2, byte[] blob, bool usesRC2 = false)
         {
             Name = name;
             Password = password;
             IterationCount = iterationCount;
             UsesPbes2 = usesPbes2;
             Blob = blob;
+            UsesRC2 = usesRC2;
         }
     }
 }
index c456eaf..a8454f1 100644 (file)
@@ -470,7 +470,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
 
         [ConditionalTheory]
         [MemberData(memberName: nameof(PfxIterationCountTests.GetCertsWith_IterationCountNotExceedingDefaultLimit_AndNullOrEmptyPassword_MemberData), MemberType = typeof(PfxIterationCountTests))]
-        public static void TestIterationCounter(string name, bool usesPbes2, byte[] blob, int iterationCount)
+        public static void TestIterationCounter(string name, bool usesPbes2, byte[] blob, int iterationCount, bool usesRC2)
         {
             _ = iterationCount;
 
@@ -482,6 +482,11 @@ namespace System.Security.Cryptography.X509Certificates.Tests
                 throw new SkipTestException(name + " uses PBES2, which is not supported on this version.");
             }
 
+            if (usesRC2 && !PlatformSupport.IsRC2Supported)
+            {
+                throw new SkipTestException(name + " uses RC2, which is not supported on this platform.");
+            }
+
             try
             {
                 long count = (long)target(blob, out int bytesConsumed);