Exemple #1
0
 public static void WriteObject(this CborWriter writer, CborObject @object)
 {
     if (@object is CborTextString text)
     {
         writer.WriteTextString(text.Value);
     }
     else if (@object is CborByteString data)
     {
         writer.WriteByteString(data.Value);
     }
     else if (@object is CborBoolean boolean)
     {
         writer.WriteBoolean(boolean.Value);
     }
     else if (@object is CborInteger number)
     {
         writer.WriteInt64(number.Value);
     }
     else if (@object is CborMap map)
     {
         writer.WriteMap(map);
     }
     else if (@object is CborArray array)
     {
         writer.WriteArray(array);
     }
     else if (@object.Type == CborType.Null)
     {
         writer.WriteNull();
     }
     else
     {
         throw new Exception($"Unknown type. Was  {@object.Type}");
     }
 }
Exemple #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));
        }
Exemple #3
0
            public static void ExecOperation(CborWriter writer, string op)
            {
                switch (op)
                {
                case nameof(writer.WriteInt64): writer.WriteInt64(42); break;

                case nameof(writer.WriteByteString): writer.WriteByteString(Array.Empty <byte>()); break;

                case nameof(writer.WriteTextString): writer.WriteTextString(""); break;

                case nameof(writer.WriteStartIndefiniteLengthTextString): writer.WriteStartIndefiniteLengthTextString(); break;

                case nameof(writer.WriteStartIndefiniteLengthByteString): writer.WriteStartIndefiniteLengthByteString(); break;

                case nameof(writer.WriteStartArray): writer.WriteStartArray(null); break;

                case nameof(writer.WriteStartMap): writer.WriteStartMap(null); break;

                case nameof(writer.WriteEndIndefiniteLengthByteString): writer.WriteEndIndefiniteLengthByteString(); break;

                case nameof(writer.WriteEndIndefiniteLengthTextString): writer.WriteEndIndefiniteLengthTextString(); break;

                case nameof(writer.WriteEndArray): writer.WriteEndArray(); break;

                case nameof(writer.WriteEndMap): writer.WriteEndMap(); break;

                default: throw new Exception($"Unrecognized CborWriter operation name {op}");
                }
            }
        public override void Write(ref CborWriter writer, Guid value)
        {
            Span <byte> bytes = new byte[16];

            value.TryWriteBytes(bytes);
            writer.WriteByteString(bytes);
        }
Exemple #5
0
        public static CoseHeaderValue FromBytes(ReadOnlySpan <byte> value)
        {
            var writer = new CborWriter();

            writer.WriteByteString(value);

            return(FromEncodedValue(Encode(writer)));
        }
Exemple #6
0
 public static void WriteByteString_SingleValue_HappyPath(string hexInput, string hexExpectedEncoding)
 {
     byte[] expectedEncoding = hexExpectedEncoding.HexToByteArray();
     byte[] input            = hexInput.HexToByteArray();
     using var writer = new CborWriter();
     writer.WriteByteString(input);
     AssertHelper.HexEqual(expectedEncoding, writer.GetEncoding());
 }
Exemple #7
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()}");
                }
                ;
            }
Exemple #8
0
 public static void WriteChunkedByteString(CborWriter writer, byte[][] chunks)
 {
     writer.WriteStartIndefiniteLengthByteString();
     foreach (byte[] chunk in chunks)
     {
         writer.WriteByteString(chunk);
     }
     writer.WriteEndIndefiniteLengthByteString();
 }
        public static void Roundtrip_ByteString(string hexInput)
        {
            byte[] input = hexInput.HexToByteArray();
#endif
            var writer = new CborWriter();
            writer.WriteByteString(input);
            byte[] encoding = writer.Encode();

            var    reader = new CborReader(encoding);
            byte[] result = reader.ReadByteString();
            AssertHelper.HexEqual(input ?? Array.Empty <byte>(), result);
        }
Exemple #10
0
        public static void WriteEncodedValue_IndefiniteLengthByteString_HappyPath()
        {
            using var writer = new CborWriter(encodeIndefiniteLengths: true);

            writer.WriteStartByteString();
            writer.WriteByteString(new byte[] { 1, 1, 1 });
            writer.WriteEncodedValue("43020202".HexToByteArray());
            writer.WriteEndByteString();

            byte[] encoding = writer.GetEncoding();
            Assert.Equal("5f4301010143020202ff", encoding.ByteArrayToHex().ToLower());
        }
Exemple #11
0
        public static void Roundtrip_ByteString(CborConformanceMode mode, byte[] input)
        {
            var writer = new CborWriter(mode);

            writer.WriteByteString(input);
            byte[] encoding = writer.Encode();

            var reader = new CborReader(encoding, mode);

            byte[] result = reader.ReadByteString();
            AssertHelper.HexEqual(input, result);
        }
        public static void WriteEncodedValue_IndefiniteLengthByteString_HappyPath()
        {
            var writer = new CborWriter(convertIndefiniteLengthEncodings: false);

            writer.WriteStartIndefiniteLengthByteString();
            writer.WriteByteString(new byte[] { 1, 1, 1 });
            writer.WriteEncodedValue("43020202".HexToByteArray());
            writer.WriteEndIndefiniteLengthByteString();

            byte[] encoding = writer.Encode();
            Assert.Equal("5f4301010143020202ff", encoding.ByteArrayToHex().ToLower());
        }
Exemple #13
0
        public static void ByteString_Encoding_ShouldContainInputBytes(CborConformanceMode mode, byte[] input)
        {
            var writer = new CborWriter(mode);

            writer.WriteByteString(input);
            byte[] encoding = writer.Encode();

            int length = input?.Length ?? 0;
            int lengthEncodingLength = GetLengthEncodingLength(length);

            Assert.Equal(lengthEncodingLength + length, encoding.Length);
            AssertHelper.HexEqual(input ?? Array.Empty <byte>(), encoding.Skip(lengthEncodingLength).ToArray());
Exemple #14
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();
        public static void ByteString_Encoding_ShouldContainInputBytes(string hexInput)
        {
            byte[] input = hexInput.HexToByteArray();
#endif
            var writer = new CborWriter();
            writer.WriteByteString(input);
            byte[] encoding = writer.Encode();

            int length = input?.Length ?? 0;
            int lengthEncodingLength = GetLengthEncodingLength(length);

            Assert.Equal(lengthEncodingLength + length, encoding.Length);
            AssertHelper.HexEqual(input ?? Array.Empty <byte>(), encoding.Skip(lengthEncodingLength).ToArray());
        public override void Write(ref CborWriter writer, CborValue value, LengthMode lengthMode)
        {
            switch (value.Type)
            {
            case CborValueType.Object:
                ((ICborConverter <CborObject>) this).Write(ref writer, (CborObject)value, lengthMode);
                break;

            case CborValueType.Array:
                ((ICborConverter <CborArray>) this).Write(ref writer, (CborArray)value, lengthMode);
                break;

            case CborValueType.Positive:
                writer.WriteUInt64(value.Value <ulong>());
                break;

            case CborValueType.Negative:
                writer.WriteInt64(value.Value <long>());
                break;

            case CborValueType.Single:
                writer.WriteSingle(value.Value <float>());
                break;

            case CborValueType.Double:
                writer.WriteDouble(value.Value <double>());
                break;

            case CborValueType.Decimal:
                writer.WriteDecimal(value.Value <decimal>());
                break;

            case CborValueType.String:
                writer.WriteString(value.Value <string>());
                break;

            case CborValueType.Boolean:
                writer.WriteBoolean(value.Value <bool>());
                break;

            case CborValueType.Null:
                writer.WriteNull();
                break;

            case CborValueType.ByteString:
                writer.WriteByteString(value.Value <ReadOnlyMemory <byte> >().Span);
                break;
            }
        }
Exemple #17
0
        public void GetValueAsBytesSucceeds(ContentTestCase @case)
        {
            byte[] content = GetDummyContent(@case);
            var    writer  = new CborWriter();

            writer.WriteByteString(content);

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

            AssertExtensions.SequenceEqual(content, headerValue.GetValueAsBytes());

            Span <byte> buffer = new byte[content.Length];
            int         length = headerValue.GetValueAsBytes(buffer);

            Assert.Equal(content.Length, length);
            AssertExtensions.SequenceEqual(content, buffer);
        }
Exemple #18
0
        public static void Roundtrip_IndefiniteByteString(CborConformanceMode mode, byte[][] chunks)
        {
            bool convertIndefiniteLengthEncodings = mode is CborConformanceMode.Canonical or CborConformanceMode.Ctap2Canonical;
            var  writer = new CborWriter(convertIndefiniteLengthEncodings: convertIndefiniteLengthEncodings);

            writer.WriteStartIndefiniteLengthByteString();
            foreach (byte[] chunk in chunks)
            {
                writer.WriteByteString(chunk);
            }
            writer.WriteEndIndefiniteLengthByteString();

            byte[] encoding = writer.Encode();

            var reader = new CborReader(encoding);

            byte[] expected = chunks.SelectMany(ch => ch).ToArray();
            byte[] result   = reader.ReadByteString();
            AssertHelper.HexEqual(expected, result);
        }
Exemple #19
0
        public void GetValueAsBytesBeingIndefiniteLengthSucceeds(ContentTestCase @case)
        {
            Verify(0);
            Verify(1);
            Verify(10);

            void Verify(int repetitions)
            {
                byte[] content = GetDummyContent(@case);
                var    writer  = new CborWriter();

                writer.WriteStartIndefiniteLengthByteString();
                for (int i = 0; i < repetitions; i++)
                {
                    writer.WriteByteString(content);
                }
                writer.WriteEndIndefiniteLengthByteString();

                int expectedLength = content.Length * repetitions;

                CoseHeaderValue     headerValue = CoseHeaderValue.FromEncodedValue(writer.Encode());
                ReadOnlySpan <byte> result      = headerValue.GetValueAsBytes();

                Assert.Equal(expectedLength, result.Length);

                for (int i = 0; i < expectedLength; i += content.Length)
                {
                    AssertExtensions.SequenceEqual(content, result.Slice(i, content.Length));
                }

                Span <byte> buffer = new byte[expectedLength];
                int         length = headerValue.GetValueAsBytes(buffer);

                Assert.Equal(expectedLength, length);

                for (int i = 0; i < expectedLength; i += content.Length)
                {
                    AssertExtensions.SequenceEqual(content, buffer.Slice(i, content.Length));
                }
            }
        }
Exemple #20
0
 public override void Write(ref CborWriter writer, byte[] value)
 {
     writer.WriteByteString(value);
 }
 static ReadOnlyMemory <byte> EncodeBytes(ReadOnlySpan <byte> value, CborWriter writer)
 {
     writer.WriteByteString(value);
     return(EncodeAndReset(writer));
 }
Exemple #22
0
 public override void Write(ref CborWriter writer, ReadOnlyMemory <byte> value)
 {
     writer.WriteByteString(value.Span);
 }