0

I'm working on some software that can be self-hosted, and it includes a component that can be downloaded and installed on end user machines (Windows only). The download comes from the self-hosted server, not from a central location, and that cannot change. How can we verify that the .msi the program downloads to update itself is valid? I can figure out the coding, but I don't know how to go about this from a security perspective.

Our installers are always signed by a valid code signing certificate from a trusted CA, so I could verify its validity and hardcode the valid certificate's hash into the software, but what happens when we have to renew the code signing cert? People on old versions of the software wouldn't be able to update to a version of the software whose installer was signed by a new cert because the certificate hash wouldn't match.

What is the correct way to verify our installers?

The thing I'm unsure of is verifying that the installer was actually signed by us. The installer is self-hosted and has auto-update capability, so it's possible that an end user could be pointed to an installer that was signed by someone other than us. We therefore need to verify that a) the .msi is signed with a valid signature, and b) it was signed by us and no one else. The second issue is the one I'm trying to solve.

schroeder
  • 123,438
  • 55
  • 284
  • 319
vaindil
  • 263
  • 1
  • 2
  • 8

2 Answers2

0

Usually, a code signature is timestamped. This way, the signature can be verified using the public key from a trusted certificate - even if the certificate is now expired - as long as the certificate was valid when the signature was made.

mti2935
  • 19,868
  • 2
  • 45
  • 64
0

A signature is made by a private key, which has a corresponding public key.

When verifying a signature, two things are verified: Does the content match what was verified? Was the content signed by a specific private key?

The first property alone, also known as Integrity, can be achieved by a hash function. The second property, also known as Authenticity, is what the Public Key Cryptography brings to the table.

How can I check that the installer was signed by us and not a third party?

  1. Create a private/public key pair
  2. Distribute the public key together with the client
  3. Sign the installer with the private key
  4. Verify that the installer was signed by the private key using the public key

Of course, this approach can and should be extended by using certificates instead of plain public keys, by using a chain of trust with intermediate certificates, etc.. However, all of this is a bit outside the scope of the question.

  • This would be a separate key pair, there's no way to do it with the code signing certificate that's already issued by a trusted CA? – vaindil Jul 06 '20 at 20:48
  • Sure, it would work with that. You just need to distribute your certificate with the software and keep the private key safe. –  Jul 06 '20 at 20:54
  • I guess I'm still confused. The code signing certificate is a trusted CA's way of saying "we've verified who this is". Is there no way to compare against a property of the digital signature to ensure that it was signed by us? Checking the hash won't work because it will presumably change when our code signing cert is renewed. – vaindil Jul 07 '20 at 04:26