Skip to content

Commit 5ec483c

Browse files
authored
S.S.C.Cose: Remove ECDsa and RSA overloads in favor of AsymmetricAlgorithm (#67661)
* Remove ECDsa and RSA overloads in favor of AsymmetricAlgorithm * GenAPI changes * Assert parameter names * Keep _dummy and _dummyPrimitive dotnet/arcade#8792 (comment)
1 parent 708171d commit 5ec483c

File tree

5 files changed

+89
-32
lines changed

5 files changed

+89
-32
lines changed

src/libraries/System.Security.Cryptography.Cose/ref/System.Security.Cryptography.Cose.cs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ namespace System.Security.Cryptography.Cose
88
{
99
public readonly partial struct CoseHeaderLabel : System.IEquatable<System.Security.Cryptography.Cose.CoseHeaderLabel>
1010
{
11+
private readonly object _dummy;
12+
private readonly int _dummyPrimitive;
1113
public CoseHeaderLabel(int label) { throw null; }
1214
public CoseHeaderLabel(string label) { throw null; }
1315
public static System.Security.Cryptography.Cose.CoseHeaderLabel Algorithm { get { throw null; } }
@@ -42,6 +44,8 @@ public void SetValue(System.Security.Cryptography.Cose.CoseHeaderLabel label, st
4244
public bool TryGetEncodedValue(System.Security.Cryptography.Cose.CoseHeaderLabel label, out System.ReadOnlyMemory<byte> encodedValue) { throw null; }
4345
public partial struct Enumerator : System.Collections.Generic.IEnumerator<(System.Security.Cryptography.Cose.CoseHeaderLabel Label, System.ReadOnlyMemory<byte> EncodedValue)>, System.Collections.IEnumerator, System.IDisposable
4446
{
47+
private object _dummy;
48+
private int _dummyPrimitive;
4549
public readonly (System.Security.Cryptography.Cose.CoseHeaderLabel Label, System.ReadOnlyMemory<byte> EncodedValue) Current { get { throw null; } }
4650
object System.Collections.IEnumerator.Current { get { throw null; } }
4751
public void Dispose() { }
@@ -56,28 +60,22 @@ internal CoseMessage() { }
5660
public System.Security.Cryptography.Cose.CoseHeaderMap ProtectedHeaders { get { throw null; } }
5761
public System.Security.Cryptography.Cose.CoseHeaderMap UnprotectedHeaders { get { throw null; } }
5862
public static System.Security.Cryptography.Cose.CoseSign1Message DecodeSign1(byte[] cborPayload) { throw null; }
59-
public static System.Security.Cryptography.Cose.CoseSign1Message DecodeSign1(ReadOnlySpan<byte> cborPayload) { throw null; }
63+
public static System.Security.Cryptography.Cose.CoseSign1Message DecodeSign1(System.ReadOnlySpan<byte> cborPayload) { throw null; }
6064
}
6165
public sealed partial class CoseSign1Message : System.Security.Cryptography.Cose.CoseMessage
6266
{
6367
internal CoseSign1Message() { }
6468
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
65-
public static byte[] Sign(ReadOnlySpan<byte> content, System.Security.Cryptography.AsymmetricAlgorithm key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.Cose.CoseHeaderMap? protectedHeaders = null, System.Security.Cryptography.Cose.CoseHeaderMap? unprotectedHeaders = null, bool isDetached = false) { throw null; }
66-
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
6769
public static byte[] Sign(byte[] content, System.Security.Cryptography.AsymmetricAlgorithm key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.Cose.CoseHeaderMap? protectedHeaders = null, System.Security.Cryptography.Cose.CoseHeaderMap? unprotectedHeaders = null, bool isDetached = false) { throw null; }
6870
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
69-
public static byte[] Sign(byte[] content, System.Security.Cryptography.ECDsa key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, bool isDetached = false) { throw null; }
70-
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
71-
public static byte[] Sign(byte[] content, System.Security.Cryptography.RSA key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, bool isDetached = false) { throw null; }
72-
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
73-
public static bool TrySign(ReadOnlySpan<byte> content, Span<byte> destination, System.Security.Cryptography.AsymmetricAlgorithm key!!, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, out int bytesWritten, System.Security.Cryptography.Cose.CoseHeaderMap? protectedHeaders = null, System.Security.Cryptography.Cose.CoseHeaderMap? unprotectedHeaders = null, bool isDetached = false) { throw null; }
71+
public static byte[] Sign(System.ReadOnlySpan<byte> content, System.Security.Cryptography.AsymmetricAlgorithm key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.Cose.CoseHeaderMap? protectedHeaders = null, System.Security.Cryptography.Cose.CoseHeaderMap? unprotectedHeaders = null, bool isDetached = false) { throw null; }
7472
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
75-
public bool Verify(System.Security.Cryptography.ECDsa key) { throw null; }
73+
public static bool TrySign(System.ReadOnlySpan<byte> content, System.Span<byte> destination, System.Security.Cryptography.AsymmetricAlgorithm key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, out int bytesWritten, System.Security.Cryptography.Cose.CoseHeaderMap? protectedHeaders = null, System.Security.Cryptography.Cose.CoseHeaderMap? unprotectedHeaders = null, bool isDetached = false) { throw null; }
7674
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
77-
public bool Verify(System.Security.Cryptography.ECDsa key, System.ReadOnlySpan<byte> content) { throw null; }
75+
public bool Verify(System.Security.Cryptography.AsymmetricAlgorithm key) { throw null; }
7876
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
79-
public bool Verify(System.Security.Cryptography.RSA key) { throw null; }
77+
public bool Verify(System.Security.Cryptography.AsymmetricAlgorithm key, byte[] content) { throw null; }
8078
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
81-
public bool Verify(System.Security.Cryptography.RSA key, System.ReadOnlySpan<byte> content) { throw null; }
79+
public bool Verify(System.Security.Cryptography.AsymmetricAlgorithm key, System.ReadOnlySpan<byte> content) { throw null; }
8280
}
8381
}

src/libraries/System.Security.Cryptography.Cose/src/Resources/Strings.resx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,12 @@
168168
<data name="Sign1SignUnsupportedHashAlgorithm" xml:space="preserve">
169169
<value>Unsuppoerted hash algorithm '{0}'.</value>
170170
</data>
171-
<data name="Sign1SignUnsupportedKey" xml:space="preserve">
172-
<value>Unsupported key '{0}'.</value>
173-
</data>
174171
<data name="Sign1UnknownCoseAlgorithm" xml:space="preserve">
175172
<value>COSE algorithm '{0}' is unknown.</value>
176173
</data>
174+
<data name="Sign1UnsupportedKey" xml:space="preserve">
175+
<value>Unsupported key '{0}'.</value>
176+
</data>
177177
<data name="Sign1VerifyAlgHeaderWasIncorrect" xml:space="preserve">
178178
<value>Algorithm header CBOR type was incorrect, expected int or tstr.</value>
179179
</data>

src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseSign1Message.cs

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,6 @@ public sealed class CoseSign1Message : CoseMessage
1717
internal CoseSign1Message(CoseHeaderMap protectedHeader, CoseHeaderMap unprotectedHeader, byte[]? content, byte[] signature, byte[] protectedHeaderAsBstr)
1818
: base(protectedHeader, unprotectedHeader, content, signature, protectedHeaderAsBstr) { }
1919

20-
[UnsupportedOSPlatform("browser")]
21-
public static byte[] Sign(byte[] content!!, ECDsa key!!, HashAlgorithmName hashAlgorithm, bool isDetached = false)
22-
=> SignCore(content.AsSpan(), key, hashAlgorithm, KeyType.ECDsa, null, null, isDetached);
23-
24-
[UnsupportedOSPlatform("browser")]
25-
public static byte[] Sign(byte[] content!!, RSA key!!, HashAlgorithmName hashAlgorithm, bool isDetached = false)
26-
=> SignCore(content.AsSpan(), key, hashAlgorithm, KeyType.RSA, null, null, isDetached);
27-
2820
[UnsupportedOSPlatform("browser")]
2921
public static byte[] Sign(byte[] content!!, AsymmetricAlgorithm key!!, HashAlgorithmName hashAlgorithm, CoseHeaderMap? protectedHeaders = null, CoseHeaderMap? unprotectedHeaders = null, bool isDetached = false)
3022
=> SignCore(content.AsSpan(), key, hashAlgorithm, GetKeyType(key), protectedHeaders, unprotectedHeaders, isDetached);
@@ -80,7 +72,7 @@ internal static KeyType GetKeyType(AsymmetricAlgorithm key)
8072
{
8173
ECDsa => KeyType.ECDsa,
8274
RSA => KeyType.RSA,
83-
_ => throw new CryptographicException(SR.Format(SR.Sign1SignUnsupportedKey, key.GetType()))
75+
_ => throw new CryptographicException(SR.Format(SR.Sign1UnsupportedKey, key.GetType()))
8476
};
8577
}
8678

@@ -197,16 +189,54 @@ private static int SignWithRSA(RSA key, ReadOnlySpan<byte> data, HashAlgorithmNa
197189
}
198190

199191
[UnsupportedOSPlatform("browser")]
200-
public bool Verify(ECDsa key) => VerifyECDsa(key, _content ?? throw new CryptographicException(SR.Sign1VerifyContentWasDetached));
192+
public bool Verify(AsymmetricAlgorithm key!!)
193+
{
194+
if (_content == null)
195+
{
196+
throw new CryptographicException(SR.Sign1VerifyContentWasDetached);
197+
}
198+
199+
return VerifyCore(key, _content);
200+
}
201201

202202
[UnsupportedOSPlatform("browser")]
203-
public bool Verify(RSA key) => VerifyRSA(key, _content ?? throw new CryptographicException(SR.Sign1VerifyContentWasDetached));
203+
public bool Verify(AsymmetricAlgorithm key!!, byte[] content!!)
204+
{
205+
if (_content != null)
206+
{
207+
throw new CryptographicException(SR.Sign1VerifyContentWasEmbedded);
208+
}
209+
210+
return VerifyCore(key, content);
211+
}
204212

205213
[UnsupportedOSPlatform("browser")]
206-
public bool Verify(ECDsa key, ReadOnlySpan<byte> content) => VerifyECDsa(key, _content == null ? content : throw new CryptographicException(SR.Sign1VerifyContentWasEmbedded));
214+
public bool Verify(AsymmetricAlgorithm key, ReadOnlySpan<byte> content)
215+
{
216+
if (_content != null)
217+
{
218+
throw new CryptographicException(SR.Sign1VerifyContentWasEmbedded);
219+
}
220+
221+
return VerifyCore(key, content);
222+
}
207223

208224
[UnsupportedOSPlatform("browser")]
209-
public bool Verify(RSA key, ReadOnlySpan<byte> content) => VerifyRSA(key, _content == null ? content : throw new CryptographicException(SR.Sign1VerifyContentWasEmbedded));
225+
private bool VerifyCore(AsymmetricAlgorithm key, ReadOnlySpan<byte> content)
226+
{
227+
if (key is ECDsa ecdsa)
228+
{
229+
return VerifyECDsa(ecdsa, content);
230+
}
231+
else if (key is RSA rsa)
232+
{
233+
return VerifyRSA(rsa, content);
234+
}
235+
else
236+
{
237+
throw new CryptographicException(SR.Format(SR.Sign1UnsupportedKey, key.GetType()));
238+
}
239+
}
210240

211241
[UnsupportedOSPlatform("browser")]
212242
private bool VerifyECDsa(ECDsa key, ReadOnlySpan<byte> content)

src/libraries/System.Security.Cryptography.Cose/tests/CoseSign1MessageTests.Sign.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public void SignVerify()
4646
[Fact]
4747
public void SignWithNullContent()
4848
{
49-
Assert.Throws<ArgumentNullException>(() => Sign(null!, DefaultKey, DefaultHash));
49+
Assert.Throws<ArgumentNullException>("content", () => Sign(null!, DefaultKey, DefaultHash));
5050
}
5151

5252
[Theory]
@@ -63,7 +63,7 @@ public void SignWithValidContent(ContentTestCase @case)
6363
[Fact]
6464
public void SignWithNullKey()
6565
{
66-
Assert.Throws<ArgumentNullException>(() => Sign(s_sampleContent, null!, DefaultHash));
66+
Assert.Throws<ArgumentNullException>("key", () => Sign(s_sampleContent, null!, DefaultHash));
6767
}
6868

6969
[Fact]
@@ -101,7 +101,7 @@ public class CoseSign1MessageTests_Sign_ECDsa : CoseSign1MessageTests_Sign<ECDsa
101101
internal override List<CoseAlgorithm> CoseAlgorithms => new() { CoseAlgorithm.ES256, CoseAlgorithm.ES384, CoseAlgorithm.ES512 };
102102

103103
internal override byte[] Sign(byte[] content, ECDsa key, HashAlgorithmName hashAlgorithm, bool isDetached = false)
104-
=> CoseSign1Message.Sign(content, key, hashAlgorithm, isDetached);
104+
=> CoseSign1Message.Sign(content, key, hashAlgorithm, isDetached: isDetached);
105105
internal override bool Verify(CoseSign1Message msg, ECDsa key)
106106
=> msg.Verify(key);
107107
internal override bool Verify(CoseSign1Message msg, ECDsa key, ReadOnlySpan<byte> content)
@@ -113,7 +113,7 @@ public class CoseSign1MessageTests_Sign_RSA : CoseSign1MessageTests_Sign<RSA>
113113
internal override List<CoseAlgorithm> CoseAlgorithms => new() { CoseAlgorithm.PS256, CoseAlgorithm.PS384, CoseAlgorithm.PS512 };
114114

115115
internal override byte[] Sign(byte[] content, RSA key, HashAlgorithmName hashAlgorithm, bool isDetached = false)
116-
=> CoseSign1Message.Sign(content, key, hashAlgorithm, isDetached);
116+
=> CoseSign1Message.Sign(content, key, hashAlgorithm, isDetached: isDetached);
117117
internal override bool Verify(CoseSign1Message msg, RSA key)
118118
=> msg.Verify(key);
119119
internal override bool Verify(CoseSign1Message msg, RSA key, ReadOnlySpan<byte> content)

src/libraries/System.Security.Cryptography.Cose/tests/CoseSign1MessageTests.Verify.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,35 @@ public void VerifyReturnsFalseAfterAttemptWithCorrectContent()
116116
Assert.False(msg.Verify(DefaultKey, wrongContent), "Calling Verify with the wrong content");
117117
}
118118

119+
[Fact]
120+
public void VerifyThrowsIfContentIsNull()
121+
{
122+
byte[] encodedMsg = CoseSign1Message.Sign(s_sampleContent, DefaultKey, DefaultHash);
123+
CoseSign1Message msg = CoseMessage.DecodeSign1(encodedMsg);
124+
125+
Assert.Throws<ArgumentNullException>("content", () => msg.Verify(DefaultKey, null!));
126+
}
127+
128+
[Fact]
129+
public void VerifyThrowsIfKeyIsNull()
130+
{
131+
byte[] encodedMsg = CoseSign1Message.Sign(s_sampleContent, DefaultKey, DefaultHash);
132+
CoseSign1Message msg = CoseMessage.DecodeSign1(encodedMsg);
133+
134+
Assert.Throws<ArgumentNullException>("key", () => msg.Verify(null!));
135+
Assert.Throws<ArgumentNullException>("key", () => msg.Verify(null!, s_sampleContent));
136+
}
137+
138+
[Fact]
139+
public void VerifyThrowsIfKeyIsNotSupported()
140+
{
141+
byte[] encodedMsg = CoseSign1Message.Sign(s_sampleContent, DefaultKey, DefaultHash);
142+
CoseSign1Message msg = CoseMessage.DecodeSign1(encodedMsg);
143+
144+
AsymmetricAlgorithm key = ECDiffieHellman.Create();
145+
Assert.Throws<CryptographicException>(() => msg.Verify(key));
146+
}
147+
119148
[Theory]
120149
// https://github.com/cose-wg/Examples/blob/master/sign1-tests/sign-fail-03.json
121150
[InlineData("D28445A1013903E6A10442313154546869732069732074686520636F6E74656E742E58408EB33E4CA31D1C465AB05AAC34CC6B23D58FEF5C083106C4D25A91AEF0B0117E2AF9A291AA32E14AB834DC56ED2A223444547E01F11D3B0916E5A4C345CACB36")]

0 commit comments

Comments
 (0)