sslinno-setup

Get certificate thumbprint from pfx in Inno Setup


I'm trying to configure HTTPS connection for my web service from Inno Setup installer. Previously, I was doing next things:

  1. Created self-signed server certificate with makecert
  2. Installed certificate to Local Machine Personal certificates using certmgr
  3. Obtained its thumbprint/hash using GetSHA1OfFile method of Inno Setup.
  4. Assigned certificate to port using netsh http add sslcert command

But now I'm switching from makecert to OpenSSL, and also introducing CA certificate, which is previously generated, and works as issuer for my server certificate. What am I doing now:

  1. Install CA certificate, using certmgr
  2. Generate server certificate from CA certificate, using OpenSSL. Server certificate consists of actual certificate and private key
  3. Combine certificate and private key to pfx file format, using OpenSSL
  4. Install pfx file, using CertUtil

Now, the issue is, when generating certificate with OpenSSL, it seems, that its sha1 hash is different from its thumbprint, so I can't use GetSHA1OfFile for this purpose anymore.

So, question is - how can I programmatically get certificate hash in Inno Setup, to assign it to port, if GetSHA1OfFile can't be used for this purpose?


Solution

  • Use the certutil.exe -dump command and read its output.

    I'm not sure, which of the fingerprints you are after, but I assume it's the one labelled Cert Hash(sha1).

    var
      Key: string;
      I: Integer;
      TempFile: string;
      Lines: TArrayOfString;
      Hash: string;
      ResultCode: Integer;
      PfxFile: string;
      Cmd, Params: string;
    begin
      PfxFile := '...\my.pfx';
      TempFile := ExpandConstant('{tmp}\certdump.txt');
      Cmd := 'cmd.exe';
      Params := '/c certutil.exe -dump "' + PfxFile + '" > "' + TempFile + '"';
      if not Exec(Cmd, Params, '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
      begin
        Log('Failed to run certificate dump');
      end
        else
      if not LoadStringsFromFile(TempFile, Lines) then
      begin
        Log('Failed to read certificate dump');
      end
        else
      begin
        Key := 'Cert Hash(sha1):';
        Hash := '';
        for I := 0 to GetArrayLength(Lines) - 1 do
        begin
          if CompareText(Copy(Lines[I], 1, Length(Key)), Key) = 0 then
          begin
            Hash := Copy(Lines[I], Length(Key) + 1, Length(Lines[I]) - Length(Key));
            Hash := Trim(Hash);
            StringChange(Hash, ' ', '');
          end;
        end;
        DeleteFile(TempFile);
        
        if Hash = '' then
        begin
          Log('Hash not found in certificate dump');
        end
          else
        begin
          Log('Certificate hash: ' + Hash);
        end;
      end;
    end;