Skip to main content

luct_core/
v1.rs

1use crate::utils::{
2    codec::{CodecError, Decode, Encode},
3    codec_vec::CodecVec,
4    hex_with_colons,
5    u24::U24,
6};
7pub(crate) use sct::SctList;
8use serde::{Deserialize, Serialize};
9use std::{
10    fmt::{self, Display},
11    io::{Read, Write},
12};
13use x509_cert::{
14    certificate::{CertificateInner, Rfc5280, TbsCertificateInner},
15    der::{Decode as DerDecode, Encode as DerEncode},
16};
17
18pub(crate) mod extension;
19pub(crate) mod proof;
20pub mod responses;
21pub(crate) mod roots;
22pub(crate) mod sct;
23pub(crate) mod sth;
24pub(crate) mod tree;
25
26pub use sct::SignedCertificateTimestamp;
27pub use sth::SignedTreeHead;
28pub use tree::MerkleTreeLeaf;
29
30// TODO(Submission support): Requests and responses for submission
31
32// TODO: LogEntryChain type
33
34#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
35pub struct LogId(pub(crate) [u8; 32]);
36
37impl fmt::Debug for LogId {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        f.debug_tuple("LogId").field(&hex::encode(self.0)).finish()
40    }
41}
42
43impl Display for LogId {
44    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45        write!(f, "{}", hex_with_colons(&self.0))
46    }
47}
48
49impl Encode for LogId {
50    fn encode(&self, mut writer: impl Write) -> Result<(), CodecError> {
51        Ok(writer.write_all(&self.0)?)
52    }
53}
54
55impl Decode for LogId {
56    fn decode(mut reader: impl Read) -> Result<Self, CodecError> {
57        let mut buf = [0u8; 32];
58        reader.read_exact(&mut buf)?;
59
60        Ok(Self(buf))
61    }
62}
63
64/// See RFC 5246 3.2
65#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
66pub(crate) enum SignatureType {
67    CertificateTimeStamp,
68    TreeHash,
69}
70
71impl Encode for SignatureType {
72    fn encode(&self, mut writer: impl Write) -> Result<(), CodecError> {
73        let discriminant = match self {
74            SignatureType::CertificateTimeStamp => 0,
75            SignatureType::TreeHash => 1,
76        };
77        Ok(writer.write_all(&[discriminant])?)
78    }
79}
80
81impl Decode for SignatureType {
82    fn decode(mut reader: impl Read) -> Result<Self, CodecError> {
83        let mut buf = vec![0u8];
84        reader.read_exact(&mut buf)?;
85
86        match buf[0] {
87            0 => Ok(SignatureType::CertificateTimeStamp),
88            1 => Ok(SignatureType::TreeHash),
89            x => Err(CodecError::UnknownVariant("SignatureType", x as u64)),
90        }
91    }
92}
93
94// See RFC 6962 3.2
95#[derive(Debug, Clone, PartialEq, Eq)]
96pub(crate) enum LogEntry {
97    X509(CertificateInner<Rfc5280>),
98    PreCert(PreCert),
99}
100
101impl Encode for LogEntry {
102    fn encode(&self, mut writer: impl Write) -> Result<(), CodecError> {
103        match self {
104            LogEntry::X509(cert) => {
105                writer.write_all(&[0, 0])?;
106
107                let mut cert_bytes = vec![];
108                let _len = cert.encode_to_vec(&mut cert_bytes)?;
109                CodecVec::<U24>::from(cert_bytes).encode(&mut writer)?;
110            }
111            LogEntry::PreCert(pre_cert) => {
112                writer.write_all(&[0, 1])?;
113                pre_cert.encode(&mut writer)?;
114            }
115        };
116
117        Ok(())
118    }
119}
120
121impl Decode for LogEntry {
122    fn decode(mut reader: impl Read) -> Result<Self, CodecError> {
123        let mut buf = [0u8; 2];
124        reader.read_exact(&mut buf)?;
125        let entry = u16::from_be_bytes(buf);
126
127        match entry {
128            0 => {
129                let cert_bytes = CodecVec::<U24>::decode(&mut reader)?;
130                let cert = CertificateInner::<Rfc5280>::from_der(cert_bytes.as_ref())?;
131                Ok(LogEntry::X509(cert))
132            }
133            1 => Ok(LogEntry::PreCert(PreCert::decode(&mut reader)?)),
134            x => Err(CodecError::UnknownVariant("LogEntry", x as u64)),
135        }
136    }
137}
138
139/// A [`PreCert`] contains a X.509 `TbsCertificate` as well as a hash of the issuer key.
140///
141/// See RFC 6962 3.2
142#[derive(Debug, Clone, PartialEq, Eq)]
143pub(crate) struct PreCert {
144    pub(crate) issuer_key_hash: [u8; 32],
145    pub(crate) tbs_certificate: TbsCertificateInner<Rfc5280>,
146}
147
148impl Encode for PreCert {
149    fn encode(&self, mut writer: impl Write) -> Result<(), CodecError> {
150        Encode::encode(&self.issuer_key_hash, &mut writer)?;
151
152        let mut cert_bytes = vec![];
153        let _len = self.tbs_certificate.encode_to_vec(&mut cert_bytes)?;
154        CodecVec::<U24>::from(cert_bytes).encode(&mut writer)?;
155
156        Ok(())
157    }
158}
159
160impl Decode for PreCert {
161    fn decode(mut reader: impl Read) -> Result<Self, CodecError> {
162        let issuer_key_hash = <[u8; 32] as Decode>::decode(&mut reader)?;
163        let cert_bytes = CodecVec::<U24>::decode(&mut reader)?;
164        let tbs_certificate = TbsCertificateInner::<Rfc5280>::from_der(cert_bytes.as_ref())?;
165
166        Ok(Self {
167            issuer_key_hash,
168            tbs_certificate,
169        })
170    }
171}