public void CoseHeaderLabel_GetHashCode() { // First, construct a COSE header of (0) using several different methods. // They should all have the same hash code, though we don't know what // the hash code is. CoseHeaderLabel label1 = default; CoseHeaderLabel label2 = new CoseHeaderLabel(); CoseHeaderLabel label3 = new CoseHeaderLabel(0); int label1HashCode = label1.GetHashCode(); Assert.Equal(label1HashCode, label2.GetHashCode()); Assert.Equal(label1HashCode, label3.GetHashCode()); // Make sure the integer hash code calculation really is randomized. // Checking 1 & 2 together rather than independently cuts the false // positive rate down to nearly 1 in 2^64. bool isReturningNormalInt32HashCode = (new CoseHeaderLabel(1).GetHashCode() == 1) && (new CoseHeaderLabel(2).GetHashCode() == 2); Assert.False(isReturningNormalInt32HashCode); // Make sure the string hash code calculation really is randomized. // Checking 1 & 2 together rather than independently cuts the false // positive rate down to nearly 1 in 2^64. bool isReturningNormalStringHashCode = (new CoseHeaderLabel("Hello").GetHashCode() == "Hello".GetHashCode()) && (new CoseHeaderLabel("World").GetHashCode() == "World".GetHashCode()); Assert.Equal(PlatformDetection.IsNetCore, isReturningNormalStringHashCode); }
public void Enumerate() { var map = new CoseHeaderMap(); SetValue(map, CoseHeaderLabel.Algorithm, (int)ECDsaAlgorithm.ES256, default(SetValueMethod)); SetEncodedValue(map, CoseHeaderLabel.CriticalHeaders, GetDummyCritHeaderValue(), default(SetValueMethod)); SetValue(map, CoseHeaderLabel.ContentType, ContentTypeDummyValue, default(SetValueMethod)); SetValue(map, CoseHeaderLabel.KeyIdentifier, s_sampleContent, default(SetValueMethod)); var writer = new CborWriter(); int currentHeader = KnownHeaderAlg; foreach (KeyValuePair <CoseHeaderLabel, CoseHeaderValue> kvp in map) { CoseHeaderLabel label = kvp.Key; CoseHeaderValue value = kvp.Value; Assert.Equal(new CoseHeaderLabel(currentHeader), label); ReadOnlyMemory <byte> expectedValue = currentHeader switch { KnownHeaderAlg => EncodeInt32((int)ECDsaAlgorithm.ES256, writer), KnownHeaderCrit => GetDummyCritHeaderValue(), KnownHeaderContentType => EncodeString(ContentTypeDummyValue, writer), KnownHeaderKid => EncodeBytes(s_sampleContent, writer), _ => throw new InvalidOperationException() }; AssertExtensions.SequenceEqual(expectedValue.Span, value.EncodedValue.Span); currentHeader++; } Assert.Equal(KnownHeaderKid + 1, currentHeader);
public void SetEncodedValue_GetEncodedValue_KnownCoseHeaderLabel(int knownHeader, byte[] encodedValue, SetValueMethod setMethod, GetValueMethod getMethod) { var map = new CoseHeaderMap(); var label = new CoseHeaderLabel(knownHeader); SetEncodedValue(map, label, encodedValue, setMethod); ReadOnlySpan <byte> returnedEncocedValue = GetEncodedValue(map, label, getMethod); AssertExtensions.SequenceEqual(encodedValue, returnedEncocedValue); }
public void SetEncodedValue_GetEncodedValue_KnownCoseHeaderLabel(int knownHeader, byte[] encodedValue) { var map = new CoseHeaderMap(); var label = new CoseHeaderLabel(knownHeader); map.SetEncodedValue(label, encodedValue); ReadOnlyMemory <byte> returnedEncocedValue = map.GetEncodedValue(label); AssertExtensions.SequenceEqual(encodedValue, returnedEncocedValue.Span); map.TryGetEncodedValue(label, out returnedEncocedValue); AssertExtensions.SequenceEqual(encodedValue, returnedEncocedValue.Span); }
public void MultiSign_AddSignatureWithDuplicateHeaderBetweenProtectedAndUnprotected() { if (MessageKind != CoseMessageKind.MultiSign) { return; } CoseHeaderMap protectedHeaders, unprotectedHeaders; Initialize(DefaultAlgorithm); CoseMultiSignMessage msg = Assert.IsType <CoseMultiSignMessage>(Decode(Sign(s_sampleContent, GetCoseSigner(DefaultKey, DefaultHash, protectedHeaders, unprotectedHeaders)))); // Algorithm header is duplicated. It is a special case because it is mandatory that the header exists in the protected map. unprotectedHeaders.Add(CoseHeaderLabel.Algorithm, (int)DefaultAlgorithm); CoseSigner signer = GetCoseSigner(DefaultKey, DefaultHash, protectedHeaders, unprotectedHeaders); Assert.Throws <CryptographicException>(() => AddSignature(msg, s_sampleContent, signer)); // other known header is duplicate. Initialize(DefaultAlgorithm); protectedHeaders.Add(CoseHeaderLabel.ContentType, ContentTypeDummyValue); unprotectedHeaders.Add(CoseHeaderLabel.ContentType, ContentTypeDummyValue); signer = GetCoseSigner(DefaultKey, DefaultHash, protectedHeaders, unprotectedHeaders); Assert.Throws <CryptographicException>(() => AddSignature(msg, s_sampleContent, signer)); // not-known int header is duplicate. Initialize(DefaultAlgorithm); var myLabel = new CoseHeaderLabel(42); protectedHeaders.Add(myLabel, 42); unprotectedHeaders.Add(myLabel, 42); signer = GetCoseSigner(DefaultKey, DefaultHash, protectedHeaders, unprotectedHeaders); Assert.Throws <CryptographicException>(() => AddSignature(msg, s_sampleContent, signer)); // not-known tstr header is duplicate. Initialize(DefaultAlgorithm); myLabel = new CoseHeaderLabel("42"); protectedHeaders.Add(myLabel, 42); unprotectedHeaders.Add(myLabel, 42); signer = GetCoseSigner(DefaultKey, DefaultHash, protectedHeaders, unprotectedHeaders); Assert.Throws <CryptographicException>(() => AddSignature(msg, s_sampleContent, signer)); void Initialize(CoseAlgorithm algorithm) { protectedHeaders = GetHeaderMapWithAlgorithm(algorithm); unprotectedHeaders = GetEmptyHeaderMap(); } }
public void MultiSign_SignWithAllCborTypesAsHeaderValue_BodyHeaders(bool useProtectedMap, byte[] encodedValue) { if (MessageKind != CoseMessageKind.MultiSign) { return; } var myLabel = new CoseHeaderLabel(42); CoseHeaderMap signProtectedHeaders = GetHeaderMapWithAlgorithm(DefaultAlgorithm); CoseHeaderMap signUnprotectedHeaders = GetEmptyHeaderMap(); CoseHeaderMap bodyProtectedHeaders = GetEmptyHeaderMap(); CoseHeaderMap bodyUnprotectedHeaders = GetEmptyHeaderMap(); (useProtectedMap ? bodyProtectedHeaders : bodyUnprotectedHeaders)[myLabel] = CoseHeaderValue.FromEncodedValue(encodedValue); List <(CoseHeaderLabel, ReadOnlyMemory <byte>)> expectedSignProtectedHeaders = GetExpectedProtectedHeaders(DefaultAlgorithm); List <(CoseHeaderLabel, ReadOnlyMemory <byte>)> expectedSignUnprotectedHeaders = GetEmptyExpectedHeaders(); List <(CoseHeaderLabel, ReadOnlyMemory <byte>)> expectedProtectedHeaders = GetEmptyExpectedHeaders(); List <(CoseHeaderLabel, ReadOnlyMemory <byte>)> expectedUnprotectedHeaders = GetEmptyExpectedHeaders(); (useProtectedMap ? expectedProtectedHeaders : expectedUnprotectedHeaders).Add((myLabel, encodedValue)); CoseSigner signer = GetCoseSigner(DefaultKey, DefaultHash, signProtectedHeaders, signUnprotectedHeaders); ReadOnlySpan <byte> encodedMessage = Sign(s_sampleContent, signer, bodyProtectedHeaders, bodyUnprotectedHeaders); AssertCoseSignMessage( encodedMessage, s_sampleContent, DefaultKey, DefaultAlgorithm, expectedSignProtectedHeaders, expectedSignUnprotectedHeaders, null, expectedProtectedHeaders, expectedUnprotectedHeaders); // Verify it is transported correctly. CoseMessage message = Decode(encodedMessage); ReadOnlyMemory <byte> roundtrippedValue = (useProtectedMap ? message.ProtectedHeaders : message.UnprotectedHeaders)[myLabel].EncodedValue; AssertExtensions.SequenceEqual(encodedValue, roundtrippedValue.Span); }
public void ReEncodeWithDuplicateHeaderBetweenProtectedAndUnprotected() { // Algorithm header is duplicated. It is a special case because it is mandatory that the header exists in the protected map. CoseSigner signer = GetCoseSigner(DefaultKey, DefaultHash); CoseMessage msg = Decode(Sign(s_sampleContent, signer)); GetSigningHeaderMap(msg, getProtectedMap: false).Add(CoseHeaderLabel.Algorithm, (int)DefaultAlgorithm); AllEncodeOverloadsShouldThrow(msg); // other known header is duplicate. CoseHeaderMap protectedHeaders = GetEmptyHeaderMap(); protectedHeaders.Add(CoseHeaderLabel.ContentType, ContentTypeDummyValue); signer = GetCoseSigner(DefaultKey, DefaultHash, protectedHeaders); msg = Decode(Sign(s_sampleContent, signer)); GetSigningHeaderMap(msg, getProtectedMap: false).Add(CoseHeaderLabel.ContentType, ContentTypeDummyValue); AllEncodeOverloadsShouldThrow(msg); // not-known int header is duplicate. var myLabel = new CoseHeaderLabel(42); protectedHeaders = GetEmptyHeaderMap(); protectedHeaders.Add(myLabel, 42); signer = GetCoseSigner(DefaultKey, DefaultHash, protectedHeaders); msg = Decode(Sign(s_sampleContent, signer)); GetSigningHeaderMap(msg, getProtectedMap: false).Add(myLabel, 42); AllEncodeOverloadsShouldThrow(msg); // not-known tstr header is duplicate. myLabel = new CoseHeaderLabel("42"); protectedHeaders = GetEmptyHeaderMap(); protectedHeaders.Add(myLabel, 42); signer = GetCoseSigner(DefaultKey, DefaultHash, protectedHeaders); msg = Decode(Sign(s_sampleContent, signer)); GetSigningHeaderMap(msg, getProtectedMap: false).Add(myLabel, 42); AllEncodeOverloadsShouldThrow(msg); }
public void MultiSign_ReEncodeWithDuplicateHeaderBetweenProtectedAndUnprotected_BodyProtected() { if (MessageKind != CoseMessageKind.MultiSign) { return; } // known header is duplicate. CoseSigner signer = GetCoseSigner(DefaultKey, DefaultHash); CoseHeaderMap protectedHeaders = GetEmptyHeaderMap(); protectedHeaders.Add(CoseHeaderLabel.ContentType, ContentTypeDummyValue); CoseMessage msg = Decode(Sign(s_sampleContent, signer, protectedHeaders)); msg.UnprotectedHeaders.Add(CoseHeaderLabel.ContentType, ContentTypeDummyValue); AllEncodeOverloadsShouldThrow(msg); // not-known int header is duplicate. var myLabel = new CoseHeaderLabel(42); protectedHeaders = GetEmptyHeaderMap(); protectedHeaders.Add(myLabel, 42); signer = GetCoseSigner(DefaultKey, DefaultHash); msg = Decode(Sign(s_sampleContent, signer, protectedHeaders)); msg.UnprotectedHeaders.Add(myLabel, 42); AllEncodeOverloadsShouldThrow(msg); // not-known tstr header is duplicate. myLabel = new CoseHeaderLabel("42"); protectedHeaders = GetEmptyHeaderMap(); protectedHeaders.Add(myLabel, 42); signer = GetCoseSigner(DefaultKey, DefaultHash); msg = Decode(Sign(s_sampleContent, signer, protectedHeaders)); msg.UnprotectedHeaders.Add(myLabel, 42); AllEncodeOverloadsShouldThrow(msg); }
public void CoseHeaderLabel_GetHashCode() { CoseHeaderLabel label = default; Assert.Equal(0, label.GetHashCode()); // There's no need to call GetHashCode on integers as they are their own hashcode. label = new CoseHeaderLabel(); Assert.Equal(0, label.GetHashCode()); label = new CoseHeaderLabel(0); Assert.Equal(0, label.GetHashCode()); label = new CoseHeaderLabel(""); Assert.Equal("".GetHashCode(), label.GetHashCode()); label = new CoseHeaderLabel(1); Assert.Equal(1, label.GetHashCode()); label = new CoseHeaderLabel("content-type"); Assert.Equal("content-type".GetHashCode(), label.GetHashCode()); }
public void SignWithDuplicateHeaderBetweenProtectedAndUnprotected() { CoseHeaderMap protectedHeaders, unprotectedHeaders; // Algorithm header is duplicated. It is a special case because it is mandatory that the header exists in the protected map. Initialize(DefaultAlgorithm); unprotectedHeaders.SetValue(CoseHeaderLabel.Algorithm, (int)DefaultAlgorithm); Assert.Throws <CryptographicException>(() => Sign(s_sampleContent, DefaultKey, DefaultHash, protectedHeaders, unprotectedHeaders)); // other known header is duplicate. Initialize(DefaultAlgorithm); protectedHeaders.SetValue(CoseHeaderLabel.ContentType, ContentTypeDummyValue); unprotectedHeaders.SetValue(CoseHeaderLabel.ContentType, ContentTypeDummyValue); Assert.Throws <CryptographicException>(() => Sign(s_sampleContent, DefaultKey, DefaultHash, protectedHeaders, unprotectedHeaders)); // not-known int header is duplicate. Initialize(DefaultAlgorithm); var myLabel = new CoseHeaderLabel(42); protectedHeaders.SetValue(myLabel, 42); unprotectedHeaders.SetValue(myLabel, 42); Assert.Throws <CryptographicException>(() => Sign(s_sampleContent, DefaultKey, DefaultHash, protectedHeaders, unprotectedHeaders)); // not-known tstr header is duplicate. Initialize(DefaultAlgorithm); myLabel = new CoseHeaderLabel("42"); protectedHeaders.SetValue(myLabel, 42); unprotectedHeaders.SetValue(myLabel, 42); Assert.Throws <CryptographicException>(() => Sign(s_sampleContent, DefaultKey, DefaultHash, protectedHeaders, unprotectedHeaders)); void Initialize(CoseAlgorithm algorithm) { protectedHeaders = GetHeaderMapWithAlgorithm(algorithm); unprotectedHeaders = GetEmptyHeaderMap(); } }
public void SignWithAllCborTypesAsHeaderValue(bool useProtectedMap, byte[] encodedValue) { var myLabel = new CoseHeaderLabel(42); CoseHeaderMap protectedHeaders = GetHeaderMapWithAlgorithm(DefaultAlgorithm); CoseHeaderMap unprotectedHeaders = GetEmptyHeaderMap(); (useProtectedMap ? protectedHeaders : unprotectedHeaders)[myLabel] = CoseHeaderValue.FromEncodedValue(encodedValue); List <(CoseHeaderLabel, ReadOnlyMemory <byte>)> expectedProtectedHeaders = GetExpectedProtectedHeaders(DefaultAlgorithm); List <(CoseHeaderLabel, ReadOnlyMemory <byte>)> expectedUnprotectedHeaders = GetEmptyExpectedHeaders(); (useProtectedMap ? expectedProtectedHeaders : expectedUnprotectedHeaders).Add((myLabel, encodedValue)); ReadOnlySpan <byte> encodedMessage = Sign(s_sampleContent, DefaultKey, DefaultHash, protectedHeaders, unprotectedHeaders); AssertCoseSignMessage(encodedMessage, s_sampleContent, DefaultKey, DefaultAlgorithm, expectedProtectedHeaders, expectedUnprotectedHeaders); // Verify it is transported correctly. CoseMessage message = Decode(encodedMessage); ReadOnlyMemory <byte> roundtrippedValue = GetSigningHeaderMap(message, useProtectedMap)[myLabel].EncodedValue; AssertExtensions.SequenceEqual(encodedValue, roundtrippedValue.Span); }
public void SignWithNotKnownHeader(bool useProtectedMap) { CoseHeaderMap protectedHeaders, unprotectedHeaders, mapForCustomHeader; List <(CoseHeaderLabel, ReadOnlyMemory <byte>)> expectedProtectedHeaders, expectedUnprotectedHeaders, listForCustomHeader; Initialize(); CoseHeaderLabel myLabel = new CoseHeaderLabel(42); int myValue = 42; mapForCustomHeader.Add(myLabel, myValue); AddEncoded(listForCustomHeader, myLabel, myValue); ReadOnlySpan <byte> encodedMsg = Sign(s_sampleContent, DefaultKey, DefaultHash, protectedHeaders, unprotectedHeaders); AssertCoseSignMessage(encodedMsg, s_sampleContent, DefaultKey, DefaultAlgorithm, expectedProtectedHeaders, expectedUnprotectedHeaders); Initialize(); myLabel = new CoseHeaderLabel("42"); mapForCustomHeader.Add(myLabel, myValue); AddEncoded(listForCustomHeader, myLabel, myValue); encodedMsg = Sign(s_sampleContent, DefaultKey, DefaultHash, protectedHeaders, unprotectedHeaders); AssertCoseSignMessage(encodedMsg, s_sampleContent, DefaultKey, DefaultAlgorithm, expectedProtectedHeaders, expectedUnprotectedHeaders); void Initialize() { protectedHeaders = GetHeaderMapWithAlgorithm(DefaultAlgorithm); unprotectedHeaders = GetEmptyHeaderMap(); mapForCustomHeader = useProtectedMap ? protectedHeaders : unprotectedHeaders; expectedProtectedHeaders = GetExpectedProtectedHeaders(DefaultAlgorithm); expectedUnprotectedHeaders = new List <(CoseHeaderLabel, ReadOnlyMemory <byte>)>(); listForCustomHeader = useProtectedMap ? expectedProtectedHeaders : expectedUnprotectedHeaders; } }