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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +3 -0
- data/History.md +81 -12
- data/README.md +12 -11
- data/ext/openssl/extconf.rb +29 -72
- data/ext/openssl/openssl_missing.h +0 -233
- data/ext/openssl/ossl.c +279 -300
- data/ext/openssl/ossl.h +13 -9
- data/ext/openssl/ossl_asn1.c +610 -423
- data/ext/openssl/ossl_asn1.h +15 -1
- data/ext/openssl/ossl_bio.c +3 -3
- data/ext/openssl/ossl_bn.c +286 -291
- data/ext/openssl/ossl_cipher.c +252 -203
- 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 +209 -236
- data/ext/openssl/ossl_pkcs12.c +26 -26
- data/ext/openssl/ossl_pkcs7.c +176 -146
- data/ext/openssl/ossl_pkey.c +102 -158
- data/ext/openssl/ossl_pkey.h +99 -99
- 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 +179 -237
- 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 +478 -353
- data/ext/openssl/ossl_ssl.h +8 -8
- data/ext/openssl/ossl_ssl_session.c +93 -97
- data/ext/openssl/ossl_ts.c +79 -125
- data/ext/openssl/ossl_x509.c +9 -28
- data/ext/openssl/ossl_x509.h +6 -6
- data/ext/openssl/ossl_x509attr.c +35 -57
- data/ext/openssl/ossl_x509cert.c +73 -104
- data/ext/openssl/ossl_x509crl.c +80 -91
- data/ext/openssl/ossl_x509ext.c +45 -75
- data/ext/openssl/ossl_x509name.c +64 -91
- data/ext/openssl/ossl_x509req.c +57 -64
- data/ext/openssl/ossl_x509revoked.c +29 -44
- data/ext/openssl/ossl_x509store.c +41 -57
- 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 +2 -4
- 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,16 +128,15 @@ 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
|
-
if (ASN1_STRING_type(
|
|
117
|
-
|
|
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
|
-
|
|
136
|
+
bn = ASN1_INTEGER_to_BN(ai, NULL);
|
|
121
137
|
|
|
122
138
|
if (!bn)
|
|
123
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
169
|
+
* ASN1_OBJECT conversions
|
|
155
170
|
*/
|
|
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;
|
|
171
|
+
VALUE
|
|
172
|
+
ossl_asn1obj_to_string_oid(const ASN1_OBJECT *a1obj)
|
|
173
|
+
{
|
|
174
|
+
VALUE str;
|
|
175
|
+
int len;
|
|
166
176
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
-
|
|
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 */
|
|
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
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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
|
-
|
|
217
|
+
ossl_raise(rb_eTypeError, "Can't convert nil into Boolean");
|
|
198
218
|
|
|
199
|
-
|
|
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,
|
|
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
|
-
|
|
215
|
-
|
|
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
|
|
218
|
-
ossl_raise(eASN1Error,
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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
|
-
|
|
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
|
-
|
|
265
|
+
ossl_raise(eASN1Error, "nil expected");
|
|
246
266
|
if(!(null = ASN1_NULL_new()))
|
|
247
|
-
|
|
267
|
+
ossl_raise(eASN1Error, NULL);
|
|
248
268
|
|
|
249
269
|
return null;
|
|
250
270
|
}
|
|
251
271
|
|
|
252
|
-
|
|
253
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
338
|
+
ossl_raise(eASN1Error, "invalid length for BOOLEAN");
|
|
319
339
|
if (p[0] != 1 || p[1] != 1)
|
|
320
|
-
|
|
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
|
-
|
|
355
|
+
ossl_raise(eASN1Error, NULL);
|
|
336
356
|
ret = rb_protect(asn1integer_to_num_i,
|
|
337
|
-
|
|
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,
|
|
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
|
-
|
|
369
|
+
long len;
|
|
350
370
|
VALUE ret;
|
|
351
|
-
int state;
|
|
352
371
|
|
|
353
372
|
p = der;
|
|
354
|
-
if
|
|
355
|
-
ossl_raise(eASN1Error,
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
ret =
|
|
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
|
-
|
|
395
|
+
ossl_raise(eASN1Error, NULL);
|
|
379
396
|
ret = rb_protect(asn1integer_to_num_i,
|
|
380
|
-
|
|
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
|
-
|
|
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
|
|
408
|
-
BIO *bio;
|
|
430
|
+
int state;
|
|
409
431
|
|
|
410
432
|
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
|
-
|
|
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
|
-
|
|
452
|
+
ossl_raise(eASN1Error, NULL);
|
|
441
453
|
ret = rb_protect(asn1time_to_time_i,
|
|
442
|
-
|
|
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
|
-
|
|
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
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
573
|
-
|
|
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
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
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
|
-
|
|
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
|
-
|
|
628
|
+
return V_ASN1_UNIVERSAL;
|
|
617
629
|
else if (s == sym_APPLICATION)
|
|
618
|
-
|
|
630
|
+
return V_ASN1_APPLICATION;
|
|
619
631
|
else if (s == sym_CONTEXT_SPECIFIC)
|
|
620
|
-
|
|
632
|
+
return V_ASN1_CONTEXT_SPECIFIC;
|
|
621
633
|
else if (s == sym_PRIVATE)
|
|
622
|
-
|
|
634
|
+
return V_ASN1_PRIVATE;
|
|
623
635
|
else
|
|
624
|
-
|
|
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
|
-
|
|
643
|
+
return sym_PRIVATE;
|
|
632
644
|
else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
|
|
633
|
-
|
|
645
|
+
return sym_CONTEXT_SPECIFIC;
|
|
634
646
|
else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
|
|
635
|
-
|
|
647
|
+
return sym_APPLICATION;
|
|
636
648
|
else
|
|
637
|
-
|
|
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
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
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
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
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
|
-
|
|
745
|
+
return ossl_asn1cons_to_der(self);
|
|
705
746
|
else {
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
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
|
-
|
|
760
|
+
VALUE tc, long *num_read)
|
|
716
761
|
{
|
|
717
762
|
VALUE value, asn1data;
|
|
718
763
|
unsigned char *p;
|
|
719
|
-
|
|
764
|
+
long flag = 0;
|
|
720
765
|
|
|
721
766
|
p = *pp;
|
|
722
767
|
|
|
723
768
|
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
|
-
|
|
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
|
-
|
|
759
|
-
|
|
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
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
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
|
-
|
|
780
|
-
asn1data
|
|
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
|
-
|
|
789
|
-
|
|
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
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
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
|
-
|
|
815
|
-
|
|
816
|
-
asn1data =
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
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
|
-
|
|
827
|
-
asn1data
|
|
874
|
+
asn1data = rb_obj_alloc(cASN1Data);
|
|
875
|
+
ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), tc);
|
|
828
876
|
}
|
|
829
877
|
|
|
830
878
|
if (indefinite)
|
|
831
|
-
|
|
879
|
+
ossl_asn1_set_indefinite_length(asn1data, Qtrue);
|
|
832
880
|
else
|
|
833
|
-
|
|
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
|
-
|
|
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
|
-
|
|
905
|
+
tag_class = sym_PRIVATE;
|
|
858
906
|
else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
|
|
859
|
-
|
|
907
|
+
tag_class = sym_CONTEXT_SPECIFIC;
|
|
860
908
|
else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
|
|
861
|
-
|
|
909
|
+
tag_class = sym_APPLICATION;
|
|
862
910
|
else
|
|
863
|
-
|
|
911
|
+
tag_class = sym_UNIVERSAL;
|
|
864
912
|
|
|
865
913
|
hlen = p - start;
|
|
866
914
|
|
|
867
915
|
if(yield) {
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
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
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
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
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
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
|
-
|
|
940
|
+
*num_read = inner_read;
|
|
893
941
|
if (len != 0 && inner_read != hlen + len) {
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
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
|
-
|
|
908
|
-
|
|
909
|
-
|
|
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
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
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
|
-
|
|
1043
|
-
|
|
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
|
-
|
|
1050
|
-
|
|
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
|
-
|
|
1055
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
1884
|
+
rb_obj_freeze(class_tag_map);
|
|
1885
|
+
|
|
1886
|
+
id_each = rb_intern_const("each");
|
|
1700
1887
|
}
|