webpki_roots_fuchsia/
lib.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use base64::engine::Engine as _;
6use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
7use std::sync::LazyLock;
8
9static CERT_PATH: &'static str = "/config/ssl/cert.pem";
10
11// To meet the required lifetime constraints we need to chain together
12// a series of statics.
13static RAW_DATA: LazyLock<String> = LazyLock::new(|| {
14    // I could have an environment variable override this, but i'd want it keyed
15    // on being a dev build so you couldn't harm trust in prod
16    std::fs::read_to_string(CERT_PATH)
17        .map_err(|e| log::error!("unable to find root certificate store: {}, {:?}", CERT_PATH, e))
18        .unwrap()
19});
20static CERT_DERS: LazyLock<Vec<Vec<u8>>> = LazyLock::new(|| {
21    let lines: Vec<&str> = RAW_DATA
22        .split('\n')
23        .filter(|l| !l.is_empty() && !l.starts_with(':') && !l.starts_with('#'))
24        .collect();
25    let mut cert_ders = vec![];
26    let mut i = 0;
27    while i < lines.len() {
28        let start = i;
29        if lines[i] != "-----BEGIN CERTIFICATE-----" {
30            panic!("Missing certificate prefix");
31        }
32        while i < lines.len() && lines[i] != "-----END CERTIFICATE-----" {
33            i += 1;
34        }
35        if i == lines.len() {
36            panic!("Missing certificate suffix");
37        }
38        let end = i;
39        i += 1;
40        let cert_base64 = &lines[start + 1..end].join("");
41
42        let cert_bytes = BASE64_STANDARD
43            .decode(cert_base64.as_bytes())
44            .expect("Invalid base64 encoding in root store");
45        cert_ders.push(cert_bytes);
46    }
47    cert_ders
48});
49pub static TLS_SERVER_ROOTS: LazyLock<Vec<webpki::TrustAnchor<'static>>> = LazyLock::new(|| {
50    CERT_DERS
51        .iter()
52        .map(|cert_bytes| {
53            webpki::TrustAnchor::try_from_cert_der(cert_bytes)
54                .expect("Parsing root certificate failed")
55        })
56        .collect()
57});
58
59#[cfg(test)]
60mod test {
61    #[test]
62    fn test_load() {
63        assert_ne!(crate::TLS_SERVER_ROOTS.len(), 0);
64    }
65}