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

SDK fails with "Module checksum failed: Could not find '/app/<Unknown>'." in a Linux container on .NET 8 #342

Closed
4 tasks done
tmoore8RJ opened this issue Dec 9, 2024 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@tmoore8RJ
Copy link

tmoore8RJ commented Dec 9, 2024

Description of the Issue

SDK fails with "Module checksum failed: Could not find '/app/'." when deployed in a Linux container on .NET 8

I'm in the process of upgrading some of my organization's .NET Framework apps to .NET Core. I updated the SDK from the deprecated one to Box.SDK.Gen 1.4.0.

My organization's C# architect notes that Bouncy Castle BC-FNA 1.0.2 is certified for use with .NET applications running on CLR 4.

I thought this issue might be similar to the AWS PublishReadyToRun issue, but I wanted to confirm they're related. It seems like in my case, Bouncy Castle is attempting to use Win32 calls in the Linux container.

Steps to Reproduce

I'm working with other teams at my organization to get a minimal example that reproduces the issue. These are the steps that are visible to me so far from our build process:

  1. Base image OS Ubuntu 22.04 jammy-20240911.1
  2. dotnet build --no-incremental -r linux-x64 --no-self-contained --no-restore --configuration Release AppService.sln
  3. dotnet publish --no-build -c Release -r linux-x64 AppService/src/AppService.csproj -o ./Target --no-self-contained -p:PublishSingleFile=true
  4. COPY Target/AppService app-bin
  5. Call GetFolderItemsAsync from the Box client's FoldersManager

Expected Behavior

A list of folders is returned.

Error Message, Including Stack Trace

unable to read encrypted data: Module checksum failed: Could not find file '/app/<Unknown>'.
 ---> Org.BouncyCastle.Pkcs.PkcsException: unable to read encrypted data: Module checksum failed: Could not find file '/app/<Unknown>'.
 ---> Org.BouncyCastle.Crypto.CryptoOperationError: Module checksum failed: Could not find file '/app/<Unknown>'.
 ---> System.IO.FileNotFoundException: Could not find file '/app/<Unknown>'.
File name: '/app/<Unknown>'
   at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirError)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, UnixFileMode openPermissions, Int64& fileLength, UnixFileMode& filePermissions, Boolean failForSymlink, Boolean& wasSymlink, Func`4 createOpenException)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode, Func`4 createOpenException)
   at System.IO.File.OpenHandle(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.File.ReadAllBytes(String path)
   at Org.BouncyCastle.Crypto.CryptoStatus.CalculateAssemblyHMac()
   at Org.BouncyCastle.Crypto.CryptoStatus.ChecksumValidate()
   --- End of inner exception stack trace ---
   at Org.BouncyCastle.Crypto.CryptoStatus.MoveToErrorStatus(CryptoOperationError error)
   at Org.BouncyCastle.Crypto.CryptoStatus.ChecksumValidate()
   at Org.BouncyCastle.Crypto.CryptoStatus.IsReady()
   at Org.BouncyCastle.Security.SecurityContext.CreateBuilder[A](IBuilderServiceType`1 type)
   at Org.BouncyCastle.Crypto.CryptoServicesRegistrar.CreateService[A](IBuilderServiceType`1 type)
   at Org.BouncyCastle.Operators.PkixPbeDecryptorProviderBuilder.MyDecryptorBuilderProvider.CreateDecryptorBuilder(AlgorithmIdentifier algorithmDetails)
   at Org.BouncyCastle.Pkcs.Pkcs8EncryptedPrivateKeyInfo.DecryptPrivateKeyInfo(IDecryptorBuilderProvider`1 inputDecryptorProvider)
   --- End of inner exception stack trace ---
   at Org.BouncyCastle.Pkcs.Pkcs8EncryptedPrivateKeyInfo.DecryptPrivateKeyInfo(IDecryptorBuilderProvider`1 inputDecryptorProvider)
   at Box.Sdk.Gen.Internal.JwtUtils.GetSigningCredentials(JwtKey key)
   at Box.Sdk.Gen.Internal.JwtUtils.CreateJwtAssertion(Dictionary`2 claims, JwtKey key, JwtSignOptions options)
   at Box.Sdk.Gen.BoxJwtAuth.RefreshTokenAsync(NetworkSession networkSession)
   at Box.Sdk.Gen.BoxJwtAuth.RetrieveTokenAsync(NetworkSession networkSession)
   at Box.Sdk.Gen.BoxJwtAuth.RetrieveAuthorizationHeaderAsync(NetworkSession networkSession)
   at Box.Sdk.Gen.Internal.HttpClientAdapter.BuildHttpRequest(FetchOptions options, Stream stream)
   at Box.Sdk.Gen.Internal.HttpClientAdapter.FetchAsync(FetchOptions options)
   at Box.Sdk.Gen.Managers.FoldersManager.GetFolderItemsAsync(String folderId, GetFolderItemsQueryParams queryParams, GetFolderItemsHeaders headers, Nullable`1 cancellationToken)
System.IO.FileNotFoundException: Could not find file '/app/<Unknown>'.
File name: '/app/<Unknown>'
   at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirError)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, UnixFileMode openPermissions, Int64& fileLength, UnixFileMode& filePermissions, Boolean failForSymlink, Boolean& wasSymlink, Func`4 createOpenException)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode, Func`4 createOpenException)
   at System.IO.File.OpenHandle(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.File.ReadAllBytes(String path)
   at Org.BouncyCastle.Crypto.CryptoStatus.CalculateAssemblyHMac()
   at Org.BouncyCastle.Crypto.CryptoStatus.ChecksumValidate()

Versions Used

.NET SDK: 1.4.0
.NET: 8.0.10

@congminh1254
Copy link
Member

Hi @tmoore8RJ

After investigation, I found out this issue can from the feature PublishSingleFile during the publish process, from the docs of MS, we can ExcludeFromSingleFile but it's not really working from my side.

I found a workaround for this issue from this comment, with some modification from my side, so you can try this:

<Target Name="ExplicitRemoveFromFilesToBundle" BeforeTargets="GenerateSingleFileBundle" DependsOnTargets="PrepareForBundle">
  <ItemGroup>
	  <FilesToRemoveFromBundle Include="@(FilesToBundle)" Condition="$([System.String]::new('%(Filename)').ToLower().Contains('bc-fips')) OR $([System.String]::new('%(Filename)').ToLower().Contains('bcpkix'))" />
  </ItemGroup>
  <Message Text="FilesToRemoveFromBundle '@(FilesToRemoveFromBundle)'" Importance="high" />
  <ItemGroup>
	  <FilesToBundle Remove="@(FilesToRemoveFromBundle)" />
  </ItemGroup>
</Target>
<Target Name="CopyFilesToRemoveFromBundle" AfterTargets="Publish">
  <Copy SourceFiles="@(FilesToRemoveFromBundle)" DestinationFolder="$(PublishDir)" />
  <Message Text="Copied files to remove from bundle to '$(PublishDir)'" Importance="high" />
</Target>

Please put this into the bottom of your .csproj file and let me know if it resolves the issue.

Bests,
Minh

@tmoore8RJ
Copy link
Author

Awesome, makes sense. I'll test these changes out and report back. Thanks!

@tmoore8RJ
Copy link
Author

I got it working. Thank you so much for your help!

In case others encounter something similar, in addition to the snippet provided that makes sure the BouncyCastle DLLs are in the Target folder after I restore, build, and publish, I also modified my Docker file to use the same pattern as the arguments to FilesToRemoveFromBundle to match the DLLs and copy them into the container in the same folder as the single file produced by the publish.

My csproj file with unrelated entries omitted

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <AssemblyName>AppService</AssemblyName>
    <RootNamespace>AppService</RootNamespace>
    <TargetFramework>net8.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Box.Sdk.Gen" Version="1.4.0" />
  </ItemGroup>
  <Target Name="ExplicitRemoveFromFilesToBundle" BeforeTargets="GenerateSingleFileBundle" DependsOnTargets="PrepareForBundle">
    <ItemGroup>
      <FilesToRemoveFromBundle Include="@(FilesToBundle)" Condition="$([System.String]::new('%(Filename)').ToLower().Contains('bc-fips')) OR $([System.String]::new('%(Filename)').ToLower().Contains('bcpkix'))" />
    </ItemGroup>
    <Message Text="FilesToRemoveFromBundle '@(FilesToRemoveFromBundle)'" Importance="high" />
    <ItemGroup>
      <FilesToBundle Remove="@(FilesToRemoveFromBundle)" />
    </ItemGroup>
  </Target>
  <Target Name="CopyFilesToRemoveFromBundle" AfterTargets="Publish">
    <Copy SourceFiles="@(FilesToRemoveFromBundle)" DestinationFolder="$(PublishDir)" />
    <Message Text="Copied files to remove from bundle to '$(PublishDir)'" Importance="high" />
  </Target>
</Project>

The additional commands in my Docker file

COPY Target/*bc-fips* .
COPY Target/*bcpkix-fips* .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

7 participants