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 }