1 use ffi; 2 use foreign_types::ForeignTypeRef; 3 use libc::{c_uint, c_ulong}; 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 bitflags! { 27 /// Flags used to verify an `X509` certificate chain. 28 pub struct X509VerifyFlags: c_ulong { 29 const CB_ISSUER_CHECK = ffi::X509_V_FLAG_CB_ISSUER_CHECK; 30 const USE_CHECK_TIME = ffi::X509_V_FLAG_USE_CHECK_TIME; 31 const CRL_CHECK = ffi::X509_V_FLAG_CRL_CHECK; 32 const CRL_CHECK_ALL = ffi::X509_V_FLAG_CRL_CHECK_ALL; 33 const IGNORE_CRITICAL = ffi::X509_V_FLAG_X509_STRICT; 34 const X509_STRICT = ffi::X509_V_FLAG_IGNORE_CRITICAL; 35 const ALLOW_PROXY_CERTS = ffi::X509_V_FLAG_ALLOW_PROXY_CERTS; 36 const POLICY_CHECK = ffi::X509_V_FLAG_POLICY_CHECK; 37 const EXPLICIT_POLICY = ffi::X509_V_FLAG_EXPLICIT_POLICY; 38 const INHIBIT_ANY = ffi::X509_V_FLAG_INHIBIT_ANY; 39 const INHIBIT_MAP = ffi::X509_V_FLAG_INHIBIT_MAP; 40 const NOTIFY_POLICY = ffi::X509_V_FLAG_NOTIFY_POLICY; 41 const EXTENDED_CRL_SUPPORT = ffi::X509_V_FLAG_EXTENDED_CRL_SUPPORT; 42 const USE_DELTAS = ffi::X509_V_FLAG_USE_DELTAS; 43 const CHECK_SS_SIGNATURE = ffi::X509_V_FLAG_CHECK_SS_SIGNATURE; 44 #[cfg(ossl102)] 45 const TRUSTED_FIRST = ffi::X509_V_FLAG_TRUSTED_FIRST; 46 #[cfg(ossl102)] 47 const SUITEB_128_LOS_ONLY = ffi::X509_V_FLAG_SUITEB_128_LOS_ONLY; 48 #[cfg(ossl102)] 49 const SUITEB_192_LOS = ffi::X509_V_FLAG_SUITEB_128_LOS; 50 #[cfg(ossl102)] 51 const SUITEB_128_LOS = ffi::X509_V_FLAG_SUITEB_192_LOS; 52 #[cfg(ossl102)] 53 const PARTIAL_CHAIN = ffi::X509_V_FLAG_PARTIAL_CHAIN; 54 #[cfg(ossl110)] 55 const NO_ALT_CHAINS = ffi::X509_V_FLAG_NO_ALT_CHAINS; 56 #[cfg(ossl110)] 57 const NO_CHECK_TIME = ffi::X509_V_FLAG_NO_CHECK_TIME; 58 } 59 } 60 61 foreign_type_and_impl_send_sync! { 62 type CType = ffi::X509_VERIFY_PARAM; 63 fn drop = ffi::X509_VERIFY_PARAM_free; 64 65 /// Adjust parameters associated with certificate verification. 66 pub struct X509VerifyParam; 67 /// Reference to `X509VerifyParam`. 68 pub struct X509VerifyParamRef; 69 } 70 71 impl X509VerifyParamRef { 72 /// Set the host flags. 73 /// 74 /// This corresponds to [`X509_VERIFY_PARAM_set_hostflags`]. 75 /// 76 /// [`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)77 pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) { 78 unsafe { 79 ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits); 80 } 81 } 82 83 /// Set verification flags. 84 /// 85 /// This corresponds to [`X509_VERIFY_PARAM_set_flags`]. 86 /// 87 /// [`X509_VERIFY_PARAM_set_flags`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_VERIFY_PARAM_set_flags.html set_flags(&mut self, flags: X509VerifyFlags) -> Result<(), ErrorStack>88 pub fn set_flags(&mut self, flags: X509VerifyFlags) -> Result<(), ErrorStack> { 89 unsafe { cvt(ffi::X509_VERIFY_PARAM_set_flags(self.as_ptr(), flags.bits)).map(|_| ()) } 90 } 91 92 /// Clear verification flags. 93 /// 94 /// This corresponds to [`X509_VERIFY_PARAM_clear_flags`]. 95 /// 96 /// [`X509_VERIFY_PARAM_clear_flags`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_VERIFY_PARAM_clear_flags.html clear_flags(&mut self, flags: X509VerifyFlags) -> Result<(), ErrorStack>97 pub fn clear_flags(&mut self, flags: X509VerifyFlags) -> Result<(), ErrorStack> { 98 unsafe { 99 cvt(ffi::X509_VERIFY_PARAM_clear_flags( 100 self.as_ptr(), 101 flags.bits, 102 )) 103 .map(|_| ()) 104 } 105 } 106 107 /// Gets verification flags. 108 /// 109 /// This corresponds to [`X509_VERIFY_PARAM_get_flags`]. 110 /// 111 /// [`X509_VERIFY_PARAM_get_flags`]: https://www.openssl.org/docs/man1.0.2/crypto/X509_VERIFY_PARAM_get_flags.html flags(&mut self) -> X509VerifyFlags112 pub fn flags(&mut self) -> X509VerifyFlags { 113 let bits = unsafe { ffi::X509_VERIFY_PARAM_get_flags(self.as_ptr()) }; 114 X509VerifyFlags { bits } 115 } 116 117 /// Set the expected DNS hostname. 118 /// 119 /// This corresponds to [`X509_VERIFY_PARAM_set1_host`]. 120 /// 121 /// [`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>122 pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> { 123 unsafe { 124 cvt(ffi::X509_VERIFY_PARAM_set1_host( 125 self.as_ptr(), 126 host.as_ptr() as *const _, 127 host.len(), 128 )) 129 .map(|_| ()) 130 } 131 } 132 133 /// Set the expected IPv4 or IPv6 address. 134 /// 135 /// This corresponds to [`X509_VERIFY_PARAM_set1_ip`]. 136 /// 137 /// [`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>138 pub fn set_ip(&mut self, ip: IpAddr) -> Result<(), ErrorStack> { 139 unsafe { 140 let mut buf = [0; 16]; 141 let len = match ip { 142 IpAddr::V4(addr) => { 143 buf[..4].copy_from_slice(&addr.octets()); 144 4 145 } 146 IpAddr::V6(addr) => { 147 buf.copy_from_slice(&addr.octets()); 148 16 149 } 150 }; 151 cvt(ffi::X509_VERIFY_PARAM_set1_ip( 152 self.as_ptr(), 153 buf.as_ptr() as *const _, 154 len, 155 )) 156 .map(|_| ()) 157 } 158 } 159 } 160