Loading openssl-sys/src/x509v3.rs +12 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,18 @@ extern "C" { pub fn GENERAL_NAME_free(name: *mut GENERAL_NAME); } #[repr(C)] pub struct ACCESS_DESCRIPTION { pub method: *mut ASN1_OBJECT, pub location: *mut GENERAL_NAME, } stack!(stack_st_ACCESS_DESCRIPTION); extern "C" { pub fn ACCESS_DESCRIPTION_free(ad: *mut ACCESS_DESCRIPTION); } #[repr(C)] pub struct AUTHORITY_KEYID { pub keyid: *mut ASN1_OCTET_STRING, Loading openssl/src/x509/mod.rs +44 −0 Original line number Diff line number Diff line Loading @@ -449,6 +449,24 @@ impl X509Ref { } } /// Returns this certificate's [`authority information access`] entries, if they exist. /// /// This corresponds to [`X509_get_ext_d2i`] called with `NID_info_access`. /// /// [`X509_get_ext_d2i`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_get_ext_d2i.html /// [`authority information access`]: https://tools.ietf.org/html/rfc5280#section-4.2.2.1 pub fn authority_info(&self) -> Option<Stack<AccessDescription>> { unsafe { let stack = ffi::X509_get_ext_d2i( self.as_ptr(), ffi::NID_info_access, ptr::null_mut(), ptr::null_mut(), ); Stack::from_ptr_opt(stack as *mut _) } } pub fn public_key(&self) -> Result<PKey<Public>, ErrorStack> { unsafe { let pkey = cvt_p(ffi::X509_get_pubkey(self.as_ptr()))?; Loading Loading @@ -1417,6 +1435,32 @@ impl Stackable for GeneralName { type StackType = ffi::stack_st_GENERAL_NAME; } foreign_type_and_impl_send_sync! { type CType = ffi::ACCESS_DESCRIPTION; fn drop = ffi::ACCESS_DESCRIPTION_free; /// `AccessDescription` of certificate authority information. pub struct AccessDescription; /// Reference to `AccessDescription`. pub struct AccessDescriptionRef; } impl AccessDescriptionRef { /// Returns the access method OID. pub fn method(&self) -> &Asn1ObjectRef { unsafe { Asn1ObjectRef::from_ptr((*self.as_ptr()).method) } } // Returns the access location. pub fn location(&self) -> &GeneralNameRef { unsafe { GeneralNameRef::from_ptr((*self.as_ptr()).location) } } } impl Stackable for AccessDescription { type StackType = ffi::stack_st_ACCESS_DESCRIPTION; } foreign_type_and_impl_send_sync! { type CType = ffi::X509_ALGOR; fn drop = ffi::X509_ALGOR_free; Loading openssl/src/x509/tests.rs +18 −0 Original line number Diff line number Diff line Loading @@ -177,6 +177,24 @@ fn test_subject_alt_name_iter() { assert!(subject_alt_names_iter.next().is_none()); } #[test] fn test_aia_ca_issuer() { // With AIA let cert = include_bytes!("../../test/aia_test_cert.pem"); let cert = X509::from_pem(cert).unwrap(); let authority_info = cert.authority_info().unwrap(); assert_eq!(authority_info.len(), 1); assert_eq!(authority_info[0].method().to_string(), "CA Issuers"); assert_eq!( authority_info[0].location().uri(), Some("http://www.example.com/cert.pem") ); // Without AIA let cert = include_bytes!("../../test/cert.pem"); let cert = X509::from_pem(cert).unwrap(); assert!(cert.authority_info().is_none()); } #[test] fn x509_builder() { let pkey = pkey(); Loading openssl/test/aia_test_cert.pem 0 → 100644 +22 −0 Original line number Diff line number Diff line -----BEGIN CERTIFICATE----- MIIDozCCAougAwIBAgIJAJayG40CARAjMA0GCSqGSIb3DQEBCwUAMA8xDTALBgNV BAMMBHRlc3QwHhcNMjEwMzAyMDA1NzQ3WhcNNDgwNzE4MDA1NzQ3WjBzMQswCQYD VQQGEwJYWDELMAkGA1UECAwCWFgxEDAOBgNVBAcMB25vd2hlcmUxEDAOBgNVBAoM B3Rlc3RvcmcxEjAQBgNVBAsMCXRlc3Rncm91cDEfMB0GA1UEAwwWbWFjaGluZS0w Lm15aG9zdC5teW5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANKA 3zhwC70hbxFVdC0dYk9BHaNntZ4LPUVwFSG2HBn34oO8zCp4wkH+VIi9vOhWiySK Gs3gW4qpjMbF82Gqc3dG2KfqUrOtWY+u54zAzqpgiJf08wmREHPoZmjqfCfgM3FO VMEA8g1BQxXEd+y7UEDoXhPIoeFnqzMu9sg4npnL9U5BLaQJiWnXHClnBrvAAKXW E8KDNmcavtFvo2xQVC09C6dJG5CrigWcZe4CaUl44rHiPaQd+jOp0HAccl/XLA0/ QyHvW6ksjco/mb7ia1U9ohaC/3NHmzUA1S3kdq/qgnkPsjmy5v8k5vizowNc5rFO XsV86BIv44rh1Jut52ECAwEAAaOBnTCBmjAMBgNVHRMEBTADAQH/MAsGA1UdDwQE AwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwIQYDVR0RBBowGIIW bWFjaGluZS0wLm15aG9zdC5teW5ldDA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUH MAKGH2h0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2VydC5wZW0wDQYJKoZIhvcNAQEL BQADggEBAH+ayx8qGvxzrG57jgXJudq+z783O6E2xGBJn1cT9Jhrg1VnlU+tHcNd fFcsp0gdQZCmm3pu3E0m/FsgTpfHUgdCOmZQp45QrxCz2oRdWQM71SSA/x1VfQ9w 670iZOEY15/ss2nRl0woaYO7tBVadpZfymW5+OhsTKn5gL0pVmW3RciHuAmbIvQO bouUwzuZIJMfca7T1MqZYdrKoJrOBj0LaPTutjfQB7O/02vUCPjTTIH20aqsMe5K KXCrjiZO2jkxQ49Hz5uwfPx12dSVHNLpsnfOAH+MUToeW+SPx2OPvl/uAHcph2lj MLA6Wi64rSUxzkcFLFsGpKcK6QKcHUw= -----END CERTIFICATE----- Loading
openssl-sys/src/x509v3.rs +12 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,18 @@ extern "C" { pub fn GENERAL_NAME_free(name: *mut GENERAL_NAME); } #[repr(C)] pub struct ACCESS_DESCRIPTION { pub method: *mut ASN1_OBJECT, pub location: *mut GENERAL_NAME, } stack!(stack_st_ACCESS_DESCRIPTION); extern "C" { pub fn ACCESS_DESCRIPTION_free(ad: *mut ACCESS_DESCRIPTION); } #[repr(C)] pub struct AUTHORITY_KEYID { pub keyid: *mut ASN1_OCTET_STRING, Loading
openssl/src/x509/mod.rs +44 −0 Original line number Diff line number Diff line Loading @@ -449,6 +449,24 @@ impl X509Ref { } } /// Returns this certificate's [`authority information access`] entries, if they exist. /// /// This corresponds to [`X509_get_ext_d2i`] called with `NID_info_access`. /// /// [`X509_get_ext_d2i`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_get_ext_d2i.html /// [`authority information access`]: https://tools.ietf.org/html/rfc5280#section-4.2.2.1 pub fn authority_info(&self) -> Option<Stack<AccessDescription>> { unsafe { let stack = ffi::X509_get_ext_d2i( self.as_ptr(), ffi::NID_info_access, ptr::null_mut(), ptr::null_mut(), ); Stack::from_ptr_opt(stack as *mut _) } } pub fn public_key(&self) -> Result<PKey<Public>, ErrorStack> { unsafe { let pkey = cvt_p(ffi::X509_get_pubkey(self.as_ptr()))?; Loading Loading @@ -1417,6 +1435,32 @@ impl Stackable for GeneralName { type StackType = ffi::stack_st_GENERAL_NAME; } foreign_type_and_impl_send_sync! { type CType = ffi::ACCESS_DESCRIPTION; fn drop = ffi::ACCESS_DESCRIPTION_free; /// `AccessDescription` of certificate authority information. pub struct AccessDescription; /// Reference to `AccessDescription`. pub struct AccessDescriptionRef; } impl AccessDescriptionRef { /// Returns the access method OID. pub fn method(&self) -> &Asn1ObjectRef { unsafe { Asn1ObjectRef::from_ptr((*self.as_ptr()).method) } } // Returns the access location. pub fn location(&self) -> &GeneralNameRef { unsafe { GeneralNameRef::from_ptr((*self.as_ptr()).location) } } } impl Stackable for AccessDescription { type StackType = ffi::stack_st_ACCESS_DESCRIPTION; } foreign_type_and_impl_send_sync! { type CType = ffi::X509_ALGOR; fn drop = ffi::X509_ALGOR_free; Loading
openssl/src/x509/tests.rs +18 −0 Original line number Diff line number Diff line Loading @@ -177,6 +177,24 @@ fn test_subject_alt_name_iter() { assert!(subject_alt_names_iter.next().is_none()); } #[test] fn test_aia_ca_issuer() { // With AIA let cert = include_bytes!("../../test/aia_test_cert.pem"); let cert = X509::from_pem(cert).unwrap(); let authority_info = cert.authority_info().unwrap(); assert_eq!(authority_info.len(), 1); assert_eq!(authority_info[0].method().to_string(), "CA Issuers"); assert_eq!( authority_info[0].location().uri(), Some("http://www.example.com/cert.pem") ); // Without AIA let cert = include_bytes!("../../test/cert.pem"); let cert = X509::from_pem(cert).unwrap(); assert!(cert.authority_info().is_none()); } #[test] fn x509_builder() { let pkey = pkey(); Loading
openssl/test/aia_test_cert.pem 0 → 100644 +22 −0 Original line number Diff line number Diff line -----BEGIN CERTIFICATE----- MIIDozCCAougAwIBAgIJAJayG40CARAjMA0GCSqGSIb3DQEBCwUAMA8xDTALBgNV BAMMBHRlc3QwHhcNMjEwMzAyMDA1NzQ3WhcNNDgwNzE4MDA1NzQ3WjBzMQswCQYD VQQGEwJYWDELMAkGA1UECAwCWFgxEDAOBgNVBAcMB25vd2hlcmUxEDAOBgNVBAoM B3Rlc3RvcmcxEjAQBgNVBAsMCXRlc3Rncm91cDEfMB0GA1UEAwwWbWFjaGluZS0w Lm15aG9zdC5teW5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANKA 3zhwC70hbxFVdC0dYk9BHaNntZ4LPUVwFSG2HBn34oO8zCp4wkH+VIi9vOhWiySK Gs3gW4qpjMbF82Gqc3dG2KfqUrOtWY+u54zAzqpgiJf08wmREHPoZmjqfCfgM3FO VMEA8g1BQxXEd+y7UEDoXhPIoeFnqzMu9sg4npnL9U5BLaQJiWnXHClnBrvAAKXW E8KDNmcavtFvo2xQVC09C6dJG5CrigWcZe4CaUl44rHiPaQd+jOp0HAccl/XLA0/ QyHvW6ksjco/mb7ia1U9ohaC/3NHmzUA1S3kdq/qgnkPsjmy5v8k5vizowNc5rFO XsV86BIv44rh1Jut52ECAwEAAaOBnTCBmjAMBgNVHRMEBTADAQH/MAsGA1UdDwQE AwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwIQYDVR0RBBowGIIW bWFjaGluZS0wLm15aG9zdC5teW5ldDA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUH MAKGH2h0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2VydC5wZW0wDQYJKoZIhvcNAQEL BQADggEBAH+ayx8qGvxzrG57jgXJudq+z783O6E2xGBJn1cT9Jhrg1VnlU+tHcNd fFcsp0gdQZCmm3pu3E0m/FsgTpfHUgdCOmZQp45QrxCz2oRdWQM71SSA/x1VfQ9w 670iZOEY15/ss2nRl0woaYO7tBVadpZfymW5+OhsTKn5gL0pVmW3RciHuAmbIvQO bouUwzuZIJMfca7T1MqZYdrKoJrOBj0LaPTutjfQB7O/02vUCPjTTIH20aqsMe5K KXCrjiZO2jkxQ49Hz5uwfPx12dSVHNLpsnfOAH+MUToeW+SPx2OPvl/uAHcph2lj MLA6Wi64rSUxzkcFLFsGpKcK6QKcHUw= -----END CERTIFICATE-----