Refs #3461 -- parse SCTs from x.509 extension (#3480)

* Stub API for SCTs, feedback wanted

* grr, flake8

* finish up the __init__

* Initial implementation and tests

* write a test. it fails because computer

* get the tests passing and fix some TODOs

* changelog entry

* This can go now

* Put a skip in this test

* grump

* Removed unreachable code

* moved changelog to the correct section

* Use the deocrator for expressing requirements

* This needs f for the right entry_type

* coverage

* syntax error

* tests for coverage

* better sct eq tests

* docs

* technically correct, the most useless kind of correct

* typo and more details

* bug

* drop __eq__
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index b89abdd..595ec70 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -3668,6 +3668,48 @@
 
 @pytest.mark.requires_backend_interface(interface=RSABackend)
 @pytest.mark.requires_backend_interface(interface=X509Backend)
+@pytest.mark.supported(
+    only_if=lambda backend: backend._lib.CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER,
+    skip_message="Requires OpenSSL 1.1.0f+",
+)
+class TestPrecertificateSignedCertificateTimestampsExtension(object):
+    def test_init(self):
+        with pytest.raises(TypeError):
+            x509.PrecertificateSignedCertificateTimestamps([object()])
+
+    def test_repr(self):
+        assert repr(x509.PrecertificateSignedCertificateTimestamps([])) == (
+            "<PrecertificateSignedCertificateTimestamps([])>"
+        )
+
+    def test_simple(self, backend):
+        cert = _load_cert(
+            os.path.join("x509", "badssl-sct.pem"),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        scts = cert.extensions.get_extension_for_class(
+            x509.PrecertificateSignedCertificateTimestamps
+        ).value
+        assert len(scts) == 1
+        [sct] = scts
+        assert scts[0] == sct
+        assert sct.version == x509.certificate_transparency.Version.v1
+        assert sct.log_id == (
+            b"\xa7\xceJNb\x07\xe0\xad\xde\xe5\xfd\xaaK\x1f\x86v\x87g\xb5\xd0"
+            b"\x02\xa5]G1\x0e~g\n\x95\xea\xb2"
+        )
+        assert sct.timestamp == datetime.datetime(
+            2016, 11, 17, 1, 56, 25, 396000
+        )
+        assert (
+            sct.entry_type ==
+            x509.certificate_transparency.LogEntryType.PRE_CERTIFICATE
+        )
+
+
+@pytest.mark.requires_backend_interface(interface=RSABackend)
+@pytest.mark.requires_backend_interface(interface=X509Backend)
 class TestInvalidExtension(object):
     def test_invalid_certificate_policies_data(self, backend):
         cert = _load_cert(