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);