From d6ab8d24d3bbec3f29bd89c8c7a52c1f5ffed7a9 Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Sat, 15 Jun 2024 13:29:13 +0200 Subject: [PATCH] add support for secp256r1 keys --- Cargo.lock | 307 ++++++++++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 2 +- src/cli.rs | 24 +++- src/input.rs | 28 +++-- src/inspect.rs | 13 ++- src/main.rs | 83 ++++++++----- 6 files changed, 400 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4008841..9417ae3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,6 +49,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.13.1" @@ -64,16 +76,19 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "biscuit-auth" version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ef2e2634c5493e5374f70bc45c9c8e5ebb547261973fe72698f6833d4b32ea" +source = "git+https://github.com/biscuit-auth/biscuit-rust.git?branch=fipscuit#c88fff0007d646440a540d647268a508ad65beec" dependencies = [ "base64", "biscuit-parser", "biscuit-quote", + "ecdsa 0.16.9", "ed25519-dalek", + "elliptic-curve 0.13.8", "getrandom 0.1.16", "hex", "nom", + "p256", + "pkcs8 0.9.0", "prost", "prost-types", "rand", @@ -108,8 +123,7 @@ dependencies = [ [[package]] name = "biscuit-parser" version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9fd6da963e73f7e6db729c3bd76784863ba405b15acbbb5cb08ebc2adbd3bf" +source = "git+https://github.com/biscuit-auth/biscuit-rust.git?branch=fipscuit#c88fff0007d646440a540d647268a508ad65beec" dependencies = [ "hex", "nom", @@ -123,8 +137,7 @@ dependencies = [ [[package]] name = "biscuit-quote" version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0071fe3634b644a8df1434e3e14841e480c4238059c66a94e479b7eff98c2bd3" +source = "git+https://github.com/biscuit-auth/biscuit-rust.git?branch=fipscuit#c88fff0007d646440a540d647268a508ad65beec" dependencies = [ "biscuit-parser", "proc-macro-error", @@ -261,6 +274,30 @@ dependencies = [ "libc", ] +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -299,6 +336,16 @@ dependencies = [ "syn 2.0.51", ] +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "der" version = "0.7.8" @@ -306,6 +353,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", + "pem-rfc7468", "zeroize", ] @@ -334,7 +382,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", + "const-oid", "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.8", + "digest 0.10.7", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", + "serdect", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -343,8 +420,8 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8", - "signature", + "pkcs8 0.10.2", + "signature 2.2.0", ] [[package]] @@ -368,6 +445,47 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array", + "group 0.12.1", + "pkcs8 0.9.0", + "rand_core", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "pem-rfc7468", + "pkcs8 0.10.2", + "rand_core", + "sec1 0.7.3", + "serdect", + "subtle", + "zeroize", +] + [[package]] name = "errno" version = "0.3.8" @@ -384,6 +502,26 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + [[package]] name = "fiat-crypto" version = "0.2.6" @@ -398,6 +536,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -422,6 +561,28 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core", + "subtle", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -449,6 +610,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -652,6 +822,17 @@ version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +[[package]] +name = "p256" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +dependencies = [ + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.8", +] + [[package]] name = "parse_duration" version = "2.1.1" @@ -663,14 +844,33 @@ dependencies = [ "regex", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + [[package]] name = "pkcs8" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der", - "spki", + "der 0.7.8", + "spki 0.7.3", ] [[package]] @@ -825,6 +1025,27 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac", + "zeroize", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "rustc_version" version = "0.4.0" @@ -853,6 +1074,35 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.8", + "generic-array", + "pkcs8 0.10.2", + "serdect", + "subtle", + "zeroize", +] + [[package]] name = "semver" version = "1.0.22" @@ -881,15 +1131,25 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", "serde", ] +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct 0.2.0", + "serde", +] + [[package]] name = "sha2" version = "0.9.9" @@ -920,15 +1180,36 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + [[package]] name = "signature" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ + "digest 0.10.7", "rand_core", ] +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + [[package]] name = "spki" version = "0.7.3" @@ -936,7 +1217,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der", + "der 0.7.8", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 75e1bb3..4e4d50b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ path = "src/main.rs" [dependencies] atty = "0.2.14" -biscuit-auth = { version = "4.0.0", features = ["serde-error"] } +biscuit-auth = { version = "4.0.0", features = ["serde-error"], git = "https://github.com/biscuit-auth/biscuit-rust.git", branch = "fipscuit" } clap = { version = "^3.0", features = ["color", "derive"] } chrono = "^0.4" hex = "0.4.3" diff --git a/src/cli.rs b/src/cli.rs index dc6cd76..6c6c9f7 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,4 +1,4 @@ -use clap::Parser; +use clap::{Parser, Subcommand}; use std::path::PathBuf; use crate::input::*; @@ -49,6 +49,16 @@ pub struct KeyPairCmd { /// Output the private key raw bytes directly, with no hex encoding #[clap(long, requires("only-private-key"))] pub raw_private_key_output: bool, + /// Key pair cryptographic algorithm + #[clap(subcommand)] + pub algorithm: Algorithm, +} + +/// Cryptographic algorithm for block signature +#[derive(Subcommand)] +pub enum Algorithm { + Ed25519, + Secp256r1, } /// Generate a biscuit from a private key and an authority block @@ -85,6 +95,9 @@ pub struct Generate { /// Add a TTL check to the generated authority block (either a RFC3339 datetime or a duration like '1d') #[clap(long, parse(try_from_str = parse_ttl))] pub add_ttl: Option, + /// Key pair cryptographic algorithm + #[clap(subcommand)] + pub algorithm: Algorithm, } /// Attenuate an existing biscuit by adding a new block @@ -99,6 +112,9 @@ pub struct Attenuate { pub block_args: common_args::BlockArgs, #[clap(flatten)] pub param_arg: common_args::ParamArg, + /// Key pair cryptographic algorithm + #[clap(subcommand)] + pub algorithm: Option, } /// Attenuate an existing biscuit by adding a new third-party block @@ -154,6 +170,9 @@ pub struct Inspect { /// Output the snapshot raw bytes directly, with no base64 encoding #[clap(long, requires("dump-snapshot-to"))] pub dump_raw_snapshot: bool, + /// Key pair cryptographic algorithm + #[clap(subcommand)] + pub algorithm: Option, } /// Inspect a snapshot @@ -216,6 +235,9 @@ pub struct GenerateThirdPartyBlock { pub block_args: common_args::BlockArgs, #[clap(flatten)] pub param_arg: common_args::ParamArg, + /// Key pair cryptographic algorithm + #[clap(subcommand)] + pub algorithm: Algorithm, } /// Seal a token, preventing further attenuation diff --git a/src/input.rs b/src/input.rs index 7bfdb92..f63abfc 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,8 +1,8 @@ use anyhow::Result; use atty::Stream; use biscuit_auth::{ - builder::{BiscuitBuilder, BlockBuilder, Rule, Term}, - Authorizer, ThirdPartyRequest, UnverifiedBiscuit, {PrivateKey, PublicKey}, + builder::{Algorithm, BiscuitBuilder, BlockBuilder, Rule, Term}, + Authorizer, PrivateKey, PublicKey, ThirdPartyRequest, UnverifiedBiscuit, }; use chrono::{DateTime, Duration, Utc}; use parse_duration as duration_parser; @@ -230,7 +230,7 @@ pub fn read_authorizer_from( Ok(()) } -pub fn read_private_key_from(from: &KeyBytes) -> Result { +pub fn read_private_key_from(from: &KeyBytes, algorithm: Algorithm) -> Result { let bytes = match from { KeyBytes::FromStdin(KeyFormat::RawBytes) => read_stdin_bytes()?, KeyBytes::FromStdin(KeyFormat::HexKey) => { @@ -246,11 +246,11 @@ pub fn read_private_key_from(from: &KeyBytes) -> Result { )?, KeyBytes::HexString(str) => hex::decode(str)?, }; - PrivateKey::from_bytes(&bytes) + PrivateKey::from_bytes(&bytes, algorithm) .map_err(|e| ParseError("private key".to_string(), format!("{}", &e)).into()) } -pub fn read_public_key_from(from: &KeyBytes) -> Result { +pub fn read_public_key_from(from: &KeyBytes, algorithm: Algorithm) -> Result { let bytes = match from { KeyBytes::FromStdin(KeyFormat::RawBytes) => read_stdin_bytes()?, KeyBytes::FromStdin(KeyFormat::HexKey) => { @@ -266,7 +266,7 @@ pub fn read_public_key_from(from: &KeyBytes) -> Result { )?, KeyBytes::HexString(str) => hex::decode(str)?, }; - PublicKey::from_bytes(&bytes) + PublicKey::from_bytes(&bytes, algorithm) .map_err(|e| ParseError("public key".to_string(), format!("{}", &e)).into()) } @@ -418,13 +418,19 @@ pub fn parse_param(kv: &str) -> Result { match annotation { Some("pubkey") => { - let hex_key = value.strip_prefix("ed25519/").ok_or_else(|| Error::new( - ErrorKind::Other, - "Unsupported public key type. Only hex-encoded ed25519 public keys are supported. They must start with `ed25519/`.", - ))?; + let (algorithm, hex_key)= if let Some(hex_key) = value.strip_prefix("ed25519/") { + (Algorithm::Ed25519, hex_key) + } else if let Some(hex_key) = value.strip_prefix("secp256r1/") { + (Algorithm::Secp256r1, hex_key) + } else { + return Err(Error::new( + ErrorKind::Other, + "Unsupported public key type. Only hex-encoded ed25519 or secp256r1 public keys are supported. They must start with `ed25519/` or `secp256r1/`", + )); + }; let bytes = hex::decode(hex_key).map_err(|e| Error::new(ErrorKind::Other, format!("{}", &e))); - let pubkey = PublicKey::from_bytes(&bytes?) + let pubkey = PublicKey::from_bytes(&bytes?, algorithm) .map_err(|e| Error::new(ErrorKind::Other, format!("{}", &e)))?; Ok(Param::PublicKey(name.to_string(), pubkey)) }, diff --git a/src/inspect.rs b/src/inspect.rs index 591db70..cace795 100644 --- a/src/inspect.rs +++ b/src/inspect.rs @@ -1,6 +1,6 @@ use anyhow::Result; use biscuit_auth::{ - builder::{Fact, Rule}, + builder::{Algorithm, Fact, Rule}, datalog::RunLimits, error::{FailedCheck, Logic, MatchedPolicy, RunLimit, Token}, Authorizer, UnverifiedBiscuit, @@ -11,9 +11,8 @@ use serde_json::json; use std::{fmt::Display, fs}; use std::{path::PathBuf, time::Duration}; -use crate::cli::*; -use crate::errors::CliError::*; use crate::input::*; +use crate::{cli, errors::CliError::*, Inspect, InspectSnapshot}; #[derive(Serialize)] struct TokenBlock { @@ -413,7 +412,13 @@ pub fn handle_inspect_inner(inspect: &Inspect) -> Result { let query_result; if let Some(key_from) = public_key_from { - let key = read_public_key_from(&key_from)?; + let algorithm = match inspect.algorithm { + Some(cli::Algorithm::Ed25519) => Algorithm::Ed25519, + Some(cli::Algorithm::Secp256r1) => Algorithm::Secp256r1, + None => Algorithm::Ed25519, + }; + + let key = read_public_key_from(&key_from, algorithm)?; let sig_result = biscuit.check_signature(|_| key); signatures_check = Some(sig_result.is_ok()); diff --git a/src/main.rs b/src/main.rs index 51fd951..ea34cd6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,8 @@ use anyhow::Result; use biscuit_auth::{ - builder::BlockBuilder, + builder::{Algorithm, BlockBuilder}, builder_ext::BuilderExt, - Biscuit, {KeyPair, PrivateKey}, + Biscuit, KeyPair, PrivateKey, }; use clap::Parser; use std::io; @@ -61,8 +61,13 @@ fn handle_keypair(key_pair_cmd: &KeyPairCmd) -> Result<()> { _ => unreachable!(), }; + let algorithm = match key_pair_cmd.algorithm { + cli::Algorithm::Ed25519 => Algorithm::Ed25519, + cli::Algorithm::Secp256r1 => Algorithm::Secp256r1, + }; + let private_key: Option = if let Some(f) = private_key_from { - Some(read_private_key_from(f)?) + Some(read_private_key_from(f, algorithm.clone())?) } else { None }; @@ -70,7 +75,7 @@ fn handle_keypair(key_pair_cmd: &KeyPairCmd) -> Result<()> { let key_pair = if let Some(private) = private_key { KeyPair::from(&private) } else { - KeyPair::new() + KeyPair::new(algorithm) }; match ( @@ -116,17 +121,25 @@ fn handle_generate(generate: &Generate) -> Result<()> { None => DatalogInput::FromEditor, }; - let private_key: Result = read_private_key_from(&match ( - &generate.private_key, - &generate.private_key_file, - &generate.raw_private_key, - ) { - (Some(hex_string), None, false) => KeyBytes::HexString(hex_string.to_owned()), - (None, Some(file), true) => KeyBytes::FromFile(KeyFormat::RawBytes, file.to_path_buf()), - (None, Some(file), false) => KeyBytes::FromFile(KeyFormat::HexKey, file.to_path_buf()), - // the other combinations are prevented by clap - _ => unreachable!(), - }); + let algorithm = match generate.algorithm { + cli::Algorithm::Ed25519 => Algorithm::Ed25519, + cli::Algorithm::Secp256r1 => Algorithm::Secp256r1, + }; + + let private_key: Result = read_private_key_from( + &match ( + &generate.private_key, + &generate.private_key_file, + &generate.raw_private_key, + ) { + (Some(hex_string), None, false) => KeyBytes::HexString(hex_string.to_owned()), + (None, Some(file), true) => KeyBytes::FromFile(KeyFormat::RawBytes, file.to_path_buf()), + (None, Some(file), false) => KeyBytes::FromFile(KeyFormat::HexKey, file.to_path_buf()), + // the other combinations are prevented by clap + _ => unreachable!(), + }, + algorithm, + ); let root = KeyPair::from(&private_key?); let mut builder = Biscuit::builder(); @@ -199,7 +212,15 @@ fn handle_attenuate(attenuate: &Attenuate) -> Result<()> { block_builder.check_expiration_date(ttl.to_datetime().into()); } - let new_biscuit = biscuit.append(block_builder)?; + let algorithm = match attenuate.algorithm { + Some(cli::Algorithm::Ed25519) => Algorithm::Ed25519, + Some(cli::Algorithm::Secp256r1) => Algorithm::Secp256r1, + None => Algorithm::Ed25519, + }; + + let keypair = KeyPair::new(algorithm); + + let new_biscuit = biscuit.append_with_keypair(&keypair, block_builder)?; let encoded = if attenuate.raw_output { new_biscuit.to_vec()? } else { @@ -267,19 +288,27 @@ fn handle_generate_third_party_block( _ => unreachable!(), }; + let algorithm = match generate_third_party_block.algorithm { + cli::Algorithm::Ed25519 => Algorithm::Ed25519, + cli::Algorithm::Secp256r1 => Algorithm::Secp256r1, + }; + ensure_no_input_conflict(&block_from, &request_from)?; - let private_key: Result = read_private_key_from(&match ( - &generate_third_party_block.private_key, - &generate_third_party_block.private_key_file, - &generate_third_party_block.raw_private_key, - ) { - (Some(hex_string), None, false) => KeyBytes::HexString(hex_string.to_owned()), - (None, Some(file), true) => KeyBytes::FromFile(KeyFormat::RawBytes, file.to_path_buf()), - (None, Some(file), false) => KeyBytes::FromFile(KeyFormat::HexKey, file.to_path_buf()), - // the other combinations are prevented by clap - _ => unreachable!(), - }); + let private_key: Result = read_private_key_from( + &match ( + &generate_third_party_block.private_key, + &generate_third_party_block.private_key_file, + &generate_third_party_block.raw_private_key, + ) { + (Some(hex_string), None, false) => KeyBytes::HexString(hex_string.to_owned()), + (None, Some(file), true) => KeyBytes::FromFile(KeyFormat::RawBytes, file.to_path_buf()), + (None, Some(file), false) => KeyBytes::FromFile(KeyFormat::HexKey, file.to_path_buf()), + // the other combinations are prevented by clap + _ => unreachable!(), + }, + algorithm, + ); let request = read_request_from(&request_from)?;