openssl 3.3.3 → 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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +3 -0
  3. data/History.md +81 -12
  4. data/README.md +12 -11
  5. data/ext/openssl/extconf.rb +29 -72
  6. data/ext/openssl/openssl_missing.h +0 -233
  7. data/ext/openssl/ossl.c +279 -300
  8. data/ext/openssl/ossl.h +13 -9
  9. data/ext/openssl/ossl_asn1.c +610 -423
  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 +27 -32
  22. data/ext/openssl/ossl_ocsp.c +209 -236
  23. data/ext/openssl/ossl_pkcs12.c +26 -26
  24. data/ext/openssl/ossl_pkcs7.c +176 -146
  25. data/ext/openssl/ossl_pkey.c +102 -158
  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 -5
  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 +79 -125
  37. data/ext/openssl/ossl_x509.c +9 -28
  38. data/ext/openssl/ossl_x509.h +6 -6
  39. data/ext/openssl/ossl_x509attr.c +35 -57
  40. data/ext/openssl/ossl_x509cert.c +73 -104
  41. data/ext/openssl/ossl_x509crl.c +80 -91
  42. data/ext/openssl/ossl_x509ext.c +45 -75
  43. data/ext/openssl/ossl_x509name.c +64 -91
  44. data/ext/openssl/ossl_x509req.c +57 -64
  45. data/ext/openssl/ossl_x509revoked.c +29 -44
  46. data/ext/openssl/ossl_x509store.c +41 -57
  47. data/lib/openssl/buffering.rb +30 -24
  48. data/lib/openssl/digest.rb +1 -1
  49. data/lib/openssl/pkey.rb +71 -49
  50. data/lib/openssl/ssl.rb +12 -79
  51. data/lib/openssl/version.rb +2 -1
  52. data/lib/openssl/x509.rb +9 -0
  53. data/lib/openssl.rb +9 -6
  54. metadata +2 -4
  55. data/ext/openssl/openssl_missing.c +0 -41
  56. 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,16 +128,15 @@ 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
+ if (ASN1_STRING_type(ai) == V_ASN1_ENUMERATED)
134
+ bn = ASN1_ENUMERATED_to_BN(ai, NULL);
119
135
  else
120
- bn = ASN1_INTEGER_to_BN(ai, NULL);
136
+ bn = ASN1_INTEGER_to_BN(ai, NULL);
121
137
 
122
138
  if (!bn)
123
- ossl_raise(eOSSLError, NULL);
139
+ ossl_raise(eOSSLError, NULL);
124
140
  num = ossl_bn_new(bn);
125
141
  BN_free(bn);
126
142
 
@@ -133,12 +149,12 @@ num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
133
149
  BIGNUM *bn;
134
150
 
135
151
  if (NIL_P(obj))
136
- ossl_raise(rb_eTypeError, "Can't convert nil into Integer");
152
+ ossl_raise(rb_eTypeError, "Can't convert nil into Integer");
137
153
 
138
154
  bn = GetBNPtr(obj);
139
155
 
140
156
  if (!(ai = BN_to_ASN1_INTEGER(bn, ai)))
141
- ossl_raise(eOSSLError, NULL);
157
+ ossl_raise(eOSSLError, NULL);
142
158
 
143
159
  return ai;
144
160
  }
@@ -149,43 +165,47 @@ asn1integer_to_num_i(VALUE arg)
149
165
  return asn1integer_to_num((ASN1_INTEGER *)arg);
150
166
  }
151
167
 
152
- /********/
153
168
  /*
154
- * ASN1 module
169
+ * ASN1_OBJECT conversions
155
170
  */
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;
171
+ VALUE
172
+ ossl_asn1obj_to_string_oid(const ASN1_OBJECT *a1obj)
173
+ {
174
+ VALUE str;
175
+ int len;
166
176
 
167
- VALUE cASN1Data;
168
- static VALUE cASN1Primitive;
169
- 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
+ }
170
191
 
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 */
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
+ }
185
200
 
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;
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
+ }
189
209
 
190
210
  /*
191
211
  * Ruby to ASN1 converters
@@ -194,9 +214,9 @@ static ASN1_BOOLEAN
194
214
  obj_to_asn1bool(VALUE obj)
195
215
  {
196
216
  if (NIL_P(obj))
197
- ossl_raise(rb_eTypeError, "Can't convert nil into Boolean");
217
+ ossl_raise(rb_eTypeError, "Can't convert nil into Boolean");
198
218
 
199
- return RTEST(obj) ? 0xff : 0x0;
219
+ return RTEST(obj) ? 0xff : 0x0;
200
220
  }
201
221
 
202
222
  static ASN1_INTEGER*
@@ -206,19 +226,19 @@ obj_to_asn1int(VALUE obj)
206
226
  }
207
227
 
208
228
  static ASN1_BIT_STRING*
209
- obj_to_asn1bstr(VALUE obj, int unused_bits)
229
+ obj_to_asn1bstr(VALUE obj, long unused_bits)
210
230
  {
211
231
  ASN1_BIT_STRING *bstr;
212
232
 
213
233
  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");
234
+ ossl_raise(eASN1Error, "unused_bits for a bitstring value must be in "\
235
+ "the range 0 to 7");
216
236
  StringValue(obj);
217
- if (!(bstr = ASN1_BIT_STRING_new()))
218
- ossl_raise(eASN1Error, "ASN1_BIT_STRING_new");
219
- if (!ASN1_BIT_STRING_set1(bstr, (uint8_t *)RSTRING_PTR(obj),
220
- RSTRING_LEN(obj), unused_bits))
221
- ossl_raise(eASN1Error, "ASN1_BIT_STRING_set1");
237
+ if(!(bstr = ASN1_BIT_STRING_new()))
238
+ ossl_raise(eASN1Error, NULL);
239
+ ASN1_BIT_STRING_set(bstr, (unsigned char *)RSTRING_PTR(obj), RSTRING_LENINT(obj));
240
+ bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
241
+ bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits;
222
242
 
223
243
  return bstr;
224
244
  }
@@ -230,7 +250,7 @@ obj_to_asn1str(VALUE obj)
230
250
 
231
251
  StringValue(obj);
232
252
  if(!(str = ASN1_STRING_new()))
233
- ossl_raise(eASN1Error, NULL);
253
+ ossl_raise(eASN1Error, NULL);
234
254
  ASN1_STRING_set(str, RSTRING_PTR(obj), RSTRING_LENINT(obj));
235
255
 
236
256
  return str;
@@ -242,15 +262,15 @@ obj_to_asn1null(VALUE obj)
242
262
  ASN1_NULL *null;
243
263
 
244
264
  if(!NIL_P(obj))
245
- ossl_raise(eASN1Error, "nil expected");
265
+ ossl_raise(eASN1Error, "nil expected");
246
266
  if(!(null = ASN1_NULL_new()))
247
- ossl_raise(eASN1Error, NULL);
267
+ ossl_raise(eASN1Error, NULL);
248
268
 
249
269
  return null;
250
270
  }
251
271
 
252
- static ASN1_OBJECT*
253
- obj_to_asn1obj(VALUE obj)
272
+ ASN1_OBJECT *
273
+ ossl_to_asn1obj(VALUE obj)
254
274
  {
255
275
  ASN1_OBJECT *a1obj;
256
276
 
@@ -272,7 +292,7 @@ obj_to_asn1utime(VALUE time)
272
292
 
273
293
  ossl_time_split(time, &sec, &off_days);
274
294
  if (!(t = ASN1_UTCTIME_adj(NULL, sec, off_days, 0)))
275
- ossl_raise(eASN1Error, NULL);
295
+ ossl_raise(eASN1Error, NULL);
276
296
 
277
297
  return t;
278
298
  }
@@ -287,7 +307,7 @@ obj_to_asn1gtime(VALUE time)
287
307
 
288
308
  ossl_time_split(time, &sec, &off_days);
289
309
  if (!(t = ASN1_GENERALIZEDTIME_adj(NULL, sec, off_days, 0)))
290
- ossl_raise(eASN1Error, NULL);
310
+ ossl_raise(eASN1Error, NULL);
291
311
 
292
312
  return t;
293
313
  }
@@ -300,7 +320,7 @@ obj_to_asn1derstr(VALUE obj)
300
320
 
301
321
  str = ossl_to_der(obj);
302
322
  if(!(a1str = ASN1_STRING_new()))
303
- ossl_raise(eASN1Error, NULL);
323
+ ossl_raise(eASN1Error, NULL);
304
324
  ASN1_STRING_set(a1str, RSTRING_PTR(str), RSTRING_LENINT(str));
305
325
 
306
326
  return a1str;
@@ -315,9 +335,9 @@ decode_bool(unsigned char* der, long length)
315
335
  const unsigned char *p = der;
316
336
 
317
337
  if (length != 3)
318
- ossl_raise(eASN1Error, "invalid length for BOOLEAN");
338
+ ossl_raise(eASN1Error, "invalid length for BOOLEAN");
319
339
  if (p[0] != 1 || p[1] != 1)
320
- ossl_raise(eASN1Error, "invalid BOOLEAN");
340
+ ossl_raise(eASN1Error, "invalid BOOLEAN");
321
341
 
322
342
  return p[2] ? Qtrue : Qfalse;
323
343
  }
@@ -332,9 +352,9 @@ decode_int(unsigned char* der, long length)
332
352
 
333
353
  p = der;
334
354
  if(!(ai = d2i_ASN1_INTEGER(NULL, &p, length)))
335
- ossl_raise(eASN1Error, NULL);
355
+ ossl_raise(eASN1Error, NULL);
336
356
  ret = rb_protect(asn1integer_to_num_i,
337
- (VALUE)ai, &status);
357
+ (VALUE)ai, &status);
338
358
  ASN1_INTEGER_free(ai);
339
359
  if(status) rb_jump_tag(status);
340
360
 
@@ -342,25 +362,22 @@ decode_int(unsigned char* der, long length)
342
362
  }
343
363
 
344
364
  static VALUE
345
- decode_bstr(unsigned char* der, long length, int *unused_bits)
365
+ decode_bstr(unsigned char* der, long length, long *unused_bits)
346
366
  {
347
367
  ASN1_BIT_STRING *bstr;
348
368
  const unsigned char *p;
349
- size_t len;
369
+ long len;
350
370
  VALUE ret;
351
- int state;
352
371
 
353
372
  p = der;
354
- if (!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length)))
355
- ossl_raise(eASN1Error, "d2i_ASN1_BIT_STRING");
356
- if (!ASN1_BIT_STRING_get_length(bstr, &len, unused_bits)) {
357
- ASN1_BIT_STRING_free(bstr);
358
- ossl_raise(eASN1Error, "ASN1_BIT_STRING_get_length");
359
- }
360
- ret = ossl_str_new((const char *)ASN1_STRING_get0_data(bstr), len, &state);
373
+ if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length)))
374
+ ossl_raise(eASN1Error, NULL);
375
+ len = bstr->length;
376
+ *unused_bits = 0;
377
+ if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT)
378
+ *unused_bits = bstr->flags & 0x07;
379
+ ret = rb_str_new((const char *)bstr->data, len);
361
380
  ASN1_BIT_STRING_free(bstr);
362
- if (state)
363
- rb_jump_tag(state);
364
381
 
365
382
  return ret;
366
383
  }
@@ -375,9 +392,9 @@ decode_enum(unsigned char* der, long length)
375
392
 
376
393
  p = der;
377
394
  if(!(ai = d2i_ASN1_ENUMERATED(NULL, &p, length)))
378
- ossl_raise(eASN1Error, NULL);
395
+ ossl_raise(eASN1Error, NULL);
379
396
  ret = rb_protect(asn1integer_to_num_i,
380
- (VALUE)ai, &status);
397
+ (VALUE)ai, &status);
381
398
  ASN1_ENUMERATED_free(ai);
382
399
  if(status) rb_jump_tag(status);
383
400
 
@@ -392,38 +409,33 @@ decode_null(unsigned char* der, long length)
392
409
 
393
410
  p = der;
394
411
  if(!(null = d2i_ASN1_NULL(NULL, &p, length)))
395
- ossl_raise(eASN1Error, NULL);
412
+ ossl_raise(eASN1Error, NULL);
396
413
  ASN1_NULL_free(null);
397
414
 
398
415
  return Qnil;
399
416
  }
400
417
 
418
+ VALUE
419
+ asn1obj_to_string_i(VALUE arg)
420
+ {
421
+ return ossl_asn1obj_to_string((const ASN1_OBJECT *)arg);
422
+ }
423
+
401
424
  static VALUE
402
425
  decode_obj(unsigned char* der, long length)
403
426
  {
404
427
  ASN1_OBJECT *obj;
405
428
  const unsigned char *p;
406
429
  VALUE ret;
407
- int nid;
408
- BIO *bio;
430
+ int state;
409
431
 
410
432
  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
-
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);
427
439
  return ret;
428
440
  }
429
441
 
@@ -437,9 +449,9 @@ decode_time(unsigned char* der, long length)
437
449
 
438
450
  p = der;
439
451
  if(!(time = d2i_ASN1_TIME(NULL, &p, length)))
440
- ossl_raise(eASN1Error, NULL);
452
+ ossl_raise(eASN1Error, NULL);
441
453
  ret = rb_protect(asn1time_to_time_i,
442
- (VALUE)time, &status);
454
+ (VALUE)time, &status);
443
455
  ASN1_TIME_free(time);
444
456
  if(status) rb_jump_tag(status);
445
457
 
@@ -450,7 +462,7 @@ static VALUE
450
462
  decode_eoc(unsigned char *der, long length)
451
463
  {
452
464
  if (length != 2 || !(der[0] == 0x00 && der[1] == 0x00))
453
- ossl_raise(eASN1Error, NULL);
465
+ ossl_raise(eASN1Error, NULL);
454
466
 
455
467
  return rb_str_new("", 0);
456
468
  }
@@ -515,62 +527,62 @@ ossl_asn1_get_asn1type(VALUE obj)
515
527
  tag = ossl_asn1_default_tag(obj);
516
528
  value = ossl_asn1_get_value(obj);
517
529
  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:
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:
528
540
  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");
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");
570
582
  }
571
583
  if(!(ret = OPENSSL_malloc(sizeof(ASN1_TYPE)))){
572
- if(free_func) free_func(ptr);
573
- ossl_raise(eASN1Error, "ASN1_TYPE alloc failure");
584
+ if(free_func) free_func(ptr);
585
+ ossl_raise(eASN1Error, "ASN1_TYPE alloc failure");
574
586
  }
575
587
  memset(ret, 0, sizeof(ASN1_TYPE));
576
588
  ASN1_TYPE_set(ret, tag, ptr);
@@ -585,10 +597,10 @@ ossl_asn1_default_tag(VALUE obj)
585
597
 
586
598
  tmp_class = CLASS_OF(obj);
587
599
  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);
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);
592
604
  }
593
605
 
594
606
  return -1;
@@ -601,7 +613,7 @@ ossl_asn1_tag(VALUE obj)
601
613
 
602
614
  tag = ossl_asn1_get_tag(obj);
603
615
  if(NIL_P(tag))
604
- ossl_raise(eASN1Error, "tag number not specified");
616
+ ossl_raise(eASN1Error, "tag number not specified");
605
617
 
606
618
  return NUM2INT(tag);
607
619
  }
@@ -613,28 +625,57 @@ ossl_asn1_tag_class(VALUE obj)
613
625
 
614
626
  s = ossl_asn1_get_tag_class(obj);
615
627
  if (NIL_P(s) || s == sym_UNIVERSAL)
616
- return V_ASN1_UNIVERSAL;
628
+ return V_ASN1_UNIVERSAL;
617
629
  else if (s == sym_APPLICATION)
618
- return V_ASN1_APPLICATION;
630
+ return V_ASN1_APPLICATION;
619
631
  else if (s == sym_CONTEXT_SPECIFIC)
620
- return V_ASN1_CONTEXT_SPECIFIC;
632
+ return V_ASN1_CONTEXT_SPECIFIC;
621
633
  else if (s == sym_PRIVATE)
622
- return V_ASN1_PRIVATE;
634
+ return V_ASN1_PRIVATE;
623
635
  else
624
- ossl_raise(eASN1Error, "invalid tag class");
636
+ ossl_raise(eASN1Error, "invalid tag class");
625
637
  }
626
638
 
627
639
  static VALUE
628
640
  ossl_asn1_class2sym(int tc)
629
641
  {
630
642
  if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
631
- return sym_PRIVATE;
643
+ return sym_PRIVATE;
632
644
  else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
633
- return sym_CONTEXT_SPECIFIC;
645
+ return sym_CONTEXT_SPECIFIC;
634
646
  else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
635
- return sym_APPLICATION;
647
+ return sym_APPLICATION;
636
648
  else
637
- 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;
638
679
  }
639
680
 
640
681
  static VALUE
@@ -650,35 +691,35 @@ to_der_internal(VALUE self, int constructed, int indef_len, VALUE body)
650
691
 
651
692
  body_length = RSTRING_LENINT(body);
652
693
  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
- }
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
+ }
672
713
  }
673
714
  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);
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);
682
723
  }
683
724
  assert(p - (unsigned char *)RSTRING_PTR(str) == total_length);
684
725
  return str;
@@ -701,83 +742,88 @@ ossl_asn1data_to_der(VALUE self)
701
742
  VALUE value = ossl_asn1_get_value(self);
702
743
 
703
744
  if (rb_obj_is_kind_of(value, rb_cArray))
704
- return ossl_asn1cons_to_der(self);
745
+ return ossl_asn1cons_to_der(self);
705
746
  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);
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);
710
751
  }
711
752
  }
712
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
+
713
758
  static VALUE
714
759
  int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
715
- VALUE tc, long *num_read)
760
+ VALUE tc, long *num_read)
716
761
  {
717
762
  VALUE value, asn1data;
718
763
  unsigned char *p;
719
- int flag = 0;
764
+ long flag = 0;
720
765
 
721
766
  p = *pp;
722
767
 
723
768
  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
- }
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
+ }
756
801
  }
757
802
  else {
758
- p += hlen;
759
- value = rb_str_new((const char *)p, length);
803
+ p += hlen;
804
+ value = rb_str_new((const char *)p, length);
760
805
  }
761
806
 
762
807
  *pp += hlen + length;
763
808
  *num_read = hlen + length;
764
809
 
765
810
  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
- }
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
+ }
777
823
  }
778
824
  else {
779
- VALUE args[3] = { value, INT2NUM(tag), tc };
780
- 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);
781
827
  }
782
828
 
783
829
  return asn1data;
@@ -785,8 +831,8 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
785
831
 
786
832
  static VALUE
787
833
  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)
834
+ long *offset, int depth, int yield, int j,
835
+ int tag, VALUE tc, long *num_read)
790
836
  {
791
837
  VALUE value, asn1data, ary;
792
838
  int indefinite;
@@ -797,40 +843,42 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
797
843
 
798
844
  available_len = indefinite ? max_len : length;
799
845
  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);
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);
811
859
  }
812
860
 
813
861
  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
- }
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);
824
872
  }
825
873
  else {
826
- VALUE args[3] = {ary, INT2NUM(tag), tc};
827
- 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);
828
876
  }
829
877
 
830
878
  if (indefinite)
831
- ossl_asn1_set_indefinite_length(asn1data, Qtrue);
879
+ ossl_asn1_set_indefinite_length(asn1data, Qtrue);
832
880
  else
833
- ossl_asn1_set_indefinite_length(asn1data, Qfalse);
881
+ ossl_asn1_set_indefinite_length(asn1data, Qfalse);
834
882
 
835
883
  *offset = off;
836
884
  return asn1data;
@@ -838,7 +886,7 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
838
886
 
839
887
  static VALUE
840
888
  ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth,
841
- int yield, long *num_read)
889
+ int yield, long *num_read)
842
890
  {
843
891
  unsigned char *start, *p;
844
892
  const unsigned char *p0;
@@ -854,46 +902,46 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth,
854
902
  if(j & 0x80) ossl_raise(eASN1Error, NULL);
855
903
  if(len > length) ossl_raise(eASN1Error, "value is too short");
856
904
  if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
857
- tag_class = sym_PRIVATE;
905
+ tag_class = sym_PRIVATE;
858
906
  else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
859
- tag_class = sym_CONTEXT_SPECIFIC;
907
+ tag_class = sym_CONTEXT_SPECIFIC;
860
908
  else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
861
- tag_class = sym_APPLICATION;
909
+ tag_class = sym_APPLICATION;
862
910
  else
863
- tag_class = sym_UNIVERSAL;
911
+ tag_class = sym_UNIVERSAL;
864
912
 
865
913
  hlen = p - start;
866
914
 
867
915
  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);
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);
877
925
  }
878
926
 
879
927
  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;
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;
884
932
  }
885
933
  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;
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;
890
938
  }
891
939
  if (num_read)
892
- *num_read = inner_read;
940
+ *num_read = inner_read;
893
941
  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);
942
+ ossl_raise(eASN1Error,
943
+ "Type mismatch. Bytes read: %ld Bytes available: %ld",
944
+ inner_read, hlen + len);
897
945
  }
898
946
 
899
947
  *offset = off;
@@ -904,9 +952,9 @@ static void
904
952
  int_ossl_decode_sanity_check(long len, long read, long offset)
905
953
  {
906
954
  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);
955
+ ossl_raise(eASN1Error,
956
+ "Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld",
957
+ read, len, offset);
910
958
  }
911
959
  }
912
960
 
@@ -1006,17 +1054,94 @@ ossl_asn1_decode_all(VALUE self, VALUE obj)
1006
1054
  tmp_len = len;
1007
1055
  ary = rb_ary_new();
1008
1056
  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;
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;
1014
1062
  }
1015
1063
  RB_GC_GUARD(tmp);
1016
1064
  int_ossl_decode_sanity_check(len, read, offset);
1017
1065
  return ary;
1018
1066
  }
1019
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
+
1020
1145
  static VALUE
1021
1146
  ossl_asn1eoc_to_der(VALUE self)
1022
1147
  {
@@ -1039,20 +1164,20 @@ ossl_asn1prim_to_der(VALUE self)
1039
1164
  VALUE str;
1040
1165
 
1041
1166
  if (ossl_asn1_default_tag(self) == -1) {
1042
- str = ossl_asn1_get_value(self);
1043
- 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));
1044
1169
  }
1045
1170
 
1046
1171
  asn1 = ossl_asn1_get_asn1type(self);
1047
1172
  alllen = i2d_ASN1_TYPE(asn1, NULL);
1048
1173
  if (alllen < 0) {
1049
- ASN1_TYPE_free(asn1);
1050
- ossl_raise(eASN1Error, "i2d_ASN1_TYPE");
1174
+ ASN1_TYPE_free(asn1);
1175
+ ossl_raise(eASN1Error, "i2d_ASN1_TYPE");
1051
1176
  }
1052
1177
  str = ossl_str_new(NULL, alllen, &state);
1053
1178
  if (state) {
1054
- ASN1_TYPE_free(asn1);
1055
- rb_jump_tag(state);
1179
+ ASN1_TYPE_free(asn1);
1180
+ rb_jump_tag(state);
1056
1181
  }
1057
1182
  p0 = p1 = (unsigned char *)RSTRING_PTR(str);
1058
1183
  if (i2d_ASN1_TYPE(asn1, &p0) < 0) {
@@ -1065,7 +1190,7 @@ ossl_asn1prim_to_der(VALUE self)
1065
1190
  /* Strip header since to_der_internal() wants only the payload */
1066
1191
  j = ASN1_get_object((const unsigned char **)&p1, &bodylen, &tag, &tc, alllen);
1067
1192
  if (j & 0x80)
1068
- ossl_raise(eASN1Error, "ASN1_get_object"); /* should not happen */
1193
+ ossl_raise(eASN1Error, "ASN1_get_object"); /* should not happen */
1069
1194
 
1070
1195
  return to_der_internal(self, 0, 0, rb_str_drop_bytes(str, alllen - bodylen));
1071
1196
  }
@@ -1087,27 +1212,48 @@ ossl_asn1cons_to_der(VALUE self)
1087
1212
  ary = rb_convert_type(ossl_asn1_get_value(self), T_ARRAY, "Array", "to_a");
1088
1213
  str = rb_str_new(NULL, 0);
1089
1214
  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);
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);
1106
1231
  }
1107
1232
 
1108
1233
  return to_der_internal(self, 1, indef_len, str);
1109
1234
  }
1110
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
+
1111
1257
  /*
1112
1258
  * call-seq:
1113
1259
  * OpenSSL::ASN1::ObjectId.register(object_id, short_name, long_name)
@@ -1127,7 +1273,7 @@ ossl_asn1obj_s_register(VALUE self, VALUE oid, VALUE sn, VALUE ln)
1127
1273
  StringValueCStr(ln);
1128
1274
 
1129
1275
  if(!OBJ_create(RSTRING_PTR(oid), RSTRING_PTR(sn), RSTRING_PTR(ln)))
1130
- ossl_raise(eASN1Error, NULL);
1276
+ ossl_raise(eASN1Error, NULL);
1131
1277
 
1132
1278
  return Qtrue;
1133
1279
  }
@@ -1147,7 +1293,7 @@ ossl_asn1obj_get_sn(VALUE self)
1147
1293
 
1148
1294
  val = ossl_asn1_get_value(self);
1149
1295
  if ((nid = OBJ_txt2nid(StringValueCStr(val))) != NID_undef)
1150
- ret = rb_str_new2(OBJ_nid2sn(nid));
1296
+ ret = rb_str_new2(OBJ_nid2sn(nid));
1151
1297
 
1152
1298
  return ret;
1153
1299
  }
@@ -1167,7 +1313,7 @@ ossl_asn1obj_get_ln(VALUE self)
1167
1313
 
1168
1314
  val = ossl_asn1_get_value(self);
1169
1315
  if ((nid = OBJ_txt2nid(StringValueCStr(val))) != NID_undef)
1170
- ret = rb_str_new2(OBJ_nid2ln(nid));
1316
+ ret = rb_str_new2(OBJ_nid2ln(nid));
1171
1317
 
1172
1318
  return ret;
1173
1319
  }
@@ -1175,23 +1321,7 @@ ossl_asn1obj_get_ln(VALUE self)
1175
1321
  static VALUE
1176
1322
  asn1obj_get_oid_i(VALUE vobj)
1177
1323
  {
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;
1324
+ return ossl_asn1obj_to_string_oid((const ASN1_OBJECT *)vobj);
1195
1325
  }
1196
1326
 
1197
1327
  /*
@@ -1208,11 +1338,11 @@ ossl_asn1obj_get_oid(VALUE self)
1208
1338
  ASN1_OBJECT *a1obj;
1209
1339
  int state;
1210
1340
 
1211
- a1obj = obj_to_asn1obj(ossl_asn1_get_value(self));
1341
+ a1obj = ossl_to_asn1obj(ossl_asn1_get_value(self));
1212
1342
  str = rb_protect(asn1obj_get_oid_i, (VALUE)a1obj, &state);
1213
1343
  ASN1_OBJECT_free(a1obj);
1214
1344
  if (state)
1215
- rb_jump_tag(state);
1345
+ rb_jump_tag(state);
1216
1346
  return str;
1217
1347
  }
1218
1348
 
@@ -1237,7 +1367,7 @@ ossl_asn1obj_eq(VALUE self, VALUE other)
1237
1367
 
1238
1368
  #define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \
1239
1369
  static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\
1240
- { return rb_funcallv_public(cASN1##klass, rb_intern("new"), argc, argv); }
1370
+ { return rb_funcall3(cASN1##klass, rb_intern("new"), argc, argv); }
1241
1371
 
1242
1372
  OSSL_ASN1_IMPL_FACTORY_METHOD(Boolean)
1243
1373
  OSSL_ASN1_IMPL_FACTORY_METHOD(Integer)
@@ -1267,13 +1397,6 @@ void
1267
1397
  Init_ossl_asn1(void)
1268
1398
  {
1269
1399
  #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
1400
 
1278
1401
  sym_UNIVERSAL = ID2SYM(rb_intern_const("UNIVERSAL"));
1279
1402
  sym_CONTEXT_SPECIFIC = ID2SYM(rb_intern_const("CONTEXT_SPECIFIC"));
@@ -1423,17 +1546,20 @@ Init_ossl_asn1(void)
1423
1546
  rb_define_module_function(mASN1, "traverse", ossl_asn1_traverse, 1);
1424
1547
  rb_define_module_function(mASN1, "decode", ossl_asn1_decode, 1);
1425
1548
  rb_define_module_function(mASN1, "decode_all", ossl_asn1_decode_all, 1);
1426
- ary = rb_ary_new();
1427
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);
1428
1559
  /*
1429
1560
  * Array storing tag names at the tag's index.
1430
1561
  */
1431
1562
  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
1563
 
1438
1564
  /* Document-class: OpenSSL::ASN1::ASN1Data
1439
1565
  *
@@ -1523,6 +1649,42 @@ Init_ossl_asn1(void)
1523
1649
  * puts int2.value # => 1
1524
1650
  */
1525
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);
1526
1688
  rb_define_method(cASN1Data, "to_der", ossl_asn1data_to_der, 0);
1527
1689
 
1528
1690
  /* Document-class: OpenSSL::ASN1::Primitive
@@ -1590,6 +1752,16 @@ Init_ossl_asn1(void)
1590
1752
  * prim_zero_tagged_explicit = <class>.new(value, 0, :EXPLICIT)
1591
1753
  */
1592
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);
1593
1765
  rb_define_method(cASN1Primitive, "to_der", ossl_asn1prim_to_der, 0);
1594
1766
 
1595
1767
  /* Document-class: OpenSSL::ASN1::Constructive
@@ -1620,7 +1792,17 @@ Init_ossl_asn1(void)
1620
1792
  * set = OpenSSL::ASN1::Set.new( [ int, str ] )
1621
1793
  */
1622
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);
1623
1804
  rb_define_method(cASN1Constructive, "to_der", ossl_asn1cons_to_der, 0);
1805
+ rb_define_method(cASN1Constructive, "each", ossl_asn1cons_each, 0);
1624
1806
 
1625
1807
  #define OSSL_ASN1_DEFINE_CLASS(name, super) \
1626
1808
  do{\
@@ -1669,10 +1851,13 @@ do{\
1669
1851
  rb_define_alias(cASN1ObjectId, "short_name", "sn");
1670
1852
  rb_define_alias(cASN1ObjectId, "long_name", "ln");
1671
1853
  rb_define_method(cASN1ObjectId, "==", ossl_asn1obj_eq, 1);
1854
+ rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);
1672
1855
 
1856
+ rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0);
1673
1857
  rb_define_method(cASN1EndOfContent, "to_der", ossl_asn1eoc_to_der, 0);
1674
1858
 
1675
1859
  class_tag_map = rb_hash_new();
1860
+ rb_gc_register_mark_object(class_tag_map);
1676
1861
  rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC));
1677
1862
  rb_hash_aset(class_tag_map, cASN1Boolean, INT2NUM(V_ASN1_BOOLEAN));
1678
1863
  rb_hash_aset(class_tag_map, cASN1Integer, INT2NUM(V_ASN1_INTEGER));
@@ -1696,5 +1881,7 @@ do{\
1696
1881
  rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING));
1697
1882
  rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING));
1698
1883
  rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING));
1699
- 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");
1700
1887
  }