Line data Source code
1 : use std::marker::PhantomData;
2 :
3 : use bitflags::bitflags;
4 : use lief_ffi as ffi;
5 :
6 : use crate::common::{into_optional, FromFFI};
7 : use crate::declare_iterator;
8 : use crate::pe::Algorithms;
9 :
10 : use super::RsaInfo;
11 :
12 : /// Structure for a x509 certificate
13 : pub struct X509<'a> {
14 : ptr: cxx::UniquePtr<ffi::PE_x509>,
15 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
16 : }
17 :
18 : impl std::fmt::Debug for X509<'_> {
19 1092 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 1092 : f.debug_struct("x509")
21 1092 : .field("version", &self.version())
22 1092 : .field("signature_algorithm", &self.signature_algorithm())
23 1092 : .field("valid_from", &self.valid_from())
24 1092 : .field("valid_to", &self.valid_to())
25 1092 : .field("issuer", &self.issuer())
26 1092 : .field("key_type", &self.key_type())
27 1092 : .field("subject", &self.subject())
28 1092 : .field("is_ca", &self.is_ca())
29 1092 : .finish()
30 1092 : }
31 : }
32 :
33 : impl<'a> FromFFI<ffi::PE_x509> for X509<'a> {
34 1092 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_x509>) -> Self {
35 1092 : X509 {
36 1092 : ptr,
37 1092 : _owner: PhantomData,
38 1092 : }
39 1092 : }
40 : }
41 :
42 : #[allow(non_camel_case_types)]
43 1092 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
44 : /// Public key scheme
45 : pub enum KeyType {
46 : /// Unknown scheme
47 : NONE,
48 :
49 : /// RSA Scheme
50 : RSA,
51 :
52 : /// Elliptic-curve scheme
53 : ECKEY,
54 :
55 : /// Elliptic-curve Diffie-Hellman
56 : ECKEY_DH,
57 :
58 : /// Elliptic-curve Digital Signature Algorithm
59 : ECDSA,
60 :
61 : /// RSA scheme with an alternative implementation for signing and decrypting
62 : RSA_ALT,
63 :
64 : /// RSA Probabilistic signature scheme
65 : RSASSA_PSS,
66 : UNKNOWN(u32),
67 : }
68 :
69 : impl From<u32> for KeyType {
70 1092 : fn from(value: u32) -> Self {
71 1092 : match value {
72 0 : 0x00000000 => KeyType::NONE,
73 1092 : 0x00000001 => KeyType::RSA,
74 0 : 0x00000002 => KeyType::ECKEY,
75 0 : 0x00000003 => KeyType::ECKEY_DH,
76 0 : 0x00000004 => KeyType::ECDSA,
77 0 : 0x00000005 => KeyType::RSA_ALT,
78 0 : 0x00000006 => KeyType::RSASSA_PSS,
79 0 : _ => KeyType::UNKNOWN(value),
80 : }
81 1092 : }
82 : }
83 :
84 : /// Key usage as defined in RFC #5280 - section-4.2.1.3
85 : #[allow(non_camel_case_types)]
86 0 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
87 : pub enum KeyUsage {
88 : /// The key is used for digital signature
89 : DIGITAL_SIGNATURE,
90 : /// The key is used for digital signature and to protect against falsely denying some action
91 : NON_REPUDIATION,
92 : /// The key is used for enciphering private or secret keys
93 : KEY_ENCIPHERMENT,
94 : /// The key is used for directly enciphering raw user data without an intermediate symmetric cipher
95 : DATA_ENCIPHERMENT,
96 : /// The key is used for key agreement (e.g. with Diffie-Hellman)
97 : KEY_AGREEMENT,
98 : /// The key is used for verifying signatures on public key certificates
99 : KEY_CERT_SIGN,
100 : /// The key is used for verifying signatures on certificate revocation lists
101 : CRL_SIGN,
102 : /// In association with KEY_AGREEMENT, the key is only used for enciphering data
103 : ENCIPHER_ONLY,
104 : /// In association with KEY_AGREEMENT, the key is only used for deciphering data
105 : DECIPHER_ONLY,
106 : UNKNOWN(u32),
107 : }
108 :
109 : impl From<u32> for KeyUsage {
110 0 : fn from(value: u32) -> Self {
111 0 : match value {
112 0 : 0x00000000 => KeyUsage::DIGITAL_SIGNATURE,
113 0 : 0x00000001 => KeyUsage::NON_REPUDIATION,
114 0 : 0x00000002 => KeyUsage::KEY_ENCIPHERMENT,
115 0 : 0x00000003 => KeyUsage::DATA_ENCIPHERMENT,
116 0 : 0x00000004 => KeyUsage::KEY_AGREEMENT,
117 0 : 0x00000005 => KeyUsage::KEY_CERT_SIGN,
118 0 : 0x00000006 => KeyUsage::CRL_SIGN,
119 0 : 0x00000007 => KeyUsage::ENCIPHER_ONLY,
120 0 : 0x00000008 => KeyUsage::DECIPHER_ONLY,
121 0 : _ => KeyUsage::UNKNOWN(value),
122 : }
123 0 : }
124 : }
125 :
126 : impl From<KeyUsage> for u32 {
127 0 : fn from(value: KeyUsage) -> u32 {
128 0 : match value {
129 0 : KeyUsage::DIGITAL_SIGNATURE => 0x00000000,
130 0 : KeyUsage::NON_REPUDIATION => 0x00000001,
131 0 : KeyUsage::KEY_ENCIPHERMENT => 0x00000002,
132 0 : KeyUsage::DATA_ENCIPHERMENT => 0x00000003,
133 0 : KeyUsage::KEY_AGREEMENT => 0x00000004,
134 0 : KeyUsage::KEY_CERT_SIGN => 0x00000005,
135 0 : KeyUsage::CRL_SIGN => 0x00000006,
136 0 : KeyUsage::ENCIPHER_ONLY => 0x00000007,
137 0 : KeyUsage::DECIPHER_ONLY => 0x00000008,
138 0 : KeyUsage::UNKNOWN(v) => v,
139 : }
140 0 : }
141 : }
142 :
143 0 : bitflags! {
144 0 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
145 0 : /// Mirror of mbedtls X509 verification flags for certificate verification
146 0 : pub struct VerificationFlags: u32 {
147 0 : const OK = 0;
148 0 : const BADCERT_EXPIRED = 1 << 0;
149 0 : const BADCERT_REVOKED = 1 << 1;
150 0 : const BADCERT_CN_MISMATCH = 1 << 2;
151 0 : const BADCERT_NOT_TRUSTED = 1 << 3;
152 0 : const BADCRL_NOT_TRUSTED = 1 << 4;
153 0 : const BADCRL_EXPIRED = 1 << 5;
154 0 : const BADCERT_MISSING = 1 << 6;
155 0 : const BADCERT_SKIP_VERIFY = 1 << 7;
156 0 : const BADCERT_OTHER = 1 << 8;
157 0 : const BADCERT_FUTURE = 1 << 9;
158 0 : const BADCRL_FUTURE = 1 << 10;
159 0 : const BADCERT_KEY_USAGE = 1 << 11;
160 0 : const BADCERT_EXT_KEY_USAGE = 1 << 12;
161 0 : const BADCERT_NS_CERT_TYPE = 1 << 13;
162 0 : const BADCERT_BAD_MD = 1 << 14;
163 0 : const BADCERT_BAD_PK = 1 << 15;
164 0 : const BADCERT_BAD_KEY = 1 << 16;
165 0 : const BADCRL_BAD_MD = 1 << 17;
166 0 : const BADCRL_BAD_PK = 1 << 18;
167 0 : const BADCRL_BAD_KEY = 1 << 19;
168 0 : }
169 0 : }
170 :
171 : impl std::fmt::Display for VerificationFlags {
172 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
173 0 : bitflags::parser::to_writer(self, f)
174 0 : }
175 : }
176 :
177 : impl From<u32> for VerificationFlags {
178 0 : fn from(value: u32) -> Self {
179 0 : VerificationFlags::from_bits_truncate(value)
180 0 : }
181 : }
182 :
183 : impl From<VerificationFlags> for u32 {
184 0 : fn from(value: VerificationFlags) -> Self {
185 0 : value.bits()
186 0 : }
187 : }
188 :
189 : impl VerificationFlags {
190 0 : pub fn is_ok(self) -> bool {
191 0 : self == VerificationFlags::OK
192 0 : }
193 : }
194 :
195 : impl X509<'_> {
196 : /// X.509 version. (1=v1, 2=v2, 3=v3)
197 1092 : pub fn version(&self) -> u32 {
198 1092 : self.ptr.version()
199 1092 : }
200 :
201 : /// Unique id for certificate issued by a specific CA.
202 884 : pub fn serial_number(&self) -> Vec<u8> {
203 884 : Vec::from(self.ptr.serial_number().as_slice())
204 884 : }
205 :
206 : /// Signature algorithm (OID)
207 1092 : pub fn signature_algorithm(&self) -> String {
208 1092 : self.ptr.signature_algorithm().to_string()
209 1092 : }
210 :
211 : /// Start time of certificate validity
212 1092 : pub fn valid_from(&self) -> Vec<u64> {
213 1092 : Vec::from(self.ptr.valid_from().as_slice())
214 1092 : }
215 :
216 : /// End time of certificate validity
217 1092 : pub fn valid_to(&self) -> Vec<u64> {
218 1092 : Vec::from(self.ptr.valid_to().as_slice())
219 1092 : }
220 :
221 : /// Issuer information
222 1092 : pub fn issuer(&self) -> String {
223 1092 : self.ptr.issuer().to_string()
224 1092 : }
225 :
226 : /// Subject information
227 1092 : pub fn subject(&self) -> String {
228 1092 : self.ptr.subject().to_string()
229 1092 : }
230 :
231 : /// The raw x509 bytes (DER encoded)
232 884 : pub fn raw(&self) -> Vec<u8> {
233 884 : Vec::from(self.ptr.raw().as_slice())
234 884 : }
235 :
236 : /// Return the underlying public-key scheme
237 1092 : pub fn key_type(&self) -> KeyType {
238 1092 : KeyType::from(self.ptr.key_type())
239 1092 : }
240 1092 : pub fn is_ca(&self) -> bool {
241 1092 : self.ptr.is_ca()
242 1092 : }
243 :
244 : /// The signature of the certificate
245 884 : pub fn signature(&self) -> Vec<u8> {
246 884 : Vec::from(self.ptr.signature().as_slice())
247 884 : }
248 :
249 : /// **If** the underlying public-key scheme is RSA, return the RSA information.
250 884 : pub fn rsa_info(&self) -> Option<RsaInfo<'_>> {
251 884 : into_optional(self.ptr.rsa_info())
252 884 : }
253 :
254 : /// Try to decrypt the given signature and check if it matches the given hash according to
255 : /// the hash algorithm provided
256 0 : pub fn check_signature(&self, hash: &[u8], signature: &[u8], digest: Algorithms) -> bool {
257 0 : unsafe {
258 0 : self.ptr.check_signature(
259 0 : hash.as_ptr(),
260 0 : hash.len(),
261 0 : signature.as_ptr(),
262 0 : signature.len(),
263 0 : digest.into(),
264 0 : )
265 0 : }
266 0 : }
267 :
268 : /// Verify that this certificate has been used **to trust** the given certificate
269 0 : pub fn verify(&self, ca: &X509) -> VerificationFlags {
270 0 : VerificationFlags::from(self.ptr.verify(ca.ptr.as_ref().unwrap()))
271 0 : }
272 :
273 : /// Return the key usage extensions of this certificate
274 0 : pub fn key_usage(&self) -> Vec<KeyUsage> {
275 0 : self.ptr
276 0 : .key_usage()
277 0 : .into_iter()
278 0 : .map(|e| KeyUsage::from(*e))
279 0 : .collect()
280 0 : }
281 :
282 : /// Return the extended key usage OIDs of this certificate
283 0 : pub fn ext_key_usage(&self) -> Vec<String> {
284 0 : self.ptr
285 0 : .ext_key_usage()
286 0 : .into_iter()
287 0 : .map(|e| e.to_string())
288 0 : .collect()
289 0 : }
290 :
291 : /// Return the certificate policies OIDs of this certificate
292 0 : pub fn certificate_policies(&self) -> Vec<String> {
293 0 : self.ptr
294 0 : .certificate_policies()
295 0 : .into_iter()
296 0 : .map(|e| e.to_string())
297 0 : .collect()
298 0 : }
299 : }
300 :
301 676 : declare_iterator!(
302 676 : Certificates,
303 676 : X509<'a>,
304 676 : ffi::PE_x509,
305 676 : ffi::PE_Signature,
306 676 : ffi::PE_Signature_it_certificates
307 676 : );
|