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