[BREAKING] Abstract biscuit-auth over crypto implementation - #334
[BREAKING] Abstract biscuit-auth over crypto implementation#334saoirse-a wants to merge 3 commits into
Conversation
KeyPair is really just the same as PrivateKey, it's not necessary to have two distinct types for these purposes and it makes trait abstraction more complex.
|
I think there is more work to be done to fully integrate the traits:
Before I go through all of that with a fine tooth comb I wanted to get confirmation that this is the right direction. |
|
I like this approach as it neatly handles both KMS and pluggable crypto providers. |
This commit adds four traits to biscuit-auth: `Sign`, `Verify`, `SerializePublicKey` and `SerializePrivateKey`. Together, these represent the behaviors of private keys and public keys, including those which can be serialized into the token and those which can't. Biscuit themselves become parameterized by the private key type that their proof uses (the public keys used in the token being determined as associated types of that private key type). These public and private keys must be serializable. For issuing a token, the keys used do not need to be serializable, and do not need to be the same as used for the token-internal keys. For third party signing, only the public key needs to be serializable. Some refactors were made to enable this change: 1. The `Keypair` type was eliminated from the code; it's function is fulfilled by the private key type and a third type was not necessary. 2. The useage of public keys in datalog authorizer running doesn't need an actual crypto implementation, just key data, so its replaced by an inert public key type that contains the algorithm tag and bytes.
c385e59 to
57c6ce4
Compare
|
Updated, I think this is ready now. |
divarvel
left a comment
There was a problem hiding this comment.
This generally looks good to me. got a few questions and nit-level comments.
| ) | ||
| .unwrap(); | ||
| hex::decode("6e9e6d5a75cf0c0e87ec1256b4dfed0ca3ba452912d213fcc70f8516583db9db").unwrap(), | ||
| ); |
There was a problem hiding this comment.
nit: it would make sense to use the from_str implementations here now that we have those (not directly related to the PR, but since we have to update these lines)
| } | ||
|
|
||
| pub fn insert_fallible(&mut self, k: &PublicKey) -> Result<u64, error::Format> { | ||
| pub(crate) fn insert_serialize<K: SerializePublicKey>(&mut self, k: &K) -> u64 { |
There was a problem hiding this comment.
nit: insert_serialize makes it sound like serialize is part of the action being performed, whereas it’s because of the trait name. Maybe making the trait name more explicit would help?
|
|
||
| pub fn get(&self, k: &PublicKey) -> Option<u64> { | ||
| self.keys.iter().position(|key| key == k).map(|i| i as u64) | ||
| pub(crate) fn insert_proto(&mut self, k: &schema::PublicKey) -> u64 { |
There was a problem hiding this comment.
i’m not sure having a dependency to the proto module makes sense here. i’d rather have all the dependencies to proto be located in convert
| use crate::crypto::Signature; | ||
| use crate::error; | ||
|
|
||
| pub trait Verify { |
There was a problem hiding this comment.
nit: the trait names make sense in the context of this trait, but i’ve found those to be a bit harder to understand when reviewing call sites.
| @@ -1,3 +1,7 @@ | |||
| # `7.0.0` | |||
|
|
|||
| - Abstract biscuits over the crypto implementation (#334) | |||
There was a problem hiding this comment.
maybe a "breaking" section indicating what changed and how to migrate
This adds traits to the biscuit-auth public interface for cryptographic operations and abstracts the Biscuit and related types over those traits.
The traits added are
Sign,Verify,SerializePublicKeyandSerializePrivateKey. Together, these represent the necessary behavior for public and private keys, distinguishing those which can be serialised into the token and those which can't:The
Biscuittype is parameterised by aSerializePrivateKey, which is the type of the key contain in its proof. All of the public keys in the token are the associated serialisable public key type for that private key.The issuer key and third party signing keys can be different types from the key contained in the token; for the issuer neither the private key nor the public key need be serialisable, for the third party key only the public key needs to be serialisable because it appears in the token.
The existing
PublicKeyandPrivateKeytypes implement these traits; no other implementations are added directly to biscuit-auth with this PR (we could either add implementations for other crypto libraries like aws-lc-rs, maybe feature gated, or just require users to write their own implementations).To support this change, two significant refactors were performed:
Keypairtype was eliminated. This was effectively redundant with thePrivateKeytype, removing it made the set of traits required simpler.PublicKeystable used in authorization execution now stores an inert representation of the public key instead of thePublicKeytype, because it doesn't need to verify signatures, just compare keys for equality. This avoids more abstraction points over crypto types in the Datalog code.