Windows Server 2016/2019 incorrectly return Authenticode signature on Owin.dll - windows

Owin.dll, the assembly inside the Owin package on Nuget.org, does not have an Authenticode signature. However, on Windows Server 2016 and Windows Server 2019, Get-AuthenticodeSignature (and sigcheck.exe) incorrectly report that Owin.dll does have an Authenticode signature.
If you deploy a Windows Server VM and run this code, it will return different signing and timestamping certificates (I only did this in Azure):
> [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
> Invoke-WebRequest "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -OutFile NuGet.exe
> .\NuGet.exe install owin -o .
> Get-AuthenticodeSignature .\Owin.1.0\lib\net40\Owin.dll | Format-List
On Windows Server 2019, it returns a SignerCertificate with Thumbprint AE9C1AE54763822EEC42474983D8B635116C8452 and TimestamperCertificate Thumbprint 893ED0E4D032C3855D5D2296B2DE2DD1AFB897DD.
On Windows Server 2016, it returns a SignerCertificate with Thumbprint E85459B23C232DB3CB94C7A56D47678F58E8E51E and TimestamperCertificate Thumbprint CFC3E3018EA65666DCE484FC7016EB42D1F108A9.
Other certificate metadata indicates that these are, in fact, certificates from Microsoft.
What's going on here? Why does this specific assembly behave this way in these specific versions of Windows?

Whilst the signature isn't part of the Owin.dll itself, Windows Server has a "Security Catalog" (under %SystemRoot%\System32\CatRoot) which identifies Owin.dll by name/hash. The security catalog is signed by Microsoft, and it's the signing certificate of the security catalog that's being returned by Get-AuthenticodeSignature. In effect it's simply a "detached" Authenticode signature, rather than being embedded in the .dll.

Related

Why does signtool.exe only find certificate when run as admin?

I'm setting up a new development laptop, and have installed a self-issued code signing certificate. I can see it in certmgr under my Current Users's Personal Certificates.
When I try to build from the Developer Command Prompt For Visual Studio 2017 I get:
error : SignTool Error: No certificates were found that met all the given criteria.
This always worked fine on my old laptop.
I have found if I run the same build from the command prompt after starting it as admin that signtool succeeds and can find the cert.
This has happened to 3/4 colleagues when we've set up new laptops. One guy is ok and can sign without running as admin. On our old laptops we never had to run as admin.
I've tried googling to find what could be the cause because I wasn't aware that running as admin or not should have any affect over this. I haven't found any reference to this problem.
How can we use signtool.exe without running it as admin?
When not running as admin it appears to be at the Private Key filter step where the cert I'm expecting to be selected gets filtered out:
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.9.12
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
C:\>signtool sign /v /debug /ph /i "<issuedby>" /fd sha256 /td sha256 "C:\TestSign.dll"
The following certificates were considered:
Issued to: Scott Langham
Issued by: <issuedby>
Expires: Sun Sep 25 09:54:55 2022
SHA1 hash: <a_hash>
Issued to: Scott Langham
Issued by: <issuedby_somethingelse>
Expires: Wed May 13 15:51:14 2020
SHA1 hash: <b_hash>
After EKU filter, 1 certs were left.
After expiry filter, 1 certs were left.
After Issuer Name filter, 1 certs were left.
After Private Key filter, 0 certs were left.
SignTool Error: No certificates were found that met all the given criteria.
I've ensured the version of signtool.exe I'm using is the same as the one that my colleague who has this working is using (10.0.18362.1). I've been able to spot any other differences between our systems.
I ran into this today and here is how I am now able to run signtool.exe via command line without elevating to admin.
Run 'mmc' and add the 'Certificates' snap-in
Select the correct key store location
(mine is in Local Computer so I select 'Computer account' here)
Find and select the certificate
Right click on the certificate, select All Tasks > Manage Private Keys...
In the 'Permissions for private keys' dialog, Add your user account and then give yourself 'Full Control'. You will now be able to sign using a normal command prompt.
Note: If you use a build machine, do the above steps for the account that performs the builds.
Similar to what #Baget said, I'd compare the certificates on your machine to that of your colleague who can successfully run the SignTool.exe command without the elevation token. Here's a chunk of PowerShell to assist you:
get-childitem -Path Cert:\ | foreach-object ({
$location = $_.Location
foreach($store in $_.StoreNames.Keys) {
get-childitem -Path "Cert:\$location\$store" | foreach-object ({
$thumb = $($_.ThumbPrint)
$issuer = $($_.Issuer)
if ($issuer -eq "CN=EXAMPLE, DC=EXAMPLE, DC=EXAMPLE, DC=EXAMPLE") {
write-host "$location $store $issuer"
}
})
}
})
Bear in mind that the output of the above may differ slightly if you run as a normal user and 'run as admin'.
Finally, do you and your colleague have the same UAC settings?
I found myself in a similar situation with signtool, it refused to work with an admin user but does work as actual Administrator.
In my case, I am not actually importing the certificate into the certificate store, but using a .pkcs12 file exported from a comodo certificate in firefox, so this makes things even stranger, as no permissions on any keys in the store are involved.
I tried granting myself permissions on some server key, but that did nothing.
I hope someone finds a solution to this problem.
In the meantime, I am signing my exe with osslsigncode instead, which works perfectly.
I extracted the exe and dependent dlls from the msys2 mingw64 build, here is a zip of everything in case it is of use to anyone, just extract it to a directory and put it in your PATH.
http://cachemiss.com/files/osslsigncode.zip
To extract this program yourself from an msys2 installation, you can use this command:
pacman --noconfirm -S mingw-w64-x86_64-osslsigncode
cd /mingw64/bin
mkdir ~/osslsigncode
cp osslsigncode.exe $(ldd osslsigncode.exe | sed -n 's,^.*\(/mingw64/[^ ]*\).*,\1,p' | sort -u) ~/osslsigncode/
cd
zip -9r osslsigncode.zip osslsigncode
I am using this in Visual Studio cmake builds with no issue.
There are two Certificate Store in Windows, User Store, and a machine store, you probably installed the certificate to the local machine, or you installed it when you run as elevated user.
Firstly you are getting such an error and you are using visual studio then See the signing tab in project properties. You will see a previously assigned signature (strong assembly)
If you enter the correct password here:
If your environment is the same as the environment in which the project is written, you will skip this error. Look the post on about the error
The reasons behind this error are:
1- Visual Studio needs some features when using certificate file to sign strong assembly.
ClickOnce Manifest Signing and Strong-Name Assembly Signing Using Visual Studio Project Designer's Signing Page
You can try this code to determine
signtool sign /debug /f mypfxfile.pfx /p <password> (mydllexectuable).exe
2- These settings can vary from machine to machine, and windows does not write these settings to the environment setting by default. check the config path
This part is just a deep note! not interested with the question you should add your private keystore file to request header and those all for this. My favorite steps about the creation of a certificate on this post

Getting An error occurred while signing: Failed to sign file.exe. SignTool Error: No certificates were found that met all the given criteria

OK - so this is really odd. I have a TFS build that signs a file and I'm getting the message above. If I look at the log from the build it says that it successfully signed and timestamped my file, (there's a .proj file that manually calls signtool) but below that in a different step (not sure where exactly) - I assume that its in the ClickOnce signing I get the error.
I'm able to sign the file myself using Signtool using the same parameters as the build uses so I thought perhaps I needed to import he cert, so I opened mmc, added the certificates snap-in, went through the Import Wizard using Local Machine to install it (the TFS build runs under a different account than mine and I don't know the password for that account so I figured that installing it at a machine level would work). I browsed for the file and imported it successfully in the Trusted Root Certification Authorities (see below):
and still I get the error when I build. The signtool is called from a .proj file called in the TFS build, but then again by the build during ClickOnce. After importing the cert through the VS screen I now see this:
And get this error:
C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Common.CurrentVersion.targets (2718): Unable to find code signing certificate in the current user’s Windows certificate store. To correct this, either disable signing of the ClickOnce manifest or install the certificate into the certificate store.
C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Common.CurrentVersion.targets (2718): Cannot import the following key file: . The key file may be password protected. To correct this, try to import the certificate again or import the certificate manually into the current user’s personal certificate store.
C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Common.CurrentVersion.targets (2718): Importing key file "les.pfx" was canceled.
The cert is in the same folder as the .csproj as well as being imported into the store.
Here's the cert info and the Thumbprint matches what's in the .csproj file:
Any ideas what I could be missing here?
According to the error message, you have to import the certificate into agent machine's personal store. When you reference the certificate from the personal store, it will not ask for the password, and thus you can access your code signing certificate.
If multiple projects being built with ClickOnce, then you have to import the certificate into each of the projects.
Please try to use the Visual Studio Command Prompt to import the certificate in your build agent machine:
Click Start → All Programs → Microsoft Visual Studio → Visual Studio
Tools → Visual Studio Command Prompt.
Type the following command sample:
sn -i "c:\Pathtofile\.pfx" VS_KEY_C1D3ACB8FBF1AGK4
Note: The sn.exe with the -i parameter, installs a key pair from into a key container named.
Re-import the pfx file into Visual Studio.
You can also try to create a PowerShell script and run pre-build scripts in your build definition to import the certificate.
The PowerShell script sample for your reference:
$pfxpath = 'pathtoees.pfx'
$password = 'password'
Add-Type -AssemblyName System.Security
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($pfxpath, $password, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"PersistKeySet")
$store = new-object system.security.cryptography.X509Certificates.X509Store -argumentlist "MY", CurrentUser
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]"ReadWrite")
$store.Add($cert)
$store.Close()
Reference these threads:
Visual studio team services deploymen/buildt certificate error
Cannot import the keyfile 'blah.pfx' - error 'The keyfile may be password protected'
Build and Publish a ClickOnce App using Team Build/VSO. (The last section about using a certificate from store)

Extend certificate expired date for windows app

How to extend the expiry date of windows app certificate? We're side loading the app/ The main obstacle is the certificate expires every year which is a bothersome to renew it through GP cause we already have issues in our environment. We would like to extend it for at least 5 years.
I have managed to find technet articles on how to create a code signing certificate but it didnt work. Visual studio doesnt accept the certificate and gives an error message that it is corrupted or invalid.
https://learn.microsoft.com/en-us/windows/uwp/packaging/create-certificate-package-signing#create-a-self-signed-certificate
https://technet.microsoft.com/itpro/powershell/windows/pki/new-selfsignedcertificate
Is there any way to do it easily?
You could do something like this, the subject must be same as UWP app's Publisher (package.appxmanifest):
New-SelfSignedCertificate -Type Custom -Subject "CN=Something" -TextExtension #("2.5.29.37={critical}{text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") -KeyUsage DigitalSignature -FriendlyName "Friendly Name" -CertStoreLocation "Cert:\LocalMachine\My" -NotBefore (Get-Date) -NotAfter (Get-Date).AddYears(5)
Now export to .pfx and add the thumbprint to the PackageCertificateThumbprint
The process is described in Microsoft documentation, but it is convoluted. There is no "visual" part as "Visual Studio" would suggest.
To sideload an application, it is sufficient to create a self-signed certificate, which means that you trust yourself. There is no trust from a CA (certification authority) involved.
These steps worked for me. The whole process being in PowerShell run as administrator.
Create the certificate
New-SelfSignedCertificate -Type Custom -Subject "CN=Company Name, O=Company Name Inc., C=CA" -KeyUsage DigitalSignature -FriendlyName "Programming certificate, 50 years" -CertStoreLocation "Cert:\CurrentUser\My" -TextExtension #("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") -NotBefore (Get-Date) -NotAfter (Get-Date).AddYears(50)
The -Subject item may contain only the CN= part, I believe the other bits are optional. O= seems to refer to the organization and C= the country code.
The -CertStoreLocation and -TextExtension are correct as written (see the documentation). I am not too familiar with what -CertStoreLocation really means, as I was not able to find it later, but that is what Microsoft suggests and remains irrelevant to the process.
The (Get-Date) bits get the current date, and .AddYears(50) would be modified to how many years the certificate should last.
The output will display the thumbprint; copy it.
Export the certificate
Set a password variable (confusingly, the password here is written without quotes).
$password = ConvertTo-SecureString -String CustomPasswordYouWouldChoose -Force -AsPlainText
Export the certificate; paste the thumbprint in the "Cert:\CurrentUser\My..." string and choose a file path (in my case, using the C:\ drive worked fine).
Export-PfxCertificate -cert "Cert:\CurrentUser\My\YOURTHUMBPRINTHERE" -FilePath C:\ProgrammingCertificate.pfx -Password $password
Add the certificate in Visual Studio
Go to Package.appxmanifest > Packaging > Choose Certificate... > Select from file... > then select your exported certificate.
Install the certificate on sideload deployment
Double-click the certificate file > Install Certificate... > Local Machine > Place all certificates in the following store > Browse > Trusted People > accept all and the import should be successful. Congratulations, the application is now certified by yourself.

MSB3481 Certificate Error

I have a build server on window 2008 R2. I am running CruiseControl.net using msbuil 3.5. I know for a fact that the certificate is installed and the thumbprint is correct. I did look into this SO question MSBuild SignFile task returning MSB3481: The signing certificate could not be located and tried that solution but didn't work. From the msbuild script the error is thrown on the code line below. I am not sure if there is anything specific to window 2008 R2.
<SignFile CertificateThumbprint="$(CertThumbprint)"
SigningTarget="#(%(ManifestItems.DeployManifestOutput))"/>
Found out during the install for the original pfx certificate file on window 2008 R2, one of the values default to prompt for password. In my scenario the original pfx certificate file doesn't have a password but windows still prompt for a password entry. During the MSBuild execution on the build server the password prompt, which causes it to hang since no response to the prompt is made.
A few ways to go about this is to supply an empty password through the assembly manifest in MSBuild script or during the pfx certificate install to opt out to prompt for password.

How to make and deploy a self-signed ClickOnce manifest with Visual Studio 2012

Let's get this out of the way... I :
use Visual Studio 2012
develop VB.NET applications - mostly .NET framework 3.5, some 2.0.
use Windows 7 for development (users are also using Windows 7. There are a small number of internal users (less than 40).
I am also going to state that I am new at this and don't fully understand this process. I do understand the underlying concepts of encryption/hashing/keys etc., but I can't tell you why you might need a .cer file and not a .pfx file.
Now then...
We have an application that uses a certificate to sign its manifest that has worked for three (or so) years. We recently upgraded from Visual Studio 2008 to Visual Studio 2012, having basically skipped Visual Studio 2010. Somewhere in that process the certificate is now invalid or corrupted.
The proposed solution: Make a new one with makecert.exe "just like we did last time". No sense paying for a certificate when all we need it for is our own small set of users and the small convenience of not seeing that "do you trust this publisher?" message (I think?).
When trying to publish, the exact error is:
Cannot publish because a project failed to build.
An error occurred while signing: Failed to sign
bin\Release\app.publish\setup.exe. SignTool Error: The signer's
certificate is not valid for signing. SignTool Error: An error
occurred while attempting to sign: bin\Release\app.publish\setup.exe
Now, the article Support Certificates In Your Applications With The .NET Framework 2.0 says:
for desktop applications, you typically install certificates in the
user store.
So when I look at the user store (via MMC with certificate snap-in) I see:
Where the red line is is the OLD/INVALID certificate. One other one is still unexpired, with my username on it (2013-06-20).
When I go to select from the store, I see this:
And in case you are curious, the other intuitive place to put one of these looks like this:
So how do I add another one where the old/bad one is?
Here is what I have tried:
Following these instructions, I executed
makecert -n "CN=TempCA" -r -sv TempCA.pvk TempCA.cer
Now I have a .pvk file, and a .cer file. Then I followed the instructions in Pvk2Pfx (Windows Drivers) and ran
pvk2pfx.exe -pvk TempCA.pvk -spc TempCA.cer -pfx TempCA.pfx
Now I have a .pfx file... (is this what I need?), but when trying to import to the certificate store using MMC, the password I used is supposedly wrong no matter what - even if I copy and paste it in. (It sounds like a bug in the import program... I can reproduce this.)
Trying another route, after importing the .cer file, it will not show up in the "select from store" window in Visual Studio, so that's useless.
I've spent a day on this and am ready to give up, but I can't. What do I need to do?
The article Using Makecert to Create Certificates for Development helped about 90% of the way...
The rest was understanding that I could do one of two things (both of these options require the certificate must be in a "trusted root" area like "Trusted Root Certification Authority", or must be signed by one that is there):
In Visual Studio, under the "signing" tab I could just use "Select from file" and use the .cer file.
If I just put my .cer file in the "personal" folder, it will appear as an option from the "select from store" button (I may need to restart the computer or Visual Studio).
The answer by Watki02 is quite helpful but missing a few details. Also, key information in that blog post should also be posted here. So...
Create your own root authority certificate:
CD \path\to\whereyouwant
makecert -n "CN=Make Up A Name" -a sha1 -r -sv MakeUpANameCertificateAuthority.pvk MakeUpANameCertificateAuthority.cer -ss MakeUpANameCertificateAuthority -sr localMachine
Password prompts
You will be prompted to create a password and then submit a password. I used the same password for both prompts
User certificate
makecert -pe -n "CN=CN=Make Up A Name User" -ss MY -a sha1 -iv MakeUpANameCertificateAuthority.pvk -ic MakeUpANameCertificateAuthority.cer -sv MakeUpAName.pvk MakeUpAName.cer
Password prompts again
I used the same password as above again
Make a portable file for exchange
pvk2pfx -pvk "MakeUpAName.pvk" -spc "MakeUpAName.cer" -pfx "MakeUpAName.pfx" -pi SamePasswordAgain
Send the file to your private clients
"MakeUpAName.pfx"
Install the certificate
c:> MMC.EXE
MENU FILE -> Add / Remove Snapin
Certificates -> Add -> Computer Account -> Finish -> OK
MENU Action->All Tasks->Import
Go through the wizard
Choose *.pfx format
Choose file
Continue with default options

Resources