Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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();
            }
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
        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();
            }
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
        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;
            }
        }