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