Fix incorrect IEEE conversion buffer size for ECDsaCmsSignature.
authorAlfred Rossi <alfredr@gmail.com>
Fri, 7 Sep 2018 15:18:30 +0000 (11:18 -0400)
committerJeremy Barton <jbarton@microsoft.com>
Fri, 7 Sep 2018 15:18:30 +0000 (08:18 -0700)
For EC curves with a keysize which is not a multiple of 8 the calculation under-allocated.

The most likely culprit is secp521r1.

Commit migrated from https://github.com/dotnet/corefx/commit/775c9f1415be3403864fe2804a9c5e16074d2d68

src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.ECDsa.cs
src/libraries/System.Security.Cryptography.Pkcs/tests/Certificates.cs
src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.netcoreapp.cs

index 8163701..fdce23c 100644 (file)
@@ -65,8 +65,13 @@ namespace System.Security.Cryptography.Pkcs
                     return false;
                 }
 
-                // 2 * KeySizeBytes => 2 * KeySizeBits / 8 => KeySizeBits / 4
-                int bufSize = key.KeySize / 4;
+                int bufSize;
+                checked
+                {
+                    // fieldSize = ceil(KeySizeBits / 8);
+                    int fieldSize = (key.KeySize + 7) / 8;
+                    bufSize = 2 * fieldSize;
+                }
 
 #if netcoreapp
                 ArrayPool<byte> pool = ArrayPool<byte>.Shared;
@@ -137,9 +142,16 @@ namespace System.Security.Cryptography.Pkcs
 
 #if netcoreapp
                 ArrayPool<byte> pool = ArrayPool<byte>.Shared;
-                // The signature size is twice the KeySize.
-                // 2 * KeySizeInBytes => 2 * KeySizeInBits / 8 => KeySizeInBits / 4
-                byte[] rented = pool.Rent(key.KeySize / 4);
+
+                int bufSize;
+                checked
+                {
+                    // fieldSize = ceil(KeySizeBits / 8);
+                    int fieldSize = (key.KeySize + 7) / 8;
+                    bufSize = 2 * fieldSize;
+                }
+
+                byte[] rented = pool.Rent(bufSize);
                 int bytesWritten = 0;
 
                 try
index 457c1ab..dc5b095 100644 (file)
@@ -20,6 +20,7 @@ namespace System.Security.Cryptography.Pkcs.Tests
         public static readonly CertLoader RSA2048SignatureOnly = new CertLoaderFromRawData(RawData.s_Rsa2048SignatureOnlyCer, RawData.s_Rsa2048SignatureOnlyPfx, "12345");
         public static readonly CertLoader Dsa1024 = new CertLoaderFromRawData(RawData.s_dsa1024Cert, RawData.s_dsa1024Pfx, "1234");
         public static readonly CertLoader ECDsaP256Win = new CertLoaderFromRawData(RawData.ECDsaP256_DigitalSignature_Cert, RawData.ECDsaP256_DigitalSignature_Pfx_Windows, "Test");
+        public static readonly CertLoader ECDsaP521Win = new CertLoaderFromRawData(RawData.ECDsaP521_DigitalSignature_Cert, RawData.ECDsaP521_DigitalSignature_Pfx_Windows, "Test");
         public static readonly CertLoader ValidLookingTsaCert = new CertLoaderFromRawData(RawData.ValidLookingTsaCert_Cer, RawData.ValidLookingTsaCert_Pfx, "export");
         public static readonly CertLoader TwoEkuTsaCert = new CertLoaderFromRawData(RawData.TwoEkuTsaCert, RawData.TwoEkuTsaPfx, "export");
         public static readonly CertLoader NonCriticalTsaEku = new CertLoaderFromRawData(RawData.NonCriticalTsaEkuCert, RawData.NonCriticalTsaEkuPfx, "export");
@@ -706,6 +707,76 @@ namespace System.Security.Cryptography.Pkcs.Tests
                 "4B6A4B231E8851926438C55B5DDE632E6ADF13C1023A65898E022100CBDF434F" +
                 "DD197D8B594E8026E44263BADE773C2BEBD060CC4109484A498E7C7E").HexToByteArray();
 
+            internal static readonly byte[] ECDsaP521_DigitalSignature_Pfx_Windows = (
+                "308205C10201033082057D06092A864886F70D010701A082056E0482056A3082" +
+                "05663082024706092A864886F70D010701A08202380482023430820230308202" +
+                "2C060B2A864886F70D010C0A0102A082013630820132301C060A2A864886F70D" +
+                "010C0103300E04089C795C574944FD6F020207D004820110C7F41C3C3314CCFC" +
+                "8A0CF90698179B7B6F1618C7BE905B09718023C302A98AFCD92C74CEFDBE9568" +
+                "6031510BEB8765918E07007F3C882B49BFBBDEFA4B9414B4A76E011A793DA489" +
+                "F5B21F9129CB81A4718A2690BE65BCBE3714DE62DEF4C792FFA52CCDE59FC48E" +
+                "5ABE03B9A34D342CE5B148FBA66CE699B9F2DDCF0475E31A1EE71543922EF65A" +
+                "3EACB69553ABE4316590D640F6DB58D7B8BF33B57EF2A35445CA6A553BF59B48" +
+                "F4D9A5B7E37AF448DCBFED3A2BD258A4BA3180A66D7508CA2037061517675135" +
+                "DB609B7DF7CB5F39874E66512C57F65DA93E3A43A12929B63FCACC82C5B8D638" +
+                "00713A83B04A6CEB47A3C79D9852AFF5DB58180B6CF8193E7194CF7F0B6EED2E" +
+                "A6697C42AC556C8C3181E2300D06092B06010401823711023100301306092A86" +
+                "4886F70D0109153106040401000000305D06092A864886F70D01091431501E4E" +
+                "00740065002D00650037003900350037003300640030002D0037003000390036" +
+                "002D0034006200300035002D0062003400330038002D00640036003000650032" +
+                "0030006600360030003100300034305D06092B060104018237110131501E4E00" +
+                "4D006900630072006F0073006F0066007400200053006F006600740077006100" +
+                "7200650020004B00650079002000530074006F00720061006700650020005000" +
+                "72006F007600690064006500723082031706092A864886F70D010706A0820308" +
+                "30820304020100308202FD06092A864886F70D010701301C060A2A864886F70D" +
+                "010C0103300E0408812C7B1E5FBB35DF020207D0808202D00AFB0F5D92F40AD4" +
+                "CCABAA4805775198F5988210F0601C39EA4A5B025A0FADB6A95C3ED3CB86E65C" +
+                "B13BA11216244BE2773705202CF5895D9E31E5FC208A9DD2D90B47495475A078" +
+                "B1B531AE496E4E534E4A23D828D2DC3488D982CB05FF9A32E7C60FCADEFA8EAB" +
+                "F01F1D29E0650DAC688F434C4D5D8A26C4D7AD339FD0A2C4E22785E07DEC2FB6" +
+                "7D041FA03BAE4BD6F3175EBB65EE79B276FECE8A8155A925792DA2F8AF2FAAF8" +
+                "75AC2207078643C6E3C3AFEF37FED0AA60BDB06C8C1908ACF8FA2BCD28BCC8D4" +
+                "47D998449108BA7A03E7AE6A439D7310E1A1A7296DBDFF48F7401E259ACE7B0A" +
+                "D7B77B06001B0D526278B109217A7FF14CBA143DBCA99604EB2067D1DE3FA94D" +
+                "D306D0937D9EF825E3B5B425F1F01A2153ECE2DFFF81779B7678626965F586DB" +
+                "B519633EE3CEBD9FB14F5CF88DF6E907176D79CC6A7B9754C5EA02AFB549C65B" +
+                "612866D48D294E44EC8A74CB36592F1C40C4B53640F5AE13F0A7A7AE731942CC" +
+                "5091C57EA07743373404698E347A10BF0433F495B69FE8077EC8971B8B322DA0" +
+                "82746883DE62FF08D3BE6D0575BCDAC392E79CC9B286953AE3B17D27C477B040" +
+                "63AC2BEA6AA74BE63456DA2DE4685E8195EF620F19FDA8943515A4BC2ECBAA2D" +
+                "16DF0237A9C272D6418F948715238EC5CA386E74E4AA67248A56A285F1FD2E17" +
+                "A5F0F09DD3448BA570A056DDC7FA275A42CC0D524911BFA8DB42BFA04588AE5B" +
+                "5044CABD353B9090F9F8CF02514C9AC0F347A9BE2A03EC351BAE2D1AC42CAC2B" +
+                "89C9ABF3600F41EDD4447CDD14192F85094FEFB95DBF260A6739276A279FD104" +
+                "E346A3FD238F7497474B1B4F8B7C02E4EECA34284C19D0AA169C178207BB1F19" +
+                "62CD5E0C8A2C7C55249628F0BFC575DF2ECB25D36E1B29631A612945B9A99070" +
+                "5FF55769B50D0B77725F61FE55284301A604C63BC7FC58F79CDF89F7E57ED060" +
+                "CDD855DF59E9A8C9A06EA0DFECA32DF2A5263D0BF72B9D485519AB87EA963D01" +
+                "9BF9F6B1D77ED4AA303B301F300706052B0E03021A0414AF6FEF9E53E1144A81" +
+                "53A9459AADF886BA2979990414AC82239C24D3BB89B37A6A6109D7B43ABC433D" +
+                "12020207D0").HexToByteArray();
+
+            internal static readonly byte[] ECDsaP521_DigitalSignature_Cert = (
+                "3082024D308201AEA00302010202101549950E8AA087A34C179BE49774C8AF30" +
+                "0A06082A8648CE3D040302301A3118301606035504030C0F4543445341205035" +
+                "32312054657374301E170D3138303930353130333230395A170D313930393035" +
+                "3130353230395A301A3118301606035504030C0F454344534120503532312054" +
+                "65737430819B301006072A8648CE3D020106052B810400230381860004019D99" +
+                "4545E2E70D4CD0901FFBADC7B6CCEED2DC4EE69624B7F0B5C3E81F7A8DEEAFFF" +
+                "BC317A3768D03F1582877D1D84FC69554B76DFFAA439929D94B6BE5CBA8CBA01" +
+                "ECB0CDCD730492414D10A00DCA812CEC46D6D92B9142297500C543652FE54A81" +
+                "427E18EC155EB05D3426A28F24819F5293F3FBC95A9CD7646D5D4D046753ECE0" +
+                "B9A3819230818F300E0603551D0F0101FF040403020388301D0603551D0E0416" +
+                "0414FFA852184A01C69680A052AF5BE279E949718DF6302E060A2B0601040182" +
+                "370A0B0B04204500430044005300410020005000350032003100200054006500" +
+                "730074000000302E060A2B0601040182370A0B0D042045004300440053004100" +
+                "20005000350032003100200054006500730074000000300A06082A8648CE3D04" +
+                "030203818C00308188024201D8EB229D9D73C8C6634E305836E938349672D12D" +
+                "73BFC5A87E2CD2985FF64EE44BB2800214E4839A2DBCEAA3F2342C269D74126A" +
+                "FE248C0C0F7C700B4680CA8F36024200F6625A58C219C389F2B4127BFDC228D8" +
+                "2765E2F9399DB66ED71EDF4D64F85998DE15ED82A75F363E42432BCE108CE55A" +
+                "41A9899160F95848826A9CE39498AEC2EF").HexToByteArray();
+
             internal static readonly byte[] ValidLookingTsaCert_Cer = (
                 "308204243082020CA003020102020401020304300D06092A864886F70D01010B" +
                 "05003029312730250603550403131E4578706572696D656E74616C2049737375" +
index 19a60f3..a526766 100644 (file)
@@ -91,6 +91,16 @@ namespace System.Security.Cryptography.Pkcs.Tests
         }
 
         [Fact]
+        public static void SignCmsUsingExplicitECDsaP521Key()
+        {
+            using (X509Certificate2 cert = Certificates.ECDsaP521Win.TryGetCertificateWithPrivateKey())
+            using (ECDsa key = cert.GetECDsaPrivateKey())
+            {
+                VerifyWithExplicitPrivateKey(cert, key);
+            }
+        }
+
+        [Fact]
         public static void CounterSignCmsUsingExplicitRSAKeyForFirstSignerAndDSAForCounterSignature()
         {
             using (X509Certificate2 cert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey())