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}"); } }
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 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); }
public static CoseHeaderValue FromBytes(ReadOnlySpan <byte> value) { var writer = new CborWriter(); writer.WriteByteString(value); return(FromEncodedValue(Encode(writer))); }
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()); }
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 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); }
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()); }
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()); }
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());
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; } }
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); }
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); }
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)); } } }
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)); }
public override void Write(ref CborWriter writer, ReadOnlyMemory <byte> value) { writer.WriteByteString(value.Span); }