Jump to content

Recommended Posts

Posted

I want to sign the exe during/after the compilation of the script.

I want to use Microsoft signtool.exe from the SDK

I got my codesign certificate to my local computer and want to use this

So I did copy the thumbprint of the certificate to the code line, changed it here to 123454332example12343

#AutoIt3Wrapper_Run_After=c:\Windows\signtool.exe sign /sha1 123454332example12343 /tr http://timestamp.sectigo.com

I tried /t /tr both did not work, I tried it without the time option, nothing happens

Is it possible to see some errors of the signtool?

 

Posted

I used this ( https://www.autoitscript.com/forum/index.php?showtopic=149137&view=findpost&p=1316935 ) some years ago

Spoiler
On 7/6/2015 at 12:35 PM, argumentum said:

...as to save others from the implementation and/or learning curve, here is the batch files as a script.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#AutoIt3Wrapper_Res_Description=sign my EXEs
#AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <File.au3>

If Not StringInStr($CmdLineRaw, "/ErrorStdOut") And Not @Compiled Then Exit MsgBox(262144, @ScriptName, "...please run from editor.", 3)

Global $iCheckIni = 0
Global $ini = StringTrimRight(@ScriptFullPath, 3) & "ini"
Global $sCERTIFICATE_PASSWORD = "replace with unique password"
Global $sCN = "replace with unique CN"
If BinaryToString(IniRead($ini, "section", "CERTIFICATE_PASSWORD", $sCERTIFICATE_PASSWORD)) = $sCERTIFICATE_PASSWORD Then $iCheckIni = 1
If BinaryToString(IniRead($ini, "section", "CN", $sCN)) = $sCN Then $iCheckIni = 1

If $iCheckIni Then
    If FileExists(@ScriptDir & '\keys') Then DirMove(@ScriptDir & '\keys', @ScriptDir & '\keys_' & @YEAR & '.' & @MON & '.' & @MDAY & '-' & @HOUR & '' & @MIN & '' & @SEC)
    IniWrite($ini, "section", "CERTIFICATE_PASSWORD", $sCERTIFICATE_PASSWORD)
    IniWrite($ini, "section", "CN", $sCN)
    IniWrite($ini, "section", "UniqueSamplePasswordCreatedOn" & @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC, UniquePasswordGen())
    ShellExecute($ini)
    MsgBox(262144 + 64, @ScriptName, "edit the ini file" & @CR & 'and run again.', 10)
    Exit
EndIf

$sCERTIFICATE_PASSWORD = IniRead($ini, "section", "CERTIFICATE_PASSWORD", $sCERTIFICATE_PASSWORD)
$sCN = IniRead($ini, "section", "CN", $sCN)

If BinaryToString($sCERTIFICATE_PASSWORD) = $sCERTIFICATE_PASSWORD Then IniWrite($ini, "section", "CERTIFICATE_PASSWORD", StringToBinary($sCERTIFICATE_PASSWORD))
If BinaryToString($sCN) = $sCN Then IniWrite($ini, "section", "CN", StringToBinary($sCN))

$sCERTIFICATE_PASSWORD = BinaryToString($sCERTIFICATE_PASSWORD)
$sCN = BinaryToString($sCN)

$sCERTIFICATE_PASSWORD = BinaryToString(IniRead($ini, "section", "CERTIFICATE_PASSWORD", $sCERTIFICATE_PASSWORD))
$sCN = BinaryToString(IniRead($ini, "section", "CN", $sCN))

Global $WindowsDir = @WindowsDir
FileChangeDir(@ScriptDir)

If Not FileExists("makecert.exe") Then Exit MsgBox(262144, @ScriptName, 'can''t find "makecert.exe" , bye.', 30)
If Not FileExists("cert2spc.exe") Then Exit MsgBox(262144, @ScriptName, 'can''t find "cert2spc.exe" , bye.', 30)
If Not FileExists("pvk2pfx.exe") Then Exit MsgBox(262144, @ScriptName, 'can''t find "pvk2pfx.exe" , bye.', 30)
If Not FileExists("signtool.exe") Then Exit MsgBox(262144, @ScriptName, 'can''t find "signtool.exe" , bye.', 30)

Local $sFileToSign = StringTrimRight(@ScriptName, 3) & 'exe' ; should sign this exe
Local $iNoPopupMsgBox = 0
If StringInStr($CmdLineRaw, "/NoPopup") Then $iNoPopupMsgBox = 1
If @Compiled Then
    If $CmdLine[0] Then
        $sFileToSign = $CmdLine[1]
    Else
        FileChangeDir($WindowsDir)
        MsgBox(262144, @ScriptName, "...please, pass a file." & @CR & '"filename.exe" /NoPopup', 30)
        Exit
    EndIf
EndIf
$sFileToSign = _PathFull($sFileToSign)
If Not FileExists($sFileToSign) Then
    FileChangeDir($WindowsDir)
    Exit MsgBox(262144, @ScriptName, 'file "' & $sFileToSign & '" does not exist !', 60)
EndIf

If StringInStr($sFileToSign, " ") Then $sFileToSign = '"' & $sFileToSign & '"'

Global $sOut = ""
ConsoleWrite(@CRLF)
ConsoleWrite('+ CertSigner - FileToSign >' & $sFileToSign & '<' & @CRLF & @CRLF)
Local $sKEYDIR = @ScriptDir & "\keys"
DirCreate($sKEYDIR)
Local $sTIMESTAMP_URL = "http://timestamp.verisign.com/scripts/timestamp.dll"
If Not FileExists(@ScriptDir & '\keys\' & $sCN & '_cert.pvk') Then createTheCerts($sCERTIFICATE_PASSWORD, $sCN)
If FileExists(@ScriptDir & '\keys\' & $sCN & '_cert.pvk') Then signTheFile($sFileToSign, $sCERTIFICATE_PASSWORD)
Local $sRun = 'signtool verify /pa ' & $sFileToSign
$sOut &= $sRun & @CRLF & @CRLF
$sOut &= runCmd($sRun)
ConsoleWrite('+ CertSigner - done.' & @CRLF)
If $iNoPopupMsgBox Then
    ; nothing
Else
    MsgBox(262144, @ScriptName, "Signing of: " & $sFileToSign & @CR & _
            "=====================================================" & @CR & _
            StringReplace($sOut, @LF, ""))
EndIf
FileChangeDir($WindowsDir)

Func createTheCerts($sCERTIFICATE_PASSWORD, $sCN = "MyPersonalCert")
    Local $sRun = 'makecert -r -n "CN=' & $sCN & '" -b 01/01/1973 -e 01/01/2030 -eku 1.3.6.1.5.5.7.3.3 -sv keys\' & $sCN & '_cert.pvk keys\' & $sCN & '_cert.cer'
    $sOut &= $sRun & @CRLF & @CRLF
    Local $Pid = Run($sRun, @ScriptDir, @SW_HIDE, 8)
    Local $Handle = _ProcessExitCode($Pid)
    While ProcessExists($Pid)
        Sleep(10)
        $sOut &= ShowStdOutErr($Pid, 1, "", "", 1) ; the executable may show an error to console, I'd like to read it.
        If WinExists("Enter Private Key Password", "") Then
            ConsoleWrite(">Enter Private Key Password<" & @CRLF)
            ControlSend("Enter Private Key Password", "", "Edit1", $sCERTIFICATE_PASSWORD)
            Sleep(50)
            ControlClick("Enter Private Key Password", "", "Button1")
            Sleep(500)
        EndIf
        If WinExists("Create Private Key Password", "") Then
            ConsoleWrite(">Create Private Key Password<" & @CRLF)
            Sleep(50)
            ControlSend("Create Private Key Password", "", "Edit1", $sCERTIFICATE_PASSWORD)
            Sleep(50)
            ControlSend("Create Private Key Password", "", "Edit2", $sCERTIFICATE_PASSWORD)
            Sleep(50)
            ControlClick("Create Private Key Password", "", "Button1")
            Sleep(500)
        EndIf
    WEnd
    Local $ExitCode = _ProcessExitCode($Pid, $Handle)
    $sOut &= @CRLF & "ExitCode : " & $ExitCode & @CRLF & "=====================================================" & @CRLF

    $sRun = 'cert2spc keys\' & $sCN & '_cert.cer keys\' & $sCN & '_cert.spc'
    $sOut &= $sRun & @CRLF & @CRLF
    $sOut &= runCmd($sRun)

    $sRun = 'pvk2pfx -pvk keys\' & $sCN & '_cert.pvk -pi ' & $sCERTIFICATE_PASSWORD & ' -spc keys\' & $sCN & '_cert.spc -pfx keys\' & $sCN & '_cert.pfx -po ' & $sCERTIFICATE_PASSWORD
    $sOut &= $sRun & @CRLF & @CRLF
    $sOut &= runCmd($sRun)

EndFunc   ;==>createTheCerts

Func signTheFile($sFileToSign, $sCERTIFICATE_PASSWORD, $sTIMESTAMP_URL = "http://timestamp.verisign.com/scripts/timestamp.dll")

    Local $sRun = 'signtool sign /f keys\' & $sCN & '_cert.pfx /p ' & $sCERTIFICATE_PASSWORD & ' ' & $sFileToSign
    $sOut &= $sRun & @CRLF & @CRLF
    $sOut &= runCmd($sRun)

    $sRun = 'signtool timestamp /t ' & $sTIMESTAMP_URL & ' ' & $sFileToSign
    $sOut &= $sRun & @CRLF & @CRLF
    $sOut &= runCmd($sRun)

EndFunc   ;==>signTheFile

ConsoleWrite(@CRLF)

Func runCmd($sRun)
    Local $Pid = Run($sRun, @ScriptDir, @SW_HIDE, 8) ; 0x8 ($STDERR_MERGED) = Provides the same handle for STDOUT and STDERR. Implies both $STDOUT_CHILD and $STDERR_CHILD.
    Local $Handle = _ProcessExitCode($Pid)
    Local $Return_Text = ShowStdOutErr($Pid)
    Local $ExitCode = _ProcessExitCode($Pid, $Handle)
    _ProcessCloseHandle($Handle)
    Return $Return_Text & @CRLF & "ExitCode : " & $ExitCode & @CRLF & "=====================================================" & @CRLF
EndFunc   ;==>runCmd

; Get STDOUT and ERROUT from commandline tool
Func ShowStdOutErr($l_Handle, $ShowConsole = 1, $Replace = "", $ReplaceWith = "", $dontLoop = 0)
    Local $Line = "x", $Line2 = "x", $tot_out, $err1 = 0, $err2 = 0, $cnt1 = 0, $cnt2 = 0
    Do
        $Line = StdoutRead($l_Handle)
        $err1 = @error
        If $Replace <> "" Then $Line = StringReplace($Line, $Replace, $ReplaceWith)
        $tot_out &= $Line
        If $ShowConsole Then ConsoleWrite($Line)
        $Line2 = StderrRead($l_Handle)
        $err2 = @error
        If $Replace <> "" Then $Line2 = StringReplace($Line2, $Replace, $ReplaceWith)
        $tot_out &= $Line2
        If $ShowConsole Then ConsoleWrite($Line2)
        ; end the loop also when AutoIt3 has ended but a sub process was shelled with Run() that is still active
        ; only do this every 50 cycles to avoid cpu hunger
        If $cnt1 = 50 Then
            $cnt1 = 0
            ; loop another 50 times just to ensure the buffers emptied.
            If Not ProcessExists($l_Handle) Then
                If $cnt2 > 2 Then ExitLoop
                $cnt2 += 1
            EndIf
        EndIf
        $cnt1 += 1
        If $dontLoop Then Return $tot_out
        Sleep(10)
    Until ($err1 And $err2)
    Return $tot_out
EndFunc   ;==>ShowStdOutErr
Func _ProcessCloseHandle($h_Process)
    ; Close the process handle of a PID
    DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $h_Process)
    If Not @error Then Return 1
    Return 0
EndFunc   ;==>_ProcessCloseHandle
;===============================================================================
;
; Function Name:    _ProcessExitCode()
; Description:      Returns a handle/exitcode from use of Run().
; Parameter(s):     $i_Pid        - ProcessID returned from a Run() execution
;                   $h_Process    - Process handle
; Requirement(s):   None
; Return Value(s):  On Success - Returns Process handle while Run() is executing
;                                (use above directly after Run() line with only PID parameter)
;                              - Returns Process Exitcode when Process does not exist
;                                (use above with PID and Process Handle parameter returned from first UDF call)
;                   On Failure - 0
; Author(s):        MHz (Thanks to DaveF for posting these DllCalls in Support Forum)
;
;===============================================================================
;
Func _ProcessExitCode($i_Pid, $h_Process = 0)
    ; 0 = Return Process Handle of PID else use Handle to Return Exitcode of a PID
    Local $v_Placeholder
    If Not IsArray($h_Process) Then
        ; Return the process handle of a PID
        $h_Process = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'int', 0x400, 'int', 0, 'int', $i_Pid)
        If Not @error Then Return $h_Process
    Else
        ; Return Process Exitcode of PID
        $h_Process = DllCall('kernel32.dll', 'ptr', 'GetExitCodeProcess', 'ptr', $h_Process[0], 'int*', $v_Placeholder)
        If Not @error Then Return $h_Process[2]
    EndIf
    Return 0
EndFunc   ;==>_ProcessExitCode

Func UniquePasswordGen()
    Local $n, $t
    For $n = 48 To 57 ; 0..9
        $t &= Chr($n)
    Next
    For $n = 65 To 90 ; A..Z
        $t &= Chr($n)
    Next
    For $n = 97 To 122 ; a..z
        $t &= Chr($n)
    Next
    Local $a = StringSplit($t, "")
    $t = ""
    For $n = 1 To 50
        $t &= $a[Random(1, $a[0], 1)]
    Next
    Return $t
EndFunc   ;==>UniquePasswordGen

I'm new at this. Any comments are very welcomed.

you can add a line like this to your au3 file:

#AutoIt3Wrapper_Run_After=""%scitedir%\tools\SignThisFile\CertSigner.exe" "%out%" /NoPopup"

where this script is compiled as CertSigner.exe in a folder named "tools\SignThisFile" under the SciTE editor's folder.

 

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted
1 hour ago, Nine said:

Don't you need to specify the name of the file you want to sign ? 

You can use %out% as described in scite run tool.

I tried %out% at the end of the line, did not work too. 
Is it not possible to use the installed softwaresign certificate, do I have to export it and use it? 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...