openssl 2.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of openssl might be problematic. Click here for more details.

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