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