This repository was archived by the owner on Jan 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Add crypto *Formatter classes and extend HashAlgorithm #11959
Merged
steveharter
merged 7 commits into
dotnet:master
from
steveharter:AddCryptoFormattersMaster
Oct 4, 2016
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
4e5ff50
Add crypto formatters
steveharter 54e4e14
Code review feedback
steveharter 6cdb948
fix comment
steveharter 139d4cf
Code review feedback
steveharter a845a14
Review feedback plus new crypto exception ctors
steveharter b4f6fc4
HashAlgorithm netfx compat refactor
steveharter 48f63a4
TransformFinalBlock assumes Initialize semantics
steveharter File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
.../tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSASignatureFormatter.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
| // See the LICENSE file in the project root for more information. | ||
|
|
||
| using System.Security.Cryptography.Tests; | ||
| using Xunit; | ||
|
|
||
| namespace System.Security.Cryptography.Dsa.Tests | ||
| { | ||
| public partial class DSASignatureFormatterTests : AsymmetricSignatureFormatterTests | ||
| { | ||
| [Fact] | ||
| public static void VerifySignature_SHA1() | ||
| { | ||
| using (DSA dsa = DSAFactory.Create()) | ||
| { | ||
| var formatter = new DSASignatureFormatter(dsa); | ||
| var deformatter = new DSASignatureDeformatter(dsa); | ||
| using (SHA1 alg = SHA1.Create()) | ||
| { | ||
| VerifySignature(formatter, deformatter, alg, "SHA1"); | ||
| VerifySignature(formatter, deformatter, alg, "sha1"); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void InvalidHashAlgorithm() | ||
| { | ||
| using (DSA dsa = DSAFactory.Create()) | ||
| { | ||
| var formatter = new DSASignatureFormatter(dsa); | ||
| var deformatter = new DSASignatureDeformatter(dsa); | ||
|
|
||
| // Unlike RSA, DSA will throw during SetHashAlgorithm | ||
| Assert.Throws<CryptographicUnexpectedOperationException>(() => | ||
| formatter.SetHashAlgorithm("INVALIDVALUE")); | ||
| Assert.Throws<CryptographicUnexpectedOperationException>(() => | ||
| deformatter.SetHashAlgorithm("INVALIDVALUE")); | ||
|
|
||
| // Currently anything other than SHA1 fails | ||
| Assert.Throws<CryptographicUnexpectedOperationException>(() => | ||
| formatter.SetHashAlgorithm("SHA256")); | ||
| Assert.Throws<CryptographicUnexpectedOperationException>(() => | ||
| deformatter.SetHashAlgorithm("SHA256")); | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void VerifyKnownSignature() | ||
| { | ||
| using (DSA dsa = DSAFactory.Create()) | ||
| { | ||
| byte[] data; | ||
| byte[] signature; | ||
| DSAParameters dsaParameters; | ||
| DSATestData.GetDSA1024_186_2(out dsaParameters, out signature, out data); | ||
|
|
||
| byte[] hash; | ||
| using (SHA1 alg = SHA1.Create()) | ||
| { | ||
| hash = alg.ComputeHash(data); | ||
| } | ||
|
|
||
| dsa.ImportParameters(dsaParameters); | ||
| var deformatter = new DSASignatureDeformatter(dsa); | ||
| deformatter.VerifySignature(hash, signature); | ||
|
|
||
| // Negative case | ||
| signature[signature.Length - 1] ^= 0xff; | ||
| Assert.False(deformatter.VerifySignature(hash, signature)); | ||
| } | ||
| } | ||
|
|
||
| public static bool SupportsFips186_3 | ||
| { | ||
| get | ||
| { | ||
| return DSAFactory.SupportsFips186_3; | ||
| } | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -67,5 +67,33 @@ internal static DSAParameters GetDSA2048Params() | |
| "081025751572").HexToByteArray(); | ||
| return p; | ||
| } | ||
|
|
||
| // The parameters and signature come from FIPS 186-2 APPENDIX 5. EXAMPLE OF THE DSA | ||
| internal static void GetDSA1024_186_2(out DSAParameters parameters, out byte[] signature, out byte[] data) | ||
| { | ||
| parameters = new DSAParameters() | ||
| { | ||
| P = ( | ||
| "8df2a494492276aa3d25759bb06869cbeac0d83afb8d0cf7cbb8324f0d7882e5d0762fc5b7210eafc2e9adac32ab7aac" + | ||
| "49693dfbf83724c2ec0736ee31c80291").HexToByteArray(), | ||
| Q = ("c773218c737ec8ee993b4f2ded30f48edace915f").HexToByteArray(), | ||
| G = ( | ||
| "626d027839ea0a13413163a55b4cb500299d5522956cefcb3bff10f399ce2c2e71cb9de5fa24babf58e5b79521925c9c" + | ||
| "c42e9f6f464b088cc572af53e6d78802").HexToByteArray(), | ||
| X = ("2070b3223dba372fde1c0ffc7b2e3b498b260614").HexToByteArray(), | ||
| Y = ( | ||
| "19131871d75b1612a819f29d78d1b0d7346f7aa77bb62a859bfd6c5675da9d212d3a36ef1672ef660b8c7c255cc0ec74" + | ||
| "858fba33f44c06699630a76b030ee333").HexToByteArray() | ||
| }; | ||
|
|
||
| signature = ( | ||
| // r | ||
| "8bac1ab66410435cb7181f95b16ab97c92b341c0" + | ||
| // s | ||
| "41e2345f1f56df2458f426d155b4ba2db6dcd8c8" | ||
| ).HexToByteArray(); | ||
|
|
||
| data = Encoding.ASCII.GetBytes("abc"); | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These three methods feel like they should be one method returning three values. It's pretty clunky this way.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The original intent was that the three parts could be used independently (i.e. not always all 3 would be used in a given test), but since that is not the case I can combine |
||
| } | ||
| } | ||
79 changes: 79 additions & 0 deletions
79
...ests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyExchangeFormatter.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
| // See the LICENSE file in the project root for more information. | ||
|
|
||
| using System.Security.Cryptography.Tests; | ||
| using Test.Cryptography; | ||
| using Xunit; | ||
|
|
||
| namespace System.Security.Cryptography.Rsa.Tests | ||
| { | ||
| public partial class RSAKeyExchangeFormatterTests | ||
| { | ||
| [Fact] | ||
| public static void VerifyDecryptKeyExchangeOaep() | ||
| { | ||
| using (RSA rsa = RSAFactory.Create()) | ||
| { | ||
| var formatter = new RSAOAEPKeyExchangeFormatter(rsa); | ||
| var deformatter = new RSAOAEPKeyExchangeDeformatter(rsa); | ||
| VerifyDecryptKeyExchange(formatter, deformatter); | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void VerifyDecryptKeyExchangePkcs1() | ||
| { | ||
| using (RSA rsa = RSAFactory.Create()) | ||
| { | ||
| var formatter = new RSAPKCS1KeyExchangeFormatter(rsa); | ||
| var deformatter = new RSAPKCS1KeyExchangeDeformatter(rsa); | ||
| VerifyDecryptKeyExchange(formatter, deformatter); | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void TestKnownValueOaep() | ||
| { | ||
| using (RSA rsa = RSAFactory.Create()) | ||
| { | ||
| rsa.ImportParameters(TestData.RSA1024Params); | ||
| byte[] encrypted = | ||
| ( "19134ffba4025a1c651120ca07258a46e005a327c3927f615465060734dc0339114cabfd13803288883abf9329296a3e3a5cb1587927" | ||
| + "a6e8a2e736f0a756e342b4adb0f1de5bba9ba5faee30456fb7409678eb71a70185606eda3303d9425fbeb730ab7803bea50e208b563f" | ||
| + "e9bfa97a8966deefb211a3bd6abe08cd15e0b927").HexToByteArray(); | ||
| RSAOAEPKeyExchangeDeformatter deformatter = new RSAOAEPKeyExchangeDeformatter(rsa); | ||
| byte[] plain = deformatter.DecryptKeyExchange(encrypted); | ||
| byte[] expectedPlain = { 0x41, 0x42, 0x43 }; | ||
| Assert.Equal(expectedPlain, plain); | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void TestKnownValuePkcs1() | ||
| { | ||
| using (RSA rsa = RSAFactory.Create()) | ||
| { | ||
| rsa.ImportParameters(TestData.RSA1024Params); | ||
| byte[] encrypted = | ||
| ( "7061adb87a8759f0a0dc6ece42f5b63bf186f845237c6b16bf824b303812486efbb8f5febb681902228a609d4330a6c21abf0fc0d271" | ||
| + "ba63d1d0d9e486668270c2dbf73ab33055dfc0b797938557b99c0e9a535605c0a4bceefe5a37594732bb566ab026e4e8d5ce47d0967d" | ||
| + "f1c66e7ee4d39d804f6d558670222d708f943eb0").HexToByteArray(); | ||
| RSAPKCS1KeyExchangeDeformatter deformatter = new RSAPKCS1KeyExchangeDeformatter(rsa); | ||
| byte[] plain = deformatter.DecryptKeyExchange(encrypted); | ||
| byte[] expectedPlain = { 0x41, 0x42, 0x43 }; | ||
| Assert.Equal(expectedPlain, plain); | ||
| } | ||
| } | ||
|
|
||
| private static void VerifyDecryptKeyExchange(AsymmetricKeyExchangeFormatter formatter, AsymmetricKeyExchangeDeformatter deformatter) | ||
| { | ||
| byte[] encrypted = formatter.CreateKeyExchange(TestData.HelloBytes); | ||
| byte[] decrypted = deformatter.DecryptKeyExchange(encrypted); | ||
| Assert.Equal(TestData.HelloBytes, decrypted); | ||
|
|
||
| encrypted[encrypted.Length - 1] ^= 0xff; | ||
| Assert.ThrowsAny<CryptographicException>(() => deformatter.DecryptKeyExchange(encrypted)); | ||
| } | ||
| } | ||
| } |
99 changes: 99 additions & 0 deletions
99
.../tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSASignatureFormatter.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
| // See the LICENSE file in the project root for more information. | ||
|
|
||
| using System.Security.Cryptography.Tests; | ||
| using Test.Cryptography; | ||
| using Xunit; | ||
|
|
||
| namespace System.Security.Cryptography.Rsa.Tests | ||
| { | ||
| public partial class RSASignatureFormatterTests : AsymmetricSignatureFormatterTests | ||
| { | ||
| [Fact] | ||
| public static void VerifySignature_SHA1() | ||
| { | ||
| using (RSA rsa = RSAFactory.Create()) | ||
| { | ||
| var formatter = new RSAPKCS1SignatureFormatter(rsa); | ||
| var deformatter = new RSAPKCS1SignatureDeformatter(rsa); | ||
|
|
||
| using (SHA1 alg = SHA1.Create()) | ||
| { | ||
| VerifySignature(formatter, deformatter, alg, "SHA1"); | ||
| VerifySignature(formatter, deformatter, alg, "sha1"); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void VerifySignature_SHA256() | ||
| { | ||
| using (RSA rsa = RSAFactory.Create()) | ||
| { | ||
| var formatter = new RSAPKCS1SignatureFormatter(rsa); | ||
| var deformatter = new RSAPKCS1SignatureDeformatter(rsa); | ||
|
|
||
| using (SHA256 alg = SHA256.Create()) | ||
| { | ||
| VerifySignature(formatter, deformatter, alg, "SHA256"); | ||
| VerifySignature(formatter, deformatter, alg, "sha256"); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void InvalidHashAlgorithm() | ||
| { | ||
| using (RSA rsa = RSAFactory.Create()) | ||
| { | ||
| var formatter = new RSAPKCS1SignatureFormatter(rsa); | ||
| var deformatter = new RSAPKCS1SignatureDeformatter(rsa); | ||
|
|
||
| // Exception is deferred until VerifySignature | ||
| formatter.SetHashAlgorithm("INVALIDVALUE"); | ||
| deformatter.SetHashAlgorithm("INVALIDVALUE"); | ||
|
|
||
| using (SHA1 alg = SHA1.Create()) | ||
| { | ||
| Assert.Throws<CryptographicUnexpectedOperationException>(() => | ||
| VerifySignature(formatter, deformatter, alg, "INVALIDVALUE")); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void VerifyKnownSignature() | ||
| { | ||
| byte[] hash = "012d161304fa0c6321221516415813022320620c".HexToByteArray(); | ||
| byte[] sig; | ||
|
|
||
| using (RSA key = RSAFactory.Create()) | ||
| { | ||
| key.ImportParameters(TestData.RSA1024Params); | ||
| RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key); | ||
| formatter.SetHashAlgorithm("SHA1"); | ||
| sig = formatter.CreateSignature(hash); | ||
|
|
||
| byte[] expectedSig = | ||
| ("566390012605b1c4c01c3c2f91ce27d19476ab7131d9ee9cd1b811afb2be02ab6b498b862f0b2368ed6b09ccc9e0ec0d4f97a4f318f4f11" + | ||
| "ae882a1131012dc35d2e0b810a38e05da71d291e88b306605c9d34815091641370bd7db7a87b115bd427fcb9993bc5ba2bd518745aef80c" + | ||
| "a4557cfa1d827ff1610595d8eeb4c15073").HexToByteArray(); | ||
| Assert.Equal(expectedSig, sig); | ||
| } | ||
|
|
||
| using (RSA key = RSAFactory.Create()) // Test against a different instance | ||
| { | ||
| key.ImportParameters(TestData.RSA1024Params); | ||
| RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key); | ||
| deformatter.SetHashAlgorithm("SHA1"); | ||
| bool verified = deformatter.VerifySignature(hash, sig); | ||
| Assert.True(verified); | ||
|
|
||
| sig[3] ^= 0xff; | ||
| verified = deformatter.VerifySignature(hash, sig); | ||
| Assert.False(verified); | ||
| } | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RSA has a known value test for PKCS#1, why doesn't DSA have a known value test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a test for a known signature although not sure how valuable that is w.r.t. RSA PKCS tests because those validate a given hash will create the same signature each time which isn't true in DSA (not deterministic)