Skip to main content

csv_rs/util/
cached_chain.rs

1// Copyright (C) Hygon Info Technologies Ltd.
2//
3// SPDX-License-Identifier: Apache-2.0
4
5//! Utilities for adhering to a cached CSV chain convention.
6//!
7//! The search path for the CSV chain is:
8//!   1. The path specified in the "CSV_CHAIN" environment variable
9//!      (if present).
10//!   2. `$HOME/.cache/hygon-csv/chain`
11//!   3. `/var/cache/hygon-csv/chain`
12//!
13//! An entire certificate chain can be created using the `hag`
14//! utility.
15
16use crate::certs::Chain;
17
18use std::{
19    env,
20    path::{Path, PathBuf},
21};
22
23use std::{
24    fs::File,
25    io::{ErrorKind, Result},
26};
27
28use codicon::Decoder;
29
30fn append_rest<P: AsRef<Path>>(path: P) -> PathBuf {
31    let mut path = path.as_ref().to_path_buf();
32    path.push("hygon-csv");
33    path.push("chain");
34    path
35}
36
37/// Returns the path stored in the optional `CSV_CHAIN`
38/// environment variable.
39pub fn env_var() -> Option<PathBuf> {
40    env::var("CSV_CHAIN").ok().map(PathBuf::from)
41}
42
43/// Returns the "user-level" search path for the CSV
44/// certificate chain (`$HOME/.cache/hygon-csv/chain`).
45pub fn home() -> Option<PathBuf> {
46    dirs::cache_dir().map(append_rest)
47}
48
49/// Returns the "system-level" search path for the CSV
50/// certificate chain (`/var/cache/hygon-csv/chain`).
51pub fn sys() -> Option<PathBuf> {
52    let sys = PathBuf::from("/var/cache");
53    if sys.exists() {
54        Some(append_rest(sys))
55    } else {
56        None
57    }
58}
59
60/// Returns the list of search paths in the order that they
61/// will be searched for the CSV certificate chain.
62pub fn path() -> Vec<PathBuf> {
63    vec![env_var(), home(), sys()]
64        .into_iter()
65        .flatten()
66        .collect()
67}
68
69/// Searches for and decodes an CSV certificate chain.
70pub fn get() -> Result<Chain> {
71    let not_found: std::io::Error = ErrorKind::NotFound.into();
72
73    let paths: Vec<_> = path().into_iter().filter(|p| p.exists()).collect();
74    let file_name = paths.first().ok_or(not_found)?;
75    let mut file = File::open(file_name)?;
76    Chain::decode(&mut file, ())
77}