public void Verify(int algorithm, string hexCborMessage)
        {
            foreach (bool usePublicOnlyKey in new[] { false, true })
            {
                CoseSign1Message msg = CoseMessage.DecodeSign1(ByteUtils.HexToByteArray(hexCborMessage));

                bool verified;
                if (Enum.IsDefined(typeof(ECDsaAlgorithm), algorithm))
                {
                    var   ecdsaAlgorithm = (ECDsaAlgorithm)algorithm;
                    ECDsa key            = usePublicOnlyKey ? ECDsaKeysWithoutPrivateKey[ecdsaAlgorithm] : ECDsaKeys[ecdsaAlgorithm];
                    verified = msg.Verify(key);
                }
                else
                {
                    RSA key = usePublicOnlyKey ? RSAKeyWithoutPrivateKey : RSAKey;
                    verified = msg.Verify(key);
                }

                Assert.True(verified, "CoseSign1Message.Verify(key)");
                AssertExtensions.SequenceEqual(s_sampleContent, msg.Content.GetValueOrDefault().Span);

                Assert.True(msg.ProtectedHeaders.TryGetEncodedValue(CoseHeaderLabel.Algorithm, out ReadOnlyMemory <byte> encodedAlg),
                            "Algorithm header must be protected");

                Assert.Equal(algorithm, new CborReader(encodedAlg).ReadInt32());
            }
        }
예제 #2
0
 private void AllEncodeOverloadsShouldThrow(CoseMessage msg)
 {
     Assert.Throws <CryptographicException>(msg.Encode);
     byte[] destination = new byte[msg.GetEncodedLength()];
     Assert.Throws <CryptographicException>(() => msg.Encode(destination));
     Assert.Throws <CryptographicException>(() => msg.TryEncode(destination, out _));
 }
예제 #3
0
        public void VerifyThrowsIfIncorrectIntegerAlgorithm(int incorrectAlg)
        {
            CoseSigner signer = GetCoseSigner(DefaultKey, DefaultHash);

            // Template header
            signer.ProtectedHeaders.Add(new CoseHeaderLabel(42), 42);
            string hexTemplateHeaders = "47A20126182A182A";
            string hexCborMessage     = Sign(s_sampleContent, signer).ByteArrayToHex();

            // Creaft a encoded protected map that replaces the "Template value" map.
            var writer = new CborWriter();

            writer.WriteStartMap(1);
            writer.WriteInt32(1);
            writer.WriteInt32(incorrectAlg);
            writer.WriteEndMap();
            byte[] newMap = writer.Encode();

            writer.Reset();
            writer.WriteByteString(newMap);
            string hexNewMap = writer.Encode().ByteArrayToHex();

            hexCborMessage = ReplaceFirst(hexCborMessage, hexTemplateHeaders, hexNewMap);

            CoseMessage msg = Decode(ByteUtils.HexToByteArray(hexCborMessage));

            Assert.Throws <CryptographicException>(() => Verify(msg, DefaultKey, s_sampleContent));
        }
        public void TestVerify(int algorithm, string hexCborMessage)
        {
            ReplaceContentInHexCborMessage(ref hexCborMessage);

            foreach (bool useNonPrivateKey in new[] { false, true })
            {
                CoseSign1Message    msg = CoseMessage.DecodeSign1(ByteUtils.HexToByteArray(hexCborMessage));
                AsymmetricAlgorithm key = GetKeyHashPair <AsymmetricAlgorithm>((CoseAlgorithm)algorithm, useNonPrivateKey).Key;

                Assert.True(Verify(msg, key, s_sampleContent), "Varification failed.");

                if (UseDetachedContent)
                {
                    Assert.Null(msg.Content);
                }
                else
                {
                    AssertExtensions.SequenceEqual(s_sampleContent, msg.Content.GetValueOrDefault().Span);
                }

                Assert.True(msg.ProtectedHeaders.TryGetEncodedValue(CoseHeaderLabel.Algorithm, out ReadOnlyMemory <byte> encodedAlg),
                            "Algorithm header must be protected");

                Assert.Equal(algorithm, new CborReader(encodedAlg).ReadInt32());
            }
        }
예제 #5
0
        public void DecodeSign1_VerifyUntagged()
        {
            // https://github.com/cose-wg/Examples/blob/master/ecdsa-examples/ecdsa-sig-01.json minus first byte.
            CoseSign1Message msg = CoseMessage.DecodeSign1(ByteUtils.HexToByteArray("8445A201260300A10442313154546869732069732074686520636F6E74656E742E58406520BBAF2081D7E0ED0F95F76EB0733D667005F7467CEC4B87B9381A6BA1EDE8E00DF29F32A37230F39A842A54821FDD223092819D7728EFB9D3A0080B75380B"));

            Assert.True(msg.VerifyEmbedded(DefaultKey));
        }
예제 #6
0
        public void DecodeVerifyDetachedContent()
        {
            CoseSign1Message msg = CoseMessage.DecodeSign1(ByteUtils.HexToByteArray("D28445A201260300A104423131F658406520BBAF2081D7E0ED0F95F76EB0733D667005F7467CEC4B87B9381A6BA1EDE8E00DF29F32A37230F39A842A54821FDD223092819D7728EFB9D3A0080B75380B"));

            Assert.Null(msg.Content);
            Assert.True(msg.Verify(DefaultKey, s_sampleContent));
        }
예제 #7
0
        public void VerifyThrowsWithUnknownAlgorithm(string hexCborMessage)
        {
            ReplaceContentInHexCborMessage(ref hexCborMessage);
            CoseSign1Message msg = CoseMessage.DecodeSign1(ByteUtils.HexToByteArray(hexCborMessage));

            Assert.Throws <CryptographicException>(() => Verify(msg, DefaultKey, s_sampleContent));
        }
예제 #8
0
        public void VerifyThrowsIfKeyIsNull()
        {
            byte[] encodedMsg = Sign(s_sampleContent, GetCoseSigner(DefaultKey, DefaultHash));

            CoseMessage msg = Decode(encodedMsg);

            Assert.Throws <ArgumentNullException>("key", () => Verify(msg, null !, s_sampleContent));
        }
예제 #9
0
        public void DecodeSign1_VerifyDetachedContent()
        {
            // Content is replaced with CBOR null - https://github.com/cose-wg/Examples/blob/master/ecdsa-examples/ecdsa-sig-01.json.
            CoseSign1Message msg = CoseMessage.DecodeSign1(ByteUtils.HexToByteArray("D28445A201260300A104423131F658406520BBAF2081D7E0ED0F95F76EB0733D667005F7467CEC4B87B9381A6BA1EDE8E00DF29F32A37230F39A842A54821FDD223092819D7728EFB9D3A0080B75380B"));

            Assert.Null(msg.Content);
            Assert.True(msg.VerifyDetached(DefaultKey, s_sampleContent));
        }
        internal override bool Verify(CoseMessage msg, AsymmetricAlgorithm key, byte[] content, byte[]?associatedData = null)
        {
            CoseMultiSignMessage multiSignMsg             = Assert.IsType <CoseMultiSignMessage>(msg);
            ReadOnlyCollection <CoseSignature> signatures = multiSignMsg.Signatures;

            Assert.Equal(1, signatures.Count);

            return(signatures[0].VerifyDetached(key, content, associatedData));
        }
        public void SignVerifyRSA(RSAAlgorithm algorithm)
        {
            HashAlgorithmName hashAlgorithm = GetHashAlgorithmNameFromCoseAlgorithm((int)algorithm);

            byte[]           coseMessageBytes = CoseSign1Message.Sign(s_sampleContent, RSAKey, hashAlgorithm);
            CoseSign1Message msg = CoseMessage.DecodeSign1(coseMessageBytes);

            Assert.True(msg.Verify(RSAKey));
        }
        internal override CoseHeaderMap GetSigningHeaderMap(CoseMessage msg, bool getProtectedMap)
        {
            CoseMultiSignMessage multiSignMsg = Assert.IsType <CoseMultiSignMessage>(msg);

            Assert.Equal(1, multiSignMsg.Signatures.Count);
            CoseSignature signature = multiSignMsg.Signatures[0];

            return(getProtectedMap ? signature.ProtectedHeaders : signature.UnprotectedHeaders);
        }
        public async Task VerifyAsyncWithUnseekableStream()
        {
            using Stream stream = GetTestStream(s_sampleContent);
            byte[] encodedMsg = await CoseSign1Message.SignAsync(stream, DefaultKey, DefaultHash);

            CoseSign1Message msg = CoseMessage.DecodeSign1(encodedMsg);

            using Stream unseekableStream = GetTestStream(s_sampleContent, StreamKind.Unseekable);
            await Assert.ThrowsAsync <ArgumentException>("detachedContent", () => msg.VerifyAsync(DefaultKey, unseekableStream));
        }
예제 #14
0
        public void VerifyThrowsIfKeyIsNotSupported()
        {
            byte[] encodedMsg = Sign(s_sampleContent, GetCoseSigner(DefaultKey, DefaultHash));

            CoseMessage msg = Decode(encodedMsg);

            AsymmetricAlgorithm key = ECDiffieHellman.Create();

            Assert.Throws <ArgumentException>("key", () => Verify(msg, key, s_sampleContent));
        }
예제 #15
0
        public void VerifyWithUnseekableStream()
        {
            using Stream stream = GetTestStream(s_sampleContent);
            byte[] encodedMsg = CoseMultiSignMessage.SignDetached(stream, GetCoseSigner(DefaultKey, DefaultHash));

            CoseMultiSignMessage msg = CoseMessage.DecodeMultiSign(encodedMsg);

            using Stream unseekableStream = GetTestStream(s_sampleContent, StreamKind.Unseekable);
            Assert.Throws <ArgumentException>("detachedContent", () => msg.Signatures[0].VerifyDetached(DefaultKey, unseekableStream));
        }
        public void VerifyWithUnreadableStream()
        {
            using Stream stream = GetTestStream(s_sampleContent);
            byte[] encodedMsg = CoseSign1Message.Sign(stream, DefaultKey, DefaultHash);

            CoseSign1Message msg = CoseMessage.DecodeSign1(encodedMsg);

            using Stream unseekableStream = GetTestStream(s_sampleContent, StreamKind.Unreadable);
            Assert.Throws <ArgumentException>("detachedContent", () => msg.Verify(DefaultKey, unseekableStream));
        }
예제 #17
0
        public void DecodeMultiSign_VerifyUntagged()
        {
            // https://github.com/cose-wg/Examples/blob/master/ecdsa-examples/ecdsa-01.json minus first 2 bytes.
            CoseMultiSignMessage msg = CoseMessage.DecodeMultiSign(ByteUtils.HexToByteArray("8443A10300A054546869732069732074686520636F6E74656E742E818343A10126A1044231315840D71C05DB52C9CE7F1BF5AAC01334BBEACAC1D86A2303E6EEAA89266F45C01ED602CA649EAF790D8BC99D2458457CA6A872061940E7AFBE48E289DFAC146AE258"));

            ReadOnlyCollection <CoseSignature> signatures = msg.Signatures;

            Assert.Equal(1, signatures.Count);
            Assert.True(signatures[0].VerifyEmbedded(DefaultKey));
        }
        public void SignVerifyECDsa(ECDsaAlgorithm algorithm)
        {
            ECDsa             ecdsa         = ECDsaKeys[algorithm];
            HashAlgorithmName hashAlgorithm = GetHashAlgorithmNameFromCoseAlgorithm((int)algorithm);

            byte[]           coseMessageBytes = CoseSign1Message.Sign(s_sampleContent, ecdsa, hashAlgorithm);
            CoseSign1Message msg = CoseMessage.DecodeSign1(coseMessageBytes);

            Assert.True(msg.Verify(ecdsa));
        }
예제 #19
0
        public void SignVerify()
        {
            foreach ((T key, HashAlgorithmName hashAlgorithm, CoseAlgorithm algorithm) in GetKeyHashAlgorithmTriplet())
            {
                ReadOnlySpan <byte> encodedMsg = Sign(s_sampleContent, key, hashAlgorithm);
                AssertSign1Message(encodedMsg, s_sampleContent, key, algorithm);

                CoseSign1Message msg = CoseMessage.DecodeSign1(encodedMsg);
                Assert.True(Verify(msg, key));
            }
        }
예제 #20
0
        public void DecodeSign1_IncorrectStructure()
        {
            var writer = new CborWriter();

            writer.WriteStartArray(4);
            writer.WriteNull();
            writer.WriteNull();
            writer.WriteNull();
            writer.WriteNull();
            writer.WriteEndArray();
            Assert.Throws <CryptographicException>(() => CoseMessage.DecodeSign1(writer.Encode()));
        }
예제 #21
0
        internal override bool Verify(CoseMessage msg, AsymmetricAlgorithm key, byte[] content, byte[]?associatedData = null)
        {
            CoseSign1Message sign1Msg = Assert.IsType <CoseSign1Message>(msg);

            if (content == null)
            {
                return(sign1Msg.VerifyDetached(key, (Stream)null !, associatedData));
            }

            using Stream stream = GetTestStream(content);
            return(sign1Msg.VerifyDetached(key, stream, associatedData));
        }
예제 #22
0
        internal override bool Verify(CoseMessage msg, AsymmetricAlgorithm key, byte[] content, byte[]?associatedData = null)
        {
            Assert.True(!OnlySupportsDetachedContent || msg.Content == null);
            CoseMultiSignMessage multiSignMsg = Assert.IsType <CoseMultiSignMessage>(msg);

            ReadOnlyCollection <CoseSignature> signatures = multiSignMsg.Signatures;

            Assert.Equal(1, signatures.Count);

            using Stream stream = GetTestStream(content);
            return(signatures[0].VerifyDetached(key, stream, associatedData));
        }
예제 #23
0
        public void DecodeMultiSign_VerifyDetachedContent()
        {
            // Content is replaced with CBOR null - https://github.com/cose-wg/Examples/blob/master/ecdsa-examples/ecdsa-01.json.
            CoseMultiSignMessage msg = CoseMessage.DecodeMultiSign(ByteUtils.HexToByteArray("D8628443A10300A0F6818343A10126A1044231315840D71C05DB52C9CE7F1BF5AAC01334BBEACAC1D86A2303E6EEAA89266F45C01ED602CA649EAF790D8BC99D2458457CA6A872061940E7AFBE48E289DFAC146AE258"));

            Assert.Null(msg.Content);

            ReadOnlyCollection <CoseSignature> signatures = msg.Signatures;

            Assert.Equal(1, signatures.Count);
            Assert.True(signatures[0].VerifyDetached(DefaultKey, s_sampleContent));
        }
예제 #24
0
        public void VerifyThrowsIfMessageWasEmbeddedAndContentWasSupplied()
        {
            if (!UseDetachedContent)
            {
                return;
            }

            CoseSign1Message msg = CoseMessage.DecodeSign1(ByteUtils.HexToByteArray("D28443A10126A10442313154546869732069732074686520636F6E74656E742E58408EB33E4CA31D1C465AB05AAC34CC6B23D58FEF5C083106C4D25A91AEF0B0117E2AF9A291AA32E14AB834DC56ED2A223444547E01F11D3B0916E5A4C345CACB36"));

            Assert.NotNull(msg.Content);
            Assert.Throws <InvalidOperationException>(() => Verify(msg, DefaultKey, s_sampleContent));
        }
예제 #25
0
        public void VerifyThrowsIfMessageWasDetachedAndContentWasNotSupplied()
        {
            if (UseDetachedContent)
            {
                return;
            }

            CoseSign1Message msg = CoseMessage.DecodeSign1(ByteUtils.HexToByteArray("D28445A201260300A104423131F658406520BBAF2081D7E0ED0F95F76EB0733D667005F7467CEC4B87B9381A6BA1EDE8E00DF29F32A37230F39A842A54821FDD223092819D7728EFB9D3A0080B75380B"));

            Assert.Null(msg.Content);
            Assert.Throws <InvalidOperationException>(() => Verify(msg, DefaultKey, s_sampleContent));
        }
        public void VerifyReturnsFalseWithWrongSignature(string hexCborMessage, bool corruptContent)
        {
            if (corruptContent && UseDetachedContent)
            {
                return;
            }

            ReplaceContentInHexCborMessage(ref hexCborMessage);

            CoseSign1Message msg = CoseMessage.DecodeSign1(ByteUtils.HexToByteArray(hexCborMessage));

            Assert.False(Verify(msg, DefaultKey, s_sampleContent));
        }
예제 #27
0
        public void DecodeSign1_ThrowsWithDuplicateHeaders(bool shouldContainInnerException, string hexCborMessage)
        {
            CryptographicException ex = Assert.Throws <CryptographicException>(() => CoseMessage.DecodeSign1(ByteUtils.HexToByteArray(hexCborMessage)));

            if (shouldContainInnerException) // if the duplicate headers were in one bucket the exception comes from CborReader because we use CborConformanceMode.Strict.
            {
                Assert.IsType <CborContentException>(ex.InnerException);
            }
            else
            {
                Assert.Null(ex.InnerException);
            }
        }
            static void VerifyContentDetached(byte[] messageEncoded, byte[] expectedContent, bool isDetached)
            {
                CoseMessage messageDecoded = CoseMessage.DecodeSign1(messageEncoded);

                if (isDetached)
                {
                    Assert.Null(messageDecoded.Content);
                }
                else
                {
                    AssertExtensions.SequenceEqual(new ReadOnlySpan <byte>(expectedContent), messageDecoded.Content.GetValueOrDefault().Span);
                }
            }
        public void VerifyReturnsFalseWithDataNotMatchingSignature()
        {
            string           encodedMsg = "D28445A201260300A10442313154546869732069732074686520636F6E74656E742E58406520BBAF2081D7E0ED0F95F76EB0733D667005F7467CEC4B87B9381A6BA1EDE8E00DF29F32A37230F39A842A54821FDD223092819D7728EFB9D3A0080B75380B";
            CoseSign1Message msg        = CoseMessage.DecodeSign1(ByteUtils.HexToByteArray(encodedMsg));

            Assert.True(msg.Verify(DefaultKey), "msg.Verify(ES256)");

            encodedMsg = ReplaceFirst(encodedMsg, "45A201260300", "45A201260301");
            msg        = CoseMessage.DecodeSign1(ByteUtils.HexToByteArray(encodedMsg));
            Assert.False(msg.Verify(DefaultKey), "msg.Verify(ES256) - Corrupt protected header");

            encodedMsg = ReplaceFirst(encodedMsg, "546869732069732074686520636F6E74656E742E", "546869732069732074686520636F6E74656E743E");
            msg        = CoseMessage.DecodeSign1(ByteUtils.HexToByteArray(encodedMsg));
            Assert.False(msg.Verify(DefaultKey), "msg.Verify(ES256) - Corrupt content");
예제 #30
0
        public void TestVerifyWithAssociatedData()
        {
            // https://github.com/cose-wg/Examples/blob/master/sign1-tests/sign-pass-02.json
            string hexCborMessage = "D28443A10126A10442313154546869732069732074686520636F6E74656E742E584010729CD711CB3813D8D8E944A8DA7111E7B258C9BDCA6135F7AE1ADBEE9509891267837E1E33BD36C150326AE62755C6BD8E540C3E8F92D7D225E8DB72B8820B";

            ReplaceContentInHexCborMessage(ref hexCborMessage);

            CoseSign1Message msg = CoseMessage.DecodeSign1(ByteUtils.HexToByteArray(hexCborMessage));

            Assert.False(Verify(msg, DefaultKey, s_sampleContent));

            byte[] associatedData = ByteUtils.HexToByteArray("11aa22bb33cc44dd55006699");
            Assert.True(Verify(msg, DefaultKey, s_sampleContent, associatedData));
        }