summaryrefslogtreecommitdiff
path: root/ext/openssl/ossl_x509attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/openssl/ossl_x509attr.c')
-rw-r--r--ext/openssl/ossl_x509attr.c81
1 files changed, 49 insertions, 32 deletions
diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c
index 7cd3fe6dfd8..78ce236d96f 100644
--- a/ext/openssl/ossl_x509attr.c
+++ b/ext/openssl/ossl_x509attr.c
@@ -186,22 +186,37 @@ static VALUE
ossl_x509attr_set_value(VALUE self, VALUE value)
{
X509_ATTRIBUTE *attr;
- ASN1_TYPE *a1type;
+ VALUE asn1_value;
+ int i, asn1_tag;
OSSL_Check_Kind(value, cASN1Data);
- if(!(a1type = ossl_asn1_get_asn1type(value)))
- ossl_raise(eASN1Error, "could not get ASN1_TYPE");
- if(ASN1_TYPE_get(a1type) == V_ASN1_SEQUENCE){
- ASN1_TYPE_free(a1type);
- ossl_raise(eASN1Error, "couldn't set SEQUENCE for attribute value.");
- }
+ 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");
+
GetX509Attr(self, attr);
- if(attr->value.set){
- if(attr->single) ASN1_TYPE_free(attr->value.single);
- else sk_ASN1_TYPE_free(attr->value.set);
+ 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;
+ }
+
+ 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);
}
- attr->single = 1;
- attr->value.single = a1type;
return value;
}
@@ -214,32 +229,34 @@ static VALUE
ossl_x509attr_get_value(VALUE self)
{
X509_ATTRIBUTE *attr;
- VALUE str, asn1;
- long length;
+ STACK_OF(ASN1_TYPE) *sk;
+ VALUE str;
+ int i, count, len;
unsigned char *p;
GetX509Attr(self, attr);
- if(attr->value.ptr == NULL) return Qnil;
- if(attr->single){
- length = i2d_ASN1_TYPE(attr->value.single, NULL);
- str = rb_str_new(0, length);
- p = (unsigned char *)RSTRING_PTR(str);
- i2d_ASN1_TYPE(attr->value.single, &p);
- ossl_str_adjust(str, p);
+ /* there is no X509_ATTRIBUTE_get0_set() :( */
+ if (!(sk = sk_ASN1_TYPE_new_null()))
+ ossl_raise(eX509AttrError, "sk_new");
+
+ count = X509_ATTRIBUTE_count(attr);
+ for (i = 0; i < count; i++)
+ sk_ASN1_TYPE_push(sk, X509_ATTRIBUTE_get0_type(attr, i));
+
+ if ((len = i2d_ASN1_SET_ANY(sk, NULL)) <= 0) {
+ sk_ASN1_TYPE_free(sk);
+ ossl_raise(eX509AttrError, NULL);
}
- else{
- length = i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set,
- (unsigned char **) NULL, i2d_ASN1_TYPE,
- V_ASN1_SET, V_ASN1_UNIVERSAL, 0);
- str = rb_str_new(0, length);
- p = (unsigned char *)RSTRING_PTR(str);
- i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set, &p,
- i2d_ASN1_TYPE, V_ASN1_SET, V_ASN1_UNIVERSAL, 0);
- ossl_str_adjust(str, p);
+ str = rb_str_new(0, len);
+ p = (unsigned char *)RSTRING_PTR(str);
+ if (i2d_ASN1_SET_ANY(sk, &p) <= 0) {
+ sk_ASN1_TYPE_free(sk);
+ ossl_raise(eX509AttrError, NULL);
}
- asn1 = rb_funcall(mASN1, rb_intern("decode"), 1, str);
+ ossl_str_adjust(str, p);
+ sk_ASN1_TYPE_free(sk);
- return asn1;
+ return rb_funcall(mASN1, rb_intern("decode"), 1, str);
}
/*