rubysl-openssl 1.0.2 → 2.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/.travis.yml +5 -6
- data/ext/rubysl/openssl/.gitignore +3 -0
- data/ext/rubysl/openssl/deprecation.rb +21 -0
- data/ext/rubysl/openssl/extconf.rb +45 -32
- data/ext/rubysl/openssl/openssl_missing.c +20 -7
- data/ext/rubysl/openssl/openssl_missing.h +22 -15
- data/ext/rubysl/openssl/ossl.c +610 -61
- data/ext/rubysl/openssl/ossl.h +31 -17
- data/ext/rubysl/openssl/ossl_asn1.c +974 -183
- data/ext/rubysl/openssl/ossl_asn1.h +3 -3
- data/ext/rubysl/openssl/ossl_bio.c +4 -3
- data/ext/rubysl/openssl/ossl_bio.h +1 -1
- data/ext/rubysl/openssl/ossl_bn.c +32 -28
- data/ext/rubysl/openssl/ossl_bn.h +1 -1
- data/ext/rubysl/openssl/ossl_cipher.c +494 -93
- data/ext/rubysl/openssl/ossl_cipher.h +1 -1
- data/ext/rubysl/openssl/ossl_config.c +4 -5
- data/ext/rubysl/openssl/ossl_config.h +1 -1
- data/ext/rubysl/openssl/ossl_digest.c +206 -24
- data/ext/rubysl/openssl/ossl_digest.h +1 -1
- data/ext/rubysl/openssl/ossl_engine.c +48 -26
- data/ext/rubysl/openssl/ossl_engine.h +1 -1
- data/ext/rubysl/openssl/ossl_hmac.c +40 -38
- data/ext/rubysl/openssl/ossl_hmac.h +1 -1
- data/ext/rubysl/openssl/ossl_ns_spki.c +157 -25
- data/ext/rubysl/openssl/ossl_ns_spki.h +1 -1
- data/ext/rubysl/openssl/ossl_ocsp.c +57 -40
- data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs12.c +15 -13
- data/ext/rubysl/openssl/ossl_pkcs12.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs5.c +108 -18
- data/ext/rubysl/openssl/ossl_pkcs7.c +44 -37
- data/ext/rubysl/openssl/ossl_pkcs7.h +1 -1
- data/ext/rubysl/openssl/ossl_pkey.c +211 -15
- data/ext/rubysl/openssl/ossl_pkey.h +19 -9
- data/ext/rubysl/openssl/ossl_pkey_dh.c +180 -47
- data/ext/rubysl/openssl/ossl_pkey_dsa.c +184 -47
- data/ext/rubysl/openssl/ossl_pkey_ec.c +177 -93
- data/ext/rubysl/openssl/ossl_pkey_rsa.c +209 -102
- data/ext/rubysl/openssl/ossl_rand.c +15 -15
- data/ext/rubysl/openssl/ossl_rand.h +1 -1
- data/ext/rubysl/openssl/ossl_ssl.c +939 -192
- data/ext/rubysl/openssl/ossl_ssl.h +6 -6
- data/ext/rubysl/openssl/ossl_ssl_session.c +78 -62
- data/ext/rubysl/openssl/ossl_version.h +2 -2
- data/ext/rubysl/openssl/ossl_x509.c +1 -1
- data/ext/rubysl/openssl/ossl_x509.h +1 -1
- data/ext/rubysl/openssl/ossl_x509attr.c +20 -19
- data/ext/rubysl/openssl/ossl_x509cert.c +169 -67
- data/ext/rubysl/openssl/ossl_x509crl.c +41 -39
- data/ext/rubysl/openssl/ossl_x509ext.c +51 -38
- data/ext/rubysl/openssl/ossl_x509name.c +139 -29
- data/ext/rubysl/openssl/ossl_x509req.c +42 -40
- data/ext/rubysl/openssl/ossl_x509revoked.c +20 -20
- data/ext/rubysl/openssl/ossl_x509store.c +99 -47
- data/ext/rubysl/openssl/ruby_missing.h +3 -16
- data/lib/openssl/bn.rb +19 -19
- data/lib/openssl/buffering.rb +222 -14
- data/lib/openssl/cipher.rb +20 -20
- data/lib/openssl/config.rb +1 -4
- data/lib/openssl/digest.rb +47 -19
- data/lib/openssl/ssl.rb +197 -1
- data/lib/openssl/x509.rb +162 -1
- data/lib/rubysl/openssl.rb +4 -8
- data/lib/rubysl/openssl/version.rb +1 -1
- data/rubysl-openssl.gemspec +1 -2
- metadata +16 -34
- data/ext/rubysl/openssl/extconf.h +0 -50
- data/lib/openssl/net/ftptls.rb +0 -53
- data/lib/openssl/net/telnets.rb +0 -251
- data/lib/openssl/pkcs7.rb +0 -25
- data/lib/openssl/ssl-internal.rb +0 -187
- data/lib/openssl/x509-internal.rb +0 -153
data/ext/rubysl/openssl/ossl.h
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* $Id
|
2
|
+
* $Id$
|
3
3
|
* 'OpenSSL for Ruby' project
|
4
4
|
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
5
5
|
* All rights reserved.
|
@@ -29,7 +29,8 @@ extern "C" {
|
|
29
29
|
# undef RFILE
|
30
30
|
#endif
|
31
31
|
#include <ruby.h>
|
32
|
-
#include <
|
32
|
+
#include <ruby/io.h>
|
33
|
+
#include <ruby/thread.h>
|
33
34
|
|
34
35
|
/*
|
35
36
|
* Check the OpenSSL version
|
@@ -45,12 +46,12 @@ extern "C" {
|
|
45
46
|
#endif
|
46
47
|
|
47
48
|
#if defined(_WIN32)
|
49
|
+
# include <openssl/e_os2.h>
|
48
50
|
# define OSSL_NO_CONF_API 1
|
49
|
-
#
|
50
|
-
#
|
51
|
-
# else
|
52
|
-
# include <winsock.h>
|
51
|
+
# if !defined(OPENSSL_SYS_WIN32)
|
52
|
+
# define OPENSSL_SYS_WIN32 1
|
53
53
|
# endif
|
54
|
+
# include <winsock2.h>
|
54
55
|
#endif
|
55
56
|
#include <errno.h>
|
56
57
|
#include <openssl/err.h>
|
@@ -74,6 +75,11 @@ extern "C" {
|
|
74
75
|
# include <openssl/ocsp.h>
|
75
76
|
#endif
|
76
77
|
|
78
|
+
/* OpenSSL requires passwords for PEM-encoded files to be at least four
|
79
|
+
* characters long
|
80
|
+
*/
|
81
|
+
#define OSSL_MIN_PWD_LEN 4
|
82
|
+
|
77
83
|
/*
|
78
84
|
* Common Module
|
79
85
|
*/
|
@@ -88,21 +94,21 @@ extern VALUE eOSSLError;
|
|
88
94
|
* CheckTypes
|
89
95
|
*/
|
90
96
|
#define OSSL_Check_Kind(obj, klass) do {\
|
91
|
-
if (!rb_obj_is_kind_of(obj, klass)) {\
|
97
|
+
if (!rb_obj_is_kind_of((obj), (klass))) {\
|
92
98
|
ossl_raise(rb_eTypeError, "wrong argument (%s)! (Expected kind of %s)",\
|
93
99
|
rb_obj_classname(obj), rb_class2name(klass));\
|
94
100
|
}\
|
95
101
|
} while (0)
|
96
102
|
|
97
103
|
#define OSSL_Check_Instance(obj, klass) do {\
|
98
|
-
if (!rb_obj_is_instance_of(obj, klass)) {\
|
104
|
+
if (!rb_obj_is_instance_of((obj), (klass))) {\
|
99
105
|
ossl_raise(rb_eTypeError, "wrong argument (%s)! (Expected instance of %s)",\
|
100
106
|
rb_obj_classname(obj), rb_class2name(klass));\
|
101
107
|
}\
|
102
108
|
} while (0)
|
103
109
|
|
104
110
|
#define OSSL_Check_Same_Class(obj1, obj2) do {\
|
105
|
-
if (!rb_obj_is_instance_of(obj1, rb_obj_class(obj2))) {\
|
111
|
+
if (!rb_obj_is_instance_of((obj1), rb_obj_class(obj2))) {\
|
106
112
|
ossl_raise(rb_eTypeError, "wrong argument type");\
|
107
113
|
}\
|
108
114
|
} while (0)
|
@@ -117,7 +123,7 @@ extern VALUE eOSSLError;
|
|
117
123
|
/*
|
118
124
|
* String to HEXString conversion
|
119
125
|
*/
|
120
|
-
int string2hex(char *, int, char **, int *);
|
126
|
+
int string2hex(const unsigned char *, int, char **, int *);
|
121
127
|
|
122
128
|
/*
|
123
129
|
* Data Conversion
|
@@ -127,13 +133,14 @@ STACK_OF(X509) *ossl_x509_ary2sk(VALUE);
|
|
127
133
|
STACK_OF(X509) *ossl_protect_x509_ary2sk(VALUE,int*);
|
128
134
|
VALUE ossl_x509_sk2ary(STACK_OF(X509) *certs);
|
129
135
|
VALUE ossl_x509crl_sk2ary(STACK_OF(X509_CRL) *crl);
|
136
|
+
VALUE ossl_x509name_sk2ary(STACK_OF(X509_NAME) *names);
|
130
137
|
VALUE ossl_buf2str(char *buf, int len);
|
131
138
|
#define ossl_str_adjust(str, p) \
|
132
139
|
do{\
|
133
|
-
int len =
|
134
|
-
int newlen = (p) - (unsigned char*)RSTRING_PTR(str);\
|
140
|
+
int len = RSTRING_LENINT(str);\
|
141
|
+
int newlen = rb_long2int((p) - (unsigned char*)RSTRING_PTR(str));\
|
135
142
|
assert(newlen <= len);\
|
136
|
-
rb_str_set_len(str, newlen);\
|
143
|
+
rb_str_set_len((str), newlen);\
|
137
144
|
}while(0)
|
138
145
|
|
139
146
|
/*
|
@@ -141,6 +148,13 @@ do{\
|
|
141
148
|
*/
|
142
149
|
int ossl_pem_passwd_cb(char *, int, int, void *);
|
143
150
|
|
151
|
+
/*
|
152
|
+
* Clear BIO* with this in PEM/DER fallback scenarios to avoid decoding
|
153
|
+
* errors piling up in OpenSSL::Errors
|
154
|
+
*/
|
155
|
+
#define OSSL_BIO_reset(bio) (void)BIO_reset((bio)); \
|
156
|
+
ERR_clear_error();
|
157
|
+
|
144
158
|
/*
|
145
159
|
* ERRor messages
|
146
160
|
*/
|
@@ -184,13 +198,13 @@ extern VALUE dOSSL;
|
|
184
198
|
} while (0)
|
185
199
|
|
186
200
|
#define OSSL_Warning(fmt, ...) do { \
|
187
|
-
OSSL_Debug(fmt, ##__VA_ARGS__); \
|
188
|
-
rb_warning(fmt, ##__VA_ARGS__); \
|
201
|
+
OSSL_Debug((fmt), ##__VA_ARGS__); \
|
202
|
+
rb_warning((fmt), ##__VA_ARGS__); \
|
189
203
|
} while (0)
|
190
204
|
|
191
205
|
#define OSSL_Warn(fmt, ...) do { \
|
192
|
-
OSSL_Debug(fmt, ##__VA_ARGS__); \
|
193
|
-
rb_warn(fmt, ##__VA_ARGS__); \
|
206
|
+
OSSL_Debug((fmt), ##__VA_ARGS__); \
|
207
|
+
rb_warn((fmt), ##__VA_ARGS__); \
|
194
208
|
} while (0)
|
195
209
|
#else
|
196
210
|
void ossl_debug(const char *, ...);
|
@@ -10,7 +10,20 @@
|
|
10
10
|
*/
|
11
11
|
#include "ossl.h"
|
12
12
|
|
13
|
-
#
|
13
|
+
#if defined(HAVE_SYS_TIME_H)
|
14
|
+
# include <sys/time.h>
|
15
|
+
#elif !defined(NT) && !defined(_WIN32)
|
16
|
+
struct timeval {
|
17
|
+
long tv_sec; /* seconds */
|
18
|
+
long tv_usec; /* and microseconds */
|
19
|
+
};
|
20
|
+
#endif
|
21
|
+
|
22
|
+
static VALUE join_der(VALUE enumerable);
|
23
|
+
static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset,
|
24
|
+
int depth, int yield, long *num_read);
|
25
|
+
static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self);
|
26
|
+
static VALUE ossl_asn1eoc_initialize(VALUE self);
|
14
27
|
|
15
28
|
/*
|
16
29
|
* DATE conversion
|
@@ -20,16 +33,16 @@ asn1time_to_time(ASN1_TIME *time)
|
|
20
33
|
{
|
21
34
|
struct tm tm;
|
22
35
|
VALUE argv[6];
|
23
|
-
|
36
|
+
|
24
37
|
if (!time || !time->data) return Qnil;
|
25
38
|
memset(&tm, 0, sizeof(struct tm));
|
26
|
-
|
39
|
+
|
27
40
|
switch (time->type) {
|
28
41
|
case V_ASN1_UTCTIME:
|
29
|
-
if (sscanf(time->data, "%2d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon,
|
42
|
+
if (sscanf((const char *)time->data, "%2d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon,
|
30
43
|
&tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
|
31
44
|
ossl_raise(rb_eTypeError, "bad UTCTIME format");
|
32
|
-
}
|
45
|
+
}
|
33
46
|
if (tm.tm_year < 69) {
|
34
47
|
tm.tm_year += 2000;
|
35
48
|
} else {
|
@@ -37,10 +50,10 @@ asn1time_to_time(ASN1_TIME *time)
|
|
37
50
|
}
|
38
51
|
break;
|
39
52
|
case V_ASN1_GENERALIZEDTIME:
|
40
|
-
if (sscanf(time->data, "%4d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon,
|
53
|
+
if (sscanf((const char *)time->data, "%4d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon,
|
41
54
|
&tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
|
42
55
|
ossl_raise(rb_eTypeError, "bad GENERALIZEDTIME format" );
|
43
|
-
}
|
56
|
+
}
|
44
57
|
break;
|
45
58
|
default:
|
46
59
|
rb_warning("unknown time format");
|
@@ -73,7 +86,7 @@ time_to_time_t(VALUE time)
|
|
73
86
|
VALUE
|
74
87
|
asn1str_to_str(ASN1_STRING *str)
|
75
88
|
{
|
76
|
-
return rb_str_new(str->data, str->length);
|
89
|
+
return rb_str_new((const char *)str->data, str->length);
|
77
90
|
}
|
78
91
|
|
79
92
|
/*
|
@@ -136,11 +149,16 @@ num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
|
|
136
149
|
ASN1_INTEGER *
|
137
150
|
num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
|
138
151
|
{
|
139
|
-
BIGNUM *bn
|
140
|
-
|
141
|
-
if (
|
152
|
+
BIGNUM *bn;
|
153
|
+
|
154
|
+
if (NIL_P(obj))
|
155
|
+
ossl_raise(rb_eTypeError, "Can't convert nil into Integer");
|
156
|
+
|
157
|
+
bn = GetBNPtr(obj);
|
158
|
+
|
159
|
+
if (!(ai = BN_to_ASN1_INTEGER(bn, ai)))
|
142
160
|
ossl_raise(eOSSLError, NULL);
|
143
|
-
|
161
|
+
|
144
162
|
return ai;
|
145
163
|
}
|
146
164
|
#endif
|
@@ -149,15 +167,17 @@ num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
|
|
149
167
|
/*
|
150
168
|
* ASN1 module
|
151
169
|
*/
|
152
|
-
#define ossl_asn1_get_value(o)
|
153
|
-
#define ossl_asn1_get_tag(o)
|
154
|
-
#define ossl_asn1_get_tagging(o)
|
155
|
-
#define ossl_asn1_get_tag_class(o)
|
156
|
-
|
157
|
-
|
158
|
-
#define
|
159
|
-
#define
|
160
|
-
#define
|
170
|
+
#define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE)
|
171
|
+
#define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG)
|
172
|
+
#define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING)
|
173
|
+
#define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS)
|
174
|
+
#define ossl_asn1_get_infinite_length(o) rb_attr_get((o),sivINFINITE_LENGTH)
|
175
|
+
|
176
|
+
#define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v))
|
177
|
+
#define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v))
|
178
|
+
#define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v))
|
179
|
+
#define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v))
|
180
|
+
#define ossl_asn1_set_infinite_length(o,v) rb_ivar_set((o),sivINFINITE_LENGTH,(v))
|
161
181
|
|
162
182
|
VALUE mASN1;
|
163
183
|
VALUE eASN1Error;
|
@@ -166,6 +186,7 @@ VALUE cASN1Data;
|
|
166
186
|
VALUE cASN1Primitive;
|
167
187
|
VALUE cASN1Constructive;
|
168
188
|
|
189
|
+
VALUE cASN1EndOfContent;
|
169
190
|
VALUE cASN1Boolean; /* BOOLEAN */
|
170
191
|
VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */
|
171
192
|
VALUE cASN1BitString; /* BIT STRING */
|
@@ -182,6 +203,20 @@ VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */
|
|
182
203
|
|
183
204
|
static ID sIMPLICIT, sEXPLICIT;
|
184
205
|
static ID sUNIVERSAL, sAPPLICATION, sCONTEXT_SPECIFIC, sPRIVATE;
|
206
|
+
static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINFINITE_LENGTH, sivUNUSED_BITS;
|
207
|
+
|
208
|
+
/*
|
209
|
+
* We need to implement these for backward compatibility
|
210
|
+
* reasons, behavior of ASN1_put_object and ASN1_object_size
|
211
|
+
* for infinite length values is different in OpenSSL <= 0.9.7
|
212
|
+
*/
|
213
|
+
#if OPENSSL_VERSION_NUMBER < 0x00908000L
|
214
|
+
#define ossl_asn1_object_size(cons, len, tag) (cons) == 2 ? (len) + ASN1_object_size((cons), 0, (tag)) : ASN1_object_size((cons), (len), (tag))
|
215
|
+
#define ossl_asn1_put_object(pp, cons, len, tag, xc) (cons) == 2 ? ASN1_put_object((pp), (cons), 0, (tag), (xc)) : ASN1_put_object((pp), (cons), (len), (tag), (xc))
|
216
|
+
#else
|
217
|
+
#define ossl_asn1_object_size(cons, len, tag) ASN1_object_size((cons), (len), (tag))
|
218
|
+
#define ossl_asn1_put_object(pp, cons, len, tag, xc) ASN1_put_object((pp), (cons), (len), (tag), (xc))
|
219
|
+
#endif
|
185
220
|
|
186
221
|
/*
|
187
222
|
* Ruby to ASN1 converters
|
@@ -189,6 +224,9 @@ static ID sUNIVERSAL, sAPPLICATION, sCONTEXT_SPECIFIC, sPRIVATE;
|
|
189
224
|
static ASN1_BOOLEAN
|
190
225
|
obj_to_asn1bool(VALUE obj)
|
191
226
|
{
|
227
|
+
if (NIL_P(obj))
|
228
|
+
ossl_raise(rb_eTypeError, "Can't convert nil into Boolean");
|
229
|
+
|
192
230
|
#if OPENSSL_VERSION_NUMBER < 0x00907000L
|
193
231
|
return RTEST(obj) ? 0xff : 0x100;
|
194
232
|
#else
|
@@ -211,7 +249,7 @@ obj_to_asn1bstr(VALUE obj, long unused_bits)
|
|
211
249
|
StringValue(obj);
|
212
250
|
if(!(bstr = ASN1_BIT_STRING_new()))
|
213
251
|
ossl_raise(eASN1Error, NULL);
|
214
|
-
ASN1_BIT_STRING_set(bstr, RSTRING_PTR(obj),
|
252
|
+
ASN1_BIT_STRING_set(bstr, (unsigned char *)RSTRING_PTR(obj), RSTRING_LENINT(obj));
|
215
253
|
bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
|
216
254
|
bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT|(unused_bits&0x07);
|
217
255
|
|
@@ -226,7 +264,7 @@ obj_to_asn1str(VALUE obj)
|
|
226
264
|
StringValue(obj);
|
227
265
|
if(!(str = ASN1_STRING_new()))
|
228
266
|
ossl_raise(eASN1Error, NULL);
|
229
|
-
ASN1_STRING_set(str, RSTRING_PTR(obj),
|
267
|
+
ASN1_STRING_set(str, RSTRING_PTR(obj), RSTRING_LENINT(obj));
|
230
268
|
|
231
269
|
return str;
|
232
270
|
}
|
@@ -292,7 +330,7 @@ obj_to_asn1derstr(VALUE obj)
|
|
292
330
|
str = ossl_to_der(obj);
|
293
331
|
if(!(a1str = ASN1_STRING_new()))
|
294
332
|
ossl_raise(eASN1Error, NULL);
|
295
|
-
ASN1_STRING_set(a1str, RSTRING_PTR(str),
|
333
|
+
ASN1_STRING_set(a1str, RSTRING_PTR(str), RSTRING_LENINT(str));
|
296
334
|
|
297
335
|
return a1str;
|
298
336
|
}
|
@@ -301,10 +339,10 @@ obj_to_asn1derstr(VALUE obj)
|
|
301
339
|
* DER to Ruby converters
|
302
340
|
*/
|
303
341
|
static VALUE
|
304
|
-
decode_bool(unsigned char* der,
|
342
|
+
decode_bool(unsigned char* der, long length)
|
305
343
|
{
|
306
344
|
int val;
|
307
|
-
unsigned
|
345
|
+
const unsigned char *p;
|
308
346
|
|
309
347
|
p = der;
|
310
348
|
if((val = d2i_ASN1_BOOLEAN(NULL, &p, length)) < 0)
|
@@ -314,11 +352,11 @@ decode_bool(unsigned char* der, int length)
|
|
314
352
|
}
|
315
353
|
|
316
354
|
static VALUE
|
317
|
-
decode_int(unsigned char* der,
|
355
|
+
decode_int(unsigned char* der, long length)
|
318
356
|
{
|
319
357
|
ASN1_INTEGER *ai;
|
320
|
-
unsigned
|
321
|
-
VALUE ret;
|
358
|
+
const unsigned char *p;
|
359
|
+
VALUE ret;
|
322
360
|
int status = 0;
|
323
361
|
|
324
362
|
p = der;
|
@@ -333,7 +371,7 @@ decode_int(unsigned char* der, int length)
|
|
333
371
|
}
|
334
372
|
|
335
373
|
static VALUE
|
336
|
-
decode_bstr(unsigned char* der,
|
374
|
+
decode_bstr(unsigned char* der, long length, long *unused_bits)
|
337
375
|
{
|
338
376
|
ASN1_BIT_STRING *bstr;
|
339
377
|
const unsigned char *p;
|
@@ -354,11 +392,11 @@ decode_bstr(unsigned char* der, int length, long *unused_bits)
|
|
354
392
|
}
|
355
393
|
|
356
394
|
static VALUE
|
357
|
-
decode_enum(unsigned char* der,
|
395
|
+
decode_enum(unsigned char* der, long length)
|
358
396
|
{
|
359
397
|
ASN1_ENUMERATED *ai;
|
360
|
-
unsigned
|
361
|
-
VALUE ret;
|
398
|
+
const unsigned char *p;
|
399
|
+
VALUE ret;
|
362
400
|
int status = 0;
|
363
401
|
|
364
402
|
p = der;
|
@@ -373,10 +411,10 @@ decode_enum(unsigned char* der, int length)
|
|
373
411
|
}
|
374
412
|
|
375
413
|
static VALUE
|
376
|
-
decode_null(unsigned char* der,
|
414
|
+
decode_null(unsigned char* der, long length)
|
377
415
|
{
|
378
416
|
ASN1_NULL *null;
|
379
|
-
unsigned char
|
417
|
+
const unsigned char *p;
|
380
418
|
|
381
419
|
p = der;
|
382
420
|
if(!(null = d2i_ASN1_NULL(NULL, &p, length)))
|
@@ -387,10 +425,10 @@ decode_null(unsigned char* der, int length)
|
|
387
425
|
}
|
388
426
|
|
389
427
|
static VALUE
|
390
|
-
decode_obj(unsigned char* der,
|
428
|
+
decode_obj(unsigned char* der, long length)
|
391
429
|
{
|
392
430
|
ASN1_OBJECT *obj;
|
393
|
-
unsigned
|
431
|
+
const unsigned char *p;
|
394
432
|
VALUE ret;
|
395
433
|
int nid;
|
396
434
|
BIO *bio;
|
@@ -416,10 +454,10 @@ decode_obj(unsigned char* der, int length)
|
|
416
454
|
}
|
417
455
|
|
418
456
|
static VALUE
|
419
|
-
decode_time(unsigned char* der,
|
457
|
+
decode_time(unsigned char* der, long length)
|
420
458
|
{
|
421
459
|
ASN1_TIME *time;
|
422
|
-
unsigned
|
460
|
+
const unsigned char *p;
|
423
461
|
VALUE ret;
|
424
462
|
int status = 0;
|
425
463
|
|
@@ -434,6 +472,15 @@ decode_time(unsigned char* der, int length)
|
|
434
472
|
return ret;
|
435
473
|
}
|
436
474
|
|
475
|
+
static VALUE
|
476
|
+
decode_eoc(unsigned char *der, long length)
|
477
|
+
{
|
478
|
+
if (length != 2 || !(der[0] == 0x00 && der[1] == 0x00))
|
479
|
+
ossl_raise(eASN1Error, NULL);
|
480
|
+
|
481
|
+
return rb_str_new("", 0);
|
482
|
+
}
|
483
|
+
|
437
484
|
/********/
|
438
485
|
|
439
486
|
typedef struct {
|
@@ -442,7 +489,7 @@ typedef struct {
|
|
442
489
|
} ossl_asn1_info_t;
|
443
490
|
|
444
491
|
static ossl_asn1_info_t ossl_asn1_info[] = {
|
445
|
-
{ "EOC",
|
492
|
+
{ "EOC", &cASN1EndOfContent, }, /* 0 */
|
446
493
|
{ "BOOLEAN", &cASN1Boolean, }, /* 1 */
|
447
494
|
{ "INTEGER", &cASN1Integer, }, /* 2 */
|
448
495
|
{ "BIT_STRING", &cASN1BitString, }, /* 3 */
|
@@ -477,6 +524,8 @@ static ossl_asn1_info_t ossl_asn1_info[] = {
|
|
477
524
|
|
478
525
|
int ossl_asn1_info_size = (sizeof(ossl_asn1_info)/sizeof(ossl_asn1_info[0]));
|
479
526
|
|
527
|
+
static VALUE class_tag_map;
|
528
|
+
|
480
529
|
static int ossl_asn1_default_tag(VALUE obj);
|
481
530
|
|
482
531
|
ASN1_TYPE*
|
@@ -486,7 +535,7 @@ ossl_asn1_get_asn1type(VALUE obj)
|
|
486
535
|
VALUE value, rflag;
|
487
536
|
void *ptr;
|
488
537
|
void (*free_func)();
|
489
|
-
|
538
|
+
int tag, flag;
|
490
539
|
|
491
540
|
tag = ossl_asn1_default_tag(obj);
|
492
541
|
value = ossl_asn1_get_value(obj);
|
@@ -501,7 +550,7 @@ ossl_asn1_get_asn1type(VALUE obj)
|
|
501
550
|
free_func = ASN1_INTEGER_free;
|
502
551
|
break;
|
503
552
|
case V_ASN1_BIT_STRING:
|
504
|
-
rflag = rb_attr_get(obj,
|
553
|
+
rflag = rb_attr_get(obj, sivUNUSED_BITS);
|
505
554
|
flag = NIL_P(rflag) ? -1 : NUM2INT(rflag);
|
506
555
|
ptr = obj_to_asn1bstr(value, flag);
|
507
556
|
free_func = ASN1_BIT_STRING_free;
|
@@ -521,7 +570,7 @@ ossl_asn1_get_asn1type(VALUE obj)
|
|
521
570
|
case V_ASN1_ISO64STRING: /* FALLTHROUGH */
|
522
571
|
case V_ASN1_GENERALSTRING: /* FALLTHROUGH */
|
523
572
|
case V_ASN1_UNIVERSALSTRING: /* FALLTHROUGH */
|
524
|
-
case V_ASN1_BMPSTRING:
|
573
|
+
case V_ASN1_BMPSTRING:
|
525
574
|
ptr = obj_to_asn1str(value);
|
526
575
|
free_func = ASN1_STRING_free;
|
527
576
|
break;
|
@@ -558,13 +607,15 @@ ossl_asn1_get_asn1type(VALUE obj)
|
|
558
607
|
static int
|
559
608
|
ossl_asn1_default_tag(VALUE obj)
|
560
609
|
{
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
610
|
+
VALUE tmp_class, tag;
|
611
|
+
|
612
|
+
tmp_class = CLASS_OF(obj);
|
613
|
+
while (tmp_class) {
|
614
|
+
tag = rb_hash_lookup(class_tag_map, tmp_class);
|
615
|
+
if (tag != Qnil) {
|
616
|
+
return NUM2INT(tag);
|
617
|
+
}
|
618
|
+
tmp_class = rb_class_superclass(tmp_class);
|
568
619
|
}
|
569
620
|
ossl_raise(eASN1Error, "universal tag for %s not found",
|
570
621
|
rb_class2name(CLASS_OF(obj)));
|
@@ -643,6 +694,22 @@ ossl_asn1_class2sym(int tc)
|
|
643
694
|
return ID2SYM(sUNIVERSAL);
|
644
695
|
}
|
645
696
|
|
697
|
+
/*
|
698
|
+
* call-seq:
|
699
|
+
* OpenSSL::ASN1::ASN1Data.new(value, tag, tag_class) => ASN1Data
|
700
|
+
*
|
701
|
+
* +value+: Please have a look at Constructive and Primitive to see how Ruby
|
702
|
+
* types are mapped to ASN.1 types and vice versa.
|
703
|
+
*
|
704
|
+
* +tag+: A +Number+ indicating the tag number.
|
705
|
+
*
|
706
|
+
* +tag_class+: A +Symbol+ indicating the tag class. Please cf. ASN1 for
|
707
|
+
* possible values.
|
708
|
+
*
|
709
|
+
* == Example
|
710
|
+
* asn1_int = OpenSSL::ASN1Data.new(42, 2, :UNIVERSAL) # => Same as OpenSSL::ASN1::Integer.new(42)
|
711
|
+
* tagged_int = OpenSSL::ASN1Data.new(42, 0, :CONTEXT_SPECIFIC) # implicitly 0-tagged INTEGER
|
712
|
+
*/
|
646
713
|
static VALUE
|
647
714
|
ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)
|
648
715
|
{
|
@@ -653,12 +720,13 @@ ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)
|
|
653
720
|
ossl_asn1_set_tag(self, tag);
|
654
721
|
ossl_asn1_set_value(self, value);
|
655
722
|
ossl_asn1_set_tag_class(self, tag_class);
|
723
|
+
ossl_asn1_set_infinite_length(self, Qfalse);
|
656
724
|
|
657
725
|
return self;
|
658
726
|
}
|
659
727
|
|
660
|
-
static VALUE
|
661
|
-
join_der_i(VALUE i, VALUE str)
|
728
|
+
static VALUE
|
729
|
+
join_der_i(VALUE i, VALUE str)
|
662
730
|
{
|
663
731
|
i = ossl_to_der_if_possible(i);
|
664
732
|
StringValue(i);
|
@@ -674,10 +742,19 @@ join_der(VALUE enumerable)
|
|
674
742
|
return str;
|
675
743
|
}
|
676
744
|
|
745
|
+
/*
|
746
|
+
* call-seq:
|
747
|
+
* asn1.to_der => DER-encoded String
|
748
|
+
*
|
749
|
+
* Encodes this ASN1Data into a DER-encoded String value. The result is
|
750
|
+
* DER-encoded except for the possibility of infinite length encodings.
|
751
|
+
* Infinite length encodings are not allowed in strict DER, so strictly
|
752
|
+
* speaking the result of such an encoding would be a BER-encoding.
|
753
|
+
*/
|
677
754
|
static VALUE
|
678
755
|
ossl_asn1data_to_der(VALUE self)
|
679
756
|
{
|
680
|
-
VALUE value, der;
|
757
|
+
VALUE value, der, inf_length;
|
681
758
|
int tag, tag_class, is_cons = 0;
|
682
759
|
long length;
|
683
760
|
unsigned char *p;
|
@@ -691,11 +768,15 @@ ossl_asn1data_to_der(VALUE self)
|
|
691
768
|
|
692
769
|
tag = ossl_asn1_tag(self);
|
693
770
|
tag_class = ossl_asn1_tag_class(self);
|
694
|
-
|
771
|
+
inf_length = ossl_asn1_get_infinite_length(self);
|
772
|
+
if (inf_length == Qtrue) {
|
773
|
+
is_cons = 2;
|
774
|
+
}
|
775
|
+
if((length = ossl_asn1_object_size(is_cons, RSTRING_LENINT(value), tag)) <= 0)
|
695
776
|
ossl_raise(eASN1Error, NULL);
|
696
777
|
der = rb_str_new(0, length);
|
697
|
-
p = RSTRING_PTR(der);
|
698
|
-
|
778
|
+
p = (unsigned char *)RSTRING_PTR(der);
|
779
|
+
ossl_asn1_put_object(&p, is_cons, RSTRING_LENINT(value), tag, tag_class);
|
699
780
|
memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
|
700
781
|
p += RSTRING_LEN(value);
|
701
782
|
ossl_str_adjust(der, p);
|
@@ -704,157 +785,345 @@ ossl_asn1data_to_der(VALUE self)
|
|
704
785
|
}
|
705
786
|
|
706
787
|
static VALUE
|
707
|
-
|
708
|
-
|
788
|
+
int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
|
789
|
+
VALUE tc, long *num_read)
|
709
790
|
{
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
VALUE ary, asn1data, value, tag_class;
|
791
|
+
VALUE value, asn1data;
|
792
|
+
unsigned char *p;
|
793
|
+
long flag = 0;
|
714
794
|
|
715
|
-
ary = rb_ary_new();
|
716
795
|
p = *pp;
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
796
|
+
|
797
|
+
if(tc == sUNIVERSAL && tag < ossl_asn1_info_size) {
|
798
|
+
switch(tag){
|
799
|
+
case V_ASN1_EOC:
|
800
|
+
value = decode_eoc(p, hlen+length);
|
801
|
+
break;
|
802
|
+
case V_ASN1_BOOLEAN:
|
803
|
+
value = decode_bool(p, hlen+length);
|
804
|
+
break;
|
805
|
+
case V_ASN1_INTEGER:
|
806
|
+
value = decode_int(p, hlen+length);
|
807
|
+
break;
|
808
|
+
case V_ASN1_BIT_STRING:
|
809
|
+
value = decode_bstr(p, hlen+length, &flag);
|
810
|
+
break;
|
811
|
+
case V_ASN1_NULL:
|
812
|
+
value = decode_null(p, hlen+length);
|
813
|
+
break;
|
814
|
+
case V_ASN1_ENUMERATED:
|
815
|
+
value = decode_enum(p, hlen+length);
|
816
|
+
break;
|
817
|
+
case V_ASN1_OBJECT:
|
818
|
+
value = decode_obj(p, hlen+length);
|
819
|
+
break;
|
820
|
+
case V_ASN1_UTCTIME: /* FALLTHROUGH */
|
821
|
+
case V_ASN1_GENERALIZEDTIME:
|
822
|
+
value = decode_time(p, hlen+length);
|
823
|
+
break;
|
824
|
+
default:
|
825
|
+
/* use original value */
|
826
|
+
p += hlen;
|
827
|
+
value = rb_str_new((const char *)p, length);
|
828
|
+
break;
|
732
829
|
}
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
830
|
+
}
|
831
|
+
else {
|
832
|
+
p += hlen;
|
833
|
+
value = rb_str_new((const char *)p, length);
|
834
|
+
}
|
835
|
+
|
836
|
+
*pp += hlen + length;
|
837
|
+
*num_read = hlen + length;
|
838
|
+
|
839
|
+
if (tc == sUNIVERSAL && tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) {
|
840
|
+
VALUE klass = *ossl_asn1_info[tag].klass;
|
841
|
+
VALUE args[4];
|
842
|
+
args[0] = value;
|
843
|
+
args[1] = INT2NUM(tag);
|
844
|
+
args[2] = Qnil;
|
845
|
+
args[3] = ID2SYM(tc);
|
846
|
+
asn1data = rb_obj_alloc(klass);
|
847
|
+
ossl_asn1_initialize(4, args, asn1data);
|
848
|
+
if(tag == V_ASN1_BIT_STRING){
|
849
|
+
rb_ivar_set(asn1data, sivUNUSED_BITS, LONG2NUM(flag));
|
752
850
|
}
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
851
|
+
}
|
852
|
+
else {
|
853
|
+
asn1data = rb_obj_alloc(cASN1Data);
|
854
|
+
ossl_asn1data_initialize(asn1data, value, INT2NUM(tag), ID2SYM(tc));
|
855
|
+
}
|
856
|
+
|
857
|
+
return asn1data;
|
858
|
+
}
|
859
|
+
|
860
|
+
static VALUE
|
861
|
+
int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
|
862
|
+
long *offset, int depth, int yield, int j,
|
863
|
+
int tag, VALUE tc, long *num_read)
|
864
|
+
{
|
865
|
+
VALUE value, asn1data, ary;
|
866
|
+
int infinite;
|
867
|
+
long off = *offset;
|
868
|
+
|
869
|
+
infinite = (j == 0x21);
|
870
|
+
ary = rb_ary_new();
|
871
|
+
|
872
|
+
while (length > 0 || infinite) {
|
873
|
+
long inner_read = 0;
|
874
|
+
value = ossl_asn1_decode0(pp, max_len, &off, depth + 1, yield, &inner_read);
|
875
|
+
*num_read += inner_read;
|
876
|
+
max_len -= inner_read;
|
877
|
+
rb_ary_push(ary, value);
|
878
|
+
if (length > 0)
|
879
|
+
length -= inner_read;
|
880
|
+
|
881
|
+
if (infinite &&
|
882
|
+
NUM2INT(ossl_asn1_get_tag(value)) == V_ASN1_EOC &&
|
883
|
+
SYM2ID(ossl_asn1_get_tag_class(value)) == sUNIVERSAL) {
|
884
|
+
break;
|
757
885
|
}
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
break;
|
770
|
-
case V_ASN1_BIT_STRING:
|
771
|
-
value = decode_bstr(start, hlen+len, &flag);
|
772
|
-
break;
|
773
|
-
case V_ASN1_NULL:
|
774
|
-
value = decode_null(start, hlen+len);
|
775
|
-
break;
|
776
|
-
case V_ASN1_ENUMERATED:
|
777
|
-
value = decode_enum(start, hlen+len);
|
778
|
-
break;
|
779
|
-
case V_ASN1_OBJECT:
|
780
|
-
value = decode_obj(start, hlen+len);
|
781
|
-
break;
|
782
|
-
case V_ASN1_UTCTIME: /* FALLTHROUGH */
|
783
|
-
case V_ASN1_GENERALIZEDTIME:
|
784
|
-
value = decode_time(start, hlen+len);
|
785
|
-
break;
|
786
|
-
default:
|
787
|
-
/* use original value */
|
788
|
-
break;
|
789
|
-
}
|
886
|
+
}
|
887
|
+
|
888
|
+
if (tc == sUNIVERSAL) {
|
889
|
+
VALUE args[4];
|
890
|
+
int not_sequence_or_set;
|
891
|
+
|
892
|
+
not_sequence_or_set = tag != V_ASN1_SEQUENCE && tag != V_ASN1_SET;
|
893
|
+
|
894
|
+
if (not_sequence_or_set) {
|
895
|
+
if (infinite) {
|
896
|
+
asn1data = rb_obj_alloc(cASN1Constructive);
|
790
897
|
}
|
791
|
-
|
792
|
-
|
793
|
-
|
898
|
+
else {
|
899
|
+
ossl_raise(eASN1Error, "invalid non-infinite tag");
|
900
|
+
return Qnil;
|
794
901
|
}
|
795
902
|
}
|
796
|
-
else{
|
797
|
-
|
798
|
-
|
903
|
+
else {
|
904
|
+
VALUE klass = *ossl_asn1_info[tag].klass;
|
905
|
+
asn1data = rb_obj_alloc(klass);
|
799
906
|
}
|
800
|
-
|
801
|
-
|
802
|
-
|
907
|
+
args[0] = ary;
|
908
|
+
args[1] = INT2NUM(tag);
|
909
|
+
args[2] = Qnil;
|
910
|
+
args[3] = ID2SYM(tc);
|
911
|
+
ossl_asn1_initialize(4, args, asn1data);
|
912
|
+
}
|
913
|
+
else {
|
914
|
+
asn1data = rb_obj_alloc(cASN1Data);
|
915
|
+
ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), ID2SYM(tc));
|
916
|
+
}
|
917
|
+
|
918
|
+
if (infinite)
|
919
|
+
ossl_asn1_set_infinite_length(asn1data, Qtrue);
|
920
|
+
else
|
921
|
+
ossl_asn1_set_infinite_length(asn1data, Qfalse);
|
922
|
+
|
923
|
+
*offset = off;
|
924
|
+
return asn1data;
|
925
|
+
}
|
926
|
+
|
927
|
+
static VALUE
|
928
|
+
ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth,
|
929
|
+
int yield, long *num_read)
|
930
|
+
{
|
931
|
+
unsigned char *start, *p;
|
932
|
+
const unsigned char *p0;
|
933
|
+
long len = 0, inner_read = 0, off = *offset, hlen;
|
934
|
+
int tag, tc, j;
|
935
|
+
VALUE asn1data, tag_class;
|
936
|
+
|
937
|
+
p = *pp;
|
938
|
+
start = p;
|
939
|
+
p0 = p;
|
940
|
+
j = ASN1_get_object(&p0, &len, &tag, &tc, length);
|
941
|
+
p = (unsigned char *)p0;
|
942
|
+
if(j & 0x80) ossl_raise(eASN1Error, NULL);
|
943
|
+
if(len > length) ossl_raise(eASN1Error, "value is too short");
|
944
|
+
if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
|
945
|
+
tag_class = sPRIVATE;
|
946
|
+
else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
|
947
|
+
tag_class = sCONTEXT_SPECIFIC;
|
948
|
+
else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
|
949
|
+
tag_class = sAPPLICATION;
|
950
|
+
else
|
951
|
+
tag_class = sUNIVERSAL;
|
952
|
+
|
953
|
+
hlen = p - start;
|
954
|
+
|
955
|
+
if(yield) {
|
956
|
+
VALUE arg = rb_ary_new();
|
957
|
+
rb_ary_push(arg, LONG2NUM(depth));
|
958
|
+
rb_ary_push(arg, LONG2NUM(*offset));
|
959
|
+
rb_ary_push(arg, LONG2NUM(hlen));
|
960
|
+
rb_ary_push(arg, LONG2NUM(len));
|
961
|
+
rb_ary_push(arg, (j & V_ASN1_CONSTRUCTED) ? Qtrue : Qfalse);
|
962
|
+
rb_ary_push(arg, ossl_asn1_class2sym(tc));
|
963
|
+
rb_ary_push(arg, INT2NUM(tag));
|
964
|
+
rb_yield(arg);
|
965
|
+
}
|
966
|
+
|
967
|
+
if(j & V_ASN1_CONSTRUCTED) {
|
968
|
+
*pp += hlen;
|
969
|
+
off += hlen;
|
970
|
+
asn1data = int_ossl_asn1_decode0_cons(pp, length, len, &off, depth, yield, j, tag, tag_class, &inner_read);
|
971
|
+
inner_read += hlen;
|
972
|
+
}
|
973
|
+
else {
|
974
|
+
if ((j & 0x01) && (len == 0)) ossl_raise(eASN1Error, "Infinite length for primitive value");
|
975
|
+
asn1data = int_ossl_asn1_decode0_prim(pp, len, hlen, tag, tag_class, &inner_read);
|
976
|
+
off += hlen + len;
|
977
|
+
}
|
978
|
+
if (num_read)
|
979
|
+
*num_read = inner_read;
|
980
|
+
if (len != 0 && inner_read != hlen + len) {
|
981
|
+
ossl_raise(eASN1Error,
|
982
|
+
"Type mismatch. Bytes read: %ld Bytes available: %ld",
|
983
|
+
inner_read, hlen + len);
|
803
984
|
}
|
804
|
-
|
985
|
+
|
805
986
|
*offset = off;
|
987
|
+
return asn1data;
|
988
|
+
}
|
806
989
|
|
807
|
-
|
990
|
+
static void
|
991
|
+
int_ossl_decode_sanity_check(long len, long read, long offset)
|
992
|
+
{
|
993
|
+
if (len != 0 && (read != len || offset != len)) {
|
994
|
+
ossl_raise(eASN1Error,
|
995
|
+
"Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld",
|
996
|
+
read, len, offset);
|
997
|
+
}
|
808
998
|
}
|
809
999
|
|
1000
|
+
/*
|
1001
|
+
* call-seq:
|
1002
|
+
* OpenSSL::ASN1.traverse(asn1) -> nil
|
1003
|
+
*
|
1004
|
+
* If a block is given, it prints out each of the elements encountered.
|
1005
|
+
* Block parameters are (in that order):
|
1006
|
+
* * depth: The recursion depth, plus one with each constructed value being encountered (Number)
|
1007
|
+
* * offset: Current byte offset (Number)
|
1008
|
+
* * header length: Combined length in bytes of the Tag and Length headers. (Number)
|
1009
|
+
* * length: The overall remaining length of the entire data (Number)
|
1010
|
+
* * constructed: Whether this value is constructed or not (Boolean)
|
1011
|
+
* * tag_class: Current tag class (Symbol)
|
1012
|
+
* * tag: The current tag (Number)
|
1013
|
+
*
|
1014
|
+
* == Example
|
1015
|
+
* der = File.binread('asn1data.der')
|
1016
|
+
* OpenSSL::ASN1.traverse(der) do | depth, offset, header_len, length, constructed, tag_class, tag|
|
1017
|
+
* puts "Depth: #{depth} Offset: #{offset} Length: #{length}"
|
1018
|
+
* puts "Header length: #{header_len} Tag: #{tag} Tag class: #{tag_class} Constructed: #{constructed}"
|
1019
|
+
* end
|
1020
|
+
*/
|
810
1021
|
static VALUE
|
811
1022
|
ossl_asn1_traverse(VALUE self, VALUE obj)
|
812
1023
|
{
|
813
1024
|
unsigned char *p;
|
814
|
-
long offset = 0;
|
815
1025
|
volatile VALUE tmp;
|
1026
|
+
long len, read = 0, offset = 0;
|
816
1027
|
|
817
1028
|
obj = ossl_to_der_if_possible(obj);
|
818
1029
|
tmp = rb_str_new4(StringValue(obj));
|
819
|
-
p = RSTRING_PTR(tmp);
|
820
|
-
|
821
|
-
|
1030
|
+
p = (unsigned char *)RSTRING_PTR(tmp);
|
1031
|
+
len = RSTRING_LEN(tmp);
|
1032
|
+
ossl_asn1_decode0(&p, len, &offset, 0, 1, &read);
|
1033
|
+
int_ossl_decode_sanity_check(len, read, offset);
|
822
1034
|
return Qnil;
|
823
1035
|
}
|
824
1036
|
|
1037
|
+
/*
|
1038
|
+
* call-seq:
|
1039
|
+
* OpenSSL::ASN1.decode(der) -> ASN1Data
|
1040
|
+
*
|
1041
|
+
* Decodes a BER- or DER-encoded value and creates an ASN1Data instance. +der+
|
1042
|
+
* may be a +String+ or any object that features a +#to_der+ method transforming
|
1043
|
+
* it into a BER-/DER-encoded +String+.
|
1044
|
+
*
|
1045
|
+
* == Example
|
1046
|
+
* der = File.binread('asn1data')
|
1047
|
+
* asn1 = OpenSSL::ASN1.decode(der)
|
1048
|
+
*/
|
825
1049
|
static VALUE
|
826
1050
|
ossl_asn1_decode(VALUE self, VALUE obj)
|
827
1051
|
{
|
828
|
-
VALUE ret
|
1052
|
+
VALUE ret;
|
829
1053
|
unsigned char *p;
|
830
|
-
long offset = 0;
|
831
1054
|
volatile VALUE tmp;
|
1055
|
+
long len, read = 0, offset = 0;
|
832
1056
|
|
833
1057
|
obj = ossl_to_der_if_possible(obj);
|
834
1058
|
tmp = rb_str_new4(StringValue(obj));
|
835
|
-
p = RSTRING_PTR(tmp);
|
836
|
-
|
837
|
-
ret =
|
838
|
-
|
1059
|
+
p = (unsigned char *)RSTRING_PTR(tmp);
|
1060
|
+
len = RSTRING_LEN(tmp);
|
1061
|
+
ret = ossl_asn1_decode0(&p, len, &offset, 0, 0, &read);
|
1062
|
+
int_ossl_decode_sanity_check(len, read, offset);
|
839
1063
|
return ret;
|
840
1064
|
}
|
841
1065
|
|
1066
|
+
/*
|
1067
|
+
* call-seq:
|
1068
|
+
* OpenSSL::ASN1.decode_all(der) -> Array of ASN1Data
|
1069
|
+
*
|
1070
|
+
* Similar to +decode+ with the difference that +decode+ expects one
|
1071
|
+
* distinct value represented in +der+. +decode_all+ on the contrary
|
1072
|
+
* decodes a sequence of sequential BER/DER values lined up in +der+
|
1073
|
+
* and returns them as an array.
|
1074
|
+
*
|
1075
|
+
* == Example
|
1076
|
+
* ders = File.binread('asn1data_seq')
|
1077
|
+
* asn1_ary = OpenSSL::ASN1.decode_all(ders)
|
1078
|
+
*/
|
842
1079
|
static VALUE
|
843
1080
|
ossl_asn1_decode_all(VALUE self, VALUE obj)
|
844
1081
|
{
|
845
|
-
VALUE
|
1082
|
+
VALUE ary, val;
|
846
1083
|
unsigned char *p;
|
847
|
-
long offset = 0;
|
1084
|
+
long len, tmp_len = 0, read = 0, offset = 0;
|
848
1085
|
volatile VALUE tmp;
|
849
1086
|
|
850
1087
|
obj = ossl_to_der_if_possible(obj);
|
851
1088
|
tmp = rb_str_new4(StringValue(obj));
|
852
|
-
p = RSTRING_PTR(tmp);
|
853
|
-
|
854
|
-
|
855
|
-
|
1089
|
+
p = (unsigned char *)RSTRING_PTR(tmp);
|
1090
|
+
len = RSTRING_LEN(tmp);
|
1091
|
+
tmp_len = len;
|
1092
|
+
ary = rb_ary_new();
|
1093
|
+
while (tmp_len > 0) {
|
1094
|
+
long tmp_read = 0;
|
1095
|
+
val = ossl_asn1_decode0(&p, tmp_len, &offset, 0, 0, &tmp_read);
|
1096
|
+
rb_ary_push(ary, val);
|
1097
|
+
read += tmp_read;
|
1098
|
+
tmp_len -= tmp_read;
|
1099
|
+
}
|
1100
|
+
int_ossl_decode_sanity_check(len, read, offset);
|
1101
|
+
return ary;
|
856
1102
|
}
|
857
1103
|
|
1104
|
+
/*
|
1105
|
+
* call-seq:
|
1106
|
+
* OpenSSL::ASN1::Primitive.new( value [, tag, tagging, tag_class ]) => Primitive
|
1107
|
+
*
|
1108
|
+
* +value+: is mandatory.
|
1109
|
+
*
|
1110
|
+
* +tag+: optional, may be specified for tagged values. If no +tag+ is
|
1111
|
+
* specified, the UNIVERSAL tag corresponding to the Primitive sub-class
|
1112
|
+
* is used by default.
|
1113
|
+
*
|
1114
|
+
* +tagging+: may be used as an encoding hint to encode a value either
|
1115
|
+
* explicitly or implicitly, see ASN1 for possible values.
|
1116
|
+
*
|
1117
|
+
* +tag_class+: if +tag+ and +tagging+ are +nil+ then this is set to
|
1118
|
+
* +:UNIVERSAL+ by default. If either +tag+ or +tagging+ are set then
|
1119
|
+
* +:CONTEXT_SPECIFIC+ is used as the default. For possible values please
|
1120
|
+
* cf. ASN1.
|
1121
|
+
*
|
1122
|
+
* == Example
|
1123
|
+
* int = OpenSSL::ASN1::Integer.new(42)
|
1124
|
+
* zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :IMPLICIT)
|
1125
|
+
* private_explicit_zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :EXPLICIT, :PRIVATE)
|
1126
|
+
*/
|
858
1127
|
static VALUE
|
859
1128
|
ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
|
860
1129
|
{
|
@@ -864,12 +1133,14 @@ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
|
|
864
1133
|
if(argc > 1){
|
865
1134
|
if(NIL_P(tag))
|
866
1135
|
ossl_raise(eASN1Error, "must specify tag number");
|
867
|
-
|
868
|
-
tagging
|
869
|
-
if(
|
870
|
-
|
871
|
-
|
872
|
-
|
1136
|
+
if(!NIL_P(tagging) && !SYMBOL_P(tagging))
|
1137
|
+
ossl_raise(eASN1Error, "invalid tagging method");
|
1138
|
+
if(NIL_P(tag_class)) {
|
1139
|
+
if (NIL_P(tagging))
|
1140
|
+
tag_class = ID2SYM(sUNIVERSAL);
|
1141
|
+
else
|
1142
|
+
tag_class = ID2SYM(sCONTEXT_SPECIFIC);
|
1143
|
+
}
|
873
1144
|
if(!SYMBOL_P(tag_class))
|
874
1145
|
ossl_raise(eASN1Error, "invalid tag class");
|
875
1146
|
if(SYM2ID(tagging) == sIMPLICIT && NUM2INT(tag) > 31)
|
@@ -877,17 +1148,33 @@ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
|
|
877
1148
|
}
|
878
1149
|
else{
|
879
1150
|
tag = INT2NUM(ossl_asn1_default_tag(self));
|
880
|
-
|
1151
|
+
tagging = Qnil;
|
881
1152
|
tag_class = ID2SYM(sUNIVERSAL);
|
882
1153
|
}
|
883
1154
|
ossl_asn1_set_tag(self, tag);
|
884
1155
|
ossl_asn1_set_value(self, value);
|
885
1156
|
ossl_asn1_set_tagging(self, tagging);
|
886
1157
|
ossl_asn1_set_tag_class(self, tag_class);
|
1158
|
+
ossl_asn1_set_infinite_length(self, Qfalse);
|
887
1159
|
|
888
1160
|
return self;
|
889
1161
|
}
|
890
1162
|
|
1163
|
+
static VALUE
|
1164
|
+
ossl_asn1eoc_initialize(VALUE self) {
|
1165
|
+
VALUE tag, tagging, tag_class, value;
|
1166
|
+
tag = INT2NUM(ossl_asn1_default_tag(self));
|
1167
|
+
tagging = Qnil;
|
1168
|
+
tag_class = ID2SYM(sUNIVERSAL);
|
1169
|
+
value = rb_str_new("", 0);
|
1170
|
+
ossl_asn1_set_tag(self, tag);
|
1171
|
+
ossl_asn1_set_value(self, value);
|
1172
|
+
ossl_asn1_set_tagging(self, tagging);
|
1173
|
+
ossl_asn1_set_tag_class(self, tag_class);
|
1174
|
+
ossl_asn1_set_infinite_length(self, Qfalse);
|
1175
|
+
return self;
|
1176
|
+
}
|
1177
|
+
|
891
1178
|
static int
|
892
1179
|
ossl_i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **pp)
|
893
1180
|
{
|
@@ -912,6 +1199,12 @@ ossl_ASN1_TYPE_free(ASN1_TYPE *a)
|
|
912
1199
|
ASN1_TYPE_free(a);
|
913
1200
|
}
|
914
1201
|
|
1202
|
+
/*
|
1203
|
+
* call-seq:
|
1204
|
+
* asn1.to_der => DER-encoded String
|
1205
|
+
*
|
1206
|
+
* See ASN1Data#to_der for details. *
|
1207
|
+
*/
|
915
1208
|
static VALUE
|
916
1209
|
ossl_asn1prim_to_der(VALUE self)
|
917
1210
|
{
|
@@ -926,7 +1219,7 @@ ossl_asn1prim_to_der(VALUE self)
|
|
926
1219
|
explicit = ossl_asn1_is_explicit(self);
|
927
1220
|
asn1 = ossl_asn1_get_asn1type(self);
|
928
1221
|
|
929
|
-
len =
|
1222
|
+
len = ossl_asn1_object_size(1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn);
|
930
1223
|
if(!(buf = OPENSSL_malloc(len))){
|
931
1224
|
ossl_ASN1_TYPE_free(asn1);
|
932
1225
|
ossl_raise(eASN1Error, "cannot alloc buffer");
|
@@ -935,7 +1228,7 @@ ossl_asn1prim_to_der(VALUE self)
|
|
935
1228
|
if (tc == V_ASN1_UNIVERSAL) {
|
936
1229
|
ossl_i2d_ASN1_TYPE(asn1, &p);
|
937
1230
|
} else if (explicit) {
|
938
|
-
|
1231
|
+
ossl_asn1_put_object(&p, 1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn, tc);
|
939
1232
|
ossl_i2d_ASN1_TYPE(asn1, &p);
|
940
1233
|
} else {
|
941
1234
|
ossl_i2d_ASN1_TYPE(asn1, &p);
|
@@ -944,45 +1237,113 @@ ossl_asn1prim_to_der(VALUE self)
|
|
944
1237
|
ossl_ASN1_TYPE_free(asn1);
|
945
1238
|
reallen = p - buf;
|
946
1239
|
assert(reallen <= len);
|
947
|
-
str = ossl_buf2str(buf, reallen); /* buf will be free in ossl_buf2str */
|
1240
|
+
str = ossl_buf2str((char *)buf, rb_long2int(reallen)); /* buf will be free in ossl_buf2str */
|
948
1241
|
|
949
1242
|
return str;
|
950
1243
|
}
|
951
1244
|
|
1245
|
+
/*
|
1246
|
+
* call-seq:
|
1247
|
+
* asn1.to_der => DER-encoded String
|
1248
|
+
*
|
1249
|
+
* See ASN1Data#to_der for details.
|
1250
|
+
*/
|
952
1251
|
static VALUE
|
953
1252
|
ossl_asn1cons_to_der(VALUE self)
|
954
1253
|
{
|
955
|
-
int tag, tn, tc, explicit;
|
956
|
-
|
1254
|
+
int tag, tn, tc, explicit, constructed = 1;
|
1255
|
+
int found_prim = 0, seq_len;
|
1256
|
+
long length;
|
957
1257
|
unsigned char *p;
|
958
|
-
VALUE value, str;
|
1258
|
+
VALUE value, str, inf_length;
|
959
1259
|
|
960
|
-
tag = ossl_asn1_default_tag(self);
|
961
1260
|
tn = NUM2INT(ossl_asn1_get_tag(self));
|
962
1261
|
tc = ossl_asn1_tag_class(self);
|
1262
|
+
inf_length = ossl_asn1_get_infinite_length(self);
|
1263
|
+
if (inf_length == Qtrue) {
|
1264
|
+
VALUE ary, example;
|
1265
|
+
constructed = 2;
|
1266
|
+
if (CLASS_OF(self) == cASN1Sequence ||
|
1267
|
+
CLASS_OF(self) == cASN1Set) {
|
1268
|
+
tag = ossl_asn1_default_tag(self);
|
1269
|
+
}
|
1270
|
+
else { /* must be a constructive encoding of a primitive value */
|
1271
|
+
ary = ossl_asn1_get_value(self);
|
1272
|
+
if (!rb_obj_is_kind_of(ary, rb_cArray))
|
1273
|
+
ossl_raise(eASN1Error, "Constructive value must be an Array");
|
1274
|
+
/* Recursively descend until a primitive value is found.
|
1275
|
+
The overall value of the entire constructed encoding
|
1276
|
+
is of the type of the first primitive encoding to be
|
1277
|
+
found. */
|
1278
|
+
while (!found_prim){
|
1279
|
+
example = rb_ary_entry(ary, 0);
|
1280
|
+
if (rb_obj_is_kind_of(example, cASN1Primitive)){
|
1281
|
+
found_prim = 1;
|
1282
|
+
}
|
1283
|
+
else {
|
1284
|
+
/* example is another ASN1Constructive */
|
1285
|
+
if (!rb_obj_is_kind_of(example, cASN1Constructive)){
|
1286
|
+
ossl_raise(eASN1Error, "invalid constructed encoding");
|
1287
|
+
return Qnil; /* dummy */
|
1288
|
+
}
|
1289
|
+
ary = ossl_asn1_get_value(example);
|
1290
|
+
}
|
1291
|
+
}
|
1292
|
+
tag = ossl_asn1_default_tag(example);
|
1293
|
+
}
|
1294
|
+
}
|
1295
|
+
else {
|
1296
|
+
if (CLASS_OF(self) == cASN1Constructive)
|
1297
|
+
ossl_raise(eASN1Error, "Constructive shall only be used with infinite length");
|
1298
|
+
tag = ossl_asn1_default_tag(self);
|
1299
|
+
}
|
963
1300
|
explicit = ossl_asn1_is_explicit(self);
|
964
1301
|
value = join_der(ossl_asn1_get_value(self));
|
965
1302
|
|
966
|
-
seq_len =
|
967
|
-
length =
|
1303
|
+
seq_len = ossl_asn1_object_size(constructed, RSTRING_LENINT(value), tag);
|
1304
|
+
length = ossl_asn1_object_size(constructed, seq_len, tn);
|
968
1305
|
str = rb_str_new(0, length);
|
969
|
-
p = RSTRING_PTR(str);
|
1306
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
970
1307
|
if(tc == V_ASN1_UNIVERSAL)
|
971
|
-
|
1308
|
+
ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc);
|
972
1309
|
else{
|
973
1310
|
if(explicit){
|
974
|
-
|
975
|
-
|
1311
|
+
ossl_asn1_put_object(&p, constructed, seq_len, tn, tc);
|
1312
|
+
ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tag, V_ASN1_UNIVERSAL);
|
1313
|
+
}
|
1314
|
+
else{
|
1315
|
+
ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc);
|
976
1316
|
}
|
977
|
-
else ASN1_put_object(&p, 1, RSTRING_LEN(value), tn, tc);
|
978
1317
|
}
|
979
1318
|
memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
|
980
1319
|
p += RSTRING_LEN(value);
|
1320
|
+
|
1321
|
+
/* In this case we need an additional EOC (one for the explicit part and
|
1322
|
+
* one for the Constructive itself. The EOC for the Constructive is
|
1323
|
+
* supplied by the user, but that for the "explicit wrapper" must be
|
1324
|
+
* added here.
|
1325
|
+
*/
|
1326
|
+
if (explicit && inf_length == Qtrue) {
|
1327
|
+
ASN1_put_eoc(&p);
|
1328
|
+
}
|
981
1329
|
ossl_str_adjust(str, p);
|
982
1330
|
|
983
1331
|
return str;
|
984
1332
|
}
|
985
1333
|
|
1334
|
+
/*
|
1335
|
+
* call-seq:
|
1336
|
+
* asn1_ary.each { |asn1| block } => asn1_ary
|
1337
|
+
*
|
1338
|
+
* Calls <i>block</i> once for each element in +self+, passing that element
|
1339
|
+
* as parameter +asn1+. If no block is given, an enumerator is returned
|
1340
|
+
* instead.
|
1341
|
+
*
|
1342
|
+
* == Example
|
1343
|
+
* asn1_ary.each do |asn1|
|
1344
|
+
* puts asn1
|
1345
|
+
* end
|
1346
|
+
*/
|
986
1347
|
static VALUE
|
987
1348
|
ossl_asn1cons_each(VALUE self)
|
988
1349
|
{
|
@@ -1070,6 +1431,7 @@ OSSL_ASN1_IMPL_FACTORY_METHOD(UTCTime)
|
|
1070
1431
|
OSSL_ASN1_IMPL_FACTORY_METHOD(GeneralizedTime)
|
1071
1432
|
OSSL_ASN1_IMPL_FACTORY_METHOD(Sequence)
|
1072
1433
|
OSSL_ASN1_IMPL_FACTORY_METHOD(Set)
|
1434
|
+
OSSL_ASN1_IMPL_FACTORY_METHOD(EndOfContent)
|
1073
1435
|
|
1074
1436
|
void
|
1075
1437
|
Init_ossl_asn1()
|
@@ -1077,8 +1439,8 @@ Init_ossl_asn1()
|
|
1077
1439
|
VALUE ary;
|
1078
1440
|
int i;
|
1079
1441
|
|
1080
|
-
#if 0
|
1081
|
-
mOSSL = rb_define_module("OpenSSL");
|
1442
|
+
#if 0
|
1443
|
+
mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
|
1082
1444
|
#endif
|
1083
1445
|
|
1084
1446
|
sUNIVERSAL = rb_intern("UNIVERSAL");
|
@@ -1088,12 +1450,155 @@ Init_ossl_asn1()
|
|
1088
1450
|
sEXPLICIT = rb_intern("EXPLICIT");
|
1089
1451
|
sIMPLICIT = rb_intern("IMPLICIT");
|
1090
1452
|
|
1453
|
+
sivVALUE = rb_intern("@value");
|
1454
|
+
sivTAG = rb_intern("@tag");
|
1455
|
+
sivTAGGING = rb_intern("@tagging");
|
1456
|
+
sivTAG_CLASS = rb_intern("@tag_class");
|
1457
|
+
sivINFINITE_LENGTH = rb_intern("@infinite_length");
|
1458
|
+
sivUNUSED_BITS = rb_intern("@unused_bits");
|
1459
|
+
|
1460
|
+
/*
|
1461
|
+
* Document-module: OpenSSL::ASN1
|
1462
|
+
*
|
1463
|
+
* Abstract Syntax Notation One (or ASN.1) is a notation syntax to
|
1464
|
+
* describe data structures and is defined in ITU-T X.680. ASN.1 itself
|
1465
|
+
* does not mandate any encoding or parsing rules, but usually ASN.1 data
|
1466
|
+
* structures are encoded using the Distinguished Encoding Rules (DER) or
|
1467
|
+
* less often the Basic Encoding Rules (BER) described in ITU-T X.690. DER
|
1468
|
+
* and BER encodings are binary Tag-Length-Value (TLV) encodings that are
|
1469
|
+
* quite concise compared to other popular data description formats such
|
1470
|
+
* as XML, JSON etc.
|
1471
|
+
* ASN.1 data structures are very common in cryptographic applications,
|
1472
|
+
* e.g. X.509 public key certificates or certificate revocation lists
|
1473
|
+
* (CRLs) are all defined in ASN.1 and DER-encoded. ASN.1, DER and BER are
|
1474
|
+
* the building blocks of applied cryptography.
|
1475
|
+
* The ASN1 module provides the necessary classes that allow generation
|
1476
|
+
* of ASN.1 data structures and the methods to encode them using a DER
|
1477
|
+
* encoding. The decode method allows parsing arbitrary BER-/DER-encoded
|
1478
|
+
* data to a Ruby object that can then be modified and re-encoded at will.
|
1479
|
+
*
|
1480
|
+
* == ASN.1 class hierarchy
|
1481
|
+
*
|
1482
|
+
* The base class representing ASN.1 structures is ASN1Data. ASN1Data offers
|
1483
|
+
* attributes to read and set the +tag+, the +tag_class+ and finally the
|
1484
|
+
* +value+ of a particular ASN.1 item. Upon parsing, any tagged values
|
1485
|
+
* (implicit or explicit) will be represented by ASN1Data instances because
|
1486
|
+
* their "real type" can only be determined using out-of-band information
|
1487
|
+
* from the ASN.1 type declaration. Since this information is normally
|
1488
|
+
* known when encoding a type, all sub-classes of ASN1Data offer an
|
1489
|
+
* additional attribute +tagging+ that allows to encode a value implicitly
|
1490
|
+
* (+:IMPLICIT+) or explicitly (+:EXPLICIT+).
|
1491
|
+
*
|
1492
|
+
* === Constructive
|
1493
|
+
*
|
1494
|
+
* Constructive is, as its name implies, the base class for all
|
1495
|
+
* constructed encodings, i.e. those that consist of several values,
|
1496
|
+
* opposed to "primitive" encodings with just one single value.
|
1497
|
+
* Primitive values that are encoded with "infinite length" are typically
|
1498
|
+
* constructed (their values come in multiple chunks) and are therefore
|
1499
|
+
* represented by instances of Constructive. The value of an Constructive
|
1500
|
+
* is always an Array.
|
1501
|
+
*
|
1502
|
+
* ==== ASN1::Set and ASN1::Sequence
|
1503
|
+
*
|
1504
|
+
* The most common constructive encodings are SETs and SEQUENCEs, which is
|
1505
|
+
* why there are two sub-classes of Constructive representing each of
|
1506
|
+
* them.
|
1507
|
+
*
|
1508
|
+
* === Primitive
|
1509
|
+
*
|
1510
|
+
* This is the super class of all primitive values. Primitive
|
1511
|
+
* itself is not used when parsing ASN.1 data, all values are either
|
1512
|
+
* instances of a corresponding sub-class of Primitive or they are
|
1513
|
+
* instances of ASN1Data if the value was tagged implicitly or explicitly.
|
1514
|
+
* Please cf. Primitive documentation for details on sub-classes and
|
1515
|
+
* their respective mappings of ASN.1 data types to Ruby objects.
|
1516
|
+
*
|
1517
|
+
* == Possible values for +tagging+
|
1518
|
+
*
|
1519
|
+
* When constructing an ASN1Data object the ASN.1 type definition may
|
1520
|
+
* require certain elements to be either implicitly or explicitly tagged.
|
1521
|
+
* This can be achieved by setting the +tagging+ attribute manually for
|
1522
|
+
* sub-classes of ASN1Data. Use the symbol +:IMPLICIT+ for implicit
|
1523
|
+
* tagging and +:EXPLICIT+ if the element requires explicit tagging.
|
1524
|
+
*
|
1525
|
+
* == Possible values for +tag_class+
|
1526
|
+
*
|
1527
|
+
* It is possible to create arbitrary ASN1Data objects that also support
|
1528
|
+
* a PRIVATE or APPLICATION tag class. Possible values for the +tag_class+
|
1529
|
+
* attribute are:
|
1530
|
+
* * +:UNIVERSAL+ (the default for untagged values)
|
1531
|
+
* * +:CONTEXT_SPECIFIC+ (the default for tagged values)
|
1532
|
+
* * +:APPLICATION+
|
1533
|
+
* * +:PRIVATE+
|
1534
|
+
*
|
1535
|
+
* == Tag constants
|
1536
|
+
*
|
1537
|
+
* There is a constant defined for each universal tag:
|
1538
|
+
* * OpenSSL::ASN1::EOC (0)
|
1539
|
+
* * OpenSSL::ASN1::BOOLEAN (1)
|
1540
|
+
* * OpenSSL::ASN1::INTEGER (2)
|
1541
|
+
* * OpenSSL::ASN1::BIT_STRING (3)
|
1542
|
+
* * OpenSSL::ASN1::OCTET_STRING (4)
|
1543
|
+
* * OpenSSL::ASN1::NULL (5)
|
1544
|
+
* * OpenSSL::ASN1::OBJECT (6)
|
1545
|
+
* * OpenSSL::ASN1::ENUMERATED (10)
|
1546
|
+
* * OpenSSL::ASN1::UTF8STRING (12)
|
1547
|
+
* * OpenSSL::ASN1::SEQUENCE (16)
|
1548
|
+
* * OpenSSL::ASN1::SET (17)
|
1549
|
+
* * OpenSSL::ASN1::NUMERICSTRING (18)
|
1550
|
+
* * OpenSSL::ASN1::PRINTABLESTRING (19)
|
1551
|
+
* * OpenSSL::ASN1::T61STRING (20)
|
1552
|
+
* * OpenSSL::ASN1::VIDEOTEXSTRING (21)
|
1553
|
+
* * OpenSSL::ASN1::IA5STRING (22)
|
1554
|
+
* * OpenSSL::ASN1::UTCTIME (23)
|
1555
|
+
* * OpenSSL::ASN1::GENERALIZEDTIME (24)
|
1556
|
+
* * OpenSSL::ASN1::GRAPHICSTRING (25)
|
1557
|
+
* * OpenSSL::ASN1::ISO64STRING (26)
|
1558
|
+
* * OpenSSL::ASN1::GENERALSTRING (27)
|
1559
|
+
* * OpenSSL::ASN1::UNIVERSALSTRING (28)
|
1560
|
+
* * OpenSSL::ASN1::BMPSTRING (30)
|
1561
|
+
*
|
1562
|
+
* == UNIVERSAL_TAG_NAME constant
|
1563
|
+
*
|
1564
|
+
* An Array that stores the name of a given tag number. These names are
|
1565
|
+
* the same as the name of the tag constant that is additionally defined,
|
1566
|
+
* e.g. UNIVERSAL_TAG_NAME[2] = "INTEGER" and OpenSSL::ASN1::INTEGER = 2.
|
1567
|
+
*
|
1568
|
+
* == Example usage
|
1569
|
+
*
|
1570
|
+
* === Decoding and viewing a DER-encoded file
|
1571
|
+
* require 'openssl'
|
1572
|
+
* require 'pp'
|
1573
|
+
* der = File.binread('data.der')
|
1574
|
+
* asn1 = OpenSSL::ASN1.decode(der)
|
1575
|
+
* pp der
|
1576
|
+
*
|
1577
|
+
* === Creating an ASN.1 structure and DER-encoding it
|
1578
|
+
* require 'openssl'
|
1579
|
+
* version = OpenSSL::ASN1::Integer.new(1)
|
1580
|
+
* # Explicitly 0-tagged implies context-specific tag class
|
1581
|
+
* serial = OpenSSL::ASN1::Integer.new(12345, 0, :EXPLICIT, :CONTEXT_SPECIFIC)
|
1582
|
+
* name = OpenSSL::ASN1::PrintableString.new('Data 1')
|
1583
|
+
* sequence = OpenSSL::ASN1::Sequence.new( [ version, serial, name ] )
|
1584
|
+
* der = sequence.to_der
|
1585
|
+
*/
|
1091
1586
|
mASN1 = rb_define_module_under(mOSSL, "ASN1");
|
1587
|
+
|
1588
|
+
/* Document-class: OpenSSL::ASN1::ASN1Error
|
1589
|
+
*
|
1590
|
+
* Generic error class for all errors raised in ASN1 and any of the
|
1591
|
+
* classes defined in it.
|
1592
|
+
*/
|
1092
1593
|
eASN1Error = rb_define_class_under(mASN1, "ASN1Error", eOSSLError);
|
1093
1594
|
rb_define_module_function(mASN1, "traverse", ossl_asn1_traverse, 1);
|
1094
1595
|
rb_define_module_function(mASN1, "decode", ossl_asn1_decode, 1);
|
1095
1596
|
rb_define_module_function(mASN1, "decode_all", ossl_asn1_decode_all, 1);
|
1096
1597
|
ary = rb_ary_new();
|
1598
|
+
|
1599
|
+
/*
|
1600
|
+
* Array storing tag names at the tag's index.
|
1601
|
+
*/
|
1097
1602
|
rb_define_const(mASN1, "UNIVERSAL_TAG_NAME", ary);
|
1098
1603
|
for(i = 0; i < ossl_asn1_info_size; i++){
|
1099
1604
|
if(ossl_asn1_info[i].name[0] == '[') continue;
|
@@ -1101,20 +1606,272 @@ Init_ossl_asn1()
|
|
1101
1606
|
rb_ary_store(ary, i, rb_str_new2(ossl_asn1_info[i].name));
|
1102
1607
|
}
|
1103
1608
|
|
1609
|
+
/* Document-class: OpenSSL::ASN1::ASN1Data
|
1610
|
+
*
|
1611
|
+
* The top-level class representing any ASN.1 object. When parsed by
|
1612
|
+
* ASN1.decode, tagged values are always represented by an instance
|
1613
|
+
* of ASN1Data.
|
1614
|
+
*
|
1615
|
+
* == The role of ASN1Data for parsing tagged values
|
1616
|
+
*
|
1617
|
+
* When encoding an ASN.1 type it is inherently clear what original
|
1618
|
+
* type (e.g. INTEGER, OCTET STRING etc.) this value has, regardless
|
1619
|
+
* of its tagging.
|
1620
|
+
* But opposed to the time an ASN.1 type is to be encoded, when parsing
|
1621
|
+
* them it is not possible to deduce the "real type" of tagged
|
1622
|
+
* values. This is why tagged values are generally parsed into ASN1Data
|
1623
|
+
* instances, but with a different outcome for implicit and explicit
|
1624
|
+
* tagging.
|
1625
|
+
*
|
1626
|
+
* === Example of a parsed implicitly tagged value
|
1627
|
+
*
|
1628
|
+
* An implicitly 1-tagged INTEGER value will be parsed as an
|
1629
|
+
* ASN1Data with
|
1630
|
+
* * +tag+ equal to 1
|
1631
|
+
* * +tag_class+ equal to +:CONTEXT_SPECIFIC+
|
1632
|
+
* * +value+ equal to a +String+ that carries the raw encoding
|
1633
|
+
* of the INTEGER.
|
1634
|
+
* This implies that a subsequent decoding step is required to
|
1635
|
+
* completely decode implicitly tagged values.
|
1636
|
+
*
|
1637
|
+
* === Example of a parsed explicitly tagged value
|
1638
|
+
*
|
1639
|
+
* An explicitly 1-tagged INTEGER value will be parsed as an
|
1640
|
+
* ASN1Data with
|
1641
|
+
* * +tag+ equal to 1
|
1642
|
+
* * +tag_class+ equal to +:CONTEXT_SPECIFIC+
|
1643
|
+
* * +value+ equal to an +Array+ with one single element, an
|
1644
|
+
* instance of OpenSSL::ASN1::Integer, i.e. the inner element
|
1645
|
+
* is the non-tagged primitive value, and the tagging is represented
|
1646
|
+
* in the outer ASN1Data
|
1647
|
+
*
|
1648
|
+
* == Example - Decoding an implicitly tagged INTEGER
|
1649
|
+
* int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT) # implicit 0-tagged
|
1650
|
+
* seq = OpenSSL::ASN1::Sequence.new( [int] )
|
1651
|
+
* der = seq.to_der
|
1652
|
+
* asn1 = OpenSSL::ASN1.decode(der)
|
1653
|
+
* # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0
|
1654
|
+
* # @infinite_length=false,
|
1655
|
+
* # @tag=16,
|
1656
|
+
* # @tag_class=:UNIVERSAL,
|
1657
|
+
* # @tagging=nil,
|
1658
|
+
* # @value=
|
1659
|
+
* # [#<OpenSSL::ASN1::ASN1Data:0x87326f4
|
1660
|
+
* # @infinite_length=false,
|
1661
|
+
* # @tag=0,
|
1662
|
+
* # @tag_class=:CONTEXT_SPECIFIC,
|
1663
|
+
* # @value="\x01">]>
|
1664
|
+
* raw_int = asn1.value[0]
|
1665
|
+
* # manually rewrite tag and tag class to make it an UNIVERSAL value
|
1666
|
+
* raw_int.tag = OpenSSL::ASN1::INTEGER
|
1667
|
+
* raw_int.tag_class = :UNIVERSAL
|
1668
|
+
* int2 = OpenSSL::ASN1.decode(raw_int)
|
1669
|
+
* puts int2.value # => 1
|
1670
|
+
*
|
1671
|
+
* == Example - Decoding an explicitly tagged INTEGER
|
1672
|
+
* int = OpenSSL::ASN1::Integer.new(1, 0, :EXPLICIT) # explicit 0-tagged
|
1673
|
+
* seq = OpenSSL::ASN1::Sequence.new( [int] )
|
1674
|
+
* der = seq.to_der
|
1675
|
+
* asn1 = OpenSSL::ASN1.decode(der)
|
1676
|
+
* # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0
|
1677
|
+
* # @infinite_length=false,
|
1678
|
+
* # @tag=16,
|
1679
|
+
* # @tag_class=:UNIVERSAL,
|
1680
|
+
* # @tagging=nil,
|
1681
|
+
* # @value=
|
1682
|
+
* # [#<OpenSSL::ASN1::ASN1Data:0x87326f4
|
1683
|
+
* # @infinite_length=false,
|
1684
|
+
* # @tag=0,
|
1685
|
+
* # @tag_class=:CONTEXT_SPECIFIC,
|
1686
|
+
* # @value=
|
1687
|
+
* # [#<OpenSSL::ASN1::Integer:0x85bf308
|
1688
|
+
* # @infinite_length=false,
|
1689
|
+
* # @tag=2,
|
1690
|
+
* # @tag_class=:UNIVERSAL
|
1691
|
+
* # @tagging=nil,
|
1692
|
+
* # @value=1>]>]>
|
1693
|
+
* int2 = asn1.value[0].value[0]
|
1694
|
+
* puts int2.value # => 1
|
1695
|
+
*/
|
1104
1696
|
cASN1Data = rb_define_class_under(mASN1, "ASN1Data", rb_cObject);
|
1697
|
+
/*
|
1698
|
+
* Carries the value of a ASN.1 type.
|
1699
|
+
* Please confer Constructive and Primitive for the mappings between
|
1700
|
+
* ASN.1 data types and Ruby classes.
|
1701
|
+
*/
|
1105
1702
|
rb_attr(cASN1Data, rb_intern("value"), 1, 1, 0);
|
1703
|
+
/*
|
1704
|
+
* A +Number+ representing the tag number of this ASN1Data. Never +nil+.
|
1705
|
+
*/
|
1106
1706
|
rb_attr(cASN1Data, rb_intern("tag"), 1, 1, 0);
|
1707
|
+
/*
|
1708
|
+
* A +Symbol+ representing the tag class of this ASN1Data. Never +nil+.
|
1709
|
+
* See ASN1Data for possible values.
|
1710
|
+
*/
|
1107
1711
|
rb_attr(cASN1Data, rb_intern("tag_class"), 1, 1, 0);
|
1712
|
+
/*
|
1713
|
+
* Never +nil+. A +Boolean+ indicating whether the encoding was infinite
|
1714
|
+
* length (in the case of parsing) or whether an infinite length encoding
|
1715
|
+
* shall be used (in the encoding case).
|
1716
|
+
* In DER, every value has a finite length associated with it. But in
|
1717
|
+
* scenarios where large amounts of data need to be transferred it
|
1718
|
+
* might be desirable to have some kind of streaming support available.
|
1719
|
+
* For example, huge OCTET STRINGs are preferably sent in smaller-sized
|
1720
|
+
* chunks, each at a time.
|
1721
|
+
* This is possible in BER by setting the length bytes of an encoding
|
1722
|
+
* to zero and by this indicating that the following value will be
|
1723
|
+
* sent in chunks. Infinite length encodings are always constructed.
|
1724
|
+
* The end of such a stream of chunks is indicated by sending a EOC
|
1725
|
+
* (End of Content) tag. SETs and SEQUENCEs may use an infinite length
|
1726
|
+
* encoding, but also primitive types such as e.g. OCTET STRINGS or
|
1727
|
+
* BIT STRINGS may leverage this functionality (cf. ITU-T X.690).
|
1728
|
+
*/
|
1729
|
+
rb_attr(cASN1Data, rb_intern("infinite_length"), 1, 1, 0);
|
1108
1730
|
rb_define_method(cASN1Data, "initialize", ossl_asn1data_initialize, 3);
|
1109
1731
|
rb_define_method(cASN1Data, "to_der", ossl_asn1data_to_der, 0);
|
1110
1732
|
|
1733
|
+
/* Document-class: OpenSSL::ASN1::Primitive
|
1734
|
+
*
|
1735
|
+
* The parent class for all primitive encodings. Attributes are the same as
|
1736
|
+
* for ASN1Data, with the addition of +tagging+.
|
1737
|
+
* Primitive values can never be infinite length encodings, thus it is not
|
1738
|
+
* possible to set the +infinite_length+ attribute for Primitive and its
|
1739
|
+
* sub-classes.
|
1740
|
+
*
|
1741
|
+
* == Primitive sub-classes and their mapping to Ruby classes
|
1742
|
+
* * OpenSSL::ASN1::EndOfContent <=> +value+ is always +nil+
|
1743
|
+
* * OpenSSL::ASN1::Boolean <=> +value+ is a +Boolean+
|
1744
|
+
* * OpenSSL::ASN1::Integer <=> +value+ is a +Number+
|
1745
|
+
* * OpenSSL::ASN1::BitString <=> +value+ is a +String+
|
1746
|
+
* * OpenSSL::ASN1::OctetString <=> +value+ is a +String+
|
1747
|
+
* * OpenSSL::ASN1::Null <=> +value+ is always +nil+
|
1748
|
+
* * OpenSSL::ASN1::Object <=> +value+ is a +String+
|
1749
|
+
* * OpenSSL::ASN1::Enumerated <=> +value+ is a +Number+
|
1750
|
+
* * OpenSSL::ASN1::UTF8String <=> +value+ is a +String+
|
1751
|
+
* * OpenSSL::ASN1::NumericString <=> +value+ is a +String+
|
1752
|
+
* * OpenSSL::ASN1::PrintableString <=> +value+ is a +String+
|
1753
|
+
* * OpenSSL::ASN1::T61String <=> +value+ is a +String+
|
1754
|
+
* * OpenSSL::ASN1::VideotexString <=> +value+ is a +String+
|
1755
|
+
* * OpenSSL::ASN1::IA5String <=> +value+ is a +String+
|
1756
|
+
* * OpenSSL::ASN1::UTCTime <=> +value+ is a +Time+
|
1757
|
+
* * OpenSSL::ASN1::GeneralizedTime <=> +value+ is a +Time+
|
1758
|
+
* * OpenSSL::ASN1::GraphicString <=> +value+ is a +String+
|
1759
|
+
* * OpenSSL::ASN1::ISO64String <=> +value+ is a +String+
|
1760
|
+
* * OpenSSL::ASN1::GeneralString <=> +value+ is a +String+
|
1761
|
+
* * OpenSSL::ASN1::UniversalString <=> +value+ is a +String+
|
1762
|
+
* * OpenSSL::ASN1::BMPString <=> +value+ is a +String+
|
1763
|
+
*
|
1764
|
+
* == OpenSSL::ASN1::BitString
|
1765
|
+
*
|
1766
|
+
* === Additional attributes
|
1767
|
+
* +unused_bits+: if the underlying BIT STRING's
|
1768
|
+
* length is a multiple of 8 then +unused_bits+ is 0. Otherwise
|
1769
|
+
* +unused_bits+ indicates the number of bits that are to be ignored in
|
1770
|
+
* the final octet of the +BitString+'s +value+.
|
1771
|
+
*
|
1772
|
+
* == OpenSSL::ASN1::ObjectId
|
1773
|
+
*
|
1774
|
+
* === Additional attributes
|
1775
|
+
* * +sn+: the short name as defined in <openssl/objects.h>.
|
1776
|
+
* * +ln+: the long name as defined in <openssl/objects.h>.
|
1777
|
+
* * +oid+: the object identifier as a +String+, e.g. "1.2.3.4.5"
|
1778
|
+
* * +short_name+: alias for +sn+.
|
1779
|
+
* * +long_name+: alias for +ln+.
|
1780
|
+
*
|
1781
|
+
* == Examples
|
1782
|
+
* With the Exception of OpenSSL::ASN1::EndOfContent, each Primitive class
|
1783
|
+
* constructor takes at least one parameter, the +value+.
|
1784
|
+
*
|
1785
|
+
* === Creating EndOfContent
|
1786
|
+
* eoc = OpenSSL::ASN1::EndOfContent.new
|
1787
|
+
*
|
1788
|
+
* === Creating any other Primitive
|
1789
|
+
* prim = <class>.new(value) # <class> being one of the sub-classes except EndOfContent
|
1790
|
+
* prim_zero_tagged_implicit = <class>.new(value, 0, :IMPLICIT)
|
1791
|
+
* prim_zero_tagged_explicit = <class>.new(value, 0, :EXPLICIT)
|
1792
|
+
*/
|
1111
1793
|
cASN1Primitive = rb_define_class_under(mASN1, "Primitive", cASN1Data);
|
1794
|
+
/*
|
1795
|
+
* May be used as a hint for encoding a value either implicitly or
|
1796
|
+
* explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+.
|
1797
|
+
* +tagging+ is not set when a ASN.1 structure is parsed using
|
1798
|
+
* OpenSSL::ASN1.decode.
|
1799
|
+
*/
|
1112
1800
|
rb_attr(cASN1Primitive, rb_intern("tagging"), 1, 1, Qtrue);
|
1801
|
+
rb_undef_method(cASN1Primitive, "infinite_length=");
|
1113
1802
|
rb_define_method(cASN1Primitive, "initialize", ossl_asn1_initialize, -1);
|
1114
1803
|
rb_define_method(cASN1Primitive, "to_der", ossl_asn1prim_to_der, 0);
|
1115
1804
|
|
1805
|
+
/* Document-class: OpenSSL::ASN1::Constructive
|
1806
|
+
*
|
1807
|
+
* The parent class for all constructed encodings. The +value+ attribute
|
1808
|
+
* of a Constructive is always an +Array+. Attributes are the same as
|
1809
|
+
* for ASN1Data, with the addition of +tagging+.
|
1810
|
+
*
|
1811
|
+
* == SET and SEQUENCE
|
1812
|
+
*
|
1813
|
+
* Most constructed encodings come in the form of a SET or a SEQUENCE.
|
1814
|
+
* These encodings are represented by one of the two sub-classes of
|
1815
|
+
* Constructive:
|
1816
|
+
* * OpenSSL::ASN1::Set
|
1817
|
+
* * OpenSSL::ASN1::Sequence
|
1818
|
+
* Please note that tagged sequences and sets are still parsed as
|
1819
|
+
* instances of ASN1Data. Find further details on tagged values
|
1820
|
+
* there.
|
1821
|
+
*
|
1822
|
+
* === Example - constructing a SEQUENCE
|
1823
|
+
* int = OpenSSL::ASN1::Integer.new(1)
|
1824
|
+
* str = OpenSSL::ASN1::PrintableString.new('abc')
|
1825
|
+
* sequence = OpenSSL::ASN1::Sequence.new( [ int, str ] )
|
1826
|
+
*
|
1827
|
+
* === Example - constructing a SET
|
1828
|
+
* int = OpenSSL::ASN1::Integer.new(1)
|
1829
|
+
* str = OpenSSL::ASN1::PrintableString.new('abc')
|
1830
|
+
* set = OpenSSL::ASN1::Set.new( [ int, str ] )
|
1831
|
+
*
|
1832
|
+
* == Infinite length primitive values
|
1833
|
+
*
|
1834
|
+
* The only case where Constructive is used directly is for infinite
|
1835
|
+
* length encodings of primitive values. These encodings are always
|
1836
|
+
* constructed, with the contents of the +value+ +Array+ being either
|
1837
|
+
* UNIVERSAL non-infinite length partial encodings of the actual value
|
1838
|
+
* or again constructive encodings with infinite length (i.e. infinite
|
1839
|
+
* length primitive encodings may be constructed recursively with another
|
1840
|
+
* infinite length value within an already infinite length value). Each
|
1841
|
+
* partial encoding must be of the same UNIVERSAL type as the overall
|
1842
|
+
* encoding. The value of the overall encoding consists of the
|
1843
|
+
* concatenation of each partial encoding taken in sequence. The +value+
|
1844
|
+
* array of the outer infinite length value must end with a
|
1845
|
+
* OpenSSL::ASN1::EndOfContent instance.
|
1846
|
+
*
|
1847
|
+
* Please note that it is not possible to encode Constructive without
|
1848
|
+
* the +infinite_length+ attribute being set to +true+, use
|
1849
|
+
* OpenSSL::ASN1::Sequence or OpenSSL::ASN1::Set in these cases instead.
|
1850
|
+
*
|
1851
|
+
* === Example - Infinite length OCTET STRING
|
1852
|
+
* partial1 = OpenSSL::ASN1::OctetString.new("\x01")
|
1853
|
+
* partial2 = OpenSSL::ASN1::OctetString.new("\x02")
|
1854
|
+
* inf_octets = OpenSSL::ASN1::Constructive.new( [ partial1,
|
1855
|
+
* partial2,
|
1856
|
+
* OpenSSL::ASN1::EndOfContent.new ],
|
1857
|
+
* OpenSSL::ASN1::OCTET_STRING,
|
1858
|
+
* nil,
|
1859
|
+
* :UNIVERSAL )
|
1860
|
+
* # The real value of inf_octets is "\x01\x02", i.e. the concatenation
|
1861
|
+
* # of partial1 and partial2
|
1862
|
+
* inf_octets.infinite_length = true
|
1863
|
+
* der = inf_octets.to_der
|
1864
|
+
* asn1 = OpenSSL::ASN1.decode(der)
|
1865
|
+
* puts asn1.infinite_length # => true
|
1866
|
+
*/
|
1116
1867
|
cASN1Constructive = rb_define_class_under(mASN1,"Constructive", cASN1Data);
|
1117
1868
|
rb_include_module(cASN1Constructive, rb_mEnumerable);
|
1869
|
+
/*
|
1870
|
+
* May be used as a hint for encoding a value either implicitly or
|
1871
|
+
* explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+.
|
1872
|
+
* +tagging+ is not set when a ASN.1 structure is parsed using
|
1873
|
+
* OpenSSL::ASN1.decode.
|
1874
|
+
*/
|
1118
1875
|
rb_attr(cASN1Constructive, rb_intern("tagging"), 1, 1, Qtrue);
|
1119
1876
|
rb_define_method(cASN1Constructive, "initialize", ossl_asn1_initialize, -1);
|
1120
1877
|
rb_define_method(cASN1Constructive, "to_der", ossl_asn1cons_to_der, 0);
|
@@ -1150,6 +1907,12 @@ do{\
|
|
1150
1907
|
OSSL_ASN1_DEFINE_CLASS(Sequence, Constructive);
|
1151
1908
|
OSSL_ASN1_DEFINE_CLASS(Set, Constructive);
|
1152
1909
|
|
1910
|
+
OSSL_ASN1_DEFINE_CLASS(EndOfContent, Data);
|
1911
|
+
|
1912
|
+
|
1913
|
+
#if 0
|
1914
|
+
cASN1ObjectId = rb_define_class_under(mASN1, "ObjectId", cASN1Primitive); /* let rdoc know */
|
1915
|
+
#endif
|
1153
1916
|
rb_define_singleton_method(cASN1ObjectId, "register", ossl_asn1obj_s_register, 3);
|
1154
1917
|
rb_define_method(cASN1ObjectId, "sn", ossl_asn1obj_get_sn, 0);
|
1155
1918
|
rb_define_method(cASN1ObjectId, "ln", ossl_asn1obj_get_ln, 0);
|
@@ -1157,4 +1920,32 @@ do{\
|
|
1157
1920
|
rb_define_alias(cASN1ObjectId, "short_name", "sn");
|
1158
1921
|
rb_define_alias(cASN1ObjectId, "long_name", "ln");
|
1159
1922
|
rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);
|
1923
|
+
|
1924
|
+
rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0);
|
1925
|
+
|
1926
|
+
class_tag_map = rb_hash_new();
|
1927
|
+
rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC));
|
1928
|
+
rb_hash_aset(class_tag_map, cASN1Boolean, INT2NUM(V_ASN1_BOOLEAN));
|
1929
|
+
rb_hash_aset(class_tag_map, cASN1Integer, INT2NUM(V_ASN1_INTEGER));
|
1930
|
+
rb_hash_aset(class_tag_map, cASN1BitString, INT2NUM(V_ASN1_BIT_STRING));
|
1931
|
+
rb_hash_aset(class_tag_map, cASN1OctetString, INT2NUM(V_ASN1_OCTET_STRING));
|
1932
|
+
rb_hash_aset(class_tag_map, cASN1Null, INT2NUM(V_ASN1_NULL));
|
1933
|
+
rb_hash_aset(class_tag_map, cASN1ObjectId, INT2NUM(V_ASN1_OBJECT));
|
1934
|
+
rb_hash_aset(class_tag_map, cASN1Enumerated, INT2NUM(V_ASN1_ENUMERATED));
|
1935
|
+
rb_hash_aset(class_tag_map, cASN1UTF8String, INT2NUM(V_ASN1_UTF8STRING));
|
1936
|
+
rb_hash_aset(class_tag_map, cASN1Sequence, INT2NUM(V_ASN1_SEQUENCE));
|
1937
|
+
rb_hash_aset(class_tag_map, cASN1Set, INT2NUM(V_ASN1_SET));
|
1938
|
+
rb_hash_aset(class_tag_map, cASN1NumericString, INT2NUM(V_ASN1_NUMERICSTRING));
|
1939
|
+
rb_hash_aset(class_tag_map, cASN1PrintableString, INT2NUM(V_ASN1_PRINTABLESTRING));
|
1940
|
+
rb_hash_aset(class_tag_map, cASN1T61String, INT2NUM(V_ASN1_T61STRING));
|
1941
|
+
rb_hash_aset(class_tag_map, cASN1VideotexString, INT2NUM(V_ASN1_VIDEOTEXSTRING));
|
1942
|
+
rb_hash_aset(class_tag_map, cASN1IA5String, INT2NUM(V_ASN1_IA5STRING));
|
1943
|
+
rb_hash_aset(class_tag_map, cASN1UTCTime, INT2NUM(V_ASN1_UTCTIME));
|
1944
|
+
rb_hash_aset(class_tag_map, cASN1GeneralizedTime, INT2NUM(V_ASN1_GENERALIZEDTIME));
|
1945
|
+
rb_hash_aset(class_tag_map, cASN1GraphicString, INT2NUM(V_ASN1_GRAPHICSTRING));
|
1946
|
+
rb_hash_aset(class_tag_map, cASN1ISO64String, INT2NUM(V_ASN1_ISO64STRING));
|
1947
|
+
rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING));
|
1948
|
+
rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING));
|
1949
|
+
rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING));
|
1950
|
+
rb_global_variable(&class_tag_map);
|
1160
1951
|
}
|