biscuit_auth/crypto/
mod.rs

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