Ruby  1.9.3p448(2013-06-27revision41675)
ossl_x509name.c
Go to the documentation of this file.
1 /*
2  * $Id: ossl_x509name.c 34505 2012-02-09 03:25:07Z nobu $
3  * 'OpenSSL for Ruby' project
4  * Copyright (C) 2001 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 WrapX509Name(klass, obj, name) do { \
14  if (!(name)) { \
15  ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \
16  } \
17  (obj) = Data_Wrap_Struct((klass), 0, X509_NAME_free, (name)); \
18 } while (0)
19 #define GetX509Name(obj, name) do { \
20  Data_Get_Struct((obj), X509_NAME, (name)); \
21  if (!(name)) { \
22  ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \
23  } \
24 } while (0)
25 #define SafeGetX509Name(obj, name) do { \
26  OSSL_Check_Kind((obj), cX509Name); \
27  GetX509Name((obj), (name)); \
28 } while (0)
29 
30 #define OBJECT_TYPE_TEMPLATE \
31  rb_const_get(cX509Name, rb_intern("OBJECT_TYPE_TEMPLATE"))
32 #define DEFAULT_OBJECT_TYPE \
33  rb_const_get(cX509Name, rb_intern("DEFAULT_OBJECT_TYPE"))
34 
35 /*
36  * Classes
37  */
40 
41 /*
42  * Public
43  */
44 VALUE
46 {
47  X509_NAME *new;
48  VALUE obj;
49 
50  if (!name) {
51  new = X509_NAME_new();
52  } else {
53  new = X509_NAME_dup(name);
54  }
55  if (!new) {
57  }
58  WrapX509Name(cX509Name, obj, new);
59 
60  return obj;
61 }
62 
63 X509_NAME *
65 {
66  X509_NAME *name;
67 
68  SafeGetX509Name(obj, name);
69 
70  return name;
71 }
72 
73 /*
74  * Private
75  */
76 static VALUE
78 {
79  X509_NAME *name;
80  VALUE obj;
81 
82  if (!(name = X509_NAME_new())) {
84  }
85  WrapX509Name(klass, obj, name);
86 
87  return obj;
88 }
89 
90 static ID id_aref;
92 #define rb_aref(obj, key) rb_funcall((obj), id_aref, 1, (key))
93 
94 static VALUE
96 {
97  VALUE self = rb_ary_entry(args, 0);
98  VALUE template = rb_ary_entry(args, 1);
99  VALUE entry[3];
100 
101  Check_Type(i, T_ARRAY);
102  entry[0] = rb_ary_entry(i, 0);
103  entry[1] = rb_ary_entry(i, 1);
104  entry[2] = rb_ary_entry(i, 2);
105  if(NIL_P(entry[2])) entry[2] = rb_aref(template, entry[0]);
106  if(NIL_P(entry[2])) entry[2] = DEFAULT_OBJECT_TYPE;
107  ossl_x509name_add_entry(3, entry, self);
108 
109  return Qnil;
110 }
111 
112 /*
113  * call-seq:
114  * X509::Name.new => name
115  * X509::Name.new(string) => name
116  * X509::Name.new(dn) => name
117  * X509::Name.new(dn, template) => name
118  */
119 static VALUE
121 {
122  X509_NAME *name;
123  VALUE arg, template;
124 
125  GetX509Name(self, name);
126  if (rb_scan_args(argc, argv, "02", &arg, &template) == 0) {
127  return self;
128  }
129  else {
130  VALUE tmp = rb_check_array_type(arg);
131  if (!NIL_P(tmp)) {
132  VALUE args;
133  if(NIL_P(template)) template = OBJECT_TYPE_TEMPLATE;
134  args = rb_ary_new3(2, self, template);
135  rb_block_call(tmp, rb_intern("each"), 0, 0, ossl_x509name_init_i, args);
136  }
137  else{
138  const unsigned char *p;
139  VALUE str = ossl_to_der_if_possible(arg);
140  X509_NAME *x;
141  StringValue(str);
142  p = (unsigned char *)RSTRING_PTR(str);
143  x = d2i_X509_NAME(&name, &p, RSTRING_LEN(str));
144  DATA_PTR(self) = name;
145  if(!x){
147  }
148  }
149  }
150 
151  return self;
152 }
153 
154 /*
155  * call-seq:
156  * name.add_entry(oid, value [, type]) => self
157  */
158 static
160 {
161  X509_NAME *name;
162  VALUE oid, value, type;
163 
164  rb_scan_args(argc, argv, "21", &oid, &value, &type);
165  StringValue(oid);
166  StringValue(value);
167  if(NIL_P(type)) type = rb_aref(OBJECT_TYPE_TEMPLATE, oid);
168  GetX509Name(self, name);
169  if (!X509_NAME_add_entry_by_txt(name, RSTRING_PTR(oid), NUM2INT(type),
170  (const unsigned char *)RSTRING_PTR(value), RSTRING_LENINT(value), -1, 0)) {
172  }
173 
174  return self;
175 }
176 
177 static VALUE
179 {
180  X509_NAME *name;
181  char *buf;
182  VALUE str;
183 
184  GetX509Name(self, name);
185  buf = X509_NAME_oneline(name, NULL, 0);
186  str = rb_str_new2(buf);
187  OPENSSL_free(buf);
188 
189  return str;
190 }
191 
192 /*
193  * call-seq:
194  * name.to_s => string
195  * name.to_s(integer) => string
196  */
197 static VALUE
199 {
200  X509_NAME *name;
201  VALUE flag, str;
202  BIO *out;
203  unsigned long iflag;
204 
205  rb_scan_args(argc, argv, "01", &flag);
206  if (NIL_P(flag))
207  return ossl_x509name_to_s_old(self);
208  else iflag = NUM2ULONG(flag);
209  if (!(out = BIO_new(BIO_s_mem())))
211  GetX509Name(self, name);
212  if (!X509_NAME_print_ex(out, name, 0, iflag)){
213  BIO_free(out);
215  }
216  str = ossl_membio2str(out);
217 
218  return str;
219 }
220 
221 /*
222  * call-seq:
223  * name.to_a => [[name, data, type], ...]
224  */
225 static VALUE
227 {
228  X509_NAME *name;
229  X509_NAME_ENTRY *entry;
230  int i,entries,nid;
231  char long_name[512];
232  const char *short_name;
233  VALUE ary, vname, ret;
234 
235  GetX509Name(self, name);
236  entries = X509_NAME_entry_count(name);
237  if (entries < 0) {
238  OSSL_Debug("name entries < 0!");
239  return rb_ary_new();
240  }
241  ret = rb_ary_new2(entries);
242  for (i=0; i<entries; i++) {
243  if (!(entry = X509_NAME_get_entry(name, i))) {
245  }
246  if (!i2t_ASN1_OBJECT(long_name, sizeof(long_name), entry->object)) {
248  }
249  nid = OBJ_ln2nid(long_name);
250  if (nid == NID_undef) {
251  vname = rb_str_new2((const char *) &long_name);
252  } else {
253  short_name = OBJ_nid2sn(nid);
254  vname = rb_str_new2(short_name); /*do not free*/
255  }
256  ary = rb_ary_new3(3,
257  vname,
258  rb_str_new((const char *)entry->value->data, entry->value->length),
259  INT2FIX(entry->value->type));
260  rb_ary_push(ret, ary);
261  }
262  return ret;
263 }
264 
265 static int
267 {
268  X509_NAME *name1, *name2;
269 
270  GetX509Name(self, name1);
271  SafeGetX509Name(other, name2);
272 
273  return X509_NAME_cmp(name1, name2);
274 }
275 
276 /*
277  * call-seq:
278  * name.cmp other => integer
279  * name.<=> other => integer
280  *
281  * Compares this Name with +other+ and returns 0 if they are the same and -1 or
282  * +1 if they are greater or less than each other respectively.
283  */
284 static VALUE
286 {
287  int result;
288 
289  result = ossl_x509name_cmp0(self, other);
290  if (result < 0) return INT2FIX(-1);
291  if (result > 1) return INT2FIX(1);
292 
293  return INT2FIX(0);
294 }
295 
296 static VALUE
298 {
299  int result;
300 
301  if(CLASS_OF(other) != cX509Name) return Qfalse;
302  result = ossl_x509name_cmp0(self, other);
303 
304  return (result == 0) ? Qtrue : Qfalse;
305 }
306 
307 /*
308  * call-seq:
309  * name.hash => integer
310  *
311  * The hash value returned is suitable for use as a certificate's filename in
312  * a CA path.
313  */
314 static VALUE
316 {
317  X509_NAME *name;
318  unsigned long hash;
319 
320  GetX509Name(self, name);
321 
322  hash = X509_NAME_hash(name);
323 
324  return ULONG2NUM(hash);
325 }
326 
327 #ifdef HAVE_X509_NAME_HASH_OLD
328 /*
329  * call-seq:
330  * name.hash_old => integer
331  *
332  * hash_old returns MD5 based hash used in OpenSSL 0.9.X.
333  */
334 static VALUE
335 ossl_x509name_hash_old(VALUE self)
336 {
337  X509_NAME *name;
338  unsigned long hash;
339 
340  GetX509Name(self, name);
341 
342  hash = X509_NAME_hash_old(name);
343 
344  return ULONG2NUM(hash);
345 }
346 #endif
347 
348 /*
349  * call-seq:
350  * name.to_der => string
351  */
352 static VALUE
354 {
355  X509_NAME *name;
356  VALUE str;
357  long len;
358  unsigned char *p;
359 
360  GetX509Name(self, name);
361  if((len = i2d_X509_NAME(name, NULL)) <= 0)
363  str = rb_str_new(0, len);
364  p = (unsigned char *)RSTRING_PTR(str);
365  if(i2d_X509_NAME(name, &p) <= 0)
367  ossl_str_adjust(str, p);
368 
369  return str;
370 }
371 
372 /*
373  * INIT
374  */
375 void
377 {
378  VALUE utf8str, ptrstr, ia5str, hash;
379 
380  id_aref = rb_intern("[]");
383 
385 
392  rb_define_alias(cX509Name, "<=>", "cmp");
395 #ifdef HAVE_X509_NAME_HASH_OLD
396  rb_define_method(cX509Name, "hash_old", ossl_x509name_hash_old, 0);
397 #endif
399 
400  utf8str = INT2NUM(V_ASN1_UTF8STRING);
401  ptrstr = INT2NUM(V_ASN1_PRINTABLESTRING);
402  ia5str = INT2NUM(V_ASN1_IA5STRING);
403  rb_define_const(cX509Name, "DEFAULT_OBJECT_TYPE", utf8str);
404  hash = rb_hash_new();
405  RHASH(hash)->ifnone = utf8str;
406  rb_hash_aset(hash, rb_str_new2("C"), ptrstr);
407  rb_hash_aset(hash, rb_str_new2("countryName"), ptrstr);
408  rb_hash_aset(hash, rb_str_new2("serialNumber"), ptrstr);
409  rb_hash_aset(hash, rb_str_new2("dnQualifier"), ptrstr);
410  rb_hash_aset(hash, rb_str_new2("DC"), ia5str);
411  rb_hash_aset(hash, rb_str_new2("domainComponent"), ia5str);
412  rb_hash_aset(hash, rb_str_new2("emailAddress"), ia5str);
413  rb_define_const(cX509Name, "OBJECT_TYPE_TEMPLATE", hash);
414 
415  rb_define_const(cX509Name, "COMPAT", ULONG2NUM(XN_FLAG_COMPAT));
416  rb_define_const(cX509Name, "RFC2253", ULONG2NUM(XN_FLAG_RFC2253));
417  rb_define_const(cX509Name, "ONELINE", ULONG2NUM(XN_FLAG_ONELINE));
418  rb_define_const(cX509Name, "MULTILINE", ULONG2NUM(XN_FLAG_MULTILINE));
419 }
#define RSTRING_LEN(string)
Definition: generator.h:45
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:956
#define GetX509Name(obj, name)
Definition: ossl_x509name.c:19
int i
Definition: win32ole.c:776
#define NUM2INT(x)
Definition: ruby.h:536
#define CLASS_OF(v)
Definition: ruby.h:376
#define Qtrue
Definition: ruby.h:366
#define ossl_str_adjust(str, p)
Definition: ossl.h:132
static VALUE ossl_x509name_alloc(VALUE klass)
Definition: ossl_x509name.c:77
#define rb_block_call(arg1, arg2, arg3, arg4, arg5, arg6)
Definition: ruby_missing.h:38
void Init_ossl_x509name()
static VALUE ossl_x509name_init_i(VALUE i, VALUE args)
Definition: ossl_x509name.c:95
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:740
#define DEFAULT_OBJECT_TYPE
Definition: ossl_x509name.c:32
static int ossl_x509name_cmp0(VALUE self, VALUE other)
static VALUE INT2NUM(int v)
Definition: ruby.h:981
#define RSTRING_PTR(string)
Definition: generator.h:42
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:514
#define Check_Type(v, t)
Definition: ruby.h:459
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_ary_new3(long n,...)
Definition: array.c:347
static VALUE ossl_x509name_to_s_old(VALUE self)
#define DATA_PTR(dta)
Definition: ruby.h:795
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:662
VALUE cX509Name
Definition: ossl_x509name.c:38
#define SafeGetX509Name(obj, name)
Definition: ossl_x509name.c:25
#define T_ARRAY
Definition: ruby.h:420
VALUE ossl_membio2str(BIO *bio)
Definition: ossl_bio.c:77
Win32OLEIDispatch * p
Definition: win32ole.c:778
static VALUE ossl_x509name_to_s(int argc, VALUE *argv, VALUE self)
int args
Definition: win32ole.c:777
#define RHASH(obj)
Definition: ruby.h:912
VALUE rb_mComparable
Definition: compar.c:14
VALUE ossl_to_der_if_possible(VALUE obj)
Definition: ossl.c:274
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:1123
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1246
VALUE rb_ary_new(void)
Definition: array.c:339
#define NIL_P(v)
Definition: ruby.h:374
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:1923
VALUE eOSSLError
Definition: ossl.c:255
static VALUE ossl_x509name_to_a(VALUE self)
int argc
Definition: ruby.c:120
#define Qfalse
Definition: ruby.h:365
static VALUE ossl_x509name_initialize(int argc, VALUE *argv, VALUE self)
arg
Definition: ripper.y:1283
static ID id_aref
Definition: ossl_x509name.c:90
#define WrapX509Name(klass, obj, name)
Definition: ossl_x509name.c:13
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1384
static VALUE ossl_x509name_eql(VALUE self, VALUE other)
VALUE rb_hash_new(void)
Definition: hash.c:229
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1415
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:3913
unsigned long ID
Definition: ruby.h:89
#define NULL
#define Qnil
Definition: ruby.h:367
int type
Definition: tcltklib.c:107
VALUE ossl_x509name_new(X509_NAME *name)
Definition: ossl_x509name.c:45
unsigned long VALUE
Definition: ruby.h:88
#define OBJECT_TYPE_TEMPLATE
Definition: ossl_x509name.c:30
static VALUE result
Definition: nkf.c:40
register unsigned int len
Definition: name2ctype.h:22210
VALUE mX509
Definition: ossl_x509.c:13
static VALUE ossl_x509name_to_der(VALUE self)
#define OSSL_Debug
Definition: ossl.h:205
static VALUE ossl_x509name_hash(VALUE self)
#define rb_aref(obj, key)
Definition: ossl_x509name.c:92
#define INT2FIX(i)
Definition: ruby.h:225
static VALUE ULONG2NUM(unsigned long v)
Definition: ruby.h:1015
static VALUE ossl_x509name_cmp(VALUE self, VALUE other)
#define NUM2ULONG(x)
Definition: ruby.h:515
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:472
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:319
static unsigned int hash(const char *str, unsigned int len)
Definition: lex.c:56
VALUE rb_ary_new2(long capa)
Definition: array.c:332
const char * name
Definition: nkf.c:208
#define RSTRING_LENINT(str)
Definition: ruby.h:684
X509_NAME * GetX509NamePtr(VALUE obj)
Definition: ossl_x509name.c:64
#define rb_intern(str)
static VALUE ossl_x509name_add_entry(int, VALUE *, VALUE)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1209
VALUE rb_str_new2(const char *)
VALUE eX509NameError
Definition: ossl_x509name.c:39
char ** argv
Definition: ruby.c:121
#define StringValue(v)
Definition: ruby.h:466
VALUE rb_str_new(const char *, long)
Definition: string.c:410