opaque X509_NAME
diff --git a/src/_cffi_src/openssl/x509name.py b/src/_cffi_src/openssl/x509name.py
index 7b833d6..86d50bb 100644
--- a/src/_cffi_src/openssl/x509name.py
+++ b/src/_cffi_src/openssl/x509name.py
@@ -16,10 +16,7 @@
 
 TYPES = """
 typedef ... Cryptography_STACK_OF_X509_NAME_ENTRY;
-typedef struct {
-    Cryptography_STACK_OF_X509_NAME_ENTRY *entries;
-    ...;
-} X509_NAME;
+typedef ... X509_NAME;
 typedef ... X509_NAME_ENTRY;
 typedef ... Cryptography_STACK_OF_X509_NAME;
 """
@@ -47,6 +44,10 @@
 int X509_NAME_cmp(const X509_NAME *, const X509_NAME *);
 char *X509_NAME_oneline(X509_NAME *, char *, int);
 X509_NAME *X509_NAME_dup(X509_NAME *);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **,
+                                               ASN1_OBJECT *, int,
+                                               const unsigned char *, int);
+int X509_NAME_add_entry(X509_NAME *, X509_NAME_ENTRY *, int, int);
 """
 
 MACROS = """
@@ -56,6 +57,9 @@
 X509_NAME *sk_X509_NAME_value(Cryptography_STACK_OF_X509_NAME *, int);
 void sk_X509_NAME_free(Cryptography_STACK_OF_X509_NAME *);
 int sk_X509_NAME_ENTRY_num(Cryptography_STACK_OF_X509_NAME_ENTRY *);
+Cryptography_STACK_OF_X509_NAME_ENTRY *sk_X509_NAME_ENTRY_new_null(void);
+int sk_X509_NAME_ENTRY_push(Cryptography_STACK_OF_X509_NAME_ENTRY *,
+                            X509_NAME_ENTRY *);
 X509_NAME_ENTRY *sk_X509_NAME_ENTRY_value(
     Cryptography_STACK_OF_X509_NAME_ENTRY *, int);
 Cryptography_STACK_OF_X509_NAME_ENTRY *sk_X509_NAME_ENTRY_dup(
diff --git a/src/cryptography/hazmat/backends/openssl/encode_asn1.py b/src/cryptography/hazmat/backends/openssl/encode_asn1.py
index 8cdf4c4..b56dfa7 100644
--- a/src/cryptography/hazmat/backends/openssl/encode_asn1.py
+++ b/src/cryptography/hazmat/backends/openssl/encode_asn1.py
@@ -97,17 +97,8 @@
     """
     subject = backend._lib.X509_NAME_new()
     for attribute in attributes:
-        value = attribute.value.encode('utf8')
-        obj = _txt2obj_gc(backend, attribute.oid.dotted_string)
-        if attribute.oid == NameOID.COUNTRY_NAME:
-            # Per RFC5280 Appendix A.1 countryName should be encoded as
-            # PrintableString, not UTF8String
-            type = backend._lib.MBSTRING_ASC
-        else:
-            type = backend._lib.MBSTRING_UTF8
-        res = backend._lib.X509_NAME_add_entry_by_OBJ(
-            subject, obj, type, value, -1, -1, 0,
-        )
+        name_entry = _encode_name_entry(backend, attribute)
+        res = backend._lib.X509_NAME_add_entry(subject, name_entry, -1, 0)
         backend.openssl_assert(res == 1)
     return subject
 
@@ -118,6 +109,33 @@
     return subject
 
 
+def _encode_sk_name_entry(backend, attributes):
+    """
+    The sk_X50_NAME_ENTRY created will not be gc'd.
+    """
+    stack = backend._lib.sk_X509_NAME_ENTRY_new_null()
+    for attribute in attributes:
+        name_entry = _encode_name_entry(backend, attribute)
+        res = backend._lib.sk_X509_NAME_ENTRY_push(stack, name_entry)
+        backend.openssl_assert(res == 1)
+    return stack
+
+
+def _encode_name_entry(backend, attribute):
+    value = attribute.value.encode('utf8')
+    obj = _txt2obj_gc(backend, attribute.oid.dotted_string)
+    if attribute.oid == NameOID.COUNTRY_NAME:
+        # Per RFC5280 Appendix A.1 countryName should be encoded as
+        # PrintableString, not UTF8String
+        type = backend._lib.MBSTRING_ASC
+    else:
+        type = backend._lib.MBSTRING_UTF8
+    name_entry = backend._lib.X509_NAME_ENTRY_create_by_OBJ(
+        backend._ffi.NULL, obj, type, value, -1
+    )
+    return name_entry
+
+
 def _encode_crl_number(backend, crl_number):
     asn1int = _encode_asn1_int_gc(backend, crl_number.crl_number)
     return _encode_extension_to_der(
@@ -516,8 +534,7 @@
             dpn = backend._lib.DIST_POINT_NAME_new()
             backend.openssl_assert(dpn != backend._ffi.NULL)
             dpn.type = _DISTPOINT_TYPE_RELATIVENAME
-            name = _encode_name_gc(backend, point.relative_name)
-            relativename = backend._lib.sk_X509_NAME_ENTRY_dup(name.entries)
+            relativename = _encode_sk_name_entry(backend, point.relative_name)
             backend.openssl_assert(relativename != backend._ffi.NULL)
             dpn.name.relativename = relativename
             dp.distpoint = dpn