summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKazuki Yamaguchi <[email protected]>2024-06-17 16:26:58 +0900
committergit <[email protected]>2024-07-24 16:50:01 +0000
commita1cf39bd366f843bc9fd1534aa8e7d301fc77252 (patch)
tree8a647bccdaac8867afd6dd4b16cf272e202be243
parent575fe63e20dff83c684a93f5f76d0c27bbc250df (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.c47
-rw-r--r--test/openssl/test_x509attr.rb4
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"