Support ECParameters that contain only D (macOS).
authorKevin Jones <kevin@vcsjones.com>
Wed, 8 Apr 2020 19:48:11 +0000 (15:48 -0400)
committerGitHub <noreply@github.com>
Wed, 8 Apr 2020 19:48:11 +0000 (12:48 -0700)
Also remove the LimitedPrivateKeySupported test conditions, as all platforms support it now.

15 files changed:
src/libraries/Common/src/System/Security/Cryptography/EccSecurityTransforms.cs
src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.LimitedPrivate.cs
src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs
src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.ImportExport.cs
src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactory.cs
src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaImportExport.cs
src/libraries/System.Security.Cryptography.Algorithms/src/Resources/Strings.resx
src/libraries/System.Security.Cryptography.Algorithms/tests/DefaultECDiffieHellmanProvider.Unix.cs
src/libraries/System.Security.Cryptography.Algorithms/tests/DefaultECDiffieHellmanProvider.Windows.cs
src/libraries/System.Security.Cryptography.Algorithms/tests/DefaultECDsaProvider.Unix.cs
src/libraries/System.Security.Cryptography.Algorithms/tests/DefaultECDsaProvider.Windows.cs
src/libraries/System.Security.Cryptography.Cng/tests/ECDiffieHellmanCngProvider.cs
src/libraries/System.Security.Cryptography.Cng/tests/ECDsaCngProvider.cs
src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDiffieHellmanOpenSslProvider.cs
src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDsaOpenSslProvider.cs

index d095711..09c8502 100644 (file)
@@ -117,6 +117,17 @@ namespace System.Security.Cryptography
             current?.Dispose();
         }
 
+        internal static ECParameters ExportPublicParametersFromPrivateKey(SafeSecKeyRefHandle handle)
+        {
+            const string ExportPassword = "DotnetExportPassphrase";
+            byte[] keyBlob = Interop.AppleCrypto.SecKeyExport(handle, exportPrivate: true, password: ExportPassword);
+            EccKeyFormatHelper.ReadEncryptedPkcs8(keyBlob, ExportPassword, out _, out ECParameters key);
+            CryptographicOperations.ZeroMemory(key.D);
+            CryptographicOperations.ZeroMemory(keyBlob);
+            key.D = null;
+            return key;
+        }
+
         internal ECParameters ExportParameters(bool includePrivateParameters, int keySizeInBits)
         {
             // Apple requires all private keys to be exported encrypted, but since we're trying to export
@@ -166,6 +177,7 @@ namespace System.Security.Cryptography
             ThrowIfDisposed();
 
             bool isPrivateKey = parameters.D != null;
+            bool hasPublicParameters = parameters.Q.X != null && parameters.Q.Y != null;
             SecKeyPair newKeys;
 
             if (isPrivateKey)
@@ -176,8 +188,17 @@ namespace System.Security.Cryptography
                 // Public import should go off without a hitch.
                 SafeSecKeyRefHandle privateKey = ImportKey(parameters);
 
-                ECParameters publicOnly = parameters;
-                publicOnly.D = null;
+                ECParameters publicOnly;
+
+                if (hasPublicParameters)
+                {
+                    publicOnly = parameters;
+                    publicOnly.D = null;
+                }
+                else
+                {
+                    publicOnly = ExportPublicParametersFromPrivateKey(privateKey);
+                }
 
                 SafeSecKeyRefHandle publicKey;
                 try
index f85c8ce..ee534fd 100644 (file)
@@ -10,14 +10,13 @@ namespace System.Security.Cryptography.Tests
 {
     public abstract partial class ECKeyFileTests<T>
     {
-        private static bool LimitedPrivateKeySupported { get; } = EcDiffieHellman.Tests.ECDiffieHellmanFactory.LimitedPrivateKeySupported;
         private const int NTE_PERM = unchecked((int)0x80090010);
 
         [Fact]
         [PlatformSpecific(TestPlatforms.Windows)]
         public void ReadWriteNistP256_PreservesKeyUsage_Explicit_LimitedPrivate()
         {
-            if (!LimitedPrivateKeySupported || !SupportsExplicitCurves)
+            if (!SupportsExplicitCurves)
             {
                 return;
             }
@@ -49,7 +48,7 @@ MGACAQAwEAYHKoZIzj0CAQYFK4EEACMESTBHAgEBBEIBpV+HhaVzC67h1rPTAQaf
 f9ZNiwTM6lfv1ZYeaPM/q0NUUWbKZVPNOP9xPRKJxpi9fQhrVeAbW9XtJ+NjA3ax
 FmY=";
 
-            ReadWriteBase64Pkcs8(base64, EccTestData.GetNistP521Key2(), LimitedPrivateKeySupported);
+            ReadWriteBase64Pkcs8(base64, EccTestData.GetNistP521Key2());
         }
 
         [Fact]
@@ -69,8 +68,7 @@ PFzVQfJ396S+yx4IIC4=";
                     PbeEncryptionAlgorithm.TripleDes3KeyPkcs12,
                     HashAlgorithmName.SHA1,
                     12321),
-                EccTestData.GetNistP521Key2(),
-                LimitedPrivateKeySupported);
+                EccTestData.GetNistP521Key2());
         }
 
         [Fact]
@@ -90,8 +88,7 @@ PFzVQfJ396S+yx4IIC4=";
                     PbeEncryptionAlgorithm.Aes256Cbc,
                     HashAlgorithmName.SHA1,
                     12321),
-                EccTestData.GetNistP521Key2(),
-                LimitedPrivateKeySupported);
+                EccTestData.GetNistP521Key2());
         }
 
         [Fact]
@@ -103,8 +100,7 @@ AwEH";
 
             ReadWriteBase64ECPrivateKey(
                 base64,
-                EccTestData.GetNistP256ReferenceKey(),
-                LimitedPrivateKeySupported);
+                EccTestData.GetNistP256ReferenceKey());
         }
 
         [Fact]
@@ -120,7 +116,7 @@ axfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54W
 K84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8
 YyVRAgEB",
                 EccTestData.GetNistP256ReferenceKeyExplicit(),
-                LimitedPrivateKeySupported && SupportsExplicitCurves);
+                SupportsExplicitCurves);
         }
 
         [Fact]
@@ -136,7 +132,7 @@ AMSdNgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg
 AAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBBCcwJQIBAQQgcKEsLbFoRe1W
 /2jPwhpHKz8E19aFG/Y0ny19WzRSs4o=",
                 EccTestData.GetNistP256ReferenceKeyExplicit(),
-                LimitedPrivateKeySupported && SupportsExplicitCurves);
+                SupportsExplicitCurves);
         }
 
         [Fact]
@@ -159,7 +155,7 @@ hjy6jYfLa1BCJhvq+WbNc7zEb2MfXVhnImaG+XTqXI0c",
                     HashAlgorithmName.SHA256,
                     1234),
                 EccTestData.GetNistP256ReferenceKeyExplicit(),
-                LimitedPrivateKeySupported && SupportsExplicitCurves);
+                SupportsExplicitCurves);
         }
 
         [Fact]
@@ -168,7 +164,7 @@ hjy6jYfLa1BCJhvq+WbNc7zEb2MfXVhnImaG+XTqXI0c",
             ReadWriteBase64ECPrivateKey(
                 "MCYCAQEEFMXZRFR94RXbJYjcb966O0c+nE2WoAsGCSskAwMCCAEBAQ==",
                 EccTestData.BrainpoolP160r1Key1,
-                SupportsBrainpool && LimitedPrivateKeySupported);
+                SupportsBrainpool);
         }
 
         [Fact]
@@ -179,7 +175,7 @@ hjy6jYfLa1BCJhvq+WbNc7zEb2MfXVhnImaG+XTqXI0c",
 MDYCAQAwFAYHKoZIzj0CAQYJKyQDAwIIAQEBBBswGQIBAQQUxdlEVH3hFdsliNxv
 3ro7Rz6cTZY=",
                 EccTestData.BrainpoolP160r1Key1,
-                SupportsBrainpool && LimitedPrivateKeySupported);
+                SupportsBrainpool);
         }
 
         [Fact]
@@ -197,7 +193,7 @@ heDtThcoFBJUsNhEHrc=",
                     HashAlgorithmName.SHA384,
                     4096),
                 EccTestData.BrainpoolP160r1Key1,
-                SupportsBrainpool && LimitedPrivateKeySupported);
+                SupportsBrainpool);
         }
 
         [Fact]
@@ -206,7 +202,7 @@ heDtThcoFBJUsNhEHrc=",
             ReadWriteBase64ECPrivateKey(
                 "MCMCAQEEFQPBmVrfrowFGNwT3+YwS7AQF+akEqAHBgUrgQQAAQ==",
                 EccTestData.Sect163k1Key1,
-                SupportsSect163k1 && LimitedPrivateKeySupported);
+                SupportsSect163k1);
         }
 
         [Fact]
@@ -217,7 +213,7 @@ heDtThcoFBJUsNhEHrc=",
 MDMCAQAwEAYHKoZIzj0CAQYFK4EEAAEEHDAaAgEBBBUDwZla366MBRjcE9/mMEuw
 EBfmpBI=",
                 EccTestData.Sect163k1Key1,
-                SupportsSect163k1 && LimitedPrivateKeySupported);
+                SupportsSect163k1);
         }
 
         [Fact]
@@ -231,7 +227,7 @@ AAAAAAABBBUAAAAAAAAAAAAAAAAAAAAAAAAAAAEEKwQC/hPAU3u8EayqB9eT3k5t
 XlyU7ugCiQcPsF04/1gyHy6ABTbVOMzao9kCFQQAAAAAAAAAAAACAQii4MwNmfil
 7wIBAg==",
                 EccTestData.Sect163k1Key1Explicit,
-                SupportsSect163k1 && LimitedPrivateKeySupported);
+                SupportsSect163k1);
         }
 
         [Fact]
@@ -245,7 +241,7 @@ AAAAAAAAAAAAAAAAAAABBCsEAv4TwFN7vBGsqgfXk95ObV5clO7oAokHD7BdOP9Y
 Mh8ugAU21TjM2qPZAhUEAAAAAAAAAAAAAgEIouDMDZn4pe8CAQIEHDAaAgEBBBUD
 wZla366MBRjcE9/mMEuwEBfmpBI=",
                 EccTestData.Sect163k1Key1Explicit,
-                SupportsSect163k1 && LimitedPrivateKeySupported);
+                SupportsSect163k1);
         }
 
         [Fact]
@@ -263,7 +259,7 @@ DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEENKfCUCiZgnSk3NJ1fYNsfsEQEiv
                     HashAlgorithmName.SHA256,
                     7),
                 EccTestData.Sect163k1Key1,
-                SupportsSect163k1 && LimitedPrivateKeySupported);
+                SupportsSect163k1);
         }
 
         [Fact]
@@ -284,7 +280,7 @@ RVA9DXUNz5+yUlfGzgErHYGwRLaLCACU6+WAC34Kkyk=",
                     HashAlgorithmName.SHA256,
                     7),
                 EccTestData.Sect163k1Key1Explicit,
-                SupportsSect163k1 && LimitedPrivateKeySupported);
+                SupportsSect163k1);
         }
 
         [Fact]
@@ -295,7 +291,7 @@ RVA9DXUNz5+yUlfGzgErHYGwRLaLCACU6+WAC34Kkyk=",
 MDICAQEEJAC08a4ef9zUsOggU8CKkIhSsmIx5sAWcPzGw+osXT/tQO3wN6AHBgUr
 gQQAEA==",
                 EccTestData.Sect283k1Key1,
-                SupportsSect283k1 && LimitedPrivateKeySupported);
+                SupportsSect283k1);
         }
 
         [Fact]
@@ -309,7 +305,7 @@ yJQ13lJCBBUAyVF9BtUkDTz/OMdLILbNTW+d1NkDFQDSwPsVdghg3vHu9NaW5naH
 VhUXVAQrBAevaZiVRhA9eTKfzD10iA8zu+gDywHsIyEbWWat6h0/h/fqWEiu8LfK
 nwIVBAAAAAAAAAAAAAHmD8iCHMdNrq/BAgEC",
                 EccTestData.C2pnb163v1Key1Explicit,
-                SupportsC2pnb163v1 && LimitedPrivateKeySupported);
+                SupportsC2pnb163v1);
         }
 
         [Fact]
@@ -323,7 +319,7 @@ JA08/zjHSyC2zU1vndTZAxUA0sD7FXYIYN7x7vTWluZ2h1YVF1QEKwQHr2mYlUYQ
 PXkyn8w9dIgPM7voA8sB7CMhG1lmreodP4f36lhIrvC3yp8CFQQAAAAAAAAAAAAB
 5g/IghzHTa6vwQIBAgQcMBoCAQEEFQD00koUBxIvRFlnvh2TwAk6ZTZ5hg==",
                 EccTestData.C2pnb163v1Key1Explicit,
-                SupportsC2pnb163v1 && LimitedPrivateKeySupported);
+                SupportsC2pnb163v1);
         }
 
         [Fact]
@@ -344,7 +340,7 @@ AerBJbccwFJfDAXP+eW3qWtaMgulL0gUYZQ7FcXH+z5CAWwdarLOCDZGqvQFtZ16",
                     HashAlgorithmName.SHA256,
                     7),
                 EccTestData.C2pnb163v1Key1Explicit,
-                SupportsC2pnb163v1 && LimitedPrivateKeySupported);
+                SupportsC2pnb163v1);
         }
 
         [Fact]
@@ -355,7 +351,7 @@ AerBJbccwFJfDAXP+eW3qWtaMgulL0gUYZQ7FcXH+z5CAWwdarLOCDZGqvQFtZ16",
 MEICAQAwEAYHKoZIzj0CAQYFK4EEABAEKzApAgEBBCQAtPGuHn/c1LDoIFPAipCI
 UrJiMebAFnD8xsPqLF0/7UDt8Dc=",
                 EccTestData.Sect283k1Key1,
-                SupportsSect283k1 && LimitedPrivateKeySupported);
+                SupportsSect283k1);
         }
 
         [Fact]
@@ -373,7 +369,7 @@ vW82QOEXDhi1gO24nhx2gUeqVTHjhFq14blAu5l5",
                     HashAlgorithmName.SHA384,
                     4096),
                 EccTestData.Sect283k1Key1,
-                SupportsSect283k1 && LimitedPrivateKeySupported);
+                SupportsSect283k1);
         }
 
         [Fact]
@@ -382,7 +378,7 @@ vW82QOEXDhi1gO24nhx2gUeqVTHjhFq14blAu5l5",
             ReadWriteBase64ECPrivateKey(
                 "MCYCAQEEFQD00koUBxIvRFlnvh2TwAk6ZTZ5hqAKBggqhkjOPQMAAQ==",
                 EccTestData.C2pnb163v1Key1,
-                SupportsC2pnb163v1 && LimitedPrivateKeySupported);
+                SupportsC2pnb163v1);
         }
 
         [Fact]
@@ -393,7 +389,7 @@ vW82QOEXDhi1gO24nhx2gUeqVTHjhFq14blAu5l5",
 MDYCAQAwEwYHKoZIzj0CAQYIKoZIzj0DAAEEHDAaAgEBBBUA9NJKFAcSL0RZZ74d
 k8AJOmU2eYY=",
                 EccTestData.C2pnb163v1Key1,
-                SupportsC2pnb163v1 && LimitedPrivateKeySupported);
+                SupportsC2pnb163v1);
         }
 
         [Fact]
@@ -411,7 +407,7 @@ DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEKWBssmLHI618uBvF0PA4VoEQIDy
                     HashAlgorithmName.SHA512,
                     1024),
                 EccTestData.C2pnb163v1Key1,
-                SupportsC2pnb163v1 && LimitedPrivateKeySupported);
+                SupportsC2pnb163v1);
         }
     }
 }
index c0b6fb5..41718a9 100644 (file)
@@ -13,7 +13,6 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests
 #endif
         bool IsCurveValid(Oid oid);
         bool ExplicitCurvesSupported { get; }
-        bool LimitedPrivateKeySupported { get; }
     }
 
     public static partial class ECDiffieHellmanFactory
@@ -41,6 +40,5 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests
         }
 
         public static bool ExplicitCurvesSupported => s_provider.ExplicitCurvesSupported;
-        public static bool LimitedPrivateKeySupported => s_provider.LimitedPrivateKeySupported;
     }
 }
index 085305d..10ca458 100644 (file)
@@ -389,9 +389,6 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests
         [Fact]
         public static void ImportFromPrivateOnlyKey()
         {
-            if (!ECDiffieHellmanFactory.LimitedPrivateKeySupported)
-                return;
-
             byte[] expectedX = "00d45615ed5d37fde699610a62cd43ba76bedd8f85ed31005fe00d6450fbbd101291abd96d4945a8b57bc73b3fe9f4671105309ec9b6879d0551d930dac8ba45d255".HexToByteArray();
             byte[] expectedY = "01425332844e592b440c0027972ad1526431c06732df19cd46a242172d4dd67c2c8c99dfc22e49949a56cf90c6473635ce82f25b33682fb19bc33bd910ed8ce3a7fa".HexToByteArray();
 
index fe65d17..221ad59 100644 (file)
@@ -13,7 +13,6 @@ namespace System.Security.Cryptography.EcDsa.Tests
 #endif
         bool IsCurveValid(Oid oid);
         bool ExplicitCurvesSupported { get; }
-        bool LimitedPrivateKeySupported { get; }
     }
 
     public static partial class ECDsaFactory
@@ -41,6 +40,5 @@ namespace System.Security.Cryptography.EcDsa.Tests
         }
 
         public static bool ExplicitCurvesSupported => s_provider.ExplicitCurvesSupported;
-        public static bool LimitedPrivateKeySupported => s_provider.LimitedPrivateKeySupported;
     }
 }
index ee0eeef..7cecc27 100644 (file)
@@ -323,9 +323,6 @@ namespace System.Security.Cryptography.EcDsa.Tests
         [Fact]
         public static void ImportFromPrivateOnlyKey()
         {
-            if (!ECDsaFactory.LimitedPrivateKeySupported)
-                return;
-
             byte[] expectedX = "00d45615ed5d37fde699610a62cd43ba76bedd8f85ed31005fe00d6450fbbd101291abd96d4945a8b57bc73b3fe9f4671105309ec9b6879d0551d930dac8ba45d255".HexToByteArray();
             byte[] expectedY = "01425332844e592b440c0027972ad1526431c06732df19cd46a242172d4dd67c2c8c99dfc22e49949a56cf90c6473635ce82f25b33682fb19bc33bd910ed8ce3a7fa".HexToByteArray();
 
index 8788568..62cbc37 100644 (file)
     <value>The specified Oid is not valid. The Oid.FriendlyName or Oid.Value property must be set.</value>
   </data>
   <data name="Cryptography_InvalidCurveKeyParameters" xml:space="preserve">
-    <value>The specified key parameters are not valid. Q.X and Q.Y are required fields. Q.X, Q.Y must be the same length. If D is specified it must be the same length as Q.X and Q.Y for named curves or the same length as Order for explicit curves.</value>
+    <value>The specified key parameters are not valid. Q.X and Q.Y, or D, must be specified. Q.X, Q.Y must be the same length. If D is specified it must be the same length as Q.X and Q.Y if also specified for named curves or the same length as Order for explicit curves.</value>
   </data>
   <data name="Cryptography_InvalidDsaParameters_MissingFields" xml:space="preserve">
     <value>The specified DSA parameters are not valid; P, Q, G and Y are all required.</value>
index 063c4e0..21c3c50 100644 (file)
@@ -35,8 +35,6 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests
             }
         }
 
-        public bool LimitedPrivateKeySupported => !PlatformDetection.IsOSX;
-
         private static bool IsValueOrFriendlyNameValid(string friendlyNameOrValue)
         {
             if (string.IsNullOrEmpty(friendlyNameOrValue))
index 5849b8b..fdd5e11 100644 (file)
@@ -23,8 +23,6 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests
             }
         }
 
-        public bool LimitedPrivateKeySupported => true;
-
         private static bool NativeOidFriendlyNameExists(string oidFriendlyName)
         {
             if (string.IsNullOrEmpty(oidFriendlyName))
index 7983e72..db573a6 100644 (file)
@@ -35,8 +35,6 @@ namespace System.Security.Cryptography.EcDsa.Tests
             }
         }
 
-        public bool LimitedPrivateKeySupported => !PlatformDetection.IsOSX;
-
         private static bool IsValueOrFriendlyNameValid(string friendlyNameOrValue)
         {
             if (string.IsNullOrEmpty(friendlyNameOrValue))
index 6b82d2b..981da0d 100644 (file)
@@ -22,8 +22,6 @@ namespace System.Security.Cryptography.EcDsa.Tests
             }
         }
 
-        public bool LimitedPrivateKeySupported => true;
-
         private static bool NativeOidFriendlyNameExists(string oidFriendlyName)
         {
             if (string.IsNullOrEmpty(oidFriendlyName))
index 8cfd7a4..1942f26 100644 (file)
@@ -37,8 +37,6 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests
             }
         }
 
-        public bool LimitedPrivateKeySupported => true;
-
         private static bool NativeOidFriendlyNameExists(string oidFriendlyName)
         {
             if (string.IsNullOrEmpty(oidFriendlyName))
index 200c610..b0dc502 100644 (file)
@@ -37,8 +37,6 @@ namespace System.Security.Cryptography.EcDsa.Tests
             }
         }
 
-        public bool LimitedPrivateKeySupported => true;
-
         private static bool NativeOidFriendlyNameExists(string oidFriendlyName)
         {
             if (string.IsNullOrEmpty(oidFriendlyName))
index 8903cf8..44c7fcb 100644 (file)
@@ -26,7 +26,6 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests
         public bool IsCurveValid(Oid oid) => _ecdsaProvider.IsCurveValid(oid);
 
         public bool ExplicitCurvesSupported => _ecdsaProvider.ExplicitCurvesSupported;
-        public bool LimitedPrivateKeySupported => _ecdsaProvider.LimitedPrivateKeySupported;
     }
 
     public partial class ECDiffieHellmanFactory
index 3cb4095..a78cf83 100644 (file)
@@ -54,8 +54,6 @@ namespace System.Security.Cryptography.EcDsa.Tests
                 return true;
             }
         }
-
-        public bool LimitedPrivateKeySupported => true;
     }
 
     public partial class ECDsaFactory