Ruby  2.0.0p645(2015-04-13revision50299)
ossl_x509ext.c
Go to the documentation of this file.
1 /*
2  * $Id: ossl_x509ext.c 31166 2011-03-24 07:29:21Z naruse $
3  * 'OpenSSL for Ruby' project
4  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5  * All rights reserved.
6  */
7 /*
8  * This program is licenced under the same licence as Ruby.
9  * (See the file 'LICENCE'.)
10  */
11 #include "ossl.h"
12 
13 #define WrapX509Ext(klass, obj, ext) do { \
14  if (!(ext)) { \
15  ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \
16  } \
17  (obj) = Data_Wrap_Struct((klass), 0, X509_EXTENSION_free, (ext)); \
18 } while (0)
19 #define GetX509Ext(obj, ext) do { \
20  Data_Get_Struct((obj), X509_EXTENSION, (ext)); \
21  if (!(ext)) { \
22  ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \
23  } \
24 } while (0)
25 #define SafeGetX509Ext(obj, ext) do { \
26  OSSL_Check_Kind((obj), cX509Ext); \
27  GetX509Ext((obj), (ext)); \
28 } while (0)
29 #define MakeX509ExtFactory(klass, obj, ctx) do { \
30  if (!((ctx) = OPENSSL_malloc(sizeof(X509V3_CTX)))) \
31  ossl_raise(rb_eRuntimeError, "CTX wasn't allocated!"); \
32  X509V3_set_ctx((ctx), NULL, NULL, NULL, NULL, 0); \
33  (obj) = Data_Wrap_Struct((klass), 0, ossl_x509extfactory_free, (ctx)); \
34 } while (0)
35 #define GetX509ExtFactory(obj, ctx) do { \
36  Data_Get_Struct((obj), X509V3_CTX, (ctx)); \
37  if (!(ctx)) { \
38  ossl_raise(rb_eRuntimeError, "CTX wasn't initialized!"); \
39  } \
40 } while (0)
41 
42 /*
43  * Classes
44  */
48 
49 /*
50  * Public
51  */
52 VALUE
53 ossl_x509ext_new(X509_EXTENSION *ext)
54 {
55  X509_EXTENSION *new;
56  VALUE obj;
57 
58  if (!ext) {
59  new = X509_EXTENSION_new();
60  } else {
61  new = X509_EXTENSION_dup(ext);
62  }
63  if (!new) {
65  }
66  WrapX509Ext(cX509Ext, obj, new);
67 
68  return obj;
69 }
70 
71 X509_EXTENSION *
73 {
74  X509_EXTENSION *ext;
75 
76  SafeGetX509Ext(obj, ext);
77 
78  return ext;
79 }
80 
81 X509_EXTENSION *
83 {
84  X509_EXTENSION *ext, *new;
85 
86  SafeGetX509Ext(obj, ext);
87  if (!(new = X509_EXTENSION_dup(ext))) {
89  }
90 
91  return new;
92 }
93 
94 /*
95  * Private
96  */
97 /*
98  * Ext factory
99  */
100 static void
101 ossl_x509extfactory_free(X509V3_CTX *ctx)
102 {
103  OPENSSL_free(ctx);
104 }
105 
106 static VALUE
108 {
109  X509V3_CTX *ctx;
110  VALUE obj;
111 
112  MakeX509ExtFactory(klass, obj, ctx);
113  rb_iv_set(obj, "@config", Qnil);
114 
115  return obj;
116 }
117 
118 static VALUE
120 {
121  X509V3_CTX *ctx;
122 
123  GetX509ExtFactory(self, ctx);
124  rb_iv_set(self, "@issuer_certificate", cert);
125  ctx->issuer_cert = GetX509CertPtr(cert); /* NO DUP NEEDED */
126 
127  return cert;
128 }
129 
130 static VALUE
132 {
133  X509V3_CTX *ctx;
134 
135  GetX509ExtFactory(self, ctx);
136  rb_iv_set(self, "@subject_certificate", cert);
137  ctx->subject_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_request", req);
149  ctx->subject_req = GetX509ReqPtr(req); /* NO DUP NEEDED */
150 
151  return req;
152 }
153 
154 static VALUE
156 {
157  X509V3_CTX *ctx;
158 
159  GetX509ExtFactory(self, ctx);
160  rb_iv_set(self, "@crl", crl);
161  ctx->crl = GetX509CRLPtr(crl); /* NO DUP NEEDED */
162 
163  return crl;
164 }
165 
166 #ifdef HAVE_X509V3_SET_NCONF
167 static VALUE
169 {
170  X509V3_CTX *ctx;
171  CONF *conf;
172 
173  GetX509ExtFactory(self, ctx);
174  rb_iv_set(self, "@config", config);
175  conf = GetConfigPtr(config); /* NO DUP NEEDED */
176  X509V3_set_nconf(ctx, conf);
177 
178  return config;
179 }
180 #else
181 #define ossl_x509extfactory_set_config rb_f_notimplement
182 #endif
183 
184 static VALUE
186 {
187  /*X509V3_CTX *ctx;*/
188  VALUE issuer_cert, subject_cert, subject_req, crl;
189 
190  /*GetX509ExtFactory(self, ctx);*/
191 
192  rb_scan_args(argc, argv, "04",
193  &issuer_cert, &subject_cert, &subject_req, &crl);
194  if (!NIL_P(issuer_cert))
195  ossl_x509extfactory_set_issuer_cert(self, issuer_cert);
196  if (!NIL_P(subject_cert))
197  ossl_x509extfactory_set_subject_cert(self, subject_cert);
198  if (!NIL_P(subject_req))
199  ossl_x509extfactory_set_subject_req(self, subject_req);
200  if (!NIL_P(crl))
201  ossl_x509extfactory_set_crl(self, crl);
202 
203  return self;
204 }
205 
206 /*
207  * Array to X509_EXTENSION
208  * Structure:
209  * ["ln", "value", bool_critical] or
210  * ["sn", "value", bool_critical] or
211  * ["ln", "critical,value"] or the same for sn
212  * ["ln", "value"] => not critical
213  */
214 static VALUE
216 {
217  X509V3_CTX *ctx;
218  X509_EXTENSION *ext;
219  VALUE oid, value, critical, valstr, obj;
220  int nid;
221 #ifdef HAVE_X509V3_EXT_NCONF_NID
222  VALUE rconf;
223  CONF *conf;
224 #else
225  static LHASH *empty_lhash;
226 #endif
227 
228  rb_scan_args(argc, argv, "21", &oid, &value, &critical);
229  StringValue(oid);
230  StringValue(value);
231  if(NIL_P(critical)) critical = Qfalse;
232 
233  nid = OBJ_ln2nid(RSTRING_PTR(oid));
234  if(!nid) nid = OBJ_sn2nid(RSTRING_PTR(oid));
235  if(!nid) ossl_raise(eX509ExtError, "unknown OID `%s'", RSTRING_PTR(oid));
236  valstr = rb_str_new2(RTEST(critical) ? "critical," : "");
237  rb_str_append(valstr, value);
238  GetX509ExtFactory(self, ctx);
239 #ifdef HAVE_X509V3_EXT_NCONF_NID
240  rconf = rb_iv_get(self, "@config");
241  conf = NIL_P(rconf) ? NULL : GetConfigPtr(rconf);
242  ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr));
243 #else
244  if (!empty_lhash) empty_lhash = lh_new(NULL, NULL);
245  ext = X509V3_EXT_conf_nid(empty_lhash, ctx, nid, RSTRING_PTR(valstr));
246 #endif
247  if (!ext){
248  ossl_raise(eX509ExtError, "%s = %s",
249  RSTRING_PTR(oid), RSTRING_PTR(value));
250  }
251  WrapX509Ext(cX509Ext, obj, ext);
252 
253  return obj;
254 }
255 
256 /*
257  * Ext
258  */
259 static VALUE
261 {
262  X509_EXTENSION *ext;
263  VALUE obj;
264 
265  if(!(ext = X509_EXTENSION_new())){
267  }
268  WrapX509Ext(klass, obj, ext);
269 
270  return obj;
271 }
272 
273 /*
274  * call-seq:
275  * OpenSSL::X509::Extension.new asn1
276  * OpenSSL::X509::Extension.new name, value
277  * OpenSSL::X509::Extension.new name, value, critical
278  *
279  * Creates an X509 extension.
280  *
281  * The extension may be created from +asn1+ data or from an extension +name+
282  * and +value+. The +name+ may be either an OID or an extension name. If
283  * +critical+ is true the extension is marked critical.
284  */
285 static VALUE
287 {
288  VALUE oid, value, critical;
289  const unsigned char *p;
290  X509_EXTENSION *ext, *x;
291 
292  GetX509Ext(self, ext);
293  if(rb_scan_args(argc, argv, "12", &oid, &value, &critical) == 1){
294  oid = ossl_to_der_if_possible(oid);
295  StringValue(oid);
296  p = (unsigned char *)RSTRING_PTR(oid);
297  x = d2i_X509_EXTENSION(&ext, &p, RSTRING_LEN(oid));
298  DATA_PTR(self) = ext;
299  if(!x)
301  return self;
302  }
303  rb_funcall(self, rb_intern("oid="), 1, oid);
304  rb_funcall(self, rb_intern("value="), 1, value);
305  if(argc > 2) rb_funcall(self, rb_intern("critical="), 1, critical);
306 
307  return self;
308 }
309 
310 static VALUE
312 {
313  X509_EXTENSION *ext;
314  ASN1_OBJECT *obj;
315  char *s;
316 
317  s = StringValuePtr(oid);
318  obj = OBJ_txt2obj(s, 0);
319  if(!obj) obj = OBJ_txt2obj(s, 1);
320  if(!obj) ossl_raise(eX509ExtError, NULL);
321  GetX509Ext(self, ext);
322  X509_EXTENSION_set_object(ext, obj);
323 
324  return oid;
325 }
326 
327 static VALUE
329 {
330  X509_EXTENSION *ext;
331  ASN1_OCTET_STRING *asn1s;
332  char *s;
333 
334  data = ossl_to_der_if_possible(data);
335  StringValue(data);
336  if(!(s = OPENSSL_malloc(RSTRING_LEN(data))))
337  ossl_raise(eX509ExtError, "malloc error");
338  memcpy(s, RSTRING_PTR(data), RSTRING_LEN(data));
339  if(!(asn1s = ASN1_OCTET_STRING_new())){
340  OPENSSL_free(s);
342  }
343  if(!M_ASN1_OCTET_STRING_set(asn1s, s, RSTRING_LENINT(data))){
344  OPENSSL_free(s);
345  ASN1_OCTET_STRING_free(asn1s);
347  }
348  OPENSSL_free(s);
349  GetX509Ext(self, ext);
350  X509_EXTENSION_set_data(ext, asn1s);
351 
352  return data;
353 }
354 
355 static VALUE
357 {
358  X509_EXTENSION *ext;
359 
360  GetX509Ext(self, ext);
361  X509_EXTENSION_set_critical(ext, RTEST(flag) ? 1 : 0);
362 
363  return flag;
364 }
365 
366 static VALUE
368 {
369  X509_EXTENSION *ext;
370  ASN1_OBJECT *extobj;
371  BIO *out;
372  VALUE ret;
373  int nid;
374 
375  GetX509Ext(obj, ext);
376  extobj = X509_EXTENSION_get_object(ext);
377  if ((nid = OBJ_obj2nid(extobj)) != NID_undef)
378  ret = rb_str_new2(OBJ_nid2sn(nid));
379  else{
380  if (!(out = BIO_new(BIO_s_mem())))
382  i2a_ASN1_OBJECT(out, extobj);
383  ret = ossl_membio2str(out);
384  }
385 
386  return ret;
387 }
388 
389 static VALUE
391 {
392  X509_EXTENSION *ext;
393  BIO *out;
394  VALUE ret;
395 
396  GetX509Ext(obj, ext);
397  if (!(out = BIO_new(BIO_s_mem())))
399  if (!X509V3_EXT_print(out, ext, 0, 0))
400  M_ASN1_OCTET_STRING_print(out, ext->value);
401  ret = ossl_membio2str(out);
402 
403  return ret;
404 }
405 
406 static VALUE
408 {
409  X509_EXTENSION *ext;
410 
411  GetX509Ext(obj, ext);
412  return X509_EXTENSION_get_critical(ext) ? Qtrue : Qfalse;
413 }
414 
415 static VALUE
417 {
418  X509_EXTENSION *ext;
419  unsigned char *p;
420  long len;
421  VALUE str;
422 
423  GetX509Ext(obj, ext);
424  if((len = i2d_X509_EXTENSION(ext, NULL)) <= 0)
426  str = rb_str_new(0, len);
427  p = (unsigned char *)RSTRING_PTR(str);
428  if(i2d_X509_EXTENSION(ext, &p) < 0)
430  ossl_str_adjust(str, p);
431 
432  return str;
433 }
434 
435 /*
436  * INIT
437  */
438 void
440 {
441  eX509ExtError = rb_define_class_under(mX509, "ExtensionError", eOSSLError);
442 
443  cX509ExtFactory = rb_define_class_under(mX509, "ExtensionFactory", rb_cObject);
444 
447 
448  rb_attr(cX509ExtFactory, rb_intern("issuer_certificate"), 1, 0, Qfalse);
449  rb_attr(cX509ExtFactory, rb_intern("subject_certificate"), 1, 0, Qfalse);
450  rb_attr(cX509ExtFactory, rb_intern("subject_request"), 1, 0, Qfalse);
451  rb_attr(cX509ExtFactory, rb_intern("crl"), 1, 0, Qfalse);
452  rb_attr(cX509ExtFactory, rb_intern("config"), 1, 0, Qfalse);
453 
460 
471 }
VALUE data
Definition: tcltklib.c:3367
void Init_ossl_x509ext(void)
Definition: ossl_x509ext.c:439
static VALUE ossl_x509ext_get_value(VALUE obj)
Definition: ossl_x509ext.c:390
Win32OLEIDispatch * p
Definition: win32ole.c:786
VALUE rb_iv_set(VALUE, const char *, VALUE)
Definition: variable.c:2594
static VALUE ossl_x509extfactory_set_subject_req(VALUE self, VALUE req)
Definition: ossl_x509ext.c:143
C_block * out
Definition: crypt.c:308
#define SafeGetX509Ext(obj, ext)
Definition: ossl_x509ext.c:25
VALUE cX509ExtFactory
Definition: ossl_x509ext.c:46
#define ossl_str_adjust(str, p)
Definition: ossl.h:138
static VALUE ossl_x509extfactory_alloc(VALUE klass)
Definition: ossl_x509ext.c:107
int ret
Definition: tcltklib.c:280
VALUE rb_iv_get(VALUE, const char *)
Definition: variable.c:2586
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
#define RSTRING_PTR(str)
NIL_P(eventloop_thread)
Definition: tcltklib.c:4067
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:773
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:534
return Qtrue
Definition: tcltklib.c:9609
VALUE cX509Ext
Definition: ossl_x509ext.c:45
#define rb_str_new2
X509_EXTENSION * DupX509ExtPtr(VALUE)
Definition: ossl_x509ext.c:82
VALUE ossl_membio2str(BIO *bio)
Definition: ossl_bio.c:77
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2125
#define GetX509ExtFactory(obj, ctx)
Definition: ossl_x509ext.c:35
flag
Definition: tcltklib.c:2047
static VALUE ossl_x509ext_get_critical(VALUE obj)
Definition: ossl_x509ext.c:407
static VALUE ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self)
Definition: ossl_x509ext.c:215
#define ossl_x509extfactory_set_config
Definition: ossl_x509ext.c:181
X509 * GetX509CertPtr(VALUE)
Definition: ossl_x509cert.c:92
VALUE ossl_to_der_if_possible(VALUE obj)
Definition: ossl.c:283
return Qfalse
Definition: tcltklib.c:6778
#define Qnil
Definition: tcltklib.c:1895
#define StringValuePtr(v)
VALUE eX509ExtError
Definition: ossl_x509ext.c:47
static VALUE char * str
Definition: tcltklib.c:3546
static VALUE ossl_x509ext_to_der(VALUE obj)
Definition: ossl_x509ext.c:416
static VALUE VALUE obj
Definition: tcltklib.c:3157
#define RSTRING_LEN(str)
VALUE eOSSLError
Definition: ossl.c:264
VALUE ossl_x509ext_new(X509_EXTENSION *)
Definition: ossl_x509ext.c:53
static VALUE ossl_x509ext_initialize(int argc, VALUE *argv, VALUE self)
Definition: ossl_x509ext.c:286
static VALUE ossl_x509extfactory_set_issuer_cert(VALUE self, VALUE cert)
Definition: ossl_x509ext.c:119
VALUE * argv
Definition: tcltklib.c:1970
memcpy(buf+1, str, len)
#define RTEST(v)
volatile VALUE value
Definition: tcltklib.c:9441
#define StringValue(v)
register char * s
Definition: os2.c:56
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
void rb_attr(VALUE, ID, int, int, int)
Definition: vm_method.c:824
int argc
Definition: tcltklib.c:1969
VALUE mX509
Definition: ossl_x509.c:13
static VALUE ossl_x509extfactory_set_subject_cert(VALUE self, VALUE cert)
Definition: ossl_x509ext.c:131
static VALUE ossl_x509ext_get_oid(VALUE obj)
Definition: ossl_x509ext.c:367
X509_EXTENSION * GetX509ExtPtr(VALUE)
Definition: ossl_x509ext.c:72
CONF * GetConfigPtr(VALUE obj)
Definition: ossl_config.c:31
#define WrapX509Ext(klass, obj, ext)
Definition: ossl_x509ext.c:13
#define MakeX509ExtFactory(klass, obj, ctx)
Definition: ossl_x509ext.c:29
static VALUE ossl_x509extfactory_initialize(int argc, VALUE *argv, VALUE self)
Definition: ossl_x509ext.c:185
static VALUE ossl_x509ext_alloc(VALUE klass)
Definition: ossl_x509ext.c:260
static VALUE ossl_x509ext_set_value(VALUE self, VALUE data)
Definition: ossl_x509ext.c:328
DATA_PTR(self)
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1426
klass
Definition: tcltklib.c:3503
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:333
#define RSTRING_LENINT(str)
VALUE rb_str_new(const char *, long)
Definition: string.c:425
static VALUE ossl_x509extfactory_set_crl(VALUE self, VALUE crl)
Definition: ossl_x509ext.c:155
unsigned long VALUE
Definition: ripper.y:104
X509_CRL * GetX509CRLPtr(VALUE)
Definition: ossl_x509crl.c:40
#define rb_intern(str)
static VALUE ossl_x509ext_set_oid(VALUE self, VALUE oid)
Definition: ossl_x509ext.c:311
#define NULL
Definition: _sdbm.c:102
X509_REQ * GetX509ReqPtr(VALUE)
Definition: ossl_x509req.c:59
static VALUE ossl_x509ext_set_critical(VALUE self, VALUE flag)
Definition: ossl_x509ext.c:356
static void ossl_x509extfactory_free(X509V3_CTX *ctx)
Definition: ossl_x509ext.c:101
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344
#define GetX509Ext(obj, ext)
Definition: ossl_x509ext.c:19
size_t len
Definition: tcltklib.c:3567