Loading openssl/src/x509/mod.rs +41 −0 Original line number Diff line number Diff line Loading @@ -1746,6 +1746,17 @@ unsafe impl ExtensionType for CertificateIssuer { type Output = Stack<GeneralName>; } /// The CRL extension identifying how to access information and services for the issuer of the CRL pub enum AuthorityInformationAccess {} // SAFETY: AuthorityInformationAccess is defined to be a stack of AccessDescription in the RFC // and in OpenSSL. unsafe impl ExtensionType for AuthorityInformationAccess { const NID: Nid = Nid::from_raw(ffi::NID_info_access); type Output = Stack<AccessDescription>; } foreign_type_and_impl_send_sync! { type CType = ffi::X509_CRL; fn drop = ffi::X509_CRL_free; Loading Loading @@ -1915,6 +1926,36 @@ impl X509CrlRef { { unsafe { cvt_n(ffi::X509_CRL_verify(self.as_ptr(), key.as_ptr())).map(|n| n != 0) } } /// Get the criticality and value of an extension. /// /// This returns None if the extension is not present or occurs multiple times. #[corresponds(X509_CRL_get_ext_d2i)] pub fn extension<T: ExtensionType>(&self) -> Result<Option<(bool, T::Output)>, ErrorStack> { let mut critical = -1; let out = unsafe { // SAFETY: self.as_ptr() is a valid pointer to an X509_CRL. let ext = ffi::X509_CRL_get_ext_d2i( self.as_ptr(), T::NID.as_raw(), &mut critical as *mut _, ptr::null_mut(), ); // SAFETY: Extensions's contract promises that the type returned by // OpenSSL here is T::Output. T::Output::from_ptr_opt(ext as *mut _) }; match (critical, out) { (0, Some(out)) => Ok(Some((false, out))), (1, Some(out)) => Ok(Some((true, out))), // -1 means the extension wasn't found, -2 means multiple were found. (-1 | -2, _) => Ok(None), // A critical value of 0 or 1 suggests success, but a null pointer // was returned so something went wrong. (0 | 1, None) => Err(ErrorStack::get()), (c_int::MIN..=-2 | 2.., _) => panic!("OpenSSL should only return -2, -1, 0, or 1 for an extension's criticality but it returned {}", critical), } } } /// The result of peer certificate verification. Loading openssl/src/x509/tests.rs +19 −1 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ use hex::{self, FromHex}; #[cfg(any(ossl102, libressl261))] use libc::time_t; use super::{CertificateIssuer, ReasonCode}; use super::{AuthorityInformationAccess, CertificateIssuer, ReasonCode}; fn pkey() -> PKey<Private> { let rsa = Rsa::generate(2048).unwrap(); Loading Loading @@ -701,6 +701,24 @@ fn test_crl_entry_extensions() { let crl = include_bytes!("../../test/entry_extensions.crl"); let crl = X509Crl::from_pem(crl).unwrap(); let (critical, access_info) = crl .extension::<AuthorityInformationAccess>() .unwrap() .expect("Authority Information Access extension should be present"); assert!( !critical, "Authority Information Access extension is not critical" ); assert_eq!( access_info.len(), 1, "Authority Information Access should have one entry" ); assert_eq!(access_info[0].method().to_string(), "CA Issuers"); assert_eq!( access_info[0].location().uri(), Some("http://www.example.com/ca.crt") ); let revoked_certs = crl.get_revoked().unwrap(); let entry = &revoked_certs[0]; Loading openssl/test/entry_extensions.crl +9 −8 Original line number Diff line number Diff line -----BEGIN X509 CRL----- MIIBXDCCAQICAQEwCgYIKoZIzj0EAwIwETEPMA0GA1UEAwwGQ1JMIENBFw0yMzAz MjgwOTQ5MThaFw0yMzA0MDQwOTUwMDdaMIGAMH4CFE+Y95/1pOqa6c9fUEJ8c04k xu2PFw0yMzAzMjgwOTQ3MzNaMFcwLwYDVR0dAQH/BCUwI6QhMB8xCzAJBgNVBAYT AkdCMRAwDgYDVQQDDAdUZXN0IENBMAoGA1UdFQQDCgEBMBgGA1UdGAQRGA8yMDIz MDMyODA5NDQ0MFqgPTA7MB8GA1UdIwQYMBaAFNX1GZ0RWuC+4gz1wuy5H32T2W+R MAoGA1UdFAQDAgEUMAwGA1UdHAQFMAOEAf8wCgYIKoZIzj0EAwIDSAAwRQIgbl7x W+WVAb+zlvKcJLmHVuC+gbqR4jqwGIHHgQl2J8kCIQCo/sAF5sDqy/cL+fbzBeUe YoY2h6lIkj9ENwU8ZCt03w== MIIBojCCAUkCAQEwCgYIKoZIzj0EAwIwHTEbMBkGA1UEAwwSY3J5cHRvZ3JhcGh5 LmlvIENBFw0yMzA3MjUxNDA1MzlaFw0yMzA4MDExNDA1MzlaMIGAMH4CFE+Y95/1 pOqa6c9fUEJ8c04kxu2PFw0yMzA3MjUxNDA1MzlaMFcwLwYDVR0dAQH/BCUwI6Qh MB8xCzAJBgNVBAYTAkdCMRAwDgYDVQQDDAdUZXN0IENBMAoGA1UdFQQDCgEBMBgG A1UdGAQRGA8yMDIzMDcyNTE0MDUzOVqgeDB2MB8GA1UdIwQYMBaAFK6qKNgsGefh XexO9WsIwiQ/73R8MAoGA1UdFAQDAgEUMAwGA1UdHAQFMAOEAf8wOQYIKwYBBQUH AQEELTArMCkGCCsGAQUFBzAChh1odHRwOi8vd3d3LmV4YW1wbGUuY29tL2NhLmNy dDAKBggqhkjOPQQDAgNHADBEAiB22SXxFnQUB41uxfyCvg2dAs2nFiR0r8jft/cd G8zcKAIgeYkNOzRn4lyopK6J94rhm8jIIuJRj3Ns9XcH+91N370= -----END X509 CRL----- Loading
openssl/src/x509/mod.rs +41 −0 Original line number Diff line number Diff line Loading @@ -1746,6 +1746,17 @@ unsafe impl ExtensionType for CertificateIssuer { type Output = Stack<GeneralName>; } /// The CRL extension identifying how to access information and services for the issuer of the CRL pub enum AuthorityInformationAccess {} // SAFETY: AuthorityInformationAccess is defined to be a stack of AccessDescription in the RFC // and in OpenSSL. unsafe impl ExtensionType for AuthorityInformationAccess { const NID: Nid = Nid::from_raw(ffi::NID_info_access); type Output = Stack<AccessDescription>; } foreign_type_and_impl_send_sync! { type CType = ffi::X509_CRL; fn drop = ffi::X509_CRL_free; Loading Loading @@ -1915,6 +1926,36 @@ impl X509CrlRef { { unsafe { cvt_n(ffi::X509_CRL_verify(self.as_ptr(), key.as_ptr())).map(|n| n != 0) } } /// Get the criticality and value of an extension. /// /// This returns None if the extension is not present or occurs multiple times. #[corresponds(X509_CRL_get_ext_d2i)] pub fn extension<T: ExtensionType>(&self) -> Result<Option<(bool, T::Output)>, ErrorStack> { let mut critical = -1; let out = unsafe { // SAFETY: self.as_ptr() is a valid pointer to an X509_CRL. let ext = ffi::X509_CRL_get_ext_d2i( self.as_ptr(), T::NID.as_raw(), &mut critical as *mut _, ptr::null_mut(), ); // SAFETY: Extensions's contract promises that the type returned by // OpenSSL here is T::Output. T::Output::from_ptr_opt(ext as *mut _) }; match (critical, out) { (0, Some(out)) => Ok(Some((false, out))), (1, Some(out)) => Ok(Some((true, out))), // -1 means the extension wasn't found, -2 means multiple were found. (-1 | -2, _) => Ok(None), // A critical value of 0 or 1 suggests success, but a null pointer // was returned so something went wrong. (0 | 1, None) => Err(ErrorStack::get()), (c_int::MIN..=-2 | 2.., _) => panic!("OpenSSL should only return -2, -1, 0, or 1 for an extension's criticality but it returned {}", critical), } } } /// The result of peer certificate verification. Loading
openssl/src/x509/tests.rs +19 −1 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ use hex::{self, FromHex}; #[cfg(any(ossl102, libressl261))] use libc::time_t; use super::{CertificateIssuer, ReasonCode}; use super::{AuthorityInformationAccess, CertificateIssuer, ReasonCode}; fn pkey() -> PKey<Private> { let rsa = Rsa::generate(2048).unwrap(); Loading Loading @@ -701,6 +701,24 @@ fn test_crl_entry_extensions() { let crl = include_bytes!("../../test/entry_extensions.crl"); let crl = X509Crl::from_pem(crl).unwrap(); let (critical, access_info) = crl .extension::<AuthorityInformationAccess>() .unwrap() .expect("Authority Information Access extension should be present"); assert!( !critical, "Authority Information Access extension is not critical" ); assert_eq!( access_info.len(), 1, "Authority Information Access should have one entry" ); assert_eq!(access_info[0].method().to_string(), "CA Issuers"); assert_eq!( access_info[0].location().uri(), Some("http://www.example.com/ca.crt") ); let revoked_certs = crl.get_revoked().unwrap(); let entry = &revoked_certs[0]; Loading
openssl/test/entry_extensions.crl +9 −8 Original line number Diff line number Diff line -----BEGIN X509 CRL----- MIIBXDCCAQICAQEwCgYIKoZIzj0EAwIwETEPMA0GA1UEAwwGQ1JMIENBFw0yMzAz MjgwOTQ5MThaFw0yMzA0MDQwOTUwMDdaMIGAMH4CFE+Y95/1pOqa6c9fUEJ8c04k xu2PFw0yMzAzMjgwOTQ3MzNaMFcwLwYDVR0dAQH/BCUwI6QhMB8xCzAJBgNVBAYT AkdCMRAwDgYDVQQDDAdUZXN0IENBMAoGA1UdFQQDCgEBMBgGA1UdGAQRGA8yMDIz MDMyODA5NDQ0MFqgPTA7MB8GA1UdIwQYMBaAFNX1GZ0RWuC+4gz1wuy5H32T2W+R MAoGA1UdFAQDAgEUMAwGA1UdHAQFMAOEAf8wCgYIKoZIzj0EAwIDSAAwRQIgbl7x W+WVAb+zlvKcJLmHVuC+gbqR4jqwGIHHgQl2J8kCIQCo/sAF5sDqy/cL+fbzBeUe YoY2h6lIkj9ENwU8ZCt03w== MIIBojCCAUkCAQEwCgYIKoZIzj0EAwIwHTEbMBkGA1UEAwwSY3J5cHRvZ3JhcGh5 LmlvIENBFw0yMzA3MjUxNDA1MzlaFw0yMzA4MDExNDA1MzlaMIGAMH4CFE+Y95/1 pOqa6c9fUEJ8c04kxu2PFw0yMzA3MjUxNDA1MzlaMFcwLwYDVR0dAQH/BCUwI6Qh MB8xCzAJBgNVBAYTAkdCMRAwDgYDVQQDDAdUZXN0IENBMAoGA1UdFQQDCgEBMBgG A1UdGAQRGA8yMDIzMDcyNTE0MDUzOVqgeDB2MB8GA1UdIwQYMBaAFK6qKNgsGefh XexO9WsIwiQ/73R8MAoGA1UdFAQDAgEUMAwGA1UdHAQFMAOEAf8wOQYIKwYBBQUH AQEELTArMCkGCCsGAQUFBzAChh1odHRwOi8vd3d3LmV4YW1wbGUuY29tL2NhLmNy dDAKBggqhkjOPQQDAgNHADBEAiB22SXxFnQUB41uxfyCvg2dAs2nFiR0r8jft/cd G8zcKAIgeYkNOzRn4lyopK6J94rhm8jIIuJRj3Ns9XcH+91N370= -----END X509 CRL-----