]> git.proxmox.com Git - proxmox-backup.git/blob - src/tools/cert.rs
d/control: add ',' after qrencode dependency
[proxmox-backup.git] / src / tools / cert.rs
1 use std::path::PathBuf;
2
3 use anyhow::Error;
4 use openssl::x509::{X509, GeneralName};
5 use openssl::stack::Stack;
6 use openssl::pkey::{Public, PKey};
7
8 use crate::configdir;
9
10 pub struct CertInfo {
11 x509: X509,
12 }
13
14 fn x509name_to_string(name: &openssl::x509::X509NameRef) -> Result<String, Error> {
15 let mut parts = Vec::new();
16 for entry in name.entries() {
17 parts.push(format!("{} = {}", entry.object().nid().short_name()?, entry.data().as_utf8()?));
18 }
19 Ok(parts.join(", "))
20 }
21
22 impl CertInfo {
23 pub fn new() -> Result<Self, Error> {
24 Self::from_path(PathBuf::from(configdir!("/proxy.pem")))
25 }
26
27 pub fn from_path(path: PathBuf) -> Result<Self, Error> {
28 let cert_pem = proxmox::tools::fs::file_get_contents(&path)?;
29 let x509 = openssl::x509::X509::from_pem(&cert_pem)?;
30 Ok(Self{
31 x509
32 })
33 }
34
35 pub fn subject_alt_names(&self) -> Option<Stack<GeneralName>> {
36 self.x509.subject_alt_names()
37 }
38
39 pub fn subject_name(&self) -> Result<String, Error> {
40 Ok(x509name_to_string(self.x509.subject_name())?)
41 }
42
43 pub fn issuer_name(&self) -> Result<String, Error> {
44 Ok(x509name_to_string(self.x509.issuer_name())?)
45 }
46
47 pub fn fingerprint(&self) -> Result<String, Error> {
48 let fp = self.x509.digest(openssl::hash::MessageDigest::sha256())?;
49 let fp_string = proxmox::tools::digest_to_hex(&fp);
50 let fp_string = fp_string.as_bytes().chunks(2).map(|v| std::str::from_utf8(v).unwrap())
51 .collect::<Vec<&str>>().join(":");
52 Ok(fp_string)
53 }
54
55 pub fn public_key(&self) -> Result<PKey<Public>, Error> {
56 let pubkey = self.x509.public_key()?;
57 Ok(pubkey)
58 }
59
60 pub fn not_before(&self) -> &openssl::asn1::Asn1TimeRef {
61 self.x509.not_before()
62 }
63
64 pub fn not_after(&self) -> &openssl::asn1::Asn1TimeRef {
65 self.x509.not_after()
66 }
67 }