Skip to content

Commit

Permalink
Merge branch 'stable'
Browse files Browse the repository at this point in the history
* stable:
  (GH-446) Enable FIPS Compliant Algorithms
  (GH-446) Opt out checksum tool from FIPS policy
  • Loading branch information
ferventcoder committed Jun 5, 2016
2 parents 1889f7e + 8fe470b commit 1e6ec5f
Show file tree
Hide file tree
Showing 13 changed files with 90 additions and 36 deletions.
3 changes: 3 additions & 0 deletions src/chocolatey.resources/chocolatey.resources.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@
<ItemGroup>
<EmbeddedResource Include="helpers\functions\Uninstall-ChocolateyEnvironmentVariable.ps1" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="tools\checksum.exe.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
Expand Down
6 changes: 6 additions & 0 deletions src/chocolatey.resources/tools/checksum.exe.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<enforceFIPSPolicy enabled="false"/>
</runtime>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ public abstract class FilesServiceSpecsBase : TinySpec

public override void Context()
{
HashProvider = new CryptoHashProvider(FileSystem, CryptoHashProviderType.Md5);
Service = new FilesService(new XmlService(FileSystem, HashProvider), FileSystem, new CryptoHashProvider(FileSystem, CryptoHashProviderType.Md5));
HashProvider = new CryptoHashProvider(FileSystem);
Service = new FilesService(new XmlService(FileSystem, HashProvider), FileSystem, HashProvider);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace chocolatey.tests.integration.infrastructure.cryptography
using System.IO;
using System.Reflection;
using System.Security.Cryptography;
using chocolatey.infrastructure.app.configuration;
using Should;
using chocolatey.infrastructure.cryptography;
using chocolatey.infrastructure.filesystem;
Expand All @@ -34,7 +35,7 @@ public abstract class CrytpoHashProviderSpecsBase : TinySpec
public override void Context()
{
FileSystem = new DotNetFileSystem();
Provider = new CryptoHashProvider(FileSystem,CryptoHashProviderType.Md5);
Provider = new CryptoHashProvider(FileSystem);
ContextDirectory = FileSystem.combine_paths(FileSystem.get_directory_name(FileSystem.get_current_assembly_path()), "context");
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/chocolatey.tests/chocolatey.tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
<Compile Include="infrastructure\commands\CommandExecutorSpecs.cs" />
<Compile Include="infrastructure\commands\PowershellExecutorSpecs.cs" />
<Compile Include="infrastructure\configuration\ConfigSpecs.cs" />
<Compile Include="infrastructure\cryptography\CrytpoHashProvider.cs" />
<Compile Include="infrastructure\cryptography\CrytpoHashProviderSpecs.cs" />
<Compile Include="infrastructure\events\context\FakeEvent.cs" />
<Compile Include="infrastructure\events\context\FakeSubscriber.cs" />
<Compile Include="infrastructure\events\EventSubscriptionManagerSpecs.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public abstract class CrytpoHashProviderSpecsBase : TinySpec

public override void Context()
{
Provider = new CryptoHashProvider(FileSystem.Object, CryptoHashProviderType.Md5);
Provider = Provider = new CryptoHashProvider(FileSystem.Object);
}
}

Expand All @@ -59,7 +59,7 @@ public override void Because()
[Fact]
public void should_provide_the_correct_hash_based_on_a_checksum()
{
var expected = BitConverter.ToString(MD5.Create().ComputeHash(byteArray)).Replace("-", string.Empty);
var expected = BitConverter.ToString(SHA256.Create().ComputeHash(byteArray)).Replace("-", string.Empty);

result.ShouldEqual(expected);
}
Expand Down
1 change: 1 addition & 0 deletions src/chocolatey/infrastructure.app/ApplicationParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ public static class Features
public static readonly string FailOnInvalidOrMissingLicense = "failOnInvalidOrMissingLicense";
public static readonly string IgnoreInvalidOptionsSwitches = "ignoreInvalidOptionsSwitches";
public static readonly string UsePackageExitCodes = "usePackageExitCodes";
public static readonly string UseFipsCompliantChecksums = "useFipsCompliantChecksums";
}

public static class Messages
Expand Down
27 changes: 27 additions & 0 deletions src/chocolatey/infrastructure.app/builders/ConfigurationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ namespace chocolatey.infrastructure.app.builders
using adapters;
using attributes;
using configuration;
using cryptography;
using domain;
using extractors;
using filesystem;
using information;
Expand Down Expand Up @@ -81,6 +83,30 @@ public static void set_up_configuration(IList<string> args, ChocolateyConfigurat
set_licensed_options(config, license, configFileSettings);
// save all changes if there are any
set_config_file_settings(configFileSettings, xmlService);

if (!config.Features.UseFipsCompliantChecksums)
{
var hashprovider = container.GetInstance<IHashProvider>();
try
{
hashprovider.set_hash_algorithm(CryptoHashProviderType.Md5);
}
catch (Exception ex)
{
if (!config.CommandName.is_equal_to("feature"))
{
if (ex.InnerException != null && ex.InnerException.Message.contains("FIPS"))
{
"chocolatey".Log().Warn(ChocolateyLoggers.Important, @"
FIPS Mode detected - run 'choco feature enable -n {0}'
to use Chocolatey.".format_with(ApplicationParameters.Features.UseFipsCompliantChecksums));
throw new ApplicationException("When FIPS Mode is enabled, Chocolatey requires {0} feature also be enabled.".format_with(ApplicationParameters.Features.UseFipsCompliantChecksums));
}

throw;
}
}
}
}

private static ConfigFileSettings get_config_file_settings(IFileSystem fileSystem, IXmlService xmlService)
Expand Down Expand Up @@ -264,6 +290,7 @@ private static void set_feature_flags(ChocolateyConfiguration config, ConfigFile
config.Features.FailOnInvalidOrMissingLicense = set_feature_flag(ApplicationParameters.Features.FailOnInvalidOrMissingLicense, configFileSettings, defaultEnabled: false, description: "Fail On Invalid Or Missing License - allows knowing when a license is expired or not applied to a machine. Available in 0.9.10+.");
config.Features.IgnoreInvalidOptionsSwitches = set_feature_flag(ApplicationParameters.Features.IgnoreInvalidOptionsSwitches, configFileSettings, defaultEnabled: true, description: "Ignore Invalid Options/Switches - If a switch or option is passed that is not recognized, should choco fail? Available in 0.9.10+.");
config.Features.UsePackageExitCodes = set_feature_flag(ApplicationParameters.Features.UsePackageExitCodes, configFileSettings, defaultEnabled: true, description: "Use Package Exit Codes - Package scripts can provide exit codes. With this on, package exit codes will be what choco uses for exit when non-zero (this value can come from a dependency package). Chocolatey defines valid exit codes as 0, 1605, 1614, 1641, 3010. With this feature off, choco will exit with a 0 or a 1 (matching previous behavior). Available in 0.9.10+.");
config.Features.UseFipsCompliantChecksums = set_feature_flag(ApplicationParameters.Features.UseFipsCompliantChecksums, configFileSettings, defaultEnabled: false, description: "Use FIPS Compliant Checksums - Ensure checksumming done by choco uses FIPS compliant algorithms. Not recommended unless required by FIPS Mode. Enabling on an existing installation could have unintended consequences related to upgrades/uninstalls. Available in 0.9.10+.");
config.PromptForConfirmation = !set_feature_flag(ApplicationParameters.Features.AllowGlobalConfirmation, configFileSettings, defaultEnabled: false, description: "Prompt for confirmation in scripts or bypass.");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ public sealed class FeaturesConfiguration
public bool FailOnInvalidOrMissingLicense { get; set; }
public bool IgnoreInvalidOptionsSwitches { get; set; }
public bool UsePackageExitCodes { get; set; }
public bool UseFipsCompliantChecksums { get; set; }
}

//todo: retrofit other command configs this way
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
namespace chocolatey.infrastructure.app.registration
{
using System.Collections.Generic;
using configuration;
using infrastructure.events;
using infrastructure.tasks;
using NuGet;
Expand Down Expand Up @@ -60,7 +61,7 @@ public void RegisterComponents(Container container)
container.Register<IRegistryService, RegistryService>(Lifestyle.Singleton);
container.Register<IFilesService, FilesService>(Lifestyle.Singleton);
container.Register<IConfigTransformService, ConfigTransformService>(Lifestyle.Singleton);
container.Register<IHashProvider>(() => new CryptoHashProvider(container.GetInstance<IFileSystem>(), CryptoHashProviderType.Md5), Lifestyle.Singleton);
container.Register<IHashProvider>(() => new CryptoHashProvider(container.GetInstance<IFileSystem>()), Lifestyle.Singleton);
container.Register<ITemplateService, TemplateService>(Lifestyle.Singleton);
container.Register<IChocolateyConfigSettingsService, ChocolateyConfigSettingsService>(Lifestyle.Singleton);
container.Register<IChocolateyPackageService, ChocolateyPackageService>(Lifestyle.Singleton);
Expand Down
61 changes: 33 additions & 28 deletions src/chocolatey/infrastructure/cryptography/CryptoHashProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,44 +16,65 @@
namespace chocolatey.infrastructure.cryptography
{
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using adapters;
using app;
using filesystem;
using platforms;
using Environment = System.Environment;
using HashAlgorithm = adapters.HashAlgorithm;

public sealed class CryptoHashProvider : IHashProvider
{
private readonly IFileSystem _fileSystem;
private readonly IHashAlgorithm _hashAlgorithm;
private IHashAlgorithm _hashAlgorithm;
private const int ERROR_LOCK_VIOLATION = 33;
private const int ERROR_SHARING_VIOLATION = 32;

public CryptoHashProvider(IFileSystem fileSystem, CryptoHashProviderType providerType)
public void set_hash_algorithm(CryptoHashProviderType algorithmType)
{
_fileSystem = fileSystem;
_hashAlgorithm = get_hash_algorithm_static(algorithmType);
}

private static IHashAlgorithm get_hash_algorithm_static(CryptoHashProviderType algorithmType)
{

var fipsOnly = false;
try
{
fipsOnly = CryptoConfig.AllowOnlyFipsAlgorithms;
}
catch (Exception ex)
{
"chocolatey".Log().Debug("Unable to get FipsPolicy from CryptoConfig:{0} {1}".format_with(Environment.NewLine, ex.Message));
}

switch (providerType)
HashAlgorithm hashAlgorithm = null;
switch (algorithmType)
{
case CryptoHashProviderType.Md5:
_hashAlgorithm = new HashAlgorithm(MD5.Create());
hashAlgorithm = new HashAlgorithm(MD5.Create());
break;
case CryptoHashProviderType.Sha1:
_hashAlgorithm = new HashAlgorithm(SHA1.Create());
hashAlgorithm = new HashAlgorithm(fipsOnly ? new SHA1Cng() : SHA1.Create());
break;
case CryptoHashProviderType.Sha256:
_hashAlgorithm = new HashAlgorithm(SHA256.Create());
hashAlgorithm = new HashAlgorithm(fipsOnly ? new SHA256Cng() : SHA256.Create());
break;
case CryptoHashProviderType.Sha512:
_hashAlgorithm = new HashAlgorithm(SHA512.Create());
hashAlgorithm = new HashAlgorithm(fipsOnly ? new SHA512Cng() : SHA512.Create());
break;
}

return hashAlgorithm;
}

public CryptoHashProvider(IFileSystem fileSystem)
{
_fileSystem = fileSystem;
set_hash_algorithm(CryptoHashProviderType.Sha256);
}

public CryptoHashProvider(IFileSystem fileSystem, IHashAlgorithm hashAlgorithm)
Expand Down Expand Up @@ -96,27 +117,11 @@ private static bool file_is_locked(Exception exception)

return errorCode == ERROR_SHARING_VIOLATION || errorCode == ERROR_LOCK_VIOLATION;
}



public static string hash_value(string originalText, CryptoHashProviderType providerType)
{
HashAlgorithm hashAlgorithm = null;
switch (providerType)
{
case CryptoHashProviderType.Md5:
hashAlgorithm = new HashAlgorithm(MD5.Create());
break;
case CryptoHashProviderType.Sha1:
hashAlgorithm = new HashAlgorithm(SHA1.Create());
break;
case CryptoHashProviderType.Sha256:
hashAlgorithm = new HashAlgorithm(SHA256.Create());
break;
case CryptoHashProviderType.Sha512:
hashAlgorithm = new HashAlgorithm(SHA512.Create());
break;
}

IHashAlgorithm hashAlgorithm = get_hash_algorithm_static(providerType);
if (hashAlgorithm == null) return string.Empty;

var hash = hashAlgorithm.ComputeHash(Encoding.ASCII.GetBytes(originalText));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ namespace chocolatey.infrastructure.cryptography
{
public enum CryptoHashProviderType
{
Unknown,
Md5,
Sha1,
Sha256,
Sha512
Sha512,
}
}
8 changes: 8 additions & 0 deletions src/chocolatey/infrastructure/cryptography/IHashProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,19 @@

namespace chocolatey.infrastructure.cryptography
{
using adapters;

/// <summary>
/// A hash provider for hashing files
/// </summary>
public interface IHashProvider
{
/// <summary>
/// Changes the algorithm
/// </summary>
/// <param name="algorithmType">Type of the algorithm.</param>
void set_hash_algorithm(CryptoHashProviderType algorithmType);

/// <summary>
/// Returns a hash of the specified file path.
/// </summary>
Expand Down

0 comments on commit 1e6ec5f

Please sign in to comment.