sp_auto_id/
host_functions.rs1use 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
7pub 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 pub fn new(inner: Arc<dyn HostFunctions>) -> Self {
20 Self(inner)
21 }
22}
23
24#[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}