cratestack_cose/auth/
service_signer.rs1use std::fmt;
4
5use cratestack_auth::ServiceSigningKey;
6use cratestack_core::CratestackError;
7use ed25519_dalek::Signer as _;
8use ed25519_dalek::ed25519::signature::MultipartSigner as _;
9
10use crate::alg::CoseAlg;
11use crate::keys::{CoseSigner, CoseVerifyKey};
12use crate::thumbprint::KID_LEN;
13
14#[derive(Clone)]
33pub struct ServiceKeySigner {
34 key: ServiceSigningKey,
35 kid: [u8; KID_LEN],
36}
37
38impl ServiceKeySigner {
39 pub fn new(key: ServiceSigningKey) -> Self {
40 let kid = CoseVerifyKey::from_ed25519(key.signing_key().verifying_key()).kid();
41 Self { key, kid }
42 }
43
44 pub fn verify_key(&self) -> CoseVerifyKey {
46 CoseVerifyKey::from_ed25519(self.key.signing_key().verifying_key())
47 }
48
49 pub fn service_key(&self) -> &ServiceSigningKey {
51 &self.key
52 }
53}
54
55impl From<ServiceSigningKey> for ServiceKeySigner {
56 fn from(key: ServiceSigningKey) -> Self {
57 Self::new(key)
58 }
59}
60
61impl fmt::Debug for ServiceKeySigner {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 f.debug_struct("ServiceKeySigner")
64 .field("issuer", &self.key.issuer())
65 .field("jwks_kid", &self.key.kid())
66 .field("cose_kid", &self.kid)
67 .finish_non_exhaustive()
68 }
69}
70
71#[async_trait::async_trait]
72impl CoseSigner for ServiceKeySigner {
73 fn alg(&self) -> CoseAlg {
74 CoseAlg::Ed25519
75 }
76
77 fn kid(&self) -> &[u8] {
78 &self.kid
79 }
80
81 async fn sign(&self, to_be_signed: &[u8]) -> Result<Vec<u8>, CratestackError> {
82 Ok(self
83 .key
84 .signing_key()
85 .sign(to_be_signed)
86 .to_bytes()
87 .to_vec())
88 }
89
90 fn sign_chunks(&self, to_be_signed: &[&[u8]]) -> Option<Result<Vec<u8>, CratestackError>> {
93 Some(
94 self.key
95 .signing_key()
96 .try_multipart_sign(to_be_signed)
97 .map(|signature| signature.to_bytes().to_vec())
98 .map_err(|_| CratestackError::Internal("Ed25519 signing failed".to_owned())),
99 )
100 }
101}