Sign multiple files with signtool.exe - windows

I have a digital cert bought from a third-party CA and I wanted to use it to sign software with a large number of library files/packages (.bpl). However, signing them one by one takes a lot of time and I am wondering is there any ways to allow me to use a shorter time to sign all the files?
The current command I am using to sign the files is as below:
signtool.exe sign /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /a "Insert_path_to_the_file_you_wish_to_sign"

I was signing multiple files using the signtool in a parallel loop. It seemed to work, but I noticed that our certificate provider (DigiCert) recommends that you avoid concurrent requests.
https://dev.digicert.com/best-practices/
So instead, I'm now using the signtool in one command - passing in all the files in one command line argument. According to Microsoft's documentation, you can use an '|' between each file.
signtool [command] [options] [file_name | ...]
https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe
And maybe useful for someone, Digicert's DigiCertUtil uses '*' between each file.
Filenames is a list of files to be code signed. To specify more then
one file, seperate each filename or file path with the asterisk
character *. Enclose the file path with quotes if it contains spaces.
example: DigiCertUtil.exe sign /kernelDriverSigning
"example.exedriver.sys" example: DigiCertUtil.exe sign /sha1
"054D9508B364A02A068FA5C6153847B6" "example.exedriver.sys"
Based on the recommendation to avoid concurrent requests, I'm assuming that even when specifying multiple files in either the SignTool or DigiCertUtil, the files will still be signed one at a time.

Related

SHA256 hash doesn't match download - what now?

Hello stackoverflow World,
I'm investigating using the miniconda package manager for the first time.
I downloaded the files from here: https://docs.conda.io/en/latest/miniconda.html
I'm on a windows machine so downloaded the following file:
As I am hoping is obvious from my title, the check sum that my machine produces using the Windows certUtil -hashfile function produces a different check sum.
Now, my main issue is what to do now...!
Do I run screaming to the hills burning all my IT kit as I go, or is there a way to get to the bottom of this?
Thanks in advance
So interestingly, using the PowerShell approach rather than the cmd line, as specified in the miniconda download reference did result in a matching Hash key.
I thought that these were supposed to be independent of the program used to unpack the HASH...?
hash is not a universally defined algorithm:
A hash function is any function that can be used to map data of arbitrary size to fixed-size values (https://en.wikipedia.org/wiki/Hash_function)
So when you use a program to hash a file and want to compare it to a published value, you must make sure that you are using the same hash function. In your case, the miniconda download page already clarifies that it is a SHA256 hash, which you need to specify when calling certutil.
Proof:
Without specifying the hash function (SHA1 is used and - as expected - produces a different hash value):
certutil -hashfile Miniconda3-latest-Windows-x86_64.exe
SHA1 hash of Miniconda3-latest-Windows-x86_64.exe:
0b553f6b77926db707c4406cafc612d74301b24e
CertUtil: -hashfile command completed successfully.
Specifying the correct function produces the right hash value:
certutil -hashfile Miniconda3-latest-Windows-x86_64.exe SHA256
SHA256 hash of Miniconda3-latest-Windows-x86_64.exe:
6013152b169c2c2d4bcd75bb03a1b8bf208b8545d69116a59351af695d9a0081
CertUtil: -hashfile command completed successfully.

Basic Usage of generate_appcast tool of Sparkle Updater

Since macOS 11.3 broke my Perl script which I have been using to generate Sparkle appcasts for the last 12 years, I decided to instead start using the generate_appcast tool which has since been provided with Sparkle. Invoking generate_appcast with no arguments, I get some brief documentation which I interpret to mean that I should provide two arguments:
a -f followed by the path to my Sparkle private key file
the path to a directory of several recent versions of my app, all zipped
So I created a new directory and copied zip archives of the three most recent versions of my app into it. Those are the .zip archives, notarized by Apple, which I upload to my site for users to download.
Then I ran this command:
Air2:~ jk$ generate_appcast -f /path/to/My_Sparkle_priv.pem /path/to/directory/of/zips
The result:
Warning: Private key not found in the Keychain (-25300). Please run the generate_keys tool
Error generating appcast from directory /path/to/My_Sparkle_priv.pem
Error Domain=NSCocoaErrorDomain Code=256 "The file “My_Sparkle_priv.pem” couldn’t be opened." UserInfo={NSUserStringVariant=(
Folder
), NSURL=file:///path/to/My_Sparkle_priv.pem/, NSFilePath=/path/to/My_Sparkle_priv.pem, NSUnderlyingError=0x13a637e10 {Error Domain=NSPOSIXErrorDomain Code=20 "Not a directory"}}
Apparently it is not recognizing the key file I provided, and also oddly implies that it expects a directory instead of a regular file. In the brief documentation, there is an example marked [DEPRECATED] which omits the -f before the path to the key file, so I tried that but got the same result. I also tried putting the path to the zips first, but that result was even worse.
My key file is, I think, a pretty standard .pem text file that begins with the line -----BEGIN DSA PRIVATE KEY----- followed by 1133 ASCII characters, etc.
Where did I miss the boat?
Astonishingly, this seems to be due to an obvious programming error in the Sparkle generate_appcast Swift source code. In attempting to remove elements indexed N and N+1 from an array of command-line arguments, the code removes element N, and then removes element N+1, which of course removes elements N and N+2 instead. After I fixed this programming error, the problem is solved.
After I do some more head-scratching and maybe consulting with others smarter than me, I shall submit a pull request or whatever to the Sparkle project next week.

How to extract a specific folder using IZARC (IZARCe)

I want to extract a specific directory form a huge zip file (>5GB) that is somewhat corrupted because of an inevitable bad maintained build system that creates the zip.
The tools such as winrar/7Zip GUI apps have no issues extracting the files, but some command line tools such as mks unzip and 7za fails to extract from the corrupted archive.
After a lot of digging around and trying out many such command line utilities I found out that IZARC successfully extracts files from the archive.
I am running the following command:
IZARCe.exe -e -d -o D:\aHugeZipFile.zip -pD:\temp #"source.txt"
The listing file source.txt contains just one entry:
source/lib/*
which is the only directory in the archive, from where the contents are to be extracted.
But, it is resulting in:
IZArc Command Line Extraction Add-On Version 1.1 (Build: 130)
Copyright(c) 2007 Ivan Zahariev, All Rights Reserved.
http://www.izarc.org contact#izarc.org
Archive File: aHugeZipFile.zip
WARNING: Nothing to do!
I have tried specifying:
/source/lib/*
source/lib/*
source/lib/
source/lib
*source/lib/*
in the listing file, all to no avail! :(
Any pointers on where the error is occurring, and how to fix the issue will be of great help. Thank you in advance!
Using relative or absolute paths for listfiles doesn't appear to work with IZArc. Try using wildcards such as ., *.doc, etc instead of paths in the listfile. Be aware that there appears to be a limitation for the folder depth that IZArc will extract to as well as a tendency to generate CRC errors when files with the same name are present in the same archive, even if they are in different directories.
I would suggest using 7-Zip command-line instead. It can recurse deeply through a file structure without error and can use relative directories and wildcards in its listfiles.
The following 7-Zip command was tested and worked perfectly.
7za x somearchive.zip -o"C:\Documents and Settings\me\desktop\temp_folder\test2" -ir#source.txt -aoa -scsWIN
the source.txt file may contain contain a combination of relative paths and/or wildcards on separate lines such as:
Output/, Folder2/, *, or *.doc.
In the command above: x (extract with full paths), -ir (include filenames, recurse subdirectories), -aoa (overide existing files without prompt), -scsWIN (set charset for list files). You may need to adjust these commands for your situation.

Getting the symbols with xperf

I read through the docs and used the commands outlined however for some reason I dont seem to be getting any symbols, just a series of "unknowns" in the function column of the summary table for everything except the topmost set of the app I was trying to debug.... I set the enviromental variable to the microsoft server and the direcories containg the pdb's for the app. I also made sure to select the "Load Symbols" item before bringing up the summary table.
Arcording to the info I was reading it should take some time for the tabl to display while it loads the symbols, however for me the table displayed almost instantly and only the top most items in sprite.exe->sprite.exe had function names, the othe rows for function were either blank or "unknown"
Im using Vista SP1.
This is the batch file I used. Did I do anything that would prevent the sybols being loaded?
REM start profiler
xperf -on PROC_THREAD+LOADER+INTERRUPT+DPC+PROFILE^
-stackwalk profile -minbuffers 16 -maxbuffers 1024 -flushtimer 0^
-f tmp.etl
REM run the app we want to profile
sprite.exe
REM stop
xperf -d profile.etl
REM set symbol path
set _NT_SYMBOL_PATH = ^
C:\Projects\C++\fl lib\bin;^ REM dlls
C:\Projects\C++\fl lib\samples\bin;^ REM main exe
SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
REM display profile
xperf profile.etl
What version of dbghelp.dll is it using? I've had trouble getting PDB symbols working with kernrate and other utilities when using the version of dbghelp.dll that is installed in %SystemRoot%\system32.
You may need to copy dbghelp.dll and symsrv.dll from a recent version of Debugging Tools for Windows into a directory where XPerf can find it.
Also, you need to remove the space before the '=', or else you're defining the "_NT_SYMBOL_PATH " variable (including the trailing space in the name).
Including comments at the end of a line is not going to work either. A line continuation character such as '^' typically needs to be the last character on the line. When I ran that statement (on XP), I ended up with "_NT_SYMBOL_PATH " equal to " C:\Projects\C++\fl lib\bin; REM dlls" and an error about the next line.
Try setting the
TRACE_FORMAT_SEARCH_PATH
environment variable. If that doesn't work, you may have to manually extract the TMF files from your PDBs using TracePdb.exe (or at least use a regular path instead of a SYM* path). This is by far the most annoying part of using ETL traces / XPerf

How do I add a multiline REG_SZ string to the registry from the command line?

As part of a build setup on a windows machine I need to add a registry entry and I'd like to do it from a simple batch file.
The entry is for a third party app so the format is fixed.
The entry takes the form of a REG_SZ string but needs to contain newlines ie. 0xOA characters as separators.
I've hit a few problems.
First attempt used regedit to load a generated .reg file. This failed as it did not seem to like either either long strings or strings with newlines. I discovered that export works fine import fails. I was able to test export as the third party app adds similar entries directly through the win32 api.
Second attempt used the command REG ADD but I can't find anyway to add the newline characters everything I try just ends up with a literal string being added.
You can import multiline REG_SZ strings containing carriage return (CR) and linefeed (LF) end-of-line (EOL) breaks into the registry using .reg files as long as you do not mind translating the text as UTF-16LE hexadecimal encoded data. To import a REG_SZ with this text:
1st Line
2nd Line
You might create a file called MULTILINETEXT.REG that contains this:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Environment]
"MULTILINETEXT"=hex(1):31,00,73,00,74,00,20,00,4c,00,69,00,6e,00,65,00,0d,00,0a,00,\
32,00,6e,00,64,00,20,00,4c,00,69,00,6e,00,65,00,0d,00,0a,00,\
00,00
To encode ASCII into UTF-16LE, simply add a null byte following each ASCII code value. REG_SZ values must terminate with a null character (,00,00) in UTF-16LE notation.
Import the registry change in the batch file REG.EXE IMPORT MULTILINETEXT.REG.
The example uses the Environment key because it is convenient, not because it is particularly useful to add such data to environment variables. One may use RegEdit to verify that the imported REG_SZ data contains the CRLF characters.
If you're not constrained to a scripting language, you can do it in C# with
Registry.CurrentUser.OpenSubKey(#"software\classes\something", true).SetValue("some key", "sometext\nothertext", RegistryValueKind.String);
You could create a VBScript(.vbs) file and just call it from a batch file, assuming you're doing other things in the batch other than this registry change. In vbscript you would be looking at something like:
set WSHShell = CreateObject("WScript.Shell")
WSHShell.RegWrite "HKEY_LOCAL_MACHINE\SOMEKEY", "value", "type"
You should be able to find the possible type values using Google.
Another approach -- that is much easier to read and maintain -- is to use a PowerShell script. Run PowerShell as Admin.
# SetLegalNotice_AsAdmin.ps1
# Define multi-line legal notice registry entry
Push-Location
Set-Location -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\
$contentCaption="Legal Notice"
$contentNotice= #"
This is a very long string that runs to many lines.
You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only.
By using this IS (which includes any device attached to this IS), you consent to the following conditions:
-The USG routinely intercepts and monitors communications on this IS for purposes including, but not limited to, penetration testing, COMSEC monitoring, network operations and defense, personnel misconduct (PM), law enforcement (LE), and counterintelligence (CI) investigations.
etc...
"#
# Caption
New-ItemProperty -Path . -Name legalnoticetext -PropertyType MultiString -Value $contentCaption -Force
# Notice
New-ItemProperty -Path . -Name legalnoticetext -PropertyType MultiString -Value $contentNotice -Force
Pop-Location

Resources