Skip to main content

p12_keystore/
keychain.rs

1use std::fmt;
2
3use der::oid::ObjectIdentifier;
4use pkcs8::PrivateKeyInfoRef;
5
6use crate::{Result, cert::Certificate, error::Error};
7
8/// Wrapper for a local key id
9#[derive(Clone, PartialEq, Eq)]
10pub struct LocalKeyId(pub Vec<u8>);
11
12impl From<Vec<u8>> for LocalKeyId {
13    fn from(value: Vec<u8>) -> Self {
14        Self(value)
15    }
16}
17
18impl From<&[u8]> for LocalKeyId {
19    fn from(value: &[u8]) -> Self {
20        Self(value.to_vec())
21    }
22}
23
24impl From<&str> for LocalKeyId {
25    fn from(value: &str) -> Self {
26        Self(value.as_bytes().to_vec())
27    }
28}
29
30impl From<String> for LocalKeyId {
31    fn from(value: String) -> Self {
32        Self(value.into())
33    }
34}
35
36impl AsRef<[u8]> for LocalKeyId {
37    fn as_ref(&self) -> &[u8] {
38        &self.0
39    }
40}
41
42impl fmt::Debug for LocalKeyId {
43    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44        f.debug_tuple("LocalKeyId").field(&hex::encode(&self.0)).finish()
45    }
46}
47
48/// PKCS#8 private key wrapper
49#[derive(Clone, PartialEq, Eq)]
50pub struct PrivateKey {
51    pub(crate) data: Vec<u8>,
52    pub(crate) oid: ObjectIdentifier,
53}
54
55impl PrivateKey {
56    /// Parses a PKCS#8 private key encoded in DER format and constructs a new instance of the struct.
57    pub fn from_der(data: &[u8]) -> Result<Self> {
58        let info: PrivateKeyInfoRef = data.try_into().map_err(|_| Error::InvalidPrivateKey)?;
59        Ok(Self {
60            data: data.to_vec(),
61            oid: info.algorithm.oid,
62        })
63    }
64
65    /// Returns a reference to the private key data in PKCS#8 DER-encoded format.
66    pub fn as_der(&self) -> &[u8] {
67        &self.data
68    }
69
70    /// Returns an ObjectIdentifier of the key algorithm.
71    pub fn oid(&self) -> ObjectIdentifier {
72        self.oid
73    }
74}
75
76impl fmt::Debug for PrivateKey {
77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78        f.debug_struct("PrivateKey")
79            .field("data", &"<PKCS#8>")
80            .field("oid", &self.oid)
81            .finish()
82    }
83}
84
85/// PrivateKeyChain represents a private key and a certificate chain
86#[derive(Clone, PartialEq, Eq)]
87pub struct PrivateKeyChain {
88    pub(crate) key: PrivateKey,
89    pub(crate) local_key_id: LocalKeyId, // Could it be optional?
90    pub(crate) certs: Vec<Certificate>,
91}
92
93impl PrivateKeyChain {
94    /// Creates a new keychain with a given key id, private key and a list of certificates.
95    /// The leaf (entity) certificate must be the first in the list, and the root certificate must be the last.
96    pub fn new<K, I>(local_key_id: K, key: PrivateKey, certs: I) -> Self
97    where
98        K: Into<LocalKeyId>,
99        I: IntoIterator<Item = Certificate>,
100    {
101        Self {
102            key,
103            local_key_id: local_key_id.into(),
104            certs: certs.into_iter().collect(),
105        }
106    }
107
108    /// Get a private key
109    pub fn key(&self) -> &PrivateKey {
110        &self.key
111    }
112
113    /// Get certificates
114    pub fn certs(&self) -> &[Certificate] {
115        &self.certs
116    }
117
118    /// Get local key id
119    pub fn local_key_id(&self) -> &LocalKeyId {
120        &self.local_key_id
121    }
122}
123
124impl fmt::Debug for PrivateKeyChain {
125    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126        f.debug_struct("PrivateKeyChain")
127            .field("key", &self.key)
128            .field("certs", &self.certs)
129            .field("local_key_id", &hex::encode(&self.local_key_id))
130            .finish()
131    }
132}