Ruby  2.4.2p198(2017-09-14revision59899)
ossl_x509ext.c
Go to the documentation of this file.
1 /*
2  * 'OpenSSL for Ruby' project
3  * Copyright (C) 2001-2002 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 NewX509Ext(klass) \
13  TypedData_Wrap_Struct((klass), &ossl_x509ext_type, 0)
14 #define SetX509Ext(obj, ext) do { \
15  if (!(ext)) { \
16  ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \
17  } \
18  RTYPEDDATA_DATA(obj) = (ext); \
19 } while (0)
20 #define GetX509Ext(obj, ext) do { \
21  TypedData_Get_Struct((obj), X509_EXTENSION, &ossl_x509ext_type, (ext)); \
22  if (!(ext)) { \
23  ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \
24  } \
25 } while (0)
26 #define SafeGetX509Ext(obj, ext) do { \
27  OSSL_Check_Kind((obj), cX509Ext); \
28  GetX509Ext((obj), (ext)); \
29 } while (0)
30 #define MakeX509ExtFactory(klass, obj, ctx) do { \
31  (obj) = TypedData_Wrap_Struct((klass), &ossl_x509extfactory_type, 0); \
32  if (!((ctx) = OPENSSL_malloc(sizeof(X509V3_CTX)))) \
33  ossl_raise(rb_eRuntimeError, "CTX wasn't allocated!"); \
34  X509V3_set_ctx((ctx), NULL, NULL, NULL, NULL, 0); \
35  RTYPEDDATA_DATA(obj) = (ctx); \
36 } while (0)
37 #define GetX509ExtFactory(obj, ctx) do { \
38  TypedData_Get_Struct((obj), X509V3_CTX, &ossl_x509extfactory_type, (ctx)); \
39  if (!(ctx)) { \
40  ossl_raise(rb_eRuntimeError, "CTX wasn't initialized!"); \
41  } \
42 } while (0)
43 
44 /*
45  * Classes
46  */
50 
51 static void
53 {
54  X509_EXTENSION_free(ptr);
55 }
56 
58  "OpenSSL/X509/EXTENSION",
59  {
61  },
63 };
64 
65 /*
66  * Public
67  */
68 VALUE
69 ossl_x509ext_new(X509_EXTENSION *ext)
70 {
71  X509_EXTENSION *new;
72  VALUE obj;
73 
74  obj = NewX509Ext(cX509Ext);
75  if (!ext) {
76  new = X509_EXTENSION_new();
77  } else {
78  new = X509_EXTENSION_dup(ext);
79  }
80  if (!new) {
82  }
83  SetX509Ext(obj, new);
84 
85  return obj;
86 }
87 
88 X509_EXTENSION *
90 {
91  X509_EXTENSION *ext;
92 
93  SafeGetX509Ext(obj, ext);
94 
95  return ext;
96 }
97 
98 /*
99  * Private
100  */
101 /*
102  * Ext factory
103  */
104 static void
106 {
107  OPENSSL_free(ctx);
108 }
109 
111  "OpenSSL/X509/EXTENSION/Factory",
112  {
114  },
116 };
117 
118 static VALUE
120 {
121  X509V3_CTX *ctx;
122  VALUE obj;
123 
124  MakeX509ExtFactory(klass, obj, ctx);
125  rb_iv_set(obj, "@config", Qnil);
126 
127  return obj;
128 }
129 
130 static VALUE
132 {
133  X509V3_CTX *ctx;
134 
135  GetX509ExtFactory(self, ctx);
136  rb_iv_set(self, "@issuer_certificate", cert);
137  ctx->issuer_cert = GetX509CertPtr(cert); /* NO DUP NEEDED */
138 
139  return cert;
140 }
141 
142 static VALUE
144 {
145  X509V3_CTX *ctx;
146 
147  GetX509ExtFactory(self, ctx);
148  rb_iv_set(self, "@subject_certificate", cert);
149  ctx->subject_cert = GetX509CertPtr(cert); /* NO DUP NEEDED */
150 
151  return cert;
152 }
153 
154 static VALUE
156 {
157  X509V3_CTX *ctx;
158 
159  GetX509ExtFactory(self, ctx);
160  rb_iv_set(self, "@subject_request", req);
161  ctx->subject_req = GetX509ReqPtr(req); /* NO DUP NEEDED */
162 
163  return req;
164 }
165 
166 static VALUE
168 {
169  X509V3_CTX *ctx;
170 
171  GetX509ExtFactory(self, ctx);
172  rb_iv_set(self, "@crl", crl);
173  ctx->crl = GetX509CRLPtr(crl); /* NO DUP NEEDED */
174 
175  return crl;
176 }
177 
178 static VALUE
180 {
181  /*X509V3_CTX *ctx;*/
182  VALUE issuer_cert, subject_cert, subject_req, crl;
183 
184  /*GetX509ExtFactory(self, ctx);*/
185 
186  rb_scan_args(argc, argv, "04",
187  &issuer_cert, &subject_cert, &subject_req, &crl);
188  if (!NIL_P(issuer_cert))
189  ossl_x509extfactory_set_issuer_cert(self, issuer_cert);
190  if (!NIL_P(subject_cert))
191  ossl_x509extfactory_set_subject_cert(self, subject_cert);
192  if (!NIL_P(subject_req))
193  ossl_x509extfactory_set_subject_req(self, subject_req);
194  if (!NIL_P(crl))
195  ossl_x509extfactory_set_crl(self, crl);
196 
197  return self;
198 }
199 
200 /*
201  * call-seq:
202  * ef.create_ext(ln_or_sn, "value", critical = false) -> X509::Extension
203  * ef.create_ext(ln_or_sn, "critical,value") -> X509::Extension
204  *
205  * Creates a new X509::Extension with passed values. See also x509v3_config(5).
206  */
207 static VALUE
209 {
210  X509V3_CTX *ctx;
211  X509_EXTENSION *ext;
212  VALUE oid, value, critical, valstr, obj;
213  int nid;
214  VALUE rconf;
215  CONF *conf;
216 
217  rb_scan_args(argc, argv, "21", &oid, &value, &critical);
218  StringValueCStr(oid);
219  StringValue(value);
220  if(NIL_P(critical)) critical = Qfalse;
221 
222  nid = OBJ_ln2nid(RSTRING_PTR(oid));
223  if(!nid) nid = OBJ_sn2nid(RSTRING_PTR(oid));
224  if(!nid) ossl_raise(eX509ExtError, "unknown OID `%"PRIsVALUE"'", oid);
225 
226  valstr = rb_str_new2(RTEST(critical) ? "critical," : "");
227  rb_str_append(valstr, value);
228  StringValueCStr(valstr);
229 
230  GetX509ExtFactory(self, ctx);
231  obj = NewX509Ext(cX509Ext);
232  rconf = rb_iv_get(self, "@config");
233  conf = NIL_P(rconf) ? NULL : DupConfigPtr(rconf);
234  X509V3_set_nconf(ctx, conf);
235  ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr));
236  X509V3_set_ctx_nodb(ctx);
237  NCONF_free(conf);
238  if (!ext){
239  ossl_raise(eX509ExtError, "%"PRIsVALUE" = %"PRIsVALUE, oid, valstr);
240  }
241  SetX509Ext(obj, ext);
242 
243  return obj;
244 }
245 
246 /*
247  * Ext
248  */
249 static VALUE
251 {
252  X509_EXTENSION *ext;
253  VALUE obj;
254 
255  obj = NewX509Ext(klass);
256  if(!(ext = X509_EXTENSION_new())){
258  }
259  SetX509Ext(obj, ext);
260 
261  return obj;
262 }
263 
264 /*
265  * call-seq:
266  * OpenSSL::X509::Extension.new asn1
267  * OpenSSL::X509::Extension.new name, value
268  * OpenSSL::X509::Extension.new name, value, critical
269  *
270  * Creates an X509 extension.
271  *
272  * The extension may be created from +asn1+ data or from an extension +name+
273  * and +value+. The +name+ may be either an OID or an extension name. If
274  * +critical+ is true the extension is marked critical.
275  */
276 static VALUE
278 {
279  VALUE oid, value, critical;
280  const unsigned char *p;
281  X509_EXTENSION *ext, *x;
282 
283  GetX509Ext(self, ext);
284  if(rb_scan_args(argc, argv, "12", &oid, &value, &critical) == 1){
285  oid = ossl_to_der_if_possible(oid);
286  StringValue(oid);
287  p = (unsigned char *)RSTRING_PTR(oid);
288  x = d2i_X509_EXTENSION(&ext, &p, RSTRING_LEN(oid));
289  DATA_PTR(self) = ext;
290  if(!x)
292  return self;
293  }
294  rb_funcall(self, rb_intern("oid="), 1, oid);
295  rb_funcall(self, rb_intern("value="), 1, value);
296  if(argc > 2) rb_funcall(self, rb_intern("critical="), 1, critical);
297 
298  return self;
299 }
300 
301 static VALUE
303 {
304  X509_EXTENSION *ext, *ext_other, *ext_new;
305 
306  rb_check_frozen(self);
307  GetX509Ext(self, ext);
308  SafeGetX509Ext(other, ext_other);
309 
310  ext_new = X509_EXTENSION_dup(ext_other);
311  if (!ext_new)
312  ossl_raise(eX509ExtError, "X509_EXTENSION_dup");
313 
314  SetX509Ext(self, ext_new);
315  X509_EXTENSION_free(ext);
316 
317  return self;
318 }
319 
320 static VALUE
322 {
323  X509_EXTENSION *ext;
324  ASN1_OBJECT *obj;
325 
326  GetX509Ext(self, ext);
327  obj = OBJ_txt2obj(StringValueCStr(oid), 0);
328  if (!obj)
329  ossl_raise(eX509ExtError, "OBJ_txt2obj");
330  if (!X509_EXTENSION_set_object(ext, obj)) {
331  ASN1_OBJECT_free(obj);
332  ossl_raise(eX509ExtError, "X509_EXTENSION_set_object");
333  }
334  ASN1_OBJECT_free(obj);
335 
336  return oid;
337 }
338 
339 static VALUE
341 {
342  X509_EXTENSION *ext;
343  ASN1_OCTET_STRING *asn1s;
344 
345  GetX509Ext(self, ext);
346  data = ossl_to_der_if_possible(data);
347  StringValue(data);
348  asn1s = X509_EXTENSION_get_data(ext);
349 
350  if (!ASN1_OCTET_STRING_set(asn1s, (unsigned char *)RSTRING_PTR(data),
351  RSTRING_LENINT(data))) {
352  ossl_raise(eX509ExtError, "ASN1_OCTET_STRING_set");
353  }
354 
355  return data;
356 }
357 
358 static VALUE
360 {
361  X509_EXTENSION *ext;
362 
363  GetX509Ext(self, ext);
364  X509_EXTENSION_set_critical(ext, RTEST(flag) ? 1 : 0);
365 
366  return flag;
367 }
368 
369 static VALUE
371 {
372  X509_EXTENSION *ext;
373  ASN1_OBJECT *extobj;
374  BIO *out;
375  VALUE ret;
376  int nid;
377 
378  GetX509Ext(obj, ext);
379  extobj = X509_EXTENSION_get_object(ext);
380  if ((nid = OBJ_obj2nid(extobj)) != NID_undef)
381  ret = rb_str_new2(OBJ_nid2sn(nid));
382  else{
383  if (!(out = BIO_new(BIO_s_mem())))
385  i2a_ASN1_OBJECT(out, extobj);
386  ret = ossl_membio2str(out);
387  }
388 
389  return ret;
390 }
391 
392 static VALUE
394 {
395  X509_EXTENSION *ext;
396  BIO *out;
397  VALUE ret;
398 
399  GetX509Ext(obj, ext);
400  if (!(out = BIO_new(BIO_s_mem())))
402  if (!X509V3_EXT_print(out, ext, 0, 0))
403  ASN1_STRING_print(out, (ASN1_STRING *)X509_EXTENSION_get_data(ext));
404  ret = ossl_membio2str(out);
405 
406  return ret;
407 }
408 
409 static VALUE
411 {
412  X509_EXTENSION *ext;
413 
414  GetX509Ext(obj, ext);
415  return X509_EXTENSION_get_critical(ext) ? Qtrue : Qfalse;
416 }
417 
418 static VALUE
420 {
421  X509_EXTENSION *ext;
422  unsigned char *p;
423  long len;
424  VALUE str;
425 
426  GetX509Ext(obj, ext);
427  if((len = i2d_X509_EXTENSION(ext, NULL)) <= 0)
429  str = rb_str_new(0, len);
430  p = (unsigned char *)RSTRING_PTR(str);
431  if(i2d_X509_EXTENSION(ext, &p) < 0)
433  ossl_str_adjust(str, p);
434 
435  return str;
436 }
437 
438 /*
439  * INIT
440  */
441 void
443 {
444 #if 0
445  mOSSL = rb_define_module("OpenSSL");
448 #endif
449 
450  eX509ExtError = rb_define_class_under(mX509, "ExtensionError", eOSSLError);
451 
452  cX509ExtFactory = rb_define_class_under(mX509, "ExtensionFactory", rb_cObject);
453 
456 
457  rb_attr(cX509ExtFactory, rb_intern("issuer_certificate"), 1, 0, Qfalse);
458  rb_attr(cX509ExtFactory, rb_intern("subject_certificate"), 1, 0, Qfalse);
459  rb_attr(cX509ExtFactory, rb_intern("subject_request"), 1, 0, Qfalse);
460  rb_attr(cX509ExtFactory, rb_intern("crl"), 1, 0, Qfalse);
461  rb_attr(cX509ExtFactory, rb_intern("config"), 1, 1, Qfalse);
462 
468 
480 }
VALUE rb_eStandardError
Definition: error.c:760
VALUE mOSSL
Definition: ossl.c:213
static VALUE ossl_x509ext_get_value(VALUE obj)
Definition: ossl_x509ext.c:393
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1145
static VALUE ossl_x509extfactory_set_subject_req(VALUE self, VALUE req)
Definition: ossl_x509ext.c:155
static const rb_data_type_t ossl_x509ext_type
Definition: ossl_x509ext.c:57
#define SafeGetX509Ext(obj, ext)
Definition: ossl_x509ext.c:26
#define Qtrue
Definition: ruby.h:437
#define ossl_str_adjust(str, p)
Definition: ossl.h:82
static VALUE ossl_x509extfactory_alloc(VALUE klass)
Definition: ossl_x509ext.c:119
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:821
VALUE rb_iv_set(VALUE, const char *, VALUE)
Definition: variable.c:3138
VALUE rb_iv_get(VALUE, const char *)
Definition: variable.c:3130
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:693
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
#define DATA_PTR(dta)
Definition: ruby.h:1113
VALUE ossl_membio2str(BIO *bio)
Definition: ossl_bio.c:47
VALUE cX509Ext
Definition: ossl_x509ext.c:47
#define NewX509Ext(klass)
Definition: ossl_x509ext.c:12
#define GetX509ExtFactory(obj, ctx)
Definition: ossl_x509ext.c:37
static VALUE ossl_x509ext_get_critical(VALUE obj)
Definition: ossl_x509ext.c:410
static VALUE ossl_x509ext_initialize_copy(VALUE self, VALUE other)
Definition: ossl_x509ext.c:302
static VALUE ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self)
Definition: ossl_x509ext.c:208
static void ossl_x509extfactory_free(void *ctx)
Definition: ossl_x509ext.c:105
#define rb_define_copy_func(klass, func)
Definition: ruby_missing.h:13
X509 * GetX509CertPtr(VALUE)
void Init_ossl_x509ext(void)
Definition: ossl_x509ext.c:442
VALUE ossl_to_der_if_possible(VALUE obj)
Definition: ossl.c:237
X509_EXTENSION * GetX509ExtPtr(VALUE obj)
Definition: ossl_x509ext.c:89
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1872
void rb_attr(VALUE, ID, int, int, int)
Definition: vm_method.c:1138
static VALUE ossl_x509ext_to_der(VALUE obj)
Definition: ossl_x509ext.c:419
#define NIL_P(v)
Definition: ruby.h:451
VALUE ossl_x509ext_new(X509_EXTENSION *ext)
Definition: ossl_x509ext.c:69
VALUE eOSSLError
Definition: ossl.c:218
int argc
Definition: ruby.c:183
#define Qfalse
Definition: ruby.h:436
#define SetX509Ext(obj, ext)
Definition: ossl_x509ext.c:14
#define rb_str_new2
Definition: intern.h:857
VALUE cX509ExtFactory
Definition: ossl_x509ext.c:48
static VALUE ossl_x509ext_initialize(int argc, VALUE *argv, VALUE self)
Definition: ossl_x509ext.c:277
static VALUE ossl_x509extfactory_set_issuer_cert(VALUE self, VALUE cert)
Definition: ossl_x509ext.c:131
#define RSTRING_LEN(str)
Definition: ruby.h:978
CONF * DupConfigPtr(VALUE obj)
Definition: ossl_config.c:35
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1919
#define PRIsVALUE
Definition: ruby.h:135
#define Qnil
Definition: ruby.h:438
unsigned long VALUE
Definition: ruby.h:85
VALUE mX509
Definition: ossl_x509.c:12
static VALUE ossl_x509extfactory_set_subject_cert(VALUE self, VALUE cert)
Definition: ossl_x509ext.c:143
VALUE eX509ExtError
Definition: ossl_x509ext.c:49
static VALUE ossl_x509ext_get_oid(VALUE obj)
Definition: ossl_x509ext.c:370
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 MakeX509ExtFactory(klass, obj, ctx)
Definition: ossl_x509ext.c:30
static VALUE ossl_x509extfactory_initialize(int argc, VALUE *argv, VALUE self)
Definition: ossl_x509ext.c:179
static VALUE ossl_x509ext_alloc(VALUE klass)
Definition: ossl_x509ext.c:250
static VALUE ossl_x509ext_set_value(VALUE self, VALUE data)
Definition: ossl_x509ext.c:340
static void ossl_x509ext_free(void *ptr)
Definition: ossl_x509ext.c:52
#define RTEST(v)
Definition: ruby.h:450
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:278
static VALUE ossl_x509extfactory_set_crl(VALUE self, VALUE crl)
Definition: ossl_x509ext.c:167
int nid
#define RSTRING_LENINT(str)
Definition: ruby.h:990
#define rb_check_frozen(obj)
Definition: intern.h:276
VALUE rb_define_module(const char *name)
Definition: class.c:768
X509_CRL * GetX509CRLPtr(VALUE)
Definition: ossl_x509crl.c:55
#define rb_intern(str)
static VALUE ossl_x509ext_set_oid(VALUE self, VALUE oid)
Definition: ossl_x509ext.c:321
#define NULL
Definition: _sdbm.c:102
X509_REQ * GetX509ReqPtr(VALUE)
Definition: ossl_x509req.c:75
static VALUE ossl_x509ext_set_critical(VALUE self, VALUE flag)
Definition: ossl_x509ext.c:359
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2818
static const rb_data_type_t ossl_x509extfactory_type
Definition: ossl_x509ext.c:110
#define GetX509Ext(obj, ext)
Definition: ossl_x509ext.c:20
char ** argv
Definition: ruby.c:184
#define StringValue(v)
Definition: ruby.h:569
VALUE rb_str_new(const char *, long)
Definition: string.c:736