1 use ffi;
2 use foreign_types::ForeignTypeRef;
3 use libc::c_uint;
4 use std::net::IpAddr;
5 
6 use cvt;
7 use error::ErrorStack;
8 
9 bitflags! {
10     /// Flags used to check an `X509` certificate.
11     pub struct X509CheckFlags: c_uint {
12         const ALWAYS_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT;
13         const NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS;
14         const NO_PARTIAL_WILDCARDS = ffi::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS;
15         const MULTI_LABEL_WILDCARDS = ffi::X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS;
16         const SINGLE_LABEL_SUBDOMAINS = ffi::X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS;
17         /// Requires OpenSSL 1.1.0 or newer.
18         #[cfg(any(ossl110))]
19         const NEVER_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_NEVER_CHECK_SUBJECT;
20 
21         #[deprecated(since = "0.10.6", note = "renamed to NO_WILDCARDS")]
22         const FLAG_NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS;
23     }
24 }
25 
26 foreign_type_and_impl_send_sync! {
27     type CType = ffi::X509_VERIFY_PARAM;
28     fn drop = ffi::X509_VERIFY_PARAM_free;
29 
30     /// Adjust parameters associated with certificate verification.
31     pub struct X509VerifyParam;
32     /// Reference to `X509VerifyParam`.
33     pub struct X509VerifyParamRef;
34 }
35 
36 impl X509VerifyParamRef {
37     /// Set the host flags.
38     ///
39     /// This corresponds to [`X509_VERIFY_PARAM_set_hostflags`].
40     ///
41     /// [`X509_VERIFY_PARAM_set_hostflags`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set_hostflags.html
set_hostflags(&mut self, hostflags: X509CheckFlags)42     pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) {
43         unsafe {
44             ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits);
45         }
46     }
47 
48     /// Set the expected DNS hostname.
49     ///
50     /// This corresponds to [`X509_VERIFY_PARAM_set1_host`].
51     ///
52     /// [`X509_VERIFY_PARAM_set1_host`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set1_host.html
set_host(&mut self, host: &str) -> Result<(), ErrorStack>53     pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> {
54         unsafe {
55             cvt(ffi::X509_VERIFY_PARAM_set1_host(
56                 self.as_ptr(),
57                 host.as_ptr() as *const _,
58                 host.len(),
59             ))
60             .map(|_| ())
61         }
62     }
63 
64     /// Set the expected IPv4 or IPv6 address.
65     ///
66     /// This corresponds to [`X509_VERIFY_PARAM_set1_ip`].
67     ///
68     /// [`X509_VERIFY_PARAM_set1_ip`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set1_ip.html
set_ip(&mut self, ip: IpAddr) -> Result<(), ErrorStack>69     pub fn set_ip(&mut self, ip: IpAddr) -> Result<(), ErrorStack> {
70         unsafe {
71             let mut buf = [0; 16];
72             let len = match ip {
73                 IpAddr::V4(addr) => {
74                     buf[..4].copy_from_slice(&addr.octets());
75                     4
76                 }
77                 IpAddr::V6(addr) => {
78                     buf.copy_from_slice(&addr.octets());
79                     16
80                 }
81             };
82             cvt(ffi::X509_VERIFY_PARAM_set1_ip(
83                 self.as_ptr(),
84                 buf.as_ptr() as *const _,
85                 len,
86             ))
87             .map(|_| ())
88         }
89     }
90 }
91