openssl 3.3.2 → 4.0.0

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