Skip to content

Commit

Permalink
Improve handling of integers larger/smaller than int32 in Alg header
Browse files Browse the repository at this point in the history
  • Loading branch information
jozkee committed Mar 15, 2022
1 parent 531c4d9 commit e937c1a
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<Reference Include="System.Security.Cryptography.Primitives" />
<Reference Include="System.Security.Cryptography.Algorithms" />
<Reference Include="System.Runtime" />
<Reference Include="System.Runtime.Numerics" />
</ItemGroup>

<ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,17 +214,28 @@ static void ValidateAlgorithmHeader(ReadOnlyMemory<byte> encodedAlg, int expecte
var reader = new CborReader(encodedAlg);
CborReaderState state = reader.PeekState();

if (state == CborReaderState.NegativeInteger || state == CborReaderState.UnsignedInteger)
if (state == CborReaderState.UnsignedInteger)
{
int alg = reader.ReadInt32();
KnownCoseAlgorithms.ThrowUnsignedIntegerNotSupported(reader.ReadUInt64());
}
else if (state == CborReaderState.NegativeInteger)
{
ulong cborNegativeIntRepresentation = reader.ReadCborNegativeIntegerRepresentation();

if (cborNegativeIntRepresentation > long.MaxValue)
{
KnownCoseAlgorithms.ThrowCborNegativeIntegerNotSupported(cborNegativeIntRepresentation);
}

long alg = checked(-1L - (long)cborNegativeIntRepresentation);
KnownCoseAlgorithms.ThrowIfNotSupported(alg);

if (reader.BytesRemaining != 0)
{
throw new CryptographicException(SR.Sign1VerifyAlgHeaderWasIncorrect);
}

return alg;
return (int)alg;
}

if (state == CborReaderState.TextString)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Numerics;

namespace System.Security.Cryptography.Cose
{
// https://www.iana.org/assignments/cose/cose.xhtml#algorithms
Expand All @@ -15,14 +17,20 @@ internal static class KnownCoseAlgorithms
internal const int PS384 = -38;
internal const int PS512 = -39;

internal static void ThrowIfNotSupported(int alg)
internal static void ThrowIfNotSupported(long alg)
{
if (alg != ES256 && alg > ES384 && alg < PS512)
{
throw new CryptographicException(SR.Format(SR.Sign1UnknownCoseAlgorithm, alg));
}
}

internal static void ThrowUnsignedIntegerNotSupported(ulong alg) // All algorithm valid values are negatives.
=> throw new CryptographicException(SR.Format(SR.Sign1UnknownCoseAlgorithm, alg));

internal static void ThrowCborNegativeIntegerNotSupported(ulong alg) // Cbor Negative Integer Representation is too big.
=> throw new CryptographicException(SR.Format(SR.Sign1UnknownCoseAlgorithm, BigInteger.MinusOne - new BigInteger(alg)));

internal static int FromString(string algString)
{
return algString switch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,5 +474,60 @@ static object[] ReturnDataAndReset(bool useProtectedMap, CborWriter w)
return new object[] { useProtectedMap, encodedValue };
}
}

[Theory]
[InlineData(0L)]
[InlineData(long.MaxValue)]
[InlineData(long.MinValue)]
[InlineData(int.MinValue - 1L)]
[InlineData(int.MaxValue + 1L)]
public void SignWithInt64AlgorithmHeaderValue(long value)
{
var writer = new CborWriter();
writer.WriteInt64(value);

byte[] encodedValue = writer.Encode();

CoseHeaderMap protectedHeaders = new CoseHeaderMap();
protectedHeaders.SetEncodedValue(CoseHeaderLabel.Algorithm, encodedValue);

Assert.Throws<CryptographicException>(() => CoseSign1Message.Sign(s_sampleContent, DefaultKey, DefaultHash, protectedHeaders));
}

[Theory]
[InlineData(0UL)]
[InlineData(ulong.MaxValue)]
[InlineData(long.MaxValue + 1UL)]
[InlineData(long.MaxValue - 1UL)]
public void SignWithUInt64AlgorithmHeaderValue(ulong value)
{
var writer = new CborWriter();
writer.WriteUInt64(value);

byte[] encodedValue = writer.Encode();

CoseHeaderMap protectedHeaders = new CoseHeaderMap();
protectedHeaders.SetEncodedValue(CoseHeaderLabel.Algorithm, encodedValue);

Assert.Throws<CryptographicException>(() => CoseSign1Message.Sign(s_sampleContent, DefaultKey, DefaultHash, protectedHeaders));
}

[Theory]
[InlineData(0UL)]
[InlineData(ulong.MaxValue)]
[InlineData(long.MaxValue + 1UL)]
[InlineData(long.MaxValue - 1UL)]
public void SignWithCborNegativeIntegerRepresentationAlgorithmHeaderValue(ulong value)
{
var writer = new CborWriter();
writer.WriteCborNegativeIntegerRepresentation(value);

byte[] encodedValue = writer.Encode();

CoseHeaderMap protectedHeaders = new CoseHeaderMap();
protectedHeaders.SetEncodedValue(CoseHeaderLabel.Algorithm, encodedValue);

Assert.Throws<CryptographicException>(() => CoseSign1Message.Sign(s_sampleContent, DefaultKey, DefaultHash, protectedHeaders));
}
}
}

0 comments on commit e937c1a

Please sign in to comment.