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

dotnet nuget sign error: Unknown error (0xc100000d) #100414

Closed
edoardo-kolver opened this issue Mar 28, 2024 · 9 comments · Fixed by #100658
Closed

dotnet nuget sign error: Unknown error (0xc100000d) #100414

edoardo-kolver opened this issue Mar 28, 2024 · 9 comments · Fixed by #100658
Assignees
Milestone

Comments

@edoardo-kolver
Copy link

Description

I try to sign a nuget package with my EV2 code signing certificate from Entrust and I get this error:

error: Unknown error (0xc100000d)

The EV2 certificate being used is valid and is confirmed working for signing exe and jar files

Reproduction Steps

This is the command I'm using (with some info redacted):
dotnet nuget sign "mynugetpackage.nupkg" --certificate-path "mycert.cer" --timestamper "http://timestamp.entrust.net/rfc3161ts2" -v detailed

Expected behavior

Package gets signed

Actual behavior

This is the output I'm getting (with some info REDACTED). The information on the certificates matches what I expect for my certificate.

X.509 certificate chain validation will use the default trust store selected by .NET for code signing.
X.509 certificate chain validation will use the default trust store selected by .NET for timestamping.

Signing package(s) with certificate:
  Subject Name: CN=_REDACTED_, SERIALNUMBER=_REDACTED_, OID.2.5.4.15=Private Organization, O=_REDACTED_, OID.1.3.6.1.4.1.311.60.2.1.3=_REDACTED_, L=_REDACTED_, S=_REDACTED_, C=_REDACTED_
  SHA1 hash: _REDACTED_
  SHA256 hash: _REDACTED_
  Issued by: CN=Entrust Extended Validation Code Signing CA - EVCS2, O="Entrust, Inc.", C=US
  Valid from: 8/14/2023 7:34:11 PM to 8/14/2026 7:34:10 PM
Timestamping package(s) with:
http://timestamp.entrust.net/rfc3161ts2
error: Unknown error (0xc100000d)
trace: System.Security.Cryptography.CryptographicException: Unknown error (0xc100000d)
trace:    at System.Security.Cryptography.RSABCrypt.TrySignHash(ReadOnlySpan`1 hash, Span`1 destination, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding, Int32& bytesWritten)
trace:    at System.Security.Cryptography.Pkcs.CmsSignature.RSACmsSignature.SignCore(ReadOnlySpan`1 dataHash, HashAlgorithmName hashAlgorithmName, X509Certificate2 certificate, AsymmetricAlgorithm key, Boolean silent, RSASignaturePadding signaturePadding, Byte[]& signatureValue)
trace:    at System.Security.Cryptography.Pkcs.CmsSignature.RSAPkcs1CmsSignature.Sign(ReadOnlySpan`1 dataHash, HashAlgorithmName hashAlgorithmName, X509Certificate2 certificate, AsymmetricAlgorithm key, Boolean silent, String& signatureAlgorithm, Byte[]& signatureValue, Byte[]& signatureParameters)
trace:    at System.Security.Cryptography.Pkcs.CmsSignature.Sign(ReadOnlySpan`1 dataHash, HashAlgorithmName hashAlgorithmName, X509Certificate2 certificate, AsymmetricAlgorithm key, Boolean silent, RSASignaturePadding rsaSignaturePadding, String& oid, ReadOnlyMemory`1& signatureValue, ReadOnlyMemory`1& signatureParameters)
trace:    at System.Security.Cryptography.Pkcs.CmsSigner.Sign(ReadOnlyMemory`1 data, String contentTypeOid, Boolean silent, X509Certificate2Collection& chainCerts)
trace:    at System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner signer, Boolean silent)
trace:    at NuGet.Packaging.Signing.X509SignatureProvider.CreatePrimarySignature(CmsSigner cmsSigner, SignPackageRequest request, Byte[] signingData)
trace:    at NuGet.Packaging.Signing.X509SignatureProvider.CreatePrimarySignatureAsync(SignPackageRequest request, SignatureContent signatureContent, ILogger logger, CancellationToken token)
trace:    at NuGet.Packaging.Signing.SigningUtility.SignAsync(SigningOptions options, SignPackageRequest signRequest, CancellationToken token)
trace:    at NuGet.Commands.SignCommandRunner.ExecuteCommandAsync(IEnumerable`1 packagesToSign, SignPackageRequest signPackageRequest, String timestamper, ILogger logger, String outputDirectory, Boolean overwrite, CancellationToken token)

Regression?

No response

Known Workarounds

No response

Configuration

dotnet --info

.NET SDK:
 Version:           8.0.101
 Commit:            6eceda187b
 Workload version:  8.0.100-manifests.30fce108

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.22631
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\8.0.101\

.NET workloads installed:
 Workload version: 8.0.100-manifests.30fce108
There are no installed workloads to display.

Host:
  Version:      8.0.1
  Architecture: x64
  Commit:       bf5e279d92

.NET SDKs installed:
  6.0.406 [C:\Program Files\dotnet\sdk]
  7.0.201 [C:\Program Files\dotnet\sdk]
  8.0.101 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 6.0.10 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 7.0.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 7.0.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

Other information

No response

Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-security, @bartonjs, @vcsjones
See info in area-owners.md if you want to be subscribed.

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Mar 28, 2024
@filipnavara
Copy link
Member

Presumably the private key is stored on some security key, right? What would be the manufacturer, firmware and driver version of the said key?

@edoardo-kolver
Copy link
Author

It's a Safenet 5110: https://cpl.thalesgroup.com/access-management/authenticators/pki-usb-authentication/etoken-5110-usb-token
hardware info says eToken 5110 CC (940)
When I use other signing command line tools, during the signing process a popup appears asking for my token password. The software that runs this is "safenet authentication client" v 10.8 R6 (10.8.2154.0)

@edoardo-kolver edoardo-kolver closed this as not planned Won't fix, can't repro, duplicate, stale Mar 28, 2024
@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label Mar 28, 2024
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Mar 28, 2024
@edoardo-kolver
Copy link
Author

(didn't mean to close it)

@vcsjones
Copy link
Member

RSABCrypt.TrySignHash

If you are using a hardware token, then it seems like we have an issue where the key is on hardware but we are using BCrypt instead of NCrypt with the key handle, which isn't going to work.

Let me see if I can reproduce this.

@vcsjones
Copy link
Member

vcsjones commented Apr 4, 2024

I was just able to reproduce the issue with the nuget CLI, let me see if I can work create a reproduction with SignedCms.

As a workaround for now, I would recommend using --certificate-fingerprint instead of specifying the public certificate file, and ensure your certificate is in the certificate store. You can use --certificate-store-name and --certificate-store-name if your certificate is not in CurrentUser/My.

@vcsjones
Copy link
Member

vcsjones commented Apr 4, 2024

Okay, this is just a case of SignedCms, and the crypto-stack more broadly, not looking for private keys that are detached from the certificate when loaded as a file. This can be reproduced entirely with

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;

using RSA rsa = RSA.Create(2048);
CertificateRequest req = new CertificateRequest("CN=Kevin Jones", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
X509Certificate2 self = req.CreateSelfSigned(DateTime.Now, DateTime.Now.AddYears(1));
X509Certificate2 cert = new(self.RawDataMemory.Span);
self.Dispose();

SignedCms cms = new(new ContentInfo([1, 2, 3]));
CmsSigner signer = new(cert);
cms.ComputeSignature(signer);

We should probably fail earlier in SignedCms saying "The loaded certificate does not have a private key".

@vcsjones
Copy link
Member

vcsjones commented Apr 4, 2024

This appears to be a regression with RSABCrypt introduced in .NET 8. It does not handle "this key is not a private key". Smaller repro:

using System.Security.Cryptography;

using RSA rsa = RSA.Create(2048);
using RSA pub = RSA.Create();
pub.ImportParameters(rsa.ExportParameters(false));
pub.SignData("hi"u8, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

On non-Windows this will correctly tell you "I do not have a private key for this". On Windows, this will give an Unknown error.

edoardo-kolver added a commit to edoardo-kolver/docs.microsoft.com-nuget that referenced this issue Apr 4, 2024
The documentation says to export the certificate, but this introduces errors when the certificate is stored in a hardware token. You just need to specify the certificate fingerprint, no need to export. See issue dotnet/runtime#100414
@edoardo-kolver
Copy link
Author

Thank you @vcsjones I confirm that it works with the hardware token when specifying --certificate-fingerprint instead of specifying a certificate path. I was following this documentation https://learn.microsoft.com/en-us/nuget/create-packages/sign-a-package and got thrown off by the "export a certificate" instructions. I made a PR to clarify the documentation. Would still be nice to get a fix for the error message on windows.

@vcsjones vcsjones self-assigned this Apr 4, 2024
@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label Apr 5, 2024
@vcsjones vcsjones added this to the 9.0.0 milestone Apr 5, 2024
@github-actions github-actions bot locked and limited conversation to collaborators May 6, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants