Merge pull request #2564 from alex/crl-index-perf

Make indexing a CRL O(1) instead of O(n).
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index 7b9f71c..a470adb 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -6,6 +6,7 @@
 
 import datetime
 import ipaddress
+import operator
 
 from email.utils import parseaddr
 
@@ -872,8 +873,16 @@
             yield self._revoked_cert(i)
 
     def __getitem__(self, idx):
-        # TODO: indexing is O(n)
-        return list(self)[idx]
+        if isinstance(idx, slice):
+            start, stop, step = idx.indices(len(self))
+            return [self._revoked_cert(i) for i in range(start, stop, step)]
+        else:
+            idx = operator.index(idx)
+            if idx < 0:
+                idx += len(self)
+            if not 0 <= idx < len(self):
+                raise IndexError
+            return self._revoked_cert(idx)
 
     def __len__(self):
         revoked = self._backend._lib.X509_CRL_get_REVOKED(self._x509_crl)
diff --git a/tests/test_x509.py b/tests/test_x509.py
index ab4d666..755b65f 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -332,7 +332,6 @@
 
 @pytest.mark.requires_backend_interface(interface=X509Backend)
 class TestRevokedCertificate(object):
-
     def test_revoked_basics(self, backend):
         crl = _load_cert(
             os.path.join("x509", "custom", "crl_all_reasons.pem"),
@@ -460,6 +459,23 @@
         with pytest.raises(ValueError):
             crl[0].extensions
 
+    def test_indexing(self, backend):
+        crl = _load_cert(
+            os.path.join("x509", "custom", "crl_all_reasons.pem"),
+            x509.load_pem_x509_crl,
+            backend
+        )
+
+        with pytest.raises(IndexError):
+            crl[-13]
+        with pytest.raises(IndexError):
+            crl[12]
+
+        assert crl[-1].serial_number == crl[11].serial_number
+        assert len(crl[2:4]) == 2
+        assert crl[2:4][0].serial_number == crl[2].serial_number
+        assert crl[2:4][1].serial_number == crl[3].serial_number
+
 
 @pytest.mark.requires_backend_interface(interface=RSABackend)
 @pytest.mark.requires_backend_interface(interface=X509Backend)