Support NuGet package signing using Azure Artifact Signing on Linux#10
Support NuGet package signing using Azure Artifact Signing on Linux#10Bradley Grainger (bgrainger) wants to merge 2 commits into
Conversation
Enable portable Artifact Signing responses to be consumed on Linux by accepting PEM/DER/base64/PKCS#7 signingCertificate payloads and selecting the actual signing cert from PKCS#7 signer info or an unambiguous leaf certificate bag. Make NuGet package signing produce verifiable packages by normalizing ZIP metadata, embedding CMS id-data content, and using the standard id-aa-timeStampToken timestamp attribute while preserving Authenticode timestamp behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add the NuGet author signed-attribute profile needed for publisher metadata: signing-time, commitment-type proof-of-origin, and signing-certificate-v2. Remote signing now obtains the signer certificate before hashing CMS signed attributes so the signing-certificate-v2 ESSCertIDv2 value is part of the signed payload. This makes Linux-generated NuGet signatures classify as Author signatures in NuGet tooling, which enables NuGetPackageExplorer to display the Publisher UI for packages signed through Azure Artifact Signing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
The second commit address this problem: NuGet Package Explorer was not showing "Publisher:" metadata as displayed in this screenshot. Previously, only the "Signature ✅" line was showing; now the other metadata (with a link to a Windows certificate dialog) appears. Reverse-engineered by pointing GPT-5.5 at the https://github.com/NuGetPackageExplorer/NuGetPackageExplorer source code.
AI Text BelowFollow-up: added NuGet author signed attributes required once packages are classified as publisher/author signatures. The final package signature now includes signing-time, id-smime-aa-ets-commitmentType with proofOfOrigin, and signing-certificate-v2/ESSCertIDv2. A redacted live Azure Artifact Signing run produced a package that |

Disclaimer
I understand none of this code; it was produced entirely by GitHub Copilot using GPT-5.5.
The point of this PR is to demonstrate that with these changes, psign-tool could produce a correctly-signed NuGet package using Azure Artifact Signing under Linux (Ubuntu 24.04 on WSL2). I'm opening this PR in case having this information is helpful for producing a new version of psign that has this support built-in; I'm not expecting this to be merged as-is (although it's fine if you do).
I am interested in getting this scenario working, and am willing to produce more targeted fixes (with AI) if required. (Note that I am a C# Windows developer not a Linux Rust developer.)
AI Generated Text Below
Summary
This makes the portable/Linux signing path work with Azure Artifact Signing responses and produce NuGet packages that
dotnet nuget verifyaccepts. It keeps the existing Authenticode timestamp behavior, while using the CMS timestamp attribute NuGet expects for package signatures.Before
A live Azure Artifact Signing response could not be consumed reliably on Linux:
signingCertificatefield was assumed to be a PEM/DER X.509 certificate. In practice it can be base64 text wrapping a PKCS#7 certificate bag, so bothportable sign-peandcode --mode portablefailed while parsing the returned certificate payload.SignerInfo, so choosing the first embedded certificate is not safe. The observed bag order could put a root/intermediate certificate before the short-lived leaf signing certificate, producing signatures attributed to the wrong certificate.NU3005because the central-directoryversion made by/ external attributes carried Unix file metadata.NU3000because the package.signature.p7sused detached CMS content. NuGet package signatures need theid-datacontent embedded.id-aa-timeStampToken(1.2.840.113549.1.9.16.2.14).Changes
psign-sip-digestthat accepts PEM, DER, base64-wrapped data, and PKCS#7 certificate bags.SignerInfowhen present, and for certificate-only bags select an unambiguous leaf/code-signing candidate instead of assuming certificate-set order.codecommand..signature.p7s.sign_pkcs7_id_datachoose detached vs attached CMS content per caller: NuGet uses attachedid-data, while App Installer/AuthentiCode-style companion signatures remain detached.id-aa-timeStampTokenfor NuGet package signatures, while preserving the Microsoft Authenticode timestamp OID for Authenticode paths.SignerInfocertificate bags, NuGet ZIP metadata normalization, and NuGet timestamp OID behavior.Testing
Automated:
Manual/live, with private Azure Artifact Signing configuration redacted and no service URLs included:
psign-toolon Linux from this branch.psign-tool code --mode portablewith Azure Artifact Signing and RFC3161 timestamping.dotnet nuget verify -v detailed; verification succeeded and NuGet recognized the timestamp.psign-tool portable verify-pe.