Пример #1
0
        public static void WriteMap_DuplicateKeys_StrictConformance_ShouldBeRecoverableError(CborConformanceMode mode, object dupeKey)
        {
            byte[] expected = PerformWrite(attemptDuplicateWrite: false);
            byte[] actual   = PerformWrite(attemptDuplicateWrite: true);
            Assert.Equal(expected.ByteArrayToHex(), actual.ByteArrayToHex());

            byte[] PerformWrite(bool attemptDuplicateWrite)
            {
                var writer = new CborWriter(mode);

                writer.WriteStartMap(2);
                Helpers.WriteValue(writer, dupeKey);
                writer.WriteInt32(0);

                if (attemptDuplicateWrite)
                {
                    Assert.Throws <InvalidOperationException>(() => Helpers.WriteValue(writer, dupeKey));
                }

                // wrap dupe key in an array to satisfy key sorting & uniqueness constraints
                Helpers.WriteValue(writer, new object[] { dupeKey });
                writer.WriteInt32(0);
                writer.WriteEndMap();

                return(writer.Encode());
            }
        }
Пример #2
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));
        }
Пример #3
0
 public static void WriteInt32_SingleValue_HappyPath(int input, string hexExpectedEncoding)
 {
     byte[] expectedEncoding = hexExpectedEncoding.HexToByteArray();
     using var writer = new CborWriter();
     writer.WriteInt32(input);
     AssertHelper.HexEqual(expectedEncoding, writer.GetEncoding());
 }
Пример #4
0
        public static CoseHeaderValue FromInt32(int value)
        {
            var writer = new CborWriter();

            writer.WriteInt32(value);

            return(FromEncodedValue(Encode(writer)));
        }
Пример #5
0
 public static void WriteMap_DuplicateKeys_StrictConformance_ShouldFail(CborConformanceLevel level, object dupeKey)
 {
     using var writer = new CborWriter(level);
     writer.WriteStartMap(2);
     Helpers.WriteValue(writer, dupeKey);
     writer.WriteInt32(0);
     Assert.Throws <InvalidOperationException>(() => Helpers.WriteValue(writer, dupeKey));
 }
Пример #6
0
            public static void WriteValue(CborWriter writer, object value, bool useDefiniteLengthCollections = true)
            {
                switch (value)
                {
                case null: writer.WriteNull(); break;

                case bool b: writer.WriteBoolean(b); break;

                case int i: writer.WriteInt32(i); break;

                case long i: writer.WriteInt64(i); break;

                case ulong i: writer.WriteUInt64(i); break;

                case float f: writer.WriteSingle(f); break;

                case double d: writer.WriteDouble(d); break;

                case decimal d: writer.WriteDecimal(d); break;

                case string s: writer.WriteTextString(s); break;

                case BigInteger i: writer.WriteBigInteger(i); break;

                case DateTimeOffset d: writer.WriteDateTimeOffset(d); break;

                case byte[] b: writer.WriteByteString(b); break;

                case byte[][] chunks: WriteChunkedByteString(writer, chunks); break;

                case string[] chunks when IsIndefiniteLengthByteString(chunks):
                    byte[][]  byteChunks = chunks.Skip(1).Select(ch => ch.HexToByteArray()).ToArray();

                    WriteChunkedByteString(writer, byteChunks);
                    break;

                case string[] chunks: WriteChunkedTextString(writer, chunks); break;

                case object[] nested when IsCborMapRepresentation(nested): WriteMap(writer, nested, useDefiniteLengthCollections); break;

                case object[] nested when IsEncodedValueRepresentation(nested):
                    byte[]    encodedValue = ((string)nested[1]).HexToByteArray();

                    writer.WriteEncodedValue(encodedValue);
                    break;

                case object[] nested when IsTaggedValueRepresentation(nested):
                    writer.WriteTag((CborTag)nested[0]);

                    WriteValue(writer, nested[1]);
                    break;

                case object[] nested: WriteArray(writer, nested, useDefiniteLengthCollections); break;

                default: throw new ArgumentException($"Unrecognized argument type {value.GetType()}");
                }
                ;
            }
            public void WriteDiscriminator(ref CborWriter writer, Type actualType)
            {
                if (!_discriminatorsByType.TryGetValue(actualType, out int discriminator))
                {
                    throw new CborException($"Unknown discriminator for type: {actualType}");
                }

                writer.WriteInt32(discriminator);
            }
Пример #8
0
        public void GetValueAsInt32Succeeds(int value)
        {
            var writer = new CborWriter();

            writer.WriteInt32(value);

            CoseHeaderValue headerValue = CoseHeaderValue.FromEncodedValue(writer.Encode());

            Assert.Equal(value, headerValue.GetValueAsInt32());
        }
        public static void Reset_NonTrivialWriter_HappyPath()
        {
            // Set up: build a nontrivial writer state.
            // Favor maps and Ctap2 canonicalization since
            // since that utilizes most of the moving parts.
            var writer = new CborWriter(conformanceMode: CborConformanceMode.Ctap2Canonical);

            for (int i = 0; i < 10; i++)
            {
                if (i % 2 == 0)
                {
                    writer.WriteStartMap(100);
                }
                else
                {
                    writer.WriteStartArray(100);
                }
            }

            writer.WriteStartMap(3);

            writer.WriteInt32(1);  // key
            writer.WriteInt32(2);  // value

            writer.WriteInt32(-1); // key
            writer.WriteInt32(1);  // value

            // End set up

            Assert.Equal(11, writer.CurrentDepth);
            Assert.True(writer.BytesWritten > 11, "must have written a nontrivial number of bytes to the buffer");

            writer.Reset();

            Assert.Equal(0, writer.CurrentDepth);
            Assert.Equal(0, writer.BytesWritten);

            // Write an object from scratch and validate that it is correct

            writer.WriteInt32(42);
            Assert.Equal(new byte[] { 0x18, 0x2a }, writer.Encode());
        }
Пример #10
0
        public void FromInt32Succeeds(int value)
        {
            var writer = new CborWriter();

            writer.WriteInt32(value);

            CoseHeaderValue headerValue = CoseHeaderValue.FromInt32(value);

            AssertExtensions.SequenceEqual(writer.Encode(), headerValue.EncodedValue.Span);
            Assert.Equal(value, headerValue.GetValueAsInt32());
        }
Пример #11
0
        private static void WriteECParametersAsCosePublicKey(CborWriter writer, ECParameters ecParams, HashAlgorithmName?algorithmName)
        {
            Debug.Assert(writer.ConformanceMode == CborConformanceMode.Ctap2Canonical && writer.ConvertIndefiniteLengthEncodings);

            if (ecParams.Q.X is null || ecParams.Q.Y is null)
            {
                throw new ArgumentException("does not specify a public key point.", nameof(ecParams));
            }

            // run these first to perform necessary validation
            (CoseKeyType kty, CoseCrvId crv) = MapECCurveToCoseKtyAndCrv(ecParams.Curve);
            CoseKeyAlgorithm?alg = (algorithmName != null) ? MapHashAlgorithmNameToCoseKeyAlg(algorithmName.Value) : (CoseKeyAlgorithm?)null;

            // Begin writing a CBOR object
            writer.WriteStartMap(definiteLength: null);

            // NB labels should be sorted according to CTAP2 canonical encoding rules.
            // While the CborWriter will attempt to sort the encodings on its own,
            // it is generally more efficient if keys are written in sorted order to begin with.

            WriteCoseKeyLabel(writer, CoseKeyLabel.Kty);
            writer.WriteInt32((int)kty);

            if (alg != null)
            {
                WriteCoseKeyLabel(writer, CoseKeyLabel.Alg);
                writer.WriteInt32((int)alg);
            }

            WriteCoseKeyLabel(writer, CoseKeyLabel.EcCrv);
            writer.WriteInt32((int)crv);

            WriteCoseKeyLabel(writer, CoseKeyLabel.EcX);
            writer.WriteByteString(ecParams.Q.X);

            WriteCoseKeyLabel(writer, CoseKeyLabel.EcY);
            writer.WriteByteString(ecParams.Q.Y);

            writer.WriteEndMap();
Пример #12
0
 static void WriteCoseKeyLabel(CborWriter writer, CoseKeyLabel label)
 {
     writer.WriteInt32((int)label);
 }
Пример #13
0
 public override void Write(ref CborWriter writer, int value)
 {
     writer.WriteInt32(value);
 }
Пример #14
0
 static ReadOnlyMemory <byte> EncodeInt32(int value, CborWriter writer)
 {
     writer.WriteInt32(value);
     return(EncodeAndReset(writer));
 }