Skip to content

Commit

Permalink
Use platform runtime check for ProtectedData (#80158)
Browse files Browse the repository at this point in the history
* Use platform runtime check for ProtectedData

* Remove duplicate TargetFramework
  • Loading branch information
vcsjones authored Jan 4, 2023
1 parent abc04f2 commit 7690b0a
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppPrevious)-windows;$(NetCoreAppPrevious);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum)</TargetFrameworks>
<TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum)</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IsPackable>true</IsPackable>
<AddXamarinPlaceholderFilesToPackage>true</AddXamarinPlaceholderFilesToPackage>
Expand All @@ -13,13 +13,11 @@ System.Security.Cryptography.ProtectedData</PackageDescription>

<!-- DesignTimeBuild requires all the TargetFramework Derived Properties to not be present in the first property group. -->
<PropertyGroup>
<TargetPlatformIdentifier>$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))</TargetPlatformIdentifier>
<IsPartialFacadeAssembly Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETFramework'">true</IsPartialFacadeAssembly>
<OmitResources Condition="'$(IsPartialFacadeAssembly)' == 'true'">true</OmitResources>
<GeneratePlatformNotSupportedAssemblyMessage Condition="'$(IsPartialFacadeAssembly)' != 'true' and '$(TargetPlatformIdentifier)' != 'windows'">SR.PlatformNotSupported_CryptographyProtectedData</GeneratePlatformNotSupportedAssemblyMessage>
</PropertyGroup>

<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'windows'">
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true'">
<Compile Include="System\Security\Cryptography\DataProtectionScope.cs" />
<Compile Include="System\Security\Cryptography\ProtectedData.cs" />
<Compile Include="$(CommonPath)Interop\Windows\Crypt32\Interop.CryptProtectData.cs"
Expand All @@ -42,12 +40,16 @@ System.Security.Cryptography.ProtectedData</PackageDescription>
Link="Common\System\Security\Cryptography\CryptoThrowHelper.Windows.cs" />
</ItemGroup>

<ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0-windows'))">
<ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">
<Compile Include="$(CommonPath)DisableRuntimeMarshalling.cs"
Link="Common\DisableRuntimeMarshalling.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
<Reference Include="System.Security" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETStandard'">
<PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,20 @@ public static partial class ProtectedData

public static byte[] Protect(byte[] userData, byte[]? optionalEntropy, DataProtectionScope scope)
{
ArgumentNullException.ThrowIfNull(userData);
CheckPlatformSupport();

if (userData is null)
throw new ArgumentNullException(nameof(userData));

return ProtectOrUnprotect(userData, optionalEntropy, scope, protect: true);
}

public static byte[] Unprotect(byte[] encryptedData, byte[]? optionalEntropy, DataProtectionScope scope)
{
ArgumentNullException.ThrowIfNull(encryptedData);
CheckPlatformSupport();

if (encryptedData is null)
throw new ArgumentNullException(nameof(encryptedData));

return ProtectOrUnprotect(encryptedData, optionalEntropy, scope, protect: false);
}
Expand Down Expand Up @@ -61,7 +67,11 @@ private static byte[] ProtectOrUnprotect(byte[] inputData, byte[]? optionalEntro
Interop.Crypt32.CryptUnprotectData(in userDataBlob, IntPtr.Zero, ref optionalEntropyBlob, IntPtr.Zero, IntPtr.Zero, flags, out outputBlob);
if (!success)
{
#if NET
int lastWin32Error = Marshal.GetLastPInvokeError();
#else
int lastWin32Error = Marshal.GetLastWin32Error();
#endif
if (protect && ErrorMayBeCausedByUnloadedProfile(lastWin32Error))
throw new CryptographicException(SR.Cryptography_DpApi_ProfileMayNotBeLoaded);
else
Expand Down Expand Up @@ -102,5 +112,13 @@ private static bool ErrorMayBeCausedByUnloadedProfile(int errorCode)
return errorCode == HResults.E_FILENOTFOUND ||
errorCode == Interop.Errors.ERROR_FILE_NOT_FOUND;
}

private static void CheckPlatformSupport()
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
throw new PlatformNotSupportedException();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Security.Cryptography;

using Xunit;

namespace System.Security.Cryptography.ProtectedDataTests
{
[PlatformSpecific(~TestPlatforms.Windows)]
public static class ProtectedUnsupportedDataTests
{
[Theory]
[InlineData(DataProtectionScope.LocalMachine)]
[InlineData(DataProtectionScope.CurrentUser)]
public static void Protect_PlatformNotSupported(DataProtectionScope scope)
{
Assert.Throws<PlatformNotSupportedException>(() => ProtectedData.Protect(null, null, scope));
}

[Theory]
[InlineData(DataProtectionScope.LocalMachine)]
[InlineData(DataProtectionScope.CurrentUser)]
public static void Unprotect_PlatformNotSupported(DataProtectionScope scope)
{
Assert.Throws<PlatformNotSupportedException>(() => ProtectedData.Unprotect(null, null, scope));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetFrameworkMinimum)</TargetFrameworks>
<TargetFrameworks>$(NetCoreAppCurrent);$(NetFrameworkMinimum)</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<Compile Include="ProtectedDataTests.cs" />
<Compile Include="ProtectedDataUnsupportedTests.cs" />
<Compile Include="$(CommonTestPath)System\Security\Cryptography\ByteUtils.cs"
Link="CommonTest\System\Security\Cryptography\ByteUtils.cs" />
</ItemGroup>
Expand Down

0 comments on commit 7690b0a

Please sign in to comment.