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

openssl_trust_handler.rs (16746B)


      1 // Copyright 2022 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::Oid;
     21 
     22 use crate::{
     23     hash_utils::hash_sha256,
     24     trust_handler::{load_eku_configuration, TrustHandlerConfig},
     25     utils::base64,
     26     Error, Result,
     27 };
     28 
     29 fn certs_der_to_x509(ders: &[Vec<u8>]) -> Result<Vec<openssl::x509::X509>> {
     30     let mut certs: Vec<openssl::x509::X509> = Vec::new();
     31 
     32     for d in ders {
     33         let cert = openssl::x509::X509::from_der(d).map_err(Error::OpenSslError)?;
     34         certs.push(cert);
     35     }
     36 
     37     Ok(certs)
     38 }
     39 
     40 fn load_trust_from_pem_data(trust_data: &[u8]) -> Result<Vec<openssl::x509::X509>> {
     41     openssl::x509::X509::stack_from_pem(trust_data).map_err(Error::OpenSslError)
     42 }
     43 
     44 // Struct to handle verification of trust chains
     45 pub(crate) struct OpenSSLTrustHandlerConfig {
     46     trust_anchors: Vec<openssl::x509::X509>,
     47     private_anchors: Vec<openssl::x509::X509>,
     48     allowed_cert_set: HashSet<String>,
     49     trust_store: Option<openssl::x509::store::X509Store>,
     50     config_store: Vec<u8>,
     51 }
     52 
     53 impl OpenSSLTrustHandlerConfig {
     54     pub fn load_default_trust(&mut self) -> Result<()> {
     55         // load config store
     56         let config = include_bytes!("./store.cfg");
     57         let mut config_reader = Cursor::new(config);
     58         self.load_configuration(&mut config_reader)?;
     59 
     60         // load debug/test private trust anchors
     61         if cfg!(test) {
     62             let pa = include_bytes!("./test_cert_root_bundle.pem");
     63             let mut pa_reader = Cursor::new(pa);
     64 
     65             self.append_private_trust_data(&mut pa_reader)?;
     66         }
     67 
     68         Ok(())
     69     }
     70 
     71     fn update_store(&mut self) -> Result<()> {
     72         let mut builder =
     73             openssl::x509::store::X509StoreBuilder::new().map_err(Error::OpenSslError)?;
     74 
     75         // add trust anchors
     76         for t in &self.trust_anchors {
     77             builder.add_cert(t.clone())?;
     78         }
     79 
     80         // add private anchors
     81         for t in &self.private_anchors {
     82             builder.add_cert(t.clone())?;
     83         }
     84 
     85         self.trust_store = Some(builder.build());
     86 
     87         Ok(())
     88     }
     89 }
     90 
     91 impl std::fmt::Debug for OpenSSLTrustHandlerConfig {
     92     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     93         write!(
     94             f,
     95             "{} trust anchors, {} private anchors.",
     96             self.trust_anchors.len(),
     97             self.private_anchors.len()
     98         )
     99     }
    100 }
    101 
    102 #[allow(dead_code)]
    103 impl TrustHandlerConfig for OpenSSLTrustHandlerConfig {
    104     fn new() -> Self {
    105         let mut th = OpenSSLTrustHandlerConfig {
    106             trust_anchors: Vec::new(),
    107             private_anchors: Vec::new(),
    108             allowed_cert_set: HashSet::new(),
    109             trust_store: None,
    110             config_store: Vec::new(),
    111         };
    112         if th.load_default_trust().is_err() {
    113             th.clear(); // just use empty trust handler to fail automatically
    114         }
    115 
    116         th
    117     }
    118 
    119     // add trust anchors
    120     fn load_trust_anchors_from_data(&mut self, trust_data_reader: &mut dyn Read) -> Result<()> {
    121         let mut trust_data = Vec::new();
    122         trust_data_reader.read_to_end(&mut trust_data)?;
    123 
    124         self.trust_anchors = load_trust_from_pem_data(&trust_data)?;
    125         if self.trust_anchors.is_empty() {
    126             return Err(Error::NotFound); // catch silent failure
    127         }
    128 
    129         self.update_store()
    130     }
    131 
    132     // add allowed list entries
    133     fn load_allowed_list(&mut self, allowed_list: &mut dyn Read) -> Result<()> {
    134         let mut buffer = Vec::new();
    135         allowed_list.read_to_end(&mut buffer)?;
    136 
    137         if let Ok(cert_list) = openssl::x509::X509::stack_from_pem(&buffer) {
    138             for cert in &cert_list {
    139                 let cert_der = cert.to_der().map_err(Error::OpenSslError)?;
    140                 let cert_sha256 = hash_sha256(&cert_der);
    141                 let cert_hash_base64 = base64::encode(&cert_sha256);
    142 
    143                 self.allowed_cert_set.insert(cert_hash_base64);
    144             }
    145         }
    146 
    147         // try to load the of base64 encoded encoding of the sha256 hash of the certificate DER encoding
    148         let reader = Cursor::new(buffer);
    149         let buf_reader = BufReader::new(reader);
    150 
    151         let mut inside_cert_block = false;
    152         for l in buf_reader.lines().map_while(|v| v.ok()) {
    153             if l.contains("-----BEGIN") {
    154                 inside_cert_block = true;
    155             }
    156             if l.contains("-----END") {
    157                 inside_cert_block = false;
    158             }
    159 
    160             // sanity check that that is is base64 encoded and outside of certificate block
    161             if !inside_cert_block && base64::decode(&l).is_ok() && !l.is_empty() {
    162                 self.allowed_cert_set.insert(l);
    163             }
    164         }
    165 
    166         Ok(())
    167     }
    168 
    169     // append private trust anchors
    170     fn append_private_trust_data(&mut self, private_anchors_reader: &mut dyn Read) -> Result<()> {
    171         let mut private_anchors_data = Vec::new();
    172         private_anchors_reader.read_to_end(&mut private_anchors_data)?;
    173 
    174         let mut pa = load_trust_from_pem_data(&private_anchors_data)?;
    175         self.private_anchors.append(&mut pa);
    176         self.update_store()
    177     }
    178 
    179     fn clear(&mut self) {
    180         self.trust_anchors = Vec::new();
    181         self.private_anchors = Vec::new();
    182         self.trust_store = None;
    183     }
    184 
    185     // load EKU configuration
    186     fn load_configuration(&mut self, config_data: &mut dyn Read) -> Result<()> {
    187         config_data.read_to_end(&mut self.config_store)?;
    188         Ok(())
    189     }
    190 
    191     // list off auxillary allowed EKU Oid
    192     fn get_auxillary_ekus(&self) -> Vec<Oid> {
    193         let mut oids = Vec::new();
    194         if let Ok(oid_strings) = load_eku_configuration(&mut Cursor::new(&self.config_store)) {
    195             for oid_str in &oid_strings {
    196                 if let Ok(oid) = Oid::from_str(oid_str) {
    197                     oids.push(oid);
    198                 }
    199             }
    200         }
    201         oids
    202     }
    203 
    204     fn get_anchors(&self) -> Vec<Vec<u8>> {
    205         let mut anchors = Vec::new();
    206 
    207         for a in &self.private_anchors {
    208             if let Ok(der) = a.to_der() {
    209                 anchors.push(der)
    210             }
    211         }
    212 
    213         for a in &self.trust_anchors {
    214             if let Ok(der) = a.to_der() {
    215                 anchors.push(der)
    216             }
    217         }
    218         anchors
    219     }
    220 
    221     // set of allowed cert hashes
    222     fn get_allowed_list(&self) -> &HashSet<String> {
    223         &self.allowed_cert_set
    224     }
    225 }
    226 
    227 // verify certificate and trust chain
    228 pub(crate) fn verify_trust(
    229     th: &dyn TrustHandlerConfig,
    230     chain_der: &[Vec<u8>],
    231     cert_der: &[u8],
    232 ) -> Result<bool> {
    233     // check the cert against the allowed list first
    234     let cert_sha256 = hash_sha256(cert_der);
    235     let cert_hash_base64 = base64::encode(&cert_sha256);
    236     if th.get_allowed_list().contains(&cert_hash_base64) {
    237         return Ok(true);
    238     }
    239 
    240     let mut cert_chain = openssl::stack::Stack::new().map_err(Error::OpenSslError)?;
    241     let mut store_ctx = openssl::x509::X509StoreContext::new().map_err(Error::OpenSslError)?;
    242 
    243     let chain = certs_der_to_x509(chain_der)?;
    244     for c in chain {
    245         cert_chain.push(c).map_err(Error::OpenSslError)?;
    246     }
    247     let cert = openssl::x509::X509::from_der(cert_der).map_err(Error::OpenSslError)?;
    248 
    249     let mut builder = openssl::x509::store::X509StoreBuilder::new().map_err(Error::OpenSslError)?;
    250 
    251     // todo: figure out the passthrough case
    252     if th.get_anchors().is_empty() {
    253         return Ok(false);
    254     }
    255 
    256     // add trust anchors
    257     for d in th.get_anchors() {
    258         let c = openssl::x509::X509::from_der(&d).map_err(Error::OpenSslError)?;
    259         builder.add_cert(c)?;
    260     }
    261     // finalize store
    262     let store = builder.build();
    263 
    264     match store_ctx.init(&store, cert.as_ref(), &cert_chain, |f| f.verify_cert()) {
    265         Ok(trust) => Ok(trust),
    266         Err(_) => Ok(false),
    267     }
    268 }
    269 #[cfg(test)]
    270 pub mod tests {
    271     #![allow(clippy::expect_used)]
    272     #![allow(clippy::panic)]
    273     #![allow(clippy::unwrap_used)]
    274 
    275     use super::*;
    276     use crate::{
    277         openssl::temp_signer::{self},
    278         Signer, SigningAlg,
    279     };
    280 
    281     #[test]
    282     fn test_trust_store() {
    283         let cert_dir = crate::utils::test::fixture_path("certs");
    284 
    285         let mut th = OpenSSLTrustHandlerConfig::new();
    286         th.clear();
    287 
    288         th.load_default_trust().unwrap();
    289 
    290         // test all the certs
    291         let (ps256, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps256, None);
    292         let (ps384, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps384, None);
    293         let (ps512, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps512, None);
    294         let (es256, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es256, None);
    295         let (es384, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es384, None);
    296         let (es512, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es512, None);
    297         let (ed25519, _) = temp_signer::get_ed_signer(&cert_dir, SigningAlg::Ed25519, None);
    298 
    299         let ps256_certs = ps256.certs().unwrap();
    300         let ps384_certs = ps384.certs().unwrap();
    301         let ps512_certs = ps512.certs().unwrap();
    302         let es256_certs = es256.certs().unwrap();
    303         let es384_certs = es384.certs().unwrap();
    304         let es512_certs = es512.certs().unwrap();
    305         let ed25519_certs = ed25519.certs().unwrap();
    306 
    307         assert!(verify_trust(&th, &ps256_certs[1..], &ps256_certs[0]).unwrap());
    308         assert!(verify_trust(&th, &ps384_certs[1..], &ps384_certs[0]).unwrap());
    309         assert!(verify_trust(&th, &ps512_certs[1..], &ps512_certs[0]).unwrap());
    310         assert!(verify_trust(&th, &es256_certs[1..], &es256_certs[0]).unwrap());
    311         assert!(verify_trust(&th, &es384_certs[1..], &es384_certs[0]).unwrap());
    312         assert!(verify_trust(&th, &es512_certs[1..], &es512_certs[0]).unwrap());
    313         assert!(verify_trust(&th, &ed25519_certs[1..], &ed25519_certs[0]).unwrap());
    314     }
    315 
    316     #[test]
    317     fn test_broken_trust_chain() {
    318         let cert_dir = crate::utils::test::fixture_path("certs");
    319         let ta = include_bytes!("../../tests/fixtures/certs/trust/test_cert_root_bundle.pem");
    320 
    321         let mut th = OpenSSLTrustHandlerConfig::new();
    322         th.clear();
    323 
    324         // load the trust store
    325         let mut reader = Cursor::new(ta);
    326         th.load_trust_anchors_from_data(&mut reader).unwrap();
    327 
    328         // test all the certs
    329         let (ps256, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps256, None);
    330         let (ps384, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps384, None);
    331         let (ps512, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps512, None);
    332         let (es256, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es256, None);
    333         let (es384, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es384, None);
    334         let (es512, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es512, None);
    335         let (ed25519, _) = temp_signer::get_ed_signer(&cert_dir, SigningAlg::Ed25519, None);
    336 
    337         let ps256_certs = ps256.certs().unwrap();
    338         let ps384_certs = ps384.certs().unwrap();
    339         let ps512_certs = ps512.certs().unwrap();
    340         let es256_certs = es256.certs().unwrap();
    341         let es384_certs = es384.certs().unwrap();
    342         let es512_certs = es512.certs().unwrap();
    343         let ed25519_certs = ed25519.certs().unwrap();
    344 
    345         assert!(!verify_trust(&th, &ps256_certs[2..], &ps256_certs[0]).unwrap());
    346         assert!(!verify_trust(&th, &ps384_certs[2..], &ps384_certs[0]).unwrap());
    347         assert!(!verify_trust(&th, &ps512_certs[2..], &ps512_certs[0]).unwrap());
    348         assert!(!verify_trust(&th, &es256_certs[2..], &es256_certs[0]).unwrap());
    349         assert!(!verify_trust(&th, &es384_certs[2..], &es384_certs[0]).unwrap());
    350         assert!(!verify_trust(&th, &es512_certs[2..], &es512_certs[0]).unwrap());
    351         assert!(!verify_trust(&th, &ed25519_certs[2..], &ed25519_certs[0]).unwrap());
    352     }
    353 
    354     #[test]
    355     fn test_allowed_list() {
    356         let cert_dir = crate::utils::test::fixture_path("certs");
    357 
    358         let mut th = OpenSSLTrustHandlerConfig::new();
    359         th.clear();
    360 
    361         let mut allowed_list_path = crate::utils::test::fixture_path("certs");
    362         allowed_list_path = allowed_list_path.join("trust");
    363         allowed_list_path = allowed_list_path.join("allowed_list.pem");
    364 
    365         let mut allowed_list = std::fs::File::open(&allowed_list_path).unwrap();
    366 
    367         th.load_allowed_list(&mut allowed_list).unwrap();
    368 
    369         // test all the certs
    370         let (ps256, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps256, None);
    371         let (ps384, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps384, None);
    372         let (ps512, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps512, None);
    373         let (es256, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es256, None);
    374         let (es384, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es384, None);
    375         let (es512, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es512, None);
    376         let (ed25519, _) = temp_signer::get_ed_signer(&cert_dir, SigningAlg::Ed25519, None);
    377 
    378         let ps256_certs = ps256.certs().unwrap();
    379         let ps384_certs = ps384.certs().unwrap();
    380         let ps512_certs = ps512.certs().unwrap();
    381         let es256_certs = es256.certs().unwrap();
    382         let es384_certs = es384.certs().unwrap();
    383         let es512_certs = es512.certs().unwrap();
    384         let ed25519_certs = ed25519.certs().unwrap();
    385 
    386         assert!(verify_trust(&th, &ps256_certs[1..], &ps256_certs[0]).unwrap());
    387         assert!(verify_trust(&th, &ps384_certs[1..], &ps384_certs[0]).unwrap());
    388         assert!(verify_trust(&th, &ps512_certs[1..], &ps512_certs[0]).unwrap());
    389         assert!(verify_trust(&th, &es256_certs[1..], &es256_certs[0]).unwrap());
    390         assert!(verify_trust(&th, &es384_certs[1..], &es384_certs[0]).unwrap());
    391         assert!(verify_trust(&th, &es512_certs[1..], &es512_certs[0]).unwrap());
    392         assert!(verify_trust(&th, &ed25519_certs[1..], &ed25519_certs[0]).unwrap());
    393     }
    394 
    395     #[test]
    396     fn test_allowed_list_hashes() {
    397         let cert_dir = crate::utils::test::fixture_path("certs");
    398 
    399         let mut th = OpenSSLTrustHandlerConfig::new();
    400         th.clear();
    401 
    402         let mut allowed_list_path = crate::utils::test::fixture_path("certs");
    403         allowed_list_path = allowed_list_path.join("trust");
    404         allowed_list_path = allowed_list_path.join("allowed_list.hash");
    405 
    406         let mut allowed_list = std::fs::File::open(&allowed_list_path).unwrap();
    407 
    408         th.load_allowed_list(&mut allowed_list).unwrap();
    409 
    410         // test all the certs
    411         let (ps256, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps256, None);
    412         let (ps384, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps384, None);
    413         let (ps512, _) = temp_signer::get_rsa_signer(&cert_dir, SigningAlg::Ps512, None);
    414         let (es256, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es256, None);
    415         let (es384, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es384, None);
    416         let (es512, _) = temp_signer::get_ec_signer(&cert_dir, SigningAlg::Es512, None);
    417         let (ed25519, _) = temp_signer::get_ed_signer(&cert_dir, SigningAlg::Ed25519, None);
    418 
    419         let ps256_certs = ps256.certs().unwrap();
    420         let ps384_certs = ps384.certs().unwrap();
    421         let ps512_certs = ps512.certs().unwrap();
    422         let es256_certs = es256.certs().unwrap();
    423         let es384_certs = es384.certs().unwrap();
    424         let es512_certs = es512.certs().unwrap();
    425         let ed25519_certs = ed25519.certs().unwrap();
    426 
    427         assert!(verify_trust(&th, &ps256_certs[1..], &ps256_certs[0]).unwrap());
    428         assert!(verify_trust(&th, &ps384_certs[1..], &ps384_certs[0]).unwrap());
    429         assert!(verify_trust(&th, &ps512_certs[1..], &ps512_certs[0]).unwrap());
    430         assert!(verify_trust(&th, &es256_certs[1..], &es256_certs[0]).unwrap());
    431         assert!(verify_trust(&th, &es384_certs[1..], &es384_certs[0]).unwrap());
    432         assert!(verify_trust(&th, &es512_certs[1..], &es512_certs[0]).unwrap());
    433         assert!(verify_trust(&th, &ed25519_certs[1..], &ed25519_certs[0]).unwrap());
    434     }
    435 }