Const-correct the low-level ASN1 i2d functions.

This is completely unchecked for now, as it all goes through tasn_enc.c.
But the only non-const encoders now are X509_NAME, and the functions
that call into it, so we can fix up the ones at the bottom.

I haven't done the macros that use the "name" or "fname" variants. The
set of macros for const are a little weird. But before expanding the
header macros out, I wanted to change the signatures on the macro side
once, so the compiler checks they're expanded correctly.

Update-Note: The type signature of some i2d functions, such as
i2d_ASN1_OCTET_STRING, is now const-correct.

Bug: 407
Change-Id: I03988f5591191b41ab4e7f014bd8d41cb071b39a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49908
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/asn1/a_time.c b/crypto/asn1/a_time.c
index ad7f784..1195569 100644
--- a/crypto/asn1/a_time.c
+++ b/crypto/asn1/a_time.c
@@ -73,7 +73,7 @@
 
 IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME)
 
-IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME)
+IMPLEMENT_ASN1_FUNCTIONS_const(ASN1_TIME)
 
 ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
 {
diff --git a/crypto/asn1/asn1_test.cc b/crypto/asn1/asn1_test.cc
index 1ea7644..dee685a 100644
--- a/crypto/asn1/asn1_test.cc
+++ b/crypto/asn1/asn1_test.cc
@@ -103,9 +103,15 @@
   }
 }
 
-template <typename T>
-void TestSerialize(T obj, int (*i2d_func)(T a, uint8_t **pp),
+// |obj| and |i2d_func| require different template parameters because C++ may
+// deduce, say, |ASN1_STRING*| via |obj| and |const ASN1_STRING*| via
+// |i2d_func|. Template argument deduction then fails. The language is not able
+// to resolve this by observing that |const ASN1_STRING*| works for both.
+template <typename T, typename U>
+void TestSerialize(T obj, int (*i2d_func)(U a, uint8_t **pp),
                    bssl::Span<const uint8_t> expected) {
+  static_assert(std::is_convertible<T, U>::value,
+                "incompatible parameter to i2d_func");
   // Test the allocating version first. It is easiest to debug.
   uint8_t *ptr = nullptr;
   int len = i2d_func(obj, &ptr);
diff --git a/crypto/asn1/tasn_typ.c b/crypto/asn1/tasn_typ.c
index 44399ea..6f574c0 100644
--- a/crypto/asn1/tasn_typ.c
+++ b/crypto/asn1/tasn_typ.c
@@ -62,7 +62,7 @@
 
 #define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \
         IMPLEMENT_ASN1_TYPE(sname) \
-        IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(sname, sname, sname) \
+        IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(sname, sname, sname) \
         sname *sname##_new(void) \
         { \
                 return ASN1_STRING_type_new(V_##sname); \
@@ -88,7 +88,7 @@
 IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BMPSTRING)
 
 IMPLEMENT_ASN1_TYPE(ASN1_NULL)
-IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL)
+IMPLEMENT_ASN1_FUNCTIONS_const(ASN1_NULL)
 
 IMPLEMENT_ASN1_TYPE(ASN1_OBJECT)
 
diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h
index b1ad520..7de2331 100644
--- a/include/openssl/asn1.h
+++ b/include/openssl/asn1.h
@@ -1200,23 +1200,23 @@
 
 DECLARE_ASN1_ITEM(ASN1_OBJECT)
 
-DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_BIT_STRING)
 OPENSSL_EXPORT int i2c_ASN1_BIT_STRING(const ASN1_BIT_STRING *a,
                                        unsigned char **pp);
 OPENSSL_EXPORT ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
                                                     const unsigned char **pp,
                                                     long length);
 
-DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_INTEGER)
 OPENSSL_EXPORT int i2c_ASN1_INTEGER(const ASN1_INTEGER *a, unsigned char **pp);
 OPENSSL_EXPORT ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,
                                               const unsigned char **pp,
                                               long length);
 OPENSSL_EXPORT ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x);
 
-DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_ENUMERATED)
 
-DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_OCTET_STRING)
 OPENSSL_EXPORT ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(
     const ASN1_OCTET_STRING *a);
 OPENSSL_EXPORT int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
@@ -1224,23 +1224,23 @@
 OPENSSL_EXPORT int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str,
                                          const unsigned char *data, int len);
 
-DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
-DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
-DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING)
-DECLARE_ASN1_FUNCTIONS(ASN1_NULL)
-DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_VISIBLESTRING)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_UNIVERSALSTRING)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_UTF8STRING)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_NULL)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_BMPSTRING)
 
 DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
 
 DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
 DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
-DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
-DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING)
-DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING)
-DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
-DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
-DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
-DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_PRINTABLESTRING)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_T61STRING)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_IA5STRING)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_GENERALSTRING)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_UTCTIME)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_GENERALIZEDTIME)
+DECLARE_ASN1_FUNCTIONS_const(ASN1_TIME)
 
 OPENSSL_EXPORT int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a);
 OPENSSL_EXPORT int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a);