You've already forked linux-packaging-mono
Imported Upstream version 5.10.0.47
Former-commit-id: d0813289fa2d35e1f8ed77530acb4fb1df441bc0
This commit is contained in:
parent
88ff76fe28
commit
e46a49ecf1
@@ -94,10 +94,13 @@ namespace System.Security.Cryptography
|
||||
public void Dispose() { }
|
||||
protected virtual void Dispose(bool disposing) { }
|
||||
protected abstract void HashCore(byte[] array, int ibStart, int cbSize);
|
||||
protected virtual void HashCore(ReadOnlySpan<byte> source) { throw null; }
|
||||
protected abstract byte[] HashFinal();
|
||||
public abstract void Initialize();
|
||||
public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { throw null; }
|
||||
public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) { throw null; }
|
||||
public bool TryComputeHash(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten) { throw null; }
|
||||
protected virtual bool TryHashFinal(Span<byte> destination, out int bytesWritten) { throw null; }
|
||||
}
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
||||
public partial struct HashAlgorithmName : System.IEquatable<System.Security.Cryptography.HashAlgorithmName>
|
||||
|
@@ -115,4 +115,7 @@
|
||||
<data name="CryptoConfigNotSupported" xml:space="preserve">
|
||||
<value>Accessing a hash algorithm by manipulating the HashName property is not supported on this platform. Instead, you must instantiate one of the supplied subtypes (such as HMACSHA1.)</value>
|
||||
</data>
|
||||
<data name="InvalidOperation_IncorrectImplementation" xml:space="preserve">
|
||||
<value>The algorithm's implementation is incorrect.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
@@ -33,6 +33,7 @@
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Buffers" />
|
||||
<Reference Include="System.Diagnostics.Contracts" />
|
||||
<Reference Include="System.Diagnostics.Debug" />
|
||||
<Reference Include="System.Resources.ResourceManager" />
|
||||
|
@@ -6,43 +6,30 @@ namespace System.Security.Cryptography
|
||||
{
|
||||
public abstract class HMAC : KeyedHashAlgorithm
|
||||
{
|
||||
private string _hashName;
|
||||
private int _blockSizeValue = 64;
|
||||
|
||||
protected int BlockSizeValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return _blockSizeValue;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_blockSizeValue = value;
|
||||
}
|
||||
get => _blockSizeValue;
|
||||
set => _blockSizeValue = value;
|
||||
}
|
||||
|
||||
protected HMAC() { }
|
||||
|
||||
public static new HMAC Create()
|
||||
{
|
||||
return Create("System.Security.Cryptography.HMAC");
|
||||
}
|
||||
public static new HMAC Create() => Create("System.Security.Cryptography.HMAC");
|
||||
|
||||
public static new HMAC Create(string algorithmName)
|
||||
{
|
||||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
public static new HMAC Create(string algorithmName) => throw new PlatformNotSupportedException();
|
||||
|
||||
public String HashName
|
||||
public string HashName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _hashName;
|
||||
}
|
||||
get => _hashName;
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(HashName));
|
||||
}
|
||||
|
||||
// On the desktop, setting the HashName selects (or switches over to) a new hashing algorithm via CryptoConfig.
|
||||
// Our intended refactoring turns HMAC back into an abstract class with no algorithm-specific implementation.
|
||||
@@ -52,7 +39,9 @@ namespace System.Security.Cryptography
|
||||
// Since the set is public, ensure that hmac.HashName = hmac.HashName works without throwing.
|
||||
|
||||
if (_hashName != null && value != _hashName)
|
||||
{
|
||||
throw new PlatformNotSupportedException(SR.HashNameMultipleSetNotSupported);
|
||||
}
|
||||
|
||||
_hashName = value;
|
||||
}
|
||||
@@ -60,38 +49,26 @@ namespace System.Security.Cryptography
|
||||
|
||||
public override byte[] Key
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Key;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
base.Key = value;
|
||||
}
|
||||
get => base.Key;
|
||||
set => base.Key = value;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
protected override void Dispose(bool disposing) =>
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
protected override void HashCore(byte[] rgb, int ib, int cb)
|
||||
{
|
||||
protected override void HashCore(byte[] rgb, int ib, int cb) =>
|
||||
throw new PlatformNotSupportedException(SR.CryptoConfigNotSupported);
|
||||
}
|
||||
|
||||
protected override byte[] HashFinal()
|
||||
{
|
||||
protected override void HashCore(ReadOnlySpan<byte> source) =>
|
||||
throw new PlatformNotSupportedException(SR.CryptoConfigNotSupported);
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
protected override byte[] HashFinal() =>
|
||||
throw new PlatformNotSupportedException(SR.CryptoConfigNotSupported);
|
||||
}
|
||||
|
||||
private String _hashName;
|
||||
protected override bool TryHashFinal(Span<byte> destination, out int bytesWritten) =>
|
||||
throw new PlatformNotSupportedException(SR.CryptoConfigNotSupported);
|
||||
|
||||
public override void Initialize() =>
|
||||
throw new PlatformNotSupportedException(SR.CryptoConfigNotSupported);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Buffers;
|
||||
using System.IO;
|
||||
|
||||
namespace System.Security.Cryptography
|
||||
@@ -15,15 +16,9 @@ namespace System.Security.Cryptography
|
||||
|
||||
protected HashAlgorithm() { }
|
||||
|
||||
public static HashAlgorithm Create()
|
||||
{
|
||||
return Create("System.Security.Cryptography.HashAlgorithm");
|
||||
}
|
||||
public static HashAlgorithm Create() => Create("System.Security.Cryptography.HashAlgorithm");
|
||||
|
||||
public static HashAlgorithm Create(string hashName)
|
||||
{
|
||||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
public static HashAlgorithm Create(string hashName) => throw new PlatformNotSupportedException();
|
||||
|
||||
public virtual int HashSize => HashSizeValue;
|
||||
|
||||
@@ -36,7 +31,7 @@ namespace System.Security.Cryptography
|
||||
if (State != 0)
|
||||
throw new CryptographicUnexpectedOperationException(SR.Cryptography_HashNotYetFinalized);
|
||||
|
||||
return (byte[])HashValue.Clone();
|
||||
return (byte[])HashValue?.Clone();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +46,32 @@ namespace System.Security.Cryptography
|
||||
return CaptureHashCodeAndReinitialize();
|
||||
}
|
||||
|
||||
public bool TryComputeHash(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
throw new ObjectDisposedException(null);
|
||||
}
|
||||
|
||||
if (destination.Length < HashSizeValue/8)
|
||||
{
|
||||
bytesWritten = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
HashCore(source);
|
||||
if (!TryHashFinal(destination, out bytesWritten))
|
||||
{
|
||||
// The only reason for failure should be that the destination isn't long enough,
|
||||
// but we checked the size earlier.
|
||||
throw new InvalidOperationException(SR.InvalidOperation_IncorrectImplementation);
|
||||
}
|
||||
HashValue = null;
|
||||
|
||||
Initialize();
|
||||
return true;
|
||||
}
|
||||
|
||||
public byte[] ComputeHash(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (buffer == null)
|
||||
@@ -121,25 +142,10 @@ namespace System.Security.Cryptography
|
||||
// ICryptoTransform methods
|
||||
|
||||
// We assume any HashAlgorithm can take input a byte at a time
|
||||
public virtual int InputBlockSize
|
||||
{
|
||||
get { return (1); }
|
||||
}
|
||||
|
||||
public virtual int OutputBlockSize
|
||||
{
|
||||
get { return (1); }
|
||||
}
|
||||
|
||||
public virtual bool CanTransformMultipleBlocks
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public virtual bool CanReuseTransform
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
public virtual int InputBlockSize => 1;
|
||||
public virtual int OutputBlockSize => 1;
|
||||
public virtual bool CanTransformMultipleBlocks => true;
|
||||
public virtual bool CanReuseTransform => true;
|
||||
|
||||
public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
|
||||
{
|
||||
@@ -198,5 +204,41 @@ namespace System.Security.Cryptography
|
||||
protected abstract void HashCore(byte[] array, int ibStart, int cbSize);
|
||||
protected abstract byte[] HashFinal();
|
||||
public abstract void Initialize();
|
||||
|
||||
protected virtual void HashCore(ReadOnlySpan<byte> source)
|
||||
{
|
||||
byte[] array = ArrayPool<byte>.Shared.Rent(source.Length);
|
||||
try
|
||||
{
|
||||
source.CopyTo(array);
|
||||
HashCore(array, 0, source.Length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Array.Clear(array, 0, source.Length);
|
||||
ArrayPool<byte>.Shared.Return(array);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual bool TryHashFinal(Span<byte> destination, out int bytesWritten)
|
||||
{
|
||||
int hashSizeInBytes = HashSizeValue / 8;
|
||||
|
||||
if (destination.Length >= hashSizeInBytes)
|
||||
{
|
||||
byte[] final = HashFinal();
|
||||
if (final.Length == hashSizeInBytes)
|
||||
{
|
||||
new ReadOnlySpan<byte>(final).CopyTo(destination);
|
||||
bytesWritten = final.Length;
|
||||
return true;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException(SR.InvalidOperation_IncorrectImplementation);
|
||||
}
|
||||
|
||||
bytesWritten = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,52 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Security.Cryptography.Hashing.Tests
|
||||
{
|
||||
public partial class HashAlgorithmTest
|
||||
{
|
||||
[Fact]
|
||||
public void SpanMethodsUsed_NotOverridden_ArrayMethodsInvoked()
|
||||
{
|
||||
byte[] input = Enumerable.Range(0, 1024).Select(i => (byte)i).ToArray();
|
||||
byte[] output;
|
||||
int bytesWritten;
|
||||
|
||||
var testAlgorithm = new SummingTestHashAlgorithm();
|
||||
|
||||
output = new byte[sizeof(long) - 1];
|
||||
Assert.False(testAlgorithm.TryComputeHash(input, output, out bytesWritten));
|
||||
Assert.Equal(0, bytesWritten);
|
||||
Assert.Equal<byte>(new byte[sizeof(long) - 1], output);
|
||||
|
||||
output = new byte[sizeof(long)];
|
||||
Assert.True(testAlgorithm.TryComputeHash(input, output, out bytesWritten));
|
||||
Assert.Equal(sizeof(long), bytesWritten);
|
||||
Assert.Equal(input.Sum(b => (long)b), BitConverter.ToInt64(output, 0));
|
||||
}
|
||||
|
||||
private sealed class SummingTestHashAlgorithm : HashAlgorithm
|
||||
{
|
||||
private long _sum;
|
||||
|
||||
public SummingTestHashAlgorithm() => HashSizeValue = sizeof(long)*8;
|
||||
|
||||
public override void Initialize() => _sum = 0;
|
||||
|
||||
protected override void HashCore(byte[] array, int ibStart, int cbSize)
|
||||
{
|
||||
for (int i = ibStart; i < ibStart + cbSize; i++) _sum += array[i];
|
||||
}
|
||||
|
||||
protected override byte[] HashFinal() => BitConverter.GetBytes(_sum);
|
||||
|
||||
// Do not override HashCore(ReadOnlySpan) and TryHashFinal. Consuming
|
||||
// test verifies that calling the base implementations invokes the array
|
||||
// implementations by verifying the right value is produced.
|
||||
}
|
||||
}
|
||||
}
|
@@ -24,12 +24,10 @@
|
||||
<Compile Include="$(CommonTestPath)\System\IO\PositionValueStream.cs">
|
||||
<Link>CommonTest\System\IO\PositionValueStream.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)\System\PlatformDetection.cs">
|
||||
<Link>CommonTest\System\PlatformDetection.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetGroup)'=='netcoreapp'">
|
||||
<Compile Include="CryptoConfigTests.cs" />
|
||||
<Compile Include="HashAlgorithmTest.netcoreapp.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
</Project>
|
Reference in New Issue
Block a user