biscuit_auth/crypto/
mod.rs

1//! cryptographic operations
2//!
3//! Biscuit tokens are based on a chain of Ed25519 signatures.
4//! This provides the fundamental operation for offline delegation: from a message
5//! and a valid signature, it is possible to add a new message and produce a valid
6//! signature for the whole.
7//!
8//! The implementation is based on [ed25519_dalek](https://github.com/dalek-cryptography/ed25519-dalek).
9#![allow(non_snake_case)]
10use crate::builder::Algorithm;
11use crate::format::schema;
12use crate::format::ThirdPartyVerificationMode;
13
14use super::error;
15mod ed25519;
16mod p256;
17
18use nom::Finish;
19use rand_core::{CryptoRng, RngCore};
20use std::fmt;
21use std::hash::Hash;
22use std::str::FromStr;
23
24/// pair of cryptographic keys used to sign a token's block
25#[derive(Debug, PartialEq)]
26pub enum KeyPair {
27    Ed25519(ed25519::KeyPair),
28    P256(p256::KeyPair),
29}
30
31impl KeyPair {
32    /// Create a new ed25519 keypair with the default OS RNG
33    pub fn new() -> Self {
34        Self::new_with_rng(Algorithm::Ed25519, &mut rand::rngs::OsRng)
35    }
36
37    /// Create a new keypair with a chosen algorithm and the default OS RNG
38    pub fn new_with_algorithm(algorithm: Algorithm) -> Self {
39        Self::new_with_rng(algorithm, &mut rand::rngs::OsRng)
40    }
41
42    pub fn new_with_rng<T: RngCore + CryptoRng>(algorithm: Algorithm, rng: &mut T) -> Self {
43        match algorithm {
44            Algorithm::Ed25519 => KeyPair::Ed25519(ed25519::KeyPair::new_with_rng(rng)),
45            Algorithm::Secp256r1 => KeyPair::P256(p256::KeyPair::new_with_rng(rng)),
46        }
47    }
48
49    pub fn from(key: &PrivateKey) -> Self {
50        match key {
51            PrivateKey::Ed25519(key) => KeyPair::Ed25519(ed25519::KeyPair::from(key)),
52            PrivateKey::P256(key) => KeyPair::P256(p256::KeyPair::from(key)),
53        }
54    }
55
56    /// deserializes from a byte array
57    pub fn from_bytes(
58        bytes: &[u8],
59        algorithm: schema::public_key::Algorithm,
60    ) -> Result<Self, error::Format> {
61        match algorithm {
62            schema::public_key::Algorithm::Ed25519 => {
63                Ok(KeyPair::Ed25519(ed25519::KeyPair::from_bytes(bytes)?))
64            }
65            schema::public_key::Algorithm::Secp256r1 => {
66                Ok(KeyPair::P256(p256::KeyPair::from_bytes(bytes)?))
67            }
68        }
69    }
70
71    pub fn sign(&self, data: &[u8]) -> Result<Signature, error::Format> {
72        match self {
73            KeyPair::Ed25519(key) => key.sign(data),
74            KeyPair::P256(key) => key.sign(data),
75        }
76    }
77
78    #[cfg(feature = "pem")]
79    pub fn from_private_key_der_with_algorithm(
80        bytes: &[u8],
81        algorithm: Algorithm,
82    ) -> Result<Self, error::Format> {
83        match algorithm {
84            Algorithm::Ed25519 => Ok(KeyPair::Ed25519(ed25519::KeyPair::from_private_key_der(
85                bytes,
86            )?)),
87            Algorithm::Secp256r1 => Ok(KeyPair::P256(p256::KeyPair::from_private_key_der(bytes)?)),
88        }
89    }
90
91    #[cfg(feature = "pem")]
92    pub fn from_private_key_der(bytes: &[u8]) -> Result<Self, error::Format> {
93        parse_any_algorithm(bytes, Self::from_private_key_der_with_algorithm)
94    }
95
96    #[cfg(feature = "pem")]
97    pub fn from_private_key_pem_with_algorithm(
98        str: &str,
99        algorithm: Algorithm,
100    ) -> Result<Self, error::Format> {
101        match algorithm {
102            Algorithm::Ed25519 => Ok(KeyPair::Ed25519(ed25519::KeyPair::from_private_key_pem(
103                str,
104            )?)),
105            Algorithm::Secp256r1 => Ok(KeyPair::P256(p256::KeyPair::from_private_key_pem(str)?)),
106        }
107    }
108
109    #[cfg(feature = "pem")]
110    pub fn from_private_key_pem(str: &str) -> Result<Self, error::Format> {
111        parse_any_algorithm(str, Self::from_private_key_pem_with_algorithm)
112    }
113
114    #[cfg(feature = "pem")]
115    pub fn to_private_key_der(&self) -> Result<zeroize::Zeroizing<Vec<u8>>, error::Format> {
116        match self {
117            KeyPair::Ed25519(key) => key.to_private_key_der(),
118            KeyPair::P256(key) => key.to_private_key_der(),
119        }
120    }
121
122    #[cfg(feature = "pem")]
123    pub fn to_private_key_pem(&self) -> Result<zeroize::Zeroizing<String>, error::Format> {
124        match self {
125            KeyPair::Ed25519(key) => key.to_private_key_pem(),
126            KeyPair::P256(key) => key.to_private_key_pem(),
127        }
128    }
129
130    pub fn private(&self) -> PrivateKey {
131        match self {
132            KeyPair::Ed25519(key) => PrivateKey::Ed25519(key.private()),
133            KeyPair::P256(key) => PrivateKey::P256(key.private()),
134        }
135    }
136
137    pub fn public(&self) -> PublicKey {
138        match self {
139            KeyPair::Ed25519(key) => PublicKey::Ed25519(key.public()),
140            KeyPair::P256(key) => PublicKey::P256(key.public()),
141        }
142    }
143
144    pub fn algorithm(&self) -> crate::format::schema::public_key::Algorithm {
145        match self {
146            KeyPair::Ed25519(_) => crate::format::schema::public_key::Algorithm::Ed25519,
147            KeyPair::P256(_) => crate::format::schema::public_key::Algorithm::Secp256r1,
148        }
149    }
150}
151
152impl std::default::Default for KeyPair {
153    fn default() -> Self {
154        Self::new()
155    }
156}
157
158/// the private part of a [KeyPair]
159#[derive(Debug, Clone, PartialEq)]
160pub enum PrivateKey {
161    Ed25519(ed25519::PrivateKey),
162    P256(p256::PrivateKey),
163}
164
165impl FromStr for PrivateKey {
166    type Err = error::Format;
167    fn from_str(s: &str) -> Result<Self, Self::Err> {
168        match s.split_once('/') {
169            Some(("ed25519-private", bytes)) => Self::from_bytes_hex(bytes, Algorithm::Ed25519),
170            Some(("secp256r1-private", bytes)) => Self::from_bytes_hex(bytes, Algorithm::Secp256r1),
171            Some((alg, _)) => Err(error::Format::InvalidKey(format!(
172                "Unsupported key algorithm {alg}"
173            ))),
174            None => Err(error::Format::InvalidKey(
175                "Missing key algorithm".to_string(),
176            )),
177        }
178    }
179}
180
181impl PrivateKey {
182    /// serializes to a byte array
183    pub fn to_bytes(&self) -> zeroize::Zeroizing<Vec<u8>> {
184        match self {
185            PrivateKey::Ed25519(key) => zeroize::Zeroizing::new(key.to_bytes()),
186            PrivateKey::P256(key) => key.to_bytes(),
187        }
188    }
189
190    /// serializes to an hex-encoded string
191    pub fn to_bytes_hex(&self) -> String {
192        hex::encode(self.to_bytes())
193    }
194
195    /// serializes to an hex-encoded string, prefixed with the key algorithm
196    pub fn to_prefixed_string(&self) -> String {
197        let algorithm = match self.algorithm() {
198            schema::public_key::Algorithm::Ed25519 => "ed25519-private",
199            schema::public_key::Algorithm::Secp256r1 => "secp256r1-private",
200        };
201        format!("{algorithm}/{}", self.to_bytes_hex())
202    }
203
204    /// deserializes from a byte array
205    pub fn from_bytes(bytes: &[u8], algorithm: Algorithm) -> Result<Self, error::Format> {
206        match algorithm {
207            Algorithm::Ed25519 => Ok(PrivateKey::Ed25519(ed25519::PrivateKey::from_bytes(bytes)?)),
208            Algorithm::Secp256r1 => Ok(PrivateKey::P256(p256::PrivateKey::from_bytes(bytes)?)),
209        }
210    }
211
212    /// deserializes from an hex-encoded string
213    pub fn from_bytes_hex(str: &str, algorithm: Algorithm) -> Result<Self, error::Format> {
214        let bytes = hex::decode(str).map_err(|e| error::Format::InvalidKey(e.to_string()))?;
215        Self::from_bytes(&bytes, algorithm)
216    }
217
218    #[cfg(feature = "pem")]
219    pub fn from_der_with_algorithm(
220        bytes: &[u8],
221        algorithm: Algorithm,
222    ) -> Result<Self, error::Format> {
223        match algorithm {
224            Algorithm::Ed25519 => Ok(PrivateKey::Ed25519(ed25519::PrivateKey::from_der(bytes)?)),
225            Algorithm::Secp256r1 => Ok(PrivateKey::P256(p256::PrivateKey::from_der(bytes)?)),
226        }
227    }
228
229    #[cfg(feature = "pem")]
230    pub fn from_der(bytes: &[u8]) -> Result<Self, error::Format> {
231        parse_any_algorithm(bytes, Self::from_der_with_algorithm)
232    }
233
234    #[cfg(feature = "pem")]
235    pub fn from_pem_with_algorithm(str: &str, algorithm: Algorithm) -> Result<Self, error::Format> {
236        match algorithm {
237            Algorithm::Ed25519 => Ok(PrivateKey::Ed25519(ed25519::PrivateKey::from_pem(str)?)),
238            Algorithm::Secp256r1 => Ok(PrivateKey::P256(p256::PrivateKey::from_pem(str)?)),
239        }
240    }
241
242    #[cfg(feature = "pem")]
243    pub fn from_pem(str: &str) -> Result<Self, error::Format> {
244        parse_any_algorithm(str, Self::from_pem_with_algorithm)
245    }
246
247    #[cfg(feature = "pem")]
248    pub fn to_der(&self) -> Result<zeroize::Zeroizing<Vec<u8>>, error::Format> {
249        match self {
250            PrivateKey::Ed25519(key) => key.to_der(),
251            PrivateKey::P256(key) => key.to_der(),
252        }
253    }
254
255    #[cfg(feature = "pem")]
256    pub fn to_pem(&self) -> Result<zeroize::Zeroizing<String>, error::Format> {
257        match self {
258            PrivateKey::Ed25519(key) => key.to_pem(),
259            PrivateKey::P256(key) => key.to_pem(),
260        }
261    }
262
263    /// returns the matching public key
264    pub fn public(&self) -> PublicKey {
265        match self {
266            PrivateKey::Ed25519(key) => PublicKey::Ed25519(key.public()),
267            PrivateKey::P256(key) => PublicKey::P256(key.public()),
268        }
269    }
270
271    pub fn algorithm(&self) -> crate::format::schema::public_key::Algorithm {
272        match self {
273            PrivateKey::Ed25519(_) => crate::format::schema::public_key::Algorithm::Ed25519,
274            PrivateKey::P256(_) => crate::format::schema::public_key::Algorithm::Secp256r1,
275        }
276    }
277}
278
279/// the public part of a [KeyPair]
280#[derive(Debug, Clone, Copy, PartialEq, Hash, Eq)]
281pub enum PublicKey {
282    Ed25519(ed25519::PublicKey),
283    P256(p256::PublicKey),
284}
285
286impl PublicKey {
287    /// serializes to a byte array
288    pub fn to_bytes(&self) -> Vec<u8> {
289        match self {
290            PublicKey::Ed25519(key) => key.to_bytes().into(),
291            PublicKey::P256(key) => key.to_bytes(),
292        }
293    }
294
295    /// serializes to an hex-encoded string
296    pub fn to_bytes_hex(&self) -> String {
297        hex::encode(self.to_bytes())
298    }
299
300    /// deserializes from a byte array
301    pub fn from_bytes(bytes: &[u8], algorithm: Algorithm) -> Result<Self, error::Format> {
302        match algorithm {
303            Algorithm::Ed25519 => Ok(PublicKey::Ed25519(ed25519::PublicKey::from_bytes(bytes)?)),
304            Algorithm::Secp256r1 => Ok(PublicKey::P256(p256::PublicKey::from_bytes(bytes)?)),
305        }
306    }
307
308    /// deserializes from an hex-encoded string
309    pub fn from_bytes_hex(str: &str, algorithm: Algorithm) -> Result<Self, error::Format> {
310        let bytes = hex::decode(str).map_err(|e| error::Format::InvalidKey(e.to_string()))?;
311        Self::from_bytes(&bytes, algorithm)
312    }
313
314    pub fn from_proto(key: &schema::PublicKey) -> Result<Self, error::Format> {
315        if key.algorithm == schema::public_key::Algorithm::Ed25519 as i32 {
316            Ok(PublicKey::Ed25519(ed25519::PublicKey::from_bytes(
317                &key.key,
318            )?))
319        } else if key.algorithm == schema::public_key::Algorithm::Secp256r1 as i32 {
320            Ok(PublicKey::P256(p256::PublicKey::from_bytes(&key.key)?))
321        } else {
322            Err(error::Format::DeserializationError(format!(
323                "deserialization error: unexpected key algorithm {}",
324                key.algorithm
325            )))
326        }
327    }
328
329    pub fn to_proto(&self) -> schema::PublicKey {
330        schema::PublicKey {
331            algorithm: self.algorithm() as i32,
332            key: self.to_bytes(),
333        }
334    }
335
336    #[cfg(feature = "pem")]
337    pub fn from_der_with_algorithm(
338        bytes: &[u8],
339        algorithm: Algorithm,
340    ) -> Result<Self, error::Format> {
341        match algorithm {
342            Algorithm::Ed25519 => Ok(PublicKey::Ed25519(ed25519::PublicKey::from_der(bytes)?)),
343            Algorithm::Secp256r1 => Ok(PublicKey::P256(p256::PublicKey::from_der(bytes)?)),
344        }
345    }
346
347    #[cfg(feature = "pem")]
348    pub fn from_der(bytes: &[u8]) -> Result<Self, error::Format> {
349        parse_any_algorithm(bytes, Self::from_der_with_algorithm)
350    }
351
352    #[cfg(feature = "pem")]
353    pub fn from_pem_with_algorithm(str: &str, algorithm: Algorithm) -> Result<Self, error::Format> {
354        match algorithm {
355            Algorithm::Ed25519 => Ok(PublicKey::Ed25519(ed25519::PublicKey::from_pem(str)?)),
356            Algorithm::Secp256r1 => Ok(PublicKey::P256(p256::PublicKey::from_pem(str)?)),
357        }
358    }
359
360    #[cfg(feature = "pem")]
361    pub fn from_pem(str: &str) -> Result<Self, error::Format> {
362        parse_any_algorithm(str, Self::from_pem_with_algorithm)
363    }
364
365    #[cfg(feature = "pem")]
366    pub fn to_der(&self) -> Result<Vec<u8>, error::Format> {
367        match self {
368            PublicKey::Ed25519(key) => key.to_der(),
369            PublicKey::P256(key) => key.to_der(),
370        }
371    }
372
373    #[cfg(feature = "pem")]
374    pub fn to_pem(&self) -> Result<String, error::Format> {
375        match self {
376            PublicKey::Ed25519(key) => key.to_pem(),
377            PublicKey::P256(key) => key.to_pem(),
378        }
379    }
380
381    pub fn verify_signature(
382        &self,
383        data: &[u8],
384        signature: &Signature,
385    ) -> Result<(), error::Format> {
386        match self {
387            PublicKey::Ed25519(key) => key.verify_signature(data, signature),
388            PublicKey::P256(key) => key.verify_signature(data, signature),
389        }
390    }
391
392    pub fn algorithm(&self) -> crate::format::schema::public_key::Algorithm {
393        match self {
394            PublicKey::Ed25519(_) => crate::format::schema::public_key::Algorithm::Ed25519,
395            PublicKey::P256(_) => crate::format::schema::public_key::Algorithm::Secp256r1,
396        }
397    }
398
399    pub fn algorithm_string(&self) -> &str {
400        match self {
401            PublicKey::Ed25519(_) => "ed25519",
402            PublicKey::P256(_) => "secp256r1",
403        }
404    }
405
406    pub(crate) fn write(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
407        match self {
408            PublicKey::Ed25519(key) => key.write(f),
409            PublicKey::P256(key) => key.write(f),
410        }
411    }
412
413    pub fn print(&self) -> String {
414        match self {
415            PublicKey::Ed25519(key) => key.print(),
416            PublicKey::P256(key) => key.print(),
417        }
418    }
419}
420
421impl fmt::Display for PublicKey {
422    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
423        self.write(f)
424    }
425}
426
427#[derive(Clone, Debug)]
428pub struct Signature(pub(crate) Vec<u8>);
429
430impl Signature {
431    pub fn from_bytes(data: &[u8]) -> Result<Self, error::Format> {
432        Ok(Signature(data.to_owned()))
433    }
434
435    pub(crate) fn from_vec(data: Vec<u8>) -> Self {
436        Signature(data)
437    }
438
439    pub fn to_bytes(&self) -> &[u8] {
440        &self.0[..]
441    }
442}
443
444impl FromStr for PublicKey {
445    type Err = error::Format;
446
447    fn from_str(s: &str) -> Result<Self, Self::Err> {
448        let (_, public_key) = biscuit_parser::parser::public_key(s)
449            .finish()
450            .map_err(|e| error::Format::InvalidKey(e.to_string()))?;
451        PublicKey::from_bytes(
452            &public_key.key,
453            match public_key.algorithm {
454                biscuit_parser::builder::Algorithm::Ed25519 => Algorithm::Ed25519,
455                biscuit_parser::builder::Algorithm::Secp256r1 => Algorithm::Secp256r1,
456            },
457        )
458    }
459}
460
461#[derive(Clone, Debug)]
462pub struct Block {
463    pub(crate) data: Vec<u8>,
464    pub(crate) next_key: PublicKey,
465    pub signature: Signature,
466    pub external_signature: Option<ExternalSignature>,
467    pub version: u32,
468}
469
470#[derive(Clone, Debug)]
471pub struct ExternalSignature {
472    pub(crate) public_key: PublicKey,
473    pub(crate) signature: Signature,
474}
475
476#[derive(Clone, Debug)]
477pub enum TokenNext {
478    Secret(PrivateKey),
479    Seal(Signature),
480}
481
482pub fn sign_authority_block(
483    keypair: &KeyPair,
484    next_key: &KeyPair,
485    message: &[u8],
486    version: u32,
487) -> Result<Signature, error::Token> {
488    let to_sign = match version {
489        0 => generate_authority_block_signature_payload_v0(&message, &next_key.public()),
490        1 => generate_authority_block_signature_payload_v1(&message, &next_key.public(), version),
491        _ => {
492            return Err(error::Format::DeserializationError(format!(
493                "unsupported block version: {}",
494                version
495            ))
496            .into())
497        }
498    };
499
500    let signature = keypair.sign(&to_sign)?;
501
502    Ok(Signature(signature.to_bytes().to_vec()))
503}
504
505pub fn sign_block(
506    keypair: &KeyPair,
507    next_key: &KeyPair,
508    message: &[u8],
509    external_signature: Option<&ExternalSignature>,
510    previous_signature: &Signature,
511    version: u32,
512) -> Result<Signature, error::Token> {
513    let to_sign = match version {
514        0 => generate_block_signature_payload_v0(&message, &next_key.public(), external_signature),
515        1 => generate_block_signature_payload_v1(
516            &message,
517            &next_key.public(),
518            external_signature,
519            previous_signature,
520            version,
521        ),
522        _ => {
523            return Err(error::Format::DeserializationError(format!(
524                "unsupported block version: {}",
525                version
526            ))
527            .into())
528        }
529    };
530
531    Ok(keypair.sign(&to_sign)?)
532}
533
534pub fn verify_authority_block_signature(
535    block: &Block,
536    public_key: &PublicKey,
537) -> Result<(), error::Format> {
538    let to_verify = match block.version {
539        0 => generate_block_signature_payload_v0(
540            &block.data,
541            &block.next_key,
542            block.external_signature.as_ref(),
543        ),
544        1 => generate_authority_block_signature_payload_v1(
545            &block.data,
546            &block.next_key,
547            block.version,
548        ),
549        _ => {
550            return Err(error::Format::DeserializationError(format!(
551                "unsupported block version: {}",
552                block.version
553            )))
554        }
555    };
556
557    public_key.verify_signature(&to_verify, &block.signature)
558}
559
560pub fn verify_block_signature(
561    block: &Block,
562    public_key: &PublicKey,
563    previous_signature: &Signature,
564    verification_mode: ThirdPartyVerificationMode,
565) -> Result<(), error::Format> {
566    let to_verify = match block.version {
567        0 => generate_block_signature_payload_v0(
568            &block.data,
569            &block.next_key,
570            block.external_signature.as_ref(),
571        ),
572        1 => generate_block_signature_payload_v1(
573            &block.data,
574            &block.next_key,
575            block.external_signature.as_ref(),
576            previous_signature,
577            block.version,
578        ),
579        _ => {
580            return Err(error::Format::DeserializationError(format!(
581                "unsupported block version: {}",
582                block.version
583            )))
584        }
585    };
586
587    public_key.verify_signature(&to_verify, &block.signature)?;
588
589    if let Some(external_signature) = block.external_signature.as_ref() {
590        verify_external_signature(
591            &block.data,
592            public_key,
593            previous_signature,
594            external_signature,
595            block.version,
596            verification_mode,
597        )?;
598    }
599
600    Ok(())
601}
602
603pub fn verify_external_signature(
604    payload: &[u8],
605    public_key: &PublicKey,
606    previous_signature: &Signature,
607    external_signature: &ExternalSignature,
608    version: u32,
609    verification_mode: ThirdPartyVerificationMode,
610) -> Result<(), error::Format> {
611    let to_verify = match verification_mode {
612        ThirdPartyVerificationMode::UnsafeLegacy => {
613            generate_external_signature_payload_v0(payload, public_key)
614        }
615        ThirdPartyVerificationMode::PreviousSignatureHashing => {
616            generate_external_signature_payload_v1(payload, previous_signature.to_bytes(), version)
617        }
618    };
619
620    external_signature
621        .public_key
622        .verify_signature(&to_verify, &external_signature.signature)
623}
624
625pub(crate) fn generate_authority_block_signature_payload_v0(
626    payload: &[u8],
627    next_key: &PublicKey,
628) -> Vec<u8> {
629    let mut to_verify = payload.to_vec();
630
631    to_verify.extend(&(next_key.algorithm() as i32).to_le_bytes());
632    to_verify.extend(next_key.to_bytes());
633    to_verify
634}
635
636pub(crate) fn generate_block_signature_payload_v0(
637    payload: &[u8],
638    next_key: &PublicKey,
639    external_signature: Option<&ExternalSignature>,
640) -> Vec<u8> {
641    let mut to_verify = payload.to_vec();
642
643    if let Some(signature) = external_signature.as_ref() {
644        to_verify.extend_from_slice(&signature.signature.to_bytes());
645    }
646    to_verify.extend(&(next_key.algorithm() as i32).to_le_bytes());
647    to_verify.extend(next_key.to_bytes());
648    to_verify
649}
650
651pub(crate) fn generate_authority_block_signature_payload_v1(
652    payload: &[u8],
653    next_key: &PublicKey,
654    version: u32,
655) -> Vec<u8> {
656    let mut to_verify = b"\0BLOCK\0\0VERSION\0".to_vec();
657    to_verify.extend(version.to_le_bytes());
658
659    to_verify.extend(b"\0PAYLOAD\0".to_vec());
660    to_verify.extend(payload.to_vec());
661
662    to_verify.extend(b"\0ALGORITHM\0".to_vec());
663    to_verify.extend(&(next_key.algorithm() as i32).to_le_bytes());
664
665    to_verify.extend(b"\0NEXTKEY\0".to_vec());
666    to_verify.extend(&next_key.to_bytes());
667
668    to_verify
669}
670
671pub(crate) fn generate_block_signature_payload_v1(
672    payload: &[u8],
673    next_key: &PublicKey,
674    external_signature: Option<&ExternalSignature>,
675    previous_signature: &Signature,
676    version: u32,
677) -> Vec<u8> {
678    let mut to_verify = b"\0BLOCK\0\0VERSION\0".to_vec();
679    to_verify.extend(version.to_le_bytes());
680
681    to_verify.extend(b"\0PAYLOAD\0".to_vec());
682    to_verify.extend(payload.to_vec());
683
684    to_verify.extend(b"\0ALGORITHM\0".to_vec());
685    to_verify.extend(&(next_key.algorithm() as i32).to_le_bytes());
686
687    to_verify.extend(b"\0NEXTKEY\0".to_vec());
688    to_verify.extend(&next_key.to_bytes());
689
690    to_verify.extend(b"\0PREVSIG\0".to_vec());
691    to_verify.extend(previous_signature.to_bytes());
692
693    if let Some(signature) = external_signature.as_ref() {
694        to_verify.extend(b"\0EXTERNALSIG\0".to_vec());
695        to_verify.extend_from_slice(&signature.signature.to_bytes());
696    }
697
698    to_verify
699}
700
701fn generate_external_signature_payload_v0(payload: &[u8], previous_key: &PublicKey) -> Vec<u8> {
702    let mut to_verify = payload.to_vec();
703    to_verify.extend(&(previous_key.algorithm() as i32).to_le_bytes());
704    to_verify.extend(&previous_key.to_bytes());
705
706    to_verify
707}
708
709pub(crate) fn generate_external_signature_payload_v1(
710    payload: &[u8],
711    previous_signature: &[u8],
712    version: u32,
713) -> Vec<u8> {
714    let mut to_verify = b"\0EXTERNAL\0\0VERSION\0".to_vec();
715    to_verify.extend(version.to_le_bytes());
716
717    to_verify.extend(b"\0PAYLOAD\0".to_vec());
718    to_verify.extend(payload.to_vec());
719
720    to_verify.extend(b"\0PREVSIG\0".to_vec());
721    to_verify.extend(previous_signature);
722    to_verify
723}
724
725pub(crate) fn generate_seal_signature_payload_v0(block: &Block) -> Vec<u8> {
726    let mut to_verify = block.data.to_vec();
727    to_verify.extend(&(block.next_key.algorithm() as i32).to_le_bytes());
728    to_verify.extend(&block.next_key.to_bytes());
729    to_verify.extend(block.signature.to_bytes());
730    to_verify
731}
732
733impl TokenNext {
734    pub fn keypair(&self) -> Result<KeyPair, error::Token> {
735        match &self {
736            TokenNext::Seal(_) => Err(error::Token::AlreadySealed),
737            TokenNext::Secret(private) => Ok(KeyPair::from(private)),
738        }
739    }
740
741    pub fn is_sealed(&self) -> bool {
742        match &self {
743            TokenNext::Seal(_) => true,
744            TokenNext::Secret(_) => false,
745        }
746    }
747}
748
749fn parse_any_algorithm<I: Copy, O>(
750    i: I,
751    parse: fn(i: I, alg: Algorithm) -> Result<O, error::Format>,
752) -> Result<O, error::Format> {
753    for algorithm in Algorithm::values() {
754        let res = parse(i, *algorithm);
755        if res.is_ok() {
756            return res;
757        }
758    }
759
760    Err(error::Format::InvalidKey(
761        "The key could not be parsed with any algorithm".to_string(),
762    ))
763}
764
765#[cfg(test)]
766mod tests {
767    use super::*;
768
769    #[test]
770    fn roundtrip_from_string() {
771        let ed_root = KeyPair::new_with_algorithm(Algorithm::Ed25519);
772        assert_eq!(
773            ed_root.public(),
774            ed_root.public().to_string().parse().unwrap()
775        );
776        assert_eq!(
777            ed_root.private().to_bytes(),
778            ed_root
779                .private()
780                .to_prefixed_string()
781                .parse::<PrivateKey>()
782                .unwrap()
783                .to_bytes()
784        );
785        let p256_root = KeyPair::new_with_algorithm(Algorithm::Secp256r1);
786        assert_eq!(
787            p256_root.public(),
788            p256_root.public().to_string().parse().unwrap()
789        );
790        assert_eq!(
791            p256_root.private().to_bytes(),
792            p256_root
793                .private()
794                .to_prefixed_string()
795                .parse::<PrivateKey>()
796                .unwrap()
797                .to_bytes()
798        )
799    }
800
801    #[test]
802    fn parsing_ed25519() {
803        let private_ed = PrivateKey::from_bytes_hex(
804            "bf6065d753c4a2c679dcd28828ac625c6c713efee2d4dd4b9c9ff3c9a2b2f966",
805            Algorithm::Ed25519,
806        )
807        .unwrap();
808
809        assert_eq!(
810            private_ed.to_prefixed_string(),
811            "ed25519-private/bf6065d753c4a2c679dcd28828ac625c6c713efee2d4dd4b9c9ff3c9a2b2f966"
812                .to_string()
813        );
814
815        let public_ed = PublicKey::from_bytes_hex(
816            "eb396fa7a681c614fefc5bd8d1fa0383f30a8c562a99d8e8a830286e844be074",
817            Algorithm::Ed25519,
818        )
819        .unwrap();
820
821        assert_eq!(
822            public_ed.to_string(),
823            "ed25519/eb396fa7a681c614fefc5bd8d1fa0383f30a8c562a99d8e8a830286e844be074".to_string()
824        );
825    }
826
827    #[test]
828    fn parsing_secp256r1() {
829        let private_p256 = PrivateKey::from_bytes_hex(
830            "4e85237ab258ca7d53051073dd6c1e501ea4699f2fed6b0f5d399dc2a5f7d38f",
831            Algorithm::Secp256r1,
832        )
833        .unwrap();
834
835        assert_eq!(
836            private_p256.to_prefixed_string(),
837            "secp256r1-private/4e85237ab258ca7d53051073dd6c1e501ea4699f2fed6b0f5d399dc2a5f7d38f"
838                .to_string()
839        );
840
841        let public_p256 = PublicKey::from_bytes_hex(
842            "03b6d94743381d3452f11a1aec8d73b0a899827d48be2e4387112e4d2faacfcc29",
843            Algorithm::Secp256r1,
844        )
845        .unwrap();
846
847        assert_eq!(
848            public_p256.to_string(),
849            "secp256r1/03b6d94743381d3452f11a1aec8d73b0a899827d48be2e4387112e4d2faacfcc29"
850                .to_string()
851        );
852
853        assert_eq!(
854            public_p256,
855            "secp256r1/03b6d94743381d3452f11a1aec8d73b0a899827d48be2e4387112e4d2faacfcc29"
856                .parse()
857                .unwrap()
858        );
859    }
860    #[test]
861    fn parsing_errors() {
862        "xx/03b6d94743381d3452f11a1aec8d73b0a899827d48be2e4387112e4d2faacfcc29"
863            .parse::<PublicKey>()
864            .unwrap_err();
865        "03b6d94743381d3452f11a1aec8d73b0a899827d48be2e4387112e4d2faacfcc29"
866            .parse::<PublicKey>()
867            .unwrap_err();
868
869        "xx/03b6d94743381d3452f11a1aec8d73b0a899827d48be2e4387112e4d2faacfcc29"
870            .parse::<PrivateKey>()
871            .unwrap_err();
872        "03b6d94743381d3452f11a1aec8d73b0a899827d48be2e4387112e4d2faacfcc29"
873            .parse::<PrivateKey>()
874            .unwrap_err();
875    }
876
877    #[cfg(feature = "pem")]
878    #[test]
879    fn ed25519_der() {
880        let ed25519_kp = KeyPair::new_with_algorithm(Algorithm::Ed25519);
881        let der_kp = ed25519_kp.to_private_key_der().unwrap();
882
883        let deser =
884            KeyPair::from_private_key_der_with_algorithm(&der_kp, Algorithm::Ed25519).unwrap();
885        assert_eq!(ed25519_kp, deser);
886        let deser = KeyPair::from_private_key_der(&der_kp).unwrap();
887        assert_eq!(ed25519_kp, deser);
888
889        let ed25519_priv = ed25519_kp.private();
890        let der_priv = ed25519_priv.to_der().unwrap();
891        let deser_priv =
892            PrivateKey::from_der_with_algorithm(&der_priv, Algorithm::Ed25519).unwrap();
893        assert_eq!(ed25519_priv, deser_priv);
894        let deser_priv = PrivateKey::from_der(&der_priv).unwrap();
895        assert_eq!(ed25519_priv, deser_priv);
896
897        let ed25519_pub = ed25519_kp.public();
898        let der_pub = ed25519_pub.to_der().unwrap();
899        let deser_pub = PublicKey::from_der_with_algorithm(&der_pub, Algorithm::Ed25519).unwrap();
900        assert_eq!(ed25519_pub, deser_pub);
901        let deser_pub = PublicKey::from_der(&der_pub).unwrap();
902        assert_eq!(ed25519_pub, deser_pub);
903    }
904
905    #[cfg(feature = "pem")]
906    #[test]
907    fn ed25519_pem() {
908        let ed25519_kp = KeyPair::new_with_algorithm(Algorithm::Ed25519);
909        let pem_kp = ed25519_kp.to_private_key_pem().unwrap();
910        let deser =
911            KeyPair::from_private_key_pem_with_algorithm(&pem_kp, Algorithm::Ed25519).unwrap();
912        assert_eq!(ed25519_kp, deser);
913        let deser = KeyPair::from_private_key_pem(&pem_kp).unwrap();
914        assert_eq!(ed25519_kp, deser);
915
916        let ed25519_priv = ed25519_kp.private();
917        let pem_priv = ed25519_priv.to_pem().unwrap();
918        let deser_priv =
919            PrivateKey::from_pem_with_algorithm(&pem_priv, Algorithm::Ed25519).unwrap();
920        assert_eq!(ed25519_priv, deser_priv);
921        let deser_priv = PrivateKey::from_pem(&pem_priv).unwrap();
922        assert_eq!(ed25519_priv, deser_priv);
923
924        let ed25519_pub = ed25519_kp.public();
925        let pem_pub = ed25519_pub.to_pem().unwrap();
926        let deser_pub = PublicKey::from_pem_with_algorithm(&pem_pub, Algorithm::Ed25519).unwrap();
927        assert_eq!(ed25519_pub, deser_pub);
928        let deser_pub = PublicKey::from_pem(&pem_pub).unwrap();
929        assert_eq!(ed25519_pub, deser_pub);
930    }
931
932    #[cfg(feature = "pem")]
933    #[test]
934    fn p256_der() {
935        let p256_kp = KeyPair::new_with_algorithm(Algorithm::Secp256r1);
936        let der_kp = p256_kp.to_private_key_der().unwrap();
937        let deser =
938            KeyPair::from_private_key_der_with_algorithm(&der_kp, Algorithm::Secp256r1).unwrap();
939        assert_eq!(p256_kp, deser);
940        let deser = KeyPair::from_private_key_der(&der_kp).unwrap();
941        assert_eq!(p256_kp, deser);
942
943        let p256_priv = p256_kp.private();
944        let der_priv = p256_priv.to_der().unwrap();
945        let deser_priv =
946            PrivateKey::from_der_with_algorithm(&der_priv, Algorithm::Secp256r1).unwrap();
947        assert_eq!(p256_priv, deser_priv);
948        let deser_priv = PrivateKey::from_der(&der_priv).unwrap();
949        assert_eq!(p256_priv, deser_priv);
950
951        let p256_pub = p256_kp.public();
952        let der_pub = p256_pub.to_der().unwrap();
953        let deser_pub = PublicKey::from_der_with_algorithm(&der_pub, Algorithm::Secp256r1).unwrap();
954        assert_eq!(p256_pub, deser_pub);
955        let deser_pub = PublicKey::from_der(&der_pub).unwrap();
956        assert_eq!(p256_pub, deser_pub);
957    }
958
959    #[cfg(feature = "pem")]
960    #[test]
961    fn p256_pem() {
962        let p256_kp = KeyPair::new_with_algorithm(Algorithm::Secp256r1);
963        let pem_kp = p256_kp.to_private_key_pem().unwrap();
964        let deser =
965            KeyPair::from_private_key_pem_with_algorithm(&pem_kp, Algorithm::Secp256r1).unwrap();
966        assert_eq!(p256_kp, deser);
967        let deser = KeyPair::from_private_key_pem(&pem_kp).unwrap();
968        assert_eq!(p256_kp, deser);
969
970        let p256_priv = p256_kp.private();
971        let pem_priv = p256_priv.to_pem().unwrap();
972        let deser_priv =
973            PrivateKey::from_pem_with_algorithm(&pem_priv, Algorithm::Secp256r1).unwrap();
974        assert_eq!(p256_priv, deser_priv);
975        let deser_priv = PrivateKey::from_pem(&pem_priv).unwrap();
976        assert_eq!(p256_priv, deser_priv);
977
978        let p256_pub = p256_kp.public();
979        let pem_pub = p256_pub.to_pem().unwrap();
980        let deser_pub = PublicKey::from_pem_with_algorithm(&pem_pub, Algorithm::Secp256r1).unwrap();
981        assert_eq!(p256_pub, deser_pub);
982        let deser_pub = PublicKey::from_pem(&pem_pub).unwrap();
983        assert_eq!(p256_pub, deser_pub);
984    }
985}