Skip to content

Commit

Permalink
Update SDK to 7.0.100-rc.2.22419.24 (#43028)
Browse files Browse the repository at this point in the history
- {lots of different SDK versions tried}
- Validate DataProtection custom algorithm has a constructor
- Additional fixes
- Suppress IL2121
- Fix NoWarn overrides
- Update LinkabilityChecker.csproj
- Update WasmLinkerTest.csproj
- Bump SDK version yet again
- Hack to stop using `msbuild` server
  - please open an issue to keep trying to remove this
- Disable msbuild server for source-build job

Co-authored-by: Steve Sanderson <SteveSandersonMS@users.noreply.github.com>
Co-authored-by: Chris Ross <chrross@microsoft.com>
Co-authored-by: Tanay Parikh <TanayParikh@users.noreply.github.com>
Co-authored-by: James Newton-King <james@newtonking.com>
Co-authored-by: Sébastien Ros <sebastienros@gmail.com>
Co-authored-by: Doug Bunting <6431421+dougbu@users.noreply.github.com>
Co-authored-by: Safia Abdalla <safia@microsoft.com>
  • Loading branch information
8 people authored Aug 30, 2022
1 parent 5659774 commit bcf7319
Show file tree
Hide file tree
Showing 18 changed files with 167 additions and 76 deletions.
8 changes: 7 additions & 1 deletion .azure/pipelines/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,13 @@ stages:
container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-7-20210714125435-9b5bbc2'
buildScript: './eng/build.sh $(_PublishArgs) --no-build-repo-tasks'
skipPublishValidation: true
timeoutInMinutes: 120
jobProperties:
timeoutInMinutes: 120
variables:
# !temporary! Remove as soon as .NET SDK includes a new-enough `msbuild` to make this hack unnecessary
DOTNET_CLI_DO_NOT_USE_MSBUILD_SERVER: true
# Log environment variables in binary logs to ease debugging
MSBUILDLOGALLENVIRONMENTVARIABLES: true

# Publish to the BAR and perform source indexing. Wait until everything else is done.
- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
Expand Down
6 changes: 6 additions & 0 deletions .azure/pipelines/jobs/default-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ jobs:
# Include the variables we always want.
COMPlus_DbgEnableMiniDump: 1
COMPlus_DbgMiniDumpName: "$(System.DefaultWorkingDirectory)/dotnet-%d.%t.core"
# !temporary! Remove as soon as .NET SDK includes a new-enough `msbuild` to make this hack unnecessary
DOTNET_CLI_DO_NOT_USE_MSBUILD_SERVER: true
# Expand provided `env:` properties, if any.
${{ if step.env }}:
${{ step.env }}
Expand All @@ -231,12 +233,16 @@ jobs:
env:
COMPlus_DbgEnableMiniDump: 1
COMPlus_DbgMiniDumpName: "$(System.DefaultWorkingDirectory)/dotnet-%d.%t.core"
# !temporary! Remove as soon as .NET SDK includes a new-enough `msbuild` to make this hack unnecessary
DOTNET_CLI_DO_NOT_USE_MSBUILD_SERVER: true
- ${{ if ne(parameters.agentOs, 'Windows') }}:
- script: $(BuildDirectory)/build.sh --ci --nobl --configuration $(BuildConfiguration) $(BuildScriptArgs)
displayName: Run build.sh
env:
COMPlus_DbgEnableMiniDump: 1
COMPlus_DbgMiniDumpName: "$(System.DefaultWorkingDirectory)/dotnet-%d.%t.core"
# !temporary! Remove as soon as .NET SDK includes a new-enough `msbuild` to make this hack unnecessary
DOTNET_CLI_DO_NOT_USE_MSBUILD_SERVER: true

- ${{ parameters.afterBuild }}

Expand Down
3 changes: 3 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@

<!-- xUnit1004 = warns about skipped tests. Make this a non-fatal build warning. -->
<WarningsNotAsErrors>$(WarningsNotAsErrors);xUnit1004</WarningsNotAsErrors>

<!-- don't warn about unnecessary trim warning suppressions. can be removed with preview 6. -->
<NoWarn>$(NoWarn);IL2121</NoWarn>
</PropertyGroup>

<!-- Source code settings -->
Expand Down
4 changes: 2 additions & 2 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"sdk": {
"version": "7.0.100-rc.1.22375.2"
"version": "7.0.100-rc.2.22426.5"
},
"tools": {
"dotnet": "7.0.100-rc.1.22375.2",
"dotnet": "7.0.100-rc.2.22426.5",
"runtimes": {
"dotnet/x86": [
"$(MicrosoftNETCoreBrowserDebugHostTransportVersion)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>

<!-- IdentityServer packages are not strong named. -->
<NoWarn>CS8002</NoWarn>
<NoWarn>$(NoWarn);CS8002</NoWarn>
<!-- This project references the shared framework transitively. Prevent restore errors by setting this flag. -->
<GenerateErrorForMissingTargetingPacks>false</GenerateErrorForMissingTargetingPacks>
<IdentityDefaultUIFramework>Bootstrap5</IdentityDefaultUIFramework>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
OutputDirectory="$(LibrariesTrimmedArtifactsPath)"
ReferenceAssemblyPaths="@(RuntimePackAsset);@(ReferencePath->WithMetadataValue('ExternallyResolved', 'true'))"
ExtraArgs="$(ILLinkArgs)"
NoWarn="$(NoWarn)"
TrimMode="link"
ToolExe="$(_DotNetHostFileName)"
ToolPath="$(_DotNetHostDirectory)" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ private static string GetBCryptAlgorithmNameFromValidationAlgorithm(ValidationAl
}
}

[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
private static Type GetManagedTypeFromEncryptionAlgorithm(EncryptionAlgorithm algorithm)
{
switch (algorithm)
Expand All @@ -180,6 +181,7 @@ private static Type GetManagedTypeFromEncryptionAlgorithm(EncryptionAlgorithm al
}
}

[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
private static Type GetManagedTypeFromValidationAlgorithm(ValidationAlgorithm algorithm)
{
switch (algorithm)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Security.Cryptography;
using System.Xml.Linq;

namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;

internal static class ManagedAlgorithmHelpers
{
private static readonly List<Type> KnownAlgorithmTypes = new List<Type>
{
typeof(Aes),
typeof(HMACSHA1),
typeof(HMACSHA256),
typeof(HMACSHA384),
typeof(HMACSHA512)
};

// Any changes to this method should also be be reflected in FriendlyNameToType.
public static string TypeToFriendlyName(Type type)
{
if (KnownAlgorithmTypes.Contains(type))
{
return type.Name;
}
else
{
return type.AssemblyQualifiedName!;
}
}

// Any changes to this method should also be be reflected in TypeToFriendlyName.
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
[UnconditionalSuppressMessage("Trimmer", "IL2075", Justification = "Unknown type is checked for whether it has a public parameterless constructor. Handle trimmed types by providing a useful error message.")]
[UnconditionalSuppressMessage("Trimmer", "IL2073", Justification = "Unknown type is checked for whether it has a public parameterless constructor. Handle trimmed types by providing a useful error message.")]
public static Type FriendlyNameToType(string typeName)
{
foreach (var knownType in KnownAlgorithmTypes)
{
if (knownType.Name == typeName)
{
return knownType;
}
}

var type = TypeExtensions.GetTypeWithTrimFriendlyErrorMessage(typeName);

// Type name could be full or assembly qualified name of known type.
if (KnownAlgorithmTypes.Contains(type))
{
return type;
}

// All other types are created using Activator.CreateInstance. Validate it has a valid constructor.
if (type.GetConstructor(Type.EmptyTypes) == null)
{
throw new InvalidOperationException($"Algorithm type {type} doesn't have a public parameterless constructor. If the app is published with trimming then the constructor may have been trimmed. Ensure the type's assembly is excluded from trimming.");
}

return type;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics.CodeAnalysis;
using System.Security.Cryptography;
using Microsoft.Extensions.Logging.Abstractions;

Expand All @@ -24,6 +25,7 @@ public sealed class ManagedAuthenticatedEncryptorConfiguration : AlgorithmConfig
/// The default algorithm is AES.
/// </remarks>
[ApplyPolicy]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
public Type EncryptionAlgorithmType { get; set; } = typeof(Aes);

/// <summary>
Expand All @@ -47,6 +49,7 @@ public sealed class ManagedAuthenticatedEncryptorConfiguration : AlgorithmConfig
/// The default algorithm is HMACSHA256.
/// </remarks>
[ApplyPolicy]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
public Type ValidationAlgorithmType { get; set; } = typeof(HMACSHA256);

/// <inheritdoc />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ public XmlSerializedDescriptorInfo ExportToXml()
// </descriptor>

var encryptionElement = new XElement("encryption",
new XAttribute("algorithm", TypeToFriendlyName(Configuration.EncryptionAlgorithmType)),
new XAttribute("algorithm", ManagedAlgorithmHelpers.TypeToFriendlyName(Configuration.EncryptionAlgorithmType)),
new XAttribute("keyLength", Configuration.EncryptionAlgorithmKeySize));

var validationElement = new XElement("validation",
new XAttribute("algorithm", TypeToFriendlyName(Configuration.ValidationAlgorithmType)));
new XAttribute("algorithm", ManagedAlgorithmHelpers.TypeToFriendlyName(Configuration.ValidationAlgorithmType)));

var rootElement = new XElement("descriptor",
new XComment(" Algorithms provided by specified SymmetricAlgorithm and KeyedHashAlgorithm "),
Expand All @@ -63,34 +63,4 @@ public XmlSerializedDescriptorInfo ExportToXml()

return new XmlSerializedDescriptorInfo(rootElement, typeof(ManagedAuthenticatedEncryptorDescriptorDeserializer));
}

// Any changes to this method should also be be reflected
// in ManagedAuthenticatedEncryptorDescriptorDeserializer.FriendlyNameToType.
private static string TypeToFriendlyName(Type type)
{
if (type == typeof(Aes))
{
return nameof(Aes);
}
else if (type == typeof(HMACSHA1))
{
return nameof(HMACSHA1);
}
else if (type == typeof(HMACSHA256))
{
return nameof(HMACSHA256);
}
else if (type == typeof(HMACSHA384))
{
return nameof(HMACSHA384);
}
else if (type == typeof(HMACSHA512))
{
return nameof(HMACSHA512);
}
else
{
return type.AssemblyQualifiedName!;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,44 +34,14 @@ public IAuthenticatedEncryptorDescriptor ImportFromXml(XElement element)
var configuration = new ManagedAuthenticatedEncryptorConfiguration();

var encryptionElement = element.Element("encryption")!;
configuration.EncryptionAlgorithmType = FriendlyNameToType((string)encryptionElement.Attribute("algorithm")!);
configuration.EncryptionAlgorithmType = ManagedAlgorithmHelpers.FriendlyNameToType((string)encryptionElement.Attribute("algorithm")!);
configuration.EncryptionAlgorithmKeySize = (int)encryptionElement.Attribute("keyLength")!;

var validationElement = element.Element("validation")!;
configuration.ValidationAlgorithmType = FriendlyNameToType((string)validationElement.Attribute("algorithm")!);
configuration.ValidationAlgorithmType = ManagedAlgorithmHelpers.FriendlyNameToType((string)validationElement.Attribute("algorithm")!);

Secret masterKey = ((string)element.Element("masterKey")!).ToSecret();

return new ManagedAuthenticatedEncryptorDescriptor(configuration, masterKey);
}

// Any changes to this method should also be be reflected
// in ManagedAuthenticatedEncryptorDescriptor.TypeToFriendlyName.
private static Type FriendlyNameToType(string typeName)
{
if (typeName == nameof(Aes))
{
return typeof(Aes);
}
else if (typeName == nameof(HMACSHA1))
{
return typeof(HMACSHA1);
}
else if (typeName == nameof(HMACSHA256))
{
return typeof(HMACSHA256);
}
else if (typeName == nameof(HMACSHA384))
{
return typeof(HMACSHA384);
}
else if (typeName == nameof(HMACSHA512))
{
return typeof(HMACSHA512);
}
else
{
return TypeExtensions.GetTypeWithTrimFriendlyErrorMessage(typeName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ private static class AlgorithmActivator
/// <summary>
/// Creates a factory that wraps a call to <see cref="Activator.CreateInstance{T}"/>.
/// </summary>
public static Func<T> CreateFactory<T>(Type implementation)
public static Func<T> CreateFactory<T>([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type implementation)
{
return ((IActivator<T>)Activator.CreateInstance(typeof(AlgorithmActivatorCore<>).MakeGenericType(implementation))!).Creator;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ private static ManagedAuthenticatedEncryptorConfiguration GetManagedAuthenticate
var valueFromRegistry = key.GetValue(nameof(ManagedAuthenticatedEncryptorConfiguration.EncryptionAlgorithmType));
if (valueFromRegistry != null)
{
options.EncryptionAlgorithmType = TypeExtensions.GetTypeWithTrimFriendlyErrorMessage(Convert.ToString(valueFromRegistry, CultureInfo.InvariantCulture)!);
options.EncryptionAlgorithmType = ManagedAlgorithmHelpers.FriendlyNameToType(Convert.ToString(valueFromRegistry, CultureInfo.InvariantCulture)!);
}

valueFromRegistry = key.GetValue(nameof(ManagedAuthenticatedEncryptorConfiguration.EncryptionAlgorithmKeySize));
Expand All @@ -189,7 +189,7 @@ private static ManagedAuthenticatedEncryptorConfiguration GetManagedAuthenticate
valueFromRegistry = key.GetValue(nameof(ManagedAuthenticatedEncryptorConfiguration.ValidationAlgorithmType));
if (valueFromRegistry != null)
{
options.ValidationAlgorithmType = TypeExtensions.GetTypeWithTrimFriendlyErrorMessage(Convert.ToString(valueFromRegistry, CultureInfo.InvariantCulture)!);
options.ValidationAlgorithmType = ManagedAlgorithmHelpers.FriendlyNameToType(Convert.ToString(valueFromRegistry, CultureInfo.InvariantCulture)!);
}

return options;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void ImportFromXml_BuiltInTypes_CreatesAppropriateDescriptor(Type encrypt
}

[Fact]
public void ImportFromXml_CustomType_CreatesAppropriateDescriptor()
public void ImportFromXml_FullyQualifiedBuiltInTypes_CreatesAppropriateDescriptor()
{
// Arrange
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));
Expand Down Expand Up @@ -83,6 +83,69 @@ public void ImportFromXml_CustomType_CreatesAppropriateDescriptor()
Assert.Equal(plaintext, roundTripPlaintext);
}

[Fact]
public void ImportFromXml_CustomType_CreatesAppropriateDescriptor()
{
// Arrange
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));

var xml = $@"
<descriptor>
<encryption algorithm='{typeof(CustomAlgorithm).AssemblyQualifiedName}' keyLength='192' />
<validation algorithm='{typeof(HMACSHA384).AssemblyQualifiedName}' />
<masterKey enc:requiresEncryption='true' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<value>{masterKey}</value>
</masterKey>
</descriptor>";

// Act
var deserializedDescriptor = new ManagedAuthenticatedEncryptorDescriptorDeserializer().ImportFromXml(XElement.Parse(xml));
var managedDescriptor = (ManagedAuthenticatedEncryptorDescriptor)deserializedDescriptor;

// Assert
Assert.Equal(typeof(CustomAlgorithm), managedDescriptor.Configuration.EncryptionAlgorithmType);
}

[Fact]
public void ImportFromXml_CustomTypeWithoutConstructor_CreatesAppropriateDescriptor()
{
// Arrange
var masterKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("[PLACEHOLDER]"));

var xml = $@"
<descriptor>
<encryption algorithm='{typeof(CustomAlgorithmNoConstructor).AssemblyQualifiedName}' keyLength='192' />
<validation algorithm='{typeof(HMACSHA384).AssemblyQualifiedName}' />
<masterKey enc:requiresEncryption='true' xmlns:enc='http://schemas.asp.net/2015/03/dataProtection'>
<value>{masterKey}</value>
</masterKey>
</descriptor>";

// Act
var ex = Assert.Throws<InvalidOperationException>(() => new ManagedAuthenticatedEncryptorDescriptorDeserializer().ImportFromXml(XElement.Parse(xml)));

// Assert
Assert.Equal($"Algorithm type {typeof(CustomAlgorithmNoConstructor).FullName} doesn't have a public parameterless constructor. If the app is published with trimming then the constructor may have been trimmed. Ensure the type's assembly is excluded from trimming.", ex.Message);
}

public class CustomAlgorithm : SymmetricAlgorithm
{
public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV) => throw new NotImplementedException();
public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV) => throw new NotImplementedException();
public override void GenerateIV() => throw new NotImplementedException();
public override void GenerateKey() => throw new NotImplementedException();
}

public class CustomAlgorithmNoConstructor : SymmetricAlgorithm
{
private CustomAlgorithmNoConstructor() { }

public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV) => throw new NotImplementedException();
public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV) => throw new NotImplementedException();
public override void GenerateIV() => throw new NotImplementedException();
public override void GenerateKey() => throw new NotImplementedException();
}

private static IAuthenticatedEncryptor CreateEncryptorInstanceFromDescriptor(ManagedAuthenticatedEncryptorDescriptor descriptor)
{
var encryptorFactory = new ManagedAuthenticatedEncryptorFactory(NullLoggerFactory.Instance);
Expand Down
Loading

0 comments on commit bcf7319

Please sign in to comment.