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()); } }
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 WriteInt32_SingleValue_HappyPath(int input, string hexExpectedEncoding) { byte[] expectedEncoding = hexExpectedEncoding.HexToByteArray(); using var writer = new CborWriter(); writer.WriteInt32(input); AssertHelper.HexEqual(expectedEncoding, writer.GetEncoding()); }
public static CoseHeaderValue FromInt32(int value) { var writer = new CborWriter(); writer.WriteInt32(value); return(FromEncodedValue(Encode(writer))); }
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)); }
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); }
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()); }
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()); }
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();
static void WriteCoseKeyLabel(CborWriter writer, CoseKeyLabel label) { writer.WriteInt32((int)label); }
public override void Write(ref CborWriter writer, int value) { writer.WriteInt32(value); }
static ReadOnlyMemory <byte> EncodeInt32(int value, CborWriter writer) { writer.WriteInt32(value); return(EncodeAndReset(writer)); }