openssl 3.3.3 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +3 -0
  3. data/History.md +111 -0
  4. data/README.md +12 -11
  5. data/ext/openssl/extconf.rb +30 -70
  6. data/ext/openssl/openssl_missing.h +0 -210
  7. data/ext/openssl/ossl.c +295 -304
  8. data/ext/openssl/ossl.h +13 -9
  9. data/ext/openssl/ossl_asn1.c +598 -406
  10. data/ext/openssl/ossl_asn1.h +15 -1
  11. data/ext/openssl/ossl_bio.c +8 -4
  12. data/ext/openssl/ossl_bn.c +286 -291
  13. data/ext/openssl/ossl_cipher.c +257 -209
  14. data/ext/openssl/ossl_cipher.h +10 -1
  15. data/ext/openssl/ossl_config.c +1 -6
  16. data/ext/openssl/ossl_digest.c +74 -43
  17. data/ext/openssl/ossl_digest.h +9 -1
  18. data/ext/openssl/ossl_engine.c +39 -103
  19. data/ext/openssl/ossl_hmac.c +30 -36
  20. data/ext/openssl/ossl_kdf.c +42 -53
  21. data/ext/openssl/ossl_ns_spki.c +27 -32
  22. data/ext/openssl/ossl_ocsp.c +208 -236
  23. data/ext/openssl/ossl_pkcs12.c +26 -26
  24. data/ext/openssl/ossl_pkcs7.c +175 -145
  25. data/ext/openssl/ossl_pkey.c +102 -158
  26. data/ext/openssl/ossl_pkey.h +99 -100
  27. data/ext/openssl/ossl_pkey_dh.c +31 -68
  28. data/ext/openssl/ossl_pkey_dsa.c +15 -54
  29. data/ext/openssl/ossl_pkey_ec.c +180 -238
  30. data/ext/openssl/ossl_pkey_rsa.c +56 -103
  31. data/ext/openssl/ossl_provider.c +0 -5
  32. data/ext/openssl/ossl_rand.c +7 -14
  33. data/ext/openssl/ossl_ssl.c +535 -384
  34. data/ext/openssl/ossl_ssl.h +8 -8
  35. data/ext/openssl/ossl_ssl_session.c +93 -97
  36. data/ext/openssl/ossl_ts.c +78 -124
  37. data/ext/openssl/ossl_x509.c +9 -28
  38. data/ext/openssl/ossl_x509attr.c +33 -54
  39. data/ext/openssl/ossl_x509cert.c +70 -101
  40. data/ext/openssl/ossl_x509crl.c +78 -89
  41. data/ext/openssl/ossl_x509ext.c +43 -64
  42. data/ext/openssl/ossl_x509name.c +64 -90
  43. data/ext/openssl/ossl_x509req.c +55 -62
  44. data/ext/openssl/ossl_x509revoked.c +28 -42
  45. data/ext/openssl/ossl_x509store.c +36 -54
  46. data/lib/openssl/buffering.rb +30 -24
  47. data/lib/openssl/digest.rb +1 -1
  48. data/lib/openssl/pkey.rb +71 -49
  49. data/lib/openssl/ssl.rb +12 -79
  50. data/lib/openssl/version.rb +2 -1
  51. data/lib/openssl/x509.rb +9 -0
  52. data/lib/openssl.rb +9 -6
  53. metadata +1 -3
  54. data/ext/openssl/openssl_missing.c +0 -41
  55. data/lib/openssl/asn1.rb +0 -188
@@ -9,64 +9,81 @@
9
9
  */
10
10
  #include "ossl.h"
11
11
 
12
- static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset,
13
- int depth, int yield, long *num_read);
12
+ /********/
13
+ /*
14
+ * ASN1 module
15
+ */
16
+ #define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE)
17
+ #define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG)
18
+ #define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING)
19
+ #define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS)
20
+ #define ossl_asn1_get_indefinite_length(o) rb_attr_get((o),sivINDEFINITE_LENGTH)
21
+
22
+ #define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v))
23
+ #define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v))
24
+ #define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v))
25
+ #define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v))
26
+ #define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v))
27
+
28
+ VALUE mASN1;
29
+ static VALUE eASN1Error;
30
+
31
+ VALUE cASN1Data;
32
+ static VALUE cASN1Primitive;
33
+ static VALUE cASN1Constructive;
34
+
35
+ static VALUE cASN1EndOfContent;
36
+ static VALUE cASN1Boolean; /* BOOLEAN */
37
+ static VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */
38
+ static VALUE cASN1BitString; /* BIT STRING */
39
+ static VALUE cASN1OctetString, cASN1UTF8String; /* STRINGs */
40
+ static VALUE cASN1NumericString, cASN1PrintableString;
41
+ static VALUE cASN1T61String, cASN1VideotexString;
42
+ static VALUE cASN1IA5String, cASN1GraphicString;
43
+ static VALUE cASN1ISO64String, cASN1GeneralString;
44
+ static VALUE cASN1UniversalString, cASN1BMPString;
45
+ static VALUE cASN1Null; /* NULL */
46
+ static VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */
47
+ static VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */
48
+ static VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */
49
+
50
+ static VALUE sym_IMPLICIT, sym_EXPLICIT;
51
+ static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE;
52
+ static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINDEFINITE_LENGTH, sivUNUSED_BITS;
53
+ static ID id_each;
14
54
 
15
55
  /*
16
56
  * DATE conversion
17
57
  */
58
+ static VALUE
59
+ time_utc_new(VALUE args)
60
+ {
61
+ return rb_funcallv(rb_cTime, rb_intern("utc"), 6, (VALUE *)args);
62
+ }
63
+
64
+ static VALUE
65
+ time_utc_new_rescue(VALUE args, VALUE exc)
66
+ {
67
+ rb_raise(eASN1Error, "invalid time");
68
+ }
69
+
18
70
  VALUE
19
- asn1time_to_time(const ASN1_TIME *time_)
71
+ asn1time_to_time(const ASN1_TIME *time)
20
72
  {
21
- ASN1_TIME *time = (ASN1_TIME *)time_; // const cast for OpenSSL 1.0.2
22
73
  struct tm tm;
23
- VALUE argv[6];
24
- int count;
25
-
26
- memset(&tm, 0, sizeof(struct tm));
27
-
28
- switch (ASN1_STRING_type(time)) {
29
- case V_ASN1_UTCTIME:
30
- count = sscanf((const char *)ASN1_STRING_get0_data(time), "%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
- ASN1_STRING_get0_data(time));
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 *)ASN1_STRING_get0_data(time), "%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
- ASN1_STRING_get0_data(time));
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);
74
+ if (!ASN1_TIME_to_tm(time, &tm))
75
+ ossl_raise(eASN1Error, "ASN1_TIME_to_tm");
76
+
77
+ VALUE args[] = {
78
+ INT2NUM(tm.tm_year + 1900),
79
+ INT2NUM(tm.tm_mon + 1),
80
+ INT2NUM(tm.tm_mday),
81
+ INT2NUM(tm.tm_hour),
82
+ INT2NUM(tm.tm_min),
83
+ INT2NUM(tm.tm_sec),
84
+ };
85
+ return rb_rescue2(time_utc_new, (VALUE)args, time_utc_new_rescue, Qnil,
86
+ rb_eArgError, 0);
70
87
  }
71
88
 
72
89
  static VALUE
@@ -81,13 +98,13 @@ ossl_time_split(VALUE time, time_t *sec, int *days)
81
98
  VALUE num = rb_Integer(time);
82
99
 
83
100
  if (FIXNUM_P(num)) {
84
- time_t t = FIX2LONG(num);
85
- *sec = t % 86400;
86
- *days = rb_long2int(t / 86400);
101
+ time_t t = FIX2LONG(num);
102
+ *sec = t % 86400;
103
+ *days = rb_long2int(t / 86400);
87
104
  }
88
105
  else {
89
- *days = NUM2INT(rb_funcall(num, rb_intern("/"), 1, INT2FIX(86400)));
90
- *sec = NUM2TIMET(rb_funcall(num, rb_intern("%"), 1, INT2FIX(86400)));
106
+ *days = NUM2INT(rb_funcall(num, rb_intern("/"), 1, INT2FIX(86400)));
107
+ *sec = NUM2TIMET(rb_funcall(num, rb_intern("%"), 1, INT2FIX(86400)));
91
108
  }
92
109
  }
93
110
 
@@ -111,18 +128,19 @@ asn1integer_to_num(const ASN1_INTEGER *ai)
111
128
  VALUE num;
112
129
 
113
130
  if (!ai) {
114
- ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!");
131
+ ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!");
115
132
  }
116
- if (ASN1_STRING_type((ASN1_STRING *)ai) == V_ASN1_ENUMERATED)
117
- /* const_cast: workaround for old OpenSSL */
118
- bn = ASN1_ENUMERATED_to_BN((ASN1_ENUMERATED *)ai, NULL);
133
+
134
+ num = ossl_bn_new(BN_value_one());
135
+ bn = GetBNPtr(num);
136
+
137
+ if (ASN1_STRING_type(ai) == V_ASN1_ENUMERATED)
138
+ bn = ASN1_ENUMERATED_to_BN(ai, bn);
119
139
  else
120
- bn = ASN1_INTEGER_to_BN(ai, NULL);
140
+ bn = ASN1_INTEGER_to_BN(ai, bn);
121
141
 
122
142
  if (!bn)
123
- ossl_raise(eOSSLError, NULL);
124
- num = ossl_bn_new(bn);
125
- BN_free(bn);
143
+ ossl_raise(eOSSLError, NULL);
126
144
 
127
145
  return num;
128
146
  }
@@ -133,12 +151,12 @@ num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
133
151
  BIGNUM *bn;
134
152
 
135
153
  if (NIL_P(obj))
136
- ossl_raise(rb_eTypeError, "Can't convert nil into Integer");
154
+ ossl_raise(rb_eTypeError, "Can't convert nil into Integer");
137
155
 
138
156
  bn = GetBNPtr(obj);
139
157
 
140
158
  if (!(ai = BN_to_ASN1_INTEGER(bn, ai)))
141
- ossl_raise(eOSSLError, NULL);
159
+ ossl_raise(eOSSLError, NULL);
142
160
 
143
161
  return ai;
144
162
  }
@@ -149,43 +167,47 @@ asn1integer_to_num_i(VALUE arg)
149
167
  return asn1integer_to_num((ASN1_INTEGER *)arg);
150
168
  }
151
169
 
152
- /********/
153
170
  /*
154
- * ASN1 module
171
+ * ASN1_OBJECT conversions
155
172
  */
156
- #define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE)
157
- #define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG)
158
- #define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING)
159
- #define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS)
160
- #define ossl_asn1_get_indefinite_length(o) rb_attr_get((o),sivINDEFINITE_LENGTH)
161
-
162
- #define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v))
163
-
164
- VALUE mASN1;
165
- VALUE eASN1Error;
173
+ VALUE
174
+ ossl_asn1obj_to_string_oid(const ASN1_OBJECT *a1obj)
175
+ {
176
+ VALUE str;
177
+ int len;
166
178
 
167
- VALUE cASN1Data;
168
- static VALUE cASN1Primitive;
169
- static VALUE cASN1Constructive;
179
+ str = rb_usascii_str_new(NULL, 127);
180
+ len = OBJ_obj2txt(RSTRING_PTR(str), RSTRING_LENINT(str), a1obj, 1);
181
+ if (len <= 0 || len == INT_MAX)
182
+ ossl_raise(eOSSLError, "OBJ_obj2txt");
183
+ if (len > RSTRING_LEN(str)) {
184
+ /* +1 is for the \0 terminator added by OBJ_obj2txt() */
185
+ rb_str_resize(str, len + 1);
186
+ len = OBJ_obj2txt(RSTRING_PTR(str), len + 1, a1obj, 1);
187
+ if (len <= 0)
188
+ ossl_raise(eOSSLError, "OBJ_obj2txt");
189
+ }
190
+ rb_str_set_len(str, len);
191
+ return str;
192
+ }
170
193
 
171
- static VALUE cASN1EndOfContent;
172
- static VALUE cASN1Boolean; /* BOOLEAN */
173
- static VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */
174
- static VALUE cASN1BitString; /* BIT STRING */
175
- static VALUE cASN1OctetString, cASN1UTF8String; /* STRINGs */
176
- static VALUE cASN1NumericString, cASN1PrintableString;
177
- static VALUE cASN1T61String, cASN1VideotexString;
178
- static VALUE cASN1IA5String, cASN1GraphicString;
179
- static VALUE cASN1ISO64String, cASN1GeneralString;
180
- static VALUE cASN1UniversalString, cASN1BMPString;
181
- static VALUE cASN1Null; /* NULL */
182
- static VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */
183
- static VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */
184
- static VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */
194
+ VALUE
195
+ ossl_asn1obj_to_string(const ASN1_OBJECT *obj)
196
+ {
197
+ int nid = OBJ_obj2nid(obj);
198
+ if (nid != NID_undef)
199
+ return rb_str_new_cstr(OBJ_nid2sn(nid));
200
+ return ossl_asn1obj_to_string_oid(obj);
201
+ }
185
202
 
186
- static VALUE sym_IMPLICIT, sym_EXPLICIT;
187
- static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE;
188
- static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINDEFINITE_LENGTH, sivUNUSED_BITS;
203
+ VALUE
204
+ ossl_asn1obj_to_string_long_name(const ASN1_OBJECT *obj)
205
+ {
206
+ int nid = OBJ_obj2nid(obj);
207
+ if (nid != NID_undef)
208
+ return rb_str_new_cstr(OBJ_nid2ln(nid));
209
+ return ossl_asn1obj_to_string_oid(obj);
210
+ }
189
211
 
190
212
  /*
191
213
  * Ruby to ASN1 converters
@@ -194,9 +216,9 @@ static ASN1_BOOLEAN
194
216
  obj_to_asn1bool(VALUE obj)
195
217
  {
196
218
  if (NIL_P(obj))
197
- ossl_raise(rb_eTypeError, "Can't convert nil into Boolean");
219
+ ossl_raise(rb_eTypeError, "Can't convert nil into Boolean");
198
220
 
199
- return RTEST(obj) ? 0xff : 0x0;
221
+ return RTEST(obj) ? 0xff : 0x0;
200
222
  }
201
223
 
202
224
  static ASN1_INTEGER*
@@ -211,8 +233,8 @@ obj_to_asn1bstr(VALUE obj, int unused_bits)
211
233
  ASN1_BIT_STRING *bstr;
212
234
 
213
235
  if (unused_bits < 0 || unused_bits > 7)
214
- ossl_raise(eASN1Error, "unused_bits for a bitstring value must be in "\
215
- "the range 0 to 7");
236
+ ossl_raise(eASN1Error, "unused_bits for a bitstring value must be in "\
237
+ "the range 0 to 7");
216
238
  StringValue(obj);
217
239
  if (!(bstr = ASN1_BIT_STRING_new()))
218
240
  ossl_raise(eASN1Error, "ASN1_BIT_STRING_new");
@@ -230,7 +252,7 @@ obj_to_asn1str(VALUE obj)
230
252
 
231
253
  StringValue(obj);
232
254
  if(!(str = ASN1_STRING_new()))
233
- ossl_raise(eASN1Error, NULL);
255
+ ossl_raise(eASN1Error, NULL);
234
256
  ASN1_STRING_set(str, RSTRING_PTR(obj), RSTRING_LENINT(obj));
235
257
 
236
258
  return str;
@@ -242,15 +264,15 @@ obj_to_asn1null(VALUE obj)
242
264
  ASN1_NULL *null;
243
265
 
244
266
  if(!NIL_P(obj))
245
- ossl_raise(eASN1Error, "nil expected");
267
+ ossl_raise(eASN1Error, "nil expected");
246
268
  if(!(null = ASN1_NULL_new()))
247
- ossl_raise(eASN1Error, NULL);
269
+ ossl_raise(eASN1Error, NULL);
248
270
 
249
271
  return null;
250
272
  }
251
273
 
252
- static ASN1_OBJECT*
253
- obj_to_asn1obj(VALUE obj)
274
+ ASN1_OBJECT *
275
+ ossl_to_asn1obj(VALUE obj)
254
276
  {
255
277
  ASN1_OBJECT *a1obj;
256
278
 
@@ -272,7 +294,7 @@ obj_to_asn1utime(VALUE time)
272
294
 
273
295
  ossl_time_split(time, &sec, &off_days);
274
296
  if (!(t = ASN1_UTCTIME_adj(NULL, sec, off_days, 0)))
275
- ossl_raise(eASN1Error, NULL);
297
+ ossl_raise(eASN1Error, NULL);
276
298
 
277
299
  return t;
278
300
  }
@@ -287,7 +309,7 @@ obj_to_asn1gtime(VALUE time)
287
309
 
288
310
  ossl_time_split(time, &sec, &off_days);
289
311
  if (!(t = ASN1_GENERALIZEDTIME_adj(NULL, sec, off_days, 0)))
290
- ossl_raise(eASN1Error, NULL);
312
+ ossl_raise(eASN1Error, NULL);
291
313
 
292
314
  return t;
293
315
  }
@@ -300,7 +322,7 @@ obj_to_asn1derstr(VALUE obj)
300
322
 
301
323
  str = ossl_to_der(obj);
302
324
  if(!(a1str = ASN1_STRING_new()))
303
- ossl_raise(eASN1Error, NULL);
325
+ ossl_raise(eASN1Error, NULL);
304
326
  ASN1_STRING_set(a1str, RSTRING_PTR(str), RSTRING_LENINT(str));
305
327
 
306
328
  return a1str;
@@ -315,9 +337,9 @@ decode_bool(unsigned char* der, long length)
315
337
  const unsigned char *p = der;
316
338
 
317
339
  if (length != 3)
318
- ossl_raise(eASN1Error, "invalid length for BOOLEAN");
340
+ ossl_raise(eASN1Error, "invalid length for BOOLEAN");
319
341
  if (p[0] != 1 || p[1] != 1)
320
- ossl_raise(eASN1Error, "invalid BOOLEAN");
342
+ ossl_raise(eASN1Error, "invalid BOOLEAN");
321
343
 
322
344
  return p[2] ? Qtrue : Qfalse;
323
345
  }
@@ -332,9 +354,9 @@ decode_int(unsigned char* der, long length)
332
354
 
333
355
  p = der;
334
356
  if(!(ai = d2i_ASN1_INTEGER(NULL, &p, length)))
335
- ossl_raise(eASN1Error, NULL);
357
+ ossl_raise(eASN1Error, NULL);
336
358
  ret = rb_protect(asn1integer_to_num_i,
337
- (VALUE)ai, &status);
359
+ (VALUE)ai, &status);
338
360
  ASN1_INTEGER_free(ai);
339
361
  if(status) rb_jump_tag(status);
340
362
 
@@ -375,9 +397,9 @@ decode_enum(unsigned char* der, long length)
375
397
 
376
398
  p = der;
377
399
  if(!(ai = d2i_ASN1_ENUMERATED(NULL, &p, length)))
378
- ossl_raise(eASN1Error, NULL);
400
+ ossl_raise(eASN1Error, NULL);
379
401
  ret = rb_protect(asn1integer_to_num_i,
380
- (VALUE)ai, &status);
402
+ (VALUE)ai, &status);
381
403
  ASN1_ENUMERATED_free(ai);
382
404
  if(status) rb_jump_tag(status);
383
405
 
@@ -392,38 +414,33 @@ decode_null(unsigned char* der, long length)
392
414
 
393
415
  p = der;
394
416
  if(!(null = d2i_ASN1_NULL(NULL, &p, length)))
395
- ossl_raise(eASN1Error, NULL);
417
+ ossl_raise(eASN1Error, NULL);
396
418
  ASN1_NULL_free(null);
397
419
 
398
420
  return Qnil;
399
421
  }
400
422
 
423
+ VALUE
424
+ asn1obj_to_string_i(VALUE arg)
425
+ {
426
+ return ossl_asn1obj_to_string((const ASN1_OBJECT *)arg);
427
+ }
428
+
401
429
  static VALUE
402
430
  decode_obj(unsigned char* der, long length)
403
431
  {
404
432
  ASN1_OBJECT *obj;
405
433
  const unsigned char *p;
406
434
  VALUE ret;
407
- int nid;
408
- BIO *bio;
435
+ int state;
409
436
 
410
437
  p = der;
411
- if(!(obj = d2i_ASN1_OBJECT(NULL, &p, length)))
412
- ossl_raise(eASN1Error, NULL);
413
- if((nid = OBJ_obj2nid(obj)) != NID_undef){
414
- ASN1_OBJECT_free(obj);
415
- ret = rb_str_new2(OBJ_nid2sn(nid));
416
- }
417
- else{
418
- if(!(bio = BIO_new(BIO_s_mem()))){
419
- ASN1_OBJECT_free(obj);
420
- ossl_raise(eASN1Error, NULL);
421
- }
422
- i2a_ASN1_OBJECT(bio, obj);
423
- ASN1_OBJECT_free(obj);
424
- ret = ossl_membio2str(bio);
425
- }
426
-
438
+ if (!(obj = d2i_ASN1_OBJECT(NULL, &p, length)))
439
+ ossl_raise(eASN1Error, "d2i_ASN1_OBJECT");
440
+ ret = rb_protect(asn1obj_to_string_i, (VALUE)obj, &state);
441
+ ASN1_OBJECT_free(obj);
442
+ if (state)
443
+ rb_jump_tag(state);
427
444
  return ret;
428
445
  }
429
446
 
@@ -437,9 +454,9 @@ decode_time(unsigned char* der, long length)
437
454
 
438
455
  p = der;
439
456
  if(!(time = d2i_ASN1_TIME(NULL, &p, length)))
440
- ossl_raise(eASN1Error, NULL);
457
+ ossl_raise(eASN1Error, NULL);
441
458
  ret = rb_protect(asn1time_to_time_i,
442
- (VALUE)time, &status);
459
+ (VALUE)time, &status);
443
460
  ASN1_TIME_free(time);
444
461
  if(status) rb_jump_tag(status);
445
462
 
@@ -450,7 +467,7 @@ static VALUE
450
467
  decode_eoc(unsigned char *der, long length)
451
468
  {
452
469
  if (length != 2 || !(der[0] == 0x00 && der[1] == 0x00))
453
- ossl_raise(eASN1Error, NULL);
470
+ ossl_raise(eASN1Error, NULL);
454
471
 
455
472
  return rb_str_new("", 0);
456
473
  }
@@ -515,62 +532,62 @@ ossl_asn1_get_asn1type(VALUE obj)
515
532
  tag = ossl_asn1_default_tag(obj);
516
533
  value = ossl_asn1_get_value(obj);
517
534
  switch(tag){
518
- case V_ASN1_BOOLEAN:
519
- ptr = (void*)(VALUE)obj_to_asn1bool(value);
520
- free_func = NULL;
521
- break;
522
- case V_ASN1_INTEGER: /* FALLTHROUGH */
523
- case V_ASN1_ENUMERATED:
524
- ptr = obj_to_asn1int(value);
525
- free_func = (free_func_type *)ASN1_INTEGER_free;
526
- break;
527
- case V_ASN1_BIT_STRING:
535
+ case V_ASN1_BOOLEAN:
536
+ ptr = (void*)(VALUE)obj_to_asn1bool(value);
537
+ free_func = NULL;
538
+ break;
539
+ case V_ASN1_INTEGER: /* FALLTHROUGH */
540
+ case V_ASN1_ENUMERATED:
541
+ ptr = obj_to_asn1int(value);
542
+ free_func = (free_func_type *)ASN1_INTEGER_free;
543
+ break;
544
+ case V_ASN1_BIT_STRING:
528
545
  rflag = rb_attr_get(obj, sivUNUSED_BITS);
529
- ptr = obj_to_asn1bstr(value, NUM2INT(rflag));
530
- free_func = (free_func_type *)ASN1_BIT_STRING_free;
531
- break;
532
- case V_ASN1_NULL:
533
- ptr = obj_to_asn1null(value);
534
- free_func = (free_func_type *)ASN1_NULL_free;
535
- break;
536
- case V_ASN1_OCTET_STRING: /* FALLTHROUGH */
537
- case V_ASN1_UTF8STRING: /* FALLTHROUGH */
538
- case V_ASN1_NUMERICSTRING: /* FALLTHROUGH */
539
- case V_ASN1_PRINTABLESTRING: /* FALLTHROUGH */
540
- case V_ASN1_T61STRING: /* FALLTHROUGH */
541
- case V_ASN1_VIDEOTEXSTRING: /* FALLTHROUGH */
542
- case V_ASN1_IA5STRING: /* FALLTHROUGH */
543
- case V_ASN1_GRAPHICSTRING: /* FALLTHROUGH */
544
- case V_ASN1_ISO64STRING: /* FALLTHROUGH */
545
- case V_ASN1_GENERALSTRING: /* FALLTHROUGH */
546
- case V_ASN1_UNIVERSALSTRING: /* FALLTHROUGH */
547
- case V_ASN1_BMPSTRING:
548
- ptr = obj_to_asn1str(value);
549
- free_func = (free_func_type *)ASN1_STRING_free;
550
- break;
551
- case V_ASN1_OBJECT:
552
- ptr = obj_to_asn1obj(value);
553
- free_func = (free_func_type *)ASN1_OBJECT_free;
554
- break;
555
- case V_ASN1_UTCTIME:
556
- ptr = obj_to_asn1utime(value);
557
- free_func = (free_func_type *)ASN1_TIME_free;
558
- break;
559
- case V_ASN1_GENERALIZEDTIME:
560
- ptr = obj_to_asn1gtime(value);
561
- free_func = (free_func_type *)ASN1_TIME_free;
562
- break;
563
- case V_ASN1_SET: /* FALLTHROUGH */
564
- case V_ASN1_SEQUENCE:
565
- ptr = obj_to_asn1derstr(obj);
566
- free_func = (free_func_type *)ASN1_STRING_free;
567
- break;
568
- default:
569
- ossl_raise(eASN1Error, "unsupported ASN.1 type");
546
+ ptr = obj_to_asn1bstr(value, NUM2INT(rflag));
547
+ free_func = (free_func_type *)ASN1_BIT_STRING_free;
548
+ break;
549
+ case V_ASN1_NULL:
550
+ ptr = obj_to_asn1null(value);
551
+ free_func = (free_func_type *)ASN1_NULL_free;
552
+ break;
553
+ case V_ASN1_OCTET_STRING: /* FALLTHROUGH */
554
+ case V_ASN1_UTF8STRING: /* FALLTHROUGH */
555
+ case V_ASN1_NUMERICSTRING: /* FALLTHROUGH */
556
+ case V_ASN1_PRINTABLESTRING: /* FALLTHROUGH */
557
+ case V_ASN1_T61STRING: /* FALLTHROUGH */
558
+ case V_ASN1_VIDEOTEXSTRING: /* FALLTHROUGH */
559
+ case V_ASN1_IA5STRING: /* FALLTHROUGH */
560
+ case V_ASN1_GRAPHICSTRING: /* FALLTHROUGH */
561
+ case V_ASN1_ISO64STRING: /* FALLTHROUGH */
562
+ case V_ASN1_GENERALSTRING: /* FALLTHROUGH */
563
+ case V_ASN1_UNIVERSALSTRING: /* FALLTHROUGH */
564
+ case V_ASN1_BMPSTRING:
565
+ ptr = obj_to_asn1str(value);
566
+ free_func = (free_func_type *)ASN1_STRING_free;
567
+ break;
568
+ case V_ASN1_OBJECT:
569
+ ptr = ossl_to_asn1obj(value);
570
+ free_func = (free_func_type *)ASN1_OBJECT_free;
571
+ break;
572
+ case V_ASN1_UTCTIME:
573
+ ptr = obj_to_asn1utime(value);
574
+ free_func = (free_func_type *)ASN1_TIME_free;
575
+ break;
576
+ case V_ASN1_GENERALIZEDTIME:
577
+ ptr = obj_to_asn1gtime(value);
578
+ free_func = (free_func_type *)ASN1_TIME_free;
579
+ break;
580
+ case V_ASN1_SET: /* FALLTHROUGH */
581
+ case V_ASN1_SEQUENCE:
582
+ ptr = obj_to_asn1derstr(obj);
583
+ free_func = (free_func_type *)ASN1_STRING_free;
584
+ break;
585
+ default:
586
+ ossl_raise(eASN1Error, "unsupported ASN.1 type");
570
587
  }
571
588
  if(!(ret = OPENSSL_malloc(sizeof(ASN1_TYPE)))){
572
- if(free_func) free_func(ptr);
573
- ossl_raise(eASN1Error, "ASN1_TYPE alloc failure");
589
+ if(free_func) free_func(ptr);
590
+ ossl_raise(eASN1Error, "ASN1_TYPE alloc failure");
574
591
  }
575
592
  memset(ret, 0, sizeof(ASN1_TYPE));
576
593
  ASN1_TYPE_set(ret, tag, ptr);
@@ -585,10 +602,10 @@ ossl_asn1_default_tag(VALUE obj)
585
602
 
586
603
  tmp_class = CLASS_OF(obj);
587
604
  while (!NIL_P(tmp_class)) {
588
- tag = rb_hash_lookup(class_tag_map, tmp_class);
589
- if (tag != Qnil)
590
- return NUM2INT(tag);
591
- tmp_class = rb_class_superclass(tmp_class);
605
+ tag = rb_hash_lookup(class_tag_map, tmp_class);
606
+ if (tag != Qnil)
607
+ return NUM2INT(tag);
608
+ tmp_class = rb_class_superclass(tmp_class);
592
609
  }
593
610
 
594
611
  return -1;
@@ -601,7 +618,7 @@ ossl_asn1_tag(VALUE obj)
601
618
 
602
619
  tag = ossl_asn1_get_tag(obj);
603
620
  if(NIL_P(tag))
604
- ossl_raise(eASN1Error, "tag number not specified");
621
+ ossl_raise(eASN1Error, "tag number not specified");
605
622
 
606
623
  return NUM2INT(tag);
607
624
  }
@@ -613,28 +630,57 @@ ossl_asn1_tag_class(VALUE obj)
613
630
 
614
631
  s = ossl_asn1_get_tag_class(obj);
615
632
  if (NIL_P(s) || s == sym_UNIVERSAL)
616
- return V_ASN1_UNIVERSAL;
633
+ return V_ASN1_UNIVERSAL;
617
634
  else if (s == sym_APPLICATION)
618
- return V_ASN1_APPLICATION;
635
+ return V_ASN1_APPLICATION;
619
636
  else if (s == sym_CONTEXT_SPECIFIC)
620
- return V_ASN1_CONTEXT_SPECIFIC;
637
+ return V_ASN1_CONTEXT_SPECIFIC;
621
638
  else if (s == sym_PRIVATE)
622
- return V_ASN1_PRIVATE;
639
+ return V_ASN1_PRIVATE;
623
640
  else
624
- ossl_raise(eASN1Error, "invalid tag class");
641
+ ossl_raise(eASN1Error, "invalid tag class");
625
642
  }
626
643
 
627
644
  static VALUE
628
645
  ossl_asn1_class2sym(int tc)
629
646
  {
630
647
  if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
631
- return sym_PRIVATE;
648
+ return sym_PRIVATE;
632
649
  else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
633
- return sym_CONTEXT_SPECIFIC;
650
+ return sym_CONTEXT_SPECIFIC;
634
651
  else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
635
- return sym_APPLICATION;
652
+ return sym_APPLICATION;
636
653
  else
637
- return sym_UNIVERSAL;
654
+ return sym_UNIVERSAL;
655
+ }
656
+
657
+ /*
658
+ * call-seq:
659
+ * OpenSSL::ASN1::ASN1Data.new(value, tag, tag_class) => ASN1Data
660
+ *
661
+ * _value_: Please have a look at Constructive and Primitive to see how Ruby
662
+ * types are mapped to ASN.1 types and vice versa.
663
+ *
664
+ * _tag_: An Integer indicating the tag number.
665
+ *
666
+ * _tag_class_: A Symbol indicating the tag class. Please cf. ASN1 for
667
+ * possible values.
668
+ *
669
+ * == Example
670
+ * asn1_int = OpenSSL::ASN1Data.new(42, 2, :UNIVERSAL) # => Same as OpenSSL::ASN1::Integer.new(42)
671
+ * tagged_int = OpenSSL::ASN1Data.new(42, 0, :CONTEXT_SPECIFIC) # implicitly 0-tagged INTEGER
672
+ */
673
+ static VALUE
674
+ ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)
675
+ {
676
+ if(!SYMBOL_P(tag_class))
677
+ ossl_raise(eASN1Error, "invalid tag class");
678
+ ossl_asn1_set_tag(self, tag);
679
+ ossl_asn1_set_value(self, value);
680
+ ossl_asn1_set_tag_class(self, tag_class);
681
+ ossl_asn1_set_indefinite_length(self, Qfalse);
682
+
683
+ return self;
638
684
  }
639
685
 
640
686
  static VALUE
@@ -650,35 +696,35 @@ to_der_internal(VALUE self, int constructed, int indef_len, VALUE body)
650
696
 
651
697
  body_length = RSTRING_LENINT(body);
652
698
  if (ossl_asn1_get_tagging(self) == sym_EXPLICIT) {
653
- int inner_length, e_encoding = indef_len ? 2 : 1;
654
-
655
- if (default_tag_number == -1)
656
- ossl_raise(eASN1Error, "explicit tagging of unknown tag");
657
-
658
- inner_length = ASN1_object_size(encoding, body_length, default_tag_number);
659
- total_length = ASN1_object_size(e_encoding, inner_length, tag_number);
660
- str = rb_str_new(NULL, total_length);
661
- p = (unsigned char *)RSTRING_PTR(str);
662
- /* Put explicit tag */
663
- ASN1_put_object(&p, e_encoding, inner_length, tag_number, tag_class);
664
- /* Append inner object */
665
- ASN1_put_object(&p, encoding, body_length, default_tag_number, V_ASN1_UNIVERSAL);
666
- memcpy(p, RSTRING_PTR(body), body_length);
667
- p += body_length;
668
- if (indef_len) {
669
- ASN1_put_eoc(&p); /* For inner object */
670
- ASN1_put_eoc(&p); /* For wrapper object */
671
- }
699
+ int inner_length, e_encoding = indef_len ? 2 : 1;
700
+
701
+ if (default_tag_number == -1)
702
+ ossl_raise(eASN1Error, "explicit tagging of unknown tag");
703
+
704
+ inner_length = ASN1_object_size(encoding, body_length, default_tag_number);
705
+ total_length = ASN1_object_size(e_encoding, inner_length, tag_number);
706
+ str = rb_str_new(NULL, total_length);
707
+ p = (unsigned char *)RSTRING_PTR(str);
708
+ /* Put explicit tag */
709
+ ASN1_put_object(&p, e_encoding, inner_length, tag_number, tag_class);
710
+ /* Append inner object */
711
+ ASN1_put_object(&p, encoding, body_length, default_tag_number, V_ASN1_UNIVERSAL);
712
+ memcpy(p, RSTRING_PTR(body), body_length);
713
+ p += body_length;
714
+ if (indef_len) {
715
+ ASN1_put_eoc(&p); /* For inner object */
716
+ ASN1_put_eoc(&p); /* For wrapper object */
717
+ }
672
718
  }
673
719
  else {
674
- total_length = ASN1_object_size(encoding, body_length, tag_number);
675
- str = rb_str_new(NULL, total_length);
676
- p = (unsigned char *)RSTRING_PTR(str);
677
- ASN1_put_object(&p, encoding, body_length, tag_number, tag_class);
678
- memcpy(p, RSTRING_PTR(body), body_length);
679
- p += body_length;
680
- if (indef_len)
681
- ASN1_put_eoc(&p);
720
+ total_length = ASN1_object_size(encoding, body_length, tag_number);
721
+ str = rb_str_new(NULL, total_length);
722
+ p = (unsigned char *)RSTRING_PTR(str);
723
+ ASN1_put_object(&p, encoding, body_length, tag_number, tag_class);
724
+ memcpy(p, RSTRING_PTR(body), body_length);
725
+ p += body_length;
726
+ if (indef_len)
727
+ ASN1_put_eoc(&p);
682
728
  }
683
729
  assert(p - (unsigned char *)RSTRING_PTR(str) == total_length);
684
730
  return str;
@@ -701,18 +747,22 @@ ossl_asn1data_to_der(VALUE self)
701
747
  VALUE value = ossl_asn1_get_value(self);
702
748
 
703
749
  if (rb_obj_is_kind_of(value, rb_cArray))
704
- return ossl_asn1cons_to_der(self);
750
+ return ossl_asn1cons_to_der(self);
705
751
  else {
706
- if (RTEST(ossl_asn1_get_indefinite_length(self)))
707
- ossl_raise(eASN1Error, "indefinite length form cannot be used " \
708
- "with primitive encoding");
709
- return ossl_asn1prim_to_der(self);
752
+ if (RTEST(ossl_asn1_get_indefinite_length(self)))
753
+ ossl_raise(eASN1Error, "indefinite length form cannot be used " \
754
+ "with primitive encoding");
755
+ return ossl_asn1prim_to_der(self);
710
756
  }
711
757
  }
712
758
 
759
+ static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self);
760
+ static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset,
761
+ int depth, int yield, long *num_read);
762
+
713
763
  static VALUE
714
764
  int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
715
- VALUE tc, long *num_read)
765
+ VALUE tc, long *num_read)
716
766
  {
717
767
  VALUE value, asn1data;
718
768
  unsigned char *p;
@@ -721,63 +771,64 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
721
771
  p = *pp;
722
772
 
723
773
  if(tc == sym_UNIVERSAL && tag < ossl_asn1_info_size) {
724
- switch(tag){
725
- case V_ASN1_EOC:
726
- value = decode_eoc(p, hlen+length);
727
- break;
728
- case V_ASN1_BOOLEAN:
729
- value = decode_bool(p, hlen+length);
730
- break;
731
- case V_ASN1_INTEGER:
732
- value = decode_int(p, hlen+length);
733
- break;
734
- case V_ASN1_BIT_STRING:
735
- value = decode_bstr(p, hlen+length, &flag);
736
- break;
737
- case V_ASN1_NULL:
738
- value = decode_null(p, hlen+length);
739
- break;
740
- case V_ASN1_ENUMERATED:
741
- value = decode_enum(p, hlen+length);
742
- break;
743
- case V_ASN1_OBJECT:
744
- value = decode_obj(p, hlen+length);
745
- break;
746
- case V_ASN1_UTCTIME: /* FALLTHROUGH */
747
- case V_ASN1_GENERALIZEDTIME:
748
- value = decode_time(p, hlen+length);
749
- break;
750
- default:
751
- /* use original value */
752
- p += hlen;
753
- value = rb_str_new((const char *)p, length);
754
- break;
755
- }
774
+ switch(tag){
775
+ case V_ASN1_EOC:
776
+ value = decode_eoc(p, hlen+length);
777
+ break;
778
+ case V_ASN1_BOOLEAN:
779
+ value = decode_bool(p, hlen+length);
780
+ break;
781
+ case V_ASN1_INTEGER:
782
+ value = decode_int(p, hlen+length);
783
+ break;
784
+ case V_ASN1_BIT_STRING:
785
+ value = decode_bstr(p, hlen+length, &flag);
786
+ break;
787
+ case V_ASN1_NULL:
788
+ value = decode_null(p, hlen+length);
789
+ break;
790
+ case V_ASN1_ENUMERATED:
791
+ value = decode_enum(p, hlen+length);
792
+ break;
793
+ case V_ASN1_OBJECT:
794
+ value = decode_obj(p, hlen+length);
795
+ break;
796
+ case V_ASN1_UTCTIME: /* FALLTHROUGH */
797
+ case V_ASN1_GENERALIZEDTIME:
798
+ value = decode_time(p, hlen+length);
799
+ break;
800
+ default:
801
+ /* use original value */
802
+ p += hlen;
803
+ value = rb_str_new((const char *)p, length);
804
+ break;
805
+ }
756
806
  }
757
807
  else {
758
- p += hlen;
759
- value = rb_str_new((const char *)p, length);
808
+ p += hlen;
809
+ value = rb_str_new((const char *)p, length);
760
810
  }
761
811
 
762
812
  *pp += hlen + length;
763
813
  *num_read = hlen + length;
764
814
 
765
815
  if (tc == sym_UNIVERSAL &&
766
- tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) {
767
- VALUE klass = *ossl_asn1_info[tag].klass;
768
- if (tag == V_ASN1_EOC)
769
- asn1data = rb_funcall(cASN1EndOfContent, rb_intern("new"), 0);
770
- else {
771
- VALUE args[4] = { value, INT2NUM(tag), Qnil, tc };
772
- asn1data = rb_funcallv_public(klass, rb_intern("new"), 4, args);
773
- }
774
- if(tag == V_ASN1_BIT_STRING){
775
- rb_ivar_set(asn1data, sivUNUSED_BITS, INT2NUM(flag));
776
- }
816
+ tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) {
817
+ VALUE klass = *ossl_asn1_info[tag].klass;
818
+ VALUE args[4];
819
+ args[0] = value;
820
+ args[1] = INT2NUM(tag);
821
+ args[2] = Qnil;
822
+ args[3] = tc;
823
+ asn1data = rb_obj_alloc(klass);
824
+ ossl_asn1_initialize(4, args, asn1data);
825
+ if(tag == V_ASN1_BIT_STRING){
826
+ rb_ivar_set(asn1data, sivUNUSED_BITS, INT2NUM(flag));
827
+ }
777
828
  }
778
829
  else {
779
- VALUE args[3] = { value, INT2NUM(tag), tc };
780
- asn1data = rb_funcallv_public(cASN1Data, rb_intern("new"), 3, args);
830
+ asn1data = rb_obj_alloc(cASN1Data);
831
+ ossl_asn1data_initialize(asn1data, value, INT2NUM(tag), tc);
781
832
  }
782
833
 
783
834
  return asn1data;
@@ -785,8 +836,8 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
785
836
 
786
837
  static VALUE
787
838
  int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
788
- long *offset, int depth, int yield, int j,
789
- int tag, VALUE tc, long *num_read)
839
+ long *offset, int depth, int yield, int j,
840
+ int tag, VALUE tc, long *num_read)
790
841
  {
791
842
  VALUE value, asn1data, ary;
792
843
  int indefinite;
@@ -797,40 +848,42 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
797
848
 
798
849
  available_len = indefinite ? max_len : length;
799
850
  while (available_len > 0) {
800
- long inner_read = 0;
801
- value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read);
802
- *num_read += inner_read;
803
- available_len -= inner_read;
804
-
805
- if (indefinite &&
806
- ossl_asn1_tag(value) == V_ASN1_EOC &&
807
- ossl_asn1_get_tag_class(value) == sym_UNIVERSAL) {
808
- break;
809
- }
810
- rb_ary_push(ary, value);
851
+ long inner_read = 0;
852
+ value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read);
853
+ *num_read += inner_read;
854
+ available_len -= inner_read;
855
+
856
+ if (indefinite) {
857
+ if (ossl_asn1_tag(value) == V_ASN1_EOC &&
858
+ ossl_asn1_get_tag_class(value) == sym_UNIVERSAL)
859
+ break;
860
+ if (available_len == 0)
861
+ ossl_raise(eASN1Error, "EOC missing in indefinite length encoding");
862
+ }
863
+ rb_ary_push(ary, value);
811
864
  }
812
865
 
813
866
  if (tc == sym_UNIVERSAL) {
814
- if (tag == V_ASN1_SEQUENCE) {
815
- VALUE args[4] = { ary, INT2NUM(tag), Qnil, tc };
816
- asn1data = rb_funcallv_public(cASN1Sequence, rb_intern("new"), 4, args);
817
- } else if (tag == V_ASN1_SET) {
818
- VALUE args[4] = { ary, INT2NUM(tag), Qnil, tc };
819
- asn1data = rb_funcallv_public(cASN1Set, rb_intern("new"), 4, args);
820
- } else {
821
- VALUE args[4] = { ary, INT2NUM(tag), Qnil, tc };
822
- asn1data = rb_funcallv_public(cASN1Constructive, rb_intern("new"), 4, args);
823
- }
867
+ VALUE args[4];
868
+ if (tag == V_ASN1_SEQUENCE || tag == V_ASN1_SET)
869
+ asn1data = rb_obj_alloc(*ossl_asn1_info[tag].klass);
870
+ else
871
+ asn1data = rb_obj_alloc(cASN1Constructive);
872
+ args[0] = ary;
873
+ args[1] = INT2NUM(tag);
874
+ args[2] = Qnil;
875
+ args[3] = tc;
876
+ ossl_asn1_initialize(4, args, asn1data);
824
877
  }
825
878
  else {
826
- VALUE args[3] = {ary, INT2NUM(tag), tc};
827
- asn1data = rb_funcallv_public(cASN1Data, rb_intern("new"), 3, args);
879
+ asn1data = rb_obj_alloc(cASN1Data);
880
+ ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), tc);
828
881
  }
829
882
 
830
883
  if (indefinite)
831
- ossl_asn1_set_indefinite_length(asn1data, Qtrue);
884
+ ossl_asn1_set_indefinite_length(asn1data, Qtrue);
832
885
  else
833
- ossl_asn1_set_indefinite_length(asn1data, Qfalse);
886
+ ossl_asn1_set_indefinite_length(asn1data, Qfalse);
834
887
 
835
888
  *offset = off;
836
889
  return asn1data;
@@ -838,7 +891,7 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
838
891
 
839
892
  static VALUE
840
893
  ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth,
841
- int yield, long *num_read)
894
+ int yield, long *num_read)
842
895
  {
843
896
  unsigned char *start, *p;
844
897
  const unsigned char *p0;
@@ -854,46 +907,46 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth,
854
907
  if(j & 0x80) ossl_raise(eASN1Error, NULL);
855
908
  if(len > length) ossl_raise(eASN1Error, "value is too short");
856
909
  if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
857
- tag_class = sym_PRIVATE;
910
+ tag_class = sym_PRIVATE;
858
911
  else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
859
- tag_class = sym_CONTEXT_SPECIFIC;
912
+ tag_class = sym_CONTEXT_SPECIFIC;
860
913
  else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
861
- tag_class = sym_APPLICATION;
914
+ tag_class = sym_APPLICATION;
862
915
  else
863
- tag_class = sym_UNIVERSAL;
916
+ tag_class = sym_UNIVERSAL;
864
917
 
865
918
  hlen = p - start;
866
919
 
867
920
  if(yield) {
868
- VALUE arg = rb_ary_new();
869
- rb_ary_push(arg, LONG2NUM(depth));
870
- rb_ary_push(arg, LONG2NUM(*offset));
871
- rb_ary_push(arg, LONG2NUM(hlen));
872
- rb_ary_push(arg, LONG2NUM(len));
873
- rb_ary_push(arg, (j & V_ASN1_CONSTRUCTED) ? Qtrue : Qfalse);
874
- rb_ary_push(arg, ossl_asn1_class2sym(tc));
875
- rb_ary_push(arg, INT2NUM(tag));
876
- rb_yield(arg);
921
+ VALUE arg = rb_ary_new();
922
+ rb_ary_push(arg, LONG2NUM(depth));
923
+ rb_ary_push(arg, LONG2NUM(*offset));
924
+ rb_ary_push(arg, LONG2NUM(hlen));
925
+ rb_ary_push(arg, LONG2NUM(len));
926
+ rb_ary_push(arg, (j & V_ASN1_CONSTRUCTED) ? Qtrue : Qfalse);
927
+ rb_ary_push(arg, ossl_asn1_class2sym(tc));
928
+ rb_ary_push(arg, INT2NUM(tag));
929
+ rb_yield(arg);
877
930
  }
878
931
 
879
932
  if(j & V_ASN1_CONSTRUCTED) {
880
- *pp += hlen;
881
- off += hlen;
882
- asn1data = int_ossl_asn1_decode0_cons(pp, length - hlen, len, &off, depth, yield, j, tag, tag_class, &inner_read);
883
- inner_read += hlen;
933
+ *pp += hlen;
934
+ off += hlen;
935
+ asn1data = int_ossl_asn1_decode0_cons(pp, length - hlen, len, &off, depth, yield, j, tag, tag_class, &inner_read);
936
+ inner_read += hlen;
884
937
  }
885
938
  else {
886
- if ((j & 0x01) && (len == 0))
887
- ossl_raise(eASN1Error, "indefinite length for primitive value");
888
- asn1data = int_ossl_asn1_decode0_prim(pp, len, hlen, tag, tag_class, &inner_read);
889
- off += hlen + len;
939
+ if ((j & 0x01) && (len == 0))
940
+ ossl_raise(eASN1Error, "indefinite length for primitive value");
941
+ asn1data = int_ossl_asn1_decode0_prim(pp, len, hlen, tag, tag_class, &inner_read);
942
+ off += hlen + len;
890
943
  }
891
944
  if (num_read)
892
- *num_read = inner_read;
945
+ *num_read = inner_read;
893
946
  if (len != 0 && inner_read != hlen + len) {
894
- ossl_raise(eASN1Error,
895
- "Type mismatch. Bytes read: %ld Bytes available: %ld",
896
- inner_read, hlen + len);
947
+ ossl_raise(eASN1Error,
948
+ "Type mismatch. Bytes read: %ld Bytes available: %ld",
949
+ inner_read, hlen + len);
897
950
  }
898
951
 
899
952
  *offset = off;
@@ -904,9 +957,9 @@ static void
904
957
  int_ossl_decode_sanity_check(long len, long read, long offset)
905
958
  {
906
959
  if (len != 0 && (read != len || offset != len)) {
907
- ossl_raise(eASN1Error,
908
- "Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld",
909
- read, len, offset);
960
+ ossl_raise(eASN1Error,
961
+ "Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld",
962
+ read, len, offset);
910
963
  }
911
964
  }
912
965
 
@@ -1006,17 +1059,94 @@ ossl_asn1_decode_all(VALUE self, VALUE obj)
1006
1059
  tmp_len = len;
1007
1060
  ary = rb_ary_new();
1008
1061
  while (tmp_len > 0) {
1009
- long tmp_read = 0;
1010
- val = ossl_asn1_decode0(&p, tmp_len, &offset, 0, 0, &tmp_read);
1011
- rb_ary_push(ary, val);
1012
- read += tmp_read;
1013
- tmp_len -= tmp_read;
1062
+ long tmp_read = 0;
1063
+ val = ossl_asn1_decode0(&p, tmp_len, &offset, 0, 0, &tmp_read);
1064
+ rb_ary_push(ary, val);
1065
+ read += tmp_read;
1066
+ tmp_len -= tmp_read;
1014
1067
  }
1015
1068
  RB_GC_GUARD(tmp);
1016
1069
  int_ossl_decode_sanity_check(len, read, offset);
1017
1070
  return ary;
1018
1071
  }
1019
1072
 
1073
+ /*
1074
+ * call-seq:
1075
+ * OpenSSL::ASN1::Primitive.new(value [, tag, tagging, tag_class ]) => Primitive
1076
+ *
1077
+ * _value_: is mandatory.
1078
+ *
1079
+ * _tag_: optional, may be specified for tagged values. If no _tag_ is
1080
+ * specified, the UNIVERSAL tag corresponding to the Primitive sub-class
1081
+ * is used by default.
1082
+ *
1083
+ * _tagging_: may be used as an encoding hint to encode a value either
1084
+ * explicitly or implicitly, see ASN1 for possible values.
1085
+ *
1086
+ * _tag_class_: if _tag_ and _tagging_ are +nil+ then this is set to
1087
+ * +:UNIVERSAL+ by default. If either _tag_ or _tagging_ are set then
1088
+ * +:CONTEXT_SPECIFIC+ is used as the default. For possible values please
1089
+ * cf. ASN1.
1090
+ *
1091
+ * == Example
1092
+ * int = OpenSSL::ASN1::Integer.new(42)
1093
+ * zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :IMPLICIT)
1094
+ * private_explicit_zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :EXPLICIT, :PRIVATE)
1095
+ */
1096
+ static VALUE
1097
+ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
1098
+ {
1099
+ VALUE value, tag, tagging, tag_class;
1100
+ int default_tag;
1101
+
1102
+ rb_scan_args(argc, argv, "13", &value, &tag, &tagging, &tag_class);
1103
+ default_tag = ossl_asn1_default_tag(self);
1104
+
1105
+ if (default_tag == -1 || argc > 1) {
1106
+ if(NIL_P(tag))
1107
+ ossl_raise(eASN1Error, "must specify tag number");
1108
+ if(!NIL_P(tagging) && !SYMBOL_P(tagging))
1109
+ ossl_raise(eASN1Error, "invalid tagging method");
1110
+ if(NIL_P(tag_class)) {
1111
+ if (NIL_P(tagging))
1112
+ tag_class = sym_UNIVERSAL;
1113
+ else
1114
+ tag_class = sym_CONTEXT_SPECIFIC;
1115
+ }
1116
+ if(!SYMBOL_P(tag_class))
1117
+ ossl_raise(eASN1Error, "invalid tag class");
1118
+ }
1119
+ else{
1120
+ tag = INT2NUM(default_tag);
1121
+ tagging = Qnil;
1122
+ tag_class = sym_UNIVERSAL;
1123
+ }
1124
+ ossl_asn1_set_tag(self, tag);
1125
+ ossl_asn1_set_value(self, value);
1126
+ ossl_asn1_set_tagging(self, tagging);
1127
+ ossl_asn1_set_tag_class(self, tag_class);
1128
+ ossl_asn1_set_indefinite_length(self, Qfalse);
1129
+ if (default_tag == V_ASN1_BIT_STRING)
1130
+ rb_ivar_set(self, sivUNUSED_BITS, INT2FIX(0));
1131
+
1132
+ return self;
1133
+ }
1134
+
1135
+ static VALUE
1136
+ ossl_asn1eoc_initialize(VALUE self) {
1137
+ VALUE tag, tagging, tag_class, value;
1138
+ tag = INT2FIX(0);
1139
+ tagging = Qnil;
1140
+ tag_class = sym_UNIVERSAL;
1141
+ value = rb_str_new("", 0);
1142
+ ossl_asn1_set_tag(self, tag);
1143
+ ossl_asn1_set_value(self, value);
1144
+ ossl_asn1_set_tagging(self, tagging);
1145
+ ossl_asn1_set_tag_class(self, tag_class);
1146
+ ossl_asn1_set_indefinite_length(self, Qfalse);
1147
+ return self;
1148
+ }
1149
+
1020
1150
  static VALUE
1021
1151
  ossl_asn1eoc_to_der(VALUE self)
1022
1152
  {
@@ -1039,20 +1169,20 @@ ossl_asn1prim_to_der(VALUE self)
1039
1169
  VALUE str;
1040
1170
 
1041
1171
  if (ossl_asn1_default_tag(self) == -1) {
1042
- str = ossl_asn1_get_value(self);
1043
- return to_der_internal(self, 0, 0, StringValue(str));
1172
+ str = ossl_asn1_get_value(self);
1173
+ return to_der_internal(self, 0, 0, StringValue(str));
1044
1174
  }
1045
1175
 
1046
1176
  asn1 = ossl_asn1_get_asn1type(self);
1047
1177
  alllen = i2d_ASN1_TYPE(asn1, NULL);
1048
1178
  if (alllen < 0) {
1049
- ASN1_TYPE_free(asn1);
1050
- ossl_raise(eASN1Error, "i2d_ASN1_TYPE");
1179
+ ASN1_TYPE_free(asn1);
1180
+ ossl_raise(eASN1Error, "i2d_ASN1_TYPE");
1051
1181
  }
1052
1182
  str = ossl_str_new(NULL, alllen, &state);
1053
1183
  if (state) {
1054
- ASN1_TYPE_free(asn1);
1055
- rb_jump_tag(state);
1184
+ ASN1_TYPE_free(asn1);
1185
+ rb_jump_tag(state);
1056
1186
  }
1057
1187
  p0 = p1 = (unsigned char *)RSTRING_PTR(str);
1058
1188
  if (i2d_ASN1_TYPE(asn1, &p0) < 0) {
@@ -1065,7 +1195,7 @@ ossl_asn1prim_to_der(VALUE self)
1065
1195
  /* Strip header since to_der_internal() wants only the payload */
1066
1196
  j = ASN1_get_object((const unsigned char **)&p1, &bodylen, &tag, &tc, alllen);
1067
1197
  if (j & 0x80)
1068
- ossl_raise(eASN1Error, "ASN1_get_object"); /* should not happen */
1198
+ ossl_raise(eASN1Error, "ASN1_get_object"); /* should not happen */
1069
1199
 
1070
1200
  return to_der_internal(self, 0, 0, rb_str_drop_bytes(str, alllen - bodylen));
1071
1201
  }
@@ -1087,27 +1217,48 @@ ossl_asn1cons_to_der(VALUE self)
1087
1217
  ary = rb_convert_type(ossl_asn1_get_value(self), T_ARRAY, "Array", "to_a");
1088
1218
  str = rb_str_new(NULL, 0);
1089
1219
  for (i = 0; i < RARRAY_LEN(ary); i++) {
1090
- VALUE item = RARRAY_AREF(ary, i);
1091
-
1092
- if (indef_len && rb_obj_is_kind_of(item, cASN1EndOfContent)) {
1093
- if (i != RARRAY_LEN(ary) - 1)
1094
- ossl_raise(eASN1Error, "illegal EOC octets in value");
1095
-
1096
- /*
1097
- * EOC is not really part of the content, but we required to add one
1098
- * at the end in the past.
1099
- */
1100
- break;
1101
- }
1102
-
1103
- item = ossl_to_der_if_possible(item);
1104
- StringValue(item);
1105
- rb_str_append(str, item);
1220
+ VALUE item = RARRAY_AREF(ary, i);
1221
+
1222
+ if (indef_len && rb_obj_is_kind_of(item, cASN1EndOfContent)) {
1223
+ if (i != RARRAY_LEN(ary) - 1)
1224
+ ossl_raise(eASN1Error, "illegal EOC octets in value");
1225
+
1226
+ /*
1227
+ * EOC is not really part of the content, but we required to add one
1228
+ * at the end in the past.
1229
+ */
1230
+ break;
1231
+ }
1232
+
1233
+ item = ossl_to_der_if_possible(item);
1234
+ StringValue(item);
1235
+ rb_str_append(str, item);
1106
1236
  }
1107
1237
 
1108
1238
  return to_der_internal(self, 1, indef_len, str);
1109
1239
  }
1110
1240
 
1241
+ /*
1242
+ * call-seq:
1243
+ * asn1_ary.each { |asn1| block } => asn1_ary
1244
+ *
1245
+ * Calls the given block once for each element in self, passing that element
1246
+ * as parameter _asn1_. If no block is given, an enumerator is returned
1247
+ * instead.
1248
+ *
1249
+ * == Example
1250
+ * asn1_ary.each do |asn1|
1251
+ * puts asn1
1252
+ * end
1253
+ */
1254
+ static VALUE
1255
+ ossl_asn1cons_each(VALUE self)
1256
+ {
1257
+ rb_block_call(ossl_asn1_get_value(self), id_each, 0, 0, 0, 0);
1258
+
1259
+ return self;
1260
+ }
1261
+
1111
1262
  /*
1112
1263
  * call-seq:
1113
1264
  * OpenSSL::ASN1::ObjectId.register(object_id, short_name, long_name)
@@ -1127,7 +1278,7 @@ ossl_asn1obj_s_register(VALUE self, VALUE oid, VALUE sn, VALUE ln)
1127
1278
  StringValueCStr(ln);
1128
1279
 
1129
1280
  if(!OBJ_create(RSTRING_PTR(oid), RSTRING_PTR(sn), RSTRING_PTR(ln)))
1130
- ossl_raise(eASN1Error, NULL);
1281
+ ossl_raise(eASN1Error, NULL);
1131
1282
 
1132
1283
  return Qtrue;
1133
1284
  }
@@ -1147,7 +1298,7 @@ ossl_asn1obj_get_sn(VALUE self)
1147
1298
 
1148
1299
  val = ossl_asn1_get_value(self);
1149
1300
  if ((nid = OBJ_txt2nid(StringValueCStr(val))) != NID_undef)
1150
- ret = rb_str_new2(OBJ_nid2sn(nid));
1301
+ ret = rb_str_new2(OBJ_nid2sn(nid));
1151
1302
 
1152
1303
  return ret;
1153
1304
  }
@@ -1167,7 +1318,7 @@ ossl_asn1obj_get_ln(VALUE self)
1167
1318
 
1168
1319
  val = ossl_asn1_get_value(self);
1169
1320
  if ((nid = OBJ_txt2nid(StringValueCStr(val))) != NID_undef)
1170
- ret = rb_str_new2(OBJ_nid2ln(nid));
1321
+ ret = rb_str_new2(OBJ_nid2ln(nid));
1171
1322
 
1172
1323
  return ret;
1173
1324
  }
@@ -1175,23 +1326,7 @@ ossl_asn1obj_get_ln(VALUE self)
1175
1326
  static VALUE
1176
1327
  asn1obj_get_oid_i(VALUE vobj)
1177
1328
  {
1178
- ASN1_OBJECT *a1obj = (void *)vobj;
1179
- VALUE str;
1180
- int len;
1181
-
1182
- str = rb_usascii_str_new(NULL, 127);
1183
- len = OBJ_obj2txt(RSTRING_PTR(str), RSTRING_LENINT(str), a1obj, 1);
1184
- if (len <= 0 || len == INT_MAX)
1185
- ossl_raise(eASN1Error, "OBJ_obj2txt");
1186
- if (len > RSTRING_LEN(str)) {
1187
- /* +1 is for the \0 terminator added by OBJ_obj2txt() */
1188
- rb_str_resize(str, len + 1);
1189
- len = OBJ_obj2txt(RSTRING_PTR(str), len + 1, a1obj, 1);
1190
- if (len <= 0)
1191
- ossl_raise(eASN1Error, "OBJ_obj2txt");
1192
- }
1193
- rb_str_set_len(str, len);
1194
- return str;
1329
+ return ossl_asn1obj_to_string_oid((const ASN1_OBJECT *)vobj);
1195
1330
  }
1196
1331
 
1197
1332
  /*
@@ -1208,11 +1343,11 @@ ossl_asn1obj_get_oid(VALUE self)
1208
1343
  ASN1_OBJECT *a1obj;
1209
1344
  int state;
1210
1345
 
1211
- a1obj = obj_to_asn1obj(ossl_asn1_get_value(self));
1346
+ a1obj = ossl_to_asn1obj(ossl_asn1_get_value(self));
1212
1347
  str = rb_protect(asn1obj_get_oid_i, (VALUE)a1obj, &state);
1213
1348
  ASN1_OBJECT_free(a1obj);
1214
1349
  if (state)
1215
- rb_jump_tag(state);
1350
+ rb_jump_tag(state);
1216
1351
  return str;
1217
1352
  }
1218
1353
 
@@ -1237,7 +1372,7 @@ ossl_asn1obj_eq(VALUE self, VALUE other)
1237
1372
 
1238
1373
  #define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \
1239
1374
  static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\
1240
- { return rb_funcallv_public(cASN1##klass, rb_intern("new"), argc, argv); }
1375
+ { return rb_funcall3(cASN1##klass, rb_intern("new"), argc, argv); }
1241
1376
 
1242
1377
  OSSL_ASN1_IMPL_FACTORY_METHOD(Boolean)
1243
1378
  OSSL_ASN1_IMPL_FACTORY_METHOD(Integer)
@@ -1267,13 +1402,6 @@ void
1267
1402
  Init_ossl_asn1(void)
1268
1403
  {
1269
1404
  #undef rb_intern
1270
- VALUE ary;
1271
- int i;
1272
-
1273
- #if 0
1274
- mOSSL = rb_define_module("OpenSSL");
1275
- eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
1276
- #endif
1277
1405
 
1278
1406
  sym_UNIVERSAL = ID2SYM(rb_intern_const("UNIVERSAL"));
1279
1407
  sym_CONTEXT_SPECIFIC = ID2SYM(rb_intern_const("CONTEXT_SPECIFIC"));
@@ -1423,17 +1551,20 @@ Init_ossl_asn1(void)
1423
1551
  rb_define_module_function(mASN1, "traverse", ossl_asn1_traverse, 1);
1424
1552
  rb_define_module_function(mASN1, "decode", ossl_asn1_decode, 1);
1425
1553
  rb_define_module_function(mASN1, "decode_all", ossl_asn1_decode_all, 1);
1426
- ary = rb_ary_new();
1427
1554
 
1555
+ VALUE ary = rb_ary_new_capa(ossl_asn1_info_size);
1556
+ for (int i = 0; i < ossl_asn1_info_size; i++) {
1557
+ const char *name = ossl_asn1_info[i].name;
1558
+ if (name[0] == '[')
1559
+ continue;
1560
+ rb_define_const(mASN1, name, INT2NUM(i));
1561
+ rb_ary_store(ary, i, rb_obj_freeze(rb_str_new_cstr(name)));
1562
+ }
1563
+ rb_obj_freeze(ary);
1428
1564
  /*
1429
1565
  * Array storing tag names at the tag's index.
1430
1566
  */
1431
1567
  rb_define_const(mASN1, "UNIVERSAL_TAG_NAME", ary);
1432
- for(i = 0; i < ossl_asn1_info_size; i++){
1433
- if(ossl_asn1_info[i].name[0] == '[') continue;
1434
- rb_define_const(mASN1, ossl_asn1_info[i].name, INT2NUM(i));
1435
- rb_ary_store(ary, i, rb_str_new2(ossl_asn1_info[i].name));
1436
- }
1437
1568
 
1438
1569
  /* Document-class: OpenSSL::ASN1::ASN1Data
1439
1570
  *
@@ -1523,6 +1654,42 @@ Init_ossl_asn1(void)
1523
1654
  * puts int2.value # => 1
1524
1655
  */
1525
1656
  cASN1Data = rb_define_class_under(mASN1, "ASN1Data", rb_cObject);
1657
+ /*
1658
+ * Carries the value of a ASN.1 type.
1659
+ * Please confer Constructive and Primitive for the mappings between
1660
+ * ASN.1 data types and Ruby classes.
1661
+ */
1662
+ rb_attr(cASN1Data, rb_intern("value"), 1, 1, 0);
1663
+ /*
1664
+ * An Integer representing the tag number of this ASN1Data. Never +nil+.
1665
+ */
1666
+ rb_attr(cASN1Data, rb_intern("tag"), 1, 1, 0);
1667
+ /*
1668
+ * A Symbol representing the tag class of this ASN1Data. Never +nil+.
1669
+ * See ASN1Data for possible values.
1670
+ */
1671
+ rb_attr(cASN1Data, rb_intern("tag_class"), 1, 1, 0);
1672
+ /*
1673
+ * Never +nil+. A boolean value indicating whether the encoding uses
1674
+ * indefinite length (in the case of parsing) or whether an indefinite
1675
+ * length form shall be used (in the encoding case).
1676
+ * In DER, every value uses definite length form. But in scenarios where
1677
+ * large amounts of data need to be transferred it might be desirable to
1678
+ * have some kind of streaming support available.
1679
+ * For example, huge OCTET STRINGs are preferably sent in smaller-sized
1680
+ * chunks, each at a time.
1681
+ * This is possible in BER by setting the length bytes of an encoding
1682
+ * to zero and by this indicating that the following value will be
1683
+ * sent in chunks. Indefinite length encodings are always constructed.
1684
+ * The end of such a stream of chunks is indicated by sending a EOC
1685
+ * (End of Content) tag. SETs and SEQUENCEs may use an indefinite length
1686
+ * encoding, but also primitive types such as e.g. OCTET STRINGS or
1687
+ * BIT STRINGS may leverage this functionality (cf. ITU-T X.690).
1688
+ */
1689
+ rb_attr(cASN1Data, rb_intern("indefinite_length"), 1, 1, 0);
1690
+ rb_define_alias(cASN1Data, "infinite_length", "indefinite_length");
1691
+ rb_define_alias(cASN1Data, "infinite_length=", "indefinite_length=");
1692
+ rb_define_method(cASN1Data, "initialize", ossl_asn1data_initialize, 3);
1526
1693
  rb_define_method(cASN1Data, "to_der", ossl_asn1data_to_der, 0);
1527
1694
 
1528
1695
  /* Document-class: OpenSSL::ASN1::Primitive
@@ -1590,6 +1757,16 @@ Init_ossl_asn1(void)
1590
1757
  * prim_zero_tagged_explicit = <class>.new(value, 0, :EXPLICIT)
1591
1758
  */
1592
1759
  cASN1Primitive = rb_define_class_under(mASN1, "Primitive", cASN1Data);
1760
+ /*
1761
+ * May be used as a hint for encoding a value either implicitly or
1762
+ * explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+.
1763
+ * _tagging_ is not set when a ASN.1 structure is parsed using
1764
+ * OpenSSL::ASN1.decode.
1765
+ */
1766
+ rb_attr(cASN1Primitive, rb_intern("tagging"), 1, 1, Qtrue);
1767
+ rb_undef_method(cASN1Primitive, "indefinite_length=");
1768
+ rb_undef_method(cASN1Primitive, "infinite_length=");
1769
+ rb_define_method(cASN1Primitive, "initialize", ossl_asn1_initialize, -1);
1593
1770
  rb_define_method(cASN1Primitive, "to_der", ossl_asn1prim_to_der, 0);
1594
1771
 
1595
1772
  /* Document-class: OpenSSL::ASN1::Constructive
@@ -1620,7 +1797,17 @@ Init_ossl_asn1(void)
1620
1797
  * set = OpenSSL::ASN1::Set.new( [ int, str ] )
1621
1798
  */
1622
1799
  cASN1Constructive = rb_define_class_under(mASN1,"Constructive", cASN1Data);
1800
+ rb_include_module(cASN1Constructive, rb_mEnumerable);
1801
+ /*
1802
+ * May be used as a hint for encoding a value either implicitly or
1803
+ * explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+.
1804
+ * _tagging_ is not set when a ASN.1 structure is parsed using
1805
+ * OpenSSL::ASN1.decode.
1806
+ */
1807
+ rb_attr(cASN1Constructive, rb_intern("tagging"), 1, 1, Qtrue);
1808
+ rb_define_method(cASN1Constructive, "initialize", ossl_asn1_initialize, -1);
1623
1809
  rb_define_method(cASN1Constructive, "to_der", ossl_asn1cons_to_der, 0);
1810
+ rb_define_method(cASN1Constructive, "each", ossl_asn1cons_each, 0);
1624
1811
 
1625
1812
  #define OSSL_ASN1_DEFINE_CLASS(name, super) \
1626
1813
  do{\
@@ -1669,10 +1856,13 @@ do{\
1669
1856
  rb_define_alias(cASN1ObjectId, "short_name", "sn");
1670
1857
  rb_define_alias(cASN1ObjectId, "long_name", "ln");
1671
1858
  rb_define_method(cASN1ObjectId, "==", ossl_asn1obj_eq, 1);
1859
+ rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);
1672
1860
 
1861
+ rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0);
1673
1862
  rb_define_method(cASN1EndOfContent, "to_der", ossl_asn1eoc_to_der, 0);
1674
1863
 
1675
1864
  class_tag_map = rb_hash_new();
1865
+ rb_gc_register_mark_object(class_tag_map);
1676
1866
  rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC));
1677
1867
  rb_hash_aset(class_tag_map, cASN1Boolean, INT2NUM(V_ASN1_BOOLEAN));
1678
1868
  rb_hash_aset(class_tag_map, cASN1Integer, INT2NUM(V_ASN1_INTEGER));
@@ -1696,5 +1886,7 @@ do{\
1696
1886
  rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING));
1697
1887
  rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING));
1698
1888
  rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING));
1699
- rb_define_const(mASN1, "CLASS_TAG_MAP", class_tag_map);
1889
+ rb_obj_freeze(class_tag_map);
1890
+
1891
+ id_each = rb_intern_const("each");
1700
1892
  }