Unverified Commit f14f7a7c authored by Jack Rickard's avatar Jack Rickard Committed by GitHub
Browse files

Merge pull request #1123 from jrobsonchase/crl_bindings

Basic CRL Bindings
parents 4adb25c0 154bc4a7
Loading
Loading
Loading
Loading
+259 −0
Original line number Diff line number Diff line
@@ -1421,6 +1421,230 @@ impl X509ReqRef {
    }
}

foreign_type_and_impl_send_sync! {
    type CType = ffi::X509_REVOKED;
    fn drop = ffi::X509_REVOKED_free;

    /// An `X509` certificate request.
    pub struct X509Revoked;
    /// Reference to `X509Crl`.
    pub struct X509RevokedRef;
}

impl Stackable for X509Revoked {
    type StackType = ffi::stack_st_X509_REVOKED;
}

impl X509Revoked {
    from_der! {
        /// Deserializes a DER-encoded certificate revocation status
        #[corresponds(d2i_X509_REVOKED)]
        from_der,
        X509Revoked,
        ffi::d2i_X509_REVOKED
    }
}

impl X509RevokedRef {
    to_der! {
        /// Serializes the certificate request to a DER-encoded certificate revocation status
        #[corresponds(d2i_X509_REVOKED)]
        to_der,
        ffi::i2d_X509_REVOKED
    }

    /// Get the date that the certificate was revoked
    #[corresponds(X509_REVOKED_get0_revocationDate)]
    pub fn revocation_date(&self) -> &Asn1TimeRef {
        unsafe {
            let r = X509_REVOKED_get0_revocationDate(self.as_ptr() as *const _);
            assert!(!r.is_null());
            Asn1TimeRef::from_ptr(r as *mut _)
        }
    }

    /// Get the serial number of the revoked certificate
    #[corresponds(X509_REVOKED_get0_serialNumber)]
    pub fn serial_number(&self) -> &Asn1IntegerRef {
        unsafe {
            let r = X509_REVOKED_get0_serialNumber(self.as_ptr() as *const _);
            assert!(!r.is_null());
            Asn1IntegerRef::from_ptr(r as *mut _)
        }
    }
}

foreign_type_and_impl_send_sync! {
    type CType = ffi::X509_CRL;
    fn drop = ffi::X509_CRL_free;

    /// An `X509` certificate request.
    pub struct X509Crl;
    /// Reference to `X509Crl`.
    pub struct X509CrlRef;
}

/// The status of a certificate in a revoction list
///
/// Corresponds to the return value from the [`X509_CRL_get0_by_*`] methods.
///
/// [`X509_CRL_get0_by_*`]: https://www.openssl.org/docs/man1.1.0/man3/X509_CRL_get0_by_serial.html
pub enum CrlStatus<'a> {
    /// The certificate is not present in the list
    NotRevoked,
    /// The certificate is in the list and is revoked
    Revoked(&'a X509RevokedRef),
    /// The certificate is in the list, but has the "removeFromCrl" status.
    ///
    /// This can occur if the certificate was revoked with the "CertificateHold"
    /// reason, and has since been unrevoked.
    RemoveFromCrl(&'a X509RevokedRef),
}

impl<'a> CrlStatus<'a> {
    // Helper used by the X509_CRL_get0_by_* methods to convert their return
    // value to the status enum.
    // Safety note: the returned CrlStatus must not outlive the owner of the
    // revoked_entry pointer.
    unsafe fn from_ffi_status(
        status: c_int,
        revoked_entry: *mut ffi::X509_REVOKED,
    ) -> CrlStatus<'a> {
        match status {
            0 => CrlStatus::NotRevoked,
            1 => {
                assert!(!revoked_entry.is_null());
                CrlStatus::Revoked(X509RevokedRef::from_ptr(revoked_entry))
            }
            2 => {
                assert!(!revoked_entry.is_null());
                CrlStatus::RemoveFromCrl(X509RevokedRef::from_ptr(revoked_entry))
            }
            _ => unreachable!(
                "{}",
                "X509_CRL_get0_by_{{serial,cert}} should only return 0, 1, or 2."
            ),
        }
    }
}

impl X509Crl {
    from_pem! {
        /// Deserializes a PEM-encoded Certificate Revocation List
        ///
        /// The input should have a header of `-----BEGIN X509 CRL-----`.
        #[corresponds(PEM_read_bio_X509_CRL)]
        from_pem,
        X509Crl,
        ffi::PEM_read_bio_X509_CRL
    }

    from_der! {
        /// Deserializes a DER-encoded Certificate Revocation List
        #[corresponds(d2i_X509_CRL)]
        from_der,
        X509Crl,
        ffi::d2i_X509_CRL
    }
}

impl X509CrlRef {
    to_pem! {
        /// Serializes the certificate request to a PEM-encoded Certificate Revocation List.
        ///
        /// The output will have a header of `-----BEGIN X509 CRL-----`.
        #[corresponds(PEM_write_bio_X509_CRL)]
        to_pem,
        ffi::PEM_write_bio_X509_CRL
    }

    to_der! {
        /// Serializes the certificate request to a DER-encoded Certificate Revocation List.
        #[corresponds(i2d_X509_CRL)]
        to_der,
        ffi::i2d_X509_CRL
    }

    /// Get the stack of revocation entries
    pub fn get_revoked(&self) -> Option<&StackRef<X509Revoked>> {
        unsafe {
            let revoked = X509_CRL_get_REVOKED(self.as_ptr());
            if revoked.is_null() {
                None
            } else {
                Some(StackRef::from_ptr(revoked))
            }
        }
    }

    /// Returns the CRL's `lastUpdate` time.
    #[corresponds(X509_CRL_get0_lastUpdate)]
    pub fn last_update(&self) -> &Asn1TimeRef {
        unsafe {
            let date = X509_CRL_get0_lastUpdate(self.as_ptr());
            assert!(!date.is_null());
            Asn1TimeRef::from_ptr(date as *mut _)
        }
    }

    /// Returns the CRL's `nextUpdate` time.
    ///
    /// If the `nextUpdate` field is missing, returns `None`.
    #[corresponds(X509_CRL_get0_nextUpdate)]
    pub fn next_update(&self) -> Option<&Asn1TimeRef> {
        unsafe {
            let date = X509_CRL_get0_nextUpdate(self.as_ptr());
            Asn1TimeRef::from_const_ptr_opt(date)
        }
    }

    /// Get the revocation status of a certificate by its serial number
    #[corresponds(X509_CRL_get0_by_serial)]
    pub fn get_by_serial<'a>(&'a self, serial: &Asn1IntegerRef) -> CrlStatus<'a> {
        unsafe {
            let mut ret = ptr::null_mut::<ffi::X509_REVOKED>();
            let status =
                ffi::X509_CRL_get0_by_serial(self.as_ptr(), &mut ret as *mut _, serial.as_ptr());
            CrlStatus::from_ffi_status(status, ret)
        }
    }

    /// Get the revocation status of a certificate
    #[corresponds(X509_CRL_get0_by_cert)]
    pub fn get_by_cert<'a>(&'a self, cert: &X509) -> CrlStatus<'a> {
        unsafe {
            let mut ret = ptr::null_mut::<ffi::X509_REVOKED>();
            let status =
                ffi::X509_CRL_get0_by_cert(self.as_ptr(), &mut ret as *mut _, cert.as_ptr());
            CrlStatus::from_ffi_status(status, ret)
        }
    }

    /// Get the issuer name from the revocation list.
    #[corresponds(X509_CRL_get_issuer)]
    pub fn issuer_name(&self) -> &X509NameRef {
        unsafe {
            let name = X509_CRL_get_issuer(self.as_ptr());
            assert!(!name.is_null());
            X509NameRef::from_ptr(name)
        }
    }

    /// Check if the CRL is signed using the given public key.
    ///
    /// Only the signature is checked: no other checks (such as certificate chain validity)
    /// are performed.
    ///
    /// Returns `true` if verification succeeds.
    #[corresponds(X509_CRL_verify)]
    pub fn verify<T>(&self, key: &PKeyRef<T>) -> Result<bool, ErrorStack>
    where
        T: HasPublic,
    {
        unsafe { cvt_n(ffi::X509_CRL_verify(self.as_ptr(), key.as_ptr())).map(|n| n != 0) }
    }
}

/// The result of peer certificate verification.
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct X509VerifyResult(c_int);
@@ -1754,6 +1978,41 @@ cfg_if! {
    }
}

cfg_if! {
    if #[cfg(any(ossl110, libressl350, boringssl))] {
        use ffi::{
            X509_CRL_get_issuer, X509_CRL_get0_nextUpdate, X509_CRL_get0_lastUpdate,
            X509_CRL_get_REVOKED,
            X509_REVOKED_get0_revocationDate, X509_REVOKED_get0_serialNumber,
        };
    } else {
        #[allow(bad_style)]
        unsafe fn X509_CRL_get0_lastUpdate(x: *const ffi::X509_CRL) -> *mut ffi::ASN1_TIME {
            (*(*x).crl).lastUpdate
        }
        #[allow(bad_style)]
        unsafe fn X509_CRL_get0_nextUpdate(x: *const ffi::X509_CRL) -> *mut ffi::ASN1_TIME {
            (*(*x).crl).nextUpdate
        }
        #[allow(bad_style)]
        unsafe fn X509_CRL_get_issuer(x: *const ffi::X509_CRL) -> *mut ffi::X509_NAME {
            (*(*x).crl).issuer
        }
        #[allow(bad_style)]
        unsafe fn X509_CRL_get_REVOKED(x: *const ffi::X509_CRL) -> *mut ffi::stack_st_X509_REVOKED {
            (*(*x).crl).revoked
        }
        #[allow(bad_style)]
        unsafe fn X509_REVOKED_get0_serialNumber(x: *const ffi::X509_REVOKED) -> *mut ffi::ASN1_INTEGER {
            (*x).serialNumber
        }
        #[allow(bad_style)]
        unsafe fn X509_REVOKED_get0_revocationDate(x: *const ffi::X509_REVOKED) -> *mut ffi::ASN1_TIME {
            (*x).revocationDate
        }
    }
}

#[derive(Copy, Clone, PartialEq, Eq)]
pub struct X509PurposeId(c_int);

+27 −1
Original line number Diff line number Diff line
@@ -24,7 +24,9 @@ use crate::x509::X509Builder;
use crate::x509::X509PurposeId;
#[cfg(any(ossl102, libressl261))]
use crate::x509::X509PurposeRef;
use crate::x509::{X509Name, X509Req, X509StoreContext, X509VerifyResult, X509};
use crate::x509::{
    CrlStatus, X509Crl, X509Name, X509Req, X509StoreContext, X509VerifyResult, X509,
};
use hex::{self, FromHex};
#[cfg(any(ossl102, libressl261))]
use libc::time_t;
@@ -531,6 +533,30 @@ fn x509_ref_version_no_version_set() {
    );
}

#[test]
fn test_load_crl() {
    let ca = include_bytes!("../../test/crl-ca.crt");
    let ca = X509::from_pem(ca).unwrap();

    let crl = include_bytes!("../../test/test.crl");
    let crl = X509Crl::from_der(crl).unwrap();
    assert!(crl.verify(&ca.public_key().unwrap()).unwrap());

    let cert = include_bytes!("../../test/subca.crt");
    let cert = X509::from_pem(cert).unwrap();

    let revoked = match crl.get_by_cert(&cert) {
        CrlStatus::Revoked(revoked) => revoked,
        _ => panic!("cert should be revoked"),
    };

    assert_eq!(
        revoked.serial_number().to_bn().unwrap(),
        cert.serial_number().to_bn().unwrap(),
        "revoked and cert serial numbers should match"
    );
}

#[test]
fn test_save_subject_der() {
    let cert = include_bytes!("../../test/cert.pem");

openssl/test/ca.crt

0 → 100644
+88 −0
Original line number Diff line number Diff line
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            13:ae:da:d8:f4:18:d7:73:b8:bd:35:c9:ce:8e:b3:fc
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=TestCA
        Validity
            Not Before: Jun  6 19:11:19 2019 GMT
            Not After : May 21 19:11:19 2022 GMT
        Subject: CN=SubCA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:b0:09:fc:54:e7:6a:9f:0c:bd:ad:5a:8d:ef:94:
                    4e:11:a6:87:19:4f:bf:a6:e1:62:a5:2d:b7:17:df:
                    67:53:70:da:fe:7d:99:17:ee:13:47:0b:40:0b:a2:
                    34:32:a9:d3:bf:20:fc:13:77:a1:d5:26:60:1f:f0:
                    d4:be:dc:76:7c:1e:6c:b4:4c:01:7c:56:cd:5c:53:
                    ec:81:b3:81:2a:b2:35:26:06:5a:79:e0:b3:9e:e4:
                    57:e1:09:de:ad:7f:c8:cd:87:ee:49:93:30:52:58:
                    b2:bc:0f:c1:b6:10:44:f8:85:d5:5b:0a:9b:28:fe:
                    f4:f4:4a:16:a6:f7:25:e9:96:47:69:73:5b:33:77:
                    92:7d:61:8d:2a:3d:d5:04:89:40:bf:6b:d2:fd:5d:
                    e2:1a:80:a9:8e:c8:92:f6:e5:4c:00:84:f9:6e:2a:
                    93:a3:23:ee:28:23:81:f4:54:f0:18:2c:ee:32:8e:
                    38:9c:a0:c8:33:04:b0:fc:4c:43:1a:5c:04:84:9f:
                    73:c6:08:c7:1d:64:39:fe:72:19:3b:cc:a5:fd:0b:
                    43:25:0d:2b:a9:88:77:9e:62:e6:ac:c2:9a:60:42:
                    4f:4a:54:47:bc:a0:29:72:7c:38:52:c9:ea:27:c5:
                    3d:d0:81:4a:3e:b8:78:79:4b:89:b8:4e:6d:1b:24:
                    15:bd
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://127.0.0.1:8081/pki/test.crl

            X509v3 Basic Constraints: 
                CA:TRUE
            X509v3 Subject Key Identifier: 
                FD:82:45:39:A1:91:41:F2:66:CC:0D:75:D5:0D:40:D5:81:A7:A1:43
            X509v3 Authority Key Identifier: 
                keyid:C5:CC:F5:A1:8C:D9:E4:A7:BA:EC:21:F5:D1:84:23:EA:0D:C2:C7:30
                DirName:/CN=TestCA
                serial:33:E7:04:87:09:32:87:21:D9:CD:7C:AA:4C:5A:BB:2C:6C:7B:54:28

            X509v3 Key Usage: 
                Certificate Sign, CRL Sign
    Signature Algorithm: sha256WithRSAEncryption
         96:a0:ff:8a:4b:bd:45:96:c9:72:3c:63:e3:48:c4:ab:ef:7e:
         db:76:3f:d9:02:9e:69:c8:d9:36:55:e1:f5:9b:c9:69:d8:69:
         02:ac:50:8c:60:94:2c:2e:b9:a8:65:ac:f5:00:b0:8b:96:25:
         0b:8a:ef:94:21:57:e2:04:c2:c3:86:bf:06:4e:91:5c:e6:bc:
         1b:03:31:8b:64:ea:c5:79:c3:5c:94:e5:aa:67:7e:74:12:07:
         14:fd:cd:32:02:26:26:c9:0a:ed:d4:da:ee:2a:84:e3:f1:60:
         b3:09:77:27:a1:3c:ac:ec:61:18:30:b5:6d:1f:16:0a:24:1a:
         cf:1c:1b:60:a5:60:e5:2c:8b:cf:37:83:0c:15:e7:79:30:3f:
         ee:50:45:7c:4b:c6:2c:cd:2c:81:0a:98:f1:65:44:7a:ca:2a:
         20:1a:de:19:d9:4b:ca:a1:e2:a4:b5:14:47:bf:b4:68:15:03:
         c0:55:e5:f4:47:0e:55:9f:fe:85:d8:2c:7d:d0:1a:96:11:b9:
         68:b7:74:1e:61:94:c1:ae:87:52:2d:c6:26:ba:51:ed:f1:91:
         c0:e6:4c:f8:ad:02:23:75:51:fc:f8:69:05:ec:cf:31:50:5a:
         41:78:eb:3d:27:4d:9b:68:ef:ba:0e:ba:3a:7d:60:00:9d:53:
         a5:08:3d:c6
-----BEGIN CERTIFICATE-----
MIIDbDCCAlSgAwIBAgIQE67a2PQY13O4vTXJzo6z/DANBgkqhkiG9w0BAQsFADAR
MQ8wDQYDVQQDDAZUZXN0Q0EwHhcNMTkwNjA2MTkxMTE5WhcNMjIwNTIxMTkxMTE5
WjAQMQ4wDAYDVQQDDAVTdWJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBALAJ/FTnap8Mva1aje+UThGmhxlPv6bhYqUttxffZ1Nw2v59mRfuE0cLQAui
NDKp078g/BN3odUmYB/w1L7cdnwebLRMAXxWzVxT7IGzgSqyNSYGWnngs57kV+EJ
3q1/yM2H7kmTMFJYsrwPwbYQRPiF1VsKmyj+9PRKFqb3JemWR2lzWzN3kn1hjSo9
1QSJQL9r0v1d4hqAqY7IkvblTACE+W4qk6Mj7igjgfRU8Bgs7jKOOJygyDMEsPxM
QxpcBISfc8YIxx1kOf5yGTvMpf0LQyUNK6mId55i5qzCmmBCT0pUR7ygKXJ8OFLJ
6ifFPdCBSj64eHlLibhObRskFb0CAwEAAaOBwDCBvTAzBgNVHR8ELDAqMCigJqAk
hiJodHRwOi8vMTI3LjAuMC4xOjgwODEvcGtpL3Rlc3QuY3JsMAwGA1UdEwQFMAMB
Af8wHQYDVR0OBBYEFP2CRTmhkUHyZswNddUNQNWBp6FDMEwGA1UdIwRFMEOAFMXM
9aGM2eSnuuwh9dGEI+oNwscwoRWkEzARMQ8wDQYDVQQDDAZUZXN0Q0GCFDPnBIcJ
Moch2c18qkxauyxse1QoMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
lqD/iku9RZbJcjxj40jEq+9+23Y/2QKeacjZNlXh9ZvJadhpAqxQjGCULC65qGWs
9QCwi5YlC4rvlCFX4gTCw4a/Bk6RXOa8GwMxi2TqxXnDXJTlqmd+dBIHFP3NMgIm
JskK7dTa7iqE4/Fgswl3J6E8rOxhGDC1bR8WCiQazxwbYKVg5SyLzzeDDBXneTA/
7lBFfEvGLM0sgQqY8WVEesoqIBreGdlLyqHipLUUR7+0aBUDwFXl9EcOVZ/+hdgs
fdAalhG5aLd0HmGUwa6HUi3GJrpR7fGRwOZM+K0CI3VR/PhpBezPMVBaQXjrPSdN
m2jvug66On1gAJ1TpQg9xg==
-----END CERTIFICATE-----
+20 −0
Original line number Diff line number Diff line
-----BEGIN CERTIFICATE-----
MIIDPDCCAiSgAwIBAgIUM+cEhwkyhyHZzXyqTFq7LGx7VCgwDQYJKoZIhvcNAQEL
BQAwETEPMA0GA1UEAwwGVGVzdENBMB4XDTE5MDYwNjE5MTA1NVoXDTI5MDYwMzE5
MTA1NVowETEPMA0GA1UEAwwGVGVzdENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAtNcFPtD1MHcolhgTHIAx/b9OyawCbVzvgasv8R9+94ZMhoGc/tNc
dVg271pCSmj+zYAFYsIwjxW+iq2e5A/fiBc6uqtNfEbU7+77QzxFG5wIbXtmmqEb
dVbqBT28NeKTR6X+EHlNgbw90CHy7byA7LMewxbTt2q1eY1RnB0ji8zdGZmIUPeC
WxzkxXEd0fg+KwBFN3YHV9CJX2KJ10qv7DvbKHeIVBU7osm6tzvNglNnnT90GFSY
zc59b+zS00axcY3Kn08Vt+1qWB9Sl8tixCTGqR538y/ambDr3NCWsiQYWys9KE1L
g0nEaIjb84R7b+qNmPtOezd9tanx7j9UzQIDAQABo4GLMIGIMB0GA1UdDgQWBBTF
zPWhjNnkp7rsIfXRhCPqDcLHMDBMBgNVHSMERTBDgBTFzPWhjNnkp7rsIfXRhCPq
DcLHMKEVpBMwETEPMA0GA1UEAwwGVGVzdENBghQz5wSHCTKHIdnNfKpMWrssbHtU
KDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
gdyQq6F8DO5rn7rZSLehTFx6tbtfncC/BOXZEGLZO0ciTrQ9Q8xHwRhz0W09QE1A
/GsBzb++PuvAl9i82WvunyPB5KZh+GPiaaqf466MdQrXj+IyqxeC9Lg9wEUjwRgp
ANVd3moKap5IZ9WDvhyEng2Oy8/btP2iqVEmd58rGAodd671eOPD8QkIxSquiIwy
Cu5s3IBZ0BOuSG9fWoyPTGMKAhzQPFiXGvWOabCkMz3TsPYVY5ENpq2K8cWn2D/r
TD1yPPdINg6HrALGD3S0sD+k588oS7U5oj1L8V4KJQTLSbh6/XcBpasa5Jdv7ZZe
lVgt69Gsn5Cf2BkbwhbF2Q==
-----END CERTIFICATE-----

openssl/test/subca.crt

0 → 100644
+88 −0
Original line number Diff line number Diff line
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            13:ae:da:d8:f4:18:d7:73:b8:bd:35:c9:ce:8e:b3:fc
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=TestCA
        Validity
            Not Before: Jun  6 19:11:19 2019 GMT
            Not After : May 21 19:11:19 2022 GMT
        Subject: CN=SubCA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:b0:09:fc:54:e7:6a:9f:0c:bd:ad:5a:8d:ef:94:
                    4e:11:a6:87:19:4f:bf:a6:e1:62:a5:2d:b7:17:df:
                    67:53:70:da:fe:7d:99:17:ee:13:47:0b:40:0b:a2:
                    34:32:a9:d3:bf:20:fc:13:77:a1:d5:26:60:1f:f0:
                    d4:be:dc:76:7c:1e:6c:b4:4c:01:7c:56:cd:5c:53:
                    ec:81:b3:81:2a:b2:35:26:06:5a:79:e0:b3:9e:e4:
                    57:e1:09:de:ad:7f:c8:cd:87:ee:49:93:30:52:58:
                    b2:bc:0f:c1:b6:10:44:f8:85:d5:5b:0a:9b:28:fe:
                    f4:f4:4a:16:a6:f7:25:e9:96:47:69:73:5b:33:77:
                    92:7d:61:8d:2a:3d:d5:04:89:40:bf:6b:d2:fd:5d:
                    e2:1a:80:a9:8e:c8:92:f6:e5:4c:00:84:f9:6e:2a:
                    93:a3:23:ee:28:23:81:f4:54:f0:18:2c:ee:32:8e:
                    38:9c:a0:c8:33:04:b0:fc:4c:43:1a:5c:04:84:9f:
                    73:c6:08:c7:1d:64:39:fe:72:19:3b:cc:a5:fd:0b:
                    43:25:0d:2b:a9:88:77:9e:62:e6:ac:c2:9a:60:42:
                    4f:4a:54:47:bc:a0:29:72:7c:38:52:c9:ea:27:c5:
                    3d:d0:81:4a:3e:b8:78:79:4b:89:b8:4e:6d:1b:24:
                    15:bd
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://127.0.0.1:8081/pki/test.crl

            X509v3 Basic Constraints: 
                CA:TRUE
            X509v3 Subject Key Identifier: 
                FD:82:45:39:A1:91:41:F2:66:CC:0D:75:D5:0D:40:D5:81:A7:A1:43
            X509v3 Authority Key Identifier: 
                keyid:C5:CC:F5:A1:8C:D9:E4:A7:BA:EC:21:F5:D1:84:23:EA:0D:C2:C7:30
                DirName:/CN=TestCA
                serial:33:E7:04:87:09:32:87:21:D9:CD:7C:AA:4C:5A:BB:2C:6C:7B:54:28

            X509v3 Key Usage: 
                Certificate Sign, CRL Sign
    Signature Algorithm: sha256WithRSAEncryption
         96:a0:ff:8a:4b:bd:45:96:c9:72:3c:63:e3:48:c4:ab:ef:7e:
         db:76:3f:d9:02:9e:69:c8:d9:36:55:e1:f5:9b:c9:69:d8:69:
         02:ac:50:8c:60:94:2c:2e:b9:a8:65:ac:f5:00:b0:8b:96:25:
         0b:8a:ef:94:21:57:e2:04:c2:c3:86:bf:06:4e:91:5c:e6:bc:
         1b:03:31:8b:64:ea:c5:79:c3:5c:94:e5:aa:67:7e:74:12:07:
         14:fd:cd:32:02:26:26:c9:0a:ed:d4:da:ee:2a:84:e3:f1:60:
         b3:09:77:27:a1:3c:ac:ec:61:18:30:b5:6d:1f:16:0a:24:1a:
         cf:1c:1b:60:a5:60:e5:2c:8b:cf:37:83:0c:15:e7:79:30:3f:
         ee:50:45:7c:4b:c6:2c:cd:2c:81:0a:98:f1:65:44:7a:ca:2a:
         20:1a:de:19:d9:4b:ca:a1:e2:a4:b5:14:47:bf:b4:68:15:03:
         c0:55:e5:f4:47:0e:55:9f:fe:85:d8:2c:7d:d0:1a:96:11:b9:
         68:b7:74:1e:61:94:c1:ae:87:52:2d:c6:26:ba:51:ed:f1:91:
         c0:e6:4c:f8:ad:02:23:75:51:fc:f8:69:05:ec:cf:31:50:5a:
         41:78:eb:3d:27:4d:9b:68:ef:ba:0e:ba:3a:7d:60:00:9d:53:
         a5:08:3d:c6
-----BEGIN CERTIFICATE-----
MIIDbDCCAlSgAwIBAgIQE67a2PQY13O4vTXJzo6z/DANBgkqhkiG9w0BAQsFADAR
MQ8wDQYDVQQDDAZUZXN0Q0EwHhcNMTkwNjA2MTkxMTE5WhcNMjIwNTIxMTkxMTE5
WjAQMQ4wDAYDVQQDDAVTdWJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBALAJ/FTnap8Mva1aje+UThGmhxlPv6bhYqUttxffZ1Nw2v59mRfuE0cLQAui
NDKp078g/BN3odUmYB/w1L7cdnwebLRMAXxWzVxT7IGzgSqyNSYGWnngs57kV+EJ
3q1/yM2H7kmTMFJYsrwPwbYQRPiF1VsKmyj+9PRKFqb3JemWR2lzWzN3kn1hjSo9
1QSJQL9r0v1d4hqAqY7IkvblTACE+W4qk6Mj7igjgfRU8Bgs7jKOOJygyDMEsPxM
QxpcBISfc8YIxx1kOf5yGTvMpf0LQyUNK6mId55i5qzCmmBCT0pUR7ygKXJ8OFLJ
6ifFPdCBSj64eHlLibhObRskFb0CAwEAAaOBwDCBvTAzBgNVHR8ELDAqMCigJqAk
hiJodHRwOi8vMTI3LjAuMC4xOjgwODEvcGtpL3Rlc3QuY3JsMAwGA1UdEwQFMAMB
Af8wHQYDVR0OBBYEFP2CRTmhkUHyZswNddUNQNWBp6FDMEwGA1UdIwRFMEOAFMXM
9aGM2eSnuuwh9dGEI+oNwscwoRWkEzARMQ8wDQYDVQQDDAZUZXN0Q0GCFDPnBIcJ
Moch2c18qkxauyxse1QoMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
lqD/iku9RZbJcjxj40jEq+9+23Y/2QKeacjZNlXh9ZvJadhpAqxQjGCULC65qGWs
9QCwi5YlC4rvlCFX4gTCw4a/Bk6RXOa8GwMxi2TqxXnDXJTlqmd+dBIHFP3NMgIm
JskK7dTa7iqE4/Fgswl3J6E8rOxhGDC1bR8WCiQazxwbYKVg5SyLzzeDDBXneTA/
7lBFfEvGLM0sgQqY8WVEesoqIBreGdlLyqHipLUUR7+0aBUDwFXl9EcOVZ/+hdgs
fdAalhG5aLd0HmGUwa6HUi3GJrpR7fGRwOZM+K0CI3VR/PhpBezPMVBaQXjrPSdN
m2jvug66On1gAJ1TpQg9xg==
-----END CERTIFICATE-----
Loading