Support encoding ExtendedKeyUsage into certificate signing requests
diff --git a/src/_cffi_src/openssl/x509.py b/src/_cffi_src/openssl/x509.py
index 6bd117b..bdcc171 100644
--- a/src/_cffi_src/openssl/x509.py
+++ b/src/_cffi_src/openssl/x509.py
@@ -325,6 +325,8 @@
 int sk_ASN1_OBJECT_num(Cryptography_STACK_OF_ASN1_OBJECT *);
 ASN1_OBJECT *sk_ASN1_OBJECT_value(Cryptography_STACK_OF_ASN1_OBJECT *, int);
 void sk_ASN1_OBJECT_free(Cryptography_STACK_OF_ASN1_OBJECT *);
+Cryptography_STACK_OF_ASN1_OBJECT *sk_ASN1_OBJECT_new_null(void);
+int sk_ASN1_OBJECT_push(Cryptography_STACK_OF_ASN1_OBJECT *, ASN1_OBJECT *);
 """
 
 CUSTOMIZATIONS = """
diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py
index 8e42b65..148cd64 100644
--- a/src/_cffi_src/openssl/x509v3.py
+++ b/src/_cffi_src/openssl/x509v3.py
@@ -33,6 +33,7 @@
 typedef ... Cryptography_STACK_OF_POLICYINFO;
 typedef ... Cryptography_STACK_OF_ASN1_INTEGER;
 typedef ... Cryptography_STACK_OF_GENERAL_SUBTREE;
+typedef ... EXTENDED_KEY_USAGE;
 
 typedef struct {
     X509 *issuer_cert;
@@ -200,6 +201,8 @@
 
 int i2d_GENERAL_NAMES(GENERAL_NAMES *, unsigned char **);
 
+int i2d_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE *, unsigned char **);
+
 int sk_GENERAL_NAME_num(struct stack_st_GENERAL_NAME *);
 int sk_GENERAL_NAME_push(struct stack_st_GENERAL_NAME *, GENERAL_NAME *);
 GENERAL_NAME *sk_GENERAL_NAME_value(struct stack_st_GENERAL_NAME *, int);
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 046a173..64d518a 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -101,7 +101,7 @@
     subject = backend._lib.X509_NAME_new()
     for attribute in attributes:
         value = attribute.value.encode('utf8')
-        obj = _txt2obj(backend, attribute.oid.dotted_string)
+        obj = _txt2obj_gc(backend, attribute.oid.dotted_string)
         res = backend._lib.X509_NAME_add_entry_by_OBJ(
             subject,
             obj,
@@ -127,6 +127,11 @@
     name = name.encode('ascii')
     obj = backend._lib.OBJ_txt2obj(name, 1)
     assert obj != backend._ffi.NULL
+    return obj
+
+
+def _txt2obj_gc(backend, name):
+    obj = _txt2obj(backend, name)
     obj = backend._ffi.gc(obj, backend._lib.ASN1_OBJECT_free)
     return obj
 
@@ -293,6 +298,25 @@
     return pp, r
 
 
+def _encode_extended_key_usage(backend, extended_key_usage):
+    eku = backend._lib.sk_ASN1_OBJECT_new_null()
+    eku = backend._ffi.gc(eku, backend._lib.sk_ASN1_OBJECT_free)
+    for oid in extended_key_usage:
+        obj = _txt2obj(backend, oid.dotted_string)
+        res = backend._lib.sk_ASN1_OBJECT_push(eku, obj)
+        assert res >= 1
+
+    pp = backend._ffi.new('unsigned char **')
+    r = backend._lib.i2d_EXTENDED_KEY_USAGE(
+        backend._ffi.cast("EXTENDED_KEY_USAGE *", eku), pp
+    )
+    assert r > 0
+    pp = backend._ffi.gc(
+        pp, lambda pointer: backend._lib.OPENSSL_free(pointer[0])
+    )
+    return pp, r
+
+
 @utils.register_interface(CipherBackend)
 @utils.register_interface(CMACBackend)
 @utils.register_interface(DERSerializationBackend)
@@ -1004,10 +1028,12 @@
                 pp, r = _encode_subject_alt_name(self, extension.value)
             elif isinstance(extension.value, x509.KeyUsage):
                 pp, r = _encode_key_usage(self, extension.value)
+            elif isinstance(extension.value, x509.ExtendedKeyUsage):
+                pp, r = _encode_extended_key_usage(self, extension.value)
             else:
                 raise NotImplementedError('Extension not yet supported.')
 
-            obj = _txt2obj(self, extension.oid.dotted_string)
+            obj = _txt2obj_gc(self, extension.oid.dotted_string)
             extension = self._lib.X509_EXTENSION_create_by_OBJ(
                 self._ffi.NULL,
                 obj,
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index 943cfd7..493abc8 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -818,5 +818,6 @@
         x509.OID_BASIC_CONSTRAINTS: _decode_basic_constraints,
         x509.OID_KEY_USAGE: _decode_key_usage,
         x509.OID_SUBJECT_ALTERNATIVE_NAME: _decode_subject_alt_name,
+        x509.OID_EXTENDED_KEY_USAGE: _decode_extended_key_usage,
     }
 )
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index 5d108ee..75552fc 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -1571,6 +1571,8 @@
         """
         if isinstance(extension, BasicConstraints):
             extension = Extension(OID_BASIC_CONSTRAINTS, critical, extension)
+        elif isinstance(extension, ExtendedKeyUsage):
+            extension = Extension(OID_EXTENDED_KEY_USAGE, critical, extension)
         elif isinstance(extension, SubjectAlternativeName):
             extension = Extension(
                 OID_SUBJECT_ALTERNATIVE_NAME, critical, extension
diff --git a/tests/test_x509.py b/tests/test_x509.py
index af7d942..cacf3c8 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -1183,6 +1183,29 @@
         with pytest.raises(ValueError):
             builder.sign(private_key, hashes.SHA256(), backend)
 
+    def test_extended_key_usage(self, backend):
+        private_key = RSA_KEY_2048.private_key(backend)
+        builder = x509.CertificateSigningRequestBuilder()
+        request = builder.subject_name(
+            x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
+        ).add_extension(
+            x509.ExtendedKeyUsage([
+                x509.OID_CLIENT_AUTH,
+                x509.OID_SERVER_AUTH,
+                x509.OID_CODE_SIGNING,
+            ]), critical=False
+        ).sign(private_key, hashes.SHA256(), backend)
+
+        eku = request.extensions.get_extension_for_oid(
+            x509.OID_EXTENDED_KEY_USAGE
+        )
+        assert eku.critical is False
+        assert eku.value == x509.ExtendedKeyUsage([
+            x509.OID_CLIENT_AUTH,
+            x509.OID_SERVER_AUTH,
+            x509.OID_CODE_SIGNING,
+        ])
+
 
 @pytest.mark.requires_backend_interface(interface=DSABackend)
 @pytest.mark.requires_backend_interface(interface=X509Backend)