Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signing: update to August 2022 CTL #4791

Merged
merged 9 commits into from
Oct 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ project.json text
*.vcxproj text eol=crlf

# Denote all files that are truly binary and should not be modified.
*.gif binary
*.jpg binary
*.pem binary
*.png binary
*.gif binary
*.zip binary
18 changes: 5 additions & 13 deletions build/common.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -201,18 +201,9 @@ Function Install-DotnetCLI {
$arch = "x86";
}

# The Quality option:
# Daily links are those from daily builds
# Signed have been post-build signed (in the case of 6.0+, pre-6.0 is signed even in daily builds)
# Validated have gone through CTI testing and other validation
# Preview are released bits that are preview versions
# GA are released servicing and GA builds
Trace-Log "$DotNetInstall -Channel $($cli.Channel) -Quality signed -InstallDir $($cli.Root) -Version $($cli.Version) -Architecture $arch -NoPath"

# dotnet-install might make http requests that fail, but it handles those errors internally
# However, Invoke-BuildStep checks if any error happened, ever. Hence we need to run dotnet-install
# in a different process, to avoid treating their handled errors as build errors.
& powershell $DotNetInstall -Channel $cli.Channel -Quality signed -InstallDir $cli.Root -Version $cli.Version -Architecture $arch -NoPath
Trace-Log "$DotNetInstall -Channel $($cli.Channel) -InstallDir $($cli.Root) -Version $($cli.Version) -Architecture $arch -NoPath"

& powershell $DotNetInstall -Channel $cli.Channel -InstallDir $cli.Root -Version $cli.Version -Architecture $arch -NoPath
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the Quality argument here and in scripts/funcTests/runFuncTests.sh. Documentation says:

Don't use both version and quality parameters. When quality is specified, the script determines the proper version on its own.

[Quality is] Not applicable for current and LTS channels and will be ignored if one of those channels is used.

For some time, we have only effectively used Channel and Version.

if ($LASTEXITCODE -ne 0)
{
throw "dotnet-install.ps1 exited with non-zero exit code"
Expand All @@ -230,12 +221,13 @@ Function Install-DotnetCLI {
}
}

# Install the 2.x runtime because our tests target netcoreapp2x
# Install the 3.x runtime because our tests target netcoreapp2x
Trace-Log "$DotNetInstall -Runtime dotnet -Channel 3.1 -InstallDir $CLIRoot -NoPath"
# dotnet-install might make http requests that fail, but it handles those errors internally
# However, Invoke-BuildStep checks if any error happened, ever. Hence we need to run dotnet-install
# in a different process, to avoid treating their handled errors as build errors.
& powershell $DotNetInstall -Runtime dotnet -Channel 3.1 -InstallDir $CLIRoot -NoPath

if ($LASTEXITCODE -ne 0)
{
throw "dotnet-install.ps1 exited with non-zero exit code"
Expand Down
2 changes: 1 addition & 1 deletion build/config.props
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
6.0:6.0.100-preview.7.21379.14 means install the preview version 6.0.100-preview.7.21379.14.
Refer to https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script#options for more details.
-->
<CliBranchForTesting Condition="'$(CliBranchForTesting)' == ''">6.0.4xx</CliBranchForTesting>
<CliBranchForTesting Condition="'$(CliBranchForTesting)' == ''">7.0:7.0.100-rtm.22510.17</CliBranchForTesting>
</PropertyGroup>

<!-- Config -->
Expand Down
17 changes: 7 additions & 10 deletions scripts/funcTests/runFuncTests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,9 @@ do
fi
unset IFS

# The quality option:
# Daily links are those from daily builds
# Signed have been post-build signed (in the case of 6.0+, pre-6.0 is signed even in daily builds)
# Validated have gone through CTI testing and other validation
# Preview are released bits that are preview versions
# GA are released servicing and GA builds
echo "cli/dotnet-install.sh --install-dir cli --channel $Channel --quality signed --version $Version -nopath"
cli/dotnet-install.sh --install-dir cli --channel $Channel --quality signed --version $Version -nopath

echo "cli/dotnet-install.sh --install-dir cli --channel $Channel --version $Version -nopath"
cli/dotnet-install.sh --install-dir cli --channel $Channel --version $Version -nopath

if (( $? )); then
echo "The .NET CLI Install for $DOTNET_BRANCH failed!!"
exit 1
Expand All @@ -91,7 +85,10 @@ if (( $? )); then
exit 1
fi

# Install .NET 5 runtimes and .NETCoreapp3.1 runtimes
# Install .NET 5, 6, and .NETCoreapp3.1 runtimes

echo "cli/dotnet-install.sh --install-dir cli --runtime dotnet --channel 6.0 -nopath"
cli/dotnet-install.sh --install-dir cli --runtime dotnet --channel 6.0 -nopath

echo "cli/dotnet-install.sh --install-dir cli --runtime dotnet --channel 5.0 -nopath"
cli/dotnet-install.sh --install-dir cli --runtime dotnet --channel 5.0 -nopath
Expand Down
3 changes: 2 additions & 1 deletion src/NuGet.Core/NuGet.Packaging/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
[assembly: CLSCompliant(true)]

[assembly: InternalsVisibleTo("Dotnet.Integration.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
[assembly: InternalsVisibleTo("NuGet.Packaging.FuncTest, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: InternalsVisibleTo("NuGet.Packaging.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: InternalsVisibleTo("NuGet.CommandLine.FuncTest, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
[assembly: InternalsVisibleTo("NuGet.Commands.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
[assembly: InternalsVisibleTo("Test.Utility, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public virtual SignatureVerificationSummary Verify(
else
{
timestamp = timestamp ?? new Timestamp();
using (var chainHolder = new X509ChainHolder())
using (X509ChainHolder chainHolder = X509ChainHolder.CreateForCodeSigning())
{
var chain = chainHolder.Chain;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ internal SignatureVerificationStatusFlags Verify(

var certificateExtraStore = SignedCms.Certificates;

using (var chainHolder = new X509ChainHolder())
using (X509ChainHolder chainHolder = X509ChainHolder.CreateForTimestamping())
{
var chain = chainHolder.Chain;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ internal sealed class FallbackCertificateBundleX509ChainFactory : CertificateBun
{
// These constants are dictated by the .NET SDK.
internal const string SubdirectoryName = "trustedroots";
internal const string FileName = "codesignctl.pem";
internal const string CodeSigningFileName = "codesignctl.pem";
dtivel marked this conversation as resolved.
Show resolved Hide resolved
internal const string TimestampingFileName = "timestampctl.pem";

private static readonly Lazy<string> ThisAssemblyDirectoryPath = new(GetThisAssemblyDirectoryPath, LazyThreadSafetyMode.ExecutionAndPublication);

Expand All @@ -23,14 +24,27 @@ private FallbackCertificateBundleX509ChainFactory(X509Certificate2Collection cer
{
}

internal static bool TryCreate(out FallbackCertificateBundleX509ChainFactory factory, string fileName = FileName)
internal static bool TryCreate(
X509StorePurpose storePurpose,
string fileName,
out FallbackCertificateBundleX509ChainFactory factory)
{
factory = null;

if (string.IsNullOrEmpty(fileName))
{
fileName = storePurpose switch
{
X509StorePurpose.CodeSigning => CodeSigningFileName,
X509StorePurpose.Timestamping => TimestampingFileName,
_ => throw new ArgumentException(Strings.InvalidX509StorePurpose, nameof(storePurpose))
};
}

string fullFilePath = Path.Combine(
ThisAssemblyDirectoryPath.Value,
SubdirectoryName,
fileName ?? FileName);
fileName);

if (TryImportFromPemFile(fullFilePath, out X509Certificate2Collection certificates))
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

namespace NuGet.Packaging.Signing
{
internal enum X509StorePurpose
{
CodeSigning = 1,
Timestamping = 2
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ namespace NuGet.Packaging.Signing
/// </summary>
public static class X509TrustStore
{
private static IX509ChainFactory Instance;
private static IX509ChainFactory CodeSigningX509ChainFactory;
private static IX509ChainFactory TimestampingX509ChainFactory;
private static readonly object LockObject = new();

/// <summary>
Expand All @@ -24,51 +25,85 @@ public static class X509TrustStore
/// <exception cref="ArgumentNullException">Thrown if <paramref name="logger" /> is <c>null</c>.</exception>
public static void InitializeForDotNetSdk(ILogger logger)
{
_ = GetX509ChainFactory(logger, CreateX509ChainFactoryForDotNetSdk);
_ = GetX509ChainFactory(X509StorePurpose.CodeSigning, logger, CreateX509ChainFactoryForDotNetSdk);
_ = GetX509ChainFactory(X509StorePurpose.Timestamping, logger, CreateX509ChainFactoryForDotNetSdk);
}

internal static IX509ChainFactory GetX509ChainFactory(ILogger logger)
internal static IX509ChainFactory GetX509ChainFactory(X509StorePurpose storePurpose, ILogger logger)
{
return GetX509ChainFactory(logger, CreateX509ChainFactory);
return GetX509ChainFactory(storePurpose, logger, CreateX509ChainFactory);
}

private static IX509ChainFactory GetX509ChainFactory(ILogger logger, Func<ILogger, IX509ChainFactory> creator)
private static IX509ChainFactory GetX509ChainFactory(
X509StorePurpose storePurpose,
ILogger logger,
Func<X509StorePurpose, ILogger, IX509ChainFactory> creator)
{
if (logger is null)
{
throw new ArgumentNullException(nameof(logger));
}

if (Instance is not null)
if (storePurpose == X509StorePurpose.CodeSigning)
{
return Instance;
if (CodeSigningX509ChainFactory is not null)
{
return CodeSigningX509ChainFactory;
}

lock (LockObject)
{
if (CodeSigningX509ChainFactory is not null)
{
return CodeSigningX509ChainFactory;
}

CodeSigningX509ChainFactory = creator(storePurpose, logger);
}

return CodeSigningX509ChainFactory;
}

lock (LockObject)
if (storePurpose == X509StorePurpose.Timestamping)
{
if (Instance is not null)
if (TimestampingX509ChainFactory is not null)
{
return Instance;
return TimestampingX509ChainFactory;
}

Instance = creator(logger);
lock (LockObject)
{
if (TimestampingX509ChainFactory is not null)
{
return TimestampingX509ChainFactory;
}

TimestampingX509ChainFactory = creator(storePurpose, logger);
}

return TimestampingX509ChainFactory;
}

return Instance;
throw new ArgumentException(Strings.InvalidX509StorePurpose, nameof(storePurpose));
}

internal static IX509ChainFactory CreateX509ChainFactoryForDotNetSdk(ILogger logger)
private static IX509ChainFactory CreateX509ChainFactoryForDotNetSdk(X509StorePurpose storePurpose, ILogger logger)
{
return CreateX509ChainFactoryForDotNetSdk(logger, fallbackCertificateBundleFile: null);
return CreateX509ChainFactoryForDotNetSdk(storePurpose, logger, fallbackCertificateBundleFile: null);
}

// Non-private for testing purposes only
internal static IX509ChainFactory CreateX509ChainFactoryForDotNetSdk(ILogger logger, FileInfo fallbackCertificateBundleFile)
internal static IX509ChainFactory CreateX509ChainFactoryForDotNetSdk(
X509StorePurpose storePurpose,
ILogger logger,
FileInfo fallbackCertificateBundleFile)
{
#if NET5_0_OR_GREATER
if (RuntimeEnvironmentHelper.IsLinux)
{
if (SystemCertificateBundleX509ChainFactory.TryCreate(
// System certificate bundle probe paths only support code signing not timestamping.
if (storePurpose == X509StorePurpose.CodeSigning &&
SystemCertificateBundleX509ChainFactory.TryCreate(
out SystemCertificateBundleX509ChainFactory systemBundleFactory))
{
logger.LogInformation(
Expand All @@ -81,8 +116,9 @@ internal static IX509ChainFactory CreateX509ChainFactoryForDotNetSdk(ILogger log
}

if (FallbackCertificateBundleX509ChainFactory.TryCreate(
out FallbackCertificateBundleX509ChainFactory fallbackBundleFactory,
fallbackCertificateBundleFile?.FullName))
storePurpose,
fallbackCertificateBundleFile?.FullName,
out FallbackCertificateBundleX509ChainFactory fallbackBundleFactory))
{
logger.LogInformation(
string.Format(
Expand All @@ -101,8 +137,9 @@ internal static IX509ChainFactory CreateX509ChainFactoryForDotNetSdk(ILogger log
if (RuntimeEnvironmentHelper.IsMacOSX)
{
if (FallbackCertificateBundleX509ChainFactory.TryCreate(
out FallbackCertificateBundleX509ChainFactory fallbackBundleFactory,
fallbackCertificateBundleFile?.FullName))
storePurpose,
fallbackCertificateBundleFile?.FullName,
out FallbackCertificateBundleX509ChainFactory fallbackBundleFactory))
{
logger.LogInformation(
string.Format(
Expand All @@ -119,23 +156,32 @@ internal static IX509ChainFactory CreateX509ChainFactoryForDotNetSdk(ILogger log
}
#endif

return CreateX509ChainFactory(logger);
return CreateX509ChainFactory(storePurpose, logger);
}

// Non-private for testing purposes only
internal static IX509ChainFactory CreateX509ChainFactory(ILogger logger)
internal static IX509ChainFactory CreateX509ChainFactory(X509StorePurpose storePurpose, ILogger logger)
{
logger.LogInformation(Strings.ChainBuilding_UsingDefaultTrustStore);

return new DotNetDefaultTrustStoreX509ChainFactory();
}

// Only for testing
internal static void SetX509ChainFactory(IX509ChainFactory chainFactory)
internal static void SetCodeSigningX509ChainFactory(IX509ChainFactory chainFactory)
{
lock (LockObject)
{
CodeSigningX509ChainFactory = chainFactory;
}
}

// Only for testing
internal static void SetTimestampingX509ChainFactory(IX509ChainFactory chainFactory)
{
lock (LockObject)
{
Instance = chainFactory;
TimestampingX509ChainFactory = chainFactory;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ public static IX509CertificateChain GetCertificateChain(
throw new ArgumentException(Strings.InvalidArgument, nameof(certificateType));
}

using (var chainHolder = new X509ChainHolder())
using (X509ChainHolder chainHolder = certificateType == CertificateType.Signature
? X509ChainHolder.CreateForCodeSigning() : X509ChainHolder.CreateForTimestamping())
{
var chain = chainHolder.Chain;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ public static bool IsSelfIssued(X509Certificate2 certificate)
throw new ArgumentNullException(nameof(certificate));
}

using (var chainHolder = new X509ChainHolder())
using (X509ChainHolder chainHolder = X509ChainHolder.CreateForCodeSigning())
{
X509Chain chain = chainHolder.Chain;

Expand Down
Loading