Code Signing Certificates for Delphi Apps

I was using OV all the time, but the last time I went EV – it offers longer expiry, but comes with an annoying dongle (which I wrote a little tool to circumvent, to make it easier to use).

Regards,

Alexander Pastuhov

0414 453 433

+1 for kSoftware. Nothing their fault but going through the certificate renewal process is a massive stress raiser for me, firstly trying to get through the Id requirements which aren’t made with WFH online businesses in mind. Then I screwed up last time in not following the advice to use Internet Explorer (not Edge, not anything else) to download the certificate. A total pain.

I’ve just renewed my certificate. It was a smooth operation. I have moved since the first one was issued, but fortunately due to having IP phone, the number hadn’t changed. I had to send a driver’s licence image as proof of the new address.

I did follow instructions to the letter and use IE.

One thing that seems different is that the export process only exported a .pfx file and not a .p12 file also which I have previously used in signing. Still to see what the FB task thinks of this, and whether the .exe looks like it has worked. :crossed_fingers:

Also, here is the batch file I use if that helps.

C:\Program Files\Microsoft SDKs\Windows\v7.1>type sf.bat
bin\signtool sign /a /t http://timestamp.comodoca.com /v “C:_projects\Arduino\Software\Arduino Emulator\Output\SimulatorForArduino.exe”
bin\signtool sign /a /tr http://timestamp.comodoca.com /fd sha256 /td sha256 /v “C:_projects\Arduino\Software\Arduino Emulator\Output\SimulatorForArduino.exe”

pause

1 Like

Should be fine, I only ever use the pfx with the SignTool action.

1 Like

@Malcolm just in case you hadn’t seen this

https://www.finalbuilder.com/resources/blogs/code-signing-changes-for-2016

Also there is a link to an example project which shows how it’s done.

One thing I always recommend is to sign and timestamp in separate steps - the reason being that timestamping often fails - timestamp servers are not all that reliable (or reachable, due to local or remote network issues) - the example above uses a list of timestamp servers (2 lists, for SHA1 and SHA256) and will try different servers if the first one fails, looping through the list of servers until one works.

1 Like

Hi Alexander,

Does your tool cope with the “enter password for every file” problem?
Can you provide some more info please?
I’m intending to buy an EV today (even though I’ve still got 2.75 years on my OV remaining).

Lex

Yes, it’s basically running in the background, watching for these prompts and enters the password automatically, every time there’s a prompt.

This is the main component, a separate thread, which you just need to pass in the password in the “data” field:

unit WindowClickingThread;

interface

uses
  Classes, Windows;

type
  TWindowClickingThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  public
    Data: string;
  end;

implementation

uses Messages, SysUtils;

{ TWindowClickingThread }

procedure TWindowClickingThread.Execute;
var
  diag, butt, edit: HWND;
  i: integer;
begin
  repeat
    sleep(1000);
    diag := 0;
    diag := FindWindow('#32770', 'Token Logon');
    if diag <> 0 then
    begin
      edit := FindWindowEx(diag, 0, 'Edit', '');
      if edit <> 0 then
        edit := FindWindowEx(diag, edit, 'Edit', '');

      if edit <> 0 then
      begin
        SendMessage(edit, WM_SETTEXT, 0, NativeUInt(@Data[1]));
        butt := FindWindowEx(diag, 0, 'Button', 'OK');
        if butt <> 0 then
          PostMessage(diag, WM_COMMAND, MAKEWPARAM(1, BN_CLICKED), butt);
        // Click "OK"
      end;
    end;

    diag := 0;
    diag := FindWindow('Credential Dialog Xaml Host', 'Windows Security');

    if diag <> 0 then
    begin
      for i := 1 to Length(Data) do
        SendMessage(diag, WM_CHAR, word(Data[i]), 0);

      SendMessage(diag, WM_KEYDOWN, 13, 0); // ENTER
      sleep(1000); // 1s - it's rather slow to respond
    end;
  until Terminated;
end;

end.

The main form is hidden in the icons area and allows to type in the password, etc. It can of course be improved, it was just a quick hack. For instance you could create a constructor here that would accept the password as a parameter…

Regards,

Alexander Pastuhov

Thanks Alexander, I’ve implemented that.
Now waiting for my EV cert to arrive so I can try it in “real life”.

Cheers,
Lex

I feel left out. I don’t sign my apps at all.

I guess the people using my freeware apps are used to accepting the warning.

None of my apps use an installer though, just unzip and run.

I got very lucky then. < 36 hours from purchase to cert ready. The company address validation was a bit clumsy, but otherwise, pretty good.

Thanks all for your help.

Cheers

It’s the first time I’ve had to worry about buying one. A few of our services customers have them, but it’s just part of the build process and someone else bought it, so I never gave it too much thought.

So far not that hard, but all I’ve really done is supply some documents and pay the money :slight_smile:

Just as a final update, this was pretty straight forward (once I had the benefit of all your advice)

The only catch was that even though I was taking care of signing the application exe, I should have let Inno Setup take care of the signing of the setup exe.

I didn’'t bother at first, because I’d worked out how to sign the app and figured I’d just do it again for the setup. However, if you let Inno Setup do it, it will also sign the uninstaller.

Otherwise, surprised at how easy it actually was. Kinda makes me suspect I haven’t done it right :slight_smile:

What you have described sounds like what I did. They trickiest bit for me, though not really difficult, was getting the app signing done in FinalBuilder as I have multiple apps to sign, so it was defining which files and looping through the list and calling the time server.