[openssl] master update

Matt Caswell matt at openssl.org
Wed Mar 6 16:18:15 UTC 2019


The branch master has been updated
       via  9fdcc21fdc9d148f78d9cd5be34030f38cc45812 (commit)
      from  27d5631236325c3fd8a3bd06af282ac496aac64b (commit)


- Log -----------------------------------------------------------------
commit 9fdcc21fdc9d148f78d9cd5be34030f38cc45812
Author: David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Tue Jan 15 21:51:25 2019 +0100

    constify *_dup() and *i2d_*() and related functions as far as possible, introducing DECLARE_ASN1_DUP_FUNCTION
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/8029)

-----------------------------------------------------------------------

Summary of changes:
 crypto/asn1/a_dup.c                  |   4 +-
 crypto/asn1/a_i2d_fp.c               |   8 +--
 crypto/asn1/asn1_locl.h              |  10 +++-
 crypto/asn1/asn_mime.c               |   2 +
 crypto/asn1/bio_ndef.c               |   1 +
 crypto/asn1/i2d_pr.c                 |   2 +-
 crypto/asn1/i2d_pu.c                 |   2 +-
 crypto/asn1/n_pkey.c                 |  12 ++--
 crypto/asn1/tasn_dec.c               |   6 +-
 crypto/asn1/tasn_enc.c               |  90 ++++++++++++++++--------------
 crypto/asn1/tasn_fre.c               |   2 +-
 crypto/asn1/tasn_prn.c               |  52 ++++++++---------
 crypto/asn1/tasn_typ.c               |   4 +-
 crypto/asn1/tasn_utl.c               |  82 ++++++++++++++++++---------
 crypto/asn1/x_bignum.c               |   8 +--
 crypto/asn1/x_int64.c                |  16 +++---
 crypto/asn1/x_long.c                 |   8 +--
 crypto/cms/cms_dd.c                  |   4 +-
 crypto/cms/cms_enc.c                 |   2 +-
 crypto/cms/cms_env.c                 |   8 +--
 crypto/cms/cms_io.c                  |   1 +
 crypto/cms/cms_kari.c                |   2 +-
 crypto/cms/cms_lcl.h                 |  14 ++---
 crypto/cms/cms_lib.c                 |   1 +
 crypto/cms/cms_pwri.c                |   2 +-
 crypto/dh/dh_ameth.c                 |   2 +-
 crypto/dh/dh_asn1.c                  |   4 +-
 crypto/dh/dh_pmeth.c                 |   2 +-
 crypto/dsa/dsa_asn1.c                |  10 ++--
 crypto/dsa/dsa_pmeth.c               |   2 +-
 crypto/ec/ec_asn1.c                  |  22 ++++----
 crypto/ec/ec_pmeth.c                 |   2 +-
 crypto/ess/ess_asn1.c                |  10 ++--
 crypto/evp/encode.c                  |   2 +-
 crypto/evp/evp_pkey.c                |   2 +-
 crypto/evp/mac_lib.c                 |   2 +-
 crypto/evp/p_lib.c                   |   8 +--
 crypto/evp/pkey_mac.c                |   2 +-
 crypto/evp/pmeth_lib.c               |   8 +--
 crypto/include/internal/evp_int.h    |   2 +-
 crypto/ocsp/v3_ocsp.c                |   6 +-
 crypto/pem/pem_pk8.c                 |  24 ++++----
 crypto/pkcs12/p12_utl.c              |   4 +-
 crypto/pkcs7/pk7_lib.c               |   1 +
 crypto/rsa/rsa_asn1.c                |   8 +--
 crypto/rsa/rsa_pmeth.c               |   2 +-
 crypto/sm2/sm2_pmeth.c               |   2 +-
 crypto/ts/ts_asn1.c                  |  44 +++++++--------
 crypto/x509/x_all.c                  |  68 +++++++++++------------
 crypto/x509/x_name.c                 |  27 +++++----
 crypto/x509/x_pubkey.c               |  36 +++++++-----
 crypto/x509/x_x509.c                 |   5 +-
 crypto/x509v3/v3_genn.c              |   2 +-
 doc/man3/ASN1_STRING_length.pod      |   2 +-
 doc/man3/EVP_PKEY_CTX_ctrl.pod       |   3 +-
 doc/man3/EVP_PKEY_CTX_new.pod        |   2 +-
 doc/man3/EVP_PKEY_set1_RSA.pod       |   8 +--
 doc/man3/PEM_read_bio_PrivateKey.pod |   7 +--
 doc/man3/SSL_SESSION_free.pod        |   2 +-
 doc/man3/SSL_new.pod                 |   3 +-
 doc/man3/X509_PUBKEY_new.pod         |   6 +-
 doc/man3/X509_dup.pod                |   4 +-
 doc/man3/d2i_PKCS8PrivateKey_bio.pod |   8 +--
 doc/man3/d2i_PrivateKey.pod          |   4 +-
 doc/man3/d2i_X509.pod                |   3 +
 include/openssl/asn1.h               | 105 ++++++++++++++++-------------------
 include/openssl/asn1t.h              |  75 +++++++++++++------------
 include/openssl/cms.h                |   2 +-
 include/openssl/dh.h                 |  12 ++--
 include/openssl/dsa.h                |  17 +++---
 include/openssl/ec.h                 |  15 +++--
 include/openssl/ess.h                |  47 +++++-----------
 include/openssl/evp.h                |  54 +++++++++---------
 include/openssl/objects.h            |   2 +-
 include/openssl/ocsp.h               |   2 +-
 include/openssl/pem.h                |  16 +++---
 include/openssl/pkcs12.h             |   4 +-
 include/openssl/pkcs7.h              |   6 +-
 include/openssl/rsa.h                |   8 +--
 include/openssl/ssl.h                |   4 +-
 include/openssl/ts.h                 |  78 ++++++++++----------------
 include/openssl/x509.h               |  98 +++++++++++++++-----------------
 include/openssl/x509v3.h             |   4 +-
 ssl/ssl_asn1.c                       |  10 ++--
 ssl/ssl_locl.h                       |   2 +-
 ssl/ssl_sess.c                       |   4 +-
 test/x509aux.c                       |   2 +-
 util/perl/OpenSSL/ParseC.pm          |  60 +++++++++++++-------
 88 files changed, 680 insertions(+), 651 deletions(-)

diff --git a/crypto/asn1/a_dup.c b/crypto/asn1/a_dup.c
index 4d22168..b5df08e 100644
--- a/crypto/asn1/a_dup.c
+++ b/crypto/asn1/a_dup.c
@@ -13,7 +13,7 @@
 
 #ifndef NO_OLD_ASN1
 
-void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, const void *x)
 {
     unsigned char *b, *p;
     const unsigned char *p2;
@@ -46,7 +46,7 @@ void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
  * decode.
  */
 
-void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
+void *ASN1_item_dup(const ASN1_ITEM *it, const void *x)
 {
     unsigned char *b = NULL;
     const unsigned char *p;
diff --git a/crypto/asn1/a_i2d_fp.c b/crypto/asn1/a_i2d_fp.c
index 2527c25..e718bf4 100644
--- a/crypto/asn1/a_i2d_fp.c
+++ b/crypto/asn1/a_i2d_fp.c
@@ -15,7 +15,7 @@
 #ifndef NO_OLD_ASN1
 
 # ifndef OPENSSL_NO_STDIO
-int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
+int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, const void *x)
 {
     BIO *b;
     int ret;
@@ -31,7 +31,7 @@ int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
 }
 # endif
 
-int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
+int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, const void *x)
 {
     char *b;
     unsigned char *p;
@@ -68,7 +68,7 @@ int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
 #endif
 
 #ifndef OPENSSL_NO_STDIO
-int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, const void *x)
 {
     BIO *b;
     int ret;
@@ -84,7 +84,7 @@ int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
 }
 #endif
 
-int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, const void *x)
 {
     unsigned char *b = NULL;
     int i, j = 0, n, ret = 1;
diff --git a/crypto/asn1/asn1_locl.h b/crypto/asn1/asn1_locl.h
index e3221d6..5720c90 100644
--- a/crypto/asn1/asn1_locl.h
+++ b/crypto/asn1/asn1_locl.h
@@ -9,6 +9,9 @@
 
 /* Internal ASN1 structures and functions: not for application use */
 
+typedef const ASN1_VALUE const_ASN1_VALUE;
+SKM_DEFINE_STACK_OF(const_ASN1_VALUE, const ASN1_VALUE, ASN1_VALUE)
+
 int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d);
 int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d);
 int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d);
@@ -46,19 +49,22 @@ DEFINE_STACK_OF(MIME_HEADER)
 void asn1_string_embed_free(ASN1_STRING *a, int embed);
 
 int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_get_choice_selector_const(const ASN1_VALUE **pval, const ASN1_ITEM *it);
 int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
                              const ASN1_ITEM *it);
 
 ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+const ASN1_VALUE **asn1_get_const_field_ptr(const ASN1_VALUE **pval,
+                                            const ASN1_TEMPLATE *tt);
 
-const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
+const ASN1_TEMPLATE *asn1_do_adb(const ASN1_VALUE *val, const ASN1_TEMPLATE *tt,
                                  int nullerr);
 
 int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
 
 void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
 void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
-int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
+int asn1_enc_restore(int *len, unsigned char **out, const ASN1_VALUE **pval,
                      const ASN1_ITEM *it);
 int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
                   const ASN1_ITEM *it);
diff --git a/crypto/asn1/asn_mime.c b/crypto/asn1/asn_mime.c
index d99f0ef..5c34938 100644
--- a/crypto/asn1/asn_mime.c
+++ b/crypto/asn1/asn_mime.c
@@ -64,6 +64,7 @@ static void mime_hdr_free(MIME_HEADER *hdr);
 
 /* Output an ASN1 structure in BER format streaming if necessary */
 
+/* unfortunately cannot constify this due to CMS_stream() and PKCS7_stream() */
 int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
                         const ASN1_ITEM *it)
 {
@@ -311,6 +312,7 @@ int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
 
 /* Handle output of ASN1 data */
 
+/* cannot constify val because of CMS_dataFinal() */
 static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
                             const ASN1_ITEM *it)
 {
diff --git a/crypto/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c
index 015c54d..d3be967 100644
--- a/crypto/asn1/bio_ndef.c
+++ b/crypto/asn1/bio_ndef.c
@@ -49,6 +49,7 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
 static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
                             void *parg);
 
+/* unfortunately cannot constify this due to CMS_stream() and PKCS7_stream() */
 BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
 {
     NDEF_SUPPORT *ndef_aux = NULL;
diff --git a/crypto/asn1/i2d_pr.c b/crypto/asn1/i2d_pr.c
index e8b1dd2..7133d3d 100644
--- a/crypto/asn1/i2d_pr.c
+++ b/crypto/asn1/i2d_pr.c
@@ -14,7 +14,7 @@
 #include "internal/asn1_int.h"
 #include "internal/evp_int.h"
 
-int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
+int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
 {
     if (a->ameth && a->ameth->old_priv_encode) {
         return a->ameth->old_priv_encode(a, pp);
diff --git a/crypto/asn1/i2d_pu.c b/crypto/asn1/i2d_pu.c
index ff15282..8195dda 100644
--- a/crypto/asn1/i2d_pu.c
+++ b/crypto/asn1/i2d_pu.c
@@ -16,7 +16,7 @@
 #include <openssl/dsa.h>
 #include <openssl/ec.h>
 
-int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
+int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp)
 {
     switch (EVP_PKEY_id(a)) {
 #ifndef OPENSSL_NO_RSA
diff --git a/crypto/asn1/n_pkey.c b/crypto/asn1/n_pkey.c
index 3c83e4b..12592d0 100644
--- a/crypto/asn1/n_pkey.c
+++ b/crypto/asn1/n_pkey.c
@@ -43,9 +43,9 @@ ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = {
         ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG)
 } static_ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY)
 
-DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_PKEY)
-IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_ENCRYPTED_PKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_name(NETSCAPE_ENCRYPTED_PKEY, NETSCAPE_ENCRYPTED_PKEY)
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_ENCRYPTED_PKEY)
 
 ASN1_SEQUENCE(NETSCAPE_PKEY) = {
         ASN1_EMBED(NETSCAPE_PKEY, version, INT32),
@@ -53,9 +53,9 @@ ASN1_SEQUENCE(NETSCAPE_PKEY) = {
         ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING)
 } static_ASN1_SEQUENCE_END(NETSCAPE_PKEY)
 
-DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY)
-IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_PKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_name(NETSCAPE_PKEY, NETSCAPE_PKEY)
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_PKEY)
 
 # endif                         /* OPENSSL_NO_RC4 */
 
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
index 03d02b7..87c01f0 100644
--- a/crypto/asn1/tasn_dec.c
+++ b/crypto/asn1/tasn_dec.c
@@ -316,7 +316,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
             if (tt->flags & ASN1_TFLG_ADB_MASK) {
                 const ASN1_TEMPLATE *seqtt;
                 ASN1_VALUE **pseqval;
-                seqtt = asn1_do_adb(pval, tt, 0);
+                seqtt = asn1_do_adb(*pval, tt, 0);
                 if (seqtt == NULL)
                     continue;
                 pseqval = asn1_get_field_ptr(pval, seqtt);
@@ -328,7 +328,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
         for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
             const ASN1_TEMPLATE *seqtt;
             ASN1_VALUE **pseqval;
-            seqtt = asn1_do_adb(pval, tt, 1);
+            seqtt = asn1_do_adb(*pval, tt, 1);
             if (seqtt == NULL)
                 goto err;
             pseqval = asn1_get_field_ptr(pval, seqtt);
@@ -394,7 +394,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
          */
         for (; i < it->tcount; tt++, i++) {
             const ASN1_TEMPLATE *seqtt;
-            seqtt = asn1_do_adb(pval, tt, 1);
+            seqtt = asn1_do_adb(*pval, tt, 1);
             if (seqtt == NULL)
                 goto err;
             if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c
index 411b53e..8ab9c37 100644
--- a/crypto/asn1/tasn_enc.c
+++ b/crypto/asn1/tasn_enc.c
@@ -16,16 +16,17 @@
 #include "internal/asn1_int.h"
 #include "asn1_locl.h"
 
-static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
+static int asn1_i2d_ex_primitive(const ASN1_VALUE **pval, unsigned char **out,
                                  const ASN1_ITEM *it, int tag, int aclass);
-static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
+static int asn1_set_seq_out(STACK_OF(const_ASN1_VALUE) *sk,
+                            unsigned char **out,
                             int skcontlen, const ASN1_ITEM *item,
                             int do_sort, int iclass);
-static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
                                 const ASN1_TEMPLATE *tt, int tag, int aclass);
-static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
+static int asn1_item_flags_i2d(const ASN1_VALUE *val, unsigned char **out,
                                const ASN1_ITEM *it, int flags);
-static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
+static int asn1_ex_i2c(const ASN1_VALUE **pval, unsigned char *cout, int *putype,
                        const ASN1_ITEM *it);
 
 /*
@@ -33,13 +34,13 @@ static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
  * indefinite length constructed encoding, where appropriate
  */
 
-int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
+int ASN1_item_ndef_i2d(const ASN1_VALUE *val, unsigned char **out,
                        const ASN1_ITEM *it)
 {
     return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
 }
 
-int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
+int ASN1_item_i2d(const ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
 {
     return asn1_item_flags_i2d(val, out, it, 0);
 }
@@ -51,7 +52,7 @@ int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
  * allocated and populated with the encoding.
  */
 
-static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
+static int asn1_item_flags_i2d(const ASN1_VALUE *val, unsigned char **out,
                                const ASN1_ITEM *it, int flags)
 {
     if (out && !*out) {
@@ -79,20 +80,22 @@ static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
  * performs the normal item handling: it can be used in external types.
  */
 
-int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
                      const ASN1_ITEM *it, int tag, int aclass)
 {
     const ASN1_TEMPLATE *tt = NULL;
     int i, seqcontlen, seqlen, ndef = 1;
     const ASN1_EXTERN_FUNCS *ef;
     const ASN1_AUX *aux = it->funcs;
-    ASN1_aux_cb *asn1_cb = 0;
+    ASN1_aux_const_cb *asn1_cb = NULL;
 
     if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
         return 0;
 
-    if (aux && aux->asn1_cb)
-        asn1_cb = aux->asn1_cb;
+    if (aux != NULL) {
+        asn1_cb = ((aux->flags & ASN1_AFLG_CONST_CB) != 0) ? aux->asn1_const_cb
+            : (ASN1_aux_const_cb *)aux->asn1_cb; /* backward compatibility */
+    }
 
     switch (it->itype) {
 
@@ -108,12 +111,12 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
     case ASN1_ITYPE_CHOICE:
         if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
             return 0;
-        i = asn1_get_choice_selector(pval, it);
+        i = asn1_get_choice_selector_const(pval, it);
         if ((i >= 0) && (i < it->tcount)) {
-            ASN1_VALUE **pchval;
+            const ASN1_VALUE **pchval;
             const ASN1_TEMPLATE *chtt;
             chtt = it->templates + i;
-            pchval = asn1_get_field_ptr(pval, chtt);
+            pchval = asn1_get_const_field_ptr(pval, chtt);
             return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass);
         }
         /* Fixme: error condition if selector out of range */
@@ -154,12 +157,12 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
         /* First work out sequence content length */
         for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
             const ASN1_TEMPLATE *seqtt;
-            ASN1_VALUE **pseqval;
+            const ASN1_VALUE **pseqval;
             int tmplen;
-            seqtt = asn1_do_adb(pval, tt, 1);
+            seqtt = asn1_do_adb(*pval, tt, 1);
             if (!seqtt)
                 return 0;
-            pseqval = asn1_get_field_ptr(pval, seqtt);
+            pseqval = asn1_get_const_field_ptr(pval, seqtt);
             tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass);
             if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen))
                 return -1;
@@ -173,11 +176,11 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
         ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
         for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
             const ASN1_TEMPLATE *seqtt;
-            ASN1_VALUE **pseqval;
-            seqtt = asn1_do_adb(pval, tt, 1);
+            const ASN1_VALUE **pseqval;
+            seqtt = asn1_do_adb(*pval, tt, 1);
             if (!seqtt)
                 return 0;
-            pseqval = asn1_get_field_ptr(pval, seqtt);
+            pseqval = asn1_get_const_field_ptr(pval, seqtt);
             /* FIXME: check for errors in enhanced version */
             asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
         }
@@ -194,11 +197,11 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
     return 0;
 }
 
-static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
                                 const ASN1_TEMPLATE *tt, int tag, int iclass)
 {
     int i, ret, flags, ttag, tclass, ndef;
-    ASN1_VALUE *tval;
+    const ASN1_VALUE *tval;
     flags = tt->flags;
 
     /*
@@ -250,10 +253,10 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
 
     if (flags & ASN1_TFLG_SK_MASK) {
         /* SET OF, SEQUENCE OF */
-        STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+        STACK_OF(const_ASN1_VALUE) *sk = (STACK_OF(const_ASN1_VALUE) *)*pval;
         int isset, sktag, skaclass;
         int skcontlen, sklen;
-        ASN1_VALUE *skitem;
+        const ASN1_VALUE *skitem;
 
         if (!*pval)
             return 0;
@@ -283,9 +286,9 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
 
         /* Determine total length of items */
         skcontlen = 0;
-        for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+        for (i = 0; i < sk_const_ASN1_VALUE_num(sk); i++) {
             int tmplen;
-            skitem = sk_ASN1_VALUE_value(sk, i);
+            skitem = sk_const_ASN1_VALUE_value(sk, i);
             tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item),
                                       -1, iclass);
             if (tmplen == -1 || (skcontlen > INT_MAX - tmplen))
@@ -351,7 +354,7 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
 typedef struct {
     unsigned char *data;
     int length;
-    ASN1_VALUE *field;
+    const ASN1_VALUE *field;
 } DER_ENC;
 
 static int der_cmp(const void *a, const void *b)
@@ -367,20 +370,21 @@ static int der_cmp(const void *a, const void *b)
 
 /* Output the content octets of SET OF or SEQUENCE OF */
 
-static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
+static int asn1_set_seq_out(STACK_OF(const_ASN1_VALUE) *sk,
+                            unsigned char **out,
                             int skcontlen, const ASN1_ITEM *item,
                             int do_sort, int iclass)
 {
     int i;
-    ASN1_VALUE *skitem;
+    const ASN1_VALUE *skitem;
     unsigned char *tmpdat = NULL, *p = NULL;
     DER_ENC *derlst = NULL, *tder;
     if (do_sort) {
         /* Don't need to sort less than 2 items */
-        if (sk_ASN1_VALUE_num(sk) < 2)
+        if (sk_const_ASN1_VALUE_num(sk) < 2)
             do_sort = 0;
         else {
-            derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
+            derlst = OPENSSL_malloc(sk_const_ASN1_VALUE_num(sk)
                                     * sizeof(*derlst));
             if (derlst == NULL)
                 return 0;
@@ -393,8 +397,8 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
     }
     /* If not sorting just output each item */
     if (!do_sort) {
-        for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
-            skitem = sk_ASN1_VALUE_value(sk, i);
+        for (i = 0; i < sk_const_ASN1_VALUE_num(sk); i++) {
+            skitem = sk_const_ASN1_VALUE_value(sk, i);
             ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
         }
         return 1;
@@ -402,33 +406,33 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
     p = tmpdat;
 
     /* Doing sort: build up a list of each member's DER encoding */
-    for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
-        skitem = sk_ASN1_VALUE_value(sk, i);
+    for (i = 0, tder = derlst; i < sk_const_ASN1_VALUE_num(sk); i++, tder++) {
+        skitem = sk_const_ASN1_VALUE_value(sk, i);
         tder->data = p;
         tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
         tder->field = skitem;
     }
 
     /* Now sort them */
-    qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
+    qsort(derlst, sk_const_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
     /* Output sorted DER encoding */
     p = *out;
-    for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
+    for (i = 0, tder = derlst; i < sk_const_ASN1_VALUE_num(sk); i++, tder++) {
         memcpy(p, tder->data, tder->length);
         p += tder->length;
     }
     *out = p;
     /* If do_sort is 2 then reorder the STACK */
     if (do_sort == 2) {
-        for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
-            (void)sk_ASN1_VALUE_set(sk, i, tder->field);
+        for (i = 0, tder = derlst; i < sk_const_ASN1_VALUE_num(sk); i++, tder++)
+            (void)sk_const_ASN1_VALUE_set(sk, i, tder->field);
     }
     OPENSSL_free(derlst);
     OPENSSL_free(tmpdat);
     return 1;
 }
 
-static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
+static int asn1_i2d_ex_primitive(const ASN1_VALUE **pval, unsigned char **out,
                                  const ASN1_ITEM *it, int tag, int aclass)
 {
     int len;
@@ -488,7 +492,7 @@ static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
 
 /* Produce content octets from a structure */
 
-static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
+static int asn1_ex_i2c(const ASN1_VALUE **pval, unsigned char *cout, int *putype,
                        const ASN1_ITEM *it)
 {
     ASN1_BOOLEAN *tbool = NULL;
@@ -521,7 +525,7 @@ static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
         typ = (ASN1_TYPE *)*pval;
         utype = typ->type;
         *putype = utype;
-        pval = &typ->value.asn1_value;
+        pval = (const ASN1_VALUE **)&typ->value.asn1_value; /* actually is const */
     } else
         utype = *putype;
 
diff --git a/crypto/asn1/tasn_fre.c b/crypto/asn1/tasn_fre.c
index 71596d7..bffa6f1 100644
--- a/crypto/asn1/tasn_fre.c
+++ b/crypto/asn1/tasn_fre.c
@@ -103,7 +103,7 @@ void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
             ASN1_VALUE **pseqval;
 
             tt--;
-            seqtt = asn1_do_adb(pval, tt, 0);
+            seqtt = asn1_do_adb(*pval, tt, 0);
             if (!seqtt)
                 continue;
             pseqval = asn1_get_field_ptr(pval, seqtt);
diff --git a/crypto/asn1/tasn_prn.c b/crypto/asn1/tasn_prn.c
index 7353906..0f56fb0 100644
--- a/crypto/asn1/tasn_prn.c
+++ b/crypto/asn1/tasn_prn.c
@@ -101,15 +101,15 @@ void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
 
 /* Main print routines */
 
-static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+static int asn1_item_print_ctx(BIO *out, const ASN1_VALUE **fld, int indent,
                                const ASN1_ITEM *it,
                                const char *fname, const char *sname,
                                int nohdr, const ASN1_PCTX *pctx);
 
-static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+static int asn1_template_print_ctx(BIO *out, const ASN1_VALUE **fld, int indent,
                             const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
 
-static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
+static int asn1_primitive_print(BIO *out, const ASN1_VALUE **fld,
                                 const ASN1_ITEM *it, int indent,
                                 const char *fname, const char *sname,
                                 const ASN1_PCTX *pctx);
@@ -118,7 +118,7 @@ static int asn1_print_fsname(BIO *out, int indent,
                              const char *fname, const char *sname,
                              const ASN1_PCTX *pctx);
 
-int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+int ASN1_item_print(BIO *out, const ASN1_VALUE *ifld, int indent,
                     const ASN1_ITEM *it, const ASN1_PCTX *pctx)
 {
     const char *sname;
@@ -131,25 +131,25 @@ int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
     return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx);
 }
 
-static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+static int asn1_item_print_ctx(BIO *out, const ASN1_VALUE **fld, int indent,
                                const ASN1_ITEM *it,
                                const char *fname, const char *sname,
                                int nohdr, const ASN1_PCTX *pctx)
 {
     const ASN1_TEMPLATE *tt;
     const ASN1_EXTERN_FUNCS *ef;
-    ASN1_VALUE **tmpfld;
+    const ASN1_VALUE **tmpfld;
     const ASN1_AUX *aux = it->funcs;
-    ASN1_aux_cb *asn1_cb;
+    ASN1_aux_const_cb *asn1_cb = NULL;
     ASN1_PRINT_ARG parg;
     int i;
-    if (aux && aux->asn1_cb) {
+    if (aux != NULL) {
         parg.out = out;
         parg.indent = indent;
         parg.pctx = pctx;
-        asn1_cb = aux->asn1_cb;
-    } else
-        asn1_cb = 0;
+        asn1_cb = ((aux->flags & ASN1_AFLG_CONST_CB) != 0) ? aux->asn1_const_cb
+            : (ASN1_aux_const_cb *)aux->asn1_cb; /* backward compatibility */
+    }
 
    if (((it->itype != ASN1_ITYPE_PRIMITIVE)
        || (it->utype != V_ASN1_BOOLEAN)) && *fld == NULL) {
@@ -195,7 +195,7 @@ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
 
     case ASN1_ITYPE_CHOICE:
         /* CHOICE type, get selector */
-        i = asn1_get_choice_selector(fld, it);
+        i = asn1_get_choice_selector_const(fld, it);
         /* This should never happen... */
         if ((i < 0) || (i >= it->tcount)) {
             if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0)
@@ -203,7 +203,7 @@ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
             return 1;
         }
         tt = it->templates + i;
-        tmpfld = asn1_get_field_ptr(fld, tt);
+        tmpfld = asn1_get_const_field_ptr(fld, tt);
         if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
             return 0;
         break;
@@ -233,10 +233,10 @@ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
         /* Print each field entry */
         for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
             const ASN1_TEMPLATE *seqtt;
-            seqtt = asn1_do_adb(fld, tt, 1);
+            seqtt = asn1_do_adb(*fld, tt, 1);
             if (!seqtt)
                 return 0;
-            tmpfld = asn1_get_field_ptr(fld, seqtt);
+            tmpfld = asn1_get_const_field_ptr(fld, seqtt);
             if (!asn1_template_print_ctx(out, tmpfld,
                                          indent + 2, seqtt, pctx))
                 return 0;
@@ -261,12 +261,12 @@ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
     return 1;
 }
 
-static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+static int asn1_template_print_ctx(BIO *out, const ASN1_VALUE **fld, int indent,
                             const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
 {
     int i, flags;
     const char *sname, *fname;
-    ASN1_VALUE *tfld;
+    const ASN1_VALUE *tfld;
     flags = tt->flags;
     if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
         sname = ASN1_ITEM_ptr(tt->item)->sname;
@@ -282,14 +282,14 @@ static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
      * a pointer to a field.
      */
     if (flags & ASN1_TFLG_EMBED) {
-        tfld = (ASN1_VALUE *)fld;
+        tfld = (const ASN1_VALUE *)fld;
         fld = &tfld;
     }
 
     if (flags & ASN1_TFLG_SK_MASK) {
         char *tname;
-        ASN1_VALUE *skitem;
-        STACK_OF(ASN1_VALUE) *stack;
+        const ASN1_VALUE *skitem;
+        STACK_OF(const_ASN1_VALUE) *stack;
 
         /* SET OF, SEQUENCE OF */
         if (fname) {
@@ -304,12 +304,12 @@ static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
             } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0)
                 return 0;
         }
-        stack = (STACK_OF(ASN1_VALUE) *)*fld;
-        for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
+        stack = (STACK_OF(const_ASN1_VALUE) *)*fld;
+        for (i = 0; i < sk_const_ASN1_VALUE_num(stack); i++) {
             if ((i > 0) && (BIO_puts(out, "\n") <= 0))
                 return 0;
 
-            skitem = sk_ASN1_VALUE_value(stack, i);
+            skitem = sk_const_ASN1_VALUE_value(stack, i);
             if (!asn1_item_print_ctx(out, &skitem, indent + 2,
                                      ASN1_ITEM_ptr(tt->item), NULL, NULL, 1,
                                      pctx))
@@ -430,7 +430,7 @@ static int asn1_print_obstring(BIO *out, const ASN1_STRING *str, int indent)
     return 1;
 }
 
-static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
+static int asn1_primitive_print(BIO *out, const ASN1_VALUE **fld,
                                 const ASN1_ITEM *it, int indent,
                                 const char *fname, const char *sname,
                                 const ASN1_PCTX *pctx)
@@ -456,9 +456,9 @@ static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
             str = (ASN1_STRING *)*fld;
     }
     if (utype == V_ASN1_ANY) {
-        ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
+        const ASN1_TYPE *atype = (const ASN1_TYPE *)*fld;
         utype = atype->type;
-        fld = &atype->value.asn1_value;
+        fld = (const ASN1_VALUE **)&atype->value.asn1_value; /* actually is const */
         str = (ASN1_STRING *)*fld;
         if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
             pname = NULL;
diff --git a/crypto/asn1/tasn_typ.c b/crypto/asn1/tasn_typ.c
index 37a9883..8095e32 100644
--- a/crypto/asn1/tasn_typ.c
+++ b/crypto/asn1/tasn_typ.c
@@ -80,5 +80,5 @@ ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) =
         ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY)
 ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY)
 
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY)
diff --git a/crypto/asn1/tasn_utl.c b/crypto/asn1/tasn_utl.c
index 1694bdc..53dad7a 100644
--- a/crypto/asn1/tasn_utl.c
+++ b/crypto/asn1/tasn_utl.c
@@ -29,6 +29,14 @@
 int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
     int *sel = offset2ptr(*pval, it->utype);
+
+    return *sel;
+}
+
+int asn1_get_choice_selector_const(const ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    int *sel = offset2ptr(*pval, it->utype);
+
     return *sel;
 }
 
@@ -40,6 +48,7 @@ int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
                              const ASN1_ITEM *it)
 {
     int *sel, ret;
+
     sel = offset2ptr(*pval, it->utype);
     ret = *sel;
     *sel = value;
@@ -66,7 +75,7 @@ int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
         && (it->itype != ASN1_ITYPE_NDEF_SEQUENCE))
         return 0;
     aux = it->funcs;
-    if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT))
+    if (aux == NULL || (aux->flags & ASN1_AFLG_REFCOUNT) == 0)
         return 0;
     lck = offset2ptr(*pval, aux->ref_offset);
     lock = offset2ptr(*pval, aux->ref_lock);
@@ -104,19 +113,33 @@ int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
 static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
     const ASN1_AUX *aux;
-    if (!pval || !*pval)
+
+    if (pval == NULL || *pval == NULL)
         return NULL;
     aux = it->funcs;
-    if (!aux || !(aux->flags & ASN1_AFLG_ENCODING))
+    if (aux == NULL || (aux->flags & ASN1_AFLG_ENCODING) == 0)
+        return NULL;
+    return offset2ptr(*pval, aux->enc_offset);
+}
+
+static const ASN1_ENCODING *asn1_get_const_enc_ptr(const ASN1_VALUE **pval,
+                                                   const ASN1_ITEM *it)
+{
+    const ASN1_AUX *aux;
+
+    if (pval == NULL || *pval == NULL)
+        return NULL;
+    aux = it->funcs;
+    if (aux == NULL || (aux->flags & ASN1_AFLG_ENCODING) == 0)
         return NULL;
     return offset2ptr(*pval, aux->enc_offset);
 }
 
 void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
-    ASN1_ENCODING *enc;
-    enc = asn1_get_enc_ptr(pval, it);
-    if (enc) {
+    ASN1_ENCODING *enc = asn1_get_enc_ptr(pval, it);
+
+    if (enc != NULL) {
         enc->enc = NULL;
         enc->len = 0;
         enc->modified = 1;
@@ -125,9 +148,9 @@ void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
 
 void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
-    ASN1_ENCODING *enc;
-    enc = asn1_get_enc_ptr(pval, it);
-    if (enc) {
+    ASN1_ENCODING *enc = asn1_get_enc_ptr(pval, it);
+
+    if (enc != NULL) {
         OPENSSL_free(enc->enc);
         enc->enc = NULL;
         enc->len = 0;
@@ -138,9 +161,9 @@ void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
 int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
                   const ASN1_ITEM *it)
 {
-    ASN1_ENCODING *enc;
-    enc = asn1_get_enc_ptr(pval, it);
-    if (!enc)
+    ASN1_ENCODING *enc = asn1_get_enc_ptr(pval, it);
+
+    if (enc == NULL)
         return 1;
 
     OPENSSL_free(enc->enc);
@@ -155,18 +178,18 @@ int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
     return 1;
 }
 
-int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
+int asn1_enc_restore(int *len, unsigned char **out, const ASN1_VALUE **pval,
                      const ASN1_ITEM *it)
 {
-    ASN1_ENCODING *enc;
-    enc = asn1_get_enc_ptr(pval, it);
-    if (!enc || enc->modified)
+    const ASN1_ENCODING *enc = asn1_get_const_enc_ptr(pval, it);
+
+    if (enc == NULL || enc->modified)
         return 0;
     if (out) {
         memcpy(*out, enc->enc, enc->len);
         *out += enc->len;
     }
-    if (len)
+    if (len != NULL)
         *len = enc->len;
     return 1;
 }
@@ -174,8 +197,8 @@ int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
 /* Given an ASN1_TEMPLATE get a pointer to a field */
 ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
 {
-    ASN1_VALUE **pvaltmp;
-    pvaltmp = offset2ptr(*pval, tt->offset);
+    ASN1_VALUE **pvaltmp = offset2ptr(*pval, tt->offset);
+
     /*
      * NOTE for BOOLEAN types the field is just a plain int so we can't
      * return int **, so settle for (int *).
@@ -183,31 +206,40 @@ ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
     return pvaltmp;
 }
 
+/* Given an ASN1_TEMPLATE get a const pointer to a field */
+const ASN1_VALUE **asn1_get_const_field_ptr(const ASN1_VALUE **pval,
+                                            const ASN1_TEMPLATE *tt)
+{
+    return offset2ptr(*pval, tt->offset);
+}
+
 /*
  * Handle ANY DEFINED BY template, find the selector, look up the relevant
  * ASN1_TEMPLATE in the table and return it.
  */
 
-const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
+const ASN1_TEMPLATE *asn1_do_adb(const ASN1_VALUE *val,
+                                 const ASN1_TEMPLATE *tt,
                                  int nullerr)
 {
     const ASN1_ADB *adb;
     const ASN1_ADB_TABLE *atbl;
     long selector;
-    ASN1_VALUE **sfld;
+    const ASN1_VALUE **sfld;
     int i;
-    if (!(tt->flags & ASN1_TFLG_ADB_MASK))
+
+    if ((tt->flags & ASN1_TFLG_ADB_MASK) == 0)
         return tt;
 
     /* Else ANY DEFINED BY ... get the table */
     adb = ASN1_ADB_ptr(tt->item);
 
     /* Get the selector field */
-    sfld = offset2ptr(*pval, adb->offset);
+    sfld = offset2ptr(val, adb->offset);
 
     /* Check if NULL */
     if (*sfld == NULL) {
-        if (!adb->null_tt)
+        if (adb->null_tt == NULL)
             goto err;
         return adb->null_tt;
     }
@@ -216,7 +248,7 @@ const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
      * Convert type to a long: NB: don't check for NID_undef here because it
      * might be a legitimate value in the table
      */
-    if (tt->flags & ASN1_TFLG_ADB_OID)
+    if ((tt->flags & ASN1_TFLG_ADB_OID) != 0)
         selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld);
     else
         selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld);
diff --git a/crypto/asn1/x_bignum.c b/crypto/asn1/x_bignum.c
index 11a2eb5..d7abca6 100644
--- a/crypto/asn1/x_bignum.c
+++ b/crypto/asn1/x_bignum.c
@@ -25,13 +25,13 @@ static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
 static int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
 static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
 
-static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+static int bn_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype,
                   const ASN1_ITEM *it);
 static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
                   int utype, char *free_cont, const ASN1_ITEM *it);
 static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
                          int utype, char *free_cont, const ASN1_ITEM *it);
-static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+static int bn_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it,
                     int indent, const ASN1_PCTX *pctx);
 
 static ASN1_PRIMITIVE_FUNCS bignum_pf = {
@@ -91,7 +91,7 @@ static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
     *pval = NULL;
 }
 
-static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+static int bn_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype,
                   const ASN1_ITEM *it)
 {
     BIGNUM *bn;
@@ -135,7 +135,7 @@ static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
     return bn_c2i(pval, cont, len, utype, free_cont, it);
 }
 
-static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+static int bn_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it,
                     int indent, const ASN1_PCTX *pctx)
 {
     if (!BN_print(out, *(BIGNUM **)pval))
diff --git a/crypto/asn1/x_int64.c b/crypto/asn1/x_int64.c
index 657e00d..1b55f4f 100644
--- a/crypto/asn1/x_int64.c
+++ b/crypto/asn1/x_int64.c
@@ -46,8 +46,8 @@ static void uint64_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
     **(uint64_t **)pval = 0;
 }
 
-static int uint64_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
-                    const ASN1_ITEM *it)
+static int uint64_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                      const ASN1_ITEM *it)
 {
     uint64_t utmp;
     int neg = 0;
@@ -71,7 +71,7 @@ static int uint64_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
 }
 
 static int uint64_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
-                    int utype, char *free_cont, const ASN1_ITEM *it)
+                      int utype, char *free_cont, const ASN1_ITEM *it)
 {
     uint64_t utmp = 0;
     char *cp;
@@ -111,7 +111,7 @@ static int uint64_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
     return 1;
 }
 
-static int uint64_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+static int uint64_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it,
                         int indent, const ASN1_PCTX *pctx)
 {
     if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED)
@@ -141,8 +141,8 @@ static void uint32_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
     **(uint32_t **)pval = 0;
 }
 
-static int uint32_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
-                    const ASN1_ITEM *it)
+static int uint32_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                      const ASN1_ITEM *it)
 {
     uint32_t utmp;
     int neg = 0;
@@ -173,7 +173,7 @@ static int uint32_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
 #define ABS_INT32_MIN ((uint32_t)INT32_MAX + 1)
 
 static int uint32_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
-                    int utype, char *free_cont, const ASN1_ITEM *it)
+                      int utype, char *free_cont, const ASN1_ITEM *it)
 {
     uint64_t utmp = 0;
     uint32_t utmp2 = 0;
@@ -220,7 +220,7 @@ static int uint32_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
     return 1;
 }
 
-static int uint32_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+static int uint32_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it,
                         int indent, const ASN1_PCTX *pctx)
 {
     if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED)
diff --git a/crypto/asn1/x_long.c b/crypto/asn1/x_long.c
index f5da0e0..89d5e83 100644
--- a/crypto/asn1/x_long.c
+++ b/crypto/asn1/x_long.c
@@ -25,11 +25,11 @@ NON_EMPTY_TRANSLATION_UNIT
 static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
 static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
 
-static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+static int long_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype,
                     const ASN1_ITEM *it);
 static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
                     int utype, char *free_cont, const ASN1_ITEM *it);
-static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+static int long_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it,
                       int indent, const ASN1_PCTX *pctx);
 
 static ASN1_PRIMITIVE_FUNCS long_pf = {
@@ -86,7 +86,7 @@ static int num_bits_ulong(unsigned long value)
     return (int)ret;
 }
 
-static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+static int long_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype,
                     const ASN1_ITEM *it)
 {
     long ltmp;
@@ -190,7 +190,7 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
     return 1;
 }
 
-static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+static int long_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it,
                       int indent, const ASN1_PCTX *pctx)
 {
     long l;
diff --git a/crypto/cms/cms_dd.c b/crypto/cms/cms_dd.c
index 0227180..8bdbdfd 100644
--- a/crypto/cms/cms_dd.c
+++ b/crypto/cms/cms_dd.c
@@ -45,14 +45,14 @@ CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
     return NULL;
 }
 
-BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms)
+BIO *cms_DigestedData_init_bio(const CMS_ContentInfo *cms)
 {
     CMS_DigestedData *dd;
     dd = cms->d.digestedData;
     return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
 }
 
-int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)
+int cms_DigestedData_do_final(const CMS_ContentInfo *cms, BIO *chain, int verify)
 {
     EVP_MD_CTX *mctx = EVP_MD_CTX_new();
     unsigned char md[EVP_MAX_MD_SIZE];
diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c
index 13d8578..d3a087b 100644
--- a/crypto/cms/cms_enc.c
+++ b/crypto/cms/cms_enc.c
@@ -204,7 +204,7 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
     return cms_EncryptedContent_init(ec, ciph, key, keylen);
 }
 
-BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
+BIO *cms_EncryptedData_init_bio(const CMS_ContentInfo *cms)
 {
     CMS_EncryptedData *enc = cms->d.encryptedData;
     if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c
index 187b721..acfbf8c 100644
--- a/crypto/cms/cms_env.c
+++ b/crypto/cms/cms_env.c
@@ -289,7 +289,7 @@ int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
 
 /* Encrypt content key in key transport recipient info */
 
-static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
+static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms,
                                           CMS_RecipientInfo *ri)
 {
     CMS_KeyTransRecipientInfo *ktri;
@@ -610,7 +610,7 @@ int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
 
 /* Encrypt content key in KEK recipient info */
 
-static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
+static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms,
                                            CMS_RecipientInfo *ri)
 {
     CMS_EncryptedContentInfo *ec;
@@ -755,7 +755,7 @@ int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
     }
 }
 
-int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
+int CMS_RecipientInfo_encrypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
 {
     switch (ri->type) {
     case CMS_RECIPINFO_TRANS:
@@ -840,7 +840,7 @@ static void cms_env_set_version(CMS_EnvelopedData *env)
     env->version = 0;
 }
 
-BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
+BIO *cms_EnvelopedData_init_bio(const CMS_ContentInfo *cms)
 {
     CMS_EncryptedContentInfo *ec;
     STACK_OF(CMS_RecipientInfo) *rinfos;
diff --git a/crypto/cms/cms_io.c b/crypto/cms/cms_io.c
index ad41884..f3b5874 100644
--- a/crypto/cms/cms_io.c
+++ b/crypto/cms/cms_io.c
@@ -14,6 +14,7 @@
 #include <openssl/cms.h>
 #include "cms_lcl.h"
 
+/* unfortunately cannot constify BIO_new_NDEF() due to this and PKCS7_stream() */
 int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms)
 {
     ASN1_OCTET_STRING **pos;
diff --git a/crypto/cms/cms_kari.c b/crypto/cms/cms_kari.c
index 9f1f5d5..866749a 100644
--- a/crypto/cms/cms_kari.c
+++ b/crypto/cms/cms_kari.c
@@ -363,7 +363,7 @@ static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
 
 /* Encrypt content key in key agreement recipient info */
 
-int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms,
+int cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
                                    CMS_RecipientInfo *ri)
 {
     CMS_KeyAgreeRecipientInfo *kari;
diff --git a/crypto/cms/cms_lcl.h b/crypto/cms/cms_lcl.h
index be4f93e..64b673a 100644
--- a/crypto/cms/cms_lcl.h
+++ b/crypto/cms/cms_lcl.h
@@ -368,8 +368,8 @@ BIO *cms_content_bio(CMS_ContentInfo *cms);
 CMS_ContentInfo *cms_Data_create(void);
 
 CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md);
-BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms);
-int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify);
+BIO *cms_DigestedData_init_bio(const CMS_ContentInfo *cms);
+int cms_DigestedData_do_final(const CMS_ContentInfo *cms, BIO *chain, int verify);
 
 BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms);
 int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain);
@@ -382,7 +382,7 @@ int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
 int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert);
 
 CMS_ContentInfo *cms_CompressedData_create(int comp_nid);
-BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms);
+BIO *cms_CompressedData_init_bio(const CMS_ContentInfo *cms);
 
 BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
 int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
@@ -394,7 +394,7 @@ int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert);
 int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert);
 
 BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
-BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
+BIO *cms_EncryptedData_init_bio(const CMS_ContentInfo *cms);
 int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
                               const EVP_CIPHER *cipher,
                               const unsigned char *key, size_t keylen);
@@ -403,18 +403,18 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
 int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
 ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);
 
-BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
+BIO *cms_EnvelopedData_init_bio(const CMS_ContentInfo *cms);
 CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms);
 int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd);
 int cms_pkey_get_ri_type(EVP_PKEY *pk);
 /* KARI routines */
 int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
                                 EVP_PKEY *pk, unsigned int flags);
-int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms,
+int cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
                                    CMS_RecipientInfo *ri);
 
 /* PWRI routines */
-int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
                                  int en_de);
 
 DECLARE_ASN1_ITEM(CMS_CertificateChoices)
diff --git a/crypto/cms/cms_lib.c b/crypto/cms/cms_lib.c
index c092341..29eacce 100644
--- a/crypto/cms/cms_lib.c
+++ b/crypto/cms/cms_lib.c
@@ -104,6 +104,7 @@ BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
 
 }
 
+/* unfortunately cannot constify SMIME_write_ASN1() due to this function */
 int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
 {
     ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
diff --git a/crypto/cms/cms_pwri.c b/crypto/cms/cms_pwri.c
index 980252d..f0502a4 100644
--- a/crypto/cms/cms_pwri.c
+++ b/crypto/cms/cms_pwri.c
@@ -273,7 +273,7 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen,
 
 /* Encrypt/Decrypt content key in PWRI recipient info */
 
-int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
                                  int en_de)
 {
     CMS_EncryptedContentInfo *ec;
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index e9eace14..1424c41 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -418,7 +418,7 @@ static int int_dh_param_copy(DH *to, const DH *from, int is_x942)
     return 1;
 }
 
-DH *DHparams_dup(DH *dh)
+DH *DHparams_dup(const DH *dh)
 {
     DH *ret;
     ret = DH_new();
diff --git a/crypto/dh/dh_asn1.c b/crypto/dh/dh_asn1.c
index 89acc7d..aabdfa8 100644
--- a/crypto/dh/dh_asn1.c
+++ b/crypto/dh/dh_asn1.c
@@ -37,7 +37,7 @@ ASN1_SEQUENCE_cb(DHparams, dh_cb) = {
         ASN1_OPT_EMBED(DH, length, ZINT32),
 } ASN1_SEQUENCE_END_cb(DH, DHparams)
 
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DH, DHparams, DHparams)
 
 /*
  * Internal only structures for handling X9.42 DH: this gets translated to or
@@ -74,7 +74,7 @@ int_dhx942_dh *d2i_int_dhx(int_dhx942_dh **a,
                            const unsigned char **pp, long length);
 int i2d_int_dhx(const int_dhx942_dh *a, unsigned char **pp);
 
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(int_dhx942_dh, DHxparams, int_dhx)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(int_dhx942_dh, DHxparams, int_dhx)
 
 /* Application public function: read in X9.42 DH parameters into DH structure */
 
diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c
index 309a176..3497915 100644
--- a/crypto/dh/dh_pmeth.c
+++ b/crypto/dh/dh_pmeth.c
@@ -77,7 +77,7 @@ static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
 }
 
 
-static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+static int pkey_dh_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
 {
     DH_PKEY_CTX *dctx, *sctx;
     if (!pkey_dh_init(dst))
diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c
index 6be9a1e..acf80c6 100644
--- a/crypto/dsa/dsa_asn1.c
+++ b/crypto/dsa/dsa_asn1.c
@@ -19,7 +19,7 @@ ASN1_SEQUENCE(DSA_SIG) = {
         ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)
 } static_ASN1_SEQUENCE_END(DSA_SIG)
 
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DSA_SIG, DSA_SIG, DSA_SIG)
 
 DSA_SIG *DSA_SIG_new(void)
 {
@@ -83,7 +83,7 @@ ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = {
         ASN1_SIMPLE(DSA, priv_key, CBIGNUM)
 } static_ASN1_SEQUENCE_END_cb(DSA, DSAPrivateKey)
 
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DSA, DSAPrivateKey, DSAPrivateKey)
 
 ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = {
         ASN1_SIMPLE(DSA, p, BIGNUM),
@@ -91,7 +91,7 @@ ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = {
         ASN1_SIMPLE(DSA, g, BIGNUM),
 } static_ASN1_SEQUENCE_END_cb(DSA, DSAparams)
 
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DSA, DSAparams, DSAparams)
 
 ASN1_SEQUENCE_cb(DSAPublicKey, dsa_cb) = {
         ASN1_SIMPLE(DSA, pub_key, BIGNUM),
@@ -100,9 +100,9 @@ ASN1_SEQUENCE_cb(DSAPublicKey, dsa_cb) = {
         ASN1_SIMPLE(DSA, g, BIGNUM)
 } static_ASN1_SEQUENCE_END_cb(DSA, DSAPublicKey)
 
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DSA, DSAPublicKey, DSAPublicKey)
 
-DSA *DSAparams_dup(DSA *dsa)
+DSA *DSAparams_dup(const DSA *dsa)
 {
     return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa);
 }
diff --git a/crypto/dsa/dsa_pmeth.c b/crypto/dsa/dsa_pmeth.c
index 0786fc2..cfba91c 100644
--- a/crypto/dsa/dsa_pmeth.c
+++ b/crypto/dsa/dsa_pmeth.c
@@ -47,7 +47,7 @@ static int pkey_dsa_init(EVP_PKEY_CTX *ctx)
     return 1;
 }
 
-static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+static int pkey_dsa_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
 {
     DSA_PKEY_CTX *dctx, *sctx;
 
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c
index ff50671..35ff948 100644
--- a/crypto/ec/ec_asn1.c
+++ b/crypto/ec/ec_asn1.c
@@ -217,9 +217,9 @@ ASN1_CHOICE(ECPKPARAMETERS) = {
         ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
 } ASN1_CHOICE_END(ECPKPARAMETERS)
 
-DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
-IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
+DECLARE_ASN1_FUNCTIONS(ECPKPARAMETERS)
+DECLARE_ASN1_ENCODE_FUNCTIONS_name(ECPKPARAMETERS, ECPKPARAMETERS)
+IMPLEMENT_ASN1_FUNCTIONS(ECPKPARAMETERS)
 
 ASN1_SEQUENCE(EC_PRIVATEKEY) = {
         ASN1_EMBED(EC_PRIVATEKEY, version, INT32),
@@ -228,9 +228,9 @@ ASN1_SEQUENCE(EC_PRIVATEKEY) = {
         ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
 } static_ASN1_SEQUENCE_END(EC_PRIVATEKEY)
 
-DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
-IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
+DECLARE_ASN1_FUNCTIONS(EC_PRIVATEKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_name(EC_PRIVATEKEY, EC_PRIVATEKEY)
+IMPLEMENT_ASN1_FUNCTIONS(EC_PRIVATEKEY)
 
 /* some declarations of internal function */
 
@@ -968,7 +968,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
     return NULL;
 }
 
-int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
+int i2d_ECPrivateKey(const EC_KEY *a, unsigned char **out)
 {
     int ret = 0, ok = 0;
     unsigned char *priv= NULL, *pub= NULL;
@@ -1040,7 +1040,7 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
     return (ok ? ret : 0);
 }
 
-int i2d_ECParameters(EC_KEY *a, unsigned char **out)
+int i2d_ECParameters(const EC_KEY *a, unsigned char **out)
 {
     if (a == NULL) {
         ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
@@ -1142,9 +1142,9 @@ ASN1_SEQUENCE(ECDSA_SIG) = {
         ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM)
 } static_ASN1_SEQUENCE_END(ECDSA_SIG)
 
-DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG)
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG)
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ECDSA_SIG, ECDSA_SIG, ECDSA_SIG)
+DECLARE_ASN1_FUNCTIONS(ECDSA_SIG)
+DECLARE_ASN1_ENCODE_FUNCTIONS_name(ECDSA_SIG, ECDSA_SIG)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(ECDSA_SIG, ECDSA_SIG, ECDSA_SIG)
 
 ECDSA_SIG *ECDSA_SIG_new(void)
 {
diff --git a/crypto/ec/ec_pmeth.c b/crypto/ec/ec_pmeth.c
index 5595edc..68211ed 100644
--- a/crypto/ec/ec_pmeth.c
+++ b/crypto/ec/ec_pmeth.c
@@ -53,7 +53,7 @@ static int pkey_ec_init(EVP_PKEY_CTX *ctx)
     return 1;
 }
 
-static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+static int pkey_ec_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
 {
     EC_PKEY_CTX *dctx, *sctx;
     if (!pkey_ec_init(dst))
diff --git a/crypto/ess/ess_asn1.c b/crypto/ess/ess_asn1.c
index d107469..0ea08e8 100644
--- a/crypto/ess/ess_asn1.c
+++ b/crypto/ess/ess_asn1.c
@@ -20,7 +20,7 @@ ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = {
         ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER)
 } static_ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL)
 
-IMPLEMENT_ASN1_FUNCTIONS_const(ESS_ISSUER_SERIAL)
+IMPLEMENT_ASN1_FUNCTIONS(ESS_ISSUER_SERIAL)
 IMPLEMENT_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL)
 
 ASN1_SEQUENCE(ESS_CERT_ID) = {
@@ -28,7 +28,7 @@ ASN1_SEQUENCE(ESS_CERT_ID) = {
         ASN1_OPT(ESS_CERT_ID, issuer_serial, ESS_ISSUER_SERIAL)
 } static_ASN1_SEQUENCE_END(ESS_CERT_ID)
 
-IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID)
+IMPLEMENT_ASN1_FUNCTIONS(ESS_CERT_ID)
 IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID)
 
 ASN1_SEQUENCE(ESS_SIGNING_CERT) = {
@@ -36,7 +36,7 @@ ASN1_SEQUENCE(ESS_SIGNING_CERT) = {
         ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT, policy_info, POLICYINFO)
 } static_ASN1_SEQUENCE_END(ESS_SIGNING_CERT)
 
-IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT)
+IMPLEMENT_ASN1_FUNCTIONS(ESS_SIGNING_CERT)
 IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT)
 
 ASN1_SEQUENCE(ESS_CERT_ID_V2) = {
@@ -45,7 +45,7 @@ ASN1_SEQUENCE(ESS_CERT_ID_V2) = {
         ASN1_OPT(ESS_CERT_ID_V2, issuer_serial, ESS_ISSUER_SERIAL)
 } static_ASN1_SEQUENCE_END(ESS_CERT_ID_V2)
 
-IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID_V2)
+IMPLEMENT_ASN1_FUNCTIONS(ESS_CERT_ID_V2)
 IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID_V2)
 
 ASN1_SEQUENCE(ESS_SIGNING_CERT_V2) = {
@@ -53,5 +53,5 @@ ASN1_SEQUENCE(ESS_SIGNING_CERT_V2) = {
         ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT_V2, policy_info, POLICYINFO)
 } static_ASN1_SEQUENCE_END(ESS_SIGNING_CERT_V2)
 
-IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT_V2)
+IMPLEMENT_ASN1_FUNCTIONS(ESS_SIGNING_CERT_V2)
 IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT_V2)
diff --git a/crypto/evp/encode.c b/crypto/evp/encode.c
index 3519e3b..ab80267 100644
--- a/crypto/evp/encode.c
+++ b/crypto/evp/encode.c
@@ -134,7 +134,7 @@ void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx)
     OPENSSL_free(ctx);
 }
 
-int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, EVP_ENCODE_CTX *sctx)
+int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, const EVP_ENCODE_CTX *sctx)
 {
     memcpy(dctx, sctx, sizeof(EVP_ENCODE_CTX));
 
diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c
index 752925f..bffe2b3 100644
--- a/crypto/evp/evp_pkey.c
+++ b/crypto/evp/evp_pkey.c
@@ -58,7 +58,7 @@ EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8)
 
 /* Turn a private key into a PKCS8 structure */
 
-PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey)
 {
     PKCS8_PRIV_KEY_INFO *p8 = PKCS8_PRIV_KEY_INFO_new();
     if (p8  == NULL) {
diff --git a/crypto/evp/mac_lib.c b/crypto/evp/mac_lib.c
index 0c04643..2f46277 100644
--- a/crypto/evp/mac_lib.c
+++ b/crypto/evp/mac_lib.c
@@ -48,7 +48,7 @@ void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx)
     OPENSSL_free(ctx);
 }
 
-int EVP_MAC_CTX_copy(EVP_MAC_CTX *dst, EVP_MAC_CTX *src)
+int EVP_MAC_CTX_copy(EVP_MAC_CTX *dst, const EVP_MAC_CTX *src)
 {
     EVP_MAC_IMPL *macdata;
 
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 5f599ab..9a882e9 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -460,7 +460,7 @@ int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
     return ret;
 }
 
-RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
+RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey)
 {
     if (pkey->type != EVP_PKEY_RSA) {
         EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
@@ -487,7 +487,7 @@ int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
     return ret;
 }
 
-DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey)
+DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey)
 {
     if (pkey->type != EVP_PKEY_DSA) {
         EVPerr(EVP_F_EVP_PKEY_GET0_DSA, EVP_R_EXPECTING_A_DSA_KEY);
@@ -515,7 +515,7 @@ int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
     return ret;
 }
 
-EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
+EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey)
 {
     if (pkey->type != EVP_PKEY_EC) {
         EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
@@ -543,7 +543,7 @@ int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
     return ret;
 }
 
-DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey)
+DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey)
 {
     if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
         EVPerr(EVP_F_EVP_PKEY_GET0_DH, EVP_R_EXPECTING_A_DH_KEY);
diff --git a/crypto/evp/pkey_mac.c b/crypto/evp/pkey_mac.c
index 3f6aa1c..858ca28 100644
--- a/crypto/evp/pkey_mac.c
+++ b/crypto/evp/pkey_mac.c
@@ -71,7 +71,7 @@ static int pkey_mac_init(EVP_PKEY_CTX *ctx)
 
 static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx);
 
-static int pkey_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
 {
     MAC_PKEY_CTX *sctx, *dctx;
 
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index 51700bf..28fa047 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -250,7 +250,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
     return int_ctx_new(NULL, e, id);
 }
 
-EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
 {
     EVP_PKEY_CTX *rctx;
     if (!pctx->pmeth || !pctx->pmeth->copy)
@@ -472,7 +472,7 @@ void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
     ctx->data = data;
 }
 
-void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
+void *EVP_PKEY_CTX_get_data(const EVP_PKEY_CTX *ctx)
 {
     return ctx->data;
 }
@@ -505,7 +505,7 @@ void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
 
 void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
                             int (*copy) (EVP_PKEY_CTX *dst,
-                                         EVP_PKEY_CTX *src))
+                                         const EVP_PKEY_CTX *src))
 {
     pmeth->copy = copy;
 }
@@ -675,7 +675,7 @@ void EVP_PKEY_meth_get_init(const EVP_PKEY_METHOD *pmeth,
 
 void EVP_PKEY_meth_get_copy(const EVP_PKEY_METHOD *pmeth,
                             int (**pcopy) (EVP_PKEY_CTX *dst,
-                                           EVP_PKEY_CTX *src))
+                                           const EVP_PKEY_CTX *src))
 {
     *pcopy = pmeth->copy;
 }
diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h
index dc75fe9..e55c1d9 100644
--- a/crypto/include/internal/evp_int.h
+++ b/crypto/include/internal/evp_int.h
@@ -44,7 +44,7 @@ struct evp_pkey_method_st {
     int pkey_id;
     int flags;
     int (*init) (EVP_PKEY_CTX *ctx);
-    int (*copy) (EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
+    int (*copy) (EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src);
     void (*cleanup) (EVP_PKEY_CTX *ctx);
     int (*paramgen_init) (EVP_PKEY_CTX *ctx);
     int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
diff --git a/crypto/ocsp/v3_ocsp.c b/crypto/ocsp/v3_ocsp.c
index c43bfc3..c58fa07 100644
--- a/crypto/ocsp/v3_ocsp.c
+++ b/crypto/ocsp/v3_ocsp.c
@@ -28,7 +28,7 @@ static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out,
                       int indent);
 
 static void *ocsp_nonce_new(void);
-static int i2d_ocsp_nonce(void *a, unsigned char **pp);
+static int i2d_ocsp_nonce(const void *a, unsigned char **pp);
 static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length);
 static void ocsp_nonce_free(void *a);
 static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
@@ -170,9 +170,9 @@ static void *ocsp_nonce_new(void)
     return ASN1_OCTET_STRING_new();
 }
 
-static int i2d_ocsp_nonce(void *a, unsigned char **pp)
+static int i2d_ocsp_nonce(const void *a, unsigned char **pp)
 {
-    ASN1_OCTET_STRING *os = a;
+    const ASN1_OCTET_STRING *os = a;
     if (pp) {
         memcpy(*pp, os->data, os->length);
         *pp += os->length;
diff --git a/crypto/pem/pem_pk8.c b/crypto/pem/pem_pk8.c
index 8372211..d8bb9bb 100644
--- a/crypto/pem/pem_pk8.c
+++ b/crypto/pem/pem_pk8.c
@@ -16,12 +16,12 @@
 #include <openssl/pkcs12.h>
 #include <openssl/pem.h>
 
-static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder,
+static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder,
                       int nid, const EVP_CIPHER *enc,
                       char *kstr, int klen, pem_password_cb *cb, void *u);
 
 #ifndef OPENSSL_NO_STDIO
-static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder,
+static int do_pk8pkey_fp(FILE *bp, const EVP_PKEY *x, int isder,
                          int nid, const EVP_CIPHER *enc,
                          char *kstr, int klen, pem_password_cb *cb, void *u);
 #endif
@@ -32,35 +32,35 @@ static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder,
  * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0.
  */
 
-int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
+int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, int nid,
                                       char *kstr, int klen,
                                       pem_password_cb *cb, void *u)
 {
     return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
 }
 
-int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+int PEM_write_bio_PKCS8PrivateKey(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc,
                                   char *kstr, int klen,
                                   pem_password_cb *cb, void *u)
 {
     return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
 }
 
-int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+int i2d_PKCS8PrivateKey_bio(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc,
                             char *kstr, int klen,
                             pem_password_cb *cb, void *u)
 {
     return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
 }
 
-int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, const EVP_PKEY *x, int nid,
                                 char *kstr, int klen,
                                 pem_password_cb *cb, void *u)
 {
     return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
 }
 
-static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid,
+static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
                       const EVP_CIPHER *enc, char *kstr, int klen,
                       pem_password_cb *cb, void *u)
 {
@@ -147,34 +147,34 @@ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
 
 #ifndef OPENSSL_NO_STDIO
 
-int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+int i2d_PKCS8PrivateKey_fp(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc,
                            char *kstr, int klen, pem_password_cb *cb, void *u)
 {
     return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
 }
 
-int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
+int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, const EVP_PKEY *x, int nid,
                                char *kstr, int klen,
                                pem_password_cb *cb, void *u)
 {
     return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
 }
 
-int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
+int PEM_write_PKCS8PrivateKey_nid(FILE *fp, const EVP_PKEY *x, int nid,
                                   char *kstr, int klen,
                                   pem_password_cb *cb, void *u)
 {
     return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
 }
 
-int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc,
                               char *kstr, int klen, pem_password_cb *cb,
                               void *u)
 {
     return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
 }
 
-static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid,
+static int do_pk8pkey_fp(FILE *fp, const EVP_PKEY *x, int isder, int nid,
                          const EVP_CIPHER *enc, char *kstr, int klen,
                          pem_password_cb *cb, void *u)
 {
diff --git a/crypto/pkcs12/p12_utl.c b/crypto/pkcs12/p12_utl.c
index 2c315c2..9e792d4 100644
--- a/crypto/pkcs12/p12_utl.c
+++ b/crypto/pkcs12/p12_utl.c
@@ -219,13 +219,13 @@ char *OPENSSL_uni2utf8(const unsigned char *uni, int unilen)
     return asctmp;
 }
 
-int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12)
+int i2d_PKCS12_bio(BIO *bp, const PKCS12 *p12)
 {
     return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
 }
 
 #ifndef OPENSSL_NO_STDIO
-int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12)
+int i2d_PKCS12_fp(FILE *fp, const PKCS12 *p12)
 {
     return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
 }
diff --git a/crypto/pkcs7/pk7_lib.c b/crypto/pkcs7/pk7_lib.c
index 6379e63..181fb5a 100644
--- a/crypto/pkcs7/pk7_lib.c
+++ b/crypto/pkcs7/pk7_lib.c
@@ -544,6 +544,7 @@ int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
     return 1;
 }
 
+/* unfortunately cannot constify BIO_new_NDEF() due to this and CMS_stream() */
 int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
 {
     ASN1_OCTET_STRING *os = NULL;
diff --git a/crypto/rsa/rsa_asn1.c b/crypto/rsa/rsa_asn1.c
index 853d769..ad9d8b3 100644
--- a/crypto/rsa/rsa_asn1.c
+++ b/crypto/rsa/rsa_asn1.c
@@ -106,16 +106,16 @@ ASN1_SEQUENCE_cb(RSA_OAEP_PARAMS, rsa_oaep_cb) = {
 
 IMPLEMENT_ASN1_FUNCTIONS(RSA_OAEP_PARAMS)
 
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(RSA, RSAPrivateKey, RSAPrivateKey)
 
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(RSA, RSAPublicKey, RSAPublicKey)
 
-RSA *RSAPublicKey_dup(RSA *rsa)
+RSA *RSAPublicKey_dup(const RSA *rsa)
 {
     return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa);
 }
 
-RSA *RSAPrivateKey_dup(RSA *rsa)
+RSA *RSAPrivateKey_dup(const RSA *rsa)
 {
     return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa);
 }
diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c
index 3bb500c..2295fa5 100644
--- a/crypto/rsa/rsa_pmeth.c
+++ b/crypto/rsa/rsa_pmeth.c
@@ -70,7 +70,7 @@ static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
     return 1;
 }
 
-static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+static int pkey_rsa_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
 {
     RSA_PKEY_CTX *dctx, *sctx;
 
diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c
index 5ca430f..fecdc28 100644
--- a/crypto/sm2/sm2_pmeth.c
+++ b/crypto/sm2/sm2_pmeth.c
@@ -54,7 +54,7 @@ static void pkey_sm2_cleanup(EVP_PKEY_CTX *ctx)
     }
 }
 
-static int pkey_sm2_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+static int pkey_sm2_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
 {
     SM2_PKEY_CTX *dctx, *sctx;
 
diff --git a/crypto/ts/ts_asn1.c b/crypto/ts/ts_asn1.c
index 5a58841..52ac2aa 100644
--- a/crypto/ts/ts_asn1.c
+++ b/crypto/ts/ts_asn1.c
@@ -17,7 +17,7 @@ ASN1_SEQUENCE(TS_MSG_IMPRINT) = {
         ASN1_SIMPLE(TS_MSG_IMPRINT, hashed_msg, ASN1_OCTET_STRING)
 } static_ASN1_SEQUENCE_END(TS_MSG_IMPRINT)
 
-IMPLEMENT_ASN1_FUNCTIONS_const(TS_MSG_IMPRINT)
+IMPLEMENT_ASN1_FUNCTIONS(TS_MSG_IMPRINT)
 IMPLEMENT_ASN1_DUP_FUNCTION(TS_MSG_IMPRINT)
 TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a)
 {
@@ -25,9 +25,9 @@ TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a)
                            d2i_TS_MSG_IMPRINT, bp, a);
 }
 
-int i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a)
+int i2d_TS_MSG_IMPRINT_bio(BIO *bp, const TS_MSG_IMPRINT *a)
 {
-    return ASN1_i2d_bio_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a);
+    return ASN1_i2d_bio_of(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a);
 }
 #ifndef OPENSSL_NO_STDIO
 TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a)
@@ -36,9 +36,9 @@ TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a)
                           d2i_TS_MSG_IMPRINT, fp, a);
 }
 
-int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a)
+int i2d_TS_MSG_IMPRINT_fp(FILE *fp, const TS_MSG_IMPRINT *a)
 {
-    return ASN1_i2d_fp_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a);
+    return ASN1_i2d_fp_of(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a);
 }
 #endif
 
@@ -51,16 +51,16 @@ ASN1_SEQUENCE(TS_REQ) = {
         ASN1_IMP_SEQUENCE_OF_OPT(TS_REQ, extensions, X509_EXTENSION, 0)
 } static_ASN1_SEQUENCE_END(TS_REQ)
 
-IMPLEMENT_ASN1_FUNCTIONS_const(TS_REQ)
+IMPLEMENT_ASN1_FUNCTIONS(TS_REQ)
 IMPLEMENT_ASN1_DUP_FUNCTION(TS_REQ)
 TS_REQ *d2i_TS_REQ_bio(BIO *bp, TS_REQ **a)
 {
     return ASN1_d2i_bio_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, bp, a);
 }
 
-int i2d_TS_REQ_bio(BIO *bp, TS_REQ *a)
+int i2d_TS_REQ_bio(BIO *bp, const TS_REQ *a)
 {
-    return ASN1_i2d_bio_of_const(TS_REQ, i2d_TS_REQ, bp, a);
+    return ASN1_i2d_bio_of(TS_REQ, i2d_TS_REQ, bp, a);
 }
 #ifndef OPENSSL_NO_STDIO
 TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a)
@@ -68,9 +68,9 @@ TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a)
     return ASN1_d2i_fp_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, fp, a);
 }
 
-int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a)
+int i2d_TS_REQ_fp(FILE *fp, const TS_REQ *a)
 {
-    return ASN1_i2d_fp_of_const(TS_REQ, i2d_TS_REQ, fp, a);
+    return ASN1_i2d_fp_of(TS_REQ, i2d_TS_REQ, fp, a);
 }
 #endif
 
@@ -80,7 +80,7 @@ ASN1_SEQUENCE(TS_ACCURACY) = {
         ASN1_IMP_OPT(TS_ACCURACY, micros, ASN1_INTEGER, 1)
 } static_ASN1_SEQUENCE_END(TS_ACCURACY)
 
-IMPLEMENT_ASN1_FUNCTIONS_const(TS_ACCURACY)
+IMPLEMENT_ASN1_FUNCTIONS(TS_ACCURACY)
 IMPLEMENT_ASN1_DUP_FUNCTION(TS_ACCURACY)
 
 ASN1_SEQUENCE(TS_TST_INFO) = {
@@ -96,7 +96,7 @@ ASN1_SEQUENCE(TS_TST_INFO) = {
         ASN1_IMP_SEQUENCE_OF_OPT(TS_TST_INFO, extensions, X509_EXTENSION, 1)
 } static_ASN1_SEQUENCE_END(TS_TST_INFO)
 
-IMPLEMENT_ASN1_FUNCTIONS_const(TS_TST_INFO)
+IMPLEMENT_ASN1_FUNCTIONS(TS_TST_INFO)
 IMPLEMENT_ASN1_DUP_FUNCTION(TS_TST_INFO)
 TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a)
 {
@@ -104,9 +104,9 @@ TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a)
                            a);
 }
 
-int i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a)
+int i2d_TS_TST_INFO_bio(BIO *bp, const TS_TST_INFO *a)
 {
-    return ASN1_i2d_bio_of_const(TS_TST_INFO, i2d_TS_TST_INFO, bp, a);
+    return ASN1_i2d_bio_of(TS_TST_INFO, i2d_TS_TST_INFO, bp, a);
 }
 #ifndef OPENSSL_NO_STDIO
 TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a)
@@ -115,9 +115,9 @@ TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a)
                           a);
 }
 
-int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a)
+int i2d_TS_TST_INFO_fp(FILE *fp, const TS_TST_INFO *a)
 {
-    return ASN1_i2d_fp_of_const(TS_TST_INFO, i2d_TS_TST_INFO, fp, a);
+    return ASN1_i2d_fp_of(TS_TST_INFO, i2d_TS_TST_INFO, fp, a);
 }
 #endif
 
@@ -127,7 +127,7 @@ ASN1_SEQUENCE(TS_STATUS_INFO) = {
         ASN1_OPT(TS_STATUS_INFO, failure_info, ASN1_BIT_STRING)
 } static_ASN1_SEQUENCE_END(TS_STATUS_INFO)
 
-IMPLEMENT_ASN1_FUNCTIONS_const(TS_STATUS_INFO)
+IMPLEMENT_ASN1_FUNCTIONS(TS_STATUS_INFO)
 IMPLEMENT_ASN1_DUP_FUNCTION(TS_STATUS_INFO)
 
 static int ts_resp_set_tst_info(TS_RESP *a)
@@ -176,7 +176,7 @@ ASN1_SEQUENCE_cb(TS_RESP, ts_resp_cb) = {
         ASN1_OPT(TS_RESP, token, PKCS7),
 } static_ASN1_SEQUENCE_END_cb(TS_RESP, TS_RESP)
 
-IMPLEMENT_ASN1_FUNCTIONS_const(TS_RESP)
+IMPLEMENT_ASN1_FUNCTIONS(TS_RESP)
 
 IMPLEMENT_ASN1_DUP_FUNCTION(TS_RESP)
 
@@ -185,9 +185,9 @@ TS_RESP *d2i_TS_RESP_bio(BIO *bp, TS_RESP **a)
     return ASN1_d2i_bio_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, bp, a);
 }
 
-int i2d_TS_RESP_bio(BIO *bp, TS_RESP *a)
+int i2d_TS_RESP_bio(BIO *bp, const TS_RESP *a)
 {
-    return ASN1_i2d_bio_of_const(TS_RESP, i2d_TS_RESP, bp, a);
+    return ASN1_i2d_bio_of(TS_RESP, i2d_TS_RESP, bp, a);
 }
 #ifndef OPENSSL_NO_STDIO
 TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a)
@@ -195,9 +195,9 @@ TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a)
     return ASN1_d2i_fp_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, fp, a);
 }
 
-int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a)
+int i2d_TS_RESP_fp(FILE *fp, const TS_RESP *a)
 {
-    return ASN1_i2d_fp_of_const(TS_RESP, i2d_TS_RESP, fp, a);
+    return ASN1_i2d_fp_of(TS_RESP, i2d_TS_RESP, fp, a);
 }
 #endif
 
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index 5fb3a59..dca138c 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -112,7 +112,7 @@ X509 *d2i_X509_fp(FILE *fp, X509 **x509)
     return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509);
 }
 
-int i2d_X509_fp(FILE *fp, X509 *x509)
+int i2d_X509_fp(FILE *fp, const X509 *x509)
 {
     return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509);
 }
@@ -123,7 +123,7 @@ X509 *d2i_X509_bio(BIO *bp, X509 **x509)
     return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509);
 }
 
-int i2d_X509_bio(BIO *bp, X509 *x509)
+int i2d_X509_bio(BIO *bp, const X509 *x509)
 {
     return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509);
 }
@@ -134,7 +134,7 @@ X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl)
     return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
 }
 
-int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl)
+int i2d_X509_CRL_fp(FILE *fp, const X509_CRL *crl)
 {
     return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
 }
@@ -145,7 +145,7 @@ X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl)
     return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
 }
 
-int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl)
+int i2d_X509_CRL_bio(BIO *bp, const X509_CRL *crl)
 {
     return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
 }
@@ -156,7 +156,7 @@ PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7)
     return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
 }
 
-int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7)
+int i2d_PKCS7_fp(FILE *fp, const PKCS7 *p7)
 {
     return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
 }
@@ -167,7 +167,7 @@ PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7)
     return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
 }
 
-int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7)
+int i2d_PKCS7_bio(BIO *bp, const PKCS7 *p7)
 {
     return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
 }
@@ -178,7 +178,7 @@ X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req)
     return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
 }
 
-int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req)
+int i2d_X509_REQ_fp(FILE *fp, const X509_REQ *req)
 {
     return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
 }
@@ -189,7 +189,7 @@ X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req)
     return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
 }
 
-int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
+int i2d_X509_REQ_bio(BIO *bp, const X509_REQ *req)
 {
     return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
 }
@@ -202,7 +202,7 @@ RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
     return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
 }
 
-int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa)
+int i2d_RSAPrivateKey_fp(FILE *fp, const RSA *rsa)
 {
     return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
 }
@@ -219,12 +219,12 @@ RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
                        (void **)rsa);
 }
 
-int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
+int i2d_RSAPublicKey_fp(FILE *fp, const RSA *rsa)
 {
     return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
 }
 
-int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
+int i2d_RSA_PUBKEY_fp(FILE *fp, const RSA *rsa)
 {
     return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY, fp, rsa);
 }
@@ -235,7 +235,7 @@ RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
     return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
 }
 
-int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
+int i2d_RSAPrivateKey_bio(BIO *bp, const RSA *rsa)
 {
     return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
 }
@@ -250,12 +250,12 @@ RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
     return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa);
 }
 
-int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
+int i2d_RSAPublicKey_bio(BIO *bp, const RSA *rsa)
 {
     return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
 }
 
-int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
+int i2d_RSA_PUBKEY_bio(BIO *bp, const RSA *rsa)
 {
     return ASN1_i2d_bio_of(RSA, i2d_RSA_PUBKEY, bp, rsa);
 }
@@ -268,9 +268,9 @@ DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa)
     return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSAPrivateKey, fp, dsa);
 }
 
-int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa)
+int i2d_DSAPrivateKey_fp(FILE *fp, const DSA *dsa)
 {
-    return ASN1_i2d_fp_of_const(DSA, i2d_DSAPrivateKey, fp, dsa);
+    return ASN1_i2d_fp_of(DSA, i2d_DSAPrivateKey, fp, dsa);
 }
 
 DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa)
@@ -278,7 +278,7 @@ DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa)
     return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa);
 }
 
-int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa)
+int i2d_DSA_PUBKEY_fp(FILE *fp, const DSA *dsa)
 {
     return ASN1_i2d_fp_of(DSA, i2d_DSA_PUBKEY, fp, dsa);
 }
@@ -289,9 +289,9 @@ DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa)
     return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSAPrivateKey, bp, dsa);
 }
 
-int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa)
+int i2d_DSAPrivateKey_bio(BIO *bp, const DSA *dsa)
 {
-    return ASN1_i2d_bio_of_const(DSA, i2d_DSAPrivateKey, bp, dsa);
+    return ASN1_i2d_bio_of(DSA, i2d_DSAPrivateKey, bp, dsa);
 }
 
 DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa)
@@ -299,7 +299,7 @@ DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa)
     return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa);
 }
 
-int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa)
+int i2d_DSA_PUBKEY_bio(BIO *bp, const DSA *dsa)
 {
     return ASN1_i2d_bio_of(DSA, i2d_DSA_PUBKEY, bp, dsa);
 }
@@ -313,7 +313,7 @@ EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey)
     return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey);
 }
 
-int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey)
+int i2d_EC_PUBKEY_fp(FILE *fp, const EC_KEY *eckey)
 {
     return ASN1_i2d_fp_of(EC_KEY, i2d_EC_PUBKEY, fp, eckey);
 }
@@ -323,7 +323,7 @@ EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey)
     return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey);
 }
 
-int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey)
+int i2d_ECPrivateKey_fp(FILE *fp, const EC_KEY *eckey)
 {
     return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey);
 }
@@ -333,7 +333,7 @@ EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey)
     return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey);
 }
 
-int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa)
+int i2d_EC_PUBKEY_bio(BIO *bp, const EC_KEY *ecdsa)
 {
     return ASN1_i2d_bio_of(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa);
 }
@@ -343,7 +343,7 @@ EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey)
     return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey);
 }
 
-int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey)
+int i2d_ECPrivateKey_bio(BIO *bp, const EC_KEY *eckey)
 {
     return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey);
 }
@@ -415,7 +415,7 @@ X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8)
     return ASN1_d2i_fp_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, fp, p8);
 }
 
-int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8)
+int i2d_PKCS8_fp(FILE *fp, const X509_SIG *p8)
 {
     return ASN1_i2d_fp_of(X509_SIG, i2d_X509_SIG, fp, p8);
 }
@@ -426,7 +426,7 @@ X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8)
     return ASN1_d2i_bio_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, bp, p8);
 }
 
-int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8)
+int i2d_PKCS8_bio(BIO *bp, const X509_SIG *p8)
 {
     return ASN1_i2d_bio_of(X509_SIG, i2d_X509_SIG, bp, p8);
 }
@@ -439,13 +439,13 @@ PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
                           d2i_PKCS8_PRIV_KEY_INFO, fp, p8inf);
 }
 
-int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf)
+int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, const PKCS8_PRIV_KEY_INFO *p8inf)
 {
     return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, fp,
                           p8inf);
 }
 
-int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key)
+int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, const EVP_PKEY *key)
 {
     PKCS8_PRIV_KEY_INFO *p8inf;
     int ret;
@@ -457,7 +457,7 @@ int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key)
     return ret;
 }
 
-int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey)
+int i2d_PrivateKey_fp(FILE *fp, const EVP_PKEY *pkey)
 {
     return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey);
 }
@@ -467,7 +467,7 @@ EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a)
     return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, fp, a);
 }
 
-int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey)
+int i2d_PUBKEY_fp(FILE *fp, const EVP_PKEY *pkey)
 {
     return ASN1_i2d_fp_of(EVP_PKEY, i2d_PUBKEY, fp, pkey);
 }
@@ -486,13 +486,13 @@ PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
                            d2i_PKCS8_PRIV_KEY_INFO, bp, p8inf);
 }
 
-int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf)
+int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, const PKCS8_PRIV_KEY_INFO *p8inf)
 {
     return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, bp,
                            p8inf);
 }
 
-int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
+int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, const EVP_PKEY *key)
 {
     PKCS8_PRIV_KEY_INFO *p8inf;
     int ret;
@@ -504,7 +504,7 @@ int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
     return ret;
 }
 
-int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey)
+int i2d_PrivateKey_bio(BIO *bp, const EVP_PKEY *pkey)
 {
     return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey);
 }
@@ -514,7 +514,7 @@ EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a)
     return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, bp, a);
 }
 
-int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey)
+int i2d_PUBKEY_bio(BIO *bp, const EVP_PKEY *pkey)
 {
     return ASN1_i2d_bio_of(EVP_PKEY, i2d_PUBKEY, bp, pkey);
 }
diff --git a/crypto/x509/x_name.c b/crypto/x509/x_name.c
index 53bbf72..8fd6566 100644
--- a/crypto/x509/x_name.c
+++ b/crypto/x509/x_name.c
@@ -28,7 +28,7 @@ static int x509_name_ex_d2i(ASN1_VALUE **val,
                             const ASN1_ITEM *it,
                             int tag, int aclass, char opt, ASN1_TLC *ctx);
 
-static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
+static int x509_name_ex_i2d(const ASN1_VALUE **val, unsigned char **out,
                             const ASN1_ITEM *it, int tag, int aclass);
 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
 static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
@@ -36,10 +36,10 @@ static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
 static int x509_name_encode(X509_NAME *a);
 static int x509_name_canon(X509_NAME *a);
 static int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in);
-static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname,
+static int i2d_name_canon(const STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname,
                           unsigned char **in);
 
-static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
+static int x509_name_ex_print(BIO *out, const ASN1_VALUE **pval,
                               int indent,
                               const char *fname, const ASN1_PCTX *pctx);
 
@@ -156,6 +156,7 @@ static int x509_name_ex_d2i(ASN1_VALUE **val,
     int i, j, ret;
     STACK_OF(X509_NAME_ENTRY) *entries;
     X509_NAME_ENTRY *entry;
+
     if (len > X509_NAME_MAX)
         len = X509_NAME_MAX;
     q = p;
@@ -207,11 +208,12 @@ static int x509_name_ex_d2i(ASN1_VALUE **val,
     return 0;
 }
 
-static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
+static int x509_name_ex_i2d(const ASN1_VALUE **val, unsigned char **out,
                             const ASN1_ITEM *it, int tag, int aclass)
 {
     int ret;
     X509_NAME *a = (X509_NAME *)*val;
+
     if (a->modified) {
         ret = x509_name_encode(a);
         if (ret < 0)
@@ -232,7 +234,7 @@ static int x509_name_encode(X509_NAME *a)
 {
     union {
         STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
-        ASN1_VALUE *a;
+        const ASN1_VALUE *a;
     } intname = {
         NULL
     };
@@ -241,6 +243,7 @@ static int x509_name_encode(X509_NAME *a)
     STACK_OF(X509_NAME_ENTRY) *entries = NULL;
     X509_NAME_ENTRY *entry;
     int i, set = -1;
+
     intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
     if (!intname.s)
         goto memerr;
@@ -277,7 +280,7 @@ static int x509_name_encode(X509_NAME *a)
     return -1;
 }
 
-static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
+static int x509_name_ex_print(BIO *out, const ASN1_VALUE **pval,
                               int indent,
                               const char *fname, const ASN1_PCTX *pctx)
 {
@@ -460,11 +463,11 @@ static int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in)
 
 }
 
-static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname,
+static int i2d_name_canon(const STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname,
                           unsigned char **in)
 {
     int i, len, ltmp;
-    ASN1_VALUE *v;
+    const ASN1_VALUE *v;
     STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
 
     len = 0;
@@ -479,14 +482,16 @@ static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname,
     return len;
 }
 
-int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
+int X509_NAME_set(X509_NAME **xn, const X509_NAME *name)
 {
+    X509_NAME *name_copy;
+
     if (*xn == name)
         return *xn != NULL;
-    if ((name = X509_NAME_dup(name)) == NULL)
+    if ((name_copy = X509_NAME_dup(name)) == NULL)
         return 0;
     X509_NAME_free(*xn);
-    *xn = name;
+    *xn = name_copy;
     return 1;
 }
 
diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c
index be42684..eb5ea27 100644
--- a/crypto/x509/x_pubkey.c
+++ b/crypto/x509/x_pubkey.c
@@ -57,6 +57,7 @@ ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
 
+/* TODO should better be called X509_PUBKEY_set1 */
 int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
 {
     X509_PUBKEY *pk = NULL;
@@ -67,7 +68,7 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
     if ((pk = X509_PUBKEY_new()) == NULL)
         goto error;
 
-    if (pkey->ameth) {
+    if (pkey != NULL && pkey->ameth) {
         if (pkey->ameth->pub_encode) {
             if (!pkey->ameth->pub_encode(pk, pkey)) {
                 X509err(X509_F_X509_PUBKEY_SET,
@@ -86,8 +87,7 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
     X509_PUBKEY_free(*x);
     *x = pk;
     pk->pkey = pkey;
-    EVP_PKEY_up_ref(pkey);
-    return 1;
+    return EVP_PKEY_up_ref(pkey);
 
  error:
     X509_PUBKEY_free(pk);
@@ -200,15 +200,22 @@ EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
     return pktmp;
 }
 
-int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
+int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp)
 {
     X509_PUBKEY *xpk = NULL;
-    int ret;
-    if (!a)
+    int ret = -1;
+
+    if (a == NULL)
         return 0;
-    if (!X509_PUBKEY_set(&xpk, a))
+    if ((xpk = X509_PUBKEY_new()) == NULL)
         return -1;
+    if (a->ameth != NULL && a->ameth->pub_encode != NULL
+        && !a->ameth->pub_encode(xpk, a))
+        goto error;
+    xpk->pkey = (EVP_PKEY *)a;
     ret = i2d_X509_PUBKEY(xpk, pp);
+    xpk->pkey = NULL;
+ error:
     X509_PUBKEY_free(xpk);
     return ret;
 }
@@ -238,7 +245,7 @@ RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
     return key;
 }
 
-int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
+int i2d_RSA_PUBKEY(const RSA *a, unsigned char **pp)
 {
     EVP_PKEY *pktmp;
     int ret;
@@ -249,8 +256,9 @@ int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
         ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
         return -1;
     }
-    EVP_PKEY_set1_RSA(pktmp, a);
+    (void)EVP_PKEY_assign_RSA(pktmp, (RSA *)a);
     ret = i2d_PUBKEY(pktmp, pp);
+    pktmp->pkey.ptr = NULL;
     EVP_PKEY_free(pktmp);
     return ret;
 }
@@ -278,7 +286,7 @@ DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
     return key;
 }
 
-int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
+int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp)
 {
     EVP_PKEY *pktmp;
     int ret;
@@ -289,8 +297,9 @@ int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
         ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
         return -1;
     }
-    EVP_PKEY_set1_DSA(pktmp, a);
+    (void)EVP_PKEY_assign_DSA(pktmp, (DSA *)a);
     ret = i2d_PUBKEY(pktmp, pp);
+    pktmp->pkey.ptr = NULL;
     EVP_PKEY_free(pktmp);
     return ret;
 }
@@ -318,7 +327,7 @@ EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
     return key;
 }
 
-int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
+int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp)
 {
     EVP_PKEY *pktmp;
     int ret;
@@ -328,8 +337,9 @@ int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
         ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
         return -1;
     }
-    EVP_PKEY_set1_EC_KEY(pktmp, a);
+    (void)EVP_PKEY_assign_EC_KEY(pktmp, (EC_KEY *)a);
     ret = i2d_PUBKEY(pktmp, pp);
+    pktmp->pkey.ptr = NULL;
     EVP_PKEY_free(pktmp);
     return ret;
 }
diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c
index bf0270e..54d015b 100644
--- a/crypto/x509/x_x509.c
+++ b/crypto/x509/x_x509.c
@@ -107,7 +107,6 @@ ASN1_SEQUENCE_ref(X509, x509_cb) = {
 } ASN1_SEQUENCE_END_ref(X509, X509)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509)
-
 IMPLEMENT_ASN1_DUP_FUNCTION(X509)
 
 int X509_set_ex_data(X509 *r, int idx, void *arg)
@@ -163,7 +162,7 @@ X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
  * error path, but that depends on similar hygiene in lower-level functions.
  * Here we avoid compounding the problem.
  */
-static int i2d_x509_aux_internal(X509 *a, unsigned char **pp)
+static int i2d_x509_aux_internal(const X509 *a, unsigned char **pp)
 {
     int length, tmplen;
     unsigned char *start = pp != NULL ? *pp : NULL;
@@ -197,7 +196,7 @@ static int i2d_x509_aux_internal(X509 *a, unsigned char **pp)
  * the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the
  * allocated buffer.
  */
-int i2d_X509_AUX(X509 *a, unsigned char **pp)
+int i2d_X509_AUX(const X509 *a, unsigned char **pp)
 {
     int length;
     unsigned char *tmp;
diff --git a/crypto/x509v3/v3_genn.c b/crypto/x509v3/v3_genn.c
index b52735f..1815d59 100644
--- a/crypto/x509v3/v3_genn.c
+++ b/crypto/x509v3/v3_genn.c
@@ -50,7 +50,7 @@ ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES)
 
 IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
 
-GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a)
+GENERAL_NAME *GENERAL_NAME_dup(const GENERAL_NAME *a)
 {
     return (GENERAL_NAME *)ASN1_dup((i2d_of_void *)i2d_GENERAL_NAME,
                                     (d2i_of_void *)d2i_GENERAL_NAME,
diff --git a/doc/man3/ASN1_STRING_length.pod b/doc/man3/ASN1_STRING_length.pod
index e726083..86eb835 100644
--- a/doc/man3/ASN1_STRING_length.pod
+++ b/doc/man3/ASN1_STRING_length.pod
@@ -14,7 +14,7 @@ ASN1_STRING_to_UTF8 - ASN1_STRING utility functions
  const unsigned char * ASN1_STRING_get0_data(const ASN1_STRING *x);
  unsigned char * ASN1_STRING_data(ASN1_STRING *x);
 
- ASN1_STRING * ASN1_STRING_dup(ASN1_STRING *a);
+ ASN1_STRING * ASN1_STRING_dup(const ASN1_STRING *a);
 
  int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b);
 
diff --git a/doc/man3/EVP_PKEY_CTX_ctrl.pod b/doc/man3/EVP_PKEY_CTX_ctrl.pod
index 5b35156..1bab6d1 100644
--- a/doc/man3/EVP_PKEY_CTX_ctrl.pod
+++ b/doc/man3/EVP_PKEY_CTX_ctrl.pod
@@ -74,7 +74,8 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len
  int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
  int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd);
 
- int EVP_PKEY_CTX_set_mac_key(EVP_PKEY_CTX *ctx, unsigned char *key, int len);
+ int EVP_PKEY_CTX_set_mac_key(EVP_PKEY_CTX *ctx, const unsigned char *key,
+                              int len);
 
  #include <openssl/rsa.h>
 
diff --git a/doc/man3/EVP_PKEY_CTX_new.pod b/doc/man3/EVP_PKEY_CTX_new.pod
index a556289..37f08e7 100644
--- a/doc/man3/EVP_PKEY_CTX_new.pod
+++ b/doc/man3/EVP_PKEY_CTX_new.pod
@@ -10,7 +10,7 @@ EVP_PKEY_CTX_new, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free - pub
 
  EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
  EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
- EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
+ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx);
  void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
 
 =head1 DESCRIPTION
diff --git a/doc/man3/EVP_PKEY_set1_RSA.pod b/doc/man3/EVP_PKEY_set1_RSA.pod
index 868e337..6363162 100644
--- a/doc/man3/EVP_PKEY_set1_RSA.pod
+++ b/doc/man3/EVP_PKEY_set1_RSA.pod
@@ -28,10 +28,10 @@ EVP_PKEY_set1_engine - EVP_PKEY assignment functions
  const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len);
  const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len);
  const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len);
- RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey);
- DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey);
- DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey);
- EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey);
+ RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey);
+ DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey);
+ DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey);
+ EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey);
 
  int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key);
  int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key);
diff --git a/doc/man3/PEM_read_bio_PrivateKey.pod b/doc/man3/PEM_read_bio_PrivateKey.pod
index 54dc27e..a5a63c4 100644
--- a/doc/man3/PEM_read_bio_PrivateKey.pod
+++ b/doc/man3/PEM_read_bio_PrivateKey.pod
@@ -36,7 +36,7 @@ PEM_write_bio_PKCS7, PEM_write_PKCS7 - PEM routines
                                    pem_password_cb *cb, void *u);
  EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x,
                                pem_password_cb *cb, void *u);
- int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+ int PEM_write_bio_PrivateKey(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc,
                               unsigned char *kstr, int klen,
                               pem_password_cb *cb, void *u);
  int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x,
@@ -46,17 +46,16 @@ PEM_write_bio_PKCS7, PEM_write_PKCS7 - PEM routines
  int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
                           unsigned char *kstr, int klen,
                           pem_password_cb *cb, void *u);
-
  int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
                                    char *kstr, int klen,
                                    pem_password_cb *cb, void *u);
  int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
                                char *kstr, int klen,
                                pem_password_cb *cb, void *u);
- int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
+ int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, int nid,
                                        char *kstr, int klen,
                                        pem_password_cb *cb, void *u);
- int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
+ int PEM_write_PKCS8PrivateKey_nid(FILE *fp, const EVP_PKEY *x, int nid,
                                    char *kstr, int klen,
                                    pem_password_cb *cb, void *u);
 
diff --git a/doc/man3/SSL_SESSION_free.pod b/doc/man3/SSL_SESSION_free.pod
index 10fc8e9..74c6ec2 100644
--- a/doc/man3/SSL_SESSION_free.pod
+++ b/doc/man3/SSL_SESSION_free.pod
@@ -12,7 +12,7 @@ SSL_SESSION_free - create, free and manage SSL_SESSION structures
  #include <openssl/ssl.h>
 
  SSL_SESSION *SSL_SESSION_new(void);
- SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src);
+ SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src);
  int SSL_SESSION_up_ref(SSL_SESSION *ses);
  void SSL_SESSION_free(SSL_SESSION *session);
 
diff --git a/doc/man3/SSL_new.pod b/doc/man3/SSL_new.pod
index 9fef643..9ca9941 100644
--- a/doc/man3/SSL_new.pod
+++ b/doc/man3/SSL_new.pod
@@ -26,7 +26,8 @@ structure are freed.
 SSL_up_ref() increments the reference count for an
 existing B<SSL> structure.
 
-SSL_dup() duplicates an existing B<SSL> structure into a new allocated one. All
+SSL_dup() duplicates an existing B<SSL> structure into a new allocated one
+or just increments the reference count if the connection is active. All
 settings are inherited from the original B<SSL> structure. Dynamic data (i.e.
 existing connection details) are not copied, the new B<SSL> is set into an
 initial accept (server) or connect (client) state.
diff --git a/doc/man3/X509_PUBKEY_new.pod b/doc/man3/X509_PUBKEY_new.pod
index 88e08ed..2d65be6 100644
--- a/doc/man3/X509_PUBKEY_new.pod
+++ b/doc/man3/X509_PUBKEY_new.pod
@@ -19,13 +19,13 @@ X509_PUBKEY_get0_param - SubjectPublicKeyInfo public key functions
  EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key);
 
  EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length);
- int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp);
+ int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp);
 
  EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
  EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
 
- int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
- int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
+ int i2d_PUBKEY_fp(const FILE *fp, EVP_PKEY *pkey);
+ int i2d_PUBKEY_bio(BIO *bp, const EVP_PKEY *pkey);
 
  int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
                             int ptype, void *pval,
diff --git a/doc/man3/X509_dup.pod b/doc/man3/X509_dup.pod
index fd5c054..8ad7648 100644
--- a/doc/man3/X509_dup.pod
+++ b/doc/man3/X509_dup.pod
@@ -259,7 +259,7 @@ X509_dup,
 
  extern const ASN1_ITEM TYPE_it;
  TYPE *TYPE_new(void);
- TYPE *TYPE_dup(TYPE *a);
+ TYPE *TYPE_dup(const TYPE *a);
  void TYPE_free(TYPE *a);
  int TYPE_print_ctx(BIO *out, TYPE *a, int indent, const ASN1_PCTX *pctx);
 
@@ -285,7 +285,7 @@ to generate the function bodies.
 TYPE_new() allocates an empty object of the indicated type.
 The object returned must be released by calling TYPE_free().
 
-TYPE_dup() copies an existing object.
+TYPE_dup() copies an existing object, leaving it untouched.
 
 TYPE_free() releases the object and all pointers and sub-objects
 within it.
diff --git a/doc/man3/d2i_PKCS8PrivateKey_bio.pod b/doc/man3/d2i_PKCS8PrivateKey_bio.pod
index 68da982..5b5371b 100644
--- a/doc/man3/d2i_PKCS8PrivateKey_bio.pod
+++ b/doc/man3/d2i_PKCS8PrivateKey_bio.pod
@@ -13,19 +13,19 @@ i2d_PKCS8PrivateKey_nid_bio, i2d_PKCS8PrivateKey_nid_fp - PKCS#8 format private
  EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u);
  EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u);
 
- int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+ int i2d_PKCS8PrivateKey_bio(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc,
                              char *kstr, int klen,
                              pem_password_cb *cb, void *u);
 
- int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+ int i2d_PKCS8PrivateKey_fp(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc,
                             char *kstr, int klen,
                             pem_password_cb *cb, void *u);
 
- int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+ int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, const EVP_PKEY *x, int nid,
                                  char *kstr, int klen,
                                  pem_password_cb *cb, void *u);
 
- int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
+ int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, const EVP_PKEY *x, int nid,
                                 char *kstr, int klen,
                                 pem_password_cb *cb, void *u);
 
diff --git a/doc/man3/d2i_PrivateKey.pod b/doc/man3/d2i_PrivateKey.pod
index eab98b3..0bce594 100644
--- a/doc/man3/d2i_PrivateKey.pod
+++ b/doc/man3/d2i_PrivateKey.pod
@@ -17,8 +17,8 @@ d2i_PrivateKey_bio, d2i_PrivateKey_fp
                          long length);
  EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
                               long length);
- int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp);
- int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp);
+ int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp);
+ int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp);
 
  EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
  EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a)
diff --git a/doc/man3/d2i_X509.pod b/doc/man3/d2i_X509.pod
index 23dc73c..cad7877 100644
--- a/doc/man3/d2i_X509.pod
+++ b/doc/man3/d2i_X509.pod
@@ -368,8 +368,11 @@ i2d_X509_VAL,
  TYPE *d2i_TYPE_bio(BIO *bp, TYPE **a);
  TYPE *d2i_TYPE_fp(FILE *fp, TYPE **a);
 
+ int i2d_TYPE(const TYPE *a, unsigned char **ppout);
  int i2d_TYPE(TYPE *a, unsigned char **ppout);
+ int i2d_TYPE_fp(FILE *fp, const TYPE *a);
  int i2d_TYPE_fp(FILE *fp, TYPE *a);
+ int i2d_TYPE_bio(BIO *bp, const TYPE *a);
  int i2d_TYPE_bio(BIO *bp, TYPE *a);
 
 =head1 DESCRIPTION
diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h
index 5a635ad..3790c6b 100644
--- a/include/openssl/asn1.h
+++ b/include/openssl/asn1.h
@@ -221,43 +221,41 @@ typedef struct ASN1_VALUE_st ASN1_VALUE;
 
 # define DECLARE_ASN1_FUNCTIONS_name(type, name) \
         DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
-        DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name)
-
-# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \
-        DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
-        DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)
+        DECLARE_ASN1_ENCODE_FUNCTIONS_name(type, name)
 
 # define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \
-        type *d2i_##name(type **a, const unsigned char **in, long len); \
-        int i2d_##name(type *a, unsigned char **out); \
+        DECLARE_ASN1_ENCODE_FUNCTIONS_only(type, name) \
         DECLARE_ASN1_ITEM(itname)
 
-# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \
+# define DECLARE_ASN1_ENCODE_FUNCTIONS_name(type, name) \
+         DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name)
+
+# define DECLARE_ASN1_ENCODE_FUNCTIONS_only(type, name) \
         type *d2i_##name(type **a, const unsigned char **in, long len); \
-        int i2d_##name(const type *a, unsigned char **out); \
-        DECLARE_ASN1_ITEM(name)
+        int i2d_##name(const type *a, unsigned char **out);
 
 # define DECLARE_ASN1_NDEF_FUNCTION(name) \
-        int i2d_##name##_NDEF(name *a, unsigned char **out);
-
-# define DECLARE_ASN1_FUNCTIONS_const(name) \
-        DECLARE_ASN1_ALLOC_FUNCTIONS(name) \
-        DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name)
+        int i2d_##name##_NDEF(const name *a, unsigned char **out);
 
 # define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
         type *name##_new(void); \
         void name##_free(type *a);
 
+# define DECLARE_ASN1_DUP_FUNCTION(type) \
+        DECLARE_ASN1_DUP_FUNCTION_name(type, type)
+
+# define DECLARE_ASN1_DUP_FUNCTION_name(type, name) \
+        type *name##_dup(const type *a);
+
 # define DECLARE_ASN1_PRINT_FUNCTION(stname) \
         DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname)
 
 # define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \
-        int fname##_print_ctx(BIO *out, stname *x, int indent, \
+        int fname##_print_ctx(BIO *out, const stname *x, int indent, \
                                          const ASN1_PCTX *pctx);
 
 # define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
-# define I2D_OF(type) int (*)(type *,unsigned char **)
-# define I2D_OF_const(type) int (*)(const type *,unsigned char **)
+# define I2D_OF(type) int (*)(const type *,unsigned char **)
 
 # define CHECKED_D2I_OF(type, d2i) \
     ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0)))
@@ -271,7 +269,7 @@ typedef struct ASN1_VALUE_st ASN1_VALUE;
     ((void**) (1 ? p : (type**)0))
 
 # define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
-# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
+# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(const type *,unsigned char **)
 # define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type)
 
 TYPEDEF_D2I2D_OF(void);
@@ -476,8 +474,8 @@ DEFINE_STACK_OF(ASN1_TYPE)
 
 typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY;
 
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_name(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_name(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)
 
 /* This is used to contain a list of bit names */
 typedef struct BIT_STRING_BITNAME_st {
@@ -515,7 +513,8 @@ typedef struct BIT_STRING_BITNAME_st {
                         B_ASN1_BMPSTRING|\
                         B_ASN1_UTF8STRING
 
-DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
+DECLARE_ASN1_ALLOC_FUNCTIONS_name(ASN1_TYPE, ASN1_TYPE)
+DECLARE_ASN1_ENCODE_FUNCTIONS(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
 
 int ASN1_TYPE_get(const ASN1_TYPE *a);
 void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
@@ -525,21 +524,14 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
 ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t);
 void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t);
 
-ASN1_OBJECT *ASN1_OBJECT_new(void);
-void ASN1_OBJECT_free(ASN1_OBJECT *a);
-int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp);
-ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
-                             long length);
-
-DECLARE_ASN1_ITEM(ASN1_OBJECT)
-
+DECLARE_ASN1_FUNCTIONS(ASN1_OBJECT)
 DEFINE_STACK_OF(ASN1_OBJECT)
 
 ASN1_STRING *ASN1_STRING_new(void);
 void ASN1_STRING_free(ASN1_STRING *a);
 void ASN1_STRING_clear_free(ASN1_STRING *a);
 int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
-ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a);
+DECLARE_ASN1_DUP_FUNCTION(ASN1_STRING)
 ASN1_STRING *ASN1_STRING_type_new(int type);
 int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
   /*
@@ -570,7 +562,7 @@ int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value,
 DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
 ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
                                 long length);
-ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x);
+DECLARE_ASN1_DUP_FUNCTION(ASN1_INTEGER)
 int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
@@ -594,7 +586,7 @@ int ASN1_TIME_diff(int *pday, int *psec,
                    const ASN1_TIME *from, const ASN1_TIME *to);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
-ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
+DECLARE_ASN1_DUP_FUNCTION(ASN1_OCTET_STRING)
 int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
                           const ASN1_OCTET_STRING *b);
 int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data,
@@ -685,19 +677,14 @@ int ASN1_put_eoc(unsigned char **pp);
 int ASN1_object_size(int constructed, int length, int tag);
 
 /* Used to implement other functions */
-void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, const void *x);
 
 # define ASN1_dup_of(type,i2d,d2i,x) \
     ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
                      CHECKED_D2I_OF(type, d2i), \
-                     CHECKED_PTR_OF(type, x)))
-
-# define ASN1_dup_of_const(type,i2d,d2i,x) \
-    ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
-                     CHECKED_D2I_OF(type, d2i), \
                      CHECKED_PTR_OF(const type, x)))
 
-void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
+void *ASN1_item_dup(const ASN1_ITEM *it, const void *x);
 
 /* ASN1 alloc/free macros for when a type is only used internally */
 
@@ -715,19 +702,14 @@ void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x);
                         CHECKED_PPTR_OF(type, x)))
 
 void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
-int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x);
+int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, const void *x);
 
 #  define ASN1_i2d_fp_of(type,i2d,out,x) \
     (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \
                  out, \
-                 CHECKED_PTR_OF(type, x)))
-
-#  define ASN1_i2d_fp_of_const(type,i2d,out,x) \
-    (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \
-                 out, \
                  CHECKED_PTR_OF(const type, x)))
 
-int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, const void *x);
 int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, unsigned long flags);
 # endif
 
@@ -742,19 +724,14 @@ void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x);
                           CHECKED_PPTR_OF(type, x)))
 
 void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
-int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x);
+int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, const void *x);
 
 #  define ASN1_i2d_bio_of(type,i2d,out,x) \
     (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
                   out, \
-                  CHECKED_PTR_OF(type, x)))
-
-#  define ASN1_i2d_bio_of_const(type,i2d,out,x) \
-    (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \
-                  out, \
                   CHECKED_PTR_OF(const type, x)))
 
-int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, const void *x);
 int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
 int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
 int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
@@ -807,8 +784,8 @@ ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
 void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
 ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in,
                           long len, const ASN1_ITEM *it);
-int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
-int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
+int ASN1_item_i2d(const ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+int ASN1_item_ndef_i2d(const ASN1_VALUE *val, unsigned char **out,
                        const ASN1_ITEM *it);
 
 void ASN1_add_oid_module(void);
@@ -839,7 +816,7 @@ int ASN1_str2mask(const char *str, unsigned long *pmask);
 /* Don't show structure name even at top level */
 # define ASN1_PCTX_FLAGS_NO_STRUCT_NAME          0x100
 
-int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+int ASN1_item_print(BIO *out, const ASN1_VALUE *ifld, int indent,
                     const ASN1_ITEM *it, const ASN1_PCTX *pctx);
 ASN1_PCTX *ASN1_PCTX_new(void);
 void ASN1_PCTX_free(ASN1_PCTX *p);
@@ -864,12 +841,14 @@ void *ASN1_SCTX_get_app_data(ASN1_SCTX *p);
 
 const BIO_METHOD *BIO_f_asn1(void);
 
+/* cannot constify val because of CMS_stream() */
 BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);
 
 int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
                         const ASN1_ITEM *it);
 int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
                               const char *hdr, const ASN1_ITEM *it);
+/* cannot constify val because of CMS_dataFinal() */
 int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
                      int ctype_nid, int econt_nid,
                      STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it);
@@ -880,6 +859,18 @@ int SMIME_text(BIO *in, BIO *out);
 const ASN1_ITEM *ASN1_ITEM_lookup(const char *name);
 const ASN1_ITEM *ASN1_ITEM_get(size_t i);
 
+/* Legacy compatibility */
+# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \
+         DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+         DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)
+# define DECLARE_ASN1_FUNCTIONS_const(type) DECLARE_ASN1_FUNCTIONS(type)
+# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \
+         DECLARE_ASN1_ENCODE_FUNCTIONS(type, name)
+# define I2D_OF_const(type) I2D_OF(type)
+# define ASN1_dup_of_const(type,i2d,d2i,x) ASN1_dup_of(type,i2d,d2i,x)
+# define ASN1_i2d_fp_of_const(type,i2d,out,x) ASN1_i2d_fp_of(type,i2d,out,x)
+# define ASN1_i2d_bio_of_const(type,i2d,out,x) ASN1_i2d_bio_of(type,i2d,out,x)
+
 # ifdef  __cplusplus
 }
 # endif
diff --git a/include/openssl/asn1t.h b/include/openssl/asn1t.h
index 06d85e4..1a836c9 100644
--- a/include/openssl/asn1t.h
+++ b/include/openssl/asn1t.h
@@ -152,19 +152,29 @@ extern "C" {
         ASN1_SEQUENCE_cb(tname, cb)
 
 # define ASN1_SEQUENCE_cb(tname, cb) \
-        static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+        static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0, NULL}; \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_SEQUENCE_const_cb(tname, const_cb) \
+        static const ASN1_AUX tname##_aux = \
+            {NULL, ASN1_AFLG_CONST_CB, 0, 0, NULL, 0, const_cb}; \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_SEQUENCE_cb_const_cb(tname, cb, const_cb) \
+        static const ASN1_AUX tname##_aux = \
+            {NULL, ASN1_AFLG_CONST_CB, 0, 0, cb, 0, const_cb}; \
         ASN1_SEQUENCE(tname)
 
 # define ASN1_BROKEN_SEQUENCE(tname) \
-        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
+        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, NULL, 0, NULL}; \
         ASN1_SEQUENCE(tname)
 
 # define ASN1_SEQUENCE_ref(tname, cb) \
-        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), offsetof(tname, lock), cb, 0}; \
+        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), offsetof(tname, lock), cb, 0, NULL}; \
         ASN1_SEQUENCE(tname)
 
 # define ASN1_SEQUENCE_enc(tname, enc, cb) \
-        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
+        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc), NULL}; \
         ASN1_SEQUENCE(tname)
 
 # define ASN1_NDEF_SEQUENCE_END(tname) \
@@ -261,7 +271,7 @@ extern "C" {
         static const ASN1_TEMPLATE tname##_ch_tt[]
 
 # define ASN1_CHOICE_cb(tname, cb) \
-        static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+        static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0, NULL}; \
         ASN1_CHOICE(tname)
 
 # define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
@@ -661,21 +671,21 @@ typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
                         const ASN1_ITEM *it, int tag, int aclass, char opt,
                         ASN1_TLC *ctx);
 
-typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+typedef int ASN1_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
                         const ASN1_ITEM *it, int tag, int aclass);
 typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
 typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
 
-typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval,
+typedef int ASN1_ex_print_func(BIO *out, const ASN1_VALUE **pval,
                                int indent, const char *fname,
                                const ASN1_PCTX *pctx);
 
-typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont,
+typedef int ASN1_primitive_i2c(const ASN1_VALUE **pval, unsigned char *cont,
                                int *putype, const ASN1_ITEM *it);
 typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont,
                                int len, int utype, char *free_cont,
                                const ASN1_ITEM *it);
-typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval,
+typedef int ASN1_primitive_print(BIO *out, const ASN1_VALUE **pval,
                                  const ASN1_ITEM *it, int indent,
                                  const ASN1_PCTX *pctx);
 
@@ -711,10 +721,16 @@ typedef struct ASN1_PRIMITIVE_FUNCS_st {
  * error has occurred and the main operation should be abandoned. If major
  * changes in the default behaviour are required then an external type is
  * more appropriate.
+ * For the operations ASN1_OP_I2D_PRE, ASN1_OP_I2D_POST, ASN1_OP_PRINT_PRE, and
+ * ASN1_OP_PRINT_POST, meanwhile a variant of the callback with const parameter
+ * 'in' is provided to make clear statically that its input is not modified. If
+ * and only if this variant is in use the flag ASN1_AFLG_CONST_CB must be set.
  */
 
 typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
                         void *exarg);
+typedef int ASN1_aux_const_cb(int operation, const ASN1_VALUE **in,
+                              const ASN1_ITEM *it, void *exarg);
 
 typedef struct ASN1_AUX_st {
     void *app_data;
@@ -723,6 +739,7 @@ typedef struct ASN1_AUX_st {
     int ref_lock;               /* Lock type to use */
     ASN1_aux_cb *asn1_cb;
     int enc_offset;             /* Offset of ASN1_ENCODING structure */
+    ASN1_aux_const_cb *asn1_const_cb; /* for ASN1_OP_I2D_ and ASN1_OP_PRINT_ */
 } ASN1_AUX;
 
 /* For print related callbacks exarg points to this structure */
@@ -750,6 +767,8 @@ typedef struct ASN1_STREAM_ARG_st {
 # define ASN1_AFLG_ENCODING      2
 /* The Sequence length is invalid */
 # define ASN1_AFLG_BROKEN        4
+/* Use the new asn1_const_cb */
+# define ASN1_AFLG_CONST_CB      8
 
 /* operation values for asn1_cb */
 
@@ -836,13 +855,13 @@ typedef struct ASN1_STREAM_ARG_st {
         { \
                 return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
         } \
-        int i2d_##fname(stname *a, unsigned char **out) \
+        int i2d_##fname(const stname *a, unsigned char **out) \
         { \
                 return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
         }
 
 # define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
-        int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
+        int i2d_##stname##_NDEF(const stname *a, unsigned char **out) \
         { \
                 return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
         }
@@ -854,28 +873,14 @@ typedef struct ASN1_STREAM_ARG_st {
                 return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, \
                                                ASN1_ITEM_rptr(stname)); \
         } \
-        static int i2d_##stname(stname *a, unsigned char **out) \
+        static int i2d_##stname(const stname *a, unsigned char **out) \
         { \
                 return ASN1_item_i2d((ASN1_VALUE *)a, out, \
                                      ASN1_ITEM_rptr(stname)); \
         }
 
-/*
- * This includes evil casts to remove const: they will go away when full ASN1
- * constification is done.
- */
-# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
-        stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
-        { \
-                return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
-        } \
-        int i2d_##fname(const stname *a, unsigned char **out) \
-        { \
-                return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
-        }
-
 # define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
-        stname * stname##_dup(stname *x) \
+        stname * stname##_dup(const stname *x) \
         { \
         return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
         }
@@ -884,20 +889,13 @@ typedef struct ASN1_STREAM_ARG_st {
         IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)
 
 # define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
-        int fname##_print_ctx(BIO *out, stname *x, int indent, \
+        int fname##_print_ctx(BIO *out, const stname *x, int indent, \
                                                 const ASN1_PCTX *pctx) \
         { \
                 return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
                         ASN1_ITEM_rptr(itname), pctx); \
         }
 
-# define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
-                IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
-
-# define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
-        IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
-        IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
-
 /* external definitions for primitive types */
 
 DECLARE_ASN1_ITEM(ASN1_BOOLEAN)
@@ -936,9 +934,14 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
                      const ASN1_ITEM *it, int tag, int aclass, char opt,
                      ASN1_TLC *ctx);
 
-int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
                      const ASN1_ITEM *it, int tag, int aclass);
 
+/* Legacy compatibility */
+# define IMPLEMENT_ASN1_FUNCTIONS_const(name) IMPLEMENT_ASN1_FUNCTIONS(name)
+# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+         IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname)
+
 #ifdef  __cplusplus
 }
 #endif
diff --git a/include/openssl/cms.h b/include/openssl/cms.h
index 4838954..e8653d7 100644
--- a/include/openssl/cms.h
+++ b/include/openssl/cms.h
@@ -199,7 +199,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
                                                const EVP_CIPHER *kekciph);
 
 int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
-int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+int CMS_RecipientInfo_encrypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
 
 int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
                    unsigned int flags);
diff --git a/include/openssl/dh.h b/include/openssl/dh.h
index bfe82b3..18858eb 100644
--- a/include/openssl/dh.h
+++ b/include/openssl/dh.h
@@ -98,7 +98,7 @@ DECLARE_ASN1_ITEM(DHparams)
 # define d2i_DHparams_bio(bp,x) \
     ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, bp, x)
 # define i2d_DHparams_bio(bp,x) \
-    ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)
+    ASN1_i2d_bio_of(DH,i2d_DHparams,bp,x)
 
 # define d2i_DHxparams_fp(fp,x) \
     (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
@@ -110,9 +110,9 @@ DECLARE_ASN1_ITEM(DHparams)
 # define d2i_DHxparams_bio(bp,x) \
     ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, bp, x)
 # define i2d_DHxparams_bio(bp,x) \
-    ASN1_i2d_bio_of_const(DH, i2d_DHxparams, bp, x)
+    ASN1_i2d_bio_of(DH, i2d_DHxparams, bp, x)
 
-DH *DHparams_dup(DH *);
+DECLARE_ASN1_DUP_FUNCTION_name(DH, DHparams)
 
 const DH_METHOD *DH_OpenSSL(void);
 
@@ -151,10 +151,8 @@ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes);
 int DH_generate_key(DH *dh);
 int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
 int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh);
-DH *d2i_DHparams(DH **a, const unsigned char **pp, long length);
-int i2d_DHparams(const DH *a, unsigned char **pp);
-DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length);
-int i2d_DHxparams(const DH *a, unsigned char **pp);
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(DH, DHparams)
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(DH, DHxparams)
 # ifndef OPENSSL_NO_STDIO
 int DHparams_print_fp(FILE *fp, const DH *x);
 # endif
diff --git a/include/openssl/dsa.h b/include/openssl/dsa.h
index ea01aaf..38ae977 100644
--- a/include/openssl/dsa.h
+++ b/include/openssl/dsa.h
@@ -17,6 +17,7 @@
 extern "C" {
 # endif
 # include <openssl/e_os2.h>
+# include <openssl/asn1.h>
 # include <openssl/bio.h>
 # include <openssl/crypto.h>
 # include <openssl/ossl_typ.h>
@@ -69,13 +70,12 @@ typedef struct DSA_SIG_st DSA_SIG;
 # define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \
                 (unsigned char *)(x))
 # define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x)
-# define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x)
+# define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of(DSA,i2d_DSAparams,bp,x)
 
-DSA *DSAparams_dup(DSA *x);
+DECLARE_ASN1_DUP_FUNCTION_name(DSA, DSAparams)
 DSA_SIG *DSA_SIG_new(void);
 void DSA_SIG_free(DSA_SIG *a);
-int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
-DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length);
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(DSA_SIG, DSA_SIG)
 void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
 int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s);
 
@@ -109,9 +109,9 @@ int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
 int DSA_set_ex_data(DSA *d, int idx, void *arg);
 void *DSA_get_ex_data(DSA *d, int idx);
 
-DSA *d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length);
-DSA *d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length);
-DSA *d2i_DSAparams(DSA **a, const unsigned char **pp, long length);
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(DSA, DSAPublicKey)
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(DSA, DSAPrivateKey)
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(DSA, DSAparams)
 
 /* Deprecated version */
 DEPRECATEDIN_0_9_8(DSA *DSA_generate_parameters(int bits,
@@ -130,9 +130,6 @@ int DSA_generate_parameters_ex(DSA *dsa, int bits,
                                BN_GENCB *cb);
 
 int DSA_generate_key(DSA *a);
-int i2d_DSAPublicKey(const DSA *a, unsigned char **pp);
-int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
-int i2d_DSAparams(const DSA *a, unsigned char **pp);
 
 int DSAparams_print(BIO *bp, const DSA *x);
 int DSA_print(BIO *bp, const DSA *x, int off);
diff --git a/include/openssl/ec.h b/include/openssl/ec.h
index 7c15368..8d4d1b1 100644
--- a/include/openssl/ec.h
+++ b/include/openssl/ec.h
@@ -123,7 +123,7 @@ void EC_GROUP_clear_free(EC_GROUP *group);
  */
 int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src);
 
-/** Creates a new EC_GROUP object and copies the copies the content
+/** Creates a new EC_GROUP object and copies the content
  *  form src to the newly created EC_KEY object
  *  \param  src  source EC_GROUP object
  *  \return newly created EC_GROUP object or NULL in case of an error.
@@ -800,7 +800,7 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
 int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
 
 # define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
-# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
+# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of(EC_GROUP,i2d_ECPKParameters,bp,x)
 # define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
                 (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
 # define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
@@ -1028,7 +1028,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);
  *               of bytes needed).
  *  \return 1 on success and 0 if an error occurred.
  */
-int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);
+int i2d_ECPrivateKey(const EC_KEY *key, unsigned char **out);
 
 /********************************************************************/
 /*        de- and encoding functions for EC parameters              */
@@ -1049,7 +1049,7 @@ EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);
  *               of bytes needed).
  *  \return 1 on success and 0 if an error occurred.
  */
-int i2d_ECParameters(EC_KEY *key, unsigned char **out);
+int i2d_ECParameters(const EC_KEY *key, unsigned char **out);
 
 /********************************************************************/
 /*         de- and encoding functions for EC public key             */
@@ -1140,22 +1140,21 @@ ECDSA_SIG *ECDSA_SIG_new(void);
  */
 void ECDSA_SIG_free(ECDSA_SIG *sig);
 
-/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
+/** i2d_ECDSA_SIG encodes content of ECDSA_SIG (note: this function modifies *pp
  *  (*pp += length of the DER encoded signature)).
  *  \param  sig  pointer to the ECDSA_SIG object
  *  \param  pp   pointer to a unsigned char pointer for the output or NULL
  *  \return the length of the DER encoded ECDSA_SIG object or 0
  */
-int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(ECDSA_SIG, ECDSA_SIG)
 
-/** Decodes a DER encoded ECDSA signature (note: this function changes *pp
+/** d2i_ECDSA_SIG decodes an ECDSA signature (note: this function modifies *pp
  *  (*pp += len)).
  *  \param  sig  pointer to ECDSA_SIG pointer (may be NULL)
  *  \param  pp   memory buffer with the DER encoded signature
  *  \param  len  length of the buffer
  *  \return pointer to the decoded ECDSA_SIG structure (or NULL)
  */
-ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len);
 
 /** Accessor for r and s fields of ECDSA_SIG
  *  \param  sig  pointer to ECDSA_SIG structure
diff --git a/include/openssl/ess.h b/include/openssl/ess.h
index 3912071..fb5e45c 100644
--- a/include/openssl/ess.h
+++ b/include/openssl/ess.h
@@ -30,45 +30,28 @@ typedef struct ESS_cert_id_v2_st ESS_CERT_ID_V2;
 
 DEFINE_STACK_OF(ESS_CERT_ID_V2)
 
-ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void);
-void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a);
-int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, unsigned char **pp);
-ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a,
-                                         const unsigned char **pp,
-                                         long length);
-ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a);
+DECLARE_ASN1_ALLOC_FUNCTIONS(ESS_ISSUER_SERIAL)
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(ESS_ISSUER_SERIAL, ESS_ISSUER_SERIAL)
+DECLARE_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL)
 
-ESS_CERT_ID *ESS_CERT_ID_new(void);
-void ESS_CERT_ID_free(ESS_CERT_ID *a);
-int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp);
-ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp,
-                             long length);
-ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a);
+DECLARE_ASN1_ALLOC_FUNCTIONS(ESS_CERT_ID)
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(ESS_CERT_ID, ESS_CERT_ID)
+DECLARE_ASN1_DUP_FUNCTION(ESS_CERT_ID)
 
-ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void);
-void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a);
-int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, unsigned char **pp);
-ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a,
-                                       const unsigned char **pp, long length);
-ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a);
+DECLARE_ASN1_ALLOC_FUNCTIONS(ESS_SIGNING_CERT)
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(ESS_SIGNING_CERT, ESS_SIGNING_CERT)
+DECLARE_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT)
 ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert,
                                             STACK_OF(X509) *certs,
                                             int issuer_needed);
 
-ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new(void);
-void ESS_CERT_ID_V2_free(ESS_CERT_ID_V2 *a);
-int i2d_ESS_CERT_ID_V2(const ESS_CERT_ID_V2 *a, unsigned char **pp);
-ESS_CERT_ID_V2 *d2i_ESS_CERT_ID_V2(ESS_CERT_ID_V2 **a,
-                                   const unsigned char **pp, long length);
-ESS_CERT_ID_V2 *ESS_CERT_ID_V2_dup(ESS_CERT_ID_V2 *a);
+DECLARE_ASN1_ALLOC_FUNCTIONS(ESS_CERT_ID_V2)
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(ESS_CERT_ID_V2, ESS_CERT_ID_V2)
+DECLARE_ASN1_DUP_FUNCTION(ESS_CERT_ID_V2)
 
-ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_new(void);
-void ESS_SIGNING_CERT_V2_free(ESS_SIGNING_CERT_V2 *a);
-int i2d_ESS_SIGNING_CERT_V2(const ESS_SIGNING_CERT_V2 *a, unsigned char **pp);
-ESS_SIGNING_CERT_V2 *d2i_ESS_SIGNING_CERT_V2(ESS_SIGNING_CERT_V2 **a,
-                                             const unsigned char **pp,
-                                             long length);
-ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_dup(ESS_SIGNING_CERT_V2 *a);
+DECLARE_ASN1_ALLOC_FUNCTIONS(ESS_SIGNING_CERT_V2)
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(ESS_SIGNING_CERT_V2, ESS_SIGNING_CERT_V2)
+DECLARE_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT_V2)
 ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_new_init(const EVP_MD *hash_alg,
                                                   X509 *signcert,
                                                   STACK_OF(X509) *certs,
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 23f07ea..72060e7 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -410,31 +410,30 @@ typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass,
 
 # ifndef OPENSSL_NO_RSA
 #  define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
-                                        (char *)(rsa))
+                                        (rsa))
 # endif
 
 # ifndef OPENSSL_NO_DSA
 #  define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
-                                        (char *)(dsa))
+                                        (dsa))
 # endif
 
 # ifndef OPENSSL_NO_DH
-#  define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\
-                                        (char *)(dh))
+#  define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,(dh))
 # endif
 
 # ifndef OPENSSL_NO_EC
 #  define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\
-                                        (char *)(eckey))
+                                        (eckey))
 # endif
 # ifndef OPENSSL_NO_SIPHASH
-#  define EVP_PKEY_assign_SIPHASH(pkey,shkey) EVP_PKEY_assign((pkey),EVP_PKEY_SIPHASH,\
-                                        (char *)(shkey))
+#  define EVP_PKEY_assign_SIPHASH(pkey,shkey) EVP_PKEY_assign((pkey),\
+                                        EVP_PKEY_SIPHASH,(shkey))
 # endif
 
 # ifndef OPENSSL_NO_POLY1305
-#  define EVP_PKEY_assign_POLY1305(pkey,polykey) EVP_PKEY_assign((pkey),EVP_PKEY_POLY1305,\
-                                        (char *)(polykey))
+#  define EVP_PKEY_assign_POLY1305(pkey,polykey) EVP_PKEY_assign((pkey),\
+                                        EVP_PKEY_POLY1305,(polykey))
 # endif
 
 /* Add some extra combinations */
@@ -513,16 +512,13 @@ void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data);
 # ifdef CONST_STRICT
 void BIO_set_md(BIO *, const EVP_MD *md);
 # else
-#  define BIO_set_md(b,md)          BIO_ctrl(b,BIO_C_SET_MD,0,(char *)(md))
+#  define BIO_set_md(b,md)          BIO_ctrl(b,BIO_C_SET_MD,0,(void *)(md))
 # endif
-# define BIO_get_md(b,mdp)          BIO_ctrl(b,BIO_C_GET_MD,0,(char *)(mdp))
-# define BIO_get_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_GET_MD_CTX,0, \
-                                             (char *)(mdcp))
-# define BIO_set_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_SET_MD_CTX,0, \
-                                             (char *)(mdcp))
+# define BIO_get_md(b,mdp)          BIO_ctrl(b,BIO_C_GET_MD,0,(mdp))
+# define BIO_get_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(mdcp))
+# define BIO_set_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(mdcp))
 # define BIO_get_cipher_status(b)   BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL)
-# define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0, \
-                                             (char *)(c_pp))
+# define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(c_pp))
 
 /*__owur*/ int EVP_Cipher(EVP_CIPHER_CTX *c,
                           unsigned char *out,
@@ -660,7 +656,7 @@ __owur int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
 
 EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void);
 void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx);
-int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, EVP_ENCODE_CTX *sctx);
+int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, const EVP_ENCODE_CTX *sctx);
 int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx);
 void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
 int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
@@ -1006,7 +1002,7 @@ void EVP_MD_do_all_sorted(void (*fn)
 EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac);
 EVP_MAC_CTX *EVP_MAC_CTX_new_id(int nid);
 void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx);
-int EVP_MAC_CTX_copy(EVP_MAC_CTX *dest, EVP_MAC_CTX *src);
+int EVP_MAC_CTX_copy(EVP_MAC_CTX *dest, const EVP_MAC_CTX *src);
 const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx);
 size_t EVP_MAC_size(EVP_MAC_CTX *ctx);
 int EVP_MAC_init(EVP_MAC_CTX *ctx);
@@ -1073,25 +1069,25 @@ const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len);
 # ifndef OPENSSL_NO_RSA
 struct rsa_st;
 int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key);
-struct rsa_st *EVP_PKEY_get0_RSA(EVP_PKEY *pkey);
+struct rsa_st *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey);
 struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
 # endif
 # ifndef OPENSSL_NO_DSA
 struct dsa_st;
 int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key);
-struct dsa_st *EVP_PKEY_get0_DSA(EVP_PKEY *pkey);
+struct dsa_st *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey);
 struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
 # endif
 # ifndef OPENSSL_NO_DH
 struct dh_st;
 int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key);
-struct dh_st *EVP_PKEY_get0_DH(EVP_PKEY *pkey);
+struct dh_st *EVP_PKEY_get0_DH(const EVP_PKEY *pkey);
 struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
 # endif
 # ifndef OPENSSL_NO_EC
 struct ec_key_st;
 int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key);
-struct ec_key_st *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey);
+struct ec_key_st *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey);
 struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
 # endif
 
@@ -1101,13 +1097,13 @@ void EVP_PKEY_free(EVP_PKEY *pkey);
 
 EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
                         long length);
-int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp);
+int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp);
 
 EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
                          long length);
 EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
                              long length);
-int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp);
+int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp);
 
 int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
 int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
@@ -1398,7 +1394,7 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx);
 
 EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
 EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
-EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx);
 void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
 
 int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
@@ -1433,7 +1429,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
                                 size_t len, const EVP_CIPHER *cipher);
 
 void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
-void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
+void *EVP_PKEY_CTX_get_data(const EVP_PKEY_CTX *ctx);
 EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);
 
 EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx);
@@ -1486,7 +1482,7 @@ void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
 
 void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
                             int (*copy) (EVP_PKEY_CTX *dst,
-                                         EVP_PKEY_CTX *src));
+                                         const EVP_PKEY_CTX *src));
 
 void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
                                void (*cleanup) (EVP_PKEY_CTX *ctx));
@@ -1591,7 +1587,7 @@ void EVP_PKEY_meth_get_init(const EVP_PKEY_METHOD *pmeth,
 
 void EVP_PKEY_meth_get_copy(const EVP_PKEY_METHOD *pmeth,
                             int (**pcopy) (EVP_PKEY_CTX *dst,
-                                           EVP_PKEY_CTX *src));
+                                           const EVP_PKEY_CTX *src));
 
 void EVP_PKEY_meth_get_cleanup(const EVP_PKEY_METHOD *pmeth,
                                void (**pcleanup) (EVP_PKEY_CTX *ctx));
diff --git a/include/openssl/objects.h b/include/openssl/objects.h
index 2df7af7..d077ad4 100644
--- a/include/openssl/objects.h
+++ b/include/openssl/objects.h
@@ -56,7 +56,7 @@ void OBJ_NAME_do_all_sorted(int type,
                             void (*fn) (const OBJ_NAME *, void *arg),
                             void *arg);
 
-ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o);
+DECLARE_ASN1_DUP_FUNCTION_name(ASN1_OBJECT, OBJ)
 ASN1_OBJECT *OBJ_nid2obj(int n);
 const char *OBJ_nid2ln(int n);
 const char *OBJ_nid2sn(int n);
diff --git a/include/openssl/ocsp.h b/include/openssl/ocsp.h
index 22afb62..3aba16c 100644
--- a/include/openssl/ocsp.h
+++ b/include/openssl/ocsp.h
@@ -146,7 +146,7 @@ typedef struct ocsp_service_locator_st OCSP_SERVICELOC;
                 (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\
                 (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs))
 
-OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id);
+DECLARE_ASN1_DUP_FUNCTION(OCSP_CERTID)
 
 OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req);
 OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req,
diff --git a/include/openssl/pem.h b/include/openssl/pem.h
index a7331ac..8f6e6a2 100644
--- a/include/openssl/pem.h
+++ b/include/openssl/pem.h
@@ -323,35 +323,35 @@ int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x,
                                          unsigned char *kstr, int klen,
                                          pem_password_cb *cb, void *u);
 
-int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
+int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, int nid,
                                       char *kstr, int klen,
                                       pem_password_cb *cb, void *u);
-int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
+int PEM_write_bio_PKCS8PrivateKey(BIO *, const EVP_PKEY *, const EVP_CIPHER *,
                                   char *, int, pem_password_cb *, void *);
-int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+int i2d_PKCS8PrivateKey_bio(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc,
                             char *kstr, int klen,
                             pem_password_cb *cb, void *u);
-int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, const EVP_PKEY *x, int nid,
                                 char *kstr, int klen,
                                 pem_password_cb *cb, void *u);
 EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
                                   void *u);
 
 # ifndef OPENSSL_NO_STDIO
-int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+int i2d_PKCS8PrivateKey_fp(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc,
                            char *kstr, int klen,
                            pem_password_cb *cb, void *u);
-int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
+int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, const EVP_PKEY *x, int nid,
                                char *kstr, int klen,
                                pem_password_cb *cb, void *u);
-int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
+int PEM_write_PKCS8PrivateKey_nid(FILE *fp, const EVP_PKEY *x, int nid,
                                   char *kstr, int klen,
                                   pem_password_cb *cb, void *u);
 
 EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
                                  void *u);
 
-int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc,
                               char *kstr, int klen, pem_password_cb *cd,
                               void *u);
 # endif
diff --git a/include/openssl/pkcs12.h b/include/openssl/pkcs12.h
index 01f9393..83caaee 100644
--- a/include/openssl/pkcs12.h
+++ b/include/openssl/pkcs12.h
@@ -207,9 +207,9 @@ int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
                     int safe_nid, int iter, const char *pass);
 PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid);
 
-int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12);
+int i2d_PKCS12_bio(BIO *bp, const PKCS12 *p12);
 # ifndef OPENSSL_NO_STDIO
-int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12);
+int i2d_PKCS12_fp(FILE *fp, const PKCS12 *p12);
 # endif
 PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12);
 # ifndef OPENSSL_NO_STDIO
diff --git a/include/openssl/pkcs7.h b/include/openssl/pkcs7.h
index 8a67dcb..5dec27f 100644
--- a/include/openssl/pkcs7.h
+++ b/include/openssl/pkcs7.h
@@ -208,11 +208,11 @@ int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,
                                    unsigned int *len);
 # ifndef OPENSSL_NO_STDIO
 PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7);
-int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7);
+int i2d_PKCS7_fp(FILE *fp, const PKCS7 *p7);
 # endif
-PKCS7 *PKCS7_dup(PKCS7 *p7);
+DECLARE_ASN1_DUP_FUNCTION(PKCS7)
 PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7);
-int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7);
+int i2d_PKCS7_bio(BIO *bp, const PKCS7 *p7);
 int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
 int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
 
diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h
index be0fbbd..6b681f4 100644
--- a/include/openssl/rsa.h
+++ b/include/openssl/rsa.h
@@ -276,8 +276,8 @@ const RSA_METHOD *RSA_PKCS1_OpenSSL(void);
 
 int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2);
 
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey)
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey)
+DECLARE_ASN1_ENCODE_FUNCTIONS_name(RSA, RSAPublicKey)
+DECLARE_ASN1_ENCODE_FUNCTIONS_name(RSA, RSAPrivateKey)
 
 typedef struct rsa_pss_params_st {
     X509_ALGOR *hashAlgorithm;
@@ -393,8 +393,8 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
 int RSA_set_ex_data(RSA *r, int idx, void *arg);
 void *RSA_get_ex_data(const RSA *r, int idx);
 
-RSA *RSAPublicKey_dup(RSA *rsa);
-RSA *RSAPrivateKey_dup(RSA *rsa);
+DECLARE_ASN1_DUP_FUNCTION_name(RSA, RSAPublicKey)
+DECLARE_ASN1_DUP_FUNCTION_name(RSA, RSAPrivateKey)
 
 /*
  * If this flag is set the RSA method is FIPS compliant and can be used in
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 9d6e1c5..1091b1c 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1660,7 +1660,7 @@ __owur int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid,
 __owur int SSL_SESSION_is_resumable(const SSL_SESSION *s);
 
 __owur SSL_SESSION *SSL_SESSION_new(void);
-__owur SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src);
+__owur SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src);
 const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
                                         unsigned int *len);
 const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *s,
@@ -1673,7 +1673,7 @@ int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses);
 int SSL_SESSION_print_keylog(BIO *bp, const SSL_SESSION *x);
 int SSL_SESSION_up_ref(SSL_SESSION *ses);
 void SSL_SESSION_free(SSL_SESSION *ses);
-__owur int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp);
+__owur int i2d_SSL_SESSION(const SSL_SESSION *in, unsigned char **pp);
 __owur int SSL_set_session(SSL *to, SSL_SESSION *session);
 int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session);
 int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session);
diff --git a/include/openssl/ts.h b/include/openssl/ts.h
index ef78d8c..3165a78 100644
--- a/include/openssl/ts.h
+++ b/include/openssl/ts.h
@@ -59,76 +59,58 @@ typedef struct TS_status_info_st TS_STATUS_INFO;
 
 typedef struct TS_resp_st TS_RESP;
 
-TS_REQ *TS_REQ_new(void);
-void TS_REQ_free(TS_REQ *a);
-int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp);
-TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length);
-
-TS_REQ *TS_REQ_dup(TS_REQ *a);
+DECLARE_ASN1_ALLOC_FUNCTIONS(TS_REQ)
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(TS_REQ, TS_REQ)
+DECLARE_ASN1_DUP_FUNCTION(TS_REQ)
 
 #ifndef OPENSSL_NO_STDIO
 TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a);
-int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a);
+int i2d_TS_REQ_fp(FILE *fp, const TS_REQ *a);
 #endif
 TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a);
-int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a);
-
-TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void);
-void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a);
-int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp);
-TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a,
-                                   const unsigned char **pp, long length);
+int i2d_TS_REQ_bio(BIO *fp, const TS_REQ *a);
 
-TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a);
+DECLARE_ASN1_ALLOC_FUNCTIONS(TS_MSG_IMPRINT)
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(TS_MSG_IMPRINT, TS_MSG_IMPRINT)
+DECLARE_ASN1_DUP_FUNCTION(TS_MSG_IMPRINT)
 
 #ifndef OPENSSL_NO_STDIO
 TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a);
-int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a);
+int i2d_TS_MSG_IMPRINT_fp(FILE *fp, const TS_MSG_IMPRINT *a);
 #endif
 TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bio, TS_MSG_IMPRINT **a);
-int i2d_TS_MSG_IMPRINT_bio(BIO *bio, TS_MSG_IMPRINT *a);
+int i2d_TS_MSG_IMPRINT_bio(BIO *bio, const TS_MSG_IMPRINT *a);
 
-TS_RESP *TS_RESP_new(void);
-void TS_RESP_free(TS_RESP *a);
-int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp);
-TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length);
-TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token);
-TS_RESP *TS_RESP_dup(TS_RESP *a);
+DECLARE_ASN1_ALLOC_FUNCTIONS(TS_RESP)
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(TS_RESP, TS_RESP)
+DECLARE_ASN1_DUP_FUNCTION(TS_RESP)
 
 #ifndef OPENSSL_NO_STDIO
 TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a);
-int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a);
+int i2d_TS_RESP_fp(FILE *fp, const TS_RESP *a);
 #endif
 TS_RESP *d2i_TS_RESP_bio(BIO *bio, TS_RESP **a);
-int i2d_TS_RESP_bio(BIO *bio, TS_RESP *a);
-
-TS_STATUS_INFO *TS_STATUS_INFO_new(void);
-void TS_STATUS_INFO_free(TS_STATUS_INFO *a);
-int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp);
-TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a,
-                                   const unsigned char **pp, long length);
-TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a);
-
-TS_TST_INFO *TS_TST_INFO_new(void);
-void TS_TST_INFO_free(TS_TST_INFO *a);
-int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp);
-TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp,
-                             long length);
-TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a);
+int i2d_TS_RESP_bio(BIO *bio, const TS_RESP *a);
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(TS_STATUS_INFO)
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(TS_STATUS_INFO, TS_STATUS_INFO)
+DECLARE_ASN1_DUP_FUNCTION(TS_STATUS_INFO)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(TS_TST_INFO)
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(TS_TST_INFO, TS_TST_INFO)
+DECLARE_ASN1_DUP_FUNCTION(TS_TST_INFO)
+TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token);
 
 #ifndef OPENSSL_NO_STDIO
 TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a);
-int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a);
+int i2d_TS_TST_INFO_fp(FILE *fp, const TS_TST_INFO *a);
 #endif
 TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bio, TS_TST_INFO **a);
-int i2d_TS_TST_INFO_bio(BIO *bio, TS_TST_INFO *a);
-
-TS_ACCURACY *TS_ACCURACY_new(void);
-void TS_ACCURACY_free(TS_ACCURACY *a);
-int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp);
-TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp,
-                             long length);
-TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a);
+int i2d_TS_TST_INFO_bio(BIO *bio, const TS_TST_INFO *a);
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(TS_ACCURACY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(TS_ACCURACY, TS_ACCURACY)
+DECLARE_ASN1_DUP_FUNCTION(TS_ACCURACY)
 
 int TS_REQ_set_version(TS_REQ *a, long version);
 long TS_REQ_get_version(const TS_REQ *a);
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 7e388d9..bf127c0 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -391,87 +391,87 @@ int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
 
 # ifndef OPENSSL_NO_STDIO
 X509 *d2i_X509_fp(FILE *fp, X509 **x509);
-int i2d_X509_fp(FILE *fp, X509 *x509);
+int i2d_X509_fp(FILE *fp, const X509 *x509);
 X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl);
-int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl);
+int i2d_X509_CRL_fp(FILE *fp, const X509_CRL *crl);
 X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req);
-int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req);
+int i2d_X509_REQ_fp(FILE *fp, const X509_REQ *req);
 #  ifndef OPENSSL_NO_RSA
 RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa);
-int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa);
+int i2d_RSAPrivateKey_fp(FILE *fp, const RSA *rsa);
 RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa);
-int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa);
+int i2d_RSAPublicKey_fp(FILE *fp, const RSA *rsa);
 RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa);
-int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa);
+int i2d_RSA_PUBKEY_fp(FILE *fp, const RSA *rsa);
 #  endif
 #  ifndef OPENSSL_NO_DSA
 DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
-int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
+int i2d_DSA_PUBKEY_fp(FILE *fp, const DSA *dsa);
 DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
-int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
+int i2d_DSAPrivateKey_fp(FILE *fp, const DSA *dsa);
 #  endif
 #  ifndef OPENSSL_NO_EC
 EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
-int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
+int i2d_EC_PUBKEY_fp(FILE *fp, const EC_KEY *eckey);
 EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
-int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
+int i2d_ECPrivateKey_fp(FILE *fp, const EC_KEY *eckey);
 #  endif
 X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8);
-int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8);
+int i2d_PKCS8_fp(FILE *fp, const X509_SIG *p8);
 PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
                                                 PKCS8_PRIV_KEY_INFO **p8inf);
-int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf);
-int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
-int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
+int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, const PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, const EVP_PKEY *key);
+int i2d_PrivateKey_fp(FILE *fp, const EVP_PKEY *pkey);
 EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
-int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
+int i2d_PUBKEY_fp(FILE *fp, const EVP_PKEY *pkey);
 EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
 # endif
 
 X509 *d2i_X509_bio(BIO *bp, X509 **x509);
-int i2d_X509_bio(BIO *bp, X509 *x509);
+int i2d_X509_bio(BIO *bp, const X509 *x509);
 X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl);
-int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl);
+int i2d_X509_CRL_bio(BIO *bp, const X509_CRL *crl);
 X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req);
-int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req);
+int i2d_X509_REQ_bio(BIO *bp, const X509_REQ *req);
 #  ifndef OPENSSL_NO_RSA
 RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa);
-int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa);
+int i2d_RSAPrivateKey_bio(BIO *bp, const RSA *rsa);
 RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa);
-int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa);
+int i2d_RSAPublicKey_bio(BIO *bp, const RSA *rsa);
 RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa);
-int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa);
+int i2d_RSA_PUBKEY_bio(BIO *bp, const RSA *rsa);
 #  endif
 #  ifndef OPENSSL_NO_DSA
 DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
-int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
+int i2d_DSA_PUBKEY_bio(BIO *bp, const DSA *dsa);
 DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
-int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
+int i2d_DSAPrivateKey_bio(BIO *bp, const DSA *dsa);
 #  endif
 #  ifndef OPENSSL_NO_EC
 EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
-int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
+int i2d_EC_PUBKEY_bio(BIO *bp, const EC_KEY *eckey);
 EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
-int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
+int i2d_ECPrivateKey_bio(BIO *bp, const EC_KEY *eckey);
 #  endif
 X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8);
-int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8);
+int i2d_PKCS8_bio(BIO *bp, const X509_SIG *p8);
 PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
                                                  PKCS8_PRIV_KEY_INFO **p8inf);
-int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf);
-int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
-int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
+int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, const PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, const EVP_PKEY *key);
+int i2d_PrivateKey_bio(BIO *bp, const EVP_PKEY *pkey);
 EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
-int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
+int i2d_PUBKEY_bio(BIO *bp, const EVP_PKEY *pkey);
 EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
 
-X509 *X509_dup(X509 *x509);
-X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
-X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
-X509_CRL *X509_CRL_dup(X509_CRL *crl);
-X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev);
-X509_REQ *X509_REQ_dup(X509_REQ *req);
-X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
+DECLARE_ASN1_DUP_FUNCTION(X509)
+DECLARE_ASN1_DUP_FUNCTION(X509_ATTRIBUTE)
+DECLARE_ASN1_DUP_FUNCTION(X509_EXTENSION)
+DECLARE_ASN1_DUP_FUNCTION(X509_CRL)
+DECLARE_ASN1_DUP_FUNCTION(X509_REVOKED)
+DECLARE_ASN1_DUP_FUNCTION(X509_REQ)
+DECLARE_ASN1_DUP_FUNCTION(X509_ALGOR)
 int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype,
                     void *pval);
 void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype,
@@ -479,8 +479,8 @@ void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype,
 void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
 int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
 
-X509_NAME *X509_NAME_dup(X509_NAME *xn);
-X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
+DECLARE_ASN1_DUP_FUNCTION(X509_NAME)
+DECLARE_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
 
 int X509_cmp_time(const ASN1_TIME *s, time_t *t);
 int X509_cmp_current_time(const ASN1_TIME *s);
@@ -510,19 +510,15 @@ EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key);
 EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key);
 int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain);
 long X509_get_pathlen(X509 *x);
-int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp);
-EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length);
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(EVP_PKEY, PUBKEY)
 # ifndef OPENSSL_NO_RSA
-int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp);
-RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length);
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(RSA, RSA_PUBKEY)
 # endif
 # ifndef OPENSSL_NO_DSA
-int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp);
-DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length);
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(DSA, DSA_PUBKEY)
 # endif
 # ifndef OPENSSL_NO_EC
-int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp);
-EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length);
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(EC_KEY, EC_PUBKEY)
 # endif
 
 DECLARE_ASN1_FUNCTIONS(X509_SIG)
@@ -544,10 +540,9 @@ DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)
 
 DECLARE_ASN1_FUNCTIONS(X509_NAME)
 
-int X509_NAME_set(X509_NAME **xn, X509_NAME *name);
+int X509_NAME_set(X509_NAME **xn, const X509_NAME *name);
 
 DECLARE_ASN1_FUNCTIONS(X509_CINF)
-
 DECLARE_ASN1_FUNCTIONS(X509)
 DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)
 
@@ -555,8 +550,7 @@ DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)
     CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, l, p, newf, dupf, freef)
 int X509_set_ex_data(X509 *r, int idx, void *arg);
 void *X509_get_ex_data(X509 *r, int idx);
-int i2d_X509_AUX(X509 *a, unsigned char **pp);
-X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length);
+DECLARE_ASN1_ENCODE_FUNCTIONS_only(X509,X509_AUX)
 
 int i2d_re_X509_tbs(X509 *x, unsigned char **pp);
 
@@ -1009,7 +1003,7 @@ X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
 DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
 
 EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8);
-PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey);
 
 int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
                     int version, int ptype, void *pval,
diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h
index 1706a82..9c7a325 100644
--- a/include/openssl/x509v3.h
+++ b/include/openssl/x509v3.h
@@ -28,7 +28,7 @@ struct v3_ext_ctx;
 typedef void *(*X509V3_EXT_NEW)(void);
 typedef void (*X509V3_EXT_FREE) (void *);
 typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long);
-typedef int (*X509V3_EXT_I2D) (void *, unsigned char **);
+typedef int (*X509V3_EXT_I2D) (const void *, unsigned char **);
 typedef STACK_OF(CONF_VALUE) *
     (*X509V3_EXT_I2V) (const struct v3_ext_method *method, void *ext,
                        STACK_OF(CONF_VALUE) *extlist);
@@ -467,7 +467,7 @@ DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID)
 DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
 
 DECLARE_ASN1_FUNCTIONS(GENERAL_NAME)
-GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a);
+DECLARE_ASN1_DUP_FUNCTION(GENERAL_NAME)
 int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b);
 
 ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index 4b70e38..e54d530 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -83,9 +83,9 @@ IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(SSL_SESSION_ASN1)
 /* Initialise OCTET STRING from buffer and length */
 
 static void ssl_session_oinit(ASN1_OCTET_STRING **dest, ASN1_OCTET_STRING *os,
-                              unsigned char *data, size_t len)
+                              const unsigned char *data, size_t len)
 {
-    os->data = data;
+    os->data = (unsigned char *)data; /* justified cast: data is not modified */
     os->length = (int)len;
     os->flags = 0;
     *dest = os;
@@ -93,15 +93,15 @@ static void ssl_session_oinit(ASN1_OCTET_STRING **dest, ASN1_OCTET_STRING *os,
 
 /* Initialise OCTET STRING from string */
 static void ssl_session_sinit(ASN1_OCTET_STRING **dest, ASN1_OCTET_STRING *os,
-                              char *data)
+                              const char *data)
 {
     if (data != NULL)
-        ssl_session_oinit(dest, os, (unsigned char *)data, strlen(data));
+        ssl_session_oinit(dest, os, (const unsigned char *)data, strlen(data));
     else
         *dest = NULL;
 }
 
-int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
+int i2d_SSL_SESSION(const SSL_SESSION *in, unsigned char **pp)
 {
 
     SSL_SESSION_ASN1 as;
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index a51cc6c..1d3397d 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -2271,7 +2271,7 @@ __owur int ssl_get_new_session(SSL *s, int session);
 __owur SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id,
                                          size_t sess_id_len);
 __owur int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello);
-__owur SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket);
+__owur SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket);
 __owur int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b);
 DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id);
 __owur int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap,
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index 58f38d5..d04b4fa 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -94,7 +94,7 @@ SSL_SESSION *SSL_SESSION_new(void)
     return ss;
 }
 
-SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src)
+SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src)
 {
     return ssl_session_dup(src, 1);
 }
@@ -103,7 +103,7 @@ SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src)
  * Create a new SSL_SESSION and duplicate the contents of |src| into it. If
  * ticket == 0 then no ticket information is duplicated, otherwise it is.
  */
-SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
+SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
 {
     SSL_SESSION *dest;
 
diff --git a/test/x509aux.c b/test/x509aux.c
index ec2618d..1489428 100644
--- a/test/x509aux.c
+++ b/test/x509aux.c
@@ -27,7 +27,7 @@ static int test_certs(int num)
     unsigned char *data = 0;
     long len;
     typedef X509 *(*d2i_X509_t)(X509 **, const unsigned char **, long);
-    typedef int (*i2d_X509_t)(X509 *, unsigned char **);
+    typedef int (*i2d_X509_t)(const X509 *, unsigned char **);
     int err = 0;
     BIO *fp = BIO_new_file(test_get_argument(num), "r");
     X509 *reuse = NULL;
diff --git a/util/perl/OpenSSL/ParseC.pm b/util/perl/OpenSSL/ParseC.pm
index 4c505f2..7a13930 100644
--- a/util/perl/OpenSSL/ParseC.pm
+++ b/util/perl/OpenSSL/ParseC.pm
@@ -257,7 +257,7 @@ my @opensslchandlers = (
 
     #####
     # Global variable stuff
-    { regexp   => qr/OPENSSL_DECLARE_GLOBAL<<<\((.*),(.*)\)>>>;/,
+    { regexp   => qr/OPENSSL_DECLARE_GLOBAL<<<\((.*),\s*(.*)\)>>>;/,
       massager => sub { return (<<"EOF");
 #ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
 OPENSSL_EXPORT $1 _shadow_$2;
@@ -331,7 +331,7 @@ EOF
 #          return ("$before$stack_of$after");
 #      }
 #    },
-    { regexp   => qr/SKM_DEFINE_STACK_OF<<<\((.*),(.*),(.*)\)>>>/,
+    { regexp   => qr/SKM_DEFINE_STACK_OF<<<\((.*),\s*(.*),\s*(.*)\)>>>/,
       massager => sub {
           return (<<"EOF");
 STACK_OF($1);
@@ -370,13 +370,13 @@ static ossl_inline sk_$1_compfunc sk_$1_set_cmp_func(STACK_OF($1) *sk,
 EOF
       }
     },
-    { regexp   => qr/DEFINE_SPECIAL_STACK_OF<<<\((.*),(.*)\)>>>/,
+    { regexp   => qr/DEFINE_SPECIAL_STACK_OF<<<\((.*),\s*(.*)\)>>>/,
       massager => sub { return ("SKM_DEFINE_STACK_OF($1,$2,$2)"); },
     },
     { regexp   => qr/DEFINE_STACK_OF<<<\((.*)\)>>>/,
       massager => sub { return ("SKM_DEFINE_STACK_OF($1,$1,$1)"); },
     },
-    { regexp   => qr/DEFINE_SPECIAL_STACK_OF_CONST<<<\((.*),(.*)\)>>>/,
+    { regexp   => qr/DEFINE_SPECIAL_STACK_OF_CONST<<<\((.*),\s*(.*)\)>>>/,
       massager => sub { return ("SKM_DEFINE_STACK_OF($1,const $2,$2)"); },
     },
     { regexp   => qr/DEFINE_STACK_OF_CONST<<<\((.*)\)>>>/,
@@ -388,7 +388,7 @@ EOF
     { regexp   => qr/DECLARE_STACK_OF<<<\((.*)\)>>>/,
       massager => sub { return ("STACK_OF($1);"); }
     },
-    { regexp   => qr/DECLARE_SPECIAL_STACK_OF<<<\((.*?),(.*?)\)>>>/,
+    { regexp   => qr/DECLARE_SPECIAL_STACK_OF<<<\((.*?),\s*(.*?)\)>>>/,
       massager => sub { return ("STACK_OF($1);"); }
      },
 
@@ -421,7 +421,15 @@ const ASN1_ITEM *$1_it(void);
 EOF
       },
     },
-    { regexp   => qr/DECLARE_ASN1_ENCODE_FUNCTIONS<<<\((.*),(.*),(.*)\)>>>/,
+    { regexp   => qr/DECLARE_ASN1_ENCODE_FUNCTIONS_only<<<\((.*),\s*(.*)\)>>>/,
+      massager => sub {
+          return (<<"EOF");
+int d2i_$2(void);
+int i2d_$2(void);
+EOF
+      },
+    },
+    { regexp   => qr/DECLARE_ASN1_ENCODE_FUNCTIONS<<<\((.*),\s*(.*),\s*(.*)\)>>>/,
       massager => sub {
           return (<<"EOF");
 int d2i_$3(void);
@@ -430,7 +438,7 @@ DECLARE_ASN1_ITEM($2)
 EOF
       },
     },
-    { regexp   => qr/DECLARE_ASN1_ENCODE_FUNCTIONS_const<<<\((.*),(.*)\)>>>/,
+    { regexp   => qr/DECLARE_ASN1_ENCODE_FUNCTIONS_name<<<\((.*),\s*(.*)\)>>>/,
       massager => sub {
           return (<<"EOF");
 int d2i_$2(void);
@@ -439,6 +447,14 @@ DECLARE_ASN1_ITEM($2)
 EOF
       },
     },
+    { regexp   => qr/DECLARE_ASN1_ALLOC_FUNCTIONS_name<<<\((.*),\s*(.*)\)>>>/,
+      massager => sub {
+          return (<<"EOF");
+int $2_free(void);
+int $2_new(void);
+EOF
+      },
+    },
     { regexp   => qr/DECLARE_ASN1_ALLOC_FUNCTIONS<<<\((.*)\)>>>/,
       massager => sub {
           return (<<"EOF");
@@ -447,7 +463,7 @@ int $1_new(void);
 EOF
       },
     },
-    { regexp   => qr/DECLARE_ASN1_FUNCTIONS_name<<<\((.*),(.*)\)>>>/,
+    { regexp   => qr/DECLARE_ASN1_FUNCTIONS_name<<<\((.*),\s*(.*)\)>>>/,
       massager => sub {
           return (<<"EOF");
 int d2i_$2(void);
@@ -458,17 +474,7 @@ DECLARE_ASN1_ITEM($2)
 EOF
       },
     },
-    { regexp   => qr/DECLARE_ASN1_FUNCTIONS_fname<<<\((.*),(.*),(.*)\)>>>/,
-      massager => sub { return (<<"EOF");
-int d2i_$3(void);
-int i2d_$3(void);
-int $3_free(void);
-int $3_new(void);
-DECLARE_ASN1_ITEM($2)
-EOF
-      }
-    },
-    { regexp   => qr/DECLARE_ASN1_FUNCTIONS(?:_const)?<<<\((.*)\)>>>/,
+    { regexp   => qr/DECLARE_ASN1_FUNCTIONS<<<\((.*)\)>>>/,
       massager => sub { return (<<"EOF");
 int d2i_$1(void);
 int i2d_$1(void);
@@ -492,7 +498,7 @@ int $1_print_ctx(void);
 EOF
       }
     },
-    { regexp   => qr/DECLARE_ASN1_PRINT_FUNCTION_name<<<\((.*),(.*)\)>>>/,
+    { regexp   => qr/DECLARE_ASN1_PRINT_FUNCTION_name<<<\((.*),\s*(.*)\)>>>/,
       massager => sub {
           return (<<"EOF");
 int $2_print_ctx(void);
@@ -502,6 +508,20 @@ EOF
     { regexp   => qr/DECLARE_ASN1_SET_OF<<<\((.*)\)>>>/,
       massager => sub { return (); }
     },
+    { regexp   => qr/DECLARE_ASN1_DUP_FUNCTION<<<\((.*)\)>>>/,
+      massager => sub {
+          return (<<"EOF");
+int $1_dup(void);
+EOF
+      }
+    },
+    { regexp   => qr/DECLARE_ASN1_DUP_FUNCTION_name<<<\((.*),\s*(.*)\)>>>/,
+      massager => sub {
+          return (<<"EOF");
+int $2_dup(void);
+EOF
+      }
+    },
     { regexp   => qr/DECLARE_PKCS12_SET_OF<<<\((.*)\)>>>/,
       massager => sub { return (); }
     },


More information about the openssl-commits mailing list