未验证 提交 ab380106 编写于 作者: D David Cantú 提交者: GitHub

Add support for indefinite length arrays (#74215)

* Add support for indefinite length arrays

* Update src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseHeaderMap.cs
Co-authored-by: Ncampersau <buchholz.bastian@googlemail.com>

* Validate indefinite-length arrays length up-front for fixed-lengh arrays

* Update src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseMessage.cs
Co-authored-by: NJeremy Barton <jbarton@microsoft.com>
Co-authored-by: Ncampersau <buchholz.bastian@googlemail.com>
Co-authored-by: NJeremy Barton <jbarton@microsoft.com>
上级 3cad3d24
......@@ -154,10 +154,10 @@
<value>Label in Critical Headers array was incorrect.</value>
</data>
<data name="CriticalHeadersMustBeArrayOfAtLeastOne" xml:space="preserve">
<value>Critical Headers must be a definite-length CBOR array of at least one element.</value>
<value>Critical Headers must be a CBOR array of at least one element.</value>
</data>
<data name="DecodeCoseSignatureMustBeArrayOfThree" xml:space="preserve">
<value>COSE Signature must be a definite-length array of 3 elements.</value>
<value>COSE Signature must be an array of three elements.</value>
</data>
<data name="DecodeErrorWhileDecoding" xml:space="preserve">
<value>Error while decoding COSE message. {0}</value>
......@@ -168,11 +168,14 @@
<data name="DecodeMessageContainedTrailingData" xml:space="preserve">
<value>CBOR payload contained trailing data after message was complete.</value>
</data>
<data name="DecodeMultiSignArrayLengthMustBeFour" xml:space="preserve">
<value>COSE_Sign must be an array of four elements.</value>
</data>
<data name="DecodeMultiSignIncorrectTag" xml:space="preserve">
<value>Incorrect tag. Expected Sign(98) or Untagged, Actual '{0}'.</value>
</data>
<data name="DecodeSign1ArrayLengthMustBeFour" xml:space="preserve">
<value>Array length for COSE_Sign1 must be four.</value>
<value>COSE_Sign1 must be an array of four elements.</value>
</data>
<data name="DecodeSign1EncodedProtectedMapIncorrect" xml:space="preserve">
<value>Protected map was incorrect.</value>
......
......@@ -266,16 +266,18 @@ private static void ValidateInsertion(CoseHeaderLabel label, CoseHeaderValue val
reader.SkipValue();
break;
case KnownHeaders.Crit:
int length = reader.ReadStartArray().GetValueOrDefault();
if (length < 1)
{
throw new ArgumentException(SR.CriticalHeadersMustBeArrayOfAtLeastOne, nameof(value));
}
reader.ReadStartArray();
bool isEmpty = true;
for (int i = 0; i < length; i++)
while (true)
{
CborReaderState state = reader.PeekState();
if (state == CborReaderState.UnsignedInteger || state == CborReaderState.NegativeInteger)
if (state == CborReaderState.EndArray)
{
reader.ReadEndArray();
break;
}
else if (state == CborReaderState.UnsignedInteger || state == CborReaderState.NegativeInteger)
{
reader.ReadInt32();
}
......@@ -287,8 +289,13 @@ private static void ValidateInsertion(CoseHeaderLabel label, CoseHeaderValue val
{
throw new ArgumentException(SR.Format(SR.CoseHeaderMapHeaderDoesNotAcceptSpecifiedValue, label.LabelName), nameof(value));
}
isEmpty = false;
}
if (isEmpty)
{
throw new ArgumentException(SR.CriticalHeadersMustBeArrayOfAtLeastOne, nameof(value));
}
reader.SkipToParent();
break;
case KnownHeaders.ContentType:
if (initialState != CborReaderState.TextString &&
......
......@@ -128,8 +128,18 @@ private static CoseSign1Message DecodeCoseSign1Core(CborReader reader)
throw new CryptographicException(SR.Format(SR.DecodeSign1IncorrectTag, tag));
}
ReadOnlyMemory<byte> coseSignArray = reader.ReadEncodedValue();
if (reader.BytesRemaining != 0)
{
throw new CryptographicException(SR.Format(SR.DecodeErrorWhileDecoding, SR.DecodeMessageContainedTrailingData));
}
reader = new CborReader(coseSignArray);
int? arrayLength = reader.ReadStartArray();
if (arrayLength != 4)
if (arrayLength.HasValue ? arrayLength != CoseSign1Message.Sign1ArrayLength :
HasIndefiniteLengthArrayIncorrectLength(coseSignArray, CoseSign1Message.Sign1ArrayLength))
{
throw new CryptographicException(SR.Format(SR.DecodeErrorWhileDecoding, SR.DecodeSign1ArrayLengthMustBeFour));
}
......@@ -149,10 +159,7 @@ private static CoseSign1Message DecodeCoseSign1Core(CborReader reader)
byte[] signature = DecodeSignature(reader);
reader.ReadEndArray();
if (reader.BytesRemaining != 0)
{
throw new CryptographicException(SR.Format(SR.DecodeErrorWhileDecoding, SR.DecodeMessageContainedTrailingData));
}
Debug.Assert(reader.BytesRemaining == 0);
return new CoseSign1Message(protectedHeader, unprotectedHeader, payload, signature, protectedHeaderAsBstr, tag.HasValue);
}
......@@ -207,10 +214,20 @@ private static CoseMultiSignMessage DecodeCoseMultiSignCore(CborReader reader)
throw new CryptographicException(SR.Format(SR.DecodeMultiSignIncorrectTag, tag));
}
ReadOnlyMemory<byte> coseSignArray = reader.ReadEncodedValue();
if (reader.BytesRemaining != 0)
{
throw new CryptographicException(SR.Format(SR.DecodeErrorWhileDecoding, SR.DecodeMessageContainedTrailingData));
}
reader = new CborReader(coseSignArray);
int? arrayLength = reader.ReadStartArray();
if (arrayLength != 4)
if (arrayLength.HasValue ? arrayLength != CoseMultiSignMessage.MultiSignArrayLength :
HasIndefiniteLengthArrayIncorrectLength(coseSignArray, CoseMultiSignMessage.MultiSignArrayLength))
{
throw new CryptographicException(SR.Format(SR.DecodeErrorWhileDecoding, SR.DecodeSign1ArrayLengthMustBeFour));
throw new CryptographicException(SR.Format(SR.DecodeErrorWhileDecoding, SR.DecodeMultiSignArrayLengthMustBeFour));
}
var protectedHeaders = new CoseHeaderMap();
......@@ -225,14 +242,10 @@ private static CoseMultiSignMessage DecodeCoseMultiSignCore(CborReader reader)
}
byte[]? payload = DecodePayload(reader);
List<CoseSignature> signatures = DecodeCoseSignaturesArray(reader, encodedProtectedHeaders);
List<CoseSignature> signatures = DecodeCoseSignaturesArray(reader);
reader.ReadEndArray();
if (reader.BytesRemaining != 0)
{
throw new CryptographicException(SR.Format(SR.DecodeErrorWhileDecoding, SR.DecodeMessageContainedTrailingData));
}
Debug.Assert(reader.BytesRemaining == 0);
return new CoseMultiSignMessage(protectedHeaders, unprotectedHeaders, payload, signatures, encodedProtectedHeaders, tag.HasValue);
}
......@@ -319,22 +332,34 @@ private static byte[] DecodeSignature(CborReader reader)
return reader.ReadByteString();
}
private static List<CoseSignature> DecodeCoseSignaturesArray(CborReader reader, byte[] bodyProtected)
private static List<CoseSignature> DecodeCoseSignaturesArray(CborReader reader)
{
int? signaturesLength = reader.ReadStartArray();
List<CoseSignature> signatures = new List<CoseSignature>(signaturesLength.GetValueOrDefault());
if (signaturesLength.GetValueOrDefault() < 1)
while (reader.PeekState() == CborReaderState.StartArray)
{
CoseSignature signature = DecodeCoseSignature(reader.ReadEncodedValue());
signatures.Add(signature);
}
reader.ReadEndArray();
if (signatures.Count < 1)
{
throw new CryptographicException(SR.Format(SR.DecodeErrorWhileDecoding, SR.MultiSignMessageMustCarryAtLeastOneSignature));
}
List<CoseSignature> signatures = new List<CoseSignature>(signaturesLength!.Value);
return signatures;
}
for (int i = 0; i < signaturesLength; i++)
private static CoseSignature DecodeCoseSignature(ReadOnlyMemory<byte> coseSignature)
{
var reader = new CborReader(coseSignature);
int? length = reader.ReadStartArray();
if (length != CoseMultiSignMessage.CoseSignatureArrayLength)
if (length.HasValue ? length != CoseMultiSignMessage.CoseSignatureArrayLength :
HasIndefiniteLengthArrayIncorrectLength(coseSignature, CoseMultiSignMessage.CoseSignatureArrayLength))
{
throw new CryptographicException(SR.Format(SR.DecodeErrorWhileDecoding, SR.DecodeCoseSignatureMustBeArrayOfThree));
}
......@@ -351,14 +376,33 @@ private static List<CoseSignature> DecodeCoseSignaturesArray(CborReader reader,
}
byte[] signatureBytes = DecodeSignature(reader);
reader.ReadEndArray();
signatures.Add(new CoseSignature(protectedHeaders, unprotectedHeaders, bodyProtected, signProtected, signatureBytes));
return new CoseSignature(protectedHeaders, unprotectedHeaders, signProtected, signatureBytes);
}
reader.ReadEndArray();
private static bool HasIndefiniteLengthArrayIncorrectLength(ReadOnlyMemory<byte> encodedArray, int expectedLength)
{
var reader = new CborReader(encodedArray);
reader.ReadStartArray();
int count = 0;
while (reader.PeekState() != CborReaderState.EndArray)
{
reader.SkipValue();
count++;
if (count > expectedLength)
{
return true;
}
}
bool retVal = count != expectedLength;
reader.ReadEndArray();
Debug.Assert(reader.BytesRemaining == 0);
return signatures;
return retVal;
}
internal static void AppendToBeSigned(
......
......@@ -17,7 +17,7 @@ namespace System.Security.Cryptography.Cose
/// </summary>
public sealed class CoseMultiSignMessage : CoseMessage
{
private const int MultiSignArrayLength = 4;
internal const int MultiSignArrayLength = 4;
private const int MultiSignSizeOfCborTag = 2;
internal const int CoseSignatureArrayLength = 3;
......@@ -804,7 +804,7 @@ private void AddSignatureCore(ReadOnlySpan<byte> contentBytes, Stream? contentSt
bytesWritten = CoseHelpers.SignHash(signer, hasher, buffer);
byte[] signature = bufferSpan.Slice(0, bytesWritten).ToArray();
_signatures.Add(new CoseSignature(this, signProtectedHeaders, signer.UnprotectedHeaders, _protectedHeaderAsBstr, encodedSignProtected, signature));
_signatures.Add(new CoseSignature(this, signProtectedHeaders, signer.UnprotectedHeaders, encodedSignProtected, signature));
}
}
finally
......@@ -877,7 +877,7 @@ private async Task AddSignatureCoreAsync(Stream content, CoseSigner signer, Read
bytesWritten = CoseHelpers.SignHash(signer, hasher, buffer);
byte[] signature = buffer.AsSpan(0, bytesWritten).ToArray();
_signatures.Add(new CoseSignature(this, signProtectedHeaders, signer.UnprotectedHeaders, _protectedHeaderAsBstr, encodedSignProtected, signature));
_signatures.Add(new CoseSignature(this, signProtectedHeaders, signer.UnprotectedHeaders, encodedSignProtected, signature));
}
ArrayPool<byte>.Shared.Return(buffer, clearArray: true);
......
......@@ -15,7 +15,7 @@ namespace System.Security.Cryptography.Cose
/// </summary>
public sealed class CoseSign1Message : CoseMessage
{
private const int Sign1ArrayLength = 4;
internal const int Sign1ArrayLength = 4;
private const int Sign1SizeOfCborTag = 1;
private readonly byte[] _signature;
......
......@@ -14,7 +14,6 @@ namespace System.Security.Cryptography.Cose
/// </summary>
public sealed class CoseSignature
{
private readonly byte[] _encodedBodyProtectedHeaders;
internal readonly byte[] _encodedSignProtectedHeaders;
internal readonly byte[] _signature;
private CoseMultiSignMessage? _message;
......@@ -43,17 +42,16 @@ public sealed class CoseSignature
/// <value>A region of memory that contains the digital signature.</value>
public ReadOnlyMemory<byte> Signature => _signature;
internal CoseSignature(CoseMultiSignMessage message, CoseHeaderMap protectedHeaders, CoseHeaderMap unprotectedHeaders, byte[] encodedBodyProtectedHeaders, byte[] encodedSignProtectedHeaders, byte[] signature)
: this(protectedHeaders, unprotectedHeaders, encodedBodyProtectedHeaders, encodedSignProtectedHeaders, signature)
internal CoseSignature(CoseMultiSignMessage message, CoseHeaderMap protectedHeaders, CoseHeaderMap unprotectedHeaders, byte[] encodedSignProtectedHeaders, byte[] signature)
: this(protectedHeaders, unprotectedHeaders, encodedSignProtectedHeaders, signature)
{
Message = message;
}
internal CoseSignature(CoseHeaderMap protectedHeaders, CoseHeaderMap unprotectedHeaders, byte[] encodedBodyProtectedHeaders, byte[] encodedSignProtectedHeaders, byte[] signature)
internal CoseSignature(CoseHeaderMap protectedHeaders, CoseHeaderMap unprotectedHeaders, byte[] encodedSignProtectedHeaders, byte[] signature)
{
ProtectedHeaders = protectedHeaders;
UnprotectedHeaders = unprotectedHeaders;
_encodedBodyProtectedHeaders = encodedBodyProtectedHeaders;
_encodedSignProtectedHeaders = encodedSignProtectedHeaders;
_signature = signature;
}
......@@ -400,7 +398,7 @@ private async Task<bool> VerifyAsyncCore(AsymmetricAlgorithm key, Stream content
{
int bufferLength = CoseMessage.ComputeToBeSignedEncodedSize(
SigStructureContext.Signature,
_encodedBodyProtectedHeaders.Length,
Message.RawProtectedHeaders.Length,
_encodedSignProtectedHeaders.Length,
associatedData.Length,
contentLength: 0);
......@@ -408,7 +406,7 @@ private async Task<bool> VerifyAsyncCore(AsymmetricAlgorithm key, Stream content
try
{
await CoseMessage.AppendToBeSignedAsync(buffer, hasher, SigStructureContext.Signature, _encodedBodyProtectedHeaders, _encodedSignProtectedHeaders, associatedData, content, cancellationToken).ConfigureAwait(false);
await CoseMessage.AppendToBeSignedAsync(buffer, hasher, SigStructureContext.Signature, Message.RawProtectedHeaders, _encodedSignProtectedHeaders, associatedData, content, cancellationToken).ConfigureAwait(false);
return VerifyHash(key, hasher, hashAlgorithm, keyType, padding);
}
finally
......@@ -432,7 +430,7 @@ private bool VerifyCore(AsymmetricAlgorithm key, ReadOnlySpan<byte> contentBytes
{
int bufferLength = CoseMessage.ComputeToBeSignedEncodedSize(
SigStructureContext.Signature,
_encodedBodyProtectedHeaders.Length,
Message.RawProtectedHeaders.Length,
_encodedSignProtectedHeaders.Length,
associatedData.Length,
contentLength: 0);
......@@ -440,7 +438,7 @@ private bool VerifyCore(AsymmetricAlgorithm key, ReadOnlySpan<byte> contentBytes
try
{
CoseMessage.AppendToBeSigned(buffer, hasher, SigStructureContext.Signature, _encodedBodyProtectedHeaders, _encodedSignProtectedHeaders, associatedData, contentBytes, contentStream);
CoseMessage.AppendToBeSigned(buffer, hasher, SigStructureContext.Signature, Message.RawProtectedHeaders.Span, _encodedSignProtectedHeaders, associatedData, contentBytes, contentStream);
return VerifyHash(key, hasher, hashAlgorithm, keyType, padding);
}
finally
......
......@@ -295,6 +295,41 @@ public void RemoveKeyValuePair_DoesNotMatchKeyOrValue(bool changeKey)
Assert.Equal(1, map.Count);
}
[Fact]
public void SetEncodedValue_CriticalHeaders_ThrowIf_ArrayEmpty()
{
// definite length
var writer = new CborWriter();
writer.WriteStartArray(0);
writer.WriteEndArray();
Verify(writer.Encode());
// indefinite length
writer.Reset();
writer.WriteStartArray(null);
writer.WriteEndArray();
Verify(writer.Encode());
void Verify(byte[] encodedValue)
{
CoseHeaderMap map = new();
CoseHeaderValue value = CoseHeaderValue.FromEncodedValue(writer.Encode());
Assert.Throws<ArgumentException>(() => map[CoseHeaderLabel.CriticalHeaders] = value);
}
}
[Fact]
public void SetEncodedValue_CriticalHeaders_ThrowIf_IndefiniteLengthArrayMissingBreak()
{
byte[] encodedValue = GetDummyCritHeaderValue(useIndefiniteLength: true);
CoseHeaderMap map = new();
CoseHeaderValue value = CoseHeaderValue.FromEncodedValue(encodedValue.AsSpan(0, encodedValue.Length - 1));
Assert.Throws<ArgumentException>(() => map[CoseHeaderLabel.CriticalHeaders] = value);
}
public enum SetValueMethod
{
ItemSet,
......@@ -493,7 +528,11 @@ public static IEnumerable<object[]> KnownHeadersEncodedValues_TestData()
writer.WriteInt32((int)ECDsaAlgorithm.ES256);
yield return ReturnDataAndReset(KnownHeaderAlg, writer, setMethod, getMethod);
WriteDummyCritHeaderValue(writer);
WriteDummyCritHeaderValue(writer, useIndefiniteLength: false);
yield return ReturnDataAndReset(KnownHeaderCrit, writer, setMethod, getMethod);
WriteDummyCritHeaderValue(writer, useIndefiniteLength: true);
yield return ReturnDataAndReset(KnownHeaderCrit, writer, setMethod, getMethod);
writer.WriteTextString(ContentTypeDummyValue);
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Formats.Cbor;
using Test.Cryptography;
......@@ -82,5 +83,66 @@ public void DecodeMultiSign_IncorrectStructure()
writer.WriteEndArray();
Assert.Throws<CryptographicException>(() => CoseMessage.DecodeMultiSign(writer.Encode()));
}
[Theory]
// COSE_Sign is an indefinite-length array
[InlineData("D8629F40A054546869732069732074686520636F6E74656E742E818343A10126A1044231315840E2AEAFD40D69D19DFE6E52077C5D7FF4E408282CBEFB5D06CBF414AF2E19D982AC45AC98B8544C908B4507DE1E90B717C3D34816FE926A2B98F53AFD2FA0F30AFF")]
// [+COSE_Signature]
[InlineData("D8628440A054546869732069732074686520636F6E74656E742E9F8343A10126A1044231315840E2AEAFD40D69D19DFE6E52077C5D7FF4E408282CBEFB5D06CBF414AF2E19D982AC45AC98B8544C908B4507DE1E90B717C3D34816FE926A2B98F53AFD2FA0F30AFF")]
// COSE_Signature
[InlineData("D8628440A054546869732069732074686520636F6E74656E742E819F43A10126A1044231315840E2AEAFD40D69D19DFE6E52077C5D7FF4E408282CBEFB5D06CBF414AF2E19D982AC45AC98B8544C908B4507DE1E90B717C3D34816FE926A2B98F53AFD2FA0F30AFF")]
// All of them
[InlineData("D8629F40A054546869732069732074686520636F6E74656E742E9F9F43A10126A1044231315840E2AEAFD40D69D19DFE6E52077C5D7FF4E408282CBEFB5D06CBF414AF2E19D982AC45AC98B8544C908B4507DE1E90B717C3D34816FE926A2B98F53AFD2FA0F30AFFFFFF")]
public void DecodeMultiSign_IndefiniteLengthArray(string hexCborPayload)
{
byte[] cborPayload = ByteUtils.HexToByteArray(hexCborPayload);
CoseMultiSignMessage msg = CoseMessage.DecodeMultiSign(cborPayload);
ReadOnlyCollection<CoseSignature> signatures = msg.Signatures;
Assert.Equal(1, signatures.Count);
Assert.True(signatures[0].VerifyEmbedded(DefaultKey));
}
[Theory]
// COSE_Sign
[InlineData("D8629F40A054546869732069732074686520636F6E74656E742E818343A10126A1044231315840E2AEAFD40D69D19DFE6E52077C5D7FF4E408282CBEFB5D06CBF414AF2E19D982AC45AC98B8544C908B4507DE1E90B717C3D34816FE926A2B98F53AFD2FA0F30A")]
// [+COSE_Signature]
[InlineData("D8628440A054546869732069732074686520636F6E74656E742E9F8343A10126A1044231315840E2AEAFD40D69D19DFE6E52077C5D7FF4E408282CBEFB5D06CBF414AF2E19D982AC45AC98B8544C908B4507DE1E90B717C3D34816FE926A2B98F53AFD2FA0F30A")]
// COSE_Signature
[InlineData("D8628440A054546869732069732074686520636F6E74656E742E819F43A10126A1044231315840E2AEAFD40D69D19DFE6E52077C5D7FF4E408282CBEFB5D06CBF414AF2E19D982AC45AC98B8544C908B4507DE1E90B717C3D34816FE926A2B98F53AFD2FA0F30A")]
public void DecodeMultiSign_IndefiniteLengthArray_MissingBreak(string hexCborPayload)
{
byte[] cborPayload = ByteUtils.HexToByteArray(hexCborPayload);
CryptographicException ex = Assert.Throws<CryptographicException>(() => CoseMessage.DecodeMultiSign(cborPayload));
Assert.IsType<CborContentException>(ex.InnerException);
}
// All these payloads contain one extra element of type byte string.
[Theory]
// COSE_Sign
[InlineData("D8629F40A054546869732069732074686520636F6E74656E742E818343A10126A1044231315840E2AEAFD40D69D19DFE6E52077C5D7FF4E408282CBEFB5D06CBF414AF2E19D982AC45AC98B8544C908B4507DE1E90B717C3D34816FE926A2B98F53AFD2FA0F30A40FF")]
// [+COSE_Signature] - this structure does not have a fixed length required, but the byte string is unexpected.
[InlineData("D8628440A054546869732069732074686520636F6E74656E742E9F8343A10126A1044231315840E2AEAFD40D69D19DFE6E52077C5D7FF4E408282CBEFB5D06CBF414AF2E19D982AC45AC98B8544C908B4507DE1E90B717C3D34816FE926A2B98F53AFD2FA0F30A40FF")]
// COSE_Signature
[InlineData("D8628440A054546869732069732074686520636F6E74656E742E819F43A10126A1044231315840E2AEAFD40D69D19DFE6E52077C5D7FF4E408282CBEFB5D06CBF414AF2E19D982AC45AC98B8544C908B4507DE1E90B717C3D34816FE926A2B98F53AFD2FA0F30A40FF")]
public void DecodeMultiSign_IndefiniteLengthArray_LargerByOne(string hexCborPayload)
{
byte[] cborPayload = ByteUtils.HexToByteArray(hexCborPayload);
CryptographicException ex = Assert.Throws<CryptographicException>(() => CoseMessage.DecodeMultiSign(cborPayload));
}
[Theory]
// COSE_Sign
[InlineData("D8629F40A054546869732069732074686520636F6E74656E742EFF")]
// [+COSE_Signature]
[InlineData("D8628440A054546869732069732074686520636F6E74656E742E9FFF")]
// COSE_Signature
[InlineData("D8628440A054546869732069732074686520636F6E74656E742E819F43A10126A104423131FF")]
public void DecodeMultiSign_IndefiniteLengthArray_ShorterByOne(string hexCborPayload)
{
byte[] cborPayload = ByteUtils.HexToByteArray(hexCborPayload);
CryptographicException ex = Assert.Throws<CryptographicException>(() => CoseMessage.DecodeMultiSign(cborPayload));
Assert.Null(ex.InnerException);
}
}
}
......@@ -69,5 +69,38 @@ public void DecodeSign1_IncorrectStructure()
writer.WriteEndArray();
Assert.Throws<CryptographicException>(() => CoseMessage.DecodeSign1(writer.Encode()));
}
[Fact]
public void DecodeSign1_IndefiniteLengthArray()
{
byte[] cborPayload = ByteUtils.HexToByteArray("D29F43A10126A10442313154546869732069732074686520636F6E74656E742E58408EB33E4CA31D1C465AB05AAC34CC6B23D58FEF5C083106C4D25A91AEF0B0117E2AF9A291AA32E14AB834DC56ED2A223444547E01F11D3B0916E5A4C345CACB36FF");
CoseSign1Message msg = CoseMessage.DecodeSign1(cborPayload);
Assert.True(msg.VerifyEmbedded(DefaultKey));
}
[Fact]
public void DecodeSign1_IndefiniteLengthArray_MissingBreak()
{
byte[] cborPayload = ByteUtils.HexToByteArray("D29F43A10126A10442313154546869732069732074686520636F6E74656E742E58408EB33E4CA31D1C465AB05AAC34CC6B23D58FEF5C083106C4D25A91AEF0B0117E2AF9A291AA32E14AB834DC56ED2A223444547E01F11D3B0916E5A4C345CACB36");
CryptographicException ex = Assert.Throws<CryptographicException>(() => CoseMessage.DecodeSign1(cborPayload));
Assert.IsType<CborContentException>(ex.InnerException);
}
[Fact]
public void DecodeSign1_IndefiniteLengthArray_LargerByOne()
{
byte[] cborPayload = ByteUtils.HexToByteArray("D29F43A10126A10442313154546869732069732074686520636F6E74656E742E58408EB33E4CA31D1C465AB05AAC34CC6B23D58FEF5C083106C4D25A91AEF0B0117E2AF9A291AA32E14AB834DC56ED2A223444547E01F11D3B0916E5A4C345CACB3640FF");
CryptographicException ex = Assert.Throws<CryptographicException>(() => CoseMessage.DecodeSign1(cborPayload));
Assert.Null(ex.InnerException);
}
[Fact]
public void DecodeSign1_IndefiniteLengthArray_ShorterByOne()
{
byte[] cborPayload = ByteUtils.HexToByteArray("D29F43A10126A10442313154546869732069732074686520636F6E74656E742EFF");
CryptographicException ex = Assert.Throws<CryptographicException>(() => CoseMessage.DecodeSign1(cborPayload));
Assert.Null(ex.InnerException);
}
}
}
......@@ -541,17 +541,17 @@ internal enum CoseMessageKind
MultiSign = 98
}
internal static void WriteDummyCritHeaderValue(CborWriter writer)
internal static void WriteDummyCritHeaderValue(CborWriter writer, bool useIndefiniteLength = false)
{
writer.WriteStartArray(1);
writer.WriteStartArray(useIndefiniteLength ? null : 1);
writer.WriteInt32(42);
writer.WriteEndArray();
}
internal static byte[] GetDummyCritHeaderValue()
internal static byte[] GetDummyCritHeaderValue(bool useIndefiniteLength = false)
{
var writer = new CborWriter();
WriteDummyCritHeaderValue(writer);
WriteDummyCritHeaderValue(writer, useIndefiniteLength);
return writer.Encode();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册