Relevant area(s)
WinGet CLI
Description of the new feature / enhancement
TL;DR
Aid developers by optionally adding a certificate from MSIX package signing that's not currently recognized by the system IF the user has admin privilege and the machine has Developer Mode enabled.
Background / Business Justification
Signed MSIX packages require the signing certificate be installed in the system's certificate store (or chain to a certificate that is) or it can't be installed (MSIX Deployment fails the install). Windows includes certificates for Windows or Store; other certificates can be added to Windows, but requires an awkward manual set of manual steps, or code. Any MSIX package signed with valid certificates not in the certificate store cause winget installation of the signed package to fail.
This is a point of friction oft repeated by developers, making local development and testing more painful than it can (or should) be.
Adding the certificate from a signed package to the system's certificate store requires admin privilege (as do all operations altering the system's certificate store), but developers routinely have admin privilege. Making it easy for developers to install certificates from signed MSIX packages doesn't enable developers to things they can't already do (developers already can routinely pwn the box in far more harmful ways).
"Self-Signed Certificate" is a Misnomer
NOTE: These packages are sometimes referred to as being signed with "self-signed certificates". That's a misnomer. It doesn't matter if you or I or Verisign or Azure Artifact Services or whoever created the certificate, or who used it to sign an MSIX package. All that matters is the certificate signing information in a signed MSIX package doesn't match a certificate known to Windows (i.e. not in the system's certificate store, or chained to one that is).
Description of the new feature/enhancement
When winget installs a signed MSIX package AND the machine has Developer Mode enabled, check if the the certificate is already installed in the certificate store and, if not, add it.
This requires multiple potential hurdles:
- System has Developer Mode enabled (aka DevUnlocked)
- WinGet is running Elevated (IntegrityLevel>=High)
a. NOTE: If not running Elevated, WinGet could throw a UAC prompt for user confirmation and (if yes) (re)run the command from an Elevated process. At a minimum, current WinGet practices regarding Elevation should apply. TBD if more is that's appropos.
- ...a configuration option is enabled
a. Command line option to explicitly allow: winget install Contoso.AwesomeMsixPackagedStuff --msix-add-signed-package-certificate-if-necessary
b. Command line option to explicitly block: winget install Contoso.AwesomeMsixPackagedStuff --msix-add-signed-package-certificate-if-necessary=block
c. Persisted configuration setting to allow or block
d. Built-in default (ie if not specified or configured) = Block (the current and safe result)
- ...management policy allows it / doesn't block it
a. Per winget's usual admin management policies e.g. allow if policy not set or explicitly enabled; block if explicitly denied
All conditions must be met or the signed MSIX package's certificate is not added to the system.
Proposed technical implementation details (optional)
See AddCertificate() for examples how to add a signed MSIX package's certificate to the system.
AddCertificate()'s large doc-comment explains the manual steps to accomplish same.
The equivalent powershell script
$msix = "C:\Path\Contoso-Awesome-Stuff.msix"
$signature = Get-AuthenticodeSignature -FilePath $msix
$certificate = $signature.SignerCertificate
if (-not $certificate) {
throw "The MSIX does not contain a signer certificate."
}
# Verify this value before trusting it.
$certificate.Thumbprint
$store = [System.Security.Cryptography.X509Certificates.X509Store]::new("TrustedPeople", "LocalMachine")
try {
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$store.Add($certificate)
}
finally {
$store.Close()
}
Considerations for Additional Hardening
MSIX packages require their certificate's SUBJECT matches the package's Publisher (xpath=/Package/Identity[@Publisher]). WinGet can verify the certificate's SUBJECT field matches the package's Publisher (IAppxPackageReader->GetManifest()->GetPackageId()->GetPublisher()). WinGet should refuse to add certificates from signed MSIX packages if their SUBJECT doesn't match the package's Publisher.
Other notes
This proposal differs from Proposal: Allow code self-signed certificates with user approve #424. That proposal targets end / all users. This proposal only targets developers.
Proposed technical implementation details
No response
Relevant area(s)
WinGet CLI
Description of the new feature / enhancement
TL;DR
Aid developers by optionally adding a certificate from MSIX package signing that's not currently recognized by the system IF the user has admin privilege and the machine has Developer Mode enabled.
Background / Business Justification
Signed MSIX packages require the signing certificate be installed in the system's certificate store (or chain to a certificate that is) or it can't be installed (MSIX Deployment fails the install). Windows includes certificates for Windows or Store; other certificates can be added to Windows, but requires an awkward manual set of manual steps, or code. Any MSIX package signed with valid certificates not in the certificate store cause winget installation of the signed package to fail.
This is a point of friction oft repeated by developers, making local development and testing more painful than it can (or should) be.
Adding the certificate from a signed package to the system's certificate store requires admin privilege (as do all operations altering the system's certificate store), but developers routinely have admin privilege. Making it easy for developers to install certificates from signed MSIX packages doesn't enable developers to things they can't already do (developers already can routinely pwn the box in far more harmful ways).
"Self-Signed Certificate" is a Misnomer
NOTE: These packages are sometimes referred to as being signed with "self-signed certificates". That's a misnomer. It doesn't matter if you or I or Verisign or Azure Artifact Services or whoever created the certificate, or who used it to sign an MSIX package. All that matters is the certificate signing information in a signed MSIX package doesn't match a certificate known to Windows (i.e. not in the system's certificate store, or chained to one that is).
Description of the new feature/enhancement
When winget installs a signed MSIX package AND the machine has Developer Mode enabled, check if the the certificate is already installed in the certificate store and, if not, add it.
This requires multiple potential hurdles:
a. NOTE: If not running Elevated, WinGet could throw a UAC prompt for user confirmation and (if yes) (re)run the command from an Elevated process. At a minimum, current WinGet practices regarding Elevation should apply. TBD if more is that's appropos.
a. Command line option to explicitly allow:
winget install Contoso.AwesomeMsixPackagedStuff --msix-add-signed-package-certificate-if-necessaryb. Command line option to explicitly block:
winget install Contoso.AwesomeMsixPackagedStuff --msix-add-signed-package-certificate-if-necessary=blockc. Persisted configuration setting to allow or block
d. Built-in default (ie if not specified or configured) = Block (the current and safe result)
a. Per winget's usual admin management policies e.g. allow if policy not set or explicitly enabled; block if explicitly denied
All conditions must be met or the signed MSIX package's certificate is not added to the system.
Proposed technical implementation details (optional)
See AddCertificate() for examples how to add a signed MSIX package's certificate to the system.
AddCertificate()'s large doc-comment explains the manual steps to accomplish same.
The equivalent powershell script
Considerations for Additional Hardening
MSIX packages require their certificate's SUBJECT matches the package's Publisher (xpath=
/Package/Identity[@Publisher]). WinGet can verify the certificate's SUBJECT field matches the package's Publisher (IAppxPackageReader->GetManifest()->GetPackageId()->GetPublisher()). WinGet should refuse to add certificates from signed MSIX packages if their SUBJECT doesn't match the package's Publisher.Other notes
This proposal differs from Proposal: Allow code self-signed certificates with user approve #424. That proposal targets end / all users. This proposal only targets developers.
Proposed technical implementation details
No response