[BUG] Broken key fingerprinting #63742
Labels
Bug
broken, incorrect, or confusing behavior
needs-triage
security
issues and PRs for the Security Working Group
Milestone
Description
This is essentially a re-open of #14593 but with a proposed cross-platform solution (that is, it should be noted, a more "proper" way of fingerprinting a key).
Setup
1.) Set
hash_type
tosha512
on both a Linux master and Windows minion (this is probably unnecessary, as the same code should be used on both.)2.) Set
master_finger
in the Windows minion's config file to the output ofsalt-key -f master.pub
on the Linux master.3.) Get the following (critical) error:
Steps to Reproduce the behavior
See above,
Expected behavior
The Windows minion should properly fingerprint the Master's key.
Versions Report
salt --versions-report
(Provided by running salt --versions-report. Please also mention any differences in master/minion versions.)Master:
Minion:
Additional context
ROOT CAUSE:
This is due to twofold problems:
1.) Window performing the hashing in
pem_finger
(salt/utils/crypt.py
) against a CRLF-line-terminated (\r\n
) file (master_minion.pem
), whereas Linux master (and Linux minions) performing hashing against the (much more sane, of course) LF-terminated (\n
) file (eithermaster.pub
orminion_master.pub
depending on context).2.) A very silly way of calculating a key's fingerprint.
1 is inexcusable. There is no reason a minion's platform should need a different checksum for its master's finger. This is bad design.
THE PROPER SOLUTION:
But thankfully, a more sane approach to 2 also simultaneously completely fixes 1, and with no code porting across platforms or checks thereof - it's completely cross-platform.
So, let's take an example Master pubkey. (This is generated explicitly for the purpose of demonstration.)
(The key was generated with
hash_type: sha512
andkey_size: 4096
on the master, configured before first-run. Now would be a good time to mention that specifying a 4096-bit key in the config does not properly generate a 4096-bit master key and instead only generates a 2048-bit key... but that's a bug for another day.)This is a PEM-encoded 2048-bit RSA public key, using PKIX format.
And, as per PEM encoding specifications, the block contained between the start label (and headers, not present) and end label is Base64-Encoded ASN.1.
Which means that a more proper fingerprinting (aside from encoding as an actual ASN.1 field itself, which is a bit of a hassle) would be to base64-DECODE the PEM block, and hash that.
A nice feature of Python's stdlib base64 library is that it is newline-agnostic. It doesn't care if there are newlines in base64 or not. It doesn't care if they're line-terminated with LF or CRLF.
The text was updated successfully, but these errors were encountered: