sp_auto_id/
host_functions.rs

1use crate::{DerVec, SignatureVerificationRequest, TbsCertificate, Validity};
2use sp_core::U256;
3use std::sync::Arc;
4use x509_parser::der_parser::asn1_rs::BitString;
5use x509_parser::prelude::{AlgorithmIdentifier, FromDer, SubjectPublicKeyInfo};
6
7/// Host function trait for Certificate registration
8pub trait HostFunctions: Send + Sync {
9    fn verify_signature(&self, req: SignatureVerificationRequest) -> Option<()>;
10    fn decode_tbs_certificate(&self, certificate: DerVec) -> Option<TbsCertificate>;
11}
12
13sp_externalities::decl_extension! {
14    pub struct HostFunctionExtension(Arc<dyn HostFunctions>);
15}
16
17impl HostFunctionExtension {
18    /// Create a new instance of [`HostFunctionExtension`].
19    pub fn new(inner: Arc<dyn HostFunctions>) -> Self {
20        Self(inner)
21    }
22}
23
24/// Implementation of host functions for Certificate registry.
25#[derive(Default)]
26pub struct HostFunctionsImpl;
27
28impl HostFunctions for HostFunctionsImpl {
29    fn verify_signature(&self, req: SignatureVerificationRequest) -> Option<()> {
30        verify_signature(req)
31    }
32
33    fn decode_tbs_certificate(&self, certificate: DerVec) -> Option<TbsCertificate> {
34        decode_tbs_certificate(certificate)
35    }
36}
37
38pub(crate) fn decode_tbs_certificate(certificate: DerVec) -> Option<TbsCertificate> {
39    let (_, tbs_certificate) =
40        x509_parser::certificate::TbsCertificate::from_der(certificate.as_ref()).ok()?;
41    let serial = U256::from_big_endian(&tbs_certificate.serial.to_bytes_be());
42    let validity = Validity::try_from(tbs_certificate.validity).ok()?;
43    let subject_common_name = tbs_certificate
44        .subject
45        .iter_common_name()
46        .next()
47        .map(|cn| cn.attr_value().as_bytes().to_vec())?;
48
49    Some(TbsCertificate {
50        serial,
51        subject_common_name,
52        subject_public_key_info: tbs_certificate.subject_pki.raw.to_vec().into(),
53        validity,
54    })
55}
56
57pub(crate) fn verify_signature(req: SignatureVerificationRequest) -> Option<()> {
58    let SignatureVerificationRequest {
59        public_key_info,
60        signature_algorithm,
61        data,
62        signature,
63    } = req;
64
65    let (_, public_key_info) = SubjectPublicKeyInfo::from_der(public_key_info.as_ref()).ok()?;
66    let (_, signature_algorithm) =
67        AlgorithmIdentifier::from_der(signature_algorithm.as_ref()).ok()?;
68    let signature = BitString::new(0, &signature);
69    x509_parser::verify::verify_signature(&public_key_info, &signature_algorithm, &signature, &data)
70        .ok()
71}