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

Xamarin Android app build fails on Windows 10 with GetAdditionalResourcesFromAssemblies throwing an exception (GenerateBuildSessionId in case of iOS) #1580

Closed
srikcgaa2 opened this issue Apr 19, 2018 · 11 comments
Assignees
Labels
Area: App+Library Build Issues when building Library projects or Application projects.

Comments

@srikcgaa2
Copy link

Steps to Reproduce

  1. On a Windows 10 machine, ensure the group policy "System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signing" is set to "Enabled"
  2. Create a new Xamarin Android application in Visual Studio 2015 Professional Update 3. Sample project attached with this issue.
  3. Build the project

Expected Behavior

Build should be successful

Actual Behavior

Build fails due to a crash with GetAdditionalResourcesFromAssemblies step throwing an InvalidOperationException. If we create a new Xamarin iOS Application instead of Android, the failure occurs from GenerateBuildSessionId step

Version Information

Please see the attached file for Visual Studio version information as well as Windows 10 system information along with the Security Group Policy screenshot. Pasted below as well for quick reference

Microsoft Visual Studio Professional 2015
Version 14.0.25431.01 Update 3
Microsoft .NET Framework
Version 4.7.02558

Installed Version: Professional

Visual Basic 2015 00322-50052-91952-AA572
Microsoft Visual Basic 2015

Visual C# 2015 00322-50052-91952-AA572
Microsoft Visual C# 2015

Visual C++ 2015 00322-50052-91952-AA572
Microsoft Visual C++ 2015

Application Insights Tools for Visual Studio Package 7.0.20622.1
Application Insights Tools for Visual Studio

ASP.NET and Web Tools 2015.1 (Beta8) 14.1.11107.0
ASP.NET and Web Tools 2015.1 (Beta8)

ASP.NET Web Frameworks and Tools 2012.2 4.1.41102.0
For additional information, visit http://go.microsoft.com/fwlink/?LinkID=309563

ASP.NET Web Frameworks and Tools 2013 5.2.40314.0
For additional information, visit http://www.asp.net/

Common Azure Tools 1.8
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

ILSpy.AddIn 1.0
Integration of the ILSpy Decompiler into Visual Studio.

JavaScript Language Service 2.0
JavaScript Language Service

JavaScript Project System 2.0
JavaScript Project System

JetBrains ReSharper Ultimate 2016.1.2 Build 105.0.20160522.80219
JetBrains ReSharper Ultimate package for Microsoft Visual Studio. For more information about ReSharper Ultimate, visit http://www.jetbrains.com/resharper. Copyright © 2018 JetBrains, Inc.

Merq 1.1.17-rc (cba4571)
Command Bus, Event Stream and Async Manager for Visual Studio extensions.

Microsoft Azure Mobile Services Tools 1.4
Microsoft Azure Mobile Services Tools

Microsoft Team Foundation Server 2015 Power Tools 14.0
Power Tools that extend the Team Foundation Server integration with Visual Studio.

Microsoft Visual Studio Process Editor 1.0
Process Editor for Microsoft Visual Studio Team Foundation Server

Mono Debugging for Visual Studio 4.7.4-pre (c2d89eb)
Support for debugging Mono processes with Visual Studio.

NuGet Package Manager 3.4.4
NuGet Package Manager in Visual Studio. For more information about NuGet, visit http://docs.nuget.org/.

PreEmptive Analytics Visualizer 1.2
Microsoft Visual Studio extension to visualize aggregated summaries from the PreEmptive Analytics product.

ShelvesetComparer 1.0
The extension allows you to compare files in two shelvesets.

SQL Server Data Tools 14.0.60519.0
Microsoft SQL Server Data Tools

TypeScript 1.8.36.0
TypeScript tools for Visual Studio

Visual Studio Spell Check Everywhere VSSpellCheckEverywhere
An extension that enables spell checking within any Visual Studio file editor or tool window that uses WPF text boxes.
https://GitHub.com/EWSoftware/VSSpellChecker

Visual Studio Spell Checker VSSpellChecker
An editor extension that checks the spelling of comments, strings, and plain text as you type or interactively with tool windows.
https://GitHub.com/EWSoftware/VSSpellChecker

VisualStudio.Mac 1.0
Mac Extension for Visual Studio

Xamarin 4.7.10.38 (34c1b6c)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin.Android 8.0.2.1 (c2a33d8)
Visual Studio extension to enable development for Xamarin.Android.

Xamarin.iOS 11.3.0.47 (51128b8)
Visual Studio extension to enable development for Xamarin.iOS.

Log File

Xamarin Log file attached. Please check the logs dated 19/April/2018

App2.zip
security policy
System Info.txt
VS Studio info.txt
XamarinLogs.zip

@srikcgaa2
Copy link
Author

srikcgaa2 commented Apr 19, 2018

Android build error

Skipping target "_GenerateAndroidAssetsDir" because it has no outputs.
*C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(396,2): error MSB4061: The "GetAdditionalResourcesFromAssemblies" task could not be instantiated from "C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Build.Tasks.dll". * [E:\WS\B1\utilities\crypto\Utilities.Crypto.csproj]
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(396,2): error MSB4061: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. --->

System.InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms. [E:\WS\B1\utilities\pto\Utilities.csproj]

C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(396,2): error MSB4061: at

System.Security.Cryptography.MD5CryptoServiceProvider..ctor()

[E:\WS\B1\utilities\crypto\Utilities.Crypto.csproj]
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(396,2): error MSB4061: --- End of inner exception stack trace --- [E:\WS\B1\utilities\crypto\Utilities.Crypto.csproj]
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(396,2): error MSB4061: at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) [E:\WS\B1\utilities\crypto\Utilities.Crypto.csproj]
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(396,2): error MSB4061: at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) [E:\WS\B1\utilities\crypto\Utilities.Crypto.csproj]
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(396,2): error MSB4061: at System.Security.Cryptography.CryptoConfig.CreateFromName(String name, Object[] args) [E:\WS\B1\utilities\crypto\Utilities.Crypto.csproj]
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(396,2): error MSB4061: at System.Security.Cryptography.MD5.Create() [E:\WS\B1\utilities\crypto\Utilities.Crypto.csproj]
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(396,2): error MSB4061: at Xamarin.Android.Tasks.GetAdditionalResourcesFromAssemblies..ctor() [E:\WS\B1\utilities\crypto\Utilities.Crypto.csproj]
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(396,2): error MSB4060: The "GetAdditionalResourcesFromAssemblies" task has been declared or used incorrectly, or failed during construction. Check the spelling of the task name and the assembly name. [E:\WS\B1\utilities\crypto\Utilities.Crypto.csproj]

@srikcgaa2
Copy link
Author

iOS Build Error

Project "E:\WS\B1\Utilities.sln" (1) is building "E:\WS\B1\platform\Platform.csproj" (3) on node 1 (default targets).
C:\Program Files (x86)\MSBuild\Xamarin\iOS\Xamarin.iOS.Windows.After.targets(17,5): error MSB4018:

The "GenerateBuildSessionId" task failed unexpectedly.

[E:\WS\B1\platform\Platform.csproj]
C:\Program Files (x86)\MSBuild\Xamarin\iOS\Xamarin.iOS.Windows.After.targets(17,5): error MSB4018:

System.InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.

[E:\WS\B1\platform\Platform.csproj]
C:\Program Files (x86)\MSBuild\Xamarin\iOS\Xamarin.iOS.Windows.After.targets(17,5): error MSB4018: at

System.Security.Cryptography.MD5CryptoServiceProvider..ctor()

[E:\WS\B1\platform\Platform.csproj]
Done Building Project "E:\WS\B1\platform\Platform.csproj" (default targets) -- FAILED.

@srikcgaa2
Copy link
Author

We have also tried to use the latest and greatest Xamarin Android and Xamarin iOS and has the same issue

@BBrelandARHS
Copy link

Same thing happening to me as well.

@cyberjetx
Copy link

Still broken in 2019. Can we please get a fix in. Deleting the key at
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy

NOR disabling
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy]
"Enabled"=dword:00000001 -> dword:00000000

work at this time.

The "GenerateBuildSessionId" task failed unexpectedly. System.InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms. at System.Security.Cryptography.MD5CryptoServiceProvider..ctor()

@kealist
Copy link

kealist commented Aug 2, 2019

@jonathanpeppers This basically is making it so that our company cannot use Xamarin due to government requirements for IT. It seems for the most part that MD5 is used for the naming of cache directories, so there must be an alternative that doesn't use broken cryptographic algorithms.

I was trying to download source and take a look at it, but the /Prepare stage is failing to download the android files: (links work, so not sure why it would be failing)

    downloading android-2.3.3_r02.zip
    downloading android-15_r05.zip
    downloading android-16_r05.zip
    downloading android-17_r03.zip
    downloading android-18_r03.zip
    downloading android-19_r04.zip
    downloading android-20_r02.zip
    downloading android-21_r02.zip
    downloading android-22_r02.zip
    downloading platform-23_r03.zip
    downloading platform-24_r02.zip
    downloading platform-25_r03.zip
    downloading platform-26_r02.zip
    downloading platform-27_r03.zip
    downloading platform-28_r04.zip
    downloading platform-29_r01.zip
    downloading docs-24_r01.zip
    downloading android_m2repository_r47.zip
    downloading x86-29_r06.zip
    downloading android-ndk-r20-windows-x86_64.zip
    downloading build-tools_r29-windows.zip
    downloading sdk-tools-windows-4333796.zip
    downloading emulator-windows-5598178.zip
Download progress: 8.59% (307 MB at 307 MB/s)
Download progress: 8.59% (307 MB at 1.29 KB/s)
Download progress: 8.59% (307 MB at 22.5 KB/s)
Download progress: 8.59% (307 MB at 9.04 KB/s)
Download progress: 8.59% (307 MB at 7.75 KB/s)
Download progress: 8.59% (307 MB at 3.88 KB/s)
Download progress: 8.59% (307 MB at 11.6 KB/s)
Download progress: 8.59% (307 MB at 14.2 KB/s)
Download progress: 8.59% (307 MB at 3.88 KB/s)
Download progress: 8.6% (307 MB at 41.8 KB/s)

Step Xamarin.Android.Prepare.Step_Android_SDK_NDK failed: Failed to download https://dl.google.com/android/repository/android-2.3.3_r02.zip: The read operation failed, see inner exception.
System.InvalidOperationException: Step Xamarin.Android.Prepare.Step_Android_SDK_NDK failed: Failed to download https://dl.google.com/android/repository/android-2.3.3_r02.zip: The read operation failed, see inner exception
. ---> System.InvalidOperationException: Failed to download https://dl.google.com/android/repository/android-2.3.3_r02.zip: The read operation failed, see inner exception. ---> System.IO.IOException: The read operation fa
iled, see inner exception. ---> System.Net.WebException: The request was aborted: The request was canceled.
    at System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size)
    at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.Read(Byte[] buffer, Int32 offset, Int32 count)
    --- End of inner exception stack trace ---

@jonathanpeppers
Copy link
Member

@kealist I would just try the command again, it doesn't have a network retry yet, you can double-check that URL in a browser: https://dl.google.com/android/repository/android-2.3.3_r02.zip

There is also a video here if that is helpful: https://youtu.be/8qaQleb6Tbk

@kealist
Copy link

kealist commented Aug 2, 2019

@jonathanpeppers Thank you. Watching video. Unfortunately it fails on those downloads even if retrying or using different consoles. I tried with MSbuild 15 and 16. I don't want to pollute this issue with off topic build issues. though

@igloo15
Copy link

igloo15 commented Aug 7, 2019

I just wanted to add that we are also running into this problem recently. New security guidance at my company as mandated from government customers is to have this FIPS policy enabled. There is no way around it so now we are quickly becoming unable to build Xamarin projects.

I hope this is fixed soon surprised this has taken so long to get on people's radar considering it was reported over a year ago.

jonathanpeppers added a commit to jonathanpeppers/java.interop that referenced this issue Sep 16, 2019
Context: dotnet/android#1580

FIPS-compliant Windows 10 machines will throw an exception if the
`System.Security.Cryptography.MD5` class is used. We are not using
this for cryptography, but for naming collisions in Java package
names.

Therefore we can switch to using `CRC64` instead of `MD5`. A simple
implementation using a lookup table will suffice for our purposes.

I also expanded the enum:

    enum PackageNamingPolicy {
        LowercaseHash = 1,
        Lowercase = 2,
        LowercaseWithAssemblyName = 3,
        LowercaseMD5 = LowercaseHash,
        LowercaseCRC64 = 4,
    }

It will currently default to `MD5` as before, but can be changed to
`LowercaseCRC64` as needed. At some point we might also change the
default value of `LowercaseHash`.

Further changes will need to be made upstream in
xamarin/xamarin-android to replace (or make optional) usage of `MD5`
vs `CRC64`.
jonathanpeppers added a commit to jonathanpeppers/java.interop that referenced this issue Sep 17, 2019
Context: dotnet/android#1580

FIPS-compliant Windows 10 machines will throw an exception if the
`System.Security.Cryptography.MD5` class is used. We are not using
this for cryptography, but for naming collisions in Java package
names.

Therefore we can switch to using `CRC64` instead of `MD5`. A simple
implementation using a lookup table will suffice for our purposes.

I also expanded the enum:

    enum PackageNamingPolicy {
        LowercaseHash = 0,
        Lowercase = 1,
        LowercaseWithAssemblyName = 2,
        LowercaseMD5 = LowercaseHash,
        LowercaseCRC64 = 3,
    }

It will currently default to `MD5` as before, but can be changed to
`LowercaseCRC64` as needed. At some point we might also change the
default value of `LowercaseHash`.

Further changes will need to be made upstream in
xamarin/xamarin-android to replace (or make optional) usage of `MD5`
vs `CRC64`.
jonathanpeppers added a commit to jonathanpeppers/java.interop that referenced this issue Sep 18, 2019
Context: dotnet/android#1580

FIPS-compliant Windows 10 machines will throw an exception if the
`System.Security.Cryptography.MD5` class is used. We are not using
this for cryptography, but for naming collisions in Java package
names.

Therefore we can switch to using `CRC64` instead of `MD5`. A simple
implementation using a lookup table will suffice for our purposes.

I also expanded the enum:

    enum PackageNamingPolicy {
        LowercaseHash = 0,
        Lowercase = 1,
        LowercaseWithAssemblyName = 2,
        LowercaseMD5 = LowercaseHash,
        LowercaseCrc64 = 3,
    }

It will currently default to `MD5` as before, but can be changed to
`LowercaseCrc64` as needed. At some point we might also change the
default value of `LowercaseHash`.

Further changes will need to be made upstream in
xamarin/xamarin-android to replace (or make optional) usage of `MD5`
vs `CRC64`.
jonpryor pushed a commit to dotnet/java-interop that referenced this issue Sep 18, 2019
…#492)

Context: dotnet/android#1580
Context: https://xamarin.github.io/bugzilla-archives/15/15205/bug.html#c1
Context: https://xamarin.github.io/bugzilla-archives/16/16826/bug.html

`JavaNativeTypeManager` [uses MD5 to generate package names][0] for
Java Callable Wrappers, using the hash of the namespace name and the
containing assembly name to produce the Java package name.  This was
because it's perfectly valid for there to be *multiple*
`Example.Name` types within a .NET application, so long as they're
in different assemblies:

	// Lib1.dll
	namespace Example {
	    public class Name : Java.Lang.Object {}
	}

	// Lib2.dll
	namespace Example {
	    public class Name : Java.Lang.Object {}
	}

Because the (default) Java package name is a hash of the namespace
and assembly name, both of these `Example.Name` instances can coexist
because they get separate Java types,
`md5fcf4c1986bf17f9628efcaae404b0b1e.Name` (`md5(Example:Lib1)`) &
`md59dee366f823d92fb98288dda3e25ec49.Name` (`md5(Example:Lib2)`).

This was *never* done for cryptographic purposes.  This was only done
to reduce the likelihood of type name collisions.

Unfortunately, this use of MD5 results in an inability to use
Xamarin.Android on FIPS-enabled machines, because when the **System
cryptography: [Use FIPS compliant algorithms][1] for encryption,
hashing, and signing** setting is enabled on Windows:

!['Use Fips compliant algorithms' setting][2]

then the `System.Security.Cryptography.MD5.Create()` method will
throw `InvalidOperationException`.

In order to support FIPS-enabled machines, use a 64-bit
[Cyclic redundancy check][3] algorithm (CRC64) to instead generate
the Java package names, e.g. `crc64aae7d955a89b38db.Name` and
`crc64217c8705f00a5054.Name`.  A sim:ple implementation using a
lookup table will suffice for our purposes, ported to C# from:

	https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c

The use of CRC64 avoids the use of MD5, thus permitting execution on
FIPS-enabled Windows machines, and also results in *shorter*
directory names -- as the Java package name is a directory name --
which helps reduce Windows `MAX_PATH` issues.

I also expanded the enum:

	enum PackageNamingPolicy {
	    LowercaseHash = 0,
	    Lowercase = 1,
	    LowercaseWithAssemblyName = 2,
	    LowercaseMD5 = LowercaseHash,
	    LowercaseCrc64 = 3,
	}

Behavior still defaults to `MD5`, as before, but can be changed to
`PackageNamingPolicy.LowercaseCrc64` as needed.

Eventually we will change the default behavior to `LowercaseCrc64`,
and use of MD5 entirely removed.

Further changes will need to be made upstream in
xamarin/xamarin-android to fully integrate support for CRC64.

[0]: xamarin/monodroid@eb04c91
[1]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
[2]: https://user-images.githubusercontent.com/24926263/38981221-7e0bf7c4-43dc-11e8-8f16-9b6d284a55fb.PNG
[3]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 18, 2019
Context: dotnet#1580

Bump to xamarin/java.interop/master@397013ed

Changes: dotnet/java-interop@be6048e...397013e

Use of MD5 results in an inability to use Xamarin.Android on
FIPS-enabled machines, because when the **System cryptography:
[Use FIPS compliant algorithms][0] for encryption,
hashing, and signing** setting is enabled on Windows:

!['Use Fips compliant algorithms' setting][1]

then the `System.Security.Cryptography.MD5.Create()` method will
throw `InvalidOperationException`.

In order to support FIPS-enabled machines, use a 64-bit
[Cyclic redundancy check][2] algorithm (CRC64) to instead generate
the Java package names, e.g. `crc64aae7d955a89b38db.Name` and
`crc64217c8705f00a5054.Name`.  A simple implementation using a
lookup table will suffice for our purposes, ported to C# from:

    https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c

The use of CRC64 avoids the use of MD5, thus permitting execution on
FIPS-enabled Windows machines, and also results in *shorter*
directory names -- as the Java package name is a directory name --
which helps reduce Windows `MAX_PATH` issues.

~~ Changes so far ~~

All usage of `MD5.Create()` or `new SHA1Managed()` have been either:

* Switched to use `new Crc64()`
* Used `Files.HashString` if more appropriate

Calls to `jarsigner` now use:

    -sigalg SHA256withRSA -digestalg SHA-256

The previous default can be restored via
`$(AndroidApkSigningAlgorithm)` and `$(AndroidApkDigestAlgorithm)`
MSBuild properties.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
[1]: https://user-images.githubusercontent.com/24926263/38981221-7e0bf7c4-43dc-11e8-8f16-9b6d284a55fb.PNG
[2]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 19, 2019
Context: dotnet#1580

Bump to xamarin/java.interop/master@cd91e48

Changes: dotnet/java-interop@be6048e...cd91e48

Use of MD5 results in an inability to use Xamarin.Android on
FIPS-enabled machines, because when the **System cryptography:
[Use FIPS compliant algorithms][0] for encryption,
hashing, and signing** setting is enabled on Windows:

!['Use Fips compliant algorithms' setting][1]

then the `System.Security.Cryptography.MD5.Create()` method will
throw `InvalidOperationException`.

In order to support FIPS-enabled machines, use a 64-bit
[Cyclic redundancy check][2] algorithm (CRC64) to instead generate
the Java package names, e.g. `crc64aae7d955a89b38db.Name` and
`crc64217c8705f00a5054.Name`.  A simple implementation using a
lookup table will suffice for our purposes, ported to C# from:

    https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c

The use of CRC64 avoids the use of MD5, thus permitting execution on
FIPS-enabled Windows machines, and also results in *shorter*
directory names -- as the Java package name is a directory name --
which helps reduce Windows `MAX_PATH` issues.

~~ Changes so far ~~

All usage of `MD5.Create()` or `new SHA1Managed()` have been either:

* Switched to use `new Crc64()`
* Used `Files.HashString` if more appropriate
* `<GetAdditionalResourcesFromAssemblies/>` now emits `XA0120` if
  `new SHA1Managed()` fails. We will deprecate this code path.

Calls to `jarsigner` now use:

    -sigalg SHA256withRSA -digestalg SHA-256

The previous default can be restored via
`$(AndroidApkSigningAlgorithm)` and `$(AndroidApkDigestAlgorithm)`
MSBuild properties.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
[1]: https://user-images.githubusercontent.com/24926263/38981221-7e0bf7c4-43dc-11e8-8f16-9b6d284a55fb.PNG
[2]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 20, 2019
Context: dotnet#1580

Bump to xamarin/java.interop/master@cd91e48

Changes: dotnet/java-interop@be6048e...cd91e48

Use of MD5 results in an inability to use Xamarin.Android on
FIPS-enabled machines, because when the **System cryptography:
[Use FIPS compliant algorithms][0] for encryption,
hashing, and signing** setting is enabled on Windows:

!['Use Fips compliant algorithms' setting][1]

then the `System.Security.Cryptography.MD5.Create()` method will
throw `InvalidOperationException`.

In order to support FIPS-enabled machines, use a 64-bit
[Cyclic redundancy check][2] algorithm (CRC64) to instead generate
the Java package names, e.g. `crc64aae7d955a89b38db.Name` and
`crc64217c8705f00a5054.Name`.  A simple implementation using a
lookup table will suffice for our purposes, ported to C# from:

    https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c

The use of CRC64 avoids the use of MD5, thus permitting execution on
FIPS-enabled Windows machines, and also results in *shorter*
directory names -- as the Java package name is a directory name --
which helps reduce Windows `MAX_PATH` issues.

~~ Changes so far ~~

All usage of `MD5.Create()` or `new SHA1Managed()` have been either:

* Switched to use `new Crc64()`
* Used `Files.HashString` if more appropriate
* `<GetAdditionalResourcesFromAssemblies/>` now emits `XA0120` if
  `new SHA1Managed()` fails. We will deprecate this code path.

Calls to `jarsigner` now use:

    -sigalg SHA256withRSA -digestalg SHA-256

The previous default can be restored via
`$(AndroidApkSigningAlgorithm)` and `$(AndroidApkDigestAlgorithm)`
MSBuild properties.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
[1]: https://user-images.githubusercontent.com/24926263/38981221-7e0bf7c4-43dc-11e8-8f16-9b6d284a55fb.PNG
[2]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 20, 2019
Context: dotnet#1580

Bump to xamarin/java.interop/master@cd91e48

Changes: dotnet/java-interop@be6048e...cd91e48

Use of MD5 results in an inability to use Xamarin.Android on
FIPS-enabled machines, because when the **System cryptography:
[Use FIPS compliant algorithms][0] for encryption,
hashing, and signing** setting is enabled on Windows:

!['Use Fips compliant algorithms' setting][1]

then the `System.Security.Cryptography.MD5.Create()` method will
throw `InvalidOperationException`.

In order to support FIPS-enabled machines, use a 64-bit
[Cyclic redundancy check][2] algorithm (CRC64) to instead generate
the Java package names, e.g. `crc64aae7d955a89b38db.Name` and
`crc64217c8705f00a5054.Name`.  A simple implementation using a
lookup table will suffice for our purposes, ported to C# from:

    https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c

The use of CRC64 avoids the use of MD5, thus permitting execution on
FIPS-enabled Windows machines, and also results in *shorter*
directory names -- as the Java package name is a directory name --
which helps reduce Windows `MAX_PATH` issues.

~~ Changes so far ~~

All usage of `MD5.Create()` or `new SHA1Managed()` have been either:

* Switched to use `new Crc64()`
* Used `Files.HashString` if more appropriate
* `<GetAdditionalResourcesFromAssemblies/>` now emits `XA0120` if
  `new SHA1Managed()` fails. We will deprecate this code path.

Calls to `jarsigner` now use:

    -sigalg SHA256withRSA -digestalg SHA-256

The previous default can be restored via
`$(AndroidApkSigningAlgorithm)` and `$(AndroidApkDigestAlgorithm)`
MSBuild properties.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
[1]: https://user-images.githubusercontent.com/24926263/38981221-7e0bf7c4-43dc-11e8-8f16-9b6d284a55fb.PNG
[2]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 20, 2019
Context: dotnet#1580

Bump to xamarin/java.interop/master@cd91e48

Changes: dotnet/java-interop@be6048e...cd91e48

Use of MD5 results in an inability to use Xamarin.Android on
FIPS-enabled machines, because when the **System cryptography:
[Use FIPS compliant algorithms][0] for encryption,
hashing, and signing** setting is enabled on Windows:

!['Use Fips compliant algorithms' setting][1]

then the `System.Security.Cryptography.MD5.Create()` method will
throw `InvalidOperationException`.

In order to support FIPS-enabled machines, use a 64-bit
[Cyclic redundancy check][2] algorithm (CRC64) to instead generate
the Java package names, e.g. `crc64aae7d955a89b38db.Name` and
`crc64217c8705f00a5054.Name`.  A simple implementation using a
lookup table will suffice for our purposes, ported to C# from:

    https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c

The use of CRC64 avoids the use of MD5, thus permitting execution on
FIPS-enabled Windows machines, and also results in *shorter*
directory names -- as the Java package name is a directory name --
which helps reduce Windows `MAX_PATH` issues.

~~ Changes so far ~~

All usage of `MD5.Create()` or `new SHA1Managed()` have been either:

* Switched to use `new Crc64()`
* Used `Files.HashString` if more appropriate
* `<GetAdditionalResourcesFromAssemblies/>` now emits `XA0120` if
  `new SHA1Managed()` fails. We will deprecate this code path.

Calls to `jarsigner` now use:

    -sigalg SHA256withRSA -digestalg SHA-256

The previous default can be restored via
`$(AndroidApkSigningAlgorithm)` and `$(AndroidApkDigestAlgorithm)`
MSBuild properties.

`$(AndroidPackageNamingPolicy)` now defaults to `LowercaseCrc64`. The
previous default can be restored by setting
`AndroidPackageNamingPolicy=LowercaseMD5`.

`JNIEnv.Initialize()` sets `JavaNativeTypeManager.PackageNamingPolicy`
via the `__XA_PACKAGE_NAMING_POLICY__` environment variable.

`@(AndroidEnvironment)` values generated by Xamarin.Android at build
time are now placed in `$(IntermediateOutputPath)__environment__.txt`.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
[1]: https://user-images.githubusercontent.com/24926263/38981221-7e0bf7c4-43dc-11e8-8f16-9b6d284a55fb.PNG
[2]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 23, 2019
Context: dotnet#1580

Bump to xamarin/java.interop/master@cd91e48

Changes: dotnet/java-interop@be6048e...cd91e48

Use of MD5 results in an inability to use Xamarin.Android on
FIPS-enabled machines, because when the **System cryptography:
[Use FIPS compliant algorithms][0] for encryption,
hashing, and signing** setting is enabled on Windows:

!['Use Fips compliant algorithms' setting][1]

then the `System.Security.Cryptography.MD5.Create()` method will
throw `InvalidOperationException`.

In order to support FIPS-enabled machines, use a 64-bit
[Cyclic redundancy check][2] algorithm (CRC64) to instead generate
the Java package names, e.g. `crc64aae7d955a89b38db.Name` and
`crc64217c8705f00a5054.Name`.  A simple implementation using a
lookup table will suffice for our purposes, ported to C# from:

    https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c

The use of CRC64 avoids the use of MD5, thus permitting execution on
FIPS-enabled Windows machines, and also results in *shorter*
directory names -- as the Java package name is a directory name --
which helps reduce Windows `MAX_PATH` issues.

~~ Changes so far ~~

All usage of `MD5.Create()` or `new SHA1Managed()` have been either:

* Switched to use `new Crc64()`
* Used `Files.HashString` if more appropriate
* `<GetAdditionalResourcesFromAssemblies/>` now emits `XA0120` if
  `new SHA1Managed()` fails. We will deprecate this code path.

Calls to `jarsigner` now use:

    -sigalg SHA256withRSA -digestalg SHA-256

The previous default can be restored via
`$(AndroidApkSigningAlgorithm)` and `$(AndroidApkDigestAlgorithm)`
MSBuild properties.

`$(AndroidPackageNamingPolicy)` now defaults to `LowercaseCrc64`. The
previous default can be restored by setting
`AndroidPackageNamingPolicy=LowercaseMD5`.

`JNIEnv.Initialize()` sets `JavaNativeTypeManager.PackageNamingPolicy`
via the `__XA_PACKAGE_NAMING_POLICY__` environment variable.

`@(AndroidEnvironment)` values generated by Xamarin.Android at build
time are now placed in `$(IntermediateOutputPath)__environment__.txt`.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
[1]: https://user-images.githubusercontent.com/24926263/38981221-7e0bf7c4-43dc-11e8-8f16-9b6d284a55fb.PNG
[2]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 23, 2019
Context: dotnet#1580

Bump to xamarin/java.interop/master@cd91e48

Changes: dotnet/java-interop@be6048e...cd91e48

Use of MD5 results in an inability to use Xamarin.Android on
FIPS-enabled machines, because when the **System cryptography:
[Use FIPS compliant algorithms][0] for encryption,
hashing, and signing** setting is enabled on Windows:

!['Use Fips compliant algorithms' setting][1]

then the `System.Security.Cryptography.MD5.Create()` method will
throw `InvalidOperationException`.

In order to support FIPS-enabled machines, use a 64-bit
[Cyclic redundancy check][2] algorithm (CRC64) to instead generate
the Java package names, e.g. `crc64aae7d955a89b38db.Name` and
`crc64217c8705f00a5054.Name`.  A simple implementation using a
lookup table will suffice for our purposes, ported to C# from:

    https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c

The use of CRC64 avoids the use of MD5, thus permitting execution on
FIPS-enabled Windows machines, and also results in *shorter*
directory names -- as the Java package name is a directory name --
which helps reduce Windows `MAX_PATH` issues.

~~ Changes so far ~~

All usage of `MD5.Create()` or `new SHA1Managed()` have been either:

* Switched to use `new Crc64()`
* Used `Files.HashString` if more appropriate
* `<GetAdditionalResourcesFromAssemblies/>` now emits `XA0120` if
  `new SHA1Managed()` fails. We will deprecate this code path.

Calls to `jarsigner` now use:

    -sigalg SHA256withRSA -digestalg SHA-256

The previous default can be restored via
`$(AndroidApkSigningAlgorithm)` and `$(AndroidApkDigestAlgorithm)`
MSBuild properties.

`$(AndroidPackageNamingPolicy)` now defaults to `LowercaseCrc64`. The
previous default can be restored by setting
`AndroidPackageNamingPolicy=LowercaseMD5`.

`JNIEnv.Initialize()` sets `JavaNativeTypeManager.PackageNamingPolicy`
via the `__XA_PACKAGE_NAMING_POLICY__` environment variable.

`@(AndroidEnvironment)` values generated by Xamarin.Android at build
time are now placed in `$(IntermediateOutputPath)__environment__.txt`.

I added support for grabbing a `screenshot.png` with `DeviceTest.cs`.
This may be useful in the future, in general.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
[1]: https://user-images.githubusercontent.com/24926263/38981221-7e0bf7c4-43dc-11e8-8f16-9b6d284a55fb.PNG
[2]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 24, 2019
Context: dotnet#1580

Bump to xamarin/java.interop/master@cd91e48

Changes: dotnet/java-interop@be6048e...cd91e48

Use of MD5 results in an inability to use Xamarin.Android on
FIPS-enabled machines, because when the **System cryptography:
[Use FIPS compliant algorithms][0] for encryption,
hashing, and signing** setting is enabled on Windows:

!['Use Fips compliant algorithms' setting][1]

then the `System.Security.Cryptography.MD5.Create()` method will
throw `InvalidOperationException`.

In order to support FIPS-enabled machines, use a 64-bit
[Cyclic redundancy check][2] algorithm (CRC64) to instead generate
the Java package names, e.g. `crc64aae7d955a89b38db.Name` and
`crc64217c8705f00a5054.Name`.  A simple implementation using a
lookup table will suffice for our purposes, ported to C# from:

    https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c

The use of CRC64 avoids the use of MD5, thus permitting execution on
FIPS-enabled Windows machines, and also results in *shorter*
directory names -- as the Java package name is a directory name --
which helps reduce Windows `MAX_PATH` issues.

~~ Changes so far ~~

All usage of `MD5.Create()` or `new SHA1Managed()` have been either:

* Switched to use `new Crc64()`
* Used `Files.HashString` if more appropriate
* `<GetAdditionalResourcesFromAssemblies/>` now emits `XA0120` if
  `new SHA1Managed()` fails. We will deprecate this code path.

Calls to `jarsigner` now use:

    -sigalg SHA256withRSA -digestalg SHA-256

The previous default can be restored via
`$(AndroidApkSigningAlgorithm)` and `$(AndroidApkDigestAlgorithm)`
MSBuild properties.

`$(AndroidPackageNamingPolicy)` now defaults to `LowercaseCrc64`. The
previous default can be restored by setting
`AndroidPackageNamingPolicy=LowercaseMD5`.

`JNIEnv.Initialize()` sets `JavaNativeTypeManager.PackageNamingPolicy`
via the `__XA_PACKAGE_NAMING_POLICY__` environment variable.

`@(AndroidEnvironment)` values generated by Xamarin.Android at build
time are now placed in `$(IntermediateOutputPath)__environment__.txt`.

I added support for grabbing a `screenshot.png` with `DeviceTest.cs`.
This may be useful in the future, in general.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
[1]: https://user-images.githubusercontent.com/24926263/38981221-7e0bf7c4-43dc-11e8-8f16-9b6d284a55fb.PNG
[2]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 24, 2019
Context: dotnet#1580

Bump to xamarin/java.interop/master@cd91e48

Changes: dotnet/java-interop@be6048e...cd91e48

Use of MD5 results in an inability to use Xamarin.Android on
FIPS-enabled machines, because when the **System cryptography:
[Use FIPS compliant algorithms][0] for encryption,
hashing, and signing** setting is enabled on Windows:

!['Use Fips compliant algorithms' setting][1]

then the `System.Security.Cryptography.MD5.Create()` method will
throw `InvalidOperationException`.

In order to support FIPS-enabled machines, use a 64-bit
[Cyclic redundancy check][2] algorithm (CRC64) to instead generate
the Java package names, e.g. `crc64aae7d955a89b38db.Name` and
`crc64217c8705f00a5054.Name`.  A simple implementation using a
lookup table will suffice for our purposes, ported to C# from:

    https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c

The use of CRC64 avoids the use of MD5, thus permitting execution on
FIPS-enabled Windows machines, and also results in *shorter*
directory names -- as the Java package name is a directory name --
which helps reduce Windows `MAX_PATH` issues.

~~ Changes so far ~~

All usage of `MD5.Create()` or `new SHA1Managed()` have been either:

* Switched to use `new Crc64()`
* Used `Files.HashString` if more appropriate
* `<GetAdditionalResourcesFromAssemblies/>` now emits `XA0120` if
  `new SHA1Managed()` fails. We will deprecate this code path.

Calls to `jarsigner` now use:

    -sigalg SHA256withRSA -digestalg SHA-256

The previous default can be restored via
`$(AndroidApkSigningAlgorithm)` and `$(AndroidApkDigestAlgorithm)`
MSBuild properties.

`$(AndroidPackageNamingPolicy)` now defaults to `LowercaseCrc64`. The
previous default can be restored by setting
`AndroidPackageNamingPolicy=LowercaseMD5`.

`JNIEnv.Initialize()` sets `JavaNativeTypeManager.PackageNamingPolicy`
via the `__XA_PACKAGE_NAMING_POLICY__` environment variable.

`@(AndroidEnvironment)` values generated by Xamarin.Android at build
time are now placed in `$(IntermediateOutputPath)__environment__.txt`.

A new `_CleanIntermediateIfPackageNamingPolicyChanges` target will run
`_CleanMonoAndroidIntermediateDir` if `$(AndroidPackageNamingPolicy)`
changes. This is necessary because many Java source files will be
invalid.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
[1]: https://user-images.githubusercontent.com/24926263/38981221-7e0bf7c4-43dc-11e8-8f16-9b6d284a55fb.PNG
[2]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 24, 2019
Context: dotnet#1580

Bump to xamarin/java.interop/master@cd91e48

Changes: dotnet/java-interop@be6048e...cd91e48

Use of MD5 results in an inability to use Xamarin.Android on
FIPS-enabled machines, because when the **System cryptography:
[Use FIPS compliant algorithms][0] for encryption,
hashing, and signing** setting is enabled on Windows:

!['Use Fips compliant algorithms' setting][1]

then the `System.Security.Cryptography.MD5.Create()` method will
throw `InvalidOperationException`.

In order to support FIPS-enabled machines, use a 64-bit
[Cyclic redundancy check][2] algorithm (CRC64) to instead generate
the Java package names, e.g. `crc64aae7d955a89b38db.Name` and
`crc64217c8705f00a5054.Name`.  A simple implementation using a
lookup table will suffice for our purposes, ported to C# from:

    https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c

The use of CRC64 avoids the use of MD5, thus permitting execution on
FIPS-enabled Windows machines, and also results in *shorter*
directory names -- as the Java package name is a directory name --
which helps reduce Windows `MAX_PATH` issues.

~~ Changes so far ~~

All usage of `MD5.Create()` or `new SHA1Managed()` have been either:

* Switched to use `new Crc64()`
* Used `Files.HashString` if more appropriate
* `<GetAdditionalResourcesFromAssemblies/>` now emits `XA0120` if
  `new SHA1Managed()` fails. We will deprecate this code path.

Calls to `jarsigner` now use:

    -sigalg SHA256withRSA -digestalg SHA-256

The previous default can be restored via
`$(AndroidApkSigningAlgorithm)` and `$(AndroidApkDigestAlgorithm)`
MSBuild properties.

`$(AndroidPackageNamingPolicy)` now defaults to `LowercaseCrc64`. The
previous default can be restored by setting
`AndroidPackageNamingPolicy=LowercaseMD5`.

`JNIEnv.Initialize()` sets `JavaNativeTypeManager.PackageNamingPolicy`
via the `__XA_PACKAGE_NAMING_POLICY__` environment variable.

`@(AndroidEnvironment)` values generated by Xamarin.Android at build
time are now placed in `$(IntermediateOutputPath)__environment__.txt`.

A new `_CleanIntermediateIfPackageNamingPolicyChanges` target will run
`_CleanMonoAndroidIntermediateDir` if `$(AndroidPackageNamingPolicy)`
changes. This is necessary because many Java source files will be
invalid.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
[1]: https://user-images.githubusercontent.com/24926263/38981221-7e0bf7c4-43dc-11e8-8f16-9b6d284a55fb.PNG
[2]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
jonpryor pushed a commit that referenced this issue Sep 30, 2019
Context: #1580

Bump to xamarin/java.interop/master@cd91e48

Changes: dotnet/java-interop@be6048e...cd91e48

Use of MD5 results in an inability to use Xamarin.Android on FIPS-
enabled machines, because when the **System cryptography:
[Use FIPS compliant algorithms][0] for encryption, hashing, and
signing** setting is enabled on Windows:

!['Use Fips compliant algorithms' setting][1]

then the `System.Security.Cryptography.MD5.Create()` method will
throw `InvalidOperationException`.

In order to support FIPS-enabled machines, use a 64-bit
[Cyclic redundancy check][2] algorithm (CRC64) to instead generate
the Java package names, e.g. `crc64aae7d955a89b38db.Name` and
`crc64217c8705f00a5054.Name`.  A simple implementation using a
lookup table will suffice for our purposes, ported to C# from:

	https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c

The use of CRC64 avoids the use of MD5, thus permitting execution on
FIPS-enabled Windows machines, and also results in *shorter*
directory names -- as the Java package name is a directory name --
which helps reduce Windows `MAX_PATH` issues.

All usage of `MD5.Create()` or `new SHA1Managed()` have been either:

  * Switched to use `new Crc64()`
  * Used `Files.HashString()` if more appropriate
  * `<GetAdditionalResourcesFromAssemblies/>` now emits warning
    `XA0120` if `new SHA1Managed()` fails.

    We will deprecate this code path.

Calls to `jarsigner` now use:

	-sigalg SHA256withRSA -digestalg SHA-256

The previous default can be restored via
`$(AndroidApkSigningAlgorithm)` and `$(AndroidApkDigestAlgorithm)`
MSBuild properties.

`$(AndroidPackageNamingPolicy)` now defaults to `LowercaseCrc64`.
The previous default can be restored by setting
`$(AndroidPackageNamingPolicy)=LowercaseMD5`.

`JNIEnv.Initialize()` sets `JavaNativeTypeManager.PackageNamingPolicy`
via the `__XA_PACKAGE_NAMING_POLICY__` environment variable.

`@(AndroidEnvironment)` values generated by Xamarin.Android at build
time are now placed in `$(IntermediateOutputPath)__environment__.txt`.

A new `_CleanIntermediateIfPackageNamingPolicyChanges` target will run
`_CleanMonoAndroidIntermediateDir` if `$(AndroidPackageNamingPolicy)`
changes. This is necessary because many Java source files will be
invalid.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
[1]: https://user-images.githubusercontent.com/24926263/38981221-7e0bf7c4-43dc-11e8-8f16-9b6d284a55fb.PNG
[2]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
jonpryor pushed a commit to dotnet/java-interop that referenced this issue Sep 30, 2019
…#492)

Context: dotnet/android#1580
Context: https://xamarin.github.io/bugzilla-archives/15/15205/bug.html#c1
Context: https://xamarin.github.io/bugzilla-archives/16/16826/bug.html

`JavaNativeTypeManager` [uses MD5 to generate package names][0] for
Java Callable Wrappers, using the hash of the namespace name and the
containing assembly name to produce the Java package name.  This was
because it's perfectly valid for there to be *multiple*
`Example.Name` types within a .NET application, so long as they're
in different assemblies:

	// Lib1.dll
	namespace Example {
	    public class Name : Java.Lang.Object {}
	}

	// Lib2.dll
	namespace Example {
	    public class Name : Java.Lang.Object {}
	}

Because the (default) Java package name is a hash of the namespace
and assembly name, both of these `Example.Name` instances can coexist
because they get separate Java types,
`md5fcf4c1986bf17f9628efcaae404b0b1e.Name` (`md5(Example:Lib1)`) &
`md59dee366f823d92fb98288dda3e25ec49.Name` (`md5(Example:Lib2)`).

This was *never* done for cryptographic purposes.  This was only done
to reduce the likelihood of type name collisions.

Unfortunately, this use of MD5 results in an inability to use
Xamarin.Android on FIPS-enabled machines, because when the **System
cryptography: [Use FIPS compliant algorithms][1] for encryption,
hashing, and signing** setting is enabled on Windows:

!['Use Fips compliant algorithms' setting][2]

then the `System.Security.Cryptography.MD5.Create()` method will
throw `InvalidOperationException`.

In order to support FIPS-enabled machines, use a 64-bit
[Cyclic redundancy check][3] algorithm (CRC64) to instead generate
the Java package names, e.g. `crc64aae7d955a89b38db.Name` and
`crc64217c8705f00a5054.Name`.  A sim:ple implementation using a
lookup table will suffice for our purposes, ported to C# from:

	https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c

The use of CRC64 avoids the use of MD5, thus permitting execution on
FIPS-enabled Windows machines, and also results in *shorter*
directory names -- as the Java package name is a directory name --
which helps reduce Windows `MAX_PATH` issues.

I also expanded the enum:

	enum PackageNamingPolicy {
	    LowercaseHash = 0,
	    Lowercase = 1,
	    LowercaseWithAssemblyName = 2,
	    LowercaseMD5 = LowercaseHash,
	    LowercaseCrc64 = 3,
	}

Behavior still defaults to `MD5`, as before, but can be changed to
`PackageNamingPolicy.LowercaseCrc64` as needed.

Eventually we will change the default behavior to `LowercaseCrc64`,
and use of MD5 entirely removed.

Further changes will need to be made upstream in
xamarin/xamarin-android to fully integrate support for CRC64.

[0]: xamarin/monodroid@eb04c91
[1]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
[2]: https://user-images.githubusercontent.com/24926263/38981221-7e0bf7c4-43dc-11e8-8f16-9b6d284a55fb.PNG
[3]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
jonpryor pushed a commit that referenced this issue Sep 30, 2019
Context: #1580

Bump to xamarin/java.interop/d16-4@b98f4232

Changes: dotnet/java-interop@4fd3539...b98f423

Use of MD5 results in an inability to use Xamarin.Android on FIPS-
enabled machines, because when the **System cryptography:
[Use FIPS compliant algorithms][0] for encryption, hashing, and
signing** setting is enabled on Windows:

!['Use Fips compliant algorithms' setting][1]

then the `System.Security.Cryptography.MD5.Create()` method will
throw `InvalidOperationException`.

In order to support FIPS-enabled machines, use a 64-bit
[Cyclic redundancy check][2] algorithm (CRC64) to instead generate
the Java package names, e.g. `crc64aae7d955a89b38db.Name` and
`crc64217c8705f00a5054.Name`.  A simple implementation using a
lookup table will suffice for our purposes, ported to C# from:

	https://github.com/gityf/crc/blob/8045f50ba6e4193d4ee5d2539025fef26e613c9f/crc/crc64.c

The use of CRC64 avoids the use of MD5, thus permitting execution on
FIPS-enabled Windows machines, and also results in *shorter*
directory names -- as the Java package name is a directory name --
which helps reduce Windows `MAX_PATH` issues.

All usage of `MD5.Create()` or `new SHA1Managed()` have been either:

  * Switched to use `new Crc64()`
  * Used `Files.HashString()` if more appropriate
  * `<GetAdditionalResourcesFromAssemblies/>` now emits warning
    `XA0120` if `new SHA1Managed()` fails.

    We will deprecate this code path.

Calls to `jarsigner` now use:

	-sigalg SHA256withRSA -digestalg SHA-256

The previous default can be restored via
`$(AndroidApkSigningAlgorithm)` and `$(AndroidApkDigestAlgorithm)`
MSBuild properties.

`$(AndroidPackageNamingPolicy)` now defaults to `LowercaseCrc64`.
The previous default can be restored by setting
`$(AndroidPackageNamingPolicy)=LowercaseMD5`.

`JNIEnv.Initialize()` sets `JavaNativeTypeManager.PackageNamingPolicy`
via the `__XA_PACKAGE_NAMING_POLICY__` environment variable.

`@(AndroidEnvironment)` values generated by Xamarin.Android at build
time are now placed in `$(IntermediateOutputPath)__environment__.txt`.

A new `_CleanIntermediateIfPackageNamingPolicyChanges` target will run
`_CleanMonoAndroidIntermediateDir` if `$(AndroidPackageNamingPolicy)`
changes. This is necessary because many Java source files will be
invalid.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
[1]: https://user-images.githubusercontent.com/24926263/38981221-7e0bf7c4-43dc-11e8-8f16-9b6d284a55fb.PNG
[2]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Oct 2, 2019
Fixes: dotnet#1580

If this works out, this would run our MSBuild test suite while the
[Use FIPS compliant algorithms][0] group policy setting is enabled.

This would validate that Xamarin.Android works as expected going
forward.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Oct 2, 2019
Fixes: dotnet#1580

If this works out, this would run our MSBuild test suite while the
[Use FIPS compliant algorithms][0] group policy setting is enabled.

This would validate that Xamarin.Android works as expected going
forward.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Oct 3, 2019
Fixes: dotnet#1580

If this works out, this would run our MSBuild test suite while the
[Use FIPS compliant algorithms][0] group policy setting is enabled.

This would validate that Xamarin.Android works as expected going
forward.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Oct 15, 2019
Fixes: dotnet#1580

If this works out, this would run our MSBuild test suite while the
[Use FIPS compliant algorithms][0] group policy setting is enabled.

This would validate that Xamarin.Android works as expected going
forward.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Oct 16, 2019
Fixes: dotnet#1580

If this works out, this would run our MSBuild test suite while the
[Use FIPS compliant algorithms][0] group policy setting is enabled.

This would validate that Xamarin.Android works as expected going
forward.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
@kealist
Copy link

kealist commented Nov 2, 2020

I do believe this is resolved for me now. Thank you for fixing the issue

@jpobst
Copy link
Contributor

jpobst commented Aug 8, 2022

Agreed, I think the policy checks MS Security has added to our build pipeline ensure there are currently no more non-FIPS compliant algorithms, and it should fail our build if any ever get added back.

@jpobst jpobst closed this as completed Aug 8, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Sep 8, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: App+Library Build Issues when building Library projects or Application projects.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants