Browse Source

Ensure DataProtection can be used in trimmed apps. (#48082)

* Add a DynamicDependency to ensure Aes decryption works in EncryptedXmlDecryptor
* Suppress the warnings from EncryptedXml
* Add trimming tests to ensure these scenarios work correctly.
* Remove the RequiresUnreferencedCode attribute on AddAuthentication, since this is the only thing in that method that has warnings.

Fix #47695

* Fix parallel build to not copy files to the same destination
Eric Erhardt 2 years ago
parent
commit
3ff3207c6f
71 changed files with 373 additions and 34 deletions
  1. 1 1
      AspNetCore.sln
  2. 2 1
      eng/RequiresDelayedBuildProjects.props
  3. 3 2
      eng/testing/linker/SupportFiles/Directory.Build.targets
  4. 4 2
      eng/testing/linker/trimmingTests.targets
  5. 1 1
      src/DataProtection/DataProtection.slnf
  6. 0 17
      src/DataProtection/DataProtection/src/Microsoft.AspNetCore.DataProtection.WarningSuppressions.xml
  7. 3 3
      src/DataProtection/DataProtection/src/XmlEncryption/CertificateXmlEncryptor.cs
  8. 9 2
      src/DataProtection/DataProtection/src/XmlEncryption/EncryptedXmlDecryptor.cs
  9. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/ActivatorTests.cs
  10. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/CngCbcAuthenticatedEncryptorFactoryTest.cs
  11. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/CngGcmAuthenticatedEncryptorFactoryTest.cs
  12. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorDeserializerTests.cs
  13. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorTests.cs
  14. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorConfigurationTests.cs
  15. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorDescriptorDeserializerTests.cs
  16. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorDescriptorTests.cs
  17. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorConfigurationTests.cs
  18. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptorDeserializerTests.cs
  19. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptorTests.cs
  20. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorConfigurationTests.cs
  21. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorDeserializerTests.cs
  22. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorTests.cs
  23. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ManagedAuthenticatedEncryptorFactoryTest.cs
  24. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Cng/CbcAuthenticatedEncryptorTests.cs
  25. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Cng/CngAuthenticatedEncryptorBaseTests.cs
  26. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Cng/GcmAuthenticatedEncryptorTests.cs
  27. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/ContainerUtilsTests.cs
  28. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/DataProtectionUtilityExtensionsTests.cs
  29. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/EphemeralDataProtectionProviderTests.cs
  30. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/HostingTests.cs
  31. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Internal/KeyManagementOptionsSetupTest.cs
  32. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/CacheableKeyRingTests.cs
  33. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/DefaultKeyResolverTests.cs
  34. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/DeferredKeyTests.cs
  35. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/KeyEscrowServiceProviderExtensionsTests.cs
  36. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/KeyRingBasedDataProtectorTests.cs
  37. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/KeyRingProviderTests.cs
  38. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/KeyRingTests.cs
  39. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/KeyTests.cs
  40. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/XmlKeyManagerTests.cs
  41. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Managed/ManagedAuthenticatedEncryptorTests.cs
  42. 1 1
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Microsoft.AspNetCore.DataProtection.Tests.csproj
  43. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/MockExtensions.cs
  44. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/RegistryPolicyResolverTests.cs
  45. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Repositories/EphemeralXmlRepositoryTests.cs
  46. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Repositories/FileSystemXmlRepositoryTests.cs
  47. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Repositories/RegistryXmlRepositoryTests.cs
  48. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/SP800_108/SP800_108Tests.cs
  49. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/SecretAssert.cs
  50. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/SecretTests.cs
  51. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/SequentialGenRandom.cs
  52. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/ServiceCollectionTests.cs
  53. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/StringLoggerFactory.cs
  54. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/TestFiles/TestCert1.PublicKeyOnly.cer
  55. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/TestFiles/TestCert1.pfx
  56. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/TestFiles/TestCert2.pfx
  57. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/TypeForwardingActivatorTests.cs
  58. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlAssert.cs
  59. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlEncryption/CertificateXmlEncryptionTests.cs
  60. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlEncryption/DpapiNGXmlEncryptionTests.cs
  61. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlEncryption/DpapiXmlEncryptionTests.cs
  62. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlEncryption/EncryptedXmlDecryptorTests.cs
  63. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlEncryption/NullXmlEncryptionTests.cs
  64. 0 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlEncryption/XmlEncryptionExtensionsTests.cs
  65. 94 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.TrimmingTests/Constants.cs
  66. 12 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.TrimmingTests/Microsoft.AspNetCore.DataProtection.TrimmingTests.proj
  67. 31 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.TrimmingTests/TestCertificateXmlEncryptor.cs
  68. 41 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.TrimmingTests/TestEncryptedXmlDecryptor.cs
  69. 24 0
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.TrimmingTests/TestUnprotectWorksWithX509Certificate.cs
  70. 0 4
      src/Security/Authentication/Core/src/AuthenticationServiceCollectionExtensions.cs
  71. 147 0
      src/Shared/TrimmingAttributes.cs

+ 1 - 1
AspNetCore.sln

@@ -499,7 +499,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Crypto
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Cryptography.KeyDerivation.Tests", "src\DataProtection\Cryptography.KeyDerivation\test\Microsoft.AspNetCore.Cryptography.KeyDerivation.Tests.csproj", "{F421D0C4-6EF7-48B7-9213-AFD21322E08B}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DataProtection.Tests", "src\DataProtection\DataProtection\test\Microsoft.AspNetCore.DataProtection.Tests.csproj", "{696BE515-B3AB-4925-969C-350F1BDA5C30}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DataProtection.Tests", "src\DataProtection\DataProtection\test\Microsoft.AspNetCore.DataProtection.Tests\Microsoft.AspNetCore.DataProtection.Tests.csproj", "{696BE515-B3AB-4925-969C-350F1BDA5C30}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DataProtection.Extensions.Tests", "src\DataProtection\Extensions\test\Microsoft.AspNetCore.DataProtection.Extensions.Tests.csproj", "{3CB3CA43-6D65-4DDE-B5E3-A9E0DF957E38}"
 EndProject

+ 2 - 1
eng/RequiresDelayedBuildProjects.props

@@ -8,6 +8,8 @@
 -->
 <Project>
   <ItemGroup>
+    <RequiresDelayedBuild Include="$(RepoRoot)src\DataProtection\DataProtection\test\Microsoft.AspNetCore.DataProtection.TrimmingTests\Microsoft.AspNetCore.DataProtection.TrimmingTests.proj" />
+    <RequiresDelayedBuild Include="$(RepoRoot)src\DefaultBuilder\test\Microsoft.AspNetCore.NativeAotTests\Microsoft.AspNetCore.NativeAotTests.proj" />
     <RequiresDelayedBuild Include="$(RepoRoot)src\Grpc\JsonTranscoding\perf\Microsoft.AspNetCore.Grpc.Microbenchmarks\Microsoft.AspNetCore.Grpc.Microbenchmarks.csproj" />
     <RequiresDelayedBuild Include="$(RepoRoot)src\Grpc\JsonTranscoding\src\Microsoft.AspNetCore.Grpc.JsonTranscoding\Microsoft.AspNetCore.Grpc.JsonTranscoding.csproj" />
     <RequiresDelayedBuild Include="$(RepoRoot)src\Grpc\JsonTranscoding\src\Microsoft.AspNetCore.Grpc.Swagger\Microsoft.AspNetCore.Grpc.Swagger.csproj" />
@@ -17,6 +19,5 @@
     <RequiresDelayedBuild Include="$(RepoRoot)src\Grpc\JsonTranscoding\test\testassets\IntegrationTestsWebsite\IntegrationTestsWebsite.csproj" />
     <RequiresDelayedBuild Include="$(RepoRoot)src\Grpc\JsonTranscoding\test\testassets\Sandbox\Sandbox.csproj" />
     <RequiresDelayedBuild Include="$(RepoRoot)src\ProjectTemplates\test\Templates.Blazor.Tests\Templates.Blazor.Tests.csproj" />
-    <RequiresDelayedBuild Include="$(RepoRoot)src\DefaultBuilder\test\Microsoft.AspNetCore.NativeAotTests\Microsoft.AspNetCore.NativeAotTests.proj" />
   </ItemGroup>
 </Project>

+ 3 - 2
eng/testing/linker/SupportFiles/Directory.Build.targets

@@ -1,5 +1,5 @@
 <Project>
-  
+
   <PropertyGroup>
     <!-- Used to silence the warning caused by the workaround for https://github.com/dotnet/runtime/issues/81382 -->
     <SuppressGenerateILCompilerExplicitPackageReferenceWarning>true</SuppressGenerateILCompilerExplicitPackageReferenceWarning>
@@ -20,6 +20,7 @@
   -->
   <ItemGroup>
     <ProjectReference Include="$(RepoRoot)src\DefaultBuilder\src\Microsoft.AspNetCore.csproj" />
+    <ProjectReference Include="$(RepoRoot)src\DataProtection\Extensions\src\Microsoft.AspNetCore.DataProtection.Extensions.csproj" />
   </ItemGroup>
-  
+
 </Project>

+ 4 - 2
eng/testing/linker/trimmingTests.targets

@@ -5,7 +5,7 @@
     <TestConsoleAppSourceFiles Condition="'@(TestConsoleAppSourceFiles)' == ''" Include="$(MSBuildProjectDirectory)\*.cs" />
 
     <TestSupportFiles Include="$(MSBuildThisFileDirectory)SupportFiles\Directory.Build.*">
-      <DestinationFolder>$(TrimmingTestDir)</DestinationFolder>
+      <DestinationFolder>$([MSBuild]::NormalizeDirectory('$(TrimmingTestProjectsDir)', '$(MSBuildProjectName)'))</DestinationFolder>
     </TestSupportFiles>
   </ItemGroup>
 
@@ -13,7 +13,9 @@
           Inputs="@(TestSupportFiles)"
           Outputs="@(TestSupportFiles->'%(DestinationFolder)\%(FileName)%(Extension)')">
     <MakeDir Directories="%(TestSupportFiles.DestinationFolder)" />
-    <Copy SourceFiles="@(TestSupportFiles)" DestinationFolder="%(TestSupportFiles.DestinationFolder)" />
+    <Copy SourceFiles="@(TestSupportFiles)"
+          DestinationFolder="%(TestSupportFiles.DestinationFolder)"
+          SkipUnchangedFiles="true" />
   </Target>
 
   <Target Name="GetTestConsoleApps">

+ 1 - 1
src/DataProtection/DataProtection.slnf

@@ -9,7 +9,7 @@
       "src\\DataProtection\\Cryptography.KeyDerivation\\src\\Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj",
       "src\\DataProtection\\Cryptography.KeyDerivation\\test\\Microsoft.AspNetCore.Cryptography.KeyDerivation.Tests.csproj",
       "src\\DataProtection\\DataProtection\\src\\Microsoft.AspNetCore.DataProtection.csproj",
-      "src\\DataProtection\\DataProtection\\test\\Microsoft.AspNetCore.DataProtection.Tests.csproj",
+      "src\\DataProtection\\DataProtection\\test\\Microsoft.AspNetCore.DataProtection.Tests\\Microsoft.AspNetCore.DataProtection.Tests.csproj",
       "src\\DataProtection\\EntityFrameworkCore\\src\\Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.csproj",
       "src\\DataProtection\\EntityFrameworkCore\\test\\Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.Test.csproj",
       "src\\DataProtection\\Extensions\\src\\Microsoft.AspNetCore.DataProtection.Extensions.csproj",

+ 0 - 17
src/DataProtection/DataProtection/src/Microsoft.AspNetCore.DataProtection.WarningSuppressions.xml

@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<linker>
-  <assembly fullname="Microsoft.AspNetCore.DataProtection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
-    <attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
-      <argument>ILLink</argument>
-      <argument>IL2026</argument>
-      <property name="Scope">member</property>
-      <property name="Target">M:Microsoft.AspNetCore.DataProtection.XmlEncryption.CertificateXmlEncryptor.EncryptElement(System.Xml.Linq.XElement)</property>
-    </attribute>
-    <attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
-      <argument>ILLink</argument>
-      <argument>IL2026</argument>
-      <property name="Scope">member</property>
-      <property name="Target">M:Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.EncryptedXmlWithCertificateKeys.#ctor(Microsoft.AspNetCore.DataProtection.XmlEncryption.XmlKeyDecryptionOptions,System.Xml.XmlDocument)</property>
-    </attribute>
-  </assembly>
-</linker>

+ 3 - 3
src/DataProtection/DataProtection/src/XmlEncryption/CertificateXmlEncryptor.cs

@@ -76,8 +76,10 @@ public sealed class CertificateXmlEncryptor : IInternalCertificateXmlEncryptor,
         return new EncryptedXmlInfo(encryptedElement, typeof(EncryptedXmlDecryptor));
     }
 
+    [UnconditionalSuppressMessage("AOT", "IL2026:RequiresUnreferencedCode",
+        Justification = "This usage of EncryptedXml to encrypt an XElement using a X509Certificate2 does not use reflection.")]
     [UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode",
-        Justification = "Only XSLTs require dynamic code. The usage of EncryptedXml doesn't use XSLTs.")]
+        Justification = "This usage of EncryptedXml to encrypt an XElement using a X509Certificate2 does not use XSLTs.")]
     private XElement EncryptElement(XElement plaintextElement)
     {
         // EncryptedXml works with XmlDocument, not XLinq. When we perform the conversion
@@ -88,9 +90,7 @@ public sealed class CertificateXmlEncryptor : IInternalCertificateXmlEncryptor,
         var elementToEncrypt = (XmlElement)xmlDocument.DocumentElement!.FirstChild!;
 
         // Perform the encryption and update the document in-place.
-#pragma warning disable IL2026 // TODO: https://github.com/dotnet/aspnetcore/issues/47695
         var encryptedXml = new EncryptedXml(xmlDocument);
-#pragma warning restore IL2026
         var encryptedData = _encryptor.PerformEncryption(encryptedXml, elementToEncrypt);
         EncryptedXml.ReplaceElement(elementToEncrypt, encryptedData, content: false);
 

+ 9 - 2
src/DataProtection/DataProtection/src/XmlEncryption/EncryptedXmlDecryptor.cs

@@ -3,6 +3,7 @@
 
 using System;
 using System.Diagnostics.CodeAnalysis;
+using System.Security.Cryptography;
 using System.Security.Cryptography.X509Certificates;
 using System.Security.Cryptography.Xml;
 using System.Xml;
@@ -44,6 +45,13 @@ public sealed class EncryptedXmlDecryptor : IInternalEncryptedXmlDecryptor, IXml
     /// </summary>
     /// <param name="encryptedElement">An encrypted XML element.</param>
     /// <returns>The decrypted form of <paramref name="encryptedElement"/>.</returns>
+#pragma warning disable SYSLIB0022 // Rijndael types are obsolete
+    // RijndaelManaged (aka AES) is used by default. If we find another important algorithm, we should add it here as well.
+    // In the meantime, a useful exception will be thrown in a trimmed app if the algorithm can't be found.
+    [DynamicDependency(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor, typeof(RijndaelManaged))]
+#pragma warning restore SYSLIB0022
+    [UnconditionalSuppressMessage("AOT", "IL2026:RequiresUnreferencedCode",
+        Justification = "The common algorithms are being preserved by the above DynamicDependency attributes.")]
     [UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode",
         Justification = "Only XSLTs require dynamic code. The usage of EncryptedXml doesn't use XSLTs.")]
     public XElement Decrypt(XElement encryptedElement)
@@ -83,10 +91,9 @@ public sealed class EncryptedXmlDecryptor : IInternalEncryptedXmlDecryptor, IXml
         private readonly XmlKeyDecryptionOptions? _options;
 
         [RequiresDynamicCode("XmlDsigXsltTransform uses XslCompiledTransform which requires dynamic code.")]
+        [RequiresUnreferencedCode("The algorithm implementations referenced in the XML payload might be removed.")]
         public EncryptedXmlWithCertificateKeys(XmlKeyDecryptionOptions? options, XmlDocument document)
-#pragma warning disable IL2026 // TODO: https://github.com/dotnet/aspnetcore/issues/47695
             : base(document)
-#pragma warning restore IL2026
         {
             _options = options;
         }

+ 0 - 0
src/DataProtection/DataProtection/test/ActivatorTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/ActivatorTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/AuthenticatedEncryption/CngCbcAuthenticatedEncryptorFactoryTest.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/CngCbcAuthenticatedEncryptorFactoryTest.cs


+ 0 - 0
src/DataProtection/DataProtection/test/AuthenticatedEncryption/CngGcmAuthenticatedEncryptorFactoryTest.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/CngGcmAuthenticatedEncryptorFactoryTest.cs


+ 0 - 0
src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorDeserializerTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorDeserializerTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorConfigurationTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorConfigurationTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorDescriptorDeserializerTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorDescriptorDeserializerTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorDescriptorTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorDescriptorTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorConfigurationTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorConfigurationTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptorDeserializerTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptorDeserializerTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptorTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptorTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorConfigurationTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorConfigurationTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorDeserializerTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorDeserializerTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorDescriptorTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/AuthenticatedEncryption/ManagedAuthenticatedEncryptorFactoryTest.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/AuthenticatedEncryption/ManagedAuthenticatedEncryptorFactoryTest.cs


+ 0 - 0
src/DataProtection/DataProtection/test/Cng/CbcAuthenticatedEncryptorTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Cng/CbcAuthenticatedEncryptorTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/Cng/CngAuthenticatedEncryptorBaseTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Cng/CngAuthenticatedEncryptorBaseTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/Cng/GcmAuthenticatedEncryptorTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Cng/GcmAuthenticatedEncryptorTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/ContainerUtilsTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/ContainerUtilsTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/DataProtectionUtilityExtensionsTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/DataProtectionUtilityExtensionsTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/EphemeralDataProtectionProviderTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/EphemeralDataProtectionProviderTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/HostingTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/HostingTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/Internal/KeyManagementOptionsSetupTest.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Internal/KeyManagementOptionsSetupTest.cs


+ 0 - 0
src/DataProtection/DataProtection/test/KeyManagement/CacheableKeyRingTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/CacheableKeyRingTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/KeyManagement/DefaultKeyResolverTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/DefaultKeyResolverTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/KeyManagement/DeferredKeyTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/DeferredKeyTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/KeyManagement/KeyEscrowServiceProviderExtensionsTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/KeyEscrowServiceProviderExtensionsTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/KeyManagement/KeyRingBasedDataProtectorTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/KeyRingBasedDataProtectorTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/KeyManagement/KeyRingProviderTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/KeyRingProviderTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/KeyManagement/KeyRingTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/KeyRingTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/KeyManagement/KeyTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/KeyTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/KeyManagement/XmlKeyManagerTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/KeyManagement/XmlKeyManagerTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/Managed/ManagedAuthenticatedEncryptorTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Managed/ManagedAuthenticatedEncryptorTests.cs


+ 1 - 1
src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests.csproj → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Microsoft.AspNetCore.DataProtection.Tests.csproj

@@ -6,7 +6,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <Compile Include="..\..\shared\test\*.cs" />
+    <Compile Include="..\..\..\shared\test\*.cs" />
     <Content Include="TestFiles\**" CopyToOutputDirectory="PreserveNewest" />
   </ItemGroup>
 

+ 0 - 0
src/DataProtection/DataProtection/test/MockExtensions.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/MockExtensions.cs


+ 0 - 0
src/DataProtection/DataProtection/test/RegistryPolicyResolverTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/RegistryPolicyResolverTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/Repositories/EphemeralXmlRepositoryTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Repositories/EphemeralXmlRepositoryTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/Repositories/FileSystemXmlRepositoryTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Repositories/FileSystemXmlRepositoryTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/Repositories/RegistryXmlRepositoryTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Repositories/RegistryXmlRepositoryTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/SP800_108/SP800_108Tests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/SP800_108/SP800_108Tests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/SecretAssert.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/SecretAssert.cs


+ 0 - 0
src/DataProtection/DataProtection/test/SecretTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/SecretTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/SequentialGenRandom.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/SequentialGenRandom.cs


+ 0 - 0
src/DataProtection/DataProtection/test/ServiceCollectionTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/ServiceCollectionTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/StringLoggerFactory.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/StringLoggerFactory.cs


+ 0 - 0
src/DataProtection/DataProtection/test/TestFiles/TestCert1.PublicKeyOnly.cer → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/TestFiles/TestCert1.PublicKeyOnly.cer


+ 0 - 0
src/DataProtection/DataProtection/test/TestFiles/TestCert1.pfx → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/TestFiles/TestCert1.pfx


+ 0 - 0
src/DataProtection/DataProtection/test/TestFiles/TestCert2.pfx → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/TestFiles/TestCert2.pfx


+ 0 - 0
src/DataProtection/DataProtection/test/TypeForwardingActivatorTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/TypeForwardingActivatorTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/XmlAssert.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlAssert.cs


+ 0 - 0
src/DataProtection/DataProtection/test/XmlEncryption/CertificateXmlEncryptionTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlEncryption/CertificateXmlEncryptionTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/XmlEncryption/DpapiNGXmlEncryptionTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlEncryption/DpapiNGXmlEncryptionTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/XmlEncryption/DpapiXmlEncryptionTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlEncryption/DpapiXmlEncryptionTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/XmlEncryption/EncryptedXmlDecryptorTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlEncryption/EncryptedXmlDecryptorTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/XmlEncryption/NullXmlEncryptionTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlEncryption/NullXmlEncryptionTests.cs


+ 0 - 0
src/DataProtection/DataProtection/test/XmlEncryption/XmlEncryptionExtensionsTests.cs → src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlEncryption/XmlEncryptionExtensionsTests.cs


+ 94 - 0
src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.TrimmingTests/Constants.cs

@@ -0,0 +1,94 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+internal static class Constants
+{
+    public const string Password = "password";
+
+    public const string Key =
+      // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Suppression approved. Dummy certificate for testing.")]
+      @"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
+        AgIH0A==";
+
+    public const string KeyRingXmlFileName = "key-9c15d488-4417-49ab-ae39-ed2f36a9ebe3.xml";
+    public const string KeyRingXmlContents = """
+        <?xml version="1.0" encoding="utf-8"?>
+        <key id="9c15d488-4417-49ab-ae39-ed2f36a9ebe3" version="1">
+          <creationDate>2023-05-04T19:16:30.3590154Z</creationDate>
+          <activationDate>2023-05-04T19:16:30.3487875Z</activationDate>
+          <expirationDate>2115-08-02T19:16:30.3487875Z</expirationDate>
+          <descriptor deserializerType="Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection">
+            <descriptor>
+              <encryption algorithm="AES_256_CBC" />
+              <validation algorithm="HMACSHA256" />
+              <encryptedSecret decryptorType="Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor, Microsoft.AspNetCore.DataProtection" xmlns="http://schemas.asp.net/2015/03/dataProtection">
+                <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#">
+                  <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
+                  <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
+                    <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
+                      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
+                      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
+                        <X509Data>
+                          <X509Certificate>MIIDATCCAemgAwIBAgIQNH2CfRDvN5FK9yzBy/U8bTANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBB1c2VyQGV4YW1wbGUuY29tMCAXDTE1MTAwNjA4NDQ0OFoYDzIxMTUxMDA2MDg0NDQ4WjAbMRkwFwYDVQQDDBB1c2VyQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvjSzpvCfj6B3MGJWDjUc+LlxZAF8Szz+tTiX9inLIdiEG1LfpJlHgrNXumnY8ZRph1BOMH8/XS28tlhz1iLSX/3EYNLwWhi/9YAT6mC+qmCJu4I+DAN0Xf/lDbRyhB/6iYgPxtuDA3yVGcrh1NQY5JibxGF7uPN8+SmMAff0rP3eseacroYsiis6SG7ItBg+2M78ZJMuPTwl+abiOSwBTtXog8/v87yk6U/VyGzaesygvHCS39tEBT8Uw6AjPEABQI3Rr95LpdbqguzQh/xzwdCp1YFlKiUHkavspg2PiI7qMIamI8H65rXh4emwlurTbTNq8anIbKuYUDbp6XEUeQIDAQABoz8wPTAOBgNVHQ8BAf8EBAMCBLAwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUzx66AAJJ4/RjAJ5dqkeTGHUATFYwDQYJKoZIhvcNAQELBQADggEBADe2e7NytbwtvbuPxX+zm2xOfzf+f335DPxll3MFNZCKM7XThkZmZn49QLh2ltmRR6e/+FiG9nWILADXJvKJFOBl/Nm+ektVXGyCk6ftcAWJnQHgY96ih0dvtn+cTIdr9iYlgICyXDJKvexN15TypbXwsKe9jnuOYvDOn2FtEKi8ysnaHEkVimCMb2DkZZKNm2yQAW5DRxfDZGTsGqeB3R3Li/AQR0DSAOFHjKEHwqolay8Y+5+3XVFi/tK8opVMO39BcP7Ag56IfC20MpzNI8Ibc7OrSy0SMG7QnYd7XT483AAiaKQnhTzmEQwhlILxOiNyi6PGbKH5fshmHRRq1Q8=</X509Certificate>
+                        </X509Data>
+                      </KeyInfo>
+                      <CipherData>
+                        <CipherValue>ahdd65gng0TzxZ/6Nw1zLvqFi3lsvz4tvAF4pBz7BZCqTHbTzaRnK5rMWSP9wEk8fa0LN9CGw7y1QxKfuPneTooYogDPGdVc6T8IbmASGfQI1SZZy7yOkF4IcTz9txJ4wbcjf4hUXPvYeBb0l1QlvKLh0BpXquhZqeM8Gat4IXz1iQbTCB31regpmeDSGJz6ok1ZFhjn0v4K5YvXucofxTmh+0aONveMWyadp56dP4KJVM5x4z6UddiFdVlk4euuSX6qbVHI7eA4UGSdnu8lsbBa5aiypS0kRO8NGyab+nSY907hn8E7mUCc9MjyS/QwFSZyT3y88q0pb1bK8zL8tA==</CipherValue>
+                      </CipherData>
+                    </EncryptedKey>
+                  </KeyInfo>
+                  <CipherData>
+                    <CipherValue>YTcCujeLvS47fgVUWLUC9FaZJDp+MSMtuxAkUWfAh5xnbKI8i0dFulIftz+lykfx+/1dMmQ/GsFSbbqhjCG6GDUKz5/eBXEg/It9Vagu9y0UTlrfj0dLaSG7jaw+wNY9DXTsvRtIHkEI0XQHWr0HqkJYVDfiA4yRZu2Sfue9nSmIZFMhCZOP286hJ0JFsqX1+phX3sR6JX31mGKopltlAsIGgL8MRTXWp5tZxuk9W+sgoWfJziDYmrPP2P6eMn7AdX4T+TDbuAY7MtaExL8Itv8WeKN34lxXocT7hRIjHaZMfiqocDX6YcIjnYhgeKQ1XlFo4j4fZ/p4PwxMmXdhrr/yAhzPhhOt6kqncsNnfVWbPS6+dh+3XE6/K0Oa2B5avbYKOv21KU69mSaXc4EsPA==</CipherValue>
+                  </CipherData>
+                </EncryptedData>
+              </encryptedSecret>
+            </descriptor>
+          </descriptor>
+        </key>
+        """;
+}

+ 12 - 0
src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.TrimmingTests/Microsoft.AspNetCore.DataProtection.TrimmingTests.proj

@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <ItemGroup>
+    <TestConsoleAppSourceFiles Include="TestCertificateXmlEncryptor.cs"
+                               AdditionalSourceFiles="Constants.cs" />
+    <TestConsoleAppSourceFiles Include="TestEncryptedXmlDecryptor.cs"
+                               AdditionalSourceFiles="Constants.cs" />
+    <TestConsoleAppSourceFiles Include="TestUnprotectWorksWithX509Certificate.cs"
+                               AdditionalSourceFiles="Constants.cs" />
+  </ItemGroup>
+
+</Project>

+ 31 - 0
src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.TrimmingTests/TestCertificateXmlEncryptor.cs

@@ -0,0 +1,31 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.AspNetCore.DataProtection.XmlEncryption;
+using Microsoft.Extensions.Logging.Abstractions;
+using System;
+using System.Security.Cryptography.X509Certificates;
+using System.Xml.Linq;
+
+var cert = new X509Certificate2(Convert.FromBase64String(Constants.Key), Constants.Password);
+
+var encryptor = new CertificateXmlEncryptor(cert, NullLoggerFactory.Instance);
+
+var e = XElement.Parse("""
+    <root>
+      <child Value="hi" />
+    </root>
+    """);
+
+var result = encryptor.Encrypt(e);
+
+if (result.DecryptorType.Name != "EncryptedXmlDecryptor")
+{
+    return -1;
+}
+if (result.EncryptedElement.Name.LocalName != "EncryptedData")
+{
+    return -2;
+}
+
+return 100;

+ 41 - 0
src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.TrimmingTests/TestEncryptedXmlDecryptor.cs

@@ -0,0 +1,41 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.AspNetCore.DataProtection;
+using Microsoft.AspNetCore.DataProtection.XmlEncryption;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Security.Cryptography.X509Certificates;
+using System.Xml.Linq;
+
+var cert = new X509Certificate2(Convert.FromBase64String(Constants.Key), Constants.Password);
+var encryptedData = XElement.Parse(Constants.KeyRingXmlContents)
+    .Element("descriptor")
+    .Element("descriptor")
+    .Element(XName.Get("encryptedSecret", "http://schemas.asp.net/2015/03/dataProtection"))
+    .Element(XName.Get("EncryptedData", "http://www.w3.org/2001/04/xmlenc#"));
+
+var services = new ServiceCollection();
+services.AddOptions();
+var dpBuilder = new DataProtectionBuilder(services);
+dpBuilder.UnprotectKeysWithAnyCertificate(cert);
+var decryptor = new EncryptedXmlDecryptor(services.BuildServiceProvider());
+
+var e = decryptor.Decrypt(encryptedData);
+
+if (e.Name != "masterKey")
+{
+    return -1;
+}
+if (e.Value != "HfIK4QgxlajUlAj2se0A90ZAtJmkI4zOLQrCwEl86WM77WlKbDQlXhnd/DYDZKHUW6t0pg0J054XFJeFZ4U6hg==")
+{
+    return -2;
+}
+
+return 100;
+
+internal sealed class DataProtectionBuilder : IDataProtectionBuilder
+{
+    public DataProtectionBuilder(IServiceCollection services) => Services = services;
+    public IServiceCollection Services { get; }
+}

+ 24 - 0
src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.TrimmingTests/TestUnprotectWorksWithX509Certificate.cs

@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.AspNetCore.DataProtection;
+using System;
+using System.IO;
+using System.Security.Cryptography.X509Certificates;
+
+var keyDirectory = new DirectoryInfo(AppContext.BaseDirectory);
+File.WriteAllText(Path.Combine(keyDirectory.FullName, Constants.KeyRingXmlFileName), Constants.KeyRingXmlContents);
+
+var cert = new X509Certificate2(Convert.FromBase64String(Constants.Key), Constants.Password);
+var dpProvider = DataProtectionProvider.Create(keyDirectory, cert);
+var protector = dpProvider.CreateProtector(purpose: "Test trimming");
+
+var protectedSecret = @"CfDJ8IjUFZwXRKtJrjntLzap6-OgblGi63sK6HDtOtu-IVhtuoLSTJl4fIbwX4vCtc8fefqPrr41QzGjHXwP-1HaCi9qlJFjvaloQ5KFPxBO2s-s1cAK9I5kl-lfjhyYrEtJRNtvgawKREAp2cZ9udM_Kog";
+var unprotectedSecret = protector.Unprotect(protectedSecret);
+
+if (unprotectedSecret != "This is a secret.")
+{
+    return -1;
+}
+
+return 100;

+ 0 - 4
src/Security/Authentication/Core/src/AuthenticationServiceCollectionExtensions.cs

@@ -1,7 +1,6 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System.Diagnostics.CodeAnalysis;
 using Microsoft.AspNetCore.Authentication;
 using Microsoft.Extensions.DependencyInjection.Extensions;
 
@@ -17,7 +16,6 @@ public static class AuthenticationServiceCollectionExtensions
     /// </summary>
     /// <param name="services">The <see cref="IServiceCollection"/>.</param>
     /// <returns>A <see cref="AuthenticationBuilder"/> that can be used to further configure authentication.</returns>
-    [RequiresUnreferencedCode("Authentication middleware does not currently support native AOT.", Url = "https://aka.ms/aspnet/nativeaot")]
     public static AuthenticationBuilder AddAuthentication(this IServiceCollection services)
     {
         ArgumentNullException.ThrowIfNull(services);
@@ -41,7 +39,6 @@ public static class AuthenticationServiceCollectionExtensions
     /// <param name="services">The <see cref="IServiceCollection"/>.</param>
     /// <param name="defaultScheme">The default scheme used as a fallback for all other schemes.</param>
     /// <returns>A <see cref="AuthenticationBuilder"/> that can be used to further configure authentication.</returns>
-    [RequiresUnreferencedCode("Authentication middleware does not currently support native AOT.", Url = "https://aka.ms/aspnet/nativeaot")]
     public static AuthenticationBuilder AddAuthentication(this IServiceCollection services, string defaultScheme)
         => services.AddAuthentication(o => o.DefaultScheme = defaultScheme);
 
@@ -51,7 +48,6 @@ public static class AuthenticationServiceCollectionExtensions
     /// <param name="services">The <see cref="IServiceCollection"/>.</param>
     /// <param name="configureOptions">A delegate to configure <see cref="AuthenticationOptions"/>.</param>
     /// <returns>A <see cref="AuthenticationBuilder"/> that can be used to further configure authentication.</returns>
-    [RequiresUnreferencedCode("Authentication middleware does not currently support native AOT.", Url = "https://aka.ms/aspnet/nativeaot")]
     public static AuthenticationBuilder AddAuthentication(this IServiceCollection services, Action<AuthenticationOptions> configureOptions)
     {
         ArgumentNullException.ThrowIfNull(services);

+ 147 - 0
src/Shared/TrimmingAttributes.cs

@@ -154,6 +154,153 @@ internal sealed class UnconditionalSuppressMessageAttribute : Attribute
     public string? Justification { get; set; }
 }
 
+/// <summary>
+/// States a dependency that one member has on another.
+/// </summary>
+/// <remarks>
+/// This can be used to inform tooling of a dependency that is otherwise not evident purely from
+/// metadata and IL, for example a member relied on via reflection.
+/// </remarks>
+[AttributeUsage(
+    AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method,
+    AllowMultiple = true, Inherited = false)]
+internal sealed class DynamicDependencyAttribute : Attribute
+{
+    /// <summary>
+    /// Initializes a new instance of the <see cref="DynamicDependencyAttribute"/> class
+    /// with the specified signature of a member on the same type as the consumer.
+    /// </summary>
+    /// <param name="memberSignature">The signature of the member depended on.</param>
+    public DynamicDependencyAttribute(string memberSignature)
+    {
+        MemberSignature = memberSignature;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="DynamicDependencyAttribute"/> class
+    /// with the specified signature of a member on a <see cref="System.Type"/>.
+    /// </summary>
+    /// <param name="memberSignature">The signature of the member depended on.</param>
+    /// <param name="type">The <see cref="System.Type"/> containing <paramref name="memberSignature"/>.</param>
+    public DynamicDependencyAttribute(string memberSignature, Type type)
+    {
+        MemberSignature = memberSignature;
+        Type = type;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="DynamicDependencyAttribute"/> class
+    /// with the specified signature of a member on a type in an assembly.
+    /// </summary>
+    /// <param name="memberSignature">The signature of the member depended on.</param>
+    /// <param name="typeName">The full name of the type containing the specified member.</param>
+    /// <param name="assemblyName">The assembly name of the type containing the specified member.</param>
+    public DynamicDependencyAttribute(string memberSignature, string typeName, string assemblyName)
+    {
+        MemberSignature = memberSignature;
+        TypeName = typeName;
+        AssemblyName = assemblyName;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="DynamicDependencyAttribute"/> class
+    /// with the specified types of members on a <see cref="System.Type"/>.
+    /// </summary>
+    /// <param name="memberTypes">The types of members depended on.</param>
+    /// <param name="type">The <see cref="System.Type"/> containing the specified members.</param>
+    public DynamicDependencyAttribute(DynamicallyAccessedMemberTypes memberTypes, Type type)
+    {
+        MemberTypes = memberTypes;
+        Type = type;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="DynamicDependencyAttribute"/> class
+    /// with the specified types of members on a type in an assembly.
+    /// </summary>
+    /// <param name="memberTypes">The types of members depended on.</param>
+    /// <param name="typeName">The full name of the type containing the specified members.</param>
+    /// <param name="assemblyName">The assembly name of the type containing the specified members.</param>
+    public DynamicDependencyAttribute(DynamicallyAccessedMemberTypes memberTypes, string typeName, string assemblyName)
+    {
+        MemberTypes = memberTypes;
+        TypeName = typeName;
+        AssemblyName = assemblyName;
+    }
+
+    /// <summary>
+    /// Gets the signature of the member depended on.
+    /// </summary>
+    /// <remarks>
+    /// Either <see cref="MemberSignature"/> must be a valid string or <see cref="MemberTypes"/>
+    /// must not equal <see cref="DynamicallyAccessedMemberTypes.None"/>, but not both.
+    /// </remarks>
+    public string? MemberSignature { get; }
+
+    /// <summary>
+    /// Gets the <see cref="DynamicallyAccessedMemberTypes"/> which specifies the type
+    /// of members depended on.
+    /// </summary>
+    /// <remarks>
+    /// Either <see cref="MemberSignature"/> must be a valid string or <see cref="MemberTypes"/>
+    /// must not equal <see cref="DynamicallyAccessedMemberTypes.None"/>, but not both.
+    /// </remarks>
+    public DynamicallyAccessedMemberTypes MemberTypes { get; }
+
+    /// <summary>
+    /// Gets the <see cref="System.Type"/> containing the specified member.
+    /// </summary>
+    /// <remarks>
+    /// If neither <see cref="Type"/> nor <see cref="TypeName"/> are specified,
+    /// the type of the consumer is assumed.
+    /// </remarks>
+    public Type? Type { get; }
+
+    /// <summary>
+    /// Gets the full name of the type containing the specified member.
+    /// </summary>
+    /// <remarks>
+    /// If neither <see cref="Type"/> nor <see cref="TypeName"/> are specified,
+    /// the type of the consumer is assumed.
+    /// </remarks>
+    public string? TypeName { get; }
+
+    /// <summary>
+    /// Gets the assembly name of the specified type.
+    /// </summary>
+    /// <remarks>
+    /// <see cref="AssemblyName"/> is only valid when <see cref="TypeName"/> is specified.
+    /// </remarks>
+    public string? AssemblyName { get; }
+
+    /// <summary>
+    /// Gets or sets the condition in which the dependency is applicable, e.g. "DEBUG".
+    /// </summary>
+    public string? Condition { get; set; }
+}
+
+/// <summary>
+/// Indicates that certain members on a specified <see cref="Type"/> are accessed dynamically,
+/// for example through <see cref="System.Reflection"/>.
+/// </summary>
+/// <remarks>
+/// This allows tools to understand which members are being accessed during the execution
+/// of a program.
+///
+/// This attribute is valid on members whose type is <see cref="Type"/> or <see cref="string"/>.
+///
+/// When this attribute is applied to a location of type <see cref="string"/>, the assumption is
+/// that the string represents a fully qualified type name.
+///
+/// When this attribute is applied to a class, interface, or struct, the members specified
+/// can be accessed dynamically on <see cref="Type"/> instances returned from calling
+/// <see cref="object.GetType"/> on instances of that class, interface, or struct.
+///
+/// If the attribute is applied to a method it's treated as a special case and it implies
+/// the attribute should be applied to the "this" parameter of the method. As such the attribute
+/// should only be used on instance methods of types assignable to System.Type (or string, but no methods
+/// will use it there).
+/// </remarks>
 [AttributeUsage(
         AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter |
         AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method |