add DSA getters/setters for opaquing the struct (#2889)

* add DSA getters/setters for opaquing the struct

* these can live in functions
diff --git a/src/_cffi_src/openssl/dsa.py b/src/_cffi_src/openssl/dsa.py
index 69935c1..2844a9e 100644
--- a/src/_cffi_src/openssl/dsa.py
+++ b/src/_cffi_src/openssl/dsa.py
@@ -35,12 +35,85 @@
              DSA *);
 int DSA_verify(int, const unsigned char *, int, const unsigned char *, int,
                DSA *);
+
+/* added in 1.1.0 to access the opaque struct */
+void DSA_get0_pqg(const DSA *, BIGNUM **, BIGNUM **, BIGNUM **);
+int DSA_set0_pqg(DSA *, BIGNUM *, BIGNUM *, BIGNUM *);
+void DSA_get0_key(const DSA *, BIGNUM **, BIGNUM **);
+int DSA_set0_key(DSA *, BIGNUM *, BIGNUM *);
 """
 
 MACROS = """
+/* DSAparams_dup is a macro in 0.9.8 */
+DSA *DSAparams_dup(DSA *);
 int DSA_generate_parameters_ex(DSA *, int, unsigned char *, int,
                                int *, unsigned long *, BN_GENCB *);
 """
 
 CUSTOMIZATIONS = """
+/* These functions were added in OpenSSL 1.1.0-pre5 (beta2) */
+#if OPENSSL_VERSION_NUMBER < 0x10100005 || defined(LIBRESSL_VERSION_NUMBER)
+void DSA_get0_pqg(const DSA *d, BIGNUM **p, BIGNUM **q, BIGNUM **g)
+{
+    if (p != NULL)
+        *p = d->p;
+    if (q != NULL)
+        *q = d->q;
+    if (g != NULL)
+        *g = d->g;
+}
+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+    /* If the fields in d are NULL, the corresponding input
+     * parameters MUST be non-NULL.
+     *
+     * It is an error to give the results from get0 on d
+     * as input parameters.
+     */
+    if (p == d->p || q == d->q || g == d->g)
+        return 0;
+    if (p != NULL) {
+        BN_free(d->p);
+        d->p = p;
+    }
+    if (q != NULL) {
+        BN_free(d->q);
+        d->q = q;
+    }
+    if (g != NULL) {
+        BN_free(d->g);
+        d->g = g;
+    }
+    return 1;
+}
+void DSA_get0_key(const DSA *d, BIGNUM **pub_key, BIGNUM **priv_key)
+{
+    if (pub_key != NULL)
+        *pub_key = d->pub_key;
+    if (priv_key != NULL)
+        *priv_key = d->priv_key;
+}
+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+    /* If the pub_key in d is NULL, the corresponding input
+     * parameters MUST be non-NULL.  The priv_key field may
+     * be left NULL.
+     *
+     * It is an error to give the results from get0 on d
+     * as input parameters.
+     */
+    if (d->pub_key == pub_key
+        || (d->priv_key != NULL && priv_key != d->priv_key))
+        return 0;
+    if (pub_key != NULL) {
+        BN_free(d->pub_key);
+        d->pub_key = pub_key;
+    }
+    if (priv_key != NULL) {
+        BN_free(d->priv_key);
+        d->priv_key = priv_key;
+    }
+    return 1;
+}
+#endif
 """