dotnet / sign

Code Signing CLI tool supporting Authenticode, NuGet, VSIX, and ClickOnce
MIT License
448 stars 84 forks source link

Error signing clickonce with Trusted Signing #735

Open JaapMosselman opened 2 days ago

JaapMosselman commented 2 days ago

``I am trying to use the new Trusted Signing option of dotnet sign which @dlemstra added. I am able to sign a msi, works fine, but have problems with clickonce.

I use this powershell in my devops pipeline: .\sign code trusted-signing "$applicationFile" --base-directory "$applicationDir" --application-name "...." --publisher-name "...." --trusted-signing-endpoint "...." --trusted-signing-account "...." --trusted-signing-certificate-profile "...." --managed-identity-client-id "...."

I get this error: fail: Sign.Core.ISigner[0] Specified method is not supported. System.ApplicationException: Specified method is not supported. ---> System.NotSupportedException: Specified method is not supported. at System.Deployment.Internal.CodeSigning.SignedCmiManifest2.AuthenticodeSignLicenseDom(XmlDocument licenseDom, CmiManifestSigner2 signer, String timeStampUrl, Boolean disallowMansignTimestampFallback) in /_/src/Sign.Core/Native/mansign2.cs:line 676 at System.Deployment.Internal.CodeSigning.SignedCmiManifest2.Sign(CmiManifestSigner2 signer, String timeStampUrl, Boolean disallowMansignTimestampFallback) in /_/src/Sign.Core/Native/mansign2.cs:line 357 at Sign.Core.ManifestSigner.Sign(FileInfo file, X509Certificate2 certificate, RSA rsaPrivateKey, SignOptions options) in /_/src/Sign.Core/DataFormatSigners/ManifestSigner.cs:line 42 --- End of inner exception stack trace --- at Sign.Core.ManifestSigner.Sign(FileInfo file, X509Certificate2 certificate, RSA rsaPrivateKey, SignOptions options) in /_/src/Sign.Core/DataFormatSigners/ManifestSigner.cs:line 52 at Sign.Core.ClickOnceSigner.SignCoreAsync(String args, FileInfo file, RSA rsaPrivateKey, X509Certificate2 certificate, SignOptions options) in /_/src/Sign.Core/DataFormatSigners/ClickOnceSigner.cs:line 220 at Sign.Core.RetryingSigner.SignAsync(String args, FileInfo file, RSA rsaPrivateKey, X509Certificate2 publicCertificate, SignOptions options) in /_/src/Sign.Core/DataFormatSigners/RetryingSigner.cs:line 40 at Sign.Core.ClickOnceSigner.<>c__DisplayClass9_0.<<SignAsync>b__0>d.MoveNext() in /_/src/Sign.Core/DataFormatSigners/ClickOnceSigner.cs:line 134 --- End of stack trace from previous location --- at System.Threading.Tasks.Parallel.<>c__531.<b530>d.MoveNext() --- End of stack trace from previous location --- at Sign.Core.ClickOnceSigner.SignAsync(IEnumerable`1 files, SignOptions options) in //src/Sign.Core/DataFormatSigners/ClickOnceSigner.cs:line 82 at Sign.Core.AggregatingSigner.SignAsync(IEnumerable`1 files, SignOptions options) in /_/src/Sign.Core/DataFormatSigners/AggregatingSigner.cs:line 204 at Sign.Core.Signer.<>c__DisplayClass3_0.<b0>d.MoveNext() in /_/src/Sign.Core/Signer.cs:line 155 --- End of stack trace from previous location --- at System.Threading.Tasks.Parallel.<>c53`1.<b530>d.MoveNext() --- End of stack trace from previous location --- at Sign.Core.Signer.SignAsync(IReadOnlyList`1 inputFiles, String outputFile, FileInfo fileList, DirectoryInfo baseDirectory, String applicationName, String publisherName, String description, Uri descriptionUrl, Uri timestampUrl, Int32 maxConcurrency, HashAlgorithmName fileHashAlgorithm, HashAlgorithmName timestampHashAlgorithm) in //src/Sign.Core/Signer.cs:line 84

`

Any hint what the problem is?

dlemstra commented 2 days ago

The issue seems to be here (mansign2.cs):

private static void AuthenticodeSignLicenseDom(XmlDocument licenseDom, CmiManifestSigner2 signer, string timeStampUrl, bool disallowMansignTimestampFallback)
{
    // Make sure it is RSA, as this is the only one Fusion will support.
    // HACK: do this in a better way
    RSA rsaPrivateKey = null;
    if (signer.Certificate.HasPrivateKey)
    {
        rsaPrivateKey = signer.Certificate.GetRSAPrivateKey();
    }
    else if (signer.StrongNameKey is RSAKeyVault provider)
    {
        rsaPrivateKey = provider;
    }

There seems to be an explicit check for RSAKeyVault and we could also add RSATrustedSigning but I really wonder if we can solve this differently? Maybe we could do this instead:

// Make sure it is RSA, as this is the only one Fusion will support.
RSA rsaPrivateKey = signer.Certificate.HasPrivateKey
    ? signer.Certificate.GetRSAPrivateKey()
    : signer.StrongNameKey as RSA;

if (rsaPrivateKey == null)
{
    throw new NotSupportedException();
}
JaapMosselman commented 1 day ago

Thanks, @dlemstra . I am eagerly waiting for the new prerelease :-).