Skip to content

Connect: verify signature in privileged updater against hardcoded Windows signing cert#64754

Merged
gzdunek merged 3 commits intomasterfrom
gzdunek/verify-signature-against-teleport-cert
Mar 23, 2026
Merged

Connect: verify signature in privileged updater against hardcoded Windows signing cert#64754
gzdunek merged 3 commits intomasterfrom
gzdunek/verify-signature-against-teleport-cert

Conversation

@gzdunek
Copy link
Copy Markdown
Contributor

@gzdunek gzdunek commented Mar 18, 2026

I realized there is a bug in the current signature verification approach (added in #63573).

The verification process currently reads the expected publisher certificate from the running service binary (tsh) and compares it with the update. While I added logic to skip this check for unsigned services, this does not address a situation where the installed service is signed with a certificate that has since expired. In that case, WinVerifyTrust would fail, preventing installation of a valid update.

While we could ignore this specific WinVerifyTrust error and continue reading the certificate from the service binary, that approach is brittle. A better option seems to just hardcode the certificate subject (which is more common in general).

I believe I overthought this problem #62545 (comment) in the first place. My main motivation for avoiding hardcoded Teleport publisher identity was to keep updates from OSS builds to OSS working, but that introduced practical issues:

  1. Testing this path requires signed artifacts, which is inconvenient for development.
  2. Validation depends on properties of the currently installed binary, which can fail for reasons unrelated to the update itself (for example an expired cert).

After this change, updates from OSS -> Teleport builds will work, while updates from OSS -> OSS will require either changing the certificate or disabling this logic entirely. I think this is acceptable, as it can be easily adjusted or disabled in custom builds.

Manual Test Plan

Test Environment

Built Teleport Connect from this branch, set client tools updates to 18.7.3.

Test Cases

  • The update was successfully installed, meaning the signature verification passed.

@gzdunek gzdunek added the no-changelog Indicates that a PR does not require a changelog entry label Mar 18, 2026
@github-actions github-actions Bot requested review from alexhemard and avatus March 18, 2026 08:47
@gzdunek gzdunek requested review from ravicious and removed request for alexhemard March 18, 2026 08:47
Copy link
Copy Markdown
Member

@ravicious ravicious left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overall change makes sense to me.


var teleportCert = &x509.Certificate{
Subject: pkix.Name{
CommonName: "Gravitational, Inc.",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Argh, should we compare just the CN in the end? The more I look at it the more brittle it seems. Especially after re-reading that comment and seeing that Tailscale looks just at CN.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I based the decision to compare the full DN on what electron-builder is doing:

As far as I know, the main issue with comparing only the CN is that it's not globally unique - a company with the same name could be registered in a different jurisdiction. Comparing the full DN reduces that risk significantly (it's unlikely to see another "Gravitational, Inc." registered in California).

Regarding concerns about brittle comparisons: after the last renewal, even the CN (something we wouldn't expect to change) was slightly different. I asked about this on Slack and got confirmation that next time the full DN should not change: https://gravitational.slack.com/archives/C010BD557L6/p1773773823087189?thread_ts=1773772598.878769&cid=C010BD557L6

Taking that into account, comparing only the CN doesn't seem meaningfully less brittle than comparing the full DN, while providing weaker guarantees.

@gzdunek gzdunek added this pull request to the merge queue Mar 23, 2026
Merged via the queue into master with commit c0a66f3 Mar 23, 2026
55 checks passed
@gzdunek gzdunek deleted the gzdunek/verify-signature-against-teleport-cert branch March 23, 2026 16:00
gzdunek added a commit that referenced this pull request Mar 27, 2026
…dows signing cert (#64754)

* Make `verifySignature` compare subject against fixed cert

* Adjust tests

* Update README.md

(cherry picked from commit c0a66f3)
gzdunek added a commit that referenced this pull request Mar 30, 2026
…dows signing cert (#64754)

* Make `verifySignature` compare subject against fixed cert

* Adjust tests

* Update README.md

(cherry picked from commit c0a66f3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog Indicates that a PR does not require a changelog entry size/sm ui

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants