Document some more ASN1_ITEM-associated functions. In doing so, fix ASN1_item_pack to not use the ASN1_OCTET_STRING typedef. The function makes an untyped ASN1_STRING. With all these caveats, one might think that ASN1_BOOLEAN ASN1_ITEMs are pretty useless. This is about right. They're really only usable embedded as a field in another struct. Bug: 426 Change-Id: Id7830b91b2d011038ce79ec848e17ad6241423e1 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49926 Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/asn1/asn_pack.c b/crypto/asn1/asn_pack.c index 3c7116e..fd7ab4b 100644 --- a/crypto/asn1/asn_pack.c +++ b/crypto/asn1/asn_pack.c
@@ -101,5 +101,6 @@ p = oct->data; if (!(ret = ASN1_item_d2i(NULL, &p, oct->length, it))) OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + /* TODO(davidben): Check for trailing data. */ return ret; }
diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h index a211019..0f12a5b 100644 --- a/include/openssl/asn1.h +++ b/include/openssl/asn1.h
@@ -283,6 +283,66 @@ OPENSSL_EXPORT int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **outp, const ASN1_ITEM *it); +// ASN1_item_dup returns a newly-allocated copy of |x|, or NULL on error. |x| +// must be an object of |it|'s C type. +// +// This function may not be used with |ASN1_ITEM|s whose C type is +// |ASN1_BOOLEAN|. +// +// WARNING: Casting the result of this function to the wrong type, or passing a +// pointer of the wrong type into this function, are potentially exploitable +// memory errors. Prefer using type-specific functions such as +// |ASN1_STRING_dup|. +OPENSSL_EXPORT void *ASN1_item_dup(const ASN1_ITEM *it, void *x); + +// The following functions behave like |ASN1_item_d2i| but read from |in| +// instead. |out| is the same parameter as in |ASN1_item_d2i|, but written with +// |void*| instead. The return values similarly match. +// +// These functions may not be used with |ASN1_ITEM|s whose C type is +// |ASN1_BOOLEAN|. +// +// WARNING: These functions do not bound how much data is read from |in|. +// Parsing an untrusted input could consume unbounded memory. +OPENSSL_EXPORT void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *out); +OPENSSL_EXPORT void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *out); + +// The following functions behave like |ASN1_item_i2d| but write to |out| +// instead. |in| is the same parameter as in |ASN1_item_i2d|, but written with +// |void*| instead. +// +// These functions may not be used with |ASN1_ITEM|s whose C type is +// |ASN1_BOOLEAN|. +OPENSSL_EXPORT int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *in); +OPENSSL_EXPORT int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *in); + +// ASN1_item_unpack parses |oct|'s contents as |it|'s ASN.1 type. It returns a +// newly-allocated instance of |it|'s C type on success, or NULL on error. +// +// This function may not be used with |ASN1_ITEM|s whose C type is +// |ASN1_BOOLEAN|. +// +// WARNING: Casting the result of this function to the wrong type is a +// potentially exploitable memory error. Callers must ensure the value is used +// consistently with |it|. +OPENSSL_EXPORT void *ASN1_item_unpack(const ASN1_STRING *oct, + const ASN1_ITEM *it); + +// ASN1_item_pack marshals |obj| as |it|'s ASN.1 type. If |out| is NULL, it +// returns a newly-allocated |ASN1_STRING| with the result, or NULL on error. +// If |out| is non-NULL, but |*out| is NULL, it does the same but additionally +// sets |*out| to the result. If both |out| and |*out| are non-NULL, it writes +// the result to |*out| and returns |*out| on success or NULL on error. +// +// This function may not be used with |ASN1_ITEM|s whose C type is +// |ASN1_BOOLEAN|. +// +// WARNING: Passing a pointer of the wrong type into this function is a +// potentially exploitable memory error. Callers must ensure |val| is consistent +// with |it|. +OPENSSL_EXPORT ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, + ASN1_STRING **out); + // Booleans. // @@ -1474,22 +1534,6 @@ OPENSSL_EXPORT int ASN1_put_eoc(unsigned char **pp); OPENSSL_EXPORT int ASN1_object_size(int constructed, int length, int tag); -OPENSSL_EXPORT void *ASN1_item_dup(const ASN1_ITEM *it, void *x); - -OPENSSL_EXPORT void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); -OPENSSL_EXPORT int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); - -OPENSSL_EXPORT void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); -OPENSSL_EXPORT int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); - -// Used to load and write netscape format cert - -OPENSSL_EXPORT void *ASN1_item_unpack(const ASN1_STRING *oct, - const ASN1_ITEM *it); - -OPENSSL_EXPORT ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, - ASN1_OCTET_STRING **oct); - // ASN1 template functions OPENSSL_EXPORT ASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf);