Ruby  2.5.0dev(2017-10-22revision60238)
ossl_asn1.c
Go to the documentation of this file.
1 /*
2  * 'OpenSSL for Ruby' team members
3  * Copyright (C) 2003
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 static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset,
13  int depth, int yield, long *num_read);
14 static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self);
15 
16 /*
17  * DATE conversion
18  */
19 VALUE
20 asn1time_to_time(const ASN1_TIME *time)
21 {
22  struct tm tm;
23  VALUE argv[6];
24  int count;
25 
26  memset(&tm, 0, sizeof(struct tm));
27 
28  switch (time->type) {
29  case V_ASN1_UTCTIME:
30  count = sscanf((const char *)time->data, "%2d%2d%2d%2d%2d%2dZ",
31  &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min,
32  &tm.tm_sec);
33 
34  if (count == 5) {
35  tm.tm_sec = 0;
36  } else if (count != 6) {
37  ossl_raise(rb_eTypeError, "bad UTCTIME format: \"%s\"",
38  time->data);
39  }
40  if (tm.tm_year < 69) {
41  tm.tm_year += 2000;
42  } else {
43  tm.tm_year += 1900;
44  }
45  break;
46  case V_ASN1_GENERALIZEDTIME:
47  count = sscanf((const char *)time->data, "%4d%2d%2d%2d%2d%2dZ",
48  &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min,
49  &tm.tm_sec);
50  if (count == 5) {
51  tm.tm_sec = 0;
52  }
53  else if (count != 6) {
54  ossl_raise(rb_eTypeError, "bad GENERALIZEDTIME format: \"%s\"",
55  time->data);
56  }
57  break;
58  default:
59  rb_warning("unknown time format");
60  return Qnil;
61  }
62  argv[0] = INT2NUM(tm.tm_year);
63  argv[1] = INT2NUM(tm.tm_mon);
64  argv[2] = INT2NUM(tm.tm_mday);
65  argv[3] = INT2NUM(tm.tm_hour);
66  argv[4] = INT2NUM(tm.tm_min);
67  argv[5] = INT2NUM(tm.tm_sec);
68 
69  return rb_funcall2(rb_cTime, rb_intern("utc"), 6, argv);
70 }
71 
72 void
73 ossl_time_split(VALUE time, time_t *sec, int *days)
74 {
75  VALUE num = rb_Integer(time);
76 
77  if (FIXNUM_P(num)) {
78  time_t t = FIX2LONG(num);
79  *sec = t % 86400;
80  *days = rb_long2int(t / 86400);
81  }
82  else {
83  *days = NUM2INT(rb_funcall(num, rb_intern("/"), 1, INT2FIX(86400)));
84  *sec = NUM2TIMET(rb_funcall(num, rb_intern("%"), 1, INT2FIX(86400)));
85  }
86 }
87 
88 /*
89  * STRING conversion
90  */
91 VALUE
92 asn1str_to_str(const ASN1_STRING *str)
93 {
94  return rb_str_new((const char *)str->data, str->length);
95 }
96 
97 /*
98  * ASN1_INTEGER conversions
99  */
100 VALUE
101 asn1integer_to_num(const ASN1_INTEGER *ai)
102 {
103  BIGNUM *bn;
104  VALUE num;
105 
106  if (!ai) {
107  ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!");
108  }
109  if (ai->type == V_ASN1_ENUMERATED)
110  /* const_cast: workaround for old OpenSSL */
111  bn = ASN1_ENUMERATED_to_BN((ASN1_ENUMERATED *)ai, NULL);
112  else
113  bn = ASN1_INTEGER_to_BN(ai, NULL);
114 
115  if (!bn)
117  num = ossl_bn_new(bn);
118  BN_free(bn);
119 
120  return num;
121 }
122 
123 ASN1_INTEGER *
124 num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
125 {
126  BIGNUM *bn;
127 
128  if (NIL_P(obj))
129  ossl_raise(rb_eTypeError, "Can't convert nil into Integer");
130 
131  bn = GetBNPtr(obj);
132 
133  if (!(ai = BN_to_ASN1_INTEGER(bn, ai)))
135 
136  return ai;
137 }
138 
139 /********/
140 /*
141  * ASN1 module
142  */
143 #define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE)
144 #define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG)
145 #define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING)
146 #define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS)
147 #define ossl_asn1_get_indefinite_length(o) rb_attr_get((o),sivINDEFINITE_LENGTH)
148 
149 #define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v))
150 #define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v))
151 #define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v))
152 #define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v))
153 #define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v))
154 
157 
161 
163 VALUE cASN1Boolean; /* BOOLEAN */
165 VALUE cASN1BitString; /* BIT STRING */
172 VALUE cASN1Null; /* NULL */
173 VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */
175 VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */
176 
177 static VALUE sym_IMPLICIT, sym_EXPLICIT;
178 static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE;
179 static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINDEFINITE_LENGTH, sivUNUSED_BITS;
180 static ID id_each;
181 
182 /*
183  * Ruby to ASN1 converters
184  */
185 static ASN1_BOOLEAN
186 obj_to_asn1bool(VALUE obj)
187 {
188  if (NIL_P(obj))
189  ossl_raise(rb_eTypeError, "Can't convert nil into Boolean");
190 
191  return RTEST(obj) ? 0xff : 0x0;
192 }
193 
194 static ASN1_INTEGER*
195 obj_to_asn1int(VALUE obj)
196 {
197  return num_to_asn1integer(obj, NULL);
198 }
199 
200 static ASN1_BIT_STRING*
201 obj_to_asn1bstr(VALUE obj, long unused_bits)
202 {
203  ASN1_BIT_STRING *bstr;
204 
205  if (unused_bits < 0 || unused_bits > 7)
206  ossl_raise(eASN1Error, "unused_bits for a bitstring value must be in "\
207  "the range 0 to 7");
208  StringValue(obj);
209  if(!(bstr = ASN1_BIT_STRING_new()))
211  ASN1_BIT_STRING_set(bstr, (unsigned char *)RSTRING_PTR(obj), RSTRING_LENINT(obj));
212  bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
213  bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits;
214 
215  return bstr;
216 }
217 
218 static ASN1_STRING*
219 obj_to_asn1str(VALUE obj)
220 {
221  ASN1_STRING *str;
222 
223  StringValue(obj);
224  if(!(str = ASN1_STRING_new()))
226  ASN1_STRING_set(str, RSTRING_PTR(obj), RSTRING_LENINT(obj));
227 
228  return str;
229 }
230 
231 static ASN1_NULL*
232 obj_to_asn1null(VALUE obj)
233 {
234  ASN1_NULL *null;
235 
236  if(!NIL_P(obj))
237  ossl_raise(eASN1Error, "nil expected");
238  if(!(null = ASN1_NULL_new()))
240 
241  return null;
242 }
243 
244 static ASN1_OBJECT*
245 obj_to_asn1obj(VALUE obj)
246 {
247  ASN1_OBJECT *a1obj;
248 
249  StringValueCStr(obj);
250  a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 0);
251  if(!a1obj) a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 1);
252  if(!a1obj) ossl_raise(eASN1Error, "invalid OBJECT ID %"PRIsVALUE, obj);
253 
254  return a1obj;
255 }
256 
257 static ASN1_UTCTIME *
258 obj_to_asn1utime(VALUE time)
259 {
260  time_t sec;
261  ASN1_UTCTIME *t;
262 
263  int off_days;
264 
265  ossl_time_split(time, &sec, &off_days);
266  if (!(t = ASN1_UTCTIME_adj(NULL, sec, off_days, 0)))
268 
269  return t;
270 }
271 
272 static ASN1_GENERALIZEDTIME *
273 obj_to_asn1gtime(VALUE time)
274 {
275  time_t sec;
276  ASN1_GENERALIZEDTIME *t;
277 
278  int off_days;
279 
280  ossl_time_split(time, &sec, &off_days);
281  if (!(t = ASN1_GENERALIZEDTIME_adj(NULL, sec, off_days, 0)))
283 
284  return t;
285 }
286 
287 static ASN1_STRING*
288 obj_to_asn1derstr(VALUE obj)
289 {
290  ASN1_STRING *a1str;
291  VALUE str;
292 
293  str = ossl_to_der(obj);
294  if(!(a1str = ASN1_STRING_new()))
296  ASN1_STRING_set(a1str, RSTRING_PTR(str), RSTRING_LENINT(str));
297 
298  return a1str;
299 }
300 
301 /*
302  * DER to Ruby converters
303  */
304 static VALUE
305 decode_bool(unsigned char* der, long length)
306 {
307  const unsigned char *p = der;
308 
309  if (length != 3)
310  ossl_raise(eASN1Error, "invalid length for BOOLEAN");
311  if (p[0] != 1 || p[1] != 1)
312  ossl_raise(eASN1Error, "invalid BOOLEAN");
313 
314  return p[2] ? Qtrue : Qfalse;
315 }
316 
317 static VALUE
318 decode_int(unsigned char* der, long length)
319 {
320  ASN1_INTEGER *ai;
321  const unsigned char *p;
322  VALUE ret;
323  int status = 0;
324 
325  p = der;
326  if(!(ai = d2i_ASN1_INTEGER(NULL, &p, length)))
329  (VALUE)ai, &status);
330  ASN1_INTEGER_free(ai);
331  if(status) rb_jump_tag(status);
332 
333  return ret;
334 }
335 
336 static VALUE
337 decode_bstr(unsigned char* der, long length, long *unused_bits)
338 {
339  ASN1_BIT_STRING *bstr;
340  const unsigned char *p;
341  long len;
342  VALUE ret;
343 
344  p = der;
345  if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length)))
347  len = bstr->length;
348  *unused_bits = 0;
349  if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT)
350  *unused_bits = bstr->flags & 0x07;
351  ret = rb_str_new((const char *)bstr->data, len);
352  ASN1_BIT_STRING_free(bstr);
353 
354  return ret;
355 }
356 
357 static VALUE
358 decode_enum(unsigned char* der, long length)
359 {
360  ASN1_ENUMERATED *ai;
361  const unsigned char *p;
362  VALUE ret;
363  int status = 0;
364 
365  p = der;
366  if(!(ai = d2i_ASN1_ENUMERATED(NULL, &p, length)))
369  (VALUE)ai, &status);
370  ASN1_ENUMERATED_free(ai);
371  if(status) rb_jump_tag(status);
372 
373  return ret;
374 }
375 
376 static VALUE
377 decode_null(unsigned char* der, long length)
378 {
379  ASN1_NULL *null;
380  const unsigned char *p;
381 
382  p = der;
383  if(!(null = d2i_ASN1_NULL(NULL, &p, length)))
385  ASN1_NULL_free(null);
386 
387  return Qnil;
388 }
389 
390 static VALUE
391 decode_obj(unsigned char* der, long length)
392 {
393  ASN1_OBJECT *obj;
394  const unsigned char *p;
395  VALUE ret;
396  int nid;
397  BIO *bio;
398 
399  p = der;
400  if(!(obj = d2i_ASN1_OBJECT(NULL, &p, length)))
402  if((nid = OBJ_obj2nid(obj)) != NID_undef){
403  ASN1_OBJECT_free(obj);
404  ret = rb_str_new2(OBJ_nid2sn(nid));
405  }
406  else{
407  if(!(bio = BIO_new(BIO_s_mem()))){
408  ASN1_OBJECT_free(obj);
410  }
411  i2a_ASN1_OBJECT(bio, obj);
412  ASN1_OBJECT_free(obj);
413  ret = ossl_membio2str(bio);
414  }
415 
416  return ret;
417 }
418 
419 static VALUE
420 decode_time(unsigned char* der, long length)
421 {
422  ASN1_TIME *time;
423  const unsigned char *p;
424  VALUE ret;
425  int status = 0;
426 
427  p = der;
428  if(!(time = d2i_ASN1_TIME(NULL, &p, length)))
431  (VALUE)time, &status);
432  ASN1_TIME_free(time);
433  if(status) rb_jump_tag(status);
434 
435  return ret;
436 }
437 
438 static VALUE
439 decode_eoc(unsigned char *der, long length)
440 {
441  if (length != 2 || !(der[0] == 0x00 && der[1] == 0x00))
443 
444  return rb_str_new("", 0);
445 }
446 
447 /********/
448 
449 typedef struct {
450  const char *name;
453 
454 static const ossl_asn1_info_t ossl_asn1_info[] = {
455  { "EOC", &cASN1EndOfContent, }, /* 0 */
456  { "BOOLEAN", &cASN1Boolean, }, /* 1 */
457  { "INTEGER", &cASN1Integer, }, /* 2 */
458  { "BIT_STRING", &cASN1BitString, }, /* 3 */
459  { "OCTET_STRING", &cASN1OctetString, }, /* 4 */
460  { "NULL", &cASN1Null, }, /* 5 */
461  { "OBJECT", &cASN1ObjectId, }, /* 6 */
462  { "OBJECT_DESCRIPTOR", NULL, }, /* 7 */
463  { "EXTERNAL", NULL, }, /* 8 */
464  { "REAL", NULL, }, /* 9 */
465  { "ENUMERATED", &cASN1Enumerated, }, /* 10 */
466  { "EMBEDDED_PDV", NULL, }, /* 11 */
467  { "UTF8STRING", &cASN1UTF8String, }, /* 12 */
468  { "RELATIVE_OID", NULL, }, /* 13 */
469  { "[UNIVERSAL 14]", NULL, }, /* 14 */
470  { "[UNIVERSAL 15]", NULL, }, /* 15 */
471  { "SEQUENCE", &cASN1Sequence, }, /* 16 */
472  { "SET", &cASN1Set, }, /* 17 */
473  { "NUMERICSTRING", &cASN1NumericString, }, /* 18 */
474  { "PRINTABLESTRING", &cASN1PrintableString, }, /* 19 */
475  { "T61STRING", &cASN1T61String, }, /* 20 */
476  { "VIDEOTEXSTRING", &cASN1VideotexString, }, /* 21 */
477  { "IA5STRING", &cASN1IA5String, }, /* 22 */
478  { "UTCTIME", &cASN1UTCTime, }, /* 23 */
479  { "GENERALIZEDTIME", &cASN1GeneralizedTime, }, /* 24 */
480  { "GRAPHICSTRING", &cASN1GraphicString, }, /* 25 */
481  { "ISO64STRING", &cASN1ISO64String, }, /* 26 */
482  { "GENERALSTRING", &cASN1GeneralString, }, /* 27 */
483  { "UNIVERSALSTRING", &cASN1UniversalString, }, /* 28 */
484  { "CHARACTER_STRING", NULL, }, /* 29 */
485  { "BMPSTRING", &cASN1BMPString, }, /* 30 */
486 };
487 
488 enum {ossl_asn1_info_size = (sizeof(ossl_asn1_info)/sizeof(ossl_asn1_info[0]))};
489 
490 static VALUE class_tag_map;
491 
492 static int ossl_asn1_default_tag(VALUE obj);
493 
494 ASN1_TYPE*
496 {
497  ASN1_TYPE *ret;
498  VALUE value, rflag;
499  void *ptr;
500  void (*free_func)();
501  int tag;
502 
503  tag = ossl_asn1_default_tag(obj);
504  value = ossl_asn1_get_value(obj);
505  switch(tag){
506  case V_ASN1_BOOLEAN:
507  ptr = (void*)(VALUE)obj_to_asn1bool(value);
508  free_func = NULL;
509  break;
510  case V_ASN1_INTEGER: /* FALLTHROUGH */
511  case V_ASN1_ENUMERATED:
512  ptr = obj_to_asn1int(value);
513  free_func = ASN1_INTEGER_free;
514  break;
515  case V_ASN1_BIT_STRING:
516  rflag = rb_attr_get(obj, sivUNUSED_BITS);
517  ptr = obj_to_asn1bstr(value, NUM2INT(rflag));
518  free_func = ASN1_BIT_STRING_free;
519  break;
520  case V_ASN1_NULL:
521  ptr = obj_to_asn1null(value);
522  free_func = ASN1_NULL_free;
523  break;
524  case V_ASN1_OCTET_STRING: /* FALLTHROUGH */
525  case V_ASN1_UTF8STRING: /* FALLTHROUGH */
526  case V_ASN1_NUMERICSTRING: /* FALLTHROUGH */
527  case V_ASN1_PRINTABLESTRING: /* FALLTHROUGH */
528  case V_ASN1_T61STRING: /* FALLTHROUGH */
529  case V_ASN1_VIDEOTEXSTRING: /* FALLTHROUGH */
530  case V_ASN1_IA5STRING: /* FALLTHROUGH */
531  case V_ASN1_GRAPHICSTRING: /* FALLTHROUGH */
532  case V_ASN1_ISO64STRING: /* FALLTHROUGH */
533  case V_ASN1_GENERALSTRING: /* FALLTHROUGH */
534  case V_ASN1_UNIVERSALSTRING: /* FALLTHROUGH */
535  case V_ASN1_BMPSTRING:
536  ptr = obj_to_asn1str(value);
537  free_func = ASN1_STRING_free;
538  break;
539  case V_ASN1_OBJECT:
540  ptr = obj_to_asn1obj(value);
541  free_func = ASN1_OBJECT_free;
542  break;
543  case V_ASN1_UTCTIME:
544  ptr = obj_to_asn1utime(value);
545  free_func = ASN1_TIME_free;
546  break;
547  case V_ASN1_GENERALIZEDTIME:
548  ptr = obj_to_asn1gtime(value);
549  free_func = ASN1_TIME_free;
550  break;
551  case V_ASN1_SET: /* FALLTHROUGH */
552  case V_ASN1_SEQUENCE:
553  ptr = obj_to_asn1derstr(obj);
554  free_func = ASN1_STRING_free;
555  break;
556  default:
557  ossl_raise(eASN1Error, "unsupported ASN.1 type");
558  }
559  if(!(ret = OPENSSL_malloc(sizeof(ASN1_TYPE)))){
560  if(free_func) free_func(ptr);
561  ossl_raise(eASN1Error, "ASN1_TYPE alloc failure");
562  }
563  memset(ret, 0, sizeof(ASN1_TYPE));
564  ASN1_TYPE_set(ret, tag, ptr);
565 
566  return ret;
567 }
568 
569 static int
570 ossl_asn1_default_tag(VALUE obj)
571 {
572  VALUE tmp_class, tag;
573 
574  tmp_class = CLASS_OF(obj);
575  while (!NIL_P(tmp_class)) {
576  tag = rb_hash_lookup(class_tag_map, tmp_class);
577  if (tag != Qnil)
578  return NUM2INT(tag);
579  tmp_class = rb_class_superclass(tmp_class);
580  }
581 
582  return -1;
583 }
584 
585 static int
586 ossl_asn1_tag(VALUE obj)
587 {
588  VALUE tag;
589 
590  tag = ossl_asn1_get_tag(obj);
591  if(NIL_P(tag))
592  ossl_raise(eASN1Error, "tag number not specified");
593 
594  return NUM2INT(tag);
595 }
596 
597 static int
598 ossl_asn1_tag_class(VALUE obj)
599 {
600  VALUE s;
601 
602  s = ossl_asn1_get_tag_class(obj);
603  if (NIL_P(s) || s == sym_UNIVERSAL)
604  return V_ASN1_UNIVERSAL;
605  else if (s == sym_APPLICATION)
606  return V_ASN1_APPLICATION;
607  else if (s == sym_CONTEXT_SPECIFIC)
608  return V_ASN1_CONTEXT_SPECIFIC;
609  else if (s == sym_PRIVATE)
610  return V_ASN1_PRIVATE;
611  else
612  ossl_raise(eASN1Error, "invalid tag class");
613 }
614 
615 static VALUE
616 ossl_asn1_class2sym(int tc)
617 {
618  if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
619  return sym_PRIVATE;
620  else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
621  return sym_CONTEXT_SPECIFIC;
622  else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
623  return sym_APPLICATION;
624  else
625  return sym_UNIVERSAL;
626 }
627 
628 /*
629  * call-seq:
630  * OpenSSL::ASN1::ASN1Data.new(value, tag, tag_class) => ASN1Data
631  *
632  * _value_: Please have a look at Constructive and Primitive to see how Ruby
633  * types are mapped to ASN.1 types and vice versa.
634  *
635  * _tag_: An Integer indicating the tag number.
636  *
637  * _tag_class_: A Symbol indicating the tag class. Please cf. ASN1 for
638  * possible values.
639  *
640  * == Example
641  * asn1_int = OpenSSL::ASN1Data.new(42, 2, :UNIVERSAL) # => Same as OpenSSL::ASN1::Integer.new(42)
642  * tagged_int = OpenSSL::ASN1Data.new(42, 0, :CONTEXT_SPECIFIC) # implicitly 0-tagged INTEGER
643  */
644 static VALUE
645 ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)
646 {
647  if(!SYMBOL_P(tag_class))
648  ossl_raise(eASN1Error, "invalid tag class");
649  ossl_asn1_set_tag(self, tag);
650  ossl_asn1_set_value(self, value);
651  ossl_asn1_set_tag_class(self, tag_class);
653 
654  return self;
655 }
656 
657 static VALUE
658 to_der_internal(VALUE self, int constructed, int indef_len, VALUE body)
659 {
660  int encoding = constructed ? indef_len ? 2 : 1 : 0;
661  int tag_class = ossl_asn1_tag_class(self);
662  int tag_number = ossl_asn1_tag(self);
663  int default_tag_number = ossl_asn1_default_tag(self);
664  int body_length, total_length;
665  VALUE str;
666  unsigned char *p;
667 
668  body_length = RSTRING_LENINT(body);
669  if (ossl_asn1_get_tagging(self) == sym_EXPLICIT) {
670  int inner_length, e_encoding = indef_len ? 2 : 1;
671 
672  if (default_tag_number == -1)
673  ossl_raise(eASN1Error, "explicit tagging of unknown tag");
674 
675  inner_length = ASN1_object_size(encoding, body_length, default_tag_number);
676  total_length = ASN1_object_size(e_encoding, inner_length, tag_number);
677  str = rb_str_new(NULL, total_length);
678  p = (unsigned char *)RSTRING_PTR(str);
679  /* Put explicit tag */
680  ASN1_put_object(&p, e_encoding, inner_length, tag_number, tag_class);
681  /* Append inner object */
682  ASN1_put_object(&p, encoding, body_length, default_tag_number, V_ASN1_UNIVERSAL);
683  memcpy(p, RSTRING_PTR(body), body_length);
684  p += body_length;
685  if (indef_len) {
686  ASN1_put_eoc(&p); /* For inner object */
687  ASN1_put_eoc(&p); /* For wrapper object */
688  }
689  }
690  else {
691  total_length = ASN1_object_size(encoding, body_length, tag_number);
692  str = rb_str_new(NULL, total_length);
693  p = (unsigned char *)RSTRING_PTR(str);
694  ASN1_put_object(&p, encoding, body_length, tag_number, tag_class);
695  memcpy(p, RSTRING_PTR(body), body_length);
696  p += body_length;
697  if (indef_len)
698  ASN1_put_eoc(&p);
699  }
700  assert(p - (unsigned char *)RSTRING_PTR(str) == total_length);
701  return str;
702 }
703 
704 static VALUE ossl_asn1prim_to_der(VALUE);
705 static VALUE ossl_asn1cons_to_der(VALUE);
706 /*
707  * call-seq:
708  * asn1.to_der => DER-encoded String
709  *
710  * Encodes this ASN1Data into a DER-encoded String value. The result is
711  * DER-encoded except for the possibility of indefinite length forms.
712  * Indefinite length forms are not allowed in strict DER, so strictly speaking
713  * the result of such an encoding would be a BER-encoding.
714  */
715 static VALUE
716 ossl_asn1data_to_der(VALUE self)
717 {
718  VALUE value = ossl_asn1_get_value(self);
719 
720  if (rb_obj_is_kind_of(value, rb_cArray))
721  return ossl_asn1cons_to_der(self);
722  else {
724  ossl_raise(eASN1Error, "indefinite length form cannot be used " \
725  "with primitive encoding");
726  return ossl_asn1prim_to_der(self);
727  }
728 }
729 
730 static VALUE
731 int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
732  VALUE tc, long *num_read)
733 {
734  VALUE value, asn1data;
735  unsigned char *p;
736  long flag = 0;
737 
738  p = *pp;
739 
740  if(tc == sym_UNIVERSAL && tag < ossl_asn1_info_size) {
741  switch(tag){
742  case V_ASN1_EOC:
743  value = decode_eoc(p, hlen+length);
744  break;
745  case V_ASN1_BOOLEAN:
746  value = decode_bool(p, hlen+length);
747  break;
748  case V_ASN1_INTEGER:
749  value = decode_int(p, hlen+length);
750  break;
751  case V_ASN1_BIT_STRING:
752  value = decode_bstr(p, hlen+length, &flag);
753  break;
754  case V_ASN1_NULL:
755  value = decode_null(p, hlen+length);
756  break;
757  case V_ASN1_ENUMERATED:
758  value = decode_enum(p, hlen+length);
759  break;
760  case V_ASN1_OBJECT:
761  value = decode_obj(p, hlen+length);
762  break;
763  case V_ASN1_UTCTIME: /* FALLTHROUGH */
764  case V_ASN1_GENERALIZEDTIME:
765  value = decode_time(p, hlen+length);
766  break;
767  default:
768  /* use original value */
769  p += hlen;
770  value = rb_str_new((const char *)p, length);
771  break;
772  }
773  }
774  else {
775  p += hlen;
776  value = rb_str_new((const char *)p, length);
777  }
778 
779  *pp += hlen + length;
780  *num_read = hlen + length;
781 
782  if (tc == sym_UNIVERSAL &&
783  tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) {
784  VALUE klass = *ossl_asn1_info[tag].klass;
785  VALUE args[4];
786  args[0] = value;
787  args[1] = INT2NUM(tag);
788  args[2] = Qnil;
789  args[3] = tc;
790  asn1data = rb_obj_alloc(klass);
791  ossl_asn1_initialize(4, args, asn1data);
792  if(tag == V_ASN1_BIT_STRING){
793  rb_ivar_set(asn1data, sivUNUSED_BITS, LONG2NUM(flag));
794  }
795  }
796  else {
797  asn1data = rb_obj_alloc(cASN1Data);
798  ossl_asn1data_initialize(asn1data, value, INT2NUM(tag), tc);
799  }
800 
801  return asn1data;
802 }
803 
804 static VALUE
805 int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
806  long *offset, int depth, int yield, int j,
807  int tag, VALUE tc, long *num_read)
808 {
809  VALUE value, asn1data, ary;
810  int indefinite;
811  long available_len, off = *offset;
812 
813  indefinite = (j == 0x21);
814  ary = rb_ary_new();
815 
816  available_len = indefinite ? max_len : length;
817  while (available_len > 0) {
818  long inner_read = 0;
819  value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read);
820  *num_read += inner_read;
821  available_len -= inner_read;
822 
823  if (indefinite &&
824  ossl_asn1_tag(value) == V_ASN1_EOC &&
825  ossl_asn1_get_tag_class(value) == sym_UNIVERSAL) {
826  break;
827  }
828  rb_ary_push(ary, value);
829  }
830 
831  if (tc == sym_UNIVERSAL) {
832  VALUE args[4];
833  if (tag == V_ASN1_SEQUENCE || tag == V_ASN1_SET)
834  asn1data = rb_obj_alloc(*ossl_asn1_info[tag].klass);
835  else
836  asn1data = rb_obj_alloc(cASN1Constructive);
837  args[0] = ary;
838  args[1] = INT2NUM(tag);
839  args[2] = Qnil;
840  args[3] = tc;
841  ossl_asn1_initialize(4, args, asn1data);
842  }
843  else {
844  asn1data = rb_obj_alloc(cASN1Data);
845  ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), tc);
846  }
847 
848  if (indefinite)
850  else
852 
853  *offset = off;
854  return asn1data;
855 }
856 
857 static VALUE
858 ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth,
859  int yield, long *num_read)
860 {
861  unsigned char *start, *p;
862  const unsigned char *p0;
863  long len = 0, inner_read = 0, off = *offset, hlen;
864  int tag, tc, j;
865  VALUE asn1data, tag_class;
866 
867  p = *pp;
868  start = p;
869  p0 = p;
870  j = ASN1_get_object(&p0, &len, &tag, &tc, length);
871  p = (unsigned char *)p0;
872  if(j & 0x80) ossl_raise(eASN1Error, NULL);
873  if(len > length) ossl_raise(eASN1Error, "value is too short");
874  if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
875  tag_class = sym_PRIVATE;
876  else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
877  tag_class = sym_CONTEXT_SPECIFIC;
878  else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
879  tag_class = sym_APPLICATION;
880  else
881  tag_class = sym_UNIVERSAL;
882 
883  hlen = p - start;
884 
885  if(yield) {
886  VALUE arg = rb_ary_new();
887  rb_ary_push(arg, LONG2NUM(depth));
888  rb_ary_push(arg, LONG2NUM(*offset));
889  rb_ary_push(arg, LONG2NUM(hlen));
890  rb_ary_push(arg, LONG2NUM(len));
891  rb_ary_push(arg, (j & V_ASN1_CONSTRUCTED) ? Qtrue : Qfalse);
892  rb_ary_push(arg, ossl_asn1_class2sym(tc));
893  rb_ary_push(arg, INT2NUM(tag));
894  rb_yield(arg);
895  }
896 
897  if(j & V_ASN1_CONSTRUCTED) {
898  *pp += hlen;
899  off += hlen;
900  asn1data = int_ossl_asn1_decode0_cons(pp, length - hlen, len, &off, depth, yield, j, tag, tag_class, &inner_read);
901  inner_read += hlen;
902  }
903  else {
904  if ((j & 0x01) && (len == 0))
905  ossl_raise(eASN1Error, "indefinite length for primitive value");
906  asn1data = int_ossl_asn1_decode0_prim(pp, len, hlen, tag, tag_class, &inner_read);
907  off += hlen + len;
908  }
909  if (num_read)
910  *num_read = inner_read;
911  if (len != 0 && inner_read != hlen + len) {
913  "Type mismatch. Bytes read: %ld Bytes available: %ld",
914  inner_read, hlen + len);
915  }
916 
917  *offset = off;
918  return asn1data;
919 }
920 
921 static void
922 int_ossl_decode_sanity_check(long len, long read, long offset)
923 {
924  if (len != 0 && (read != len || offset != len)) {
926  "Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld",
927  read, len, offset);
928  }
929 }
930 
931 /*
932  * call-seq:
933  * OpenSSL::ASN1.traverse(asn1) -> nil
934  *
935  * If a block is given, it prints out each of the elements encountered.
936  * Block parameters are (in that order):
937  * * depth: The recursion depth, plus one with each constructed value being encountered (Integer)
938  * * offset: Current byte offset (Integer)
939  * * header length: Combined length in bytes of the Tag and Length headers. (Integer)
940  * * length: The overall remaining length of the entire data (Integer)
941  * * constructed: Whether this value is constructed or not (Boolean)
942  * * tag_class: Current tag class (Symbol)
943  * * tag: The current tag number (Integer)
944  *
945  * == Example
946  * der = File.binread('asn1data.der')
947  * OpenSSL::ASN1.traverse(der) do | depth, offset, header_len, length, constructed, tag_class, tag|
948  * puts "Depth: #{depth} Offset: #{offset} Length: #{length}"
949  * puts "Header length: #{header_len} Tag: #{tag} Tag class: #{tag_class} Constructed: #{constructed}"
950  * end
951  */
952 static VALUE
953 ossl_asn1_traverse(VALUE self, VALUE obj)
954 {
955  unsigned char *p;
956  VALUE tmp;
957  long len, read = 0, offset = 0;
958 
959  obj = ossl_to_der_if_possible(obj);
960  tmp = rb_str_new4(StringValue(obj));
961  p = (unsigned char *)RSTRING_PTR(tmp);
962  len = RSTRING_LEN(tmp);
963  ossl_asn1_decode0(&p, len, &offset, 0, 1, &read);
964  RB_GC_GUARD(tmp);
965  int_ossl_decode_sanity_check(len, read, offset);
966  return Qnil;
967 }
968 
969 /*
970  * call-seq:
971  * OpenSSL::ASN1.decode(der) -> ASN1Data
972  *
973  * Decodes a BER- or DER-encoded value and creates an ASN1Data instance. _der_
974  * may be a String or any object that features a +.to_der+ method transforming
975  * it into a BER-/DER-encoded String+
976  *
977  * == Example
978  * der = File.binread('asn1data')
979  * asn1 = OpenSSL::ASN1.decode(der)
980  */
981 static VALUE
982 ossl_asn1_decode(VALUE self, VALUE obj)
983 {
984  VALUE ret;
985  unsigned char *p;
986  VALUE tmp;
987  long len, read = 0, offset = 0;
988 
989  obj = ossl_to_der_if_possible(obj);
990  tmp = rb_str_new4(StringValue(obj));
991  p = (unsigned char *)RSTRING_PTR(tmp);
992  len = RSTRING_LEN(tmp);
993  ret = ossl_asn1_decode0(&p, len, &offset, 0, 0, &read);
994  RB_GC_GUARD(tmp);
995  int_ossl_decode_sanity_check(len, read, offset);
996  return ret;
997 }
998 
999 /*
1000  * call-seq:
1001  * OpenSSL::ASN1.decode_all(der) -> Array of ASN1Data
1002  *
1003  * Similar to #decode with the difference that #decode expects one
1004  * distinct value represented in _der_. #decode_all on the contrary
1005  * decodes a sequence of sequential BER/DER values lined up in _der_
1006  * and returns them as an array.
1007  *
1008  * == Example
1009  * ders = File.binread('asn1data_seq')
1010  * asn1_ary = OpenSSL::ASN1.decode_all(ders)
1011  */
1012 static VALUE
1013 ossl_asn1_decode_all(VALUE self, VALUE obj)
1014 {
1015  VALUE ary, val;
1016  unsigned char *p;
1017  long len, tmp_len = 0, read = 0, offset = 0;
1018  VALUE tmp;
1019 
1020  obj = ossl_to_der_if_possible(obj);
1021  tmp = rb_str_new4(StringValue(obj));
1022  p = (unsigned char *)RSTRING_PTR(tmp);
1023  len = RSTRING_LEN(tmp);
1024  tmp_len = len;
1025  ary = rb_ary_new();
1026  while (tmp_len > 0) {
1027  long tmp_read = 0;
1028  val = ossl_asn1_decode0(&p, tmp_len, &offset, 0, 0, &tmp_read);
1029  rb_ary_push(ary, val);
1030  read += tmp_read;
1031  tmp_len -= tmp_read;
1032  }
1033  RB_GC_GUARD(tmp);
1034  int_ossl_decode_sanity_check(len, read, offset);
1035  return ary;
1036 }
1037 
1038 /*
1039  * call-seq:
1040  * OpenSSL::ASN1::Primitive.new(value [, tag, tagging, tag_class ]) => Primitive
1041  *
1042  * _value_: is mandatory.
1043  *
1044  * _tag_: optional, may be specified for tagged values. If no _tag_ is
1045  * specified, the UNIVERSAL tag corresponding to the Primitive sub-class
1046  * is used by default.
1047  *
1048  * _tagging_: may be used as an encoding hint to encode a value either
1049  * explicitly or implicitly, see ASN1 for possible values.
1050  *
1051  * _tag_class_: if _tag_ and _tagging_ are +nil+ then this is set to
1052  * +:UNIVERSAL+ by default. If either _tag_ or _tagging_ are set then
1053  * +:CONTEXT_SPECIFIC+ is used as the default. For possible values please
1054  * cf. ASN1.
1055  *
1056  * == Example
1057  * int = OpenSSL::ASN1::Integer.new(42)
1058  * zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :IMPLICIT)
1059  * private_explicit_zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :EXPLICIT, :PRIVATE)
1060  */
1061 static VALUE
1062 ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
1063 {
1064  VALUE value, tag, tagging, tag_class;
1065  int default_tag;
1066 
1067  rb_scan_args(argc, argv, "13", &value, &tag, &tagging, &tag_class);
1068  default_tag = ossl_asn1_default_tag(self);
1069 
1070  if (default_tag == -1 || argc > 1) {
1071  if(NIL_P(tag))
1072  ossl_raise(eASN1Error, "must specify tag number");
1073  if(!NIL_P(tagging) && !SYMBOL_P(tagging))
1074  ossl_raise(eASN1Error, "invalid tagging method");
1075  if(NIL_P(tag_class)) {
1076  if (NIL_P(tagging))
1077  tag_class = sym_UNIVERSAL;
1078  else
1079  tag_class = sym_CONTEXT_SPECIFIC;
1080  }
1081  if(!SYMBOL_P(tag_class))
1082  ossl_raise(eASN1Error, "invalid tag class");
1083  }
1084  else{
1085  tag = INT2NUM(default_tag);
1086  tagging = Qnil;
1087  tag_class = sym_UNIVERSAL;
1088  }
1089  ossl_asn1_set_tag(self, tag);
1090  ossl_asn1_set_value(self, value);
1091  ossl_asn1_set_tagging(self, tagging);
1092  ossl_asn1_set_tag_class(self, tag_class);
1094  if (default_tag == V_ASN1_BIT_STRING)
1095  rb_ivar_set(self, sivUNUSED_BITS, INT2FIX(0));
1096 
1097  return self;
1098 }
1099 
1100 static VALUE
1101 ossl_asn1eoc_initialize(VALUE self) {
1102  VALUE tag, tagging, tag_class, value;
1103  tag = INT2FIX(0);
1104  tagging = Qnil;
1105  tag_class = sym_UNIVERSAL;
1106  value = rb_str_new("", 0);
1107  ossl_asn1_set_tag(self, tag);
1108  ossl_asn1_set_value(self, value);
1109  ossl_asn1_set_tagging(self, tagging);
1110  ossl_asn1_set_tag_class(self, tag_class);
1112  return self;
1113 }
1114 
1115 static VALUE
1116 ossl_asn1eoc_to_der(VALUE self)
1117 {
1118  return rb_str_new("\0\0", 2);
1119 }
1120 
1121 /*
1122  * call-seq:
1123  * asn1.to_der => DER-encoded String
1124  *
1125  * See ASN1Data#to_der for details.
1126  */
1127 static VALUE
1128 ossl_asn1prim_to_der(VALUE self)
1129 {
1130  ASN1_TYPE *asn1;
1131  long alllen, bodylen;
1132  unsigned char *p0, *p1;
1133  int j, tag, tc, state;
1134  VALUE str;
1135 
1136  if (ossl_asn1_default_tag(self) == -1) {
1137  str = ossl_asn1_get_value(self);
1138  return to_der_internal(self, 0, 0, StringValue(str));
1139  }
1140 
1141  asn1 = ossl_asn1_get_asn1type(self);
1142  alllen = i2d_ASN1_TYPE(asn1, NULL);
1143  if (alllen < 0) {
1144  ASN1_TYPE_free(asn1);
1145  ossl_raise(eASN1Error, "i2d_ASN1_TYPE");
1146  }
1147  str = ossl_str_new(NULL, alllen, &state);
1148  if (state) {
1149  ASN1_TYPE_free(asn1);
1150  rb_jump_tag(state);
1151  }
1152  p0 = p1 = (unsigned char *)RSTRING_PTR(str);
1153  i2d_ASN1_TYPE(asn1, &p0);
1154  ASN1_TYPE_free(asn1);
1155  assert(p0 - p1 == alllen);
1156 
1157  /* Strip header since to_der_internal() wants only the payload */
1158  j = ASN1_get_object((const unsigned char **)&p1, &bodylen, &tag, &tc, alllen);
1159  if (j & 0x80)
1160  ossl_raise(eASN1Error, "ASN1_get_object"); /* should not happen */
1161 
1162  return to_der_internal(self, 0, 0, rb_str_drop_bytes(str, alllen - bodylen));
1163 }
1164 
1165 /*
1166  * call-seq:
1167  * asn1.to_der => DER-encoded String
1168  *
1169  * See ASN1Data#to_der for details.
1170  */
1171 static VALUE
1172 ossl_asn1cons_to_der(VALUE self)
1173 {
1174  VALUE ary, str;
1175  long i;
1176  int indef_len;
1177 
1178  indef_len = RTEST(ossl_asn1_get_indefinite_length(self));
1179  ary = rb_convert_type(ossl_asn1_get_value(self), T_ARRAY, "Array", "to_a");
1180  str = rb_str_new(NULL, 0);
1181  for (i = 0; i < RARRAY_LEN(ary); i++) {
1182  VALUE item = RARRAY_AREF(ary, i);
1183 
1184  if (indef_len && rb_obj_is_kind_of(item, cASN1EndOfContent)) {
1185  if (i != RARRAY_LEN(ary) - 1)
1186  ossl_raise(eASN1Error, "illegal EOC octets in value");
1187 
1188  /*
1189  * EOC is not really part of the content, but we required to add one
1190  * at the end in the past.
1191  */
1192  break;
1193  }
1194 
1195  item = ossl_to_der_if_possible(item);
1196  StringValue(item);
1197  rb_str_append(str, item);
1198  }
1199 
1200  return to_der_internal(self, 1, indef_len, str);
1201 }
1202 
1203 /*
1204  * call-seq:
1205  * asn1_ary.each { |asn1| block } => asn1_ary
1206  *
1207  * Calls the given block once for each element in self, passing that element
1208  * as parameter _asn1_. If no block is given, an enumerator is returned
1209  * instead.
1210  *
1211  * == Example
1212  * asn1_ary.each do |asn1|
1213  * puts asn1
1214  * end
1215  */
1216 static VALUE
1217 ossl_asn1cons_each(VALUE self)
1218 {
1219  rb_block_call(ossl_asn1_get_value(self), id_each, 0, 0, 0, 0);
1220 
1221  return self;
1222 }
1223 
1224 /*
1225  * call-seq:
1226  * OpenSSL::ASN1::ObjectId.register(object_id, short_name, long_name)
1227  *
1228  * This adds a new ObjectId to the internal tables. Where _object_id_ is the
1229  * numerical form, _short_name_ is the short name, and _long_name_ is the long
1230  * name.
1231  *
1232  * Returns +true+ if successful. Raises an OpenSSL::ASN1::ASN1Error if it fails.
1233  *
1234  */
1235 static VALUE
1236 ossl_asn1obj_s_register(VALUE self, VALUE oid, VALUE sn, VALUE ln)
1237 {
1238  StringValueCStr(oid);
1239  StringValueCStr(sn);
1240  StringValueCStr(ln);
1241 
1242  if(!OBJ_create(RSTRING_PTR(oid), RSTRING_PTR(sn), RSTRING_PTR(ln)))
1244 
1245  return Qtrue;
1246 }
1247 
1248 /*
1249  * call-seq:
1250  * oid.sn -> string
1251  * oid.short_name -> string
1252  *
1253  * The short name of the ObjectId, as defined in <openssl/objects.h>.
1254  */
1255 static VALUE
1256 ossl_asn1obj_get_sn(VALUE self)
1257 {
1258  VALUE val, ret = Qnil;
1259  int nid;
1260 
1261  val = ossl_asn1_get_value(self);
1262  if ((nid = OBJ_txt2nid(StringValueCStr(val))) != NID_undef)
1263  ret = rb_str_new2(OBJ_nid2sn(nid));
1264 
1265  return ret;
1266 }
1267 
1268 /*
1269  * call-seq:
1270  * oid.ln -> string
1271  * oid.long_name -> string
1272  *
1273  * The long name of the ObjectId, as defined in <openssl/objects.h>.
1274  */
1275 static VALUE
1276 ossl_asn1obj_get_ln(VALUE self)
1277 {
1278  VALUE val, ret = Qnil;
1279  int nid;
1280 
1281  val = ossl_asn1_get_value(self);
1282  if ((nid = OBJ_txt2nid(StringValueCStr(val))) != NID_undef)
1283  ret = rb_str_new2(OBJ_nid2ln(nid));
1284 
1285  return ret;
1286 }
1287 
1288 static VALUE
1289 asn1obj_get_oid_i(VALUE vobj)
1290 {
1291  ASN1_OBJECT *a1obj = (void *)vobj;
1292  VALUE str;
1293  int len;
1294 
1295  str = rb_usascii_str_new(NULL, 127);
1296  len = OBJ_obj2txt(RSTRING_PTR(str), RSTRING_LENINT(str), a1obj, 1);
1297  if (len <= 0 || len == INT_MAX)
1298  ossl_raise(eASN1Error, "OBJ_obj2txt");
1299  if (len > RSTRING_LEN(str)) {
1300  /* +1 is for the \0 terminator added by OBJ_obj2txt() */
1301  rb_str_resize(str, len + 1);
1302  len = OBJ_obj2txt(RSTRING_PTR(str), len + 1, a1obj, 1);
1303  if (len <= 0)
1304  ossl_raise(eASN1Error, "OBJ_obj2txt");
1305  }
1306  rb_str_set_len(str, len);
1307  return str;
1308 }
1309 
1310 /*
1311  * call-seq:
1312  * oid.oid -> string
1313  *
1314  * Returns a String representing the Object Identifier in the dot notation,
1315  * e.g. "1.2.3.4.5"
1316  */
1317 static VALUE
1318 ossl_asn1obj_get_oid(VALUE self)
1319 {
1320  VALUE str;
1321  ASN1_OBJECT *a1obj;
1322  int state;
1323 
1324  a1obj = obj_to_asn1obj(ossl_asn1_get_value(self));
1325  str = rb_protect(asn1obj_get_oid_i, (VALUE)a1obj, &state);
1326  ASN1_OBJECT_free(a1obj);
1327  if (state)
1328  rb_jump_tag(state);
1329  return str;
1330 }
1331 
1332 #define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \
1333 static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\
1334 { return rb_funcall3(cASN1##klass, rb_intern("new"), argc, argv); }
1335 
1340 OSSL_ASN1_IMPL_FACTORY_METHOD(OctetString)
1342 OSSL_ASN1_IMPL_FACTORY_METHOD(NumericString)
1343 OSSL_ASN1_IMPL_FACTORY_METHOD(PrintableString)
1345 OSSL_ASN1_IMPL_FACTORY_METHOD(VideotexString)
1347 OSSL_ASN1_IMPL_FACTORY_METHOD(GraphicString)
1348 OSSL_ASN1_IMPL_FACTORY_METHOD(ISO64String)
1349 OSSL_ASN1_IMPL_FACTORY_METHOD(GeneralString)
1350 OSSL_ASN1_IMPL_FACTORY_METHOD(UniversalString)
1355 OSSL_ASN1_IMPL_FACTORY_METHOD(GeneralizedTime)
1358 OSSL_ASN1_IMPL_FACTORY_METHOD(EndOfContent)
1359 
1360 void
1362 {
1363  VALUE ary;
1364  int i;
1365 
1366 #if 0
1367  mOSSL = rb_define_module("OpenSSL");
1369 #endif
1370 
1371  sym_UNIVERSAL = ID2SYM(rb_intern_const("UNIVERSAL"));
1372  sym_CONTEXT_SPECIFIC = ID2SYM(rb_intern_const("CONTEXT_SPECIFIC"));
1373  sym_APPLICATION = ID2SYM(rb_intern_const("APPLICATION"));
1374  sym_PRIVATE = ID2SYM(rb_intern_const("PRIVATE"));
1375  sym_EXPLICIT = ID2SYM(rb_intern_const("EXPLICIT"));
1376  sym_IMPLICIT = ID2SYM(rb_intern_const("IMPLICIT"));
1377 
1378  sivVALUE = rb_intern("@value");
1379  sivTAG = rb_intern("@tag");
1380  sivTAGGING = rb_intern("@tagging");
1381  sivTAG_CLASS = rb_intern("@tag_class");
1382  sivINDEFINITE_LENGTH = rb_intern("@indefinite_length");
1383  sivUNUSED_BITS = rb_intern("@unused_bits");
1384 
1385  /*
1386  * Document-module: OpenSSL::ASN1
1387  *
1388  * Abstract Syntax Notation One (or ASN.1) is a notation syntax to
1389  * describe data structures and is defined in ITU-T X.680. ASN.1 itself
1390  * does not mandate any encoding or parsing rules, but usually ASN.1 data
1391  * structures are encoded using the Distinguished Encoding Rules (DER) or
1392  * less often the Basic Encoding Rules (BER) described in ITU-T X.690. DER
1393  * and BER encodings are binary Tag-Length-Value (TLV) encodings that are
1394  * quite concise compared to other popular data description formats such
1395  * as XML, JSON etc.
1396  * ASN.1 data structures are very common in cryptographic applications,
1397  * e.g. X.509 public key certificates or certificate revocation lists
1398  * (CRLs) are all defined in ASN.1 and DER-encoded. ASN.1, DER and BER are
1399  * the building blocks of applied cryptography.
1400  * The ASN1 module provides the necessary classes that allow generation
1401  * of ASN.1 data structures and the methods to encode them using a DER
1402  * encoding. The decode method allows parsing arbitrary BER-/DER-encoded
1403  * data to a Ruby object that can then be modified and re-encoded at will.
1404  *
1405  * == ASN.1 class hierarchy
1406  *
1407  * The base class representing ASN.1 structures is ASN1Data. ASN1Data offers
1408  * attributes to read and set the _tag_, the _tag_class_ and finally the
1409  * _value_ of a particular ASN.1 item. Upon parsing, any tagged values
1410  * (implicit or explicit) will be represented by ASN1Data instances because
1411  * their "real type" can only be determined using out-of-band information
1412  * from the ASN.1 type declaration. Since this information is normally
1413  * known when encoding a type, all sub-classes of ASN1Data offer an
1414  * additional attribute _tagging_ that allows to encode a value implicitly
1415  * (+:IMPLICIT+) or explicitly (+:EXPLICIT+).
1416  *
1417  * === Constructive
1418  *
1419  * Constructive is, as its name implies, the base class for all
1420  * constructed encodings, i.e. those that consist of several values,
1421  * opposed to "primitive" encodings with just one single value. The value of
1422  * an Constructive is always an Array.
1423  *
1424  * ==== ASN1::Set and ASN1::Sequence
1425  *
1426  * The most common constructive encodings are SETs and SEQUENCEs, which is
1427  * why there are two sub-classes of Constructive representing each of
1428  * them.
1429  *
1430  * === Primitive
1431  *
1432  * This is the super class of all primitive values. Primitive
1433  * itself is not used when parsing ASN.1 data, all values are either
1434  * instances of a corresponding sub-class of Primitive or they are
1435  * instances of ASN1Data if the value was tagged implicitly or explicitly.
1436  * Please cf. Primitive documentation for details on sub-classes and
1437  * their respective mappings of ASN.1 data types to Ruby objects.
1438  *
1439  * == Possible values for _tagging_
1440  *
1441  * When constructing an ASN1Data object the ASN.1 type definition may
1442  * require certain elements to be either implicitly or explicitly tagged.
1443  * This can be achieved by setting the _tagging_ attribute manually for
1444  * sub-classes of ASN1Data. Use the symbol +:IMPLICIT+ for implicit
1445  * tagging and +:EXPLICIT+ if the element requires explicit tagging.
1446  *
1447  * == Possible values for _tag_class_
1448  *
1449  * It is possible to create arbitrary ASN1Data objects that also support
1450  * a PRIVATE or APPLICATION tag class. Possible values for the _tag_class_
1451  * attribute are:
1452  * * +:UNIVERSAL+ (the default for untagged values)
1453  * * +:CONTEXT_SPECIFIC+ (the default for tagged values)
1454  * * +:APPLICATION+
1455  * * +:PRIVATE+
1456  *
1457  * == Tag constants
1458  *
1459  * There is a constant defined for each universal tag:
1460  * * OpenSSL::ASN1::EOC (0)
1461  * * OpenSSL::ASN1::BOOLEAN (1)
1462  * * OpenSSL::ASN1::INTEGER (2)
1463  * * OpenSSL::ASN1::BIT_STRING (3)
1464  * * OpenSSL::ASN1::OCTET_STRING (4)
1465  * * OpenSSL::ASN1::NULL (5)
1466  * * OpenSSL::ASN1::OBJECT (6)
1467  * * OpenSSL::ASN1::ENUMERATED (10)
1468  * * OpenSSL::ASN1::UTF8STRING (12)
1469  * * OpenSSL::ASN1::SEQUENCE (16)
1470  * * OpenSSL::ASN1::SET (17)
1471  * * OpenSSL::ASN1::NUMERICSTRING (18)
1472  * * OpenSSL::ASN1::PRINTABLESTRING (19)
1473  * * OpenSSL::ASN1::T61STRING (20)
1474  * * OpenSSL::ASN1::VIDEOTEXSTRING (21)
1475  * * OpenSSL::ASN1::IA5STRING (22)
1476  * * OpenSSL::ASN1::UTCTIME (23)
1477  * * OpenSSL::ASN1::GENERALIZEDTIME (24)
1478  * * OpenSSL::ASN1::GRAPHICSTRING (25)
1479  * * OpenSSL::ASN1::ISO64STRING (26)
1480  * * OpenSSL::ASN1::GENERALSTRING (27)
1481  * * OpenSSL::ASN1::UNIVERSALSTRING (28)
1482  * * OpenSSL::ASN1::BMPSTRING (30)
1483  *
1484  * == UNIVERSAL_TAG_NAME constant
1485  *
1486  * An Array that stores the name of a given tag number. These names are
1487  * the same as the name of the tag constant that is additionally defined,
1488  * e.g. UNIVERSAL_TAG_NAME[2] = "INTEGER" and OpenSSL::ASN1::INTEGER = 2.
1489  *
1490  * == Example usage
1491  *
1492  * === Decoding and viewing a DER-encoded file
1493  * require 'openssl'
1494  * require 'pp'
1495  * der = File.binread('data.der')
1496  * asn1 = OpenSSL::ASN1.decode(der)
1497  * pp der
1498  *
1499  * === Creating an ASN.1 structure and DER-encoding it
1500  * require 'openssl'
1501  * version = OpenSSL::ASN1::Integer.new(1)
1502  * # Explicitly 0-tagged implies context-specific tag class
1503  * serial = OpenSSL::ASN1::Integer.new(12345, 0, :EXPLICIT, :CONTEXT_SPECIFIC)
1504  * name = OpenSSL::ASN1::PrintableString.new('Data 1')
1505  * sequence = OpenSSL::ASN1::Sequence.new( [ version, serial, name ] )
1506  * der = sequence.to_der
1507  */
1508  mASN1 = rb_define_module_under(mOSSL, "ASN1");
1509 
1510  /* Document-class: OpenSSL::ASN1::ASN1Error
1511  *
1512  * Generic error class for all errors raised in ASN1 and any of the
1513  * classes defined in it.
1514  */
1516  rb_define_module_function(mASN1, "traverse", ossl_asn1_traverse, 1);
1517  rb_define_module_function(mASN1, "decode", ossl_asn1_decode, 1);
1518  rb_define_module_function(mASN1, "decode_all", ossl_asn1_decode_all, 1);
1519  ary = rb_ary_new();
1520 
1521  /*
1522  * Array storing tag names at the tag's index.
1523  */
1524  rb_define_const(mASN1, "UNIVERSAL_TAG_NAME", ary);
1525  for(i = 0; i < ossl_asn1_info_size; i++){
1526  if(ossl_asn1_info[i].name[0] == '[') continue;
1527  rb_define_const(mASN1, ossl_asn1_info[i].name, INT2NUM(i));
1528  rb_ary_store(ary, i, rb_str_new2(ossl_asn1_info[i].name));
1529  }
1530 
1531  /* Document-class: OpenSSL::ASN1::ASN1Data
1532  *
1533  * The top-level class representing any ASN.1 object. When parsed by
1534  * ASN1.decode, tagged values are always represented by an instance
1535  * of ASN1Data.
1536  *
1537  * == The role of ASN1Data for parsing tagged values
1538  *
1539  * When encoding an ASN.1 type it is inherently clear what original
1540  * type (e.g. INTEGER, OCTET STRING etc.) this value has, regardless
1541  * of its tagging.
1542  * But opposed to the time an ASN.1 type is to be encoded, when parsing
1543  * them it is not possible to deduce the "real type" of tagged
1544  * values. This is why tagged values are generally parsed into ASN1Data
1545  * instances, but with a different outcome for implicit and explicit
1546  * tagging.
1547  *
1548  * === Example of a parsed implicitly tagged value
1549  *
1550  * An implicitly 1-tagged INTEGER value will be parsed as an
1551  * ASN1Data with
1552  * * _tag_ equal to 1
1553  * * _tag_class_ equal to +:CONTEXT_SPECIFIC+
1554  * * _value_ equal to a String that carries the raw encoding
1555  * of the INTEGER.
1556  * This implies that a subsequent decoding step is required to
1557  * completely decode implicitly tagged values.
1558  *
1559  * === Example of a parsed explicitly tagged value
1560  *
1561  * An explicitly 1-tagged INTEGER value will be parsed as an
1562  * ASN1Data with
1563  * * _tag_ equal to 1
1564  * * _tag_class_ equal to +:CONTEXT_SPECIFIC+
1565  * * _value_ equal to an Array with one single element, an
1566  * instance of OpenSSL::ASN1::Integer, i.e. the inner element
1567  * is the non-tagged primitive value, and the tagging is represented
1568  * in the outer ASN1Data
1569  *
1570  * == Example - Decoding an implicitly tagged INTEGER
1571  * int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT) # implicit 0-tagged
1572  * seq = OpenSSL::ASN1::Sequence.new( [int] )
1573  * der = seq.to_der
1574  * asn1 = OpenSSL::ASN1.decode(der)
1575  * # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0
1576  * # @indefinite_length=false,
1577  * # @tag=16,
1578  * # @tag_class=:UNIVERSAL,
1579  * # @tagging=nil,
1580  * # @value=
1581  * # [#<OpenSSL::ASN1::ASN1Data:0x87326f4
1582  * # @indefinite_length=false,
1583  * # @tag=0,
1584  * # @tag_class=:CONTEXT_SPECIFIC,
1585  * # @value="\x01">]>
1586  * raw_int = asn1.value[0]
1587  * # manually rewrite tag and tag class to make it an UNIVERSAL value
1588  * raw_int.tag = OpenSSL::ASN1::INTEGER
1589  * raw_int.tag_class = :UNIVERSAL
1590  * int2 = OpenSSL::ASN1.decode(raw_int)
1591  * puts int2.value # => 1
1592  *
1593  * == Example - Decoding an explicitly tagged INTEGER
1594  * int = OpenSSL::ASN1::Integer.new(1, 0, :EXPLICIT) # explicit 0-tagged
1595  * seq = OpenSSL::ASN1::Sequence.new( [int] )
1596  * der = seq.to_der
1597  * asn1 = OpenSSL::ASN1.decode(der)
1598  * # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0
1599  * # @indefinite_length=false,
1600  * # @tag=16,
1601  * # @tag_class=:UNIVERSAL,
1602  * # @tagging=nil,
1603  * # @value=
1604  * # [#<OpenSSL::ASN1::ASN1Data:0x87326f4
1605  * # @indefinite_length=false,
1606  * # @tag=0,
1607  * # @tag_class=:CONTEXT_SPECIFIC,
1608  * # @value=
1609  * # [#<OpenSSL::ASN1::Integer:0x85bf308
1610  * # @indefinite_length=false,
1611  * # @tag=2,
1612  * # @tag_class=:UNIVERSAL
1613  * # @tagging=nil,
1614  * # @value=1>]>]>
1615  * int2 = asn1.value[0].value[0]
1616  * puts int2.value # => 1
1617  */
1619  /*
1620  * Carries the value of a ASN.1 type.
1621  * Please confer Constructive and Primitive for the mappings between
1622  * ASN.1 data types and Ruby classes.
1623  */
1624  rb_attr(cASN1Data, rb_intern("value"), 1, 1, 0);
1625  /*
1626  * An Integer representing the tag number of this ASN1Data. Never +nil+.
1627  */
1628  rb_attr(cASN1Data, rb_intern("tag"), 1, 1, 0);
1629  /*
1630  * A Symbol representing the tag class of this ASN1Data. Never +nil+.
1631  * See ASN1Data for possible values.
1632  */
1633  rb_attr(cASN1Data, rb_intern("tag_class"), 1, 1, 0);
1634  /*
1635  * Never +nil+. A boolean value indicating whether the encoding uses
1636  * indefinite length (in the case of parsing) or whether an indefinite
1637  * length form shall be used (in the encoding case).
1638  * In DER, every value uses definite length form. But in scenarios where
1639  * large amounts of data need to be transferred it might be desirable to
1640  * have some kind of streaming support available.
1641  * For example, huge OCTET STRINGs are preferably sent in smaller-sized
1642  * chunks, each at a time.
1643  * This is possible in BER by setting the length bytes of an encoding
1644  * to zero and by this indicating that the following value will be
1645  * sent in chunks. Indefinite length encodings are always constructed.
1646  * The end of such a stream of chunks is indicated by sending a EOC
1647  * (End of Content) tag. SETs and SEQUENCEs may use an indefinite length
1648  * encoding, but also primitive types such as e.g. OCTET STRINGS or
1649  * BIT STRINGS may leverage this functionality (cf. ITU-T X.690).
1650  */
1651  rb_attr(cASN1Data, rb_intern("indefinite_length"), 1, 1, 0);
1652  rb_define_alias(cASN1Data, "infinite_length", "indefinite_length");
1653  rb_define_alias(cASN1Data, "infinite_length=", "indefinite_length=");
1654  rb_define_method(cASN1Data, "initialize", ossl_asn1data_initialize, 3);
1655  rb_define_method(cASN1Data, "to_der", ossl_asn1data_to_der, 0);
1656 
1657  /* Document-class: OpenSSL::ASN1::Primitive
1658  *
1659  * The parent class for all primitive encodings. Attributes are the same as
1660  * for ASN1Data, with the addition of _tagging_.
1661  * Primitive values can never be encoded with indefinite length form, thus
1662  * it is not possible to set the _indefinite_length_ attribute for Primitive
1663  * and its sub-classes.
1664  *
1665  * == Primitive sub-classes and their mapping to Ruby classes
1666  * * OpenSSL::ASN1::EndOfContent <=> _value_ is always +nil+
1667  * * OpenSSL::ASN1::Boolean <=> _value_ is +true+ or +false+
1668  * * OpenSSL::ASN1::Integer <=> _value_ is an Integer
1669  * * OpenSSL::ASN1::BitString <=> _value_ is a String
1670  * * OpenSSL::ASN1::OctetString <=> _value_ is a String
1671  * * OpenSSL::ASN1::Null <=> _value_ is always +nil+
1672  * * OpenSSL::ASN1::Object <=> _value_ is a String
1673  * * OpenSSL::ASN1::Enumerated <=> _value_ is an Integer
1674  * * OpenSSL::ASN1::UTF8String <=> _value_ is a String
1675  * * OpenSSL::ASN1::NumericString <=> _value_ is a String
1676  * * OpenSSL::ASN1::PrintableString <=> _value_ is a String
1677  * * OpenSSL::ASN1::T61String <=> _value_ is a String
1678  * * OpenSSL::ASN1::VideotexString <=> _value_ is a String
1679  * * OpenSSL::ASN1::IA5String <=> _value_ is a String
1680  * * OpenSSL::ASN1::UTCTime <=> _value_ is a Time
1681  * * OpenSSL::ASN1::GeneralizedTime <=> _value_ is a Time
1682  * * OpenSSL::ASN1::GraphicString <=> _value_ is a String
1683  * * OpenSSL::ASN1::ISO64String <=> _value_ is a String
1684  * * OpenSSL::ASN1::GeneralString <=> _value_ is a String
1685  * * OpenSSL::ASN1::UniversalString <=> _value_ is a String
1686  * * OpenSSL::ASN1::BMPString <=> _value_ is a String
1687  *
1688  * == OpenSSL::ASN1::BitString
1689  *
1690  * === Additional attributes
1691  * _unused_bits_: if the underlying BIT STRING's
1692  * length is a multiple of 8 then _unused_bits_ is 0. Otherwise
1693  * _unused_bits_ indicates the number of bits that are to be ignored in
1694  * the final octet of the BitString's _value_.
1695  *
1696  * == OpenSSL::ASN1::ObjectId
1697  *
1698  * NOTE: While OpenSSL::ASN1::ObjectId.new will allocate a new ObjectId,
1699  * it is not typically allocated this way, but rather that are received from
1700  * parsed ASN1 encodings.
1701  *
1702  * === Additional attributes
1703  * * _sn_: the short name as defined in <openssl/objects.h>.
1704  * * _ln_: the long name as defined in <openssl/objects.h>.
1705  * * _oid_: the object identifier as a String, e.g. "1.2.3.4.5"
1706  * * _short_name_: alias for _sn_.
1707  * * _long_name_: alias for _ln_.
1708  *
1709  * == Examples
1710  * With the Exception of OpenSSL::ASN1::EndOfContent, each Primitive class
1711  * constructor takes at least one parameter, the _value_.
1712  *
1713  * === Creating EndOfContent
1714  * eoc = OpenSSL::ASN1::EndOfContent.new
1715  *
1716  * === Creating any other Primitive
1717  * prim = <class>.new(value) # <class> being one of the sub-classes except EndOfContent
1718  * prim_zero_tagged_implicit = <class>.new(value, 0, :IMPLICIT)
1719  * prim_zero_tagged_explicit = <class>.new(value, 0, :EXPLICIT)
1720  */
1722  /*
1723  * May be used as a hint for encoding a value either implicitly or
1724  * explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+.
1725  * _tagging_ is not set when a ASN.1 structure is parsed using
1726  * OpenSSL::ASN1.decode.
1727  */
1728  rb_attr(cASN1Primitive, rb_intern("tagging"), 1, 1, Qtrue);
1729  rb_undef_method(cASN1Primitive, "indefinite_length=");
1730  rb_undef_method(cASN1Primitive, "infinite_length=");
1731  rb_define_method(cASN1Primitive, "initialize", ossl_asn1_initialize, -1);
1732  rb_define_method(cASN1Primitive, "to_der", ossl_asn1prim_to_der, 0);
1733 
1734  /* Document-class: OpenSSL::ASN1::Constructive
1735  *
1736  * The parent class for all constructed encodings. The _value_ attribute
1737  * of a Constructive is always an Array. Attributes are the same as
1738  * for ASN1Data, with the addition of _tagging_.
1739  *
1740  * == SET and SEQUENCE
1741  *
1742  * Most constructed encodings come in the form of a SET or a SEQUENCE.
1743  * These encodings are represented by one of the two sub-classes of
1744  * Constructive:
1745  * * OpenSSL::ASN1::Set
1746  * * OpenSSL::ASN1::Sequence
1747  * Please note that tagged sequences and sets are still parsed as
1748  * instances of ASN1Data. Find further details on tagged values
1749  * there.
1750  *
1751  * === Example - constructing a SEQUENCE
1752  * int = OpenSSL::ASN1::Integer.new(1)
1753  * str = OpenSSL::ASN1::PrintableString.new('abc')
1754  * sequence = OpenSSL::ASN1::Sequence.new( [ int, str ] )
1755  *
1756  * === Example - constructing a SET
1757  * int = OpenSSL::ASN1::Integer.new(1)
1758  * str = OpenSSL::ASN1::PrintableString.new('abc')
1759  * set = OpenSSL::ASN1::Set.new( [ int, str ] )
1760  */
1763  /*
1764  * May be used as a hint for encoding a value either implicitly or
1765  * explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+.
1766  * _tagging_ is not set when a ASN.1 structure is parsed using
1767  * OpenSSL::ASN1.decode.
1768  */
1769  rb_attr(cASN1Constructive, rb_intern("tagging"), 1, 1, Qtrue);
1770  rb_define_method(cASN1Constructive, "initialize", ossl_asn1_initialize, -1);
1771  rb_define_method(cASN1Constructive, "to_der", ossl_asn1cons_to_der, 0);
1772  rb_define_method(cASN1Constructive, "each", ossl_asn1cons_each, 0);
1773 
1774 #define OSSL_ASN1_DEFINE_CLASS(name, super) \
1775 do{\
1776  cASN1##name = rb_define_class_under(mASN1, #name, cASN1##super);\
1777  rb_define_module_function(mASN1, #name, ossl_asn1_##name, -1);\
1778 }while(0)
1779 
1780  OSSL_ASN1_DEFINE_CLASS(Boolean, Primitive);
1781  OSSL_ASN1_DEFINE_CLASS(Integer, Primitive);
1782  OSSL_ASN1_DEFINE_CLASS(Enumerated, Primitive);
1783  OSSL_ASN1_DEFINE_CLASS(BitString, Primitive);
1784  OSSL_ASN1_DEFINE_CLASS(OctetString, Primitive);
1785  OSSL_ASN1_DEFINE_CLASS(UTF8String, Primitive);
1786  OSSL_ASN1_DEFINE_CLASS(NumericString, Primitive);
1787  OSSL_ASN1_DEFINE_CLASS(PrintableString, Primitive);
1788  OSSL_ASN1_DEFINE_CLASS(T61String, Primitive);
1789  OSSL_ASN1_DEFINE_CLASS(VideotexString, Primitive);
1790  OSSL_ASN1_DEFINE_CLASS(IA5String, Primitive);
1791  OSSL_ASN1_DEFINE_CLASS(GraphicString, Primitive);
1792  OSSL_ASN1_DEFINE_CLASS(ISO64String, Primitive);
1793  OSSL_ASN1_DEFINE_CLASS(GeneralString, Primitive);
1794  OSSL_ASN1_DEFINE_CLASS(UniversalString, Primitive);
1795  OSSL_ASN1_DEFINE_CLASS(BMPString, Primitive);
1796  OSSL_ASN1_DEFINE_CLASS(Null, Primitive);
1797  OSSL_ASN1_DEFINE_CLASS(ObjectId, Primitive);
1798  OSSL_ASN1_DEFINE_CLASS(UTCTime, Primitive);
1799  OSSL_ASN1_DEFINE_CLASS(GeneralizedTime, Primitive);
1800 
1801  OSSL_ASN1_DEFINE_CLASS(Sequence, Constructive);
1802  OSSL_ASN1_DEFINE_CLASS(Set, Constructive);
1803 
1804  OSSL_ASN1_DEFINE_CLASS(EndOfContent, Data);
1805 
1806 
1807  /* Document-class: OpenSSL::ASN1::ObjectId
1808  *
1809  * Represents the primitive object id for OpenSSL::ASN1
1810  */
1811 #if 0
1812  cASN1ObjectId = rb_define_class_under(mASN1, "ObjectId", cASN1Primitive); /* let rdoc know */
1813 #endif
1814  rb_define_singleton_method(cASN1ObjectId, "register", ossl_asn1obj_s_register, 3);
1815  rb_define_method(cASN1ObjectId, "sn", ossl_asn1obj_get_sn, 0);
1816  rb_define_method(cASN1ObjectId, "ln", ossl_asn1obj_get_ln, 0);
1817  rb_define_method(cASN1ObjectId, "oid", ossl_asn1obj_get_oid, 0);
1818  rb_define_alias(cASN1ObjectId, "short_name", "sn");
1819  rb_define_alias(cASN1ObjectId, "long_name", "ln");
1820  rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);
1821 
1822  rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0);
1823  rb_define_method(cASN1EndOfContent, "to_der", ossl_asn1eoc_to_der, 0);
1824 
1825  class_tag_map = rb_hash_new();
1826  rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC));
1827  rb_hash_aset(class_tag_map, cASN1Boolean, INT2NUM(V_ASN1_BOOLEAN));
1828  rb_hash_aset(class_tag_map, cASN1Integer, INT2NUM(V_ASN1_INTEGER));
1829  rb_hash_aset(class_tag_map, cASN1BitString, INT2NUM(V_ASN1_BIT_STRING));
1830  rb_hash_aset(class_tag_map, cASN1OctetString, INT2NUM(V_ASN1_OCTET_STRING));
1831  rb_hash_aset(class_tag_map, cASN1Null, INT2NUM(V_ASN1_NULL));
1832  rb_hash_aset(class_tag_map, cASN1ObjectId, INT2NUM(V_ASN1_OBJECT));
1833  rb_hash_aset(class_tag_map, cASN1Enumerated, INT2NUM(V_ASN1_ENUMERATED));
1834  rb_hash_aset(class_tag_map, cASN1UTF8String, INT2NUM(V_ASN1_UTF8STRING));
1835  rb_hash_aset(class_tag_map, cASN1Sequence, INT2NUM(V_ASN1_SEQUENCE));
1836  rb_hash_aset(class_tag_map, cASN1Set, INT2NUM(V_ASN1_SET));
1837  rb_hash_aset(class_tag_map, cASN1NumericString, INT2NUM(V_ASN1_NUMERICSTRING));
1838  rb_hash_aset(class_tag_map, cASN1PrintableString, INT2NUM(V_ASN1_PRINTABLESTRING));
1839  rb_hash_aset(class_tag_map, cASN1T61String, INT2NUM(V_ASN1_T61STRING));
1840  rb_hash_aset(class_tag_map, cASN1VideotexString, INT2NUM(V_ASN1_VIDEOTEXSTRING));
1841  rb_hash_aset(class_tag_map, cASN1IA5String, INT2NUM(V_ASN1_IA5STRING));
1842  rb_hash_aset(class_tag_map, cASN1UTCTime, INT2NUM(V_ASN1_UTCTIME));
1843  rb_hash_aset(class_tag_map, cASN1GeneralizedTime, INT2NUM(V_ASN1_GENERALIZEDTIME));
1844  rb_hash_aset(class_tag_map, cASN1GraphicString, INT2NUM(V_ASN1_GRAPHICSTRING));
1845  rb_hash_aset(class_tag_map, cASN1ISO64String, INT2NUM(V_ASN1_ISO64STRING));
1846  rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING));
1847  rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING));
1848  rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING));
1849  rb_global_variable(&class_tag_map);
1850 
1851  id_each = rb_intern_const("each");
1852 }
VALUE mOSSL
Definition: ossl.c:231
VALUE cASN1Data
Definition: ossl_asn1.c:158
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
Definition: eval.c:992
#define rb_str_new4
Definition: intern.h:837
#define ossl_asn1_get_tagging(o)
Definition: ossl_asn1.c:145
#define RARRAY_LEN(a)
Definition: ruby.h:1019
#define id_each
Definition: enum.c:24
#define INT2NUM(x)
Definition: ruby.h:1538
VALUE cASN1ISO64String
Definition: ossl_asn1.c:170
#define NUM2INT(x)
Definition: ruby.h:684
int count
Definition: encoding.c:56
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1716
#define CLASS_OF(v)
Definition: ruby.h:453
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
Definition: eval.c:821
VALUE cASN1IA5String
Definition: ossl_asn1.c:169
#define Qtrue
Definition: ruby.h:437
VALUE cASN1Constructive
Definition: ossl_asn1.c:160
VALUE cASN1PrintableString
Definition: ossl_asn1.c:167
VALUE mASN1
Definition: ossl_asn1.c:155
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:924
#define rb_long2int(n)
Definition: ruby.h:319
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
void rb_str_set_len(VALUE, long)
Definition: string.c:2627
VALUE cASN1BMPString
Definition: ossl_asn1.c:171
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:693
#define ossl_asn1_set_value(o, v)
Definition: ossl_asn1.c:149
#define RB_GC_GUARD(v)
Definition: ruby.h:552
VALUE rb_Integer(VALUE)
Equivalent to Kernel#Integer in Ruby.
Definition: object.c:3148
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:2121
void Init_ossl_asn1(void)
Definition: ossl_asn1.c:1361
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:864
VALUE rb_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE)
VALUE rb_hash_lookup(VALUE hash, VALUE key)
Definition: hash.c:853
#define T_ARRAY
Definition: ruby.h:498
VALUE asn1integer_to_num(const ASN1_INTEGER *ai)
Definition: ossl_asn1.c:101
#define ossl_asn1_get_tag_class(o)
Definition: ossl_asn1.c:146
VALUE ossl_membio2str(BIO *bio)
Definition: ossl_bio.c:29
#define FIXNUM_P(f)
Definition: ruby.h:365
void rb_undef_method(VALUE klass, const char *name)
Definition: class.c:1533
#define ossl_asn1_set_tagging(o, v)
Definition: ossl_asn1.c:151
VALUE cASN1Null
Definition: ossl_asn1.c:172
VALUE cASN1OctetString
Definition: ossl_asn1.c:166
void rb_global_variable(VALUE *var)
Definition: gc.c:6276
VALUE cASN1BitString
Definition: ossl_asn1.c:165
#define ossl_asn1_set_indefinite_length(o, v)
Definition: ossl_asn1.c:153
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
Definition: object.c:842
VALUE ossl_to_der_if_possible(VALUE obj)
Definition: ossl.c:255
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:1616
#define val
VALUE cASN1UniversalString
Definition: ossl_asn1.c:171
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1893
void rb_attr(VALUE, ID, int, int, int)
Definition: vm_method.c:1137
#define OSSL_ASN1_DEFINE_CLASS(name, super)
VALUE cASN1Boolean
Definition: ossl_asn1.c:163
VALUE rb_ary_new(void)
Definition: array.c:499
#define GetBNPtr(obj)
Definition: ossl_bn.h:18
VALUE cASN1ObjectId
Definition: ossl_asn1.c:173
#define NIL_P(v)
Definition: ruby.h:451
#define OSSL_ASN1_IMPL_FACTORY_METHOD(klass)
Definition: ossl_asn1.c:1332
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2691
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:815
VALUE eOSSLError
Definition: ossl.c:236
int argc
Definition: ruby.c:187
#define Qfalse
Definition: ruby.h:436
#define rb_str_new2
Definition: intern.h:835
ASN1_TYPE * ossl_asn1_get_asn1type(VALUE obj)
Definition: ossl_asn1.c:495
VALUE rb_str_resize(VALUE, long)
Definition: string.c:2644
VALUE cASN1Set
Definition: ossl_asn1.c:175
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1758
#define RSTRING_LEN(str)
Definition: ruby.h:971
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1731
#define ossl_asn1_set_tag(o, v)
Definition: ossl_asn1.c:150
VALUE rb_yield(VALUE)
Definition: vm_eval.c:973
VALUE rb_mEnumerable
Definition: enum.c:19
VALUE rb_hash_new(void)
Definition: hash.c:424
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1908
VALUE cASN1UTF8String
Definition: ossl_asn1.c:166
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1315
#define ossl_asn1_get_indefinite_length(o)
Definition: ossl_asn1.c:147
#define PRIsVALUE
Definition: ruby.h:135
unsigned long ID
Definition: ruby.h:86
#define Qnil
Definition: ruby.h:438
VALUE rb_eStandardError
Definition: error.c:799
VALUE cASN1GraphicString
Definition: ossl_asn1.c:169
unsigned long VALUE
Definition: ruby.h:85
#define rb_funcall2
Definition: ruby.h:1791
VALUE rb_eTypeError
Definition: error.c:801
#define ossl_asn1_set_tag_class(o, v)
Definition: ossl_asn1.c:152
void ossl_time_split(VALUE time, time_t *sec, int *days)
Definition: ossl_asn1.c:73
VALUE cASN1Integer
Definition: ossl_asn1.c:164
#define LONG2NUM(x)
Definition: ruby.h:1573
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
VALUE cASN1Primitive
Definition: ossl_asn1.c:159
#define RSTRING_PTR(str)
Definition: ruby.h:975
VALUE cASN1T61String
Definition: ossl_asn1.c:168
VALUE cASN1UTCTime
Definition: ossl_asn1.c:174
VALUE cASN1EndOfContent
Definition: ossl_asn1.c:162
VALUE asn1str_to_str(const ASN1_STRING *str)
Definition: ossl_asn1.c:92
#define INT2FIX(i)
Definition: ruby.h:232
#define RARRAY_AREF(a, i)
Definition: ruby.h:1033
VALUE rb_class_superclass(VALUE)
call-seq: class.superclass -> a_super_class or nil
Definition: object.c:2204
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Converts an object into another type.
Definition: object.c:2965
VALUE asn1time_to_time(const ASN1_TIME *time)
Definition: ossl_asn1.c:20
#define RTEST(v)
Definition: ruby.h:450
void rb_warning(const char *fmt,...)
Definition: error.c:267
#define ossl_asn1_get_value(o)
Definition: ossl_asn1.c:143
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:293
#define assert
Definition: ruby_assert.h:37
VALUE rb_cArray
Definition: array.c:26
VALUE cASN1Sequence
Definition: ossl_asn1.c:175
const char * name
Definition: ossl_asn1.c:450
const char * name
Definition: nkf.c:208
#define ID2SYM(x)
Definition: ruby.h:383
#define ossl_asn1_get_tag(o)
Definition: ossl_asn1.c:144
VALUE ossl_bn_new(const BIGNUM *bn)
Definition: ossl_bn.c:58
VALUE cASN1Enumerated
Definition: ossl_asn1.c:164
int nid
VALUE cASN1NumericString
Definition: ossl_asn1.c:167
VALUE rb_str_drop_bytes(VALUE, long)
Definition: string.c:4473
VALUE cASN1VideotexString
Definition: ossl_asn1.c:168
#define RSTRING_LENINT(str)
Definition: ruby.h:983
VALUE ossl_str_new(const char *ptr, long len, int *pstate)
Definition: ossl.c:101
#define rb_intern_const(str)
Definition: ruby.h:1777
VALUE rb_define_module(const char *name)
Definition: class.c:768
#define rb_intern(str)
VALUE rb_usascii_str_new(const char *, long)
Definition: string.c:743
#define SYMBOL_P(x)
Definition: ruby.h:382
VALUE cASN1GeneralString
Definition: ossl_asn1.c:170
#define NULL
Definition: _sdbm.c:102
#define FIX2LONG(x)
Definition: ruby.h:363
RUBY_EXTERN VALUE rb_cTime
Definition: ruby.h:1931
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
VALUE cASN1GeneralizedTime
Definition: ossl_asn1.c:174
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2900
VALUE ossl_to_der(VALUE obj)
Definition: ossl.c:244
VALUE eASN1Error
Definition: ossl_asn1.c:156
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1224
char ** argv
Definition: ruby.c:188
#define StringValue(v)
Definition: ruby.h:569
VALUE rb_str_new(const char *, long)
Definition: string.c:737
ASN1_INTEGER * num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
Definition: ossl_asn1.c:124