-
Notifications
You must be signed in to change notification settings - Fork 48
Add Signer trait #340
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
base: main
Are you sure you want to change the base?
Add Signer trait #340
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,7 +12,7 @@ | |
| //! The implementation is based on [ed25519_dalek](https://github.com/dalek-cryptography/ed25519-dalek). | ||
| #![allow(non_snake_case)] | ||
| use crate::builder::Algorithm; | ||
| use crate::format::schema; | ||
| use crate::format::schema::{self, public_key::Algorithm as SchemaAlgorithm}; | ||
| use crate::format::ThirdPartyVerificationMode; | ||
|
|
||
| use super::error; | ||
|
|
@@ -25,13 +25,32 @@ use std::fmt; | |
| use std::hash::Hash; | ||
| use std::str::FromStr; | ||
|
|
||
| mod traits; | ||
| pub use traits::*; | ||
|
|
||
| /// pair of cryptographic keys used to sign a token's block | ||
| #[derive(Debug, PartialEq)] | ||
| pub enum KeyPair { | ||
| Ed25519(ed25519::KeyPair), | ||
| P256(p256::KeyPair), | ||
| } | ||
|
|
||
| impl Signer for KeyPair { | ||
| fn sign(&self, data: &[u8]) -> Result<Signature, error::Format> { | ||
| match self { | ||
| Self::Ed25519(key) => key.sign(data), | ||
| Self::P256(key) => key.sign(data), | ||
| } | ||
| } | ||
|
|
||
| fn algorithm(&self) -> Algorithm { | ||
| match self { | ||
| Self::Ed25519(_) => Algorithm::Ed25519, | ||
| Self::P256(_) => Algorithm::Secp256r1, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl KeyPair { | ||
| /// Create a new ed25519 keypair with the default OS RNG | ||
| pub fn new() -> Self { | ||
|
|
@@ -74,8 +93,8 @@ impl KeyPair { | |
|
|
||
| pub fn sign(&self, data: &[u8]) -> Result<Signature, error::Format> { | ||
| match self { | ||
| KeyPair::Ed25519(key) => key.sign(data), | ||
| KeyPair::P256(key) => key.sign(data), | ||
| Self::Ed25519(key) => key.sign(data), | ||
| Self::P256(key) => key.sign(data), | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -145,10 +164,10 @@ impl KeyPair { | |
| } | ||
| } | ||
|
|
||
| pub fn algorithm(&self) -> crate::format::schema::public_key::Algorithm { | ||
| pub fn algorithm(&self) -> SchemaAlgorithm { | ||
| match self { | ||
| KeyPair::Ed25519(_) => crate::format::schema::public_key::Algorithm::Ed25519, | ||
| KeyPair::P256(_) => crate::format::schema::public_key::Algorithm::Secp256r1, | ||
| Self::Ed25519(_) => SchemaAlgorithm::Ed25519, | ||
| Self::P256(_) => SchemaAlgorithm::Secp256r1, | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -272,10 +291,10 @@ impl PrivateKey { | |
| } | ||
| } | ||
|
|
||
| pub fn algorithm(&self) -> crate::format::schema::public_key::Algorithm { | ||
| pub fn algorithm(&self) -> SchemaAlgorithm { | ||
| match self { | ||
| PrivateKey::Ed25519(_) => crate::format::schema::public_key::Algorithm::Ed25519, | ||
| PrivateKey::P256(_) => crate::format::schema::public_key::Algorithm::Secp256r1, | ||
| Self::Ed25519(_) => SchemaAlgorithm::Ed25519, | ||
| Self::P256(_) => SchemaAlgorithm::Secp256r1, | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -429,13 +448,13 @@ impl fmt::Display for PublicKey { | |
| } | ||
|
|
||
| #[derive(Clone, Debug)] | ||
| /// A signature of a [Biscuit](crate::Biscuit) block. | ||
| /// | ||
| /// May be constructed via [Into] from [ed25519_dalek::Signature] or | ||
| /// from [ecdsa::Signature] with the [NistP256](::p256::NistP256) curve. | ||
| pub struct Signature(pub(crate) Vec<u8>); | ||
|
|
||
| impl Signature { | ||
| pub fn from_bytes(data: &[u8]) -> Result<Self, error::Format> { | ||
| Ok(Signature(data.to_owned())) | ||
| } | ||
|
|
||
|
Comment on lines
-435
to
-438
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was never usable before as |
||
| pub(crate) fn from_vec(data: Vec<u8>) -> Self { | ||
| Signature(data) | ||
| } | ||
|
|
@@ -445,6 +464,18 @@ impl Signature { | |
| } | ||
| } | ||
|
|
||
| impl From<ed25519_dalek::Signature> for Signature { | ||
| fn from(value: ed25519_dalek::Signature) -> Self { | ||
| Self(value.to_vec()) | ||
| } | ||
| } | ||
|
|
||
| impl From<ecdsa::Signature<::p256::NistP256>> for Signature { | ||
| fn from(value: ecdsa::Signature<::p256::NistP256>) -> Self { | ||
| Self(value.to_der().as_bytes().to_vec()) | ||
| } | ||
| } | ||
|
|
||
| impl FromStr for PublicKey { | ||
| type Err = error::Format; | ||
|
|
||
|
|
@@ -484,7 +515,7 @@ pub enum TokenNext { | |
| } | ||
|
|
||
| pub fn sign_authority_block( | ||
| keypair: &KeyPair, | ||
| signer: &impl Signer, | ||
| next_key: &KeyPair, | ||
| message: &[u8], | ||
| version: u32, | ||
|
|
@@ -500,7 +531,7 @@ pub fn sign_authority_block( | |
| } | ||
| }; | ||
|
|
||
| let signature = keypair.sign(&to_sign)?; | ||
| let signature = signer.sign(&to_sign)?; | ||
|
|
||
| Ok(Signature(signature.to_bytes().to_vec())) | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| use super::Signature; | ||
| use crate::{error, Algorithm}; | ||
| // so we can link to this in cargo docs. | ||
| #[cfg(doc)] | ||
| use crate::BiscuitBuilder; | ||
|
|
||
| /// A trait for signing arbitrary byte inputs with biscuit-compatible | ||
| /// [algorithms](Algorithm). | ||
| /// | ||
| /// Instances of `Signer` may be used with [BiscuitBuilder] as root keys. | ||
| pub trait Signer { | ||
| /// The algorithm used. Must match the signature returned via [sign](Self::sign). | ||
| fn algorithm(&self) -> Algorithm; | ||
| /// Sign a series of bytes, returning a signature. This signature must match | ||
| /// what [self.algorithm()](Self::algorithm) returns. Any incorrect values | ||
| /// will likely result in invalid tokens. | ||
| fn sign(&self, data: &[u8]) -> Result<Signature, error::Format>; | ||
| } | ||
|
Comment on lines
+11
to
+18
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't super like this API, but it should do fine. The other option would be to have Also, this may be better named as Could also add an associated
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Notably we want this separate from a potential later |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,7 @@ | |
| //! | ||
| //! - serialization of Biscuit blocks to Protobuf then `Vec<u8>` | ||
| //! - serialization of a wrapper structure containing serialized blocks and the signature | ||
| use super::crypto::{self, KeyPair, PrivateKey, PublicKey, TokenNext}; | ||
| use super::crypto::{self, KeyPair, PrivateKey, PublicKey, Signer, TokenNext}; | ||
|
|
||
| use prost::Message; | ||
|
|
||
|
|
@@ -17,8 +17,10 @@ use super::token::Block; | |
| use crate::crypto::ExternalSignature; | ||
| use crate::crypto::Signature; | ||
| use crate::datalog::SymbolTable; | ||
| use crate::format::schema::public_key::Algorithm as SchemaAlgorithm; | ||
| use crate::token::RootKeyProvider; | ||
| use crate::token::DATALOG_3_3; | ||
| use crate::Algorithm; | ||
|
|
||
| /// Structures generated from the Protobuf schema | ||
| pub mod schema; /*{ | ||
|
|
@@ -292,7 +294,7 @@ impl SerializedBiscuit { | |
| /// creates a new token | ||
| pub fn new( | ||
| root_key_id: Option<u32>, | ||
| root_keypair: &KeyPair, | ||
| root_keypair: &impl Signer, | ||
| next_keypair: &KeyPair, | ||
| authority: &Block, | ||
| ) -> Result<Self, error::Token> { | ||
|
|
@@ -315,7 +317,7 @@ impl SerializedBiscuit { | |
| /// creates a new token | ||
| pub(crate) fn new_inner( | ||
| root_key_id: Option<u32>, | ||
| root_keypair: &KeyPair, | ||
| root_signer: &impl Signer, | ||
| next_keypair: &KeyPair, | ||
| authority: &Block, | ||
| authority_signature_version: u32, | ||
|
|
@@ -328,7 +330,7 @@ impl SerializedBiscuit { | |
| })?; | ||
|
|
||
| let signature = crypto::sign_authority_block( | ||
| root_keypair, | ||
| root_signer, | ||
| next_keypair, | ||
| &v, | ||
| authority_signature_version, | ||
|
|
@@ -548,7 +550,7 @@ pub(crate) enum ThirdPartyVerificationMode { | |
| } | ||
|
|
||
| fn block_signature_version<I>( | ||
| block_keypair: &KeyPair, | ||
| block_keypair: &impl Signer, | ||
| next_keypair: &KeyPair, | ||
| external_signature: &Option<ExternalSignature>, | ||
| block_version: &Option<u32>, | ||
|
|
@@ -568,8 +570,8 @@ where | |
| _ => {} | ||
| } | ||
|
|
||
| match (block_keypair, next_keypair) { | ||
| (KeyPair::Ed25519(_), KeyPair::Ed25519(_)) => {} | ||
| match (block_keypair.algorithm(), next_keypair.algorithm()) { | ||
| (Algorithm::Ed25519, SchemaAlgorithm::Ed25519) => {} | ||
|
Comment on lines
+573
to
+574
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Kinda gross here (the |
||
| _ => { | ||
| return NON_ED25519_SIGNATURE_VERSION; | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously this was implicitly public as a return type; now it's explicit (hence the added comment) and addressable.
There may be some merit with regards to changing this into an
enumtype, although this may technically be a breaking change.