See attached. OpenSSL can't actually represent large universal tags because it collides with the V_ASN1_NEG flag, yet it happily parses them in high tag number form. d2i_ASN1_TYPE interprets 1f82020100 as a negative zero, rather than an element with tag [UNIVERSAL 258].
I've intentionally made the patch very conservative, so it only limits universal tags, in case there is worry about someone actually using tag number 258 of another class. (Although I've never seen anything go beyond 31 into high tag number form at all.) Our version of the change has a test: https://boringssl.googlesource.com/boringssl/+/fb2c6f8c8565e1e2d85c24408050c96521acbcdc%5E%21/ It should be straight-forward to adapt (the test barely does anything). I'm not sure how adding a test in OpenSSL works these days, so I leave that to you. David -- Ticket here: http://rt.openssl.org/Ticket/Display.html?id=4364 Please log in as guest with password guest if prompted
>From be074e3369ee0754f1413be82d0fa0f5effc8b27 Mon Sep 17 00:00:00 2001 From: David Benjamin <david...@google.com> Date: Tue, 1 Mar 2016 13:58:04 -0500 Subject: [PATCH] ASN1_get_object should not accept large universal tags. The high bits of the type get used for the V_ASN1_NEG bit, so when used with ASN1_ANY/ASN1_TYPE, universal tags become ambiguous. This allows one to create a negative zero, which should be impossible. Impose an upper bound on universal tags accepted by crypto/asn1. See also BoringSSL's https://boringssl.googlesource.com/boringssl/+/fb2c6f8c8565e1e2d85c24408050c96521acbcdc. --- crypto/asn1/asn1_lib.c | 4 ++++ include/openssl/asn1.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c index da1ac78..fe1473f 100644 --- a/crypto/asn1/asn1_lib.c +++ b/crypto/asn1/asn1_lib.c @@ -126,6 +126,10 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, if (--max == 0) goto err; } + + if (xclass == V_ASN1_UNIVERSAL && tag > V_ASN1_MAX_UNIVERSAL) + goto err; + *ptag = tag; *pclass = xclass; if (!asn1_get_length(&p, &inf, plength, (int)max)) diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h index 360914d..aa064d2 100644 --- a/include/openssl/asn1.h +++ b/include/openssl/asn1.h @@ -95,6 +95,9 @@ extern "C" { # define V_ASN1_ANY -4/* used in ASN1 template code */ # define V_ASN1_NEG 0x100/* negative flag */ +/* No supported universal tags may exceed this value, to avoid ambiguity with + * V_ASN1_NEG. */ +# define V_ASN1_MAX_UNIVERSAL 0xff # define V_ASN1_UNDEF -1 # define V_ASN1_EOC 0 -- 2.7.0.rc3.207.g0ac5344
-- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev