Ruby  2.4.2p198(2017-09-14revision59899)
ossl_x509attr.c
Go to the documentation of this file.
1 /*
2  * 'OpenSSL for Ruby' project
3  * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>
4  * All rights reserved.
5  */
6 /*
7  * This program is licensed under the same licence as Ruby.
8  * (See the file 'LICENCE'.)
9  */
10 #include "ossl.h"
11 
12 #define NewX509Attr(klass) \
13  TypedData_Wrap_Struct((klass), &ossl_x509attr_type, 0)
14 #define SetX509Attr(obj, attr) do { \
15  if (!(attr)) { \
16  ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \
17  } \
18  RTYPEDDATA_DATA(obj) = (attr); \
19 } while (0)
20 #define GetX509Attr(obj, attr) do { \
21  TypedData_Get_Struct((obj), X509_ATTRIBUTE, &ossl_x509attr_type, (attr)); \
22  if (!(attr)) { \
23  ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \
24  } \
25 } while (0)
26 #define SafeGetX509Attr(obj, attr) do { \
27  OSSL_Check_Kind((obj), cX509Attr); \
28  GetX509Attr((obj), (attr)); \
29 } while (0)
30 
31 /*
32  * Classes
33  */
36 
37 static void
39 {
40  X509_ATTRIBUTE_free(ptr);
41 }
42 
44  "OpenSSL/X509/ATTRIBUTE",
45  {
47  },
49 };
50 
51 /*
52  * Public
53  */
54 VALUE
55 ossl_x509attr_new(X509_ATTRIBUTE *attr)
56 {
57  X509_ATTRIBUTE *new;
58  VALUE obj;
59 
60  obj = NewX509Attr(cX509Attr);
61  if (!attr) {
62  new = X509_ATTRIBUTE_new();
63  } else {
64  new = X509_ATTRIBUTE_dup(attr);
65  }
66  if (!new) {
68  }
69  SetX509Attr(obj, new);
70 
71  return obj;
72 }
73 
74 X509_ATTRIBUTE *
76 {
77  X509_ATTRIBUTE *attr;
78 
79  SafeGetX509Attr(obj, attr);
80 
81  return attr;
82 }
83 
84 /*
85  * Private
86  */
87 static VALUE
89 {
90  X509_ATTRIBUTE *attr;
91  VALUE obj;
92 
93  obj = NewX509Attr(klass);
94  if (!(attr = X509_ATTRIBUTE_new()))
96  SetX509Attr(obj, attr);
97 
98  return obj;
99 }
100 
101 /*
102  * call-seq:
103  * Attribute.new(oid [, value]) => attr
104  */
105 static VALUE
107 {
108  VALUE oid, value;
109  X509_ATTRIBUTE *attr, *x;
110  const unsigned char *p;
111 
112  GetX509Attr(self, attr);
113  if(rb_scan_args(argc, argv, "11", &oid, &value) == 1){
114  oid = ossl_to_der_if_possible(oid);
115  StringValue(oid);
116  p = (unsigned char *)RSTRING_PTR(oid);
117  x = d2i_X509_ATTRIBUTE(&attr, &p, RSTRING_LEN(oid));
118  DATA_PTR(self) = attr;
119  if(!x){
121  }
122  return self;
123  }
124  rb_funcall(self, rb_intern("oid="), 1, oid);
125  rb_funcall(self, rb_intern("value="), 1, value);
126 
127  return self;
128 }
129 
130 static VALUE
132 {
133  X509_ATTRIBUTE *attr, *attr_other, *attr_new;
134 
135  rb_check_frozen(self);
136  GetX509Attr(self, attr);
137  SafeGetX509Attr(other, attr_other);
138 
139  attr_new = X509_ATTRIBUTE_dup(attr_other);
140  if (!attr_new)
141  ossl_raise(eX509AttrError, "X509_ATTRIBUTE_dup");
142 
143  SetX509Attr(self, attr_new);
144  X509_ATTRIBUTE_free(attr);
145 
146  return self;
147 }
148 
149 /*
150  * call-seq:
151  * attr.oid = string => string
152  */
153 static VALUE
155 {
156  X509_ATTRIBUTE *attr;
157  ASN1_OBJECT *obj;
158  char *s;
159 
160  GetX509Attr(self, attr);
161  s = StringValueCStr(oid);
162  obj = OBJ_txt2obj(s, 0);
163  if(!obj) ossl_raise(eX509AttrError, NULL);
164  if (!X509_ATTRIBUTE_set1_object(attr, obj)) {
165  ASN1_OBJECT_free(obj);
166  ossl_raise(eX509AttrError, "X509_ATTRIBUTE_set1_object");
167  }
168  ASN1_OBJECT_free(obj);
169 
170  return oid;
171 }
172 
173 /*
174  * call-seq:
175  * attr.oid => string
176  */
177 static VALUE
179 {
180  X509_ATTRIBUTE *attr;
181  ASN1_OBJECT *oid;
182  BIO *out;
183  VALUE ret;
184  int nid;
185 
186  GetX509Attr(self, attr);
187  oid = X509_ATTRIBUTE_get0_object(attr);
188  if ((nid = OBJ_obj2nid(oid)) != NID_undef)
189  ret = rb_str_new2(OBJ_nid2sn(nid));
190  else{
191  if (!(out = BIO_new(BIO_s_mem())))
193  i2a_ASN1_OBJECT(out, oid);
194  ret = ossl_membio2str(out);
195  }
196 
197  return ret;
198 }
199 
200 /*
201  * call-seq:
202  * attr.value = asn1 => asn1
203  */
204 static VALUE
206 {
207  X509_ATTRIBUTE *attr;
208  VALUE asn1_value;
209  int i, asn1_tag;
210 
211  OSSL_Check_Kind(value, cASN1Data);
212  asn1_tag = NUM2INT(rb_attr_get(value, rb_intern("@tag")));
213  asn1_value = rb_attr_get(value, rb_intern("@value"));
214  if (asn1_tag != V_ASN1_SET)
215  ossl_raise(eASN1Error, "argument must be ASN1::Set");
216  if (!RB_TYPE_P(asn1_value, T_ARRAY))
217  ossl_raise(eASN1Error, "ASN1::Set has non-array value");
218 
219  GetX509Attr(self, attr);
220  if (X509_ATTRIBUTE_count(attr)) { /* populated, reset first */
221  ASN1_OBJECT *obj = X509_ATTRIBUTE_get0_object(attr);
222  X509_ATTRIBUTE *new_attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, 0, NULL, -1);
223  if (!new_attr)
225  SetX509Attr(self, new_attr);
226  X509_ATTRIBUTE_free(attr);
227  attr = new_attr;
228  }
229 
230  for (i = 0; i < RARRAY_LEN(asn1_value); i++) {
231  ASN1_TYPE *a1type = ossl_asn1_get_asn1type(RARRAY_AREF(asn1_value, i));
232  if (!X509_ATTRIBUTE_set1_data(attr, ASN1_TYPE_get(a1type),
233  a1type->value.ptr, -1)) {
234  ASN1_TYPE_free(a1type);
236  }
237  ASN1_TYPE_free(a1type);
238  }
239 
240  return value;
241 }
242 
243 /*
244  * call-seq:
245  * attr.value => asn1
246  */
247 static VALUE
249 {
250  X509_ATTRIBUTE *attr;
251  STACK_OF(ASN1_TYPE) *sk;
252  VALUE str;
253  int i, count, len;
254  unsigned char *p;
255 
256  GetX509Attr(self, attr);
257  /* there is no X509_ATTRIBUTE_get0_set() :( */
258  if (!(sk = sk_ASN1_TYPE_new_null()))
259  ossl_raise(eX509AttrError, "sk_new");
260 
261  count = X509_ATTRIBUTE_count(attr);
262  for (i = 0; i < count; i++)
263  sk_ASN1_TYPE_push(sk, X509_ATTRIBUTE_get0_type(attr, i));
264 
265  if ((len = i2d_ASN1_SET_ANY(sk, NULL)) <= 0) {
266  sk_ASN1_TYPE_free(sk);
268  }
269  str = rb_str_new(0, len);
270  p = (unsigned char *)RSTRING_PTR(str);
271  if (i2d_ASN1_SET_ANY(sk, &p) <= 0) {
272  sk_ASN1_TYPE_free(sk);
274  }
275  ossl_str_adjust(str, p);
276  sk_ASN1_TYPE_free(sk);
277 
278  return rb_funcall(mASN1, rb_intern("decode"), 1, str);
279 }
280 
281 /*
282  * call-seq:
283  * attr.to_der => string
284  */
285 static VALUE
287 {
288  X509_ATTRIBUTE *attr;
289  VALUE str;
290  int len;
291  unsigned char *p;
292 
293  GetX509Attr(self, attr);
294  if((len = i2d_X509_ATTRIBUTE(attr, NULL)) <= 0)
296  str = rb_str_new(0, len);
297  p = (unsigned char *)RSTRING_PTR(str);
298  if(i2d_X509_ATTRIBUTE(attr, &p) <= 0)
300  ossl_str_adjust(str, p);
301 
302  return str;
303 }
304 
305 /*
306  * X509_ATTRIBUTE init
307  */
308 void
310 {
311 #if 0
312  mOSSL = rb_define_module("OpenSSL");
315 #endif
316 
318 
328 }
static VALUE ossl_x509attr_to_der(VALUE self)
static VALUE ossl_x509attr_set_oid(VALUE self, VALUE oid)
VALUE rb_eStandardError
Definition: error.c:760
VALUE mOSSL
Definition: ossl.c:213
VALUE cASN1Data
Definition: ossl_asn1.c:169
#define RARRAY_LEN(a)
Definition: ruby.h:1026
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1145
static VALUE ossl_x509attr_initialize_copy(VALUE self, VALUE other)
static VALUE ossl_x509attr_get_oid(VALUE self)
#define NUM2INT(x)
Definition: ruby.h:684
int count
Definition: encoding.c:56
void Init_ossl_x509attr(void)
#define NewX509Attr(klass)
Definition: ossl_x509attr.c:12
static VALUE ossl_x509attr_alloc(VALUE klass)
Definition: ossl_x509attr.c:88
#define ossl_str_adjust(str, p)
Definition: ossl.h:82
VALUE mASN1
Definition: ossl_asn1.c:166
static void ossl_x509attr_free(void *ptr)
Definition: ossl_x509attr.c:38
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:821
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:693
VALUE eX509AttrError
Definition: ossl_x509attr.c:35
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
STACK_OF(X509) *ossl_x509_ary2sk0(VALUE)
#define DATA_PTR(dta)
Definition: ruby.h:1113
#define T_ARRAY
Definition: ruby.h:498
VALUE ossl_membio2str(BIO *bio)
Definition: ossl_bio.c:47
static const rb_data_type_t ossl_x509attr_type
Definition: ossl_x509attr.c:43
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
#define rb_define_copy_func(klass, func)
Definition: ruby_missing.h:13
VALUE ossl_to_der_if_possible(VALUE obj)
Definition: ossl.c:237
VALUE ossl_x509attr_new(X509_ATTRIBUTE *attr)
Definition: ossl_x509attr.c:55
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1872
#define SetX509Attr(obj, attr)
Definition: ossl_x509attr.c:14
VALUE eOSSLError
Definition: ossl.c:218
X509_ATTRIBUTE * GetX509AttrPtr(VALUE obj)
Definition: ossl_x509attr.c:75
int argc
Definition: ruby.c:183
#define rb_str_new2
Definition: intern.h:857
static VALUE ossl_x509attr_set_value(VALUE self, VALUE value)
ASN1_TYPE * ossl_asn1_get_asn1type(VALUE obj)
Definition: ossl_asn1.c:514
#define RSTRING_LEN(str)
Definition: ruby.h:978
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1919
unsigned long VALUE
Definition: ruby.h:85
VALUE cX509Attr
Definition: ossl_x509attr.c:34
VALUE mX509
Definition: ossl_x509.c:12
register unsigned int len
Definition: zonetab.h:51
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:790
#define StringValueCStr(v)
Definition: ruby.h:571
#define RSTRING_PTR(str)
Definition: ruby.h:982
#define RARRAY_AREF(a, i)
Definition: ruby.h:1040
#define OSSL_Check_Kind(obj, klass)
Definition: ossl.h:52
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:278
static VALUE ossl_x509attr_get_value(VALUE self)
int nid
#define rb_check_frozen(obj)
Definition: intern.h:276
static VALUE ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self)
VALUE rb_define_module(const char *name)
Definition: class.c:768
#define rb_intern(str)
#define NULL
Definition: _sdbm.c:102
#define i2d_ASN1_SET_ANY(sk, x)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
#define SafeGetX509Attr(obj, attr)
Definition: ossl_x509attr.c:26
VALUE eASN1Error
Definition: ossl_asn1.c:167
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1273
char ** argv
Definition: ruby.c:184
#define StringValue(v)
Definition: ruby.h:569
VALUE rb_str_new(const char *, long)
Definition: string.c:736
#define GetX509Attr(obj, attr)
Definition: ossl_x509attr.c:20