diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2016-12-15 14:50:23 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2017-07-23 13:32:35 +0900 |
commit | af895bc5596b1521e13a3c6ab65aacdb6913e128 (patch) | |
tree | 7ae2f707f66fd0c69caf66ed1b072efbffd16510 /ext/openssl/ossl_asn1.c | |
parent | f61af664ecf4fd74ef0adc1138bc09455e89199f (diff) | |
download | ruby-openssl-af895bc5596b1521e13a3c6ab65aacdb6913e128.tar.gz |
asn1: avoid truncating OID in OpenSSL::ASN1::ObjectId#oid
OpenSSL::ASN1::ObjectId#oid, which returns the dotted representation of
the OID, is silently truncating the result if it overflows the 128-bytes
buffer. Although it normally won't be more than 127-characters, it'd be
better to avoid. This can be done by checking the return value of
OBJ_obj2txt().
Previous releases of LibreSSL (< 2.5.1) have a bug in OBJ_obj2txt() and
it does not work if the resulting string would be larger than the
buffer. A workaround is added to the test. It should be removed when we
deprecate support for LibreSSL 2.4.
Diffstat (limited to 'ext/openssl/ossl_asn1.c')
-rw-r--r-- | ext/openssl/ossl_asn1.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c index 00d598ef..50fcb5b1 100644 --- a/ext/openssl/ossl_asn1.c +++ b/ext/openssl/ossl_asn1.c @@ -1347,6 +1347,28 @@ ossl_asn1obj_get_ln(VALUE self) return ret; } +static VALUE +asn1obj_get_oid_i(VALUE vobj) +{ + ASN1_OBJECT *a1obj = (void *)vobj; + VALUE str; + int len; + + str = rb_usascii_str_new(NULL, 127); + len = OBJ_obj2txt(RSTRING_PTR(str), RSTRING_LENINT(str), a1obj, 1); + if (len <= 0 || len == INT_MAX) + ossl_raise(eASN1Error, "OBJ_obj2txt"); + if (len > RSTRING_LEN(str)) { + /* +1 is for the \0 terminator added by OBJ_obj2txt() */ + rb_str_resize(str, len + 1); + len = OBJ_obj2txt(RSTRING_PTR(str), len + 1, a1obj, 1); + if (len <= 0) + ossl_raise(eASN1Error, "OBJ_obj2txt"); + } + rb_str_set_len(str, len); + return str; +} + /* * call-seq: * oid.oid -> string @@ -1357,16 +1379,16 @@ ossl_asn1obj_get_ln(VALUE self) static VALUE ossl_asn1obj_get_oid(VALUE self) { - VALUE val; + VALUE str; ASN1_OBJECT *a1obj; - char buf[128]; + int state; - val = ossl_asn1_get_value(self); - a1obj = obj_to_asn1obj(val); - OBJ_obj2txt(buf, sizeof(buf), a1obj, 1); + a1obj = obj_to_asn1obj(ossl_asn1_get_value(self)); + str = rb_protect(asn1obj_get_oid_i, (VALUE)a1obj, &state); ASN1_OBJECT_free(a1obj); - - return rb_str_new2(buf); + if (state) + rb_jump_tag(state); + return str; } #define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \ |