Merge pull request #2589 from reaperhulk/dict-dict-dict

add a comment and a dict we need in #2582
diff --git a/src/_cffi_src/openssl/bignum.py b/src/_cffi_src/openssl/bignum.py
index ae03500..455afdc 100644
--- a/src/_cffi_src/openssl/bignum.py
+++ b/src/_cffi_src/openssl/bignum.py
@@ -71,6 +71,8 @@
 """
 
 MACROS = """
+int BN_num_bytes(const BIGNUM *);
+
 int BN_zero(BIGNUM *);
 int BN_one(BIGNUM *);
 int BN_mod(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 0dd9a2e..c0c9ebe 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -919,17 +919,14 @@
         assert bn != self._ffi.NULL
         if six.PY3:
             # Python 3 has constant time from_bytes, so use that.
-
-            bn_num_bytes = (self._lib.BN_num_bits(bn) + 7) // 8
+            bn_num_bytes = self._lib.BN_num_bytes(bn)
             bin_ptr = self._ffi.new("unsigned char[]", bn_num_bytes)
             bin_len = self._lib.BN_bn2bin(bn, bin_ptr)
             # A zero length means the BN has value 0
             self.openssl_assert(bin_len >= 0)
             return int.from_bytes(self._ffi.buffer(bin_ptr)[:bin_len], "big")
-
         else:
             # Under Python 2 the best we can do is hex()
-
             hex_cdata = self._lib.BN_bn2hex(bn)
             self.openssl_assert(hex_cdata != self._ffi.NULL)
             hex_str = self._ffi.string(hex_cdata)
diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py
index 10b8da4..4dee72f 100644
--- a/src/cryptography/x509/extensions.py
+++ b/src/cryptography/x509/extensions.py
@@ -961,6 +961,9 @@
     def __ne__(self, other):
         return not self == other
 
+    def __getitem__(self, idx):
+        return self._general_names[idx]
+
 
 @utils.register_interface(ExtensionType)
 class CertificateIssuer(object):
@@ -990,6 +993,9 @@
     def __ne__(self, other):
         return not self == other
 
+    def __getitem__(self, idx):
+        return self._general_names[idx]
+
 
 @utils.register_interface(ExtensionType)
 class CRLReason(object):
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py
index c8d3589..c0e9d28 100644
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -4,6 +4,7 @@
 
 from __future__ import absolute_import, division, print_function
 
+import datetime
 import os
 import subprocess
 import sys
@@ -13,7 +14,7 @@
 
 import pytest
 
-from cryptography import utils
+from cryptography import utils, x509
 from cryptography.exceptions import InternalError, _Reasons
 from cryptography.hazmat.backends.interfaces import RSABackend
 from cryptography.hazmat.backends.openssl.backend import (
@@ -500,6 +501,55 @@
         with pytest.raises(TypeError):
             backend.create_x509_certificate(object(), private_key, DummyHash())
 
+    @pytest.mark.skipif(
+        backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000,
+        reason="Requires an older OpenSSL. Must be < 1.0.1"
+    )
+    def test_sign_with_dsa_private_key_is_unsupported(self):
+        private_key = DSA_KEY_2048.private_key(backend)
+        builder = x509.CertificateBuilder()
+        builder = builder.subject_name(
+            x509.Name([x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u'US')])
+        ).issuer_name(
+            x509.Name([x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u'US')])
+        ).serial_number(
+            1
+        ).public_key(
+            private_key.public_key()
+        ).not_valid_before(
+            datetime.datetime(2002, 1, 1, 12, 1)
+        ).not_valid_after(
+            datetime.datetime(2032, 1, 1, 12, 1)
+        )
+
+        with pytest.raises(NotImplementedError):
+            builder.sign(private_key, hashes.SHA512(), backend)
+
+    @pytest.mark.skipif(
+        backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000,
+        reason="Requires an older OpenSSL. Must be < 1.0.1"
+    )
+    def test_sign_with_ec_private_key_is_unsupported(self):
+        _skip_curve_unsupported(backend, ec.SECP256R1())
+        private_key = ec.generate_private_key(ec.SECP256R1(), backend)
+        builder = x509.CertificateBuilder()
+        builder = builder.subject_name(
+            x509.Name([x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u'US')])
+        ).issuer_name(
+            x509.Name([x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u'US')])
+        ).serial_number(
+            1
+        ).public_key(
+            private_key.public_key()
+        ).not_valid_before(
+            datetime.datetime(2002, 1, 1, 12, 1)
+        ).not_valid_after(
+            datetime.datetime(2032, 1, 1, 12, 1)
+        )
+
+        with pytest.raises(NotImplementedError):
+            builder.sign(private_key, hashes.SHA512(), backend)
+
 
 class TestOpenSSLSignX509CertificateRevocationList(object):
     def test_invalid_builder(self):
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 560324b..578015e 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -1739,57 +1739,6 @@
         with pytest.raises(TypeError):
             builder.sign(private_key, object(), backend)
 
-    @pytest.mark.requires_backend_interface(interface=DSABackend)
-    @pytest.mark.requires_backend_interface(interface=X509Backend)
-    def test_sign_with_dsa_private_key_is_unsupported(self, backend):
-        if backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
-            pytest.skip("Requires an older OpenSSL. Must be < 1.0.1")
-
-        private_key = DSA_KEY_2048.private_key(backend)
-        builder = x509.CertificateBuilder()
-        builder = builder.subject_name(
-            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
-        ).issuer_name(
-            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
-        ).serial_number(
-            1
-        ).public_key(
-            private_key.public_key()
-        ).not_valid_before(
-            datetime.datetime(2002, 1, 1, 12, 1)
-        ).not_valid_after(
-            datetime.datetime(2032, 1, 1, 12, 1)
-        )
-
-        with pytest.raises(NotImplementedError):
-            builder.sign(private_key, hashes.SHA512(), backend)
-
-    @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
-    @pytest.mark.requires_backend_interface(interface=X509Backend)
-    def test_sign_with_ec_private_key_is_unsupported(self, backend):
-        if backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
-            pytest.skip("Requires an older OpenSSL. Must be < 1.0.1")
-
-        _skip_curve_unsupported(backend, ec.SECP256R1())
-        private_key = ec.generate_private_key(ec.SECP256R1(), backend)
-        builder = x509.CertificateBuilder()
-        builder = builder.subject_name(
-            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
-        ).issuer_name(
-            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
-        ).serial_number(
-            1
-        ).public_key(
-            private_key.public_key()
-        ).not_valid_before(
-            datetime.datetime(2002, 1, 1, 12, 1)
-        ).not_valid_after(
-            datetime.datetime(2032, 1, 1, 12, 1)
-        )
-
-        with pytest.raises(NotImplementedError):
-            builder.sign(private_key, hashes.SHA512(), backend)
-
     @pytest.mark.parametrize(
         "cdp",
         [
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index f802300..67081b2 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -87,6 +87,17 @@
             x509.DNSName(u"crypto.local"),
         ]
 
+    def test_indexing(self):
+        ci = x509.CertificateIssuer([
+            x509.DNSName(u"cryptography.io"),
+            x509.DNSName(u"crypto.local"),
+            x509.DNSName(u"another.local"),
+            x509.RFC822Name(u"email@another.local"),
+            x509.UniformResourceIdentifier(u"http://another.local"),
+        ])
+        assert ci[-1] == ci[4]
+        assert ci[2:6:2] == [ci[2], ci[4]]
+
     def test_eq(self):
         ci1 = x509.CertificateIssuer([x509.DNSName(u"cryptography.io")])
         ci2 = x509.CertificateIssuer([x509.DNSName(u"cryptography.io")])
@@ -1561,6 +1572,17 @@
             x509.DNSName(u"crypto.local"),
         ]
 
+    def test_indexing(self):
+        ian = x509.IssuerAlternativeName([
+            x509.DNSName(u"cryptography.io"),
+            x509.DNSName(u"crypto.local"),
+            x509.DNSName(u"another.local"),
+            x509.RFC822Name(u"email@another.local"),
+            x509.UniformResourceIdentifier(u"http://another.local"),
+        ])
+        assert ian[-1] == ian[4]
+        assert ian[2:6:2] == [ian[2], ian[4]]
+
     def test_invalid_general_names(self):
         with pytest.raises(TypeError):
             x509.IssuerAlternativeName(