Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corefx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Barton <jbarton@microsoft.com>2018-04-05 09:03:10 +0300
committerGitHub <noreply@github.com>2018-04-05 09:03:10 +0300
commit368511a8cc8e544b2fb750266f816e1bd5a0c39d (patch)
treebae6d822e957927243ee080d2efdbaa4735340bc
parent7d207e5ab6736f396bd00835efc2d7544a616049 (diff)
Throw the same exception for data too big and data too small in RSA Decrypt
A previous change brought the Cryptography_Padding_DecDataTooBig exception condition and message from .NET Framework to make sure that all platforms/providers were throwing in the same cases. That change left the "data too small" error up to the individual provider libraries. Windows reported NTE_BAD_DATA ("Bad data.") except for when it reported ERROR_INVALID_PARAMETER ("The parameter is incorrect.") macOS reported an AppleCryptographicException wrapping a CFError whose message had a CSSM error const complaining about the size. Linux (RSAOpenSsl) just tried the decryption and reported a padding failure, except for when the padding worked out and it returned... something. With this change all platforms will reject incorrectly sized data with a unified string. The data is now reported as not valid for the size of the key whether it was too big or too small, and now reports consistently across the different platforms and providers.
-rw-r--r--src/Common/src/System/Security/Cryptography/RSACng.EncryptDecrypt.cs10
-rw-r--r--src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs5
-rw-r--r--src/Common/src/System/Security/Cryptography/RSASecurityTransforms.cs20
-rw-r--r--src/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs53
-rw-r--r--src/System.Security.Cryptography.Algorithms/src/Resources/Strings.resx6
-rw-r--r--src/System.Security.Cryptography.Cng/src/Resources/Strings.resx6
-rw-r--r--src/System.Security.Cryptography.Csp/src/Resources/Strings.resx6
-rw-r--r--src/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs10
-rw-r--r--src/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs6
-rw-r--r--src/System.Security.Cryptography.OpenSsl/src/Resources/Strings.resx6
-rw-r--r--src/System.Security.Cryptography.X509Certificates/src/Resources/Strings.resx6
11 files changed, 91 insertions, 43 deletions
diff --git a/src/Common/src/System/Security/Cryptography/RSACng.EncryptDecrypt.cs b/src/Common/src/System/Security/Cryptography/RSACng.EncryptDecrypt.cs
index 2230f91430..75444d49da 100644
--- a/src/Common/src/System/Security/Cryptography/RSACng.EncryptDecrypt.cs
+++ b/src/Common/src/System/Security/Cryptography/RSACng.EncryptDecrypt.cs
@@ -52,10 +52,9 @@ namespace System.Security.Cryptography
int modulusSizeInBytes = RsaPaddingProcessor.BytesRequiredForBitCount(KeySize);
- if (!encrypt && data.Length > modulusSizeInBytes)
+ if (!encrypt && data.Length != modulusSizeInBytes)
{
- throw new CryptographicException(
- SR.Format(SR.Cryptography_Padding_DecDataTooBig, modulusSizeInBytes));
+ throw new CryptographicException(SR.Cryptography_RSA_DecryptWrongSize);
}
if (encrypt &&
@@ -141,10 +140,9 @@ namespace System.Security.Cryptography
int modulusSizeInBytes = RsaPaddingProcessor.BytesRequiredForBitCount(KeySize);
- if (!encrypt && data.Length > modulusSizeInBytes)
+ if (!encrypt && data.Length != modulusSizeInBytes)
{
- throw new CryptographicException(
- SR.Format(SR.Cryptography_Padding_DecDataTooBig, modulusSizeInBytes));
+ throw new CryptographicException(SR.Cryptography_RSA_DecryptWrongSize);
}
if (encrypt &&
diff --git a/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs b/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs
index 8ee05705ed..e3758e28cb 100644
--- a/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs
+++ b/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs
@@ -154,10 +154,9 @@ namespace System.Security.Cryptography
int rsaSize = Interop.Crypto.RsaSize(key);
- if (data.Length > rsaSize)
+ if (data.Length != rsaSize)
{
- throw new CryptographicException(
- SR.Format(SR.Cryptography_Padding_DecDataTooBig, rsaSize));
+ throw new CryptographicException(SR.Cryptography_RSA_DecryptWrongSize);
}
if (destination.Length < rsaSize)
diff --git a/src/Common/src/System/Security/Cryptography/RSASecurityTransforms.cs b/src/Common/src/System/Security/Cryptography/RSASecurityTransforms.cs
index 131b93fc86..761d2bd1e3 100644
--- a/src/Common/src/System/Security/Cryptography/RSASecurityTransforms.cs
+++ b/src/Common/src/System/Security/Cryptography/RSASecurityTransforms.cs
@@ -275,16 +275,15 @@ namespace System.Security.Cryptography
throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
}
- if (padding.Mode == RSAEncryptionPaddingMode.Pkcs1)
- {
- int modulusSizeInBytes = RsaPaddingProcessor.BytesRequiredForBitCount(KeySize);
+ int modulusSizeInBytes = RsaPaddingProcessor.BytesRequiredForBitCount(KeySize);
- if (data.Length > modulusSizeInBytes)
- {
- throw new CryptographicException(
- SR.Format(SR.Cryptography_Padding_DecDataTooBig, modulusSizeInBytes));
- }
+ if (data.Length != modulusSizeInBytes)
+ {
+ throw new CryptographicException(SR.Cryptography_RSA_DecryptWrongSize);
+ }
+ if (padding.Mode == RSAEncryptionPaddingMode.Pkcs1)
+ {
return Interop.AppleCrypto.RsaDecrypt(keys.PrivateKey, data, padding);
}
@@ -344,10 +343,9 @@ namespace System.Security.Cryptography
int modulusSizeInBytes = RsaPaddingProcessor.BytesRequiredForBitCount(KeySize);
- if (data.Length > modulusSizeInBytes)
+ if (data.Length != modulusSizeInBytes)
{
- throw new CryptographicException(
- SR.Format(SR.Cryptography_Padding_DecDataTooBig, modulusSizeInBytes));
+ throw new CryptographicException(SR.Cryptography_RSA_DecryptWrongSize);
}
if (padding.Mode == RSAEncryptionPaddingMode.Pkcs1 ||
diff --git a/src/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs b/src/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs
index 391d34e77b..513f28e177 100644
--- a/src/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs
+++ b/src/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs
@@ -467,6 +467,59 @@ namespace System.Security.Cryptography.Rsa.Tests
}
[Fact]
+ public void RsaDecryptPkcs1LeadingZero()
+ {
+ // The first search for an encrypted value with a leading 0x00 turned up one with
+ // two leading zeros. How fortuitous.
+ byte[] encrypted = (
+ "0000B81E93CB9BA2B096DAC80ADC0C053D15CAD79A09D3DC154E3E75E0F59AF0" +
+ "D0816C0946946A56FEAEDB951A49C3854966C01C47A9F54DE2A050C1625869FE" +
+ "02BAD7AA427C42FE79D31267AE8713504CBBBBFA28EED0DF3E9F5BFC12C8A701" +
+ "382E92BC50D7E9E9897AEBDDA8005B7906AE1ABAFFD30CF5A8733CAB7264445A" +
+ "333730EA31F5F9F120B4B59F689BA529E106DA78340678C3BA2CE46427375A84" +
+ "9E86950FC18BD1D6C33508596BAEF0D916F0E29D647C037022753B1E8E44ABCF" +
+ "0079CEFA8972F02D05C4204078BD9ADF98571CE5374AB94BF01918F0EA31A815" +
+ "59F065A4C3FA0DD0E3086530608CA54387F86F25ED77D46C7576376B64BE3C91").HexToByteArray();
+
+ using (RSA rsa = RSAFactory.Create(TestData.RSA2048Params))
+ {
+ byte[] decrypted = Decrypt(rsa, encrypted, RSAEncryptionPadding.Pkcs1);
+ Assert.Equal(TestData.HelloBytes, decrypted);
+ }
+ }
+
+ [Fact]
+ public void RsaDecryptPkcs1Deficient()
+ {
+ // This value is gibberish, but it happens to be true that if it is preceded
+ // with 0x00 it happens to pass a PKCS1 encryption padding sanity test with the
+ // RSA2048Params key.
+ //
+ // If instead of prepending a 0x00 one appended 0x4B, it would decrypt to "Hello".
+ byte[] encrypted = (
+ "7EF2A69BBCF5B29A19DF6698B8BAB5EC4D9DF1D8CAA27D7D1BF60D560DB7D79D" +
+ "020C85620657F2A32C872EE44DB604FAFFF792A886BEF2E142A2DB0379C5C57D" +
+ "D444D2065A7976A6163B4A0D51AEE421B099A8E8A823A917A6E55A4A8E660715" +
+ "B9AC53CF37392228B2F7042CCBDA14CA88314FD353EA70AA9899E88771B01C8E" +
+ "E0DE35BD342F43809670B056B35A0EB68D370E1489D51AA4780766739887DBC6" +
+ "A716FE05773803C43B5040BF29AB33C4567E8986B3C442A7CEFCF46D61E13E54" +
+ "85468C0FF3FDC804BDDE60E4310CC45F5196DC75F713581D934FB914661B6B69" +
+ "EC3CE2CF469D7CD8727B959B5593F8D38124B0947E7948252BF9A53763877F").HexToByteArray();
+
+ byte[] correctlyPadded = new byte[encrypted.Length + 1];
+ Buffer.BlockCopy(encrypted, 0, correctlyPadded, 1, encrypted.Length);
+
+ using (RSA rsa = RSAFactory.Create(TestData.RSA2048Params))
+ {
+ byte[] decrypted = Decrypt(rsa, correctlyPadded, RSAEncryptionPadding.Pkcs1);
+ Assert.NotNull(decrypted);
+
+ Assert.ThrowsAny<CryptographicException>(
+ () => rsa.Decrypt(encrypted, RSAEncryptionPadding.Pkcs1));
+ }
+ }
+
+ [Fact]
public void RsaDecryptPkcs1WrongDataLength()
{
using (RSA rsa = RSAFactory.Create(TestData.RSA2048Params))
diff --git a/src/System.Security.Cryptography.Algorithms/src/Resources/Strings.resx b/src/System.Security.Cryptography.Algorithms/src/Resources/Strings.resx
index 5025cb8b08..5d1ed666c3 100644
--- a/src/System.Security.Cryptography.Algorithms/src/Resources/Strings.resx
+++ b/src/System.Security.Cryptography.Algorithms/src/Resources/Strings.resx
@@ -214,9 +214,6 @@
<data name="Cryptography_OpenInvalidHandle" xml:space="preserve">
<value>Cannot open an invalid handle.</value>
</data>
- <data name="Cryptography_Padding_DecDataTooBig" xml:space="preserve">
- <value>The data to be decrypted exceeds the maximum for this modulus of {0} bytes.</value>
- </data>
<data name="Cryptography_PartialBlock" xml:space="preserve">
<value>The input data is not a complete block.</value>
</data>
@@ -235,6 +232,9 @@
<data name="Cryptography_Rijndael_BlockSize" xml:space="preserve">
<value>BlockSize must be 128 in this implementation.</value>
</data>
+ <data name="Cryptography_RSA_DecryptWrongSize" xml:space="preserve">
+ <value>The length of the data to decrypt is not valid for the size of this key.</value>
+ </data>
<data name="Cryptography_SignHash_WrongSize" xml:space="preserve">
<value>The provided hash value is not the expected size for the specified hash algorithm.</value>
</data>
diff --git a/src/System.Security.Cryptography.Cng/src/Resources/Strings.resx b/src/System.Security.Cryptography.Cng/src/Resources/Strings.resx
index 08873ff1f4..bb79d2225f 100644
--- a/src/System.Security.Cryptography.Cng/src/Resources/Strings.resx
+++ b/src/System.Security.Cryptography.Cng/src/Resources/Strings.resx
@@ -181,12 +181,12 @@
<data name="Cryptography_OAEP_Decryption_Failed" xml:space="preserve">
<value>Error occurred while decoding OAEP padding.</value>
</data>
- <data name="Cryptography_Padding_DecDataTooBig" xml:space="preserve">
- <value>The data to be decrypted exceeds the maximum for this modulus of {0} bytes.</value>
- </data>
<data name="Cryptography_PartialBlock" xml:space="preserve">
<value>The input data is not a complete block.</value>
</data>
+ <data name="Cryptography_RSA_DecryptWrongSize" xml:space="preserve">
+ <value>The length of the data to decrypt is not valid for the size of this key.</value>
+ </data>
<data name="Cryptography_SignHash_WrongSize" xml:space="preserve">
<value>The provided hash value is not the expected size for the specified hash algorithm.</value>
</data>
diff --git a/src/System.Security.Cryptography.Csp/src/Resources/Strings.resx b/src/System.Security.Cryptography.Csp/src/Resources/Strings.resx
index 21a1a56de9..125132c3fa 100644
--- a/src/System.Security.Cryptography.Csp/src/Resources/Strings.resx
+++ b/src/System.Security.Cryptography.Csp/src/Resources/Strings.resx
@@ -180,9 +180,6 @@
<data name="Cryptography_OpenInvalidHandle" xml:space="preserve">
<value>Cannot open an invalid handle.</value>
</data>
- <data name="Cryptography_Padding_DecDataTooBig" xml:space="preserve">
- <value>The data to be decrypted exceeds the maximum for this modulus of {0} bytes.</value>
- </data>
<data name="Cryptography_PartialBlock" xml:space="preserve">
<value>The input data is not a complete block.</value>
</data>
@@ -201,6 +198,9 @@
<data name="Cryptography_RC2_EKSKS2" xml:space="preserve">
<value>EffectiveKeySize must be the same as KeySize in this implementation.</value>
</data>
+ <data name="Cryptography_RSA_DecryptWrongSize" xml:space="preserve">
+ <value>The length of the data to decrypt is not valid for the size of this key.</value>
+ </data>
<data name="Cryptography_TransformBeyondEndOfBuffer" xml:space="preserve">
<value>Attempt to transform beyond end of buffer.</value>
</data>
diff --git a/src/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs b/src/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs
index 52b5bc68b3..46d1a3581c 100644
--- a/src/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs
+++ b/src/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs
@@ -41,9 +41,9 @@ namespace System.Security.Cryptography
if (rgb == null)
throw new ArgumentNullException(nameof(rgb));
- // size check -- must be at most the modulus size
- if (rgb.Length > (KeySize / 8))
- throw new CryptographicException(SR.Format(SR.Cryptography_Padding_DecDataTooBig, Convert.ToString(KeySize / 8)));
+ // size check -- must be exactly the modulus size
+ if (rgb.Length != (KeySize / 8))
+ throw new CryptographicException(SR.Cryptography_RSA_DecryptWrongSize);
return _impl.Decrypt(rgb, fOAEP ? RSAEncryptionPadding.OaepSHA1 : RSAEncryptionPadding.Pkcs1);
}
@@ -65,8 +65,8 @@ namespace System.Security.Cryptography
{
if (padding == null)
throw new ArgumentNullException(nameof(padding));
- if (data.Length > (KeySize / 8))
- throw new CryptographicException(SR.Format(SR.Cryptography_Padding_DecDataTooBig, Convert.ToString(KeySize / 8)));
+ if (data.Length != (KeySize / 8))
+ throw new CryptographicException(SR.Cryptography_RSA_DecryptWrongSize);
if (padding != RSAEncryptionPadding.Pkcs1 && padding != RSAEncryptionPadding.OaepSHA1)
throw PaddingModeNotSupported();
diff --git a/src/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs b/src/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs
index e1d75bd522..4d249b6a82 100644
--- a/src/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs
+++ b/src/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs
@@ -266,10 +266,10 @@ namespace System.Security.Cryptography
// Save the KeySize value to a local because it has non-trivial cost.
int keySize = KeySize;
- // size check -- must be at most the modulus size
- if (rgb.Length > (keySize / 8))
+ // size check -- must be exactly the modulus size
+ if (rgb.Length != (keySize / 8))
{
- throw new CryptographicException(SR.Format(SR.Cryptography_Padding_DecDataTooBig, Convert.ToString(keySize / 8)));
+ throw new CryptographicException(SR.Cryptography_RSA_DecryptWrongSize);
}
byte[] decryptedKey;
diff --git a/src/System.Security.Cryptography.OpenSsl/src/Resources/Strings.resx b/src/System.Security.Cryptography.OpenSsl/src/Resources/Strings.resx
index 9a34c36634..99aadc32f2 100644
--- a/src/System.Security.Cryptography.OpenSsl/src/Resources/Strings.resx
+++ b/src/System.Security.Cryptography.OpenSsl/src/Resources/Strings.resx
@@ -174,9 +174,6 @@
<data name="Cryptography_OpenInvalidHandle" xml:space="preserve">
<value>Cannot open an invalid handle.</value>
</data>
- <data name="Cryptography_Padding_DecDataTooBig" xml:space="preserve">
- <value>The data to be decrypted exceeds the maximum for this modulus of {0} bytes.</value>
- </data>
<data name="Cryptography_TlsRequires64ByteSeed" xml:space="preserve">
<value>The TLS key derivation function requires a seed value of exactly 64 bytes.</value>
</data>
@@ -192,6 +189,9 @@
<data name="Cryptography_OAEP_Decryption_Failed" xml:space="preserve">
<value>Error occurred while decoding OAEP padding.</value>
</data>
+ <data name="Cryptography_RSA_DecryptWrongSize" xml:space="preserve">
+ <value>The length of the data to decrypt is not valid for the size of this key.</value>
+ </data>
<data name="Cryptography_SignHash_WrongSize" xml:space="preserve">
<value>The provided hash value is not the expected size for the specified hash algorithm.</value>
</data>
diff --git a/src/System.Security.Cryptography.X509Certificates/src/Resources/Strings.resx b/src/System.Security.Cryptography.X509Certificates/src/Resources/Strings.resx
index 14b95dea57..749f88bb57 100644
--- a/src/System.Security.Cryptography.X509Certificates/src/Resources/Strings.resx
+++ b/src/System.Security.Cryptography.X509Certificates/src/Resources/Strings.resx
@@ -190,15 +190,15 @@
<data name="Cryptography_OpenInvalidHandle" xml:space="preserve">
<value>Cannot open an invalid handle.</value>
</data>
- <data name="Cryptography_Padding_DecDataTooBig" xml:space="preserve">
- <value>The data to be decrypted exceeds the maximum for this modulus of {0} bytes.</value>
- </data>
<data name="Cryptography_PrivateKey_DoesNotMatch" xml:space="preserve">
<value>The provided key does not match the public key for this certificate.</value>
</data>
<data name="Cryptography_PrivateKey_WrongAlgorithm" xml:space="preserve">
<value>The provided key does not match the public key algorithm for this certificate.</value>
</data>
+ <data name="Cryptography_RSA_DecryptWrongSize" xml:space="preserve">
+ <value>The length of the data to decrypt is not valid for the size of this key.</value>
+ </data>
<data name="Cryptography_SignHash_WrongSize" xml:space="preserve">
<value>The provided hash value is not the expected size for the specified hash algorithm.</value>
</data>