Why do mage.exe need administrative privileges to access certificate, but signtool.exe do not - powershell

I'm making a CI build task in PowerShell to sign an assembly and the manifest with signtool and mage.
It works great, except that I have to run PowerShell as Administrator to get mage to accept the certificate. What I find really strange is that signtool can use the same certificate without privileges.
The certificate is a .pfx file.
Script:
signtool sign /f $certPath /p $certPassword /q /t $timestampUri "Example.dll"
mage -s "Example.dll.manifest" -CertFile $certPath -Password $certPassword -ti $timestampUri
Without privileges:
Done Adding Additional Store
Successfully signed and timestamped: Example.dll
Unable to open certificate "D:\example.pfx":
Access denied.
With privileges:
Done Adding Additional Store
Successfully signed and timestamped: Example.dll
Example.dll.manifest successfully signed
Does anyone know what is going on here?
Edit:
I used Procmon as adviced. Log below in CSV
Procmon logs

Related

Powershell: How to check the above statement is passed or failed inside if condition in powershell

I have a IF condition which check for a file avaialble in the path and does the action of signing the scripts.
But I am looking for another condition here like, after the signing process has done successfully or not also it should check.
If (Test-Path -Path "$env:DigiCertificate"){
signtool sign /f $env:DigiCertificate /fd SHA256 /p $env:DigicertsPassword $MediaFolderPath\scripts\*.ps1 $MediaFolderPath\tools\*.exe
}
Else {
Write-Host "##[warning]For Digitally signing of scripts, required certificate not found to sign" -ForegroundColor Yellow
exit 1
}
So, here I have a condition to check for the Certificate and fail if its not there, but I am looking for the signtool operation fails to sign the scripts also it should fail. Please help me to achieve this.

Digitally signing all identified powershell scripts in TFS Azure Devops

I am working on digitally signing of all powershell scripts in a folder from a repo in the TFS azure devops.
Using below command I can sign all the scripts under a specific folder:
signtool.exe sign /f MyCertificate.pfx /p Mypassword "C:\folder\repo\powershellscripts\*.ps1
So here I need to implement a logic in powershell script like if the MyCertificate.pfx is not found in the specified path the signing process should fail saying required certificate not found to sign.
I know the below code to check above executed code returns 0 success, 1 fail. But to check whether the certificate is present is the specified path or not I need help.
if (! $?) {
Write-Host "required certificate not found to sign" -ForegroundColor Red
exit
}
you do not specify a path for MyCertificate.pfx, so it must be present in the current workdirectory and so you can do
If (Test-Path .\MyCertificate.pfx){
signtool.exe sign /f MyCertificate.pfx /p Mypassword "C:\folder\repo\powershellscripts\*.ps1
}
Else {
write-error "required certificate not found to sign"
return #exit would cause to exit the process, what you probably not want to do
}

Using Powershell as terminal in IntelliJ IDEA IDEs like PyCharm, PHPStorm or RubyMine

I have been attempting to run powershell as my terminal on windows in pycharm, so I did the following:
However, when I try this, it says that it cannot execute my scripts, and hence I get the following error: SecurityError and the Fully Qualified Id is : UnAuthorizedAccess.
This arises from the fact that pycharm's terminal cannot execute my Powershell_profile.ps1 profile file.
How can I successfully run Pycharm's terminal with Powershell?
What I have tried so far, is going into my main powershell directory as in %windir%/system32/WindowsPowerShell/1.0/profile.ps1, and then change it to include the following:
Set-ExecutionPolicy Unrestricted
However, this does not help, and I get the same error when I try to open of pycharm's terminal.
I have also tried to run pycharm as Admin, however this does not solve the problem either, and I get the same aforementioned error.
I've replaced cmd.exe with powershell.exe in a simpler way and hope it can help.
I'm using webstorm2017 and Win10 os.
1.Find the exact location of powershell.exe.In mine and I believe in most computers the location would be C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe.Copy the whole path into your clipboard.
2.In your IDE open File=>Setting=>Tools=>Terminal, and paste the path into "Shell path" blank.
3.Restart the IDE and everything would be ok.
Set-ExecutionPolicy Unrestricted -Scope CurrentUser
I updated the powershell.exe path in IntelliJ -> Settings -> Terminal
Opened a powershell instance in Admin mode.
Executed Set-ExecutionPolicy Unrestricted -Scope CurrentUser
Restarted IntelliJ and the issue was solved.
Step 3 is from ebelanger's answer.
Browse to the PowerShell executable, right-click, run as administrator.
From the prompt, use the same command you tried:
Set-ExecutionPolicy Unrestricted
Once that is done, close PowerShell, and attempt to use it again from your application.
Note:
You can't set the execution policy from a script, as the default execution policy prevents you from running scripts. (even if it's the profile script - still a script)
In PyCharm
File->Settings->Tools->Terminal
Shell path:
"powershell.exe -ExecutionPolicy Bypass"
Then restart PyCharm
In the Default Shell TextBox you can append the execution policy command line option like so:
powershell.exe -Executionpolicy Unrestricted
If you're running on Windows 8 x64 then running both the commands below may help. It worked for me.
Set-ExecutionPolicy Unrestricted
start-job { Set-ExecutionPolicy Unrestricted -Force } -RunAs32
Credit to a comment found here:
Powershell on Windows 7: Set-ExecutionPolicy for regular users
As mentioned in other answers, if after setting powershell.exe as your terimal in IntelliJ → Settings → Tools → Terminal → Shell path it throws UnAuthorizedAccess errors, normal way to solve this is to alter execution policy:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
Note that Unrestricted level is the least secure of all, and you're usually can go with RemoteSigned in order to disable unsigned scripts downloaded from the web until you manually remove Internet or Intranet Zone.Identifier from them, usually with Unlock button in file properties.
However, you may run to an occasion when you're not able to change execution policy. Usually that's because of corporate security settings in Active Directory. In PowerShell, that corresponds to scopes MachinePolicy and UserPolicy. A primary symptom of this situation is the following message:
Set-ExecutionPolicy : Windows PowerShell updated your execution policy
successfully, but the setting is overridden by a policy defined at a
more specific scope. Due to the override, your shell will retain its
current effective execution policy of AllSigned. Type
"Get-ExecutionPolicy -List" to view your execution policy settings.
For more information please see "Get-Help Set-ExecutionPolicy".
You can't set execution policies at this scopes with PowerShell or gpedit.msc. Attempts to change this settings directly in registry is also ineffective: they're applied on restart or login, but at the same time they're being re-imported from Active Directory. However, while you won't be able to run arbitrary PowerShell scripts all around, for profiles and other local scripts that's only modified manually there's still a solution:
Run the following command in PowerShell to create ceritificate files root.pvk and root.cer - it will ask you to define and then confirm password to the certificate:
makecert -n "CN=PowerShell Local Certificate Root" -a sha1 -eku 1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer -ss Root -sr localMachine
In the same folder, run the following command to import generated certificate files as your self-signed certificate - it will ask for the password you're defined above:
makecert -pe -n "CN=PowerShell User" -ss MY -a sha1 -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk -ic root.cer
Sign your profile script with the following command:
Set-AuthenticodeSignature "[script path]" #(Get-ChildItem cert:\CurrentUser\My -codesign)[0]
When running a script signed with self-ceritificate for the first time, PowerShell will ask you about trusting the certificate like this:
The file [script path] is published by CN=PowerShell User. This publisher is not trusted on your system. Only run scripts from trusted publishers.
[V] Never run [D] Do not run [R] Run once [A] Always run [?] Help (default is "D")
Answer A to always run self-signed certificates.
Now your profile script won't cause any errors. However, note that signing a certificate adds a signature block in the end of your script containing its hash. If you're about to modify the script, remove that block and, after you're done with editing the script, sign it again by repeating step 3.
Specify the shell that will run by default. Here are some examples of different shells:
Bash: /bin/bash
Z shell: /bin/zsh
Bash for Windows: bash.exe
WSL: wsl.exe
PowerShell: powershell
Command Prompt: cmd.exe
Cygwin: "C:\cygwin\bin\bash.exe" --login -i
for more info: https://www.jetbrains.com/help/webstorm/settings-tools-terminal.html
As of this writing (2018-9-20), there is now a PowerShell plugin available here.
I have installed v1.1 in PyCharm v2018.2.3 (Professional), and it seems to work like a charm, no pun intended.
This plugin provides Intellisense-type support of PS1 scripts, as well as an integrated PowerShell terminal. In order to open the terminal, go to Tools > PowerShell Console...
There appears to be no need to muck about with any kinds of settings or permissions in order to get it to work. It Just Works.
You only need to write powershell in the Shell path input, just like in the image, also you can see jetBrains documentation and configure any shell you want.
powershell configuration
For WebStorm and PowerShell 6+ on Windows 10.
Just follow this screenshot and change the default cmd.exe to pwsh.exe from settings. Finally restart the ide. Done!

Signtool error The specificed PFX password is not correct

I have a new certificate from DigiCert .pfx file which when I try to use it for signing gives the error "The specified PFX password is not correct" However the password works fine when installing it locally. I have tried without specifying a password without success. The certificate was given to me buy another person who purchased it.
Thanks
I had the same issue but solved it by removing " from the password.
Before: signtool.exe sign /f mycert.pfx /p "password" /v /t http://... "application.exe"
After: signtool.exe sign /f mycert.pfx /p password /v /t http://... application.exe
I had the same issue as well when trying to sign dll files with post-build events in Visual Studio. I found out that the issue was having special characters like percentage sign (%) and comma (,) in the password. I fixed it after setting a new password without those special characters.
I hope this helps
Another possible issue is the encryption of the PFX could be unrecognized, for example a newer SHA256 encrypted cert cannot be used to sign on older SDK's
See related SO answers:
signtool - the specified PFX password is not correct from new machine
and
Why I get "The specified PFX password is not correct" when trying to sign application with signtool?
I had the same issue in Azure Devops where I was using a Command Line task:
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x86\signtool.exe" sign /f "D:\Cert\CodeSigning.pfx" /p %_pwd123_% /d "" /du "" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 "D:\Build\Installer.msi"
This resulted in 'The specified PFX password is incorrect'.
But I was able to take the actual script command from the failed pipeline, copy it into a cmd prompt on the build machine and run it (without any changes) successfully.
I also tried creating a pipeline variable as I've seen others do and use that in the command like $(pfxPwd). That also seemed to translate perfectly when run but still failed.
The solution was to use the pipeline variable but include it in the command like this instead: %pfxPwd%
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x86\signtool.exe" sign /f "D:\Cert\CodeSigning.pfx" /p %pfxPwd% /d "" /du "" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 "D:\Build\Installer.msi"
Perhaps this trouble was caused by the password beginning and ending with %.
But since this certificate and password came from IT, there were no other options.
Note: I later discovered that if I change the variable type to 'secret' it no longer works.

Is it possible to sign a powershell script with a snk file?

I have made a small powershell script (ps1 file) for internal use only.
To make it a little easier to execute the powershell script, I want to sign it.
We have a snk-file that we use to sign assemblies that we give to our customers.
Is it possible to sign the script with the snk file?
The answer is no.
.cer files are X.509 Certificates
.pfx files are encrypted X.509 Certificates using a password-based symmetric key
.snk files only contain the RSA key (public/private or public only)
The Set-AuthenticodeSignature cmdlet have a param -Certificate that accept
[System.Security.Cryptography.X509Certificates.X509Certificate2]
then you need a certificate. You can read this answer on SuperUser for more info about sign a powershell script.