public static void EndWriteMap_DefiniteLengthNotMet_WithNestedData_ShouldThrowInvalidOperationException(int definiteLength) { using var writer = new CborWriter(); writer.WriteStartMap(definiteLength); for (int i = 1; i < definiteLength; i++) { writer.WriteTextString($"key_{i}"); writer.WriteStartMap(definiteLength: 1); writer.WriteInt64(i); writer.WriteInt64(i); writer.WriteEndMap(); } Assert.Throws <InvalidOperationException>(() => writer.WriteEndMap()); }
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 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 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 WriteEndArray_AfterStartMap_ShouldThrowInvalidOperationException(int depth) { var writer = new CborWriter(); for (int i = 0; i < depth; i++) { if (i % 2 == 0) { writer.WriteStartArray(1); } else { writer.WriteStartMap(1); } } writer.WriteStartMap(definiteLength: 0); Assert.Throws <InvalidOperationException>(() => writer.WriteEndArray()); }
public static void WriteEndArray_ImbalancedCall_ShouldThrowInvalidOperationException(int depth) { using var writer = new CborWriter(); for (int i = 0; i < depth; i++) { writer.WriteStartMap(1); } Assert.Throws <InvalidOperationException>(() => writer.WriteEndArray()); }
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 static void Write_TaggedEmptyMap_ShouldSucceed() { var writer = new CborWriter(); writer.WriteTag(CborTag.DateTimeString); writer.WriteStartMap(0); writer.WriteEndMap(); byte[] encoding = writer.Encode(); Assert.Equal("C0A0", encoding.ByteArrayToHex()); }
public static void WriteMap_DefiniteLengthExceeded_ShouldThrowInvalidOperationException(int definiteLength) { using var writer = new CborWriter(); writer.WriteStartMap(definiteLength); for (int i = 0; i < definiteLength; i++) { writer.WriteTextString($"key_{i}"); writer.WriteInt64(i); } Assert.Throws <InvalidOperationException>(() => writer.WriteInt64(0)); }
public static void WriteMap(this CborWriter writer, CborMap map) { writer.WriteStartMap(map.Count); foreach (var item in map) { WriteObject(writer, item.Key); WriteObject(writer, item.Value); } writer.WriteEndMap(); }
public static void WriteMap(CborWriter writer, object[] keyValuePairs, bool useDefiniteLengthCollections = true) { if (!IsCborMapRepresentation(keyValuePairs)) { throw new ArgumentException($"CBOR map representation must contain odd number of elements prepended with a '{MapPrefixIdentifier}' constant."); } if (useDefiniteLengthCollections) { writer.WriteStartMap(keyValuePairs.Length / 2); } else { writer.WriteStartMap(null); } foreach (object value in keyValuePairs.Skip(1)) { WriteValue(writer, value, useDefiniteLengthCollections); } writer.WriteEndMap(); }
public static void EndWriteMap_IndefiniteLength_OddItems_ShouldThrowInvalidOperationException(int length) { using var writer = new CborWriter(); writer.WriteStartMap(); for (int i = 1; i < length; i++) { writer.WriteTextString($"key_{i}"); writer.WriteInt64(i); } writer.WriteInt64(0); Assert.Throws <InvalidOperationException>(() => writer.WriteEndMap()); }
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 WriteStartMap_IndefiniteLength_NoPatching_UnsupportedConformance_ShouldThrowInvalidOperationException(CborConformanceMode conformanceMode) { var writer = new CborWriter(conformanceMode, convertIndefiniteLengthEncodings: false); Assert.Throws <InvalidOperationException>(() => writer.WriteStartMap(null)); }