diff options
author | Kazuki Yamaguchi <[email protected]> | 2024-06-17 16:26:58 +0900 |
---|---|---|
committer | git <[email protected]> | 2024-07-24 16:50:01 +0000 |
commit | a1cf39bd366f843bc9fd1534aa8e7d301fc77252 (patch) | |
tree | 8a647bccdaac8867afd6dd4b16cf272e202be243 | |
parent | 575fe63e20dff83c684a93f5f76d0c27bbc250df (diff) |
[ruby/openssl] x509attr: avoid using OpenSSL::ASN1 internals in #value=
OpenSSL::ASN1 is being rewritten in Ruby. To make it easier, let's
remove dependency to the instance variables and the internal-use
function ossl_asn1_get_asn1type() outside OpenSSL::ASN1.
This also fixes the insufficient validation of the passed value with
its tagging.
https://github.com/ruby/openssl/commit/35a157462e
-rw-r--r-- | ext/openssl/ossl_x509attr.c | 47 | ||||
-rw-r--r-- | test/openssl/test_x509attr.rb | 4 |
2 files changed, 27 insertions, 24 deletions
diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index be525c9e7c..967fe89f01 100644 --- a/ext/openssl/ossl_x509attr.c +++ b/ext/openssl/ossl_x509attr.c @@ -201,37 +201,36 @@ static VALUE ossl_x509attr_set_value(VALUE self, VALUE value) { X509_ATTRIBUTE *attr; - VALUE asn1_value; - int i, asn1_tag; + GetX509Attr(self, attr); OSSL_Check_Kind(value, cASN1Data); - asn1_tag = NUM2INT(rb_attr_get(value, rb_intern("@tag"))); - asn1_value = rb_attr_get(value, rb_intern("@value")); - if (asn1_tag != V_ASN1_SET) - ossl_raise(eASN1Error, "argument must be ASN1::Set"); - if (!RB_TYPE_P(asn1_value, T_ARRAY)) - ossl_raise(eASN1Error, "ASN1::Set has non-array value"); + VALUE der = ossl_to_der(value); + const unsigned char *p = (const unsigned char *)RSTRING_PTR(der); + STACK_OF(ASN1_TYPE) *sk = d2i_ASN1_SET_ANY(NULL, &p, RSTRING_LEN(der)); + if (!sk) + ossl_raise(eX509AttrError, "attribute value must be ASN1::Set"); - GetX509Attr(self, attr); if (X509_ATTRIBUTE_count(attr)) { /* populated, reset first */ - ASN1_OBJECT *obj = X509_ATTRIBUTE_get0_object(attr); - X509_ATTRIBUTE *new_attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, 0, NULL, -1); - if (!new_attr) - ossl_raise(eX509AttrError, NULL); - SetX509Attr(self, new_attr); - X509_ATTRIBUTE_free(attr); - attr = new_attr; + ASN1_OBJECT *obj = X509_ATTRIBUTE_get0_object(attr); + X509_ATTRIBUTE *new_attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, 0, NULL, -1); + if (!new_attr) { + sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + ossl_raise(eX509AttrError, "X509_ATTRIBUTE_create_by_OBJ"); + } + SetX509Attr(self, new_attr); + X509_ATTRIBUTE_free(attr); + attr = new_attr; } - for (i = 0; i < RARRAY_LEN(asn1_value); i++) { - ASN1_TYPE *a1type = ossl_asn1_get_asn1type(RARRAY_AREF(asn1_value, i)); - if (!X509_ATTRIBUTE_set1_data(attr, ASN1_TYPE_get(a1type), - a1type->value.ptr, -1)) { - ASN1_TYPE_free(a1type); - ossl_raise(eX509AttrError, NULL); - } - ASN1_TYPE_free(a1type); + for (int i = 0; i < sk_ASN1_TYPE_num(sk); i++) { + ASN1_TYPE *a1type = sk_ASN1_TYPE_value(sk, i); + if (!X509_ATTRIBUTE_set1_data(attr, ASN1_TYPE_get(a1type), + a1type->value.ptr, -1)) { + sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + ossl_raise(eX509AttrError, "X509_ATTRIBUTE_set1_data"); + } } + sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); return value; } diff --git a/test/openssl/test_x509attr.rb b/test/openssl/test_x509attr.rb index 2919d23d2d..bec03a1871 100644 --- a/test/openssl/test_x509attr.rb +++ b/test/openssl/test_x509attr.rb @@ -48,6 +48,10 @@ class OpenSSL::TestX509Attribute < OpenSSL::TestCase assert_raise(TypeError) { attr.value = "1234" } + assert_raise(OpenSSL::X509::AttributeError) { + v = OpenSSL::ASN1::Set([OpenSSL::ASN1::UTF8String("1234")], 17, :EXPLICIT) + attr.value = v + } assert_equal(test_der, attr.to_der) assert_raise(OpenSSL::X509::AttributeError) { attr.oid = "abc123" |