c2pa-rs

A fork of https://github.com/contentauth/c2pa-rs/
git clone git://archive.git.mtrnord.blog/mtrnords-photography-manager/c2pa-rs.git
Log | Files | Refs | README

webpki_trust_handler.rs (21948B)


      1 // Copyright 2023 Adobe. All rights reserved.
      2 // This file is licensed to you under the Apache License,
      3 // Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
      4 // or the MIT license (http://opensource.org/licenses/MIT),
      5 // at your option.
      6 
      7 // Unless required by applicable law or agreed to in writing,
      8 // this software is distributed on an "AS IS" BASIS, WITHOUT
      9 // WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
     10 // implied. See the LICENSE-MIT and LICENSE-APACHE files for the
     11 // specific language governing permissions and limitations under
     12 // each license.
     13 
     14 use std::{
     15     collections::HashSet,
     16     io::{BufRead, BufReader, Cursor, Read},
     17     str::FromStr,
     18 };
     19 
     20 use asn1_rs::{nom::AsBytes, Any, Class, Header, Tag};
     21 use x509_parser::{
     22     der_parser::der::{parse_der_integer, parse_der_sequence_of},
     23     oid_registry::Oid,
     24     prelude::*,
     25 };
     26 
     27 use crate::{
     28     cose_validator::*,
     29     error::{Error, Result},
     30     hash_utils::{hash_sha256, vec_compare},
     31     trust_handler::{
     32         has_allowed_oid, load_eku_configuration, load_trust_from_data, TrustHandlerConfig,
     33     },
     34     utils::base64,
     35     wasm::webcrypto_validator::async_validate,
     36     SigningAlg,
     37 };
     38 
     39 // Struct to handle verification of trust chains using WebPki
     40 pub(crate) struct WebTrustHandlerConfig {
     41     pub trust_anchors: Vec<Vec<u8>>,
     42     pub private_anchors: Vec<Vec<u8>>,
     43     allowed_cert_set: HashSet<String>,
     44     config_store: Vec<u8>,
     45 }
     46 
     47 impl std::fmt::Debug for WebTrustHandlerConfig {
     48     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     49         write!(
     50             f,
     51             "{} trust anchors, {} private anchors.",
     52             self.trust_anchors.len(),
     53             self.private_anchors.len()
     54         )
     55     }
     56 }
     57 
     58 impl WebTrustHandlerConfig {
     59     pub fn load_default_trust(&mut self) -> Result<()> {
     60         // load config store
     61         let config = include_bytes!("./store.cfg");
     62         let mut config_reader = Cursor::new(config);
     63         self.load_configuration(&mut config_reader)?;
     64 
     65         // load debug/test private trust anchors
     66         if cfg!(test) {
     67             let pa = include_bytes!("./test_cert_root_bundle.pem");
     68             let mut pa_reader = Cursor::new(pa);
     69 
     70             self.append_private_trust_data(&mut pa_reader)?;
     71         }
     72 
     73         Ok(())
     74     }
     75 }
     76 
     77 impl TrustHandlerConfig for WebTrustHandlerConfig {
     78     fn new() -> Self {
     79         let mut th = WebTrustHandlerConfig {
     80             trust_anchors: Vec::new(),
     81             private_anchors: Vec::new(),
     82             allowed_cert_set: HashSet::new(),
     83             config_store: Vec::new(),
     84         };
     85 
     86         if th.load_default_trust().is_err() {
     87             th.clear(); // just use empty trust handler to fail automatically
     88         }
     89 
     90         th
     91     }
     92 
     93     // add trust anchors
     94     fn load_trust_anchors_from_data(&mut self, trust_data_reader: &mut dyn Read) -> Result<()> {
     95         let mut trust_data = Vec::new();
     96         trust_data_reader.read_to_end(&mut trust_data)?;
     97 
     98         let mut anchors = load_trust_from_data(&trust_data)?;
     99         self.trust_anchors.append(&mut anchors);
    100         Ok(())
    101     }
    102 
    103     // append private trust anchors
    104     fn append_private_trust_data(&mut self, private_anchors_reader: &mut dyn Read) -> Result<()> {
    105         let mut private_anchors_data = Vec::new();
    106         private_anchors_reader.read_to_end(&mut private_anchors_data)?;
    107 
    108         let mut anchors = load_trust_from_data(&private_anchors_data)?;
    109         self.private_anchors.append(&mut anchors);
    110 
    111         Ok(())
    112     }
    113 
    114     fn clear(&mut self) {
    115         self.trust_anchors = Vec::new();
    116         self.private_anchors = Vec::new();
    117     }
    118 
    119     // load EKU configuration
    120     fn load_configuration(&mut self, config_data: &mut dyn Read) -> Result<()> {
    121         config_data.read_to_end(&mut self.config_store)?;
    122         Ok(())
    123     }
    124 
    125     // list off auxillary allowed EKU Oid
    126     fn get_auxillary_ekus(&self) -> Vec<Oid> {
    127         let mut oids = Vec::new();
    128         if let Ok(oid_strings) = load_eku_configuration(&mut Cursor::new(&self.config_store)) {
    129             for oid_str in &oid_strings {
    130                 if let Ok(oid) = Oid::from_str(oid_str) {
    131                     oids.push(oid);
    132                 }
    133             }
    134         }
    135         oids
    136     }
    137 
    138     fn get_anchors(&self) -> Vec<Vec<u8>> {
    139         let mut anchors = Vec::new();
    140 
    141         anchors.append(&mut self.trust_anchors.clone());
    142         anchors.append(&mut self.private_anchors.clone());
    143 
    144         anchors
    145     }
    146 
    147     // add allowed list entries
    148     fn load_allowed_list(&mut self, allowed_list: &mut dyn Read) -> Result<()> {
    149         let mut buffer = Vec::new();
    150         allowed_list.read_to_end(&mut buffer)?;
    151 
    152         if let Ok(cert_list) = load_trust_from_data(&buffer) {
    153             for cert_der in &cert_list {
    154                 let cert_sha256 = hash_sha256(cert_der);
    155                 let cert_hash_base64 = base64::encode(&cert_sha256);
    156 
    157                 self.allowed_cert_set.insert(cert_hash_base64);
    158             }
    159         }
    160 
    161         // try to load the of base64 encoded encoding of the sha256 hash of the certificate DER encoding
    162         let reader = Cursor::new(buffer);
    163         let buf_reader = BufReader::new(reader);
    164 
    165         let mut inside_cert_block = false;
    166         for l in buf_reader.lines().flatten() {
    167             if l.contains("-----BEGIN") {
    168                 inside_cert_block = true;
    169             }
    170             if l.contains("-----END") {
    171                 inside_cert_block = false;
    172             }
    173 
    174             // sanity check that data is base64 encoded and outside of certificate block
    175             if !inside_cert_block && base64::decode(&l).is_ok() && !l.is_empty() {
    176                 self.allowed_cert_set.insert(l);
    177             }
    178         }
    179 
    180         Ok(())
    181     }
    182 
    183     // set of allowed cert hashes
    184     fn get_allowed_list(&self) -> &HashSet<String> {
    185         &self.allowed_cert_set
    186     }
    187 }
    188 
    189 fn find_allowed_eku<'a>(cert_der: &'a [u8], allowed_ekus: &'a Vec<Oid<'a>>) -> Option<&'a Oid<'a>> {
    190     if let Ok((_rem, cert)) = X509Certificate::from_der(cert_der) {
    191         if let Ok(Some(eku)) = cert.extended_key_usage() {
    192             if let Some(o) = has_allowed_oid(eku.value, allowed_ekus) {
    193                 return Some(o);
    194             }
    195         }
    196     }
    197     None
    198 }
    199 fn cert_signing_alg(cert: &x509_parser::certificate::X509Certificate) -> Option<String> {
    200     let cert_alg = cert.signature_algorithm.algorithm.clone();
    201 
    202     let signing_alg = if cert_alg == SHA256_WITH_RSAENCRYPTION_OID {
    203         "rsa256".to_string()
    204     } else if cert_alg == SHA384_WITH_RSAENCRYPTION_OID {
    205         "rsa384".to_string()
    206     } else if cert_alg == SHA512_WITH_RSAENCRYPTION_OID {
    207         "rsa512".to_string()
    208     } else if cert_alg == ECDSA_WITH_SHA256_OID {
    209         SigningAlg::Es256.to_string()
    210     } else if cert_alg == ECDSA_WITH_SHA384_OID {
    211         SigningAlg::Es384.to_string()
    212     } else if cert_alg == ECDSA_WITH_SHA512_OID {
    213         SigningAlg::Es512.to_string()
    214     } else if cert_alg == RSASSA_PSS_OID {
    215         if let Some(parameters) = &cert.signature_algorithm.parameters {
    216             let seq = match parameters.as_sequence() {
    217                 Ok(s) => s,
    218                 Err(_) => return None,
    219             };
    220 
    221             let (_i, (ha_alg, mgf_ai)) = match seq.parse(|i| {
    222                 let (i, h) = Header::from_der(i)?;
    223                 if h.class() != Class::ContextSpecific || h.tag() != Tag(0) {
    224                     return Err(nom::Err::Error(asn1_rs::Error::BerValueError));
    225                 }
    226 
    227                 let (i, ha_alg) = AlgorithmIdentifier::from_der(i)
    228                     .map_err(|_| nom::Err::Error(asn1_rs::Error::BerValueError))?;
    229 
    230                 let (i, h) = Header::from_der(i)?;
    231                 if h.class() != Class::ContextSpecific || h.tag() != Tag(1) {
    232                     return Err(nom::Err::Error(asn1_rs::Error::BerValueError));
    233                 }
    234 
    235                 let (i, mgf_ai) = AlgorithmIdentifier::from_der(i)
    236                     .map_err(|_| nom::Err::Error(asn1_rs::Error::BerValueError))?;
    237 
    238                 // Ignore anything that follows these two parameters.
    239 
    240                 Ok((i, (ha_alg, mgf_ai)))
    241             }) {
    242                 Ok((ii, (h, m))) => (ii, (h, m)),
    243                 Err(_) => return None,
    244             };
    245 
    246             let mgf_ai_parameters = match mgf_ai.parameters {
    247                 Some(m) => m,
    248                 None => return None,
    249             };
    250 
    251             let mgf_ai_parameters = match mgf_ai_parameters.as_sequence() {
    252                 Ok(m) => m,
    253                 Err(_) => return None,
    254             };
    255 
    256             let (_i, mgf_ai_params_algorithm) = match Any::from_der(&mgf_ai_parameters.content) {
    257                 Ok((i, m)) => (i, m),
    258                 Err(_) => return None,
    259             };
    260 
    261             let mgf_ai_params_algorithm = match mgf_ai_params_algorithm.as_oid() {
    262                 Ok(m) => m,
    263                 Err(_) => return None,
    264             };
    265 
    266             // must be the same
    267             if ha_alg.algorithm != mgf_ai_params_algorithm {
    268                 return None;
    269             }
    270 
    271             // check for one of the mandatory types
    272             if ha_alg.algorithm == SHA256_OID {
    273                 "ps256".to_string()
    274             } else if ha_alg.algorithm == SHA384_OID {
    275                 "ps384".to_string()
    276             } else if ha_alg.algorithm == SHA512_OID {
    277                 "ps512".to_string()
    278             } else {
    279                 return None;
    280             }
    281         } else {
    282             return None;
    283         }
    284     } else if cert_alg == ED25519_OID {
    285         SigningAlg::Ed25519.to_string()
    286     } else {
    287         return None;
    288     };
    289 
    290     Some(signing_alg)
    291 }
    292 
    293 async fn verify_data(
    294     cert_der: Vec<u8>,
    295     sig_alg: Option<String>,
    296     sig: Vec<u8>,
    297     data: Vec<u8>,
    298 ) -> Result<bool> {
    299     use x509_parser::prelude::*;
    300 
    301     let (_, cert) =
    302         X509Certificate::from_der(cert_der.as_bytes()).map_err(|_e| Error::CoseCertUntrusted)?;
    303 
    304     let certificate_public_key = cert.public_key();
    305     if let Some(cert_alg_string) = sig_alg {
    306         let (algo, hash, salt_len) = match cert_alg_string.as_str() {
    307             "rsa256" => (
    308                 "RSASSA-PKCS1-v1_5".to_string(),
    309                 "SHA-256".to_string().to_string(),
    310                 0,
    311             ),
    312             "rsa384" => ("RSASSA-PKCS1-v1_5".to_string(), "SHA-384".to_string(), 0),
    313             "rsa512" => ("RSASSA-PKCS1-v1_5".to_string(), "SHA-512".to_string(), 0),
    314             "es256" => ("ECDSA".to_string(), "SHA-256".to_string().to_string(), 0),
    315             "es384" => ("ECDSA".to_string(), "SHA-384".to_string(), 0),
    316             "es512" => ("ECDSA".to_string(), "SHA-512".to_string(), 0),
    317             "ps256" => ("RSA-PSS".to_string(), "SHA-256".to_string(), 32),
    318             "ps384" => ("RSA-PSS".to_string(), "SHA-384".to_string(), 48),
    319             "ps512" => ("RSA-PSS".to_string(), "SHA-512".to_string(), 64),
    320             "ed25519" => ("ED25519".to_string(), "SHA-512".to_string(), 0),
    321             _ => return Err(Error::UnsupportedType),
    322         };
    323 
    324         let adjusted_sig = if cert_alg_string.starts_with("es") {
    325             let parsed_alg_string: SigningAlg = cert_alg_string
    326                 .parse()
    327                 .map_err(|_| Error::UnknownAlgorithm)?;
    328             match der_to_p1363(&sig, parsed_alg_string) {
    329                 Some(p1363) => p1363,
    330                 None => sig,
    331             }
    332         } else {
    333             sig
    334         };
    335 
    336         async_validate(
    337             algo,
    338             hash,
    339             salt_len,
    340             certificate_public_key.raw.to_vec(),
    341             adjusted_sig,
    342             data,
    343         )
    344         .await
    345     } else {
    346         return Err(Error::BadParam("unknown alg processing cert".to_string()));
    347     }
    348 }
    349 // convert der signatures to P1363 format: r | s
    350 fn der_to_p1363(data: &[u8], alg: SigningAlg) -> Option<Vec<u8>> {
    351     // handle if this is a der sequence
    352     if let Ok((_, bo)) = parse_der_sequence_of(parse_der_integer)(data) {
    353         let seq = bo.as_sequence().ok()?;
    354 
    355         if seq.len() != 2 {
    356             return None;
    357         }
    358 
    359         let rp = seq[0].as_bigint().ok()?;
    360         let sp = seq[1].as_bigint().ok()?;
    361 
    362         let mut r = rp.to_str_radix(16);
    363         let mut s = sp.to_str_radix(16);
    364 
    365         let sig_len: usize = match alg {
    366             SigningAlg::Es256 => 64,
    367             SigningAlg::Es384 => 96,
    368             SigningAlg::Es512 => 132,
    369             _ => return None,
    370         };
    371 
    372         // pad or truncate as needed
    373         let rp = if r.len() > sig_len {
    374             // truncate
    375             let offset = r.len() - sig_len;
    376             &r[offset..r.len()]
    377         } else {
    378             // pad
    379             while r.len() != sig_len {
    380                 r.insert(0, '0');
    381             }
    382             r.as_ref()
    383         };
    384 
    385         let sp = if s.len() > sig_len {
    386             // truncate
    387             let offset = s.len() - sig_len;
    388             &s[offset..s.len()]
    389         } else {
    390             // pad
    391             while s.len() != sig_len {
    392                 s.insert(0, '0');
    393             }
    394             s.as_ref()
    395         };
    396 
    397         if rp.len() != sig_len || rp.len() != sp.len() {
    398             return None;
    399         }
    400 
    401         // merge r and s strings
    402         let mut new_sig = rp.to_string();
    403         new_sig.push_str(sp);
    404 
    405         // convert back from hex string to byte array
    406         let result = (0..new_sig.len())
    407             .step_by(2)
    408             .map(|i| {
    409                 u8::from_str_radix(&new_sig[i..i + 2], 16)
    410                     .map_err(|_err| crate::Error::InvalidEcdsaSignature)
    411             })
    412             .collect();
    413 
    414         if let Ok(p1363) = result {
    415             Some(p1363)
    416         } else {
    417             None
    418         }
    419     } else {
    420         Some(data.to_vec())
    421     }
    422 }
    423 
    424 async fn check_chain_order(certs: &[Vec<u8>]) -> Result<()> {
    425     use x509_parser::prelude::*;
    426 
    427     let chain_length = certs.len();
    428     if chain_length < 2 {
    429         return Ok(());
    430     }
    431 
    432     for i in 1..chain_length {
    433         let (_, current_cert) =
    434             X509Certificate::from_der(&certs[i - 1]).map_err(|_e| Error::CoseCertUntrusted)?;
    435 
    436         let issuer_der = certs[i].to_vec();
    437         let data = current_cert.tbs_certificate.as_ref();
    438         let sig = current_cert.signature_value.as_ref();
    439 
    440         let sig_alg = cert_signing_alg(&current_cert);
    441 
    442         let result = verify_data(issuer_der, sig_alg, sig.to_vec(), data.to_vec()).await;
    443 
    444         // keep going as long as it validate
    445         match result {
    446             Ok(b) => {
    447                 if !b {
    448                     return Err(Error::OtherError("cert chain order invalid".into()));
    449                 }
    450             }
    451             Err(e) => return Err(e),
    452         }
    453     }
    454     Ok(())
    455 }
    456 
    457 async fn on_trust_list(
    458     th: &dyn TrustHandlerConfig,
    459     certs: &[Vec<u8>],
    460     ee_der: &[u8],
    461 ) -> Result<bool> {
    462     use x509_parser::prelude::*;
    463 
    464     // check the cert against the allowed list first
    465     let cert_sha256 = hash_sha256(ee_der);
    466     let cert_hash_base64 = base64::encode(&cert_sha256);
    467     if th.get_allowed_list().contains(&cert_hash_base64) {
    468         return Ok(true);
    469     }
    470 
    471     // add ee cert if needed to the chain
    472     let full_chain = if !certs.is_empty() && vec_compare(ee_der, &certs[0]) {
    473         certs.to_vec()
    474     } else {
    475         let mut full_chain: Vec<Vec<u8>> = Vec::new();
    476         full_chain.push(ee_der.to_vec());
    477         let mut in_chain = certs.to_vec();
    478         full_chain.append(&mut in_chain);
    479         full_chain
    480     };
    481 
    482     // make sure chain is in the correct order and valid
    483     check_chain_order(&full_chain).await?;
    484 
    485     // build anchors and check against trust anchors,
    486     let mut anchors: Vec<X509Certificate> = Vec::new();
    487     let source_anchors = th.get_anchors();
    488     for anchor_der in &source_anchors {
    489         let (_, anchor) =
    490             X509Certificate::from_der(anchor_der).map_err(|_e| Error::CoseCertUntrusted)?;
    491         anchors.push(anchor);
    492     }
    493 
    494     if anchors.is_empty() {
    495         return Ok(false);
    496     }
    497 
    498     // work back from last cert in chain against the trust anchors
    499     for cert in certs.iter().rev() {
    500         let (_, chain_cert) =
    501             X509Certificate::from_der(cert).map_err(|_e| Error::CoseCertUntrusted)?;
    502 
    503         for anchor in &source_anchors {
    504             let data = chain_cert.tbs_certificate.as_ref();
    505             let sig = chain_cert.signature_value.as_ref();
    506 
    507             let sig_alg = cert_signing_alg(&chain_cert);
    508 
    509             let (_, anchor_cert) =
    510                 X509Certificate::from_der(anchor).map_err(|_e| Error::CoseCertUntrusted)?;
    511 
    512             if chain_cert.issuer() == anchor_cert.subject() {
    513                 let result =
    514                     verify_data(anchor.clone(), sig_alg, sig.to_vec(), data.to_vec()).await;
    515 
    516                 match result {
    517                     Ok(b) => {
    518                         if b {
    519                             return Ok(true);
    520                         }
    521                     }
    522                     Err(_) => continue,
    523                 }
    524             }
    525         }
    526     }
    527     // todo: consider (path check and names restrictions)
    528 
    529     Ok(false)
    530 }
    531 
    532 // verify certificate and trust chain
    533 pub(crate) async fn verify_trust_async(
    534     th: &dyn TrustHandlerConfig,
    535     chain_der: &[Vec<u8>],
    536     cert_der: &[u8],
    537 ) -> Result<bool> {
    538     // check configured EKUs against end-entity cert
    539     find_allowed_eku(cert_der, &th.get_auxillary_ekus()).ok_or(Error::CoseCertUntrusted)?;
    540 
    541     on_trust_list(th, chain_der, cert_der).await
    542 }
    543 
    544 #[cfg(test)]
    545 pub mod tests {
    546     #![allow(clippy::expect_used)]
    547     #![allow(clippy::panic)]
    548     #![allow(clippy::unwrap_used)]
    549 
    550     #[cfg(target_arch = "wasm32")]
    551     use wasm_bindgen_test::*;
    552 
    553     use super::*;
    554     #[cfg_attr(not(target_arch = "wasm32"), test)]
    555     #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
    556     #[wasm_bindgen_test]
    557     async fn test_trust_store() {
    558         let mut th = WebTrustHandlerConfig::new();
    559         th.clear();
    560 
    561         th.load_default_trust().unwrap();
    562 
    563         // test all the certs
    564         let ps256 = include_bytes!("../../tests/fixtures/certs/ps256.pub");
    565         let ps384 = include_bytes!("../../tests/fixtures/certs/ps384.pub");
    566         let ps512 = include_bytes!("../../tests/fixtures/certs/ps512.pub");
    567         let es256 = include_bytes!("../../tests/fixtures/certs/es256.pub");
    568         let es384 = include_bytes!("../../tests/fixtures/certs/es384.pub");
    569         let es512 = include_bytes!("../../tests/fixtures/certs/es512.pub");
    570         let ed25519 = include_bytes!("../../tests/fixtures/certs/ed25519.pub");
    571 
    572         let ps256_certs = load_trust_from_data(ps256).unwrap();
    573         let ps384_certs = load_trust_from_data(ps384).unwrap();
    574         let ps512_certs = load_trust_from_data(ps512).unwrap();
    575         let es256_certs = load_trust_from_data(es256).unwrap();
    576         let es384_certs = load_trust_from_data(es384).unwrap();
    577         let es512_certs = load_trust_from_data(es512).unwrap();
    578         let ed25519_certs = load_trust_from_data(ed25519).unwrap();
    579 
    580         assert!(verify_trust_async(&th, &ps256_certs[1..], &ps256_certs[0])
    581             .await
    582             .unwrap());
    583         assert!(verify_trust_async(&th, &ps384_certs[1..], &ps384_certs[0])
    584             .await
    585             .unwrap());
    586         assert!(verify_trust_async(&th, &ps512_certs[1..], &ps512_certs[0])
    587             .await
    588             .unwrap());
    589         assert!(verify_trust_async(&th, &es256_certs[1..], &es256_certs[0])
    590             .await
    591             .unwrap());
    592 
    593         assert!(verify_trust_async(&th, &es384_certs[1..], &es384_certs[0])
    594             .await
    595             .unwrap());
    596         assert!(verify_trust_async(&th, &es512_certs[1..], &es512_certs[0])
    597             .await
    598             .unwrap());
    599 
    600         assert!(
    601             verify_trust_async(&th, &ed25519_certs[1..], &ed25519_certs[0])
    602                 .await
    603                 .unwrap()
    604         );
    605     }
    606 
    607     #[cfg_attr(not(target_arch = "wasm32"), test)]
    608     #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
    609     #[wasm_bindgen_test]
    610     async fn test_broken_trust_chain() {
    611         let mut th = WebTrustHandlerConfig::new();
    612         th.clear();
    613 
    614         th.load_default_trust().unwrap();
    615 
    616         // test all the certs
    617         let ps256 = include_bytes!("../../tests/fixtures/certs/ps256.pub");
    618         let ps384 = include_bytes!("../../tests/fixtures/certs/ps384.pub");
    619         let ps512 = include_bytes!("../../tests/fixtures/certs/ps512.pub");
    620         let es256 = include_bytes!("../../tests/fixtures/certs/es256.pub");
    621         let es384 = include_bytes!("../../tests/fixtures/certs/es384.pub");
    622         let es512 = include_bytes!("../../tests/fixtures/certs/es512.pub");
    623         let ed25519 = include_bytes!("../../tests/fixtures/certs/ed25519.pub");
    624 
    625         let ps256_certs = load_trust_from_data(ps256).unwrap();
    626         let ps384_certs = load_trust_from_data(ps384).unwrap();
    627         let ps512_certs = load_trust_from_data(ps512).unwrap();
    628         let es256_certs = load_trust_from_data(es256).unwrap();
    629         let es384_certs = load_trust_from_data(es384).unwrap();
    630         let es512_certs = load_trust_from_data(es512).unwrap();
    631         let ed25519_certs = load_trust_from_data(ed25519).unwrap();
    632 
    633         assert!(!verify_trust_async(&th, &ps256_certs[2..], &ps256_certs[0])
    634             .await
    635             .unwrap());
    636         assert!(!verify_trust_async(&th, &ps384_certs[2..], &ps384_certs[0])
    637             .await
    638             .unwrap());
    639         assert!(!verify_trust_async(&th, &ps512_certs[2..], &ps512_certs[0])
    640             .await
    641             .unwrap());
    642         assert!(!verify_trust_async(&th, &es256_certs[2..], &es256_certs[0])
    643             .await
    644             .unwrap());
    645         assert!(!verify_trust_async(&th, &es384_certs[2..], &es384_certs[0])
    646             .await
    647             .unwrap());
    648         assert!(!verify_trust_async(&th, &es512_certs[2..], &es512_certs[0])
    649             .await
    650             .unwrap());
    651         assert!(
    652             !verify_trust_async(&th, &ed25519_certs[2..], &ed25519_certs[0])
    653                 .await
    654                 .unwrap()
    655         );
    656     }
    657 }