-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SSlibKey: consider stronger validation of keytype/scheme for keyval #766
Comments
An argument against more comprehensive and/or earlier validation is that a key might be deserialized but never used for signature verification. In that case it might not matter if the key is invalid. Similarly, a key might be inconsistent, but still manage to verify a signature. This is likely the case for ecdsa keys, e.g. if the keyval contains a nistp256 key, but scheme is "ecdsa-sha2-nistp384" (or vice-versa). I lean towards checking early and comprehensively, and failing hard if an SSlibKey is inconsistent. If we want to support deserialisation of unknown keys, we should implement this in the Key.from_dict interface. |
Fix test, which successfully verifies a signature from an ecdsa nistp256 key, using a "ecdsa-sha2-nistp384" key. This only worked because keytype/scheme/keyval combos in an SSlibKey are not validated sufficiently (see secure-systems-lab#766). The test data was created using below snippet. Note how the signature is not created with CryptoSigner, which does not support nistp384. ``` from cryptography.hazmat.primitives.asymmetric.ec import ( ECDSA, SECP384R1, EllipticCurvePrivateKey, ) from cryptography.hazmat.primitives.hashes import SHA384 from cryptography.hazmat.primitives.serialization import load_pem_private_key from securesystemslib.signer import SSlibKey with open("tests/data/pems/ecdsa_secp384r1_private.pem", "rb") as f: priv: EllipticCurvePrivateKey = load_pem_private_key(f.read(), None) assert isinstance(priv.curve, SECP384R1) pub = SSlibKey.from_crypto(priv.public_key()) sig = priv.sign(b"DATA", ECDSA(SHA384())) print(pub.keyid) print(sig.hex()) print(repr(pub.keyval["public"]).strip("'")) ``` Signed-off-by: Lukas Puehringer <[email protected]>
Added checks as requrested in secure-systems-lab#766: - keytype matches scheme - scheme matches deserialized key type (only for pem formatted keyvals; for ed25519 the check happens implicitly on deserialization) - scheme matches deserialized key curve (only for ecdsa) Note that this PR does not move the checks to the constructor as suggested in secure-systems-lab#766. This may or may not be addressed in a follow-up PR. failing tests fixed in secure-systems-lab#794 Signed-off-by: Lukas Puehringer <[email protected]>
Added checks as requrested in secure-systems-lab#766: - keytype matches scheme - scheme matches deserialized key type (only for pem formatted keyvals; for ed25519 the check happens implicitly on deserialization) - scheme matches deserialized key curve (only for ecdsa) Note that this PR does not move the checks to the constructor as suggested in secure-systems-lab#766. This may or may not be addressed in a follow-up PR. failing tests fixed in secure-systems-lab#794 Signed-off-by: Lukas Puehringer <[email protected]>
Fix test, which successfully verifies a signature from an ecdsa nistp256 key, using a "ecdsa-sha2-nistp384" key. This only worked because keytype/scheme/keyval combos in an SSlibKey are not validated sufficiently (see secure-systems-lab#766). The test data was created using below snippet. Note how the signature is not created with CryptoSigner, which does not support nistp384. ``` from cryptography.hazmat.primitives.asymmetric.ec import ( ECDSA, SECP384R1, EllipticCurvePrivateKey, ) from cryptography.hazmat.primitives.hashes import SHA384 from cryptography.hazmat.primitives.serialization import load_pem_private_key from securesystemslib.signer import SSlibKey with open("tests/data/pems/ecdsa_secp384r1_private.pem", "rb") as f: priv: EllipticCurvePrivateKey = load_pem_private_key(f.read(), None) assert isinstance(priv.curve, SECP384R1) pub = SSlibKey.from_crypto(priv.public_key()) sig = priv.sign(b"DATA", ECDSA(SHA384())) print(pub.keyid) print(sig.hex()) print(repr(pub.keyval["public"]).strip("'")) ``` Signed-off-by: Lukas Puehringer <[email protected]>
Added checks as requrested in secure-systems-lab#766: - keytype matches scheme - scheme matches deserialized key type (only for pem formatted keyvals; for ed25519 the check happens implicitly on deserialization) - scheme matches deserialized key curve (only for ecdsa) Note that this PR does not move the checks to the constructor as suggested in secure-systems-lab#766. This may or may not be addressed in a follow-up PR. failing tests fixed in secure-systems-lab#794 Signed-off-by: Lukas Puehringer <[email protected]>
The consistency of SSlibKey instances is mainly "validated" at usage time. That is, in
SSlibKey.verify_signature
, when keyval is deserialised based on scheme, unknown schemes and undeserializable keyvals are filtered out. This validation is incomplete and also happens late.For comparison, at creation time inputs are hardly validated (see e.g. in from_dict or in the base constructor). Note that an additional safeguard exists in the Key.from_dict deserialisation interface, which filters out unregistered keytype, scheme pairs.
Let's consider:
See related issues related to invalid SSlibKey instances and validation: #764 #765, #669, #559
The text was updated successfully, but these errors were encountered: