зеркало из https://github.com/dotnet/aspnetcore.git
Simplify Guid reading/writing code in DataProtection (#36403)
Simplify Guid reading/writing code in DataProtection.
This commit is contained in:
Родитель
bb0cde1935
Коммит
8392779338
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Microsoft.AspNetCore.Cryptography;
|
using Microsoft.AspNetCore.Cryptography;
|
||||||
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
||||||
|
@ -128,7 +129,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
fixed (byte* pbRetVal = retVal)
|
fixed (byte* pbRetVal = retVal)
|
||||||
{
|
{
|
||||||
WriteBigEndianInteger(pbRetVal, MAGIC_HEADER_V0);
|
WriteBigEndianInteger(pbRetVal, MAGIC_HEADER_V0);
|
||||||
Write32bitAlignedGuid(&pbRetVal[sizeof(uint)], defaultKeyId);
|
WriteGuid(&pbRetVal[sizeof(uint)], defaultKeyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point, retVal := { magicHeader || keyId || encryptorSpecificProtectedPayload }
|
// At this point, retVal := { magicHeader || keyId || encryptorSpecificProtectedPayload }
|
||||||
|
@ -142,36 +143,17 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to read a GUID from a 32-bit alignment; useful on architectures where unaligned reads
|
private static Guid ReadGuid(void* ptr)
|
||||||
// can result in weird behaviors at runtime.
|
|
||||||
private static Guid Read32bitAlignedGuid(void* ptr)
|
|
||||||
{
|
{
|
||||||
Debug.Assert((long)ptr % 4 == 0);
|
#if NETCOREAPP
|
||||||
|
// Performs appropriate endianness fixups
|
||||||
Guid retVal;
|
return new Guid(new ReadOnlySpan<byte>(ptr, sizeof(Guid)));
|
||||||
if (BitConverter.IsLittleEndian)
|
#elif NETSTANDARD2_0 || NETFRAMEWORK
|
||||||
{
|
Debug.Assert(BitConverter.IsLittleEndian);
|
||||||
((int*)&retVal)[0] = ((int*)ptr)[0];
|
return Unsafe.ReadUnaligned<Guid>(ptr);
|
||||||
((int*)&retVal)[1] = ((int*)ptr)[1];
|
#else
|
||||||
((int*)&retVal)[2] = ((int*)ptr)[2];
|
#error Update target frameworks
|
||||||
((int*)&retVal)[3] = ((int*)ptr)[3];
|
#endif
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// The first 8 bytes of the Guid hold one 32-bit integer
|
|
||||||
// and two 16-bit integers that must be byte-swapped.
|
|
||||||
((byte*)&retVal)[0] = ((byte*)ptr)[3];
|
|
||||||
((byte*)&retVal)[1] = ((byte*)ptr)[2];
|
|
||||||
((byte*)&retVal)[2] = ((byte*)ptr)[1];
|
|
||||||
((byte*)&retVal)[3] = ((byte*)ptr)[0];
|
|
||||||
((byte*)&retVal)[4] = ((byte*)ptr)[5];
|
|
||||||
((byte*)&retVal)[5] = ((byte*)ptr)[4];
|
|
||||||
((byte*)&retVal)[6] = ((byte*)ptr)[7];
|
|
||||||
((byte*)&retVal)[7] = ((byte*)ptr)[6];
|
|
||||||
((int*)&retVal)[2] = ((int*)ptr)[2];
|
|
||||||
((int*)&retVal)[3] = ((int*)ptr)[3];
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static uint ReadBigEndian32BitInteger(byte* ptr)
|
private static uint ReadBigEndian32BitInteger(byte* ptr)
|
||||||
|
@ -233,7 +215,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
fixed (byte* pbInput = protectedData)
|
fixed (byte* pbInput = protectedData)
|
||||||
{
|
{
|
||||||
magicHeaderFromPayload = ReadBigEndian32BitInteger(pbInput);
|
magicHeaderFromPayload = ReadBigEndian32BitInteger(pbInput);
|
||||||
keyIdFromPayload = Read32bitAlignedGuid(&pbInput[sizeof(uint)]);
|
keyIdFromPayload = ReadGuid(&pbInput[sizeof(uint)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are the magic header and version information correct?
|
// Are the magic header and version information correct?
|
||||||
|
@ -318,34 +300,20 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to write a GUID to a 32-bit alignment; useful on ARM where unaligned reads
|
private static void WriteGuid(void* ptr, Guid value)
|
||||||
// can result in weird behaviors at runtime.
|
|
||||||
private static void Write32bitAlignedGuid(void* ptr, Guid value)
|
|
||||||
{
|
{
|
||||||
Debug.Assert((long)ptr % 4 == 0);
|
#if NETCOREAPP
|
||||||
|
var span = new Span<byte>(ptr, sizeof(Guid));
|
||||||
|
|
||||||
if (BitConverter.IsLittleEndian)
|
// Performs appropriate endianness fixups
|
||||||
{
|
var success = value.TryWriteBytes(span);
|
||||||
((int*)ptr)[0] = ((int*)&value)[0];
|
Debug.Assert(success, "Failed to write Guid.");
|
||||||
((int*)ptr)[1] = ((int*)&value)[1];
|
#elif NETSTANDARD2_0 || NETFRAMEWORK
|
||||||
((int*)ptr)[2] = ((int*)&value)[2];
|
Debug.Assert(BitConverter.IsLittleEndian);
|
||||||
((int*)ptr)[3] = ((int*)&value)[3];
|
Unsafe.WriteUnaligned<Guid>(ptr, value);
|
||||||
}
|
#else
|
||||||
else
|
#error Update target frameworks
|
||||||
{
|
#endif
|
||||||
// The first 8 bytes of the Guid hold one 32-bit integer
|
|
||||||
// and two 16-bit integers that must be byte-swapped.
|
|
||||||
((byte*)ptr)[0] = ((byte*)&value)[3];
|
|
||||||
((byte*)ptr)[1] = ((byte*)&value)[2];
|
|
||||||
((byte*)ptr)[2] = ((byte*)&value)[1];
|
|
||||||
((byte*)ptr)[3] = ((byte*)&value)[0];
|
|
||||||
((byte*)ptr)[4] = ((byte*)&value)[5];
|
|
||||||
((byte*)ptr)[5] = ((byte*)&value)[4];
|
|
||||||
((byte*)ptr)[6] = ((byte*)&value)[7];
|
|
||||||
((byte*)ptr)[7] = ((byte*)&value)[6];
|
|
||||||
((int*)ptr)[2] = ((int*)&value)[2];
|
|
||||||
((int*)ptr)[3] = ((int*)&value)[3];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteBigEndianInteger(byte* ptr, uint value)
|
private static void WriteBigEndianInteger(byte* ptr, uint value)
|
||||||
|
@ -402,7 +370,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
// The caller will not mutate it.
|
// The caller will not mutate it.
|
||||||
fixed (byte* pExistingTemplate = existingTemplate)
|
fixed (byte* pExistingTemplate = existingTemplate)
|
||||||
{
|
{
|
||||||
if (Read32bitAlignedGuid(&pExistingTemplate[sizeof(uint)]) == keyId)
|
if (ReadGuid(&pExistingTemplate[sizeof(uint)]) == keyId)
|
||||||
{
|
{
|
||||||
return existingTemplate;
|
return existingTemplate;
|
||||||
}
|
}
|
||||||
|
@ -415,7 +383,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
||||||
byte[] newTemplate = (byte[])existingTemplate.Clone();
|
byte[] newTemplate = (byte[])existingTemplate.Clone();
|
||||||
fixed (byte* pNewTemplate = newTemplate)
|
fixed (byte* pNewTemplate = newTemplate)
|
||||||
{
|
{
|
||||||
Write32bitAlignedGuid(&pNewTemplate[sizeof(uint)], keyId);
|
WriteGuid(&pNewTemplate[sizeof(uint)], keyId);
|
||||||
if (isProtecting)
|
if (isProtecting)
|
||||||
{
|
{
|
||||||
Volatile.Write(ref _aadTemplate, newTemplate);
|
Volatile.Write(ref _aadTemplate, newTemplate);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче