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,119 @@
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_X509_H_)
11
+ #define _OSSL_X509_H_
12
+
13
+ /*
14
+ * X509 main module
15
+ */
16
+ extern VALUE mX509;
17
+
18
+ /*
19
+ * Converts the VALUE into Integer and set it to the ASN1_TIME. This is a
20
+ * wrapper for X509_time_adj_ex() so passing NULL creates a new ASN1_TIME.
21
+ * Note that the caller must check the NULL return.
22
+ */
23
+ ASN1_TIME *ossl_x509_time_adjust(ASN1_TIME *, VALUE);
24
+
25
+ void Init_ossl_x509(void);
26
+
27
+ /*
28
+ * X509Attr
29
+ */
30
+ extern VALUE cX509Attr;
31
+ extern VALUE eX509AttrError;
32
+
33
+ VALUE ossl_x509attr_new(X509_ATTRIBUTE *);
34
+ X509_ATTRIBUTE *GetX509AttrPtr(VALUE);
35
+ void Init_ossl_x509attr(void);
36
+
37
+ /*
38
+ * X509Cert
39
+ */
40
+ extern VALUE cX509Cert;
41
+ extern VALUE eX509CertError;
42
+
43
+ VALUE ossl_x509_new(X509 *);
44
+ VALUE ossl_x509_new_from_file(VALUE);
45
+ X509 *GetX509CertPtr(VALUE);
46
+ X509 *DupX509CertPtr(VALUE);
47
+ void Init_ossl_x509cert(void);
48
+
49
+ /*
50
+ * X509CRL
51
+ */
52
+ extern VALUE cX509CRL;
53
+ extern VALUE eX509CRLError;
54
+
55
+ VALUE ossl_x509crl_new(X509_CRL *);
56
+ X509_CRL *GetX509CRLPtr(VALUE);
57
+ X509_CRL *DupX509CRLPtr(VALUE);
58
+ void Init_ossl_x509crl(void);
59
+
60
+ /*
61
+ * X509Extension
62
+ */
63
+ extern VALUE cX509Ext;
64
+ extern VALUE cX509ExtFactory;
65
+ extern VALUE eX509ExtError;
66
+
67
+ VALUE ossl_x509ext_new(X509_EXTENSION *);
68
+ X509_EXTENSION *GetX509ExtPtr(VALUE);
69
+ void Init_ossl_x509ext(void);
70
+
71
+ /*
72
+ * X509Name
73
+ */
74
+ extern VALUE cX509Name;
75
+ extern VALUE eX509NameError;
76
+
77
+ VALUE ossl_x509name_new(X509_NAME *);
78
+ X509_NAME *GetX509NamePtr(VALUE);
79
+ void Init_ossl_x509name(void);
80
+
81
+ /*
82
+ * X509Request
83
+ */
84
+ extern VALUE cX509Req;
85
+ extern VALUE eX509ReqError;
86
+
87
+ VALUE ossl_x509req_new(X509_REQ *);
88
+ X509_REQ *GetX509ReqPtr(VALUE);
89
+ X509_REQ *DupX509ReqPtr(VALUE);
90
+ void Init_ossl_x509req(void);
91
+
92
+ /*
93
+ * X509Revoked
94
+ */
95
+ extern VALUE cX509Rev;
96
+ extern VALUE eX509RevError;
97
+
98
+ VALUE ossl_x509revoked_new(X509_REVOKED *);
99
+ X509_REVOKED *DupX509RevokedPtr(VALUE);
100
+ void Init_ossl_x509revoked(void);
101
+
102
+ /*
103
+ * X509Store and X509StoreContext
104
+ */
105
+ extern VALUE cX509Store;
106
+ extern VALUE cX509StoreContext;
107
+ extern VALUE eX509StoreError;
108
+
109
+ VALUE ossl_x509store_new(X509_STORE *);
110
+ X509_STORE *GetX509StorePtr(VALUE);
111
+ X509_STORE *DupX509StorePtr(VALUE);
112
+
113
+ VALUE ossl_x509stctx_new(X509_STORE_CTX *);
114
+ VALUE ossl_x509stctx_clear_ptr(VALUE);
115
+ X509_STORE_CTX *GetX509StCtxtPtr(VALUE);
116
+
117
+ void Init_ossl_x509store(void);
118
+
119
+ #endif /* _OSSL_X509_H_ */
@@ -0,0 +1,328 @@
1
+ /*
2
+ * 'OpenSSL for Ruby' project
3
+ * Copyright (C) 2001 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
+ #include "ossl.h"
11
+
12
+ #define NewX509Attr(klass) \
13
+ TypedData_Wrap_Struct((klass), &ossl_x509attr_type, 0)
14
+ #define SetX509Attr(obj, attr) do { \
15
+ if (!(attr)) { \
16
+ ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \
17
+ } \
18
+ RTYPEDDATA_DATA(obj) = (attr); \
19
+ } while (0)
20
+ #define GetX509Attr(obj, attr) do { \
21
+ TypedData_Get_Struct((obj), X509_ATTRIBUTE, &ossl_x509attr_type, (attr)); \
22
+ if (!(attr)) { \
23
+ ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \
24
+ } \
25
+ } while (0)
26
+ #define SafeGetX509Attr(obj, attr) do { \
27
+ OSSL_Check_Kind((obj), cX509Attr); \
28
+ GetX509Attr((obj), (attr)); \
29
+ } while (0)
30
+
31
+ /*
32
+ * Classes
33
+ */
34
+ VALUE cX509Attr;
35
+ VALUE eX509AttrError;
36
+
37
+ static void
38
+ ossl_x509attr_free(void *ptr)
39
+ {
40
+ X509_ATTRIBUTE_free(ptr);
41
+ }
42
+
43
+ static const rb_data_type_t ossl_x509attr_type = {
44
+ "OpenSSL/X509/ATTRIBUTE",
45
+ {
46
+ 0, ossl_x509attr_free,
47
+ },
48
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
49
+ };
50
+
51
+ /*
52
+ * Public
53
+ */
54
+ VALUE
55
+ ossl_x509attr_new(X509_ATTRIBUTE *attr)
56
+ {
57
+ X509_ATTRIBUTE *new;
58
+ VALUE obj;
59
+
60
+ obj = NewX509Attr(cX509Attr);
61
+ if (!attr) {
62
+ new = X509_ATTRIBUTE_new();
63
+ } else {
64
+ new = X509_ATTRIBUTE_dup(attr);
65
+ }
66
+ if (!new) {
67
+ ossl_raise(eX509AttrError, NULL);
68
+ }
69
+ SetX509Attr(obj, new);
70
+
71
+ return obj;
72
+ }
73
+
74
+ X509_ATTRIBUTE *
75
+ GetX509AttrPtr(VALUE obj)
76
+ {
77
+ X509_ATTRIBUTE *attr;
78
+
79
+ SafeGetX509Attr(obj, attr);
80
+
81
+ return attr;
82
+ }
83
+
84
+ /*
85
+ * Private
86
+ */
87
+ static VALUE
88
+ ossl_x509attr_alloc(VALUE klass)
89
+ {
90
+ X509_ATTRIBUTE *attr;
91
+ VALUE obj;
92
+
93
+ obj = NewX509Attr(klass);
94
+ if (!(attr = X509_ATTRIBUTE_new()))
95
+ ossl_raise(eX509AttrError, NULL);
96
+ SetX509Attr(obj, attr);
97
+
98
+ return obj;
99
+ }
100
+
101
+ /*
102
+ * call-seq:
103
+ * Attribute.new(oid [, value]) => attr
104
+ */
105
+ static VALUE
106
+ ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self)
107
+ {
108
+ VALUE oid, value;
109
+ X509_ATTRIBUTE *attr, *x;
110
+ const unsigned char *p;
111
+
112
+ GetX509Attr(self, attr);
113
+ if(rb_scan_args(argc, argv, "11", &oid, &value) == 1){
114
+ oid = ossl_to_der_if_possible(oid);
115
+ StringValue(oid);
116
+ p = (unsigned char *)RSTRING_PTR(oid);
117
+ x = d2i_X509_ATTRIBUTE(&attr, &p, RSTRING_LEN(oid));
118
+ DATA_PTR(self) = attr;
119
+ if(!x){
120
+ ossl_raise(eX509AttrError, NULL);
121
+ }
122
+ return self;
123
+ }
124
+ rb_funcall(self, rb_intern("oid="), 1, oid);
125
+ rb_funcall(self, rb_intern("value="), 1, value);
126
+
127
+ return self;
128
+ }
129
+
130
+ static VALUE
131
+ ossl_x509attr_initialize_copy(VALUE self, VALUE other)
132
+ {
133
+ X509_ATTRIBUTE *attr, *attr_other, *attr_new;
134
+
135
+ rb_check_frozen(self);
136
+ GetX509Attr(self, attr);
137
+ SafeGetX509Attr(other, attr_other);
138
+
139
+ attr_new = X509_ATTRIBUTE_dup(attr_other);
140
+ if (!attr_new)
141
+ ossl_raise(eX509AttrError, "X509_ATTRIBUTE_dup");
142
+
143
+ SetX509Attr(self, attr_new);
144
+ X509_ATTRIBUTE_free(attr);
145
+
146
+ return self;
147
+ }
148
+
149
+ /*
150
+ * call-seq:
151
+ * attr.oid = string => string
152
+ */
153
+ static VALUE
154
+ ossl_x509attr_set_oid(VALUE self, VALUE oid)
155
+ {
156
+ X509_ATTRIBUTE *attr;
157
+ ASN1_OBJECT *obj;
158
+ char *s;
159
+
160
+ GetX509Attr(self, attr);
161
+ s = StringValueCStr(oid);
162
+ obj = OBJ_txt2obj(s, 0);
163
+ if(!obj) ossl_raise(eX509AttrError, NULL);
164
+ if (!X509_ATTRIBUTE_set1_object(attr, obj)) {
165
+ ASN1_OBJECT_free(obj);
166
+ ossl_raise(eX509AttrError, "X509_ATTRIBUTE_set1_object");
167
+ }
168
+ ASN1_OBJECT_free(obj);
169
+
170
+ return oid;
171
+ }
172
+
173
+ /*
174
+ * call-seq:
175
+ * attr.oid => string
176
+ */
177
+ static VALUE
178
+ ossl_x509attr_get_oid(VALUE self)
179
+ {
180
+ X509_ATTRIBUTE *attr;
181
+ ASN1_OBJECT *oid;
182
+ BIO *out;
183
+ VALUE ret;
184
+ int nid;
185
+
186
+ GetX509Attr(self, attr);
187
+ oid = X509_ATTRIBUTE_get0_object(attr);
188
+ if ((nid = OBJ_obj2nid(oid)) != NID_undef)
189
+ ret = rb_str_new2(OBJ_nid2sn(nid));
190
+ else{
191
+ if (!(out = BIO_new(BIO_s_mem())))
192
+ ossl_raise(eX509AttrError, NULL);
193
+ i2a_ASN1_OBJECT(out, oid);
194
+ ret = ossl_membio2str(out);
195
+ }
196
+
197
+ return ret;
198
+ }
199
+
200
+ /*
201
+ * call-seq:
202
+ * attr.value = asn1 => asn1
203
+ */
204
+ static VALUE
205
+ ossl_x509attr_set_value(VALUE self, VALUE value)
206
+ {
207
+ X509_ATTRIBUTE *attr;
208
+ VALUE asn1_value;
209
+ int i, asn1_tag;
210
+
211
+ OSSL_Check_Kind(value, cASN1Data);
212
+ asn1_tag = NUM2INT(rb_attr_get(value, rb_intern("@tag")));
213
+ asn1_value = rb_attr_get(value, rb_intern("@value"));
214
+ if (asn1_tag != V_ASN1_SET)
215
+ ossl_raise(eASN1Error, "argument must be ASN1::Set");
216
+ if (!RB_TYPE_P(asn1_value, T_ARRAY))
217
+ ossl_raise(eASN1Error, "ASN1::Set has non-array value");
218
+
219
+ GetX509Attr(self, attr);
220
+ if (X509_ATTRIBUTE_count(attr)) { /* populated, reset first */
221
+ ASN1_OBJECT *obj = X509_ATTRIBUTE_get0_object(attr);
222
+ X509_ATTRIBUTE *new_attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, 0, NULL, -1);
223
+ if (!new_attr)
224
+ ossl_raise(eX509AttrError, NULL);
225
+ SetX509Attr(self, new_attr);
226
+ X509_ATTRIBUTE_free(attr);
227
+ attr = new_attr;
228
+ }
229
+
230
+ for (i = 0; i < RARRAY_LEN(asn1_value); i++) {
231
+ ASN1_TYPE *a1type = ossl_asn1_get_asn1type(RARRAY_AREF(asn1_value, i));
232
+ if (!X509_ATTRIBUTE_set1_data(attr, ASN1_TYPE_get(a1type),
233
+ a1type->value.ptr, -1)) {
234
+ ASN1_TYPE_free(a1type);
235
+ ossl_raise(eX509AttrError, NULL);
236
+ }
237
+ ASN1_TYPE_free(a1type);
238
+ }
239
+
240
+ return value;
241
+ }
242
+
243
+ /*
244
+ * call-seq:
245
+ * attr.value => asn1
246
+ */
247
+ static VALUE
248
+ ossl_x509attr_get_value(VALUE self)
249
+ {
250
+ X509_ATTRIBUTE *attr;
251
+ STACK_OF(ASN1_TYPE) *sk;
252
+ VALUE str;
253
+ int i, count, len;
254
+ unsigned char *p;
255
+
256
+ GetX509Attr(self, attr);
257
+ /* there is no X509_ATTRIBUTE_get0_set() :( */
258
+ if (!(sk = sk_ASN1_TYPE_new_null()))
259
+ ossl_raise(eX509AttrError, "sk_new");
260
+
261
+ count = X509_ATTRIBUTE_count(attr);
262
+ for (i = 0; i < count; i++)
263
+ sk_ASN1_TYPE_push(sk, X509_ATTRIBUTE_get0_type(attr, i));
264
+
265
+ if ((len = i2d_ASN1_SET_ANY(sk, NULL)) <= 0) {
266
+ sk_ASN1_TYPE_free(sk);
267
+ ossl_raise(eX509AttrError, NULL);
268
+ }
269
+ str = rb_str_new(0, len);
270
+ p = (unsigned char *)RSTRING_PTR(str);
271
+ if (i2d_ASN1_SET_ANY(sk, &p) <= 0) {
272
+ sk_ASN1_TYPE_free(sk);
273
+ ossl_raise(eX509AttrError, NULL);
274
+ }
275
+ ossl_str_adjust(str, p);
276
+ sk_ASN1_TYPE_free(sk);
277
+
278
+ return rb_funcall(mASN1, rb_intern("decode"), 1, str);
279
+ }
280
+
281
+ /*
282
+ * call-seq:
283
+ * attr.to_der => string
284
+ */
285
+ static VALUE
286
+ ossl_x509attr_to_der(VALUE self)
287
+ {
288
+ X509_ATTRIBUTE *attr;
289
+ VALUE str;
290
+ int len;
291
+ unsigned char *p;
292
+
293
+ GetX509Attr(self, attr);
294
+ if((len = i2d_X509_ATTRIBUTE(attr, NULL)) <= 0)
295
+ ossl_raise(eX509AttrError, NULL);
296
+ str = rb_str_new(0, len);
297
+ p = (unsigned char *)RSTRING_PTR(str);
298
+ if(i2d_X509_ATTRIBUTE(attr, &p) <= 0)
299
+ ossl_raise(eX509AttrError, NULL);
300
+ ossl_str_adjust(str, p);
301
+
302
+ return str;
303
+ }
304
+
305
+ /*
306
+ * X509_ATTRIBUTE init
307
+ */
308
+ void
309
+ Init_ossl_x509attr(void)
310
+ {
311
+ #if 0
312
+ mOSSL = rb_define_module("OpenSSL");
313
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
314
+ mX509 = rb_define_module_under(mOSSL, "X509");
315
+ #endif
316
+
317
+ eX509AttrError = rb_define_class_under(mX509, "AttributeError", eOSSLError);
318
+
319
+ cX509Attr = rb_define_class_under(mX509, "Attribute", rb_cObject);
320
+ rb_define_alloc_func(cX509Attr, ossl_x509attr_alloc);
321
+ rb_define_method(cX509Attr, "initialize", ossl_x509attr_initialize, -1);
322
+ rb_define_copy_func(cX509Attr, ossl_x509attr_initialize_copy);
323
+ rb_define_method(cX509Attr, "oid=", ossl_x509attr_set_oid, 1);
324
+ rb_define_method(cX509Attr, "oid", ossl_x509attr_get_oid, 0);
325
+ rb_define_method(cX509Attr, "value=", ossl_x509attr_set_value, 1);
326
+ rb_define_method(cX509Attr, "value", ossl_x509attr_get_value, 0);
327
+ rb_define_method(cX509Attr, "to_der", ossl_x509attr_to_der, 0);
328
+ }
@@ -0,0 +1,860 @@
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
+ #include "ossl.h"
11
+
12
+ #define NewX509(klass) \
13
+ TypedData_Wrap_Struct((klass), &ossl_x509_type, 0)
14
+ #define SetX509(obj, x509) do { \
15
+ if (!(x509)) { \
16
+ ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \
17
+ } \
18
+ RTYPEDDATA_DATA(obj) = (x509); \
19
+ } while (0)
20
+ #define GetX509(obj, x509) do { \
21
+ TypedData_Get_Struct((obj), X509, &ossl_x509_type, (x509)); \
22
+ if (!(x509)) { \
23
+ ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \
24
+ } \
25
+ } while (0)
26
+ #define SafeGetX509(obj, x509) do { \
27
+ OSSL_Check_Kind((obj), cX509Cert); \
28
+ GetX509((obj), (x509)); \
29
+ } while (0)
30
+
31
+ /*
32
+ * Classes
33
+ */
34
+ VALUE cX509Cert;
35
+ VALUE eX509CertError;
36
+
37
+ static void
38
+ ossl_x509_free(void *ptr)
39
+ {
40
+ X509_free(ptr);
41
+ }
42
+
43
+ static const rb_data_type_t ossl_x509_type = {
44
+ "OpenSSL/X509",
45
+ {
46
+ 0, ossl_x509_free,
47
+ },
48
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
49
+ };
50
+
51
+ /*
52
+ * Public
53
+ */
54
+ VALUE
55
+ ossl_x509_new(X509 *x509)
56
+ {
57
+ X509 *new;
58
+ VALUE obj;
59
+
60
+ obj = NewX509(cX509Cert);
61
+ if (!x509) {
62
+ new = X509_new();
63
+ } else {
64
+ new = X509_dup(x509);
65
+ }
66
+ if (!new) {
67
+ ossl_raise(eX509CertError, NULL);
68
+ }
69
+ SetX509(obj, new);
70
+
71
+ return obj;
72
+ }
73
+
74
+ VALUE
75
+ ossl_x509_new_from_file(VALUE filename)
76
+ {
77
+ X509 *x509;
78
+ FILE *fp;
79
+ VALUE obj;
80
+
81
+ rb_check_safe_obj(filename);
82
+ obj = NewX509(cX509Cert);
83
+ if (!(fp = fopen(StringValueCStr(filename), "r"))) {
84
+ ossl_raise(eX509CertError, "%s", strerror(errno));
85
+ }
86
+ rb_fd_fix_cloexec(fileno(fp));
87
+ x509 = PEM_read_X509(fp, NULL, NULL, NULL);
88
+ /*
89
+ * prepare for DER...
90
+ #if !defined(OPENSSL_NO_FP_API)
91
+ if (!x509) {
92
+ (void)ERR_get_error();
93
+ rewind(fp);
94
+
95
+ x509 = d2i_X509_fp(fp, NULL);
96
+ }
97
+ #endif
98
+ */
99
+ fclose(fp);
100
+ if (!x509) {
101
+ ossl_raise(eX509CertError, NULL);
102
+ }
103
+ SetX509(obj, x509);
104
+
105
+ return obj;
106
+ }
107
+
108
+ X509 *
109
+ GetX509CertPtr(VALUE obj)
110
+ {
111
+ X509 *x509;
112
+
113
+ SafeGetX509(obj, x509);
114
+
115
+ return x509;
116
+ }
117
+
118
+ X509 *
119
+ DupX509CertPtr(VALUE obj)
120
+ {
121
+ X509 *x509;
122
+
123
+ SafeGetX509(obj, x509);
124
+
125
+ X509_up_ref(x509);
126
+
127
+ return x509;
128
+ }
129
+
130
+ /*
131
+ * Private
132
+ */
133
+ static VALUE
134
+ ossl_x509_alloc(VALUE klass)
135
+ {
136
+ X509 *x509;
137
+ VALUE obj;
138
+
139
+ obj = NewX509(klass);
140
+ x509 = X509_new();
141
+ if (!x509) ossl_raise(eX509CertError, NULL);
142
+ SetX509(obj, x509);
143
+
144
+ return obj;
145
+ }
146
+
147
+ /*
148
+ * call-seq:
149
+ * Certificate.new => cert
150
+ * Certificate.new(string) => cert
151
+ */
152
+ static VALUE
153
+ ossl_x509_initialize(int argc, VALUE *argv, VALUE self)
154
+ {
155
+ BIO *in;
156
+ X509 *x509, *x = DATA_PTR(self);
157
+ VALUE arg;
158
+
159
+ if (rb_scan_args(argc, argv, "01", &arg) == 0) {
160
+ /* create just empty X509Cert */
161
+ return self;
162
+ }
163
+ arg = ossl_to_der_if_possible(arg);
164
+ in = ossl_obj2bio(arg);
165
+ x509 = PEM_read_bio_X509(in, &x, NULL, NULL);
166
+ DATA_PTR(self) = x;
167
+ if (!x509) {
168
+ OSSL_BIO_reset(in);
169
+ x509 = d2i_X509_bio(in, &x);
170
+ DATA_PTR(self) = x;
171
+ }
172
+ BIO_free(in);
173
+ if (!x509) ossl_raise(eX509CertError, NULL);
174
+
175
+ return self;
176
+ }
177
+
178
+ static VALUE
179
+ ossl_x509_copy(VALUE self, VALUE other)
180
+ {
181
+ X509 *a, *b, *x509;
182
+
183
+ rb_check_frozen(self);
184
+ if (self == other) return self;
185
+
186
+ GetX509(self, a);
187
+ SafeGetX509(other, b);
188
+
189
+ x509 = X509_dup(b);
190
+ if (!x509) ossl_raise(eX509CertError, NULL);
191
+
192
+ DATA_PTR(self) = x509;
193
+ X509_free(a);
194
+
195
+ return self;
196
+ }
197
+
198
+ /*
199
+ * call-seq:
200
+ * cert.to_der => string
201
+ */
202
+ static VALUE
203
+ ossl_x509_to_der(VALUE self)
204
+ {
205
+ X509 *x509;
206
+ VALUE str;
207
+ long len;
208
+ unsigned char *p;
209
+
210
+ GetX509(self, x509);
211
+ if ((len = i2d_X509(x509, NULL)) <= 0)
212
+ ossl_raise(eX509CertError, NULL);
213
+ str = rb_str_new(0, len);
214
+ p = (unsigned char *)RSTRING_PTR(str);
215
+ if (i2d_X509(x509, &p) <= 0)
216
+ ossl_raise(eX509CertError, NULL);
217
+ ossl_str_adjust(str, p);
218
+
219
+ return str;
220
+ }
221
+
222
+ /*
223
+ * call-seq:
224
+ * cert.to_pem => string
225
+ */
226
+ static VALUE
227
+ ossl_x509_to_pem(VALUE self)
228
+ {
229
+ X509 *x509;
230
+ BIO *out;
231
+ VALUE str;
232
+
233
+ GetX509(self, x509);
234
+ out = BIO_new(BIO_s_mem());
235
+ if (!out) ossl_raise(eX509CertError, NULL);
236
+
237
+ if (!PEM_write_bio_X509(out, x509)) {
238
+ BIO_free(out);
239
+ ossl_raise(eX509CertError, NULL);
240
+ }
241
+ str = ossl_membio2str(out);
242
+
243
+ return str;
244
+ }
245
+
246
+ /*
247
+ * call-seq:
248
+ * cert.to_text => string
249
+ */
250
+ static VALUE
251
+ ossl_x509_to_text(VALUE self)
252
+ {
253
+ X509 *x509;
254
+ BIO *out;
255
+ VALUE str;
256
+
257
+ GetX509(self, x509);
258
+
259
+ out = BIO_new(BIO_s_mem());
260
+ if (!out) ossl_raise(eX509CertError, NULL);
261
+
262
+ if (!X509_print(out, x509)) {
263
+ BIO_free(out);
264
+ ossl_raise(eX509CertError, NULL);
265
+ }
266
+ str = ossl_membio2str(out);
267
+
268
+ return str;
269
+ }
270
+
271
+ #if 0
272
+ /*
273
+ * Makes from X509 X509_REQuest
274
+ */
275
+ static VALUE
276
+ ossl_x509_to_req(VALUE self)
277
+ {
278
+ X509 *x509;
279
+ X509_REQ *req;
280
+ VALUE obj;
281
+
282
+ GetX509(self, x509);
283
+ if (!(req = X509_to_X509_REQ(x509, NULL, EVP_md5()))) {
284
+ ossl_raise(eX509CertError, NULL);
285
+ }
286
+ obj = ossl_x509req_new(req);
287
+ X509_REQ_free(req);
288
+
289
+ return obj;
290
+ }
291
+ #endif
292
+
293
+ /*
294
+ * call-seq:
295
+ * cert.version => integer
296
+ */
297
+ static VALUE
298
+ ossl_x509_get_version(VALUE self)
299
+ {
300
+ X509 *x509;
301
+
302
+ GetX509(self, x509);
303
+
304
+ return LONG2NUM(X509_get_version(x509));
305
+ }
306
+
307
+ /*
308
+ * call-seq:
309
+ * cert.version = integer => integer
310
+ */
311
+ static VALUE
312
+ ossl_x509_set_version(VALUE self, VALUE version)
313
+ {
314
+ X509 *x509;
315
+ long ver;
316
+
317
+ if ((ver = NUM2LONG(version)) < 0) {
318
+ ossl_raise(eX509CertError, "version must be >= 0!");
319
+ }
320
+ GetX509(self, x509);
321
+ if (!X509_set_version(x509, ver)) {
322
+ ossl_raise(eX509CertError, NULL);
323
+ }
324
+
325
+ return version;
326
+ }
327
+
328
+ /*
329
+ * call-seq:
330
+ * cert.serial => integer
331
+ */
332
+ static VALUE
333
+ ossl_x509_get_serial(VALUE self)
334
+ {
335
+ X509 *x509;
336
+
337
+ GetX509(self, x509);
338
+
339
+ return asn1integer_to_num(X509_get_serialNumber(x509));
340
+ }
341
+
342
+ /*
343
+ * call-seq:
344
+ * cert.serial = integer => integer
345
+ */
346
+ static VALUE
347
+ ossl_x509_set_serial(VALUE self, VALUE num)
348
+ {
349
+ X509 *x509;
350
+
351
+ GetX509(self, x509);
352
+ X509_set_serialNumber(x509, num_to_asn1integer(num, X509_get_serialNumber(x509)));
353
+
354
+ return num;
355
+ }
356
+
357
+ /*
358
+ * call-seq:
359
+ * cert.signature_algorithm => string
360
+ */
361
+ static VALUE
362
+ ossl_x509_get_signature_algorithm(VALUE self)
363
+ {
364
+ X509 *x509;
365
+ BIO *out;
366
+ VALUE str;
367
+
368
+ GetX509(self, x509);
369
+ out = BIO_new(BIO_s_mem());
370
+ if (!out) ossl_raise(eX509CertError, NULL);
371
+
372
+ if (!i2a_ASN1_OBJECT(out, X509_get0_tbs_sigalg(x509)->algorithm)) {
373
+ BIO_free(out);
374
+ ossl_raise(eX509CertError, NULL);
375
+ }
376
+ str = ossl_membio2str(out);
377
+
378
+ return str;
379
+ }
380
+
381
+ /*
382
+ * call-seq:
383
+ * cert.subject => name
384
+ */
385
+ static VALUE
386
+ ossl_x509_get_subject(VALUE self)
387
+ {
388
+ X509 *x509;
389
+ X509_NAME *name;
390
+
391
+ GetX509(self, x509);
392
+ if (!(name = X509_get_subject_name(x509))) { /* NO DUP - don't free! */
393
+ ossl_raise(eX509CertError, NULL);
394
+ }
395
+
396
+ return ossl_x509name_new(name);
397
+ }
398
+
399
+ /*
400
+ * call-seq:
401
+ * cert.subject = name => name
402
+ */
403
+ static VALUE
404
+ ossl_x509_set_subject(VALUE self, VALUE subject)
405
+ {
406
+ X509 *x509;
407
+
408
+ GetX509(self, x509);
409
+ if (!X509_set_subject_name(x509, GetX509NamePtr(subject))) { /* DUPs name */
410
+ ossl_raise(eX509CertError, NULL);
411
+ }
412
+
413
+ return subject;
414
+ }
415
+
416
+ /*
417
+ * call-seq:
418
+ * cert.issuer => name
419
+ */
420
+ static VALUE
421
+ ossl_x509_get_issuer(VALUE self)
422
+ {
423
+ X509 *x509;
424
+ X509_NAME *name;
425
+
426
+ GetX509(self, x509);
427
+ if(!(name = X509_get_issuer_name(x509))) { /* NO DUP - don't free! */
428
+ ossl_raise(eX509CertError, NULL);
429
+ }
430
+
431
+ return ossl_x509name_new(name);
432
+ }
433
+
434
+ /*
435
+ * call-seq:
436
+ * cert.issuer = name => name
437
+ */
438
+ static VALUE
439
+ ossl_x509_set_issuer(VALUE self, VALUE issuer)
440
+ {
441
+ X509 *x509;
442
+
443
+ GetX509(self, x509);
444
+ if (!X509_set_issuer_name(x509, GetX509NamePtr(issuer))) { /* DUPs name */
445
+ ossl_raise(eX509CertError, NULL);
446
+ }
447
+
448
+ return issuer;
449
+ }
450
+
451
+ /*
452
+ * call-seq:
453
+ * cert.not_before => time
454
+ */
455
+ static VALUE
456
+ ossl_x509_get_not_before(VALUE self)
457
+ {
458
+ X509 *x509;
459
+ const ASN1_TIME *asn1time;
460
+
461
+ GetX509(self, x509);
462
+ if (!(asn1time = X509_get0_notBefore(x509))) {
463
+ ossl_raise(eX509CertError, NULL);
464
+ }
465
+
466
+ return asn1time_to_time(asn1time);
467
+ }
468
+
469
+ /*
470
+ * call-seq:
471
+ * cert.not_before = time => time
472
+ */
473
+ static VALUE
474
+ ossl_x509_set_not_before(VALUE self, VALUE time)
475
+ {
476
+ X509 *x509;
477
+ ASN1_TIME *asn1time;
478
+
479
+ GetX509(self, x509);
480
+ asn1time = ossl_x509_time_adjust(NULL, time);
481
+ if (!X509_set_notBefore(x509, asn1time)) {
482
+ ASN1_TIME_free(asn1time);
483
+ ossl_raise(eX509CertError, "X509_set_notBefore");
484
+ }
485
+ ASN1_TIME_free(asn1time);
486
+
487
+ return time;
488
+ }
489
+
490
+ /*
491
+ * call-seq:
492
+ * cert.not_after => time
493
+ */
494
+ static VALUE
495
+ ossl_x509_get_not_after(VALUE self)
496
+ {
497
+ X509 *x509;
498
+ const ASN1_TIME *asn1time;
499
+
500
+ GetX509(self, x509);
501
+ if (!(asn1time = X509_get0_notAfter(x509))) {
502
+ ossl_raise(eX509CertError, NULL);
503
+ }
504
+
505
+ return asn1time_to_time(asn1time);
506
+ }
507
+
508
+ /*
509
+ * call-seq:
510
+ * cert.not_after = time => time
511
+ */
512
+ static VALUE
513
+ ossl_x509_set_not_after(VALUE self, VALUE time)
514
+ {
515
+ X509 *x509;
516
+ ASN1_TIME *asn1time;
517
+
518
+ GetX509(self, x509);
519
+ asn1time = ossl_x509_time_adjust(NULL, time);
520
+ if (!X509_set_notAfter(x509, asn1time)) {
521
+ ASN1_TIME_free(asn1time);
522
+ ossl_raise(eX509CertError, "X509_set_notAfter");
523
+ }
524
+ ASN1_TIME_free(asn1time);
525
+
526
+ return time;
527
+ }
528
+
529
+ /*
530
+ * call-seq:
531
+ * cert.public_key => key
532
+ */
533
+ static VALUE
534
+ ossl_x509_get_public_key(VALUE self)
535
+ {
536
+ X509 *x509;
537
+ EVP_PKEY *pkey;
538
+
539
+ GetX509(self, x509);
540
+ if (!(pkey = X509_get_pubkey(x509))) { /* adds an reference */
541
+ ossl_raise(eX509CertError, NULL);
542
+ }
543
+
544
+ return ossl_pkey_new(pkey); /* NO DUP - OK */
545
+ }
546
+
547
+ /*
548
+ * call-seq:
549
+ * cert.public_key = key => key
550
+ */
551
+ static VALUE
552
+ ossl_x509_set_public_key(VALUE self, VALUE key)
553
+ {
554
+ X509 *x509;
555
+
556
+ GetX509(self, x509);
557
+ if (!X509_set_pubkey(x509, GetPKeyPtr(key))) { /* DUPs pkey */
558
+ ossl_raise(eX509CertError, NULL);
559
+ }
560
+
561
+ return key;
562
+ }
563
+
564
+ /*
565
+ * call-seq:
566
+ * cert.sign(key, digest) => self
567
+ */
568
+ static VALUE
569
+ ossl_x509_sign(VALUE self, VALUE key, VALUE digest)
570
+ {
571
+ X509 *x509;
572
+ EVP_PKEY *pkey;
573
+ const EVP_MD *md;
574
+
575
+ pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
576
+ md = GetDigestPtr(digest);
577
+ GetX509(self, x509);
578
+ if (!X509_sign(x509, pkey, md)) {
579
+ ossl_raise(eX509CertError, NULL);
580
+ }
581
+
582
+ return self;
583
+ }
584
+
585
+ /*
586
+ * call-seq:
587
+ * cert.verify(key) => true | false
588
+ *
589
+ * Checks that cert signature is made with PRIVversion of this PUBLIC 'key'
590
+ */
591
+ static VALUE
592
+ ossl_x509_verify(VALUE self, VALUE key)
593
+ {
594
+ X509 *x509;
595
+ EVP_PKEY *pkey;
596
+
597
+ pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
598
+ GetX509(self, x509);
599
+
600
+ switch (X509_verify(x509, pkey)) {
601
+ case 1:
602
+ return Qtrue;
603
+ case 0:
604
+ ossl_clear_error();
605
+ return Qfalse;
606
+ default:
607
+ ossl_raise(eX509CertError, NULL);
608
+ }
609
+ }
610
+
611
+ /*
612
+ * call-seq:
613
+ * cert.check_private_key(key)
614
+ *
615
+ * Checks if 'key' is PRIV key for this cert
616
+ */
617
+ static VALUE
618
+ ossl_x509_check_private_key(VALUE self, VALUE key)
619
+ {
620
+ X509 *x509;
621
+ EVP_PKEY *pkey;
622
+
623
+ /* not needed private key, but should be */
624
+ pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
625
+ GetX509(self, x509);
626
+ if (!X509_check_private_key(x509, pkey)) {
627
+ OSSL_Warning("Check private key:%s", OSSL_ErrMsg());
628
+ return Qfalse;
629
+ }
630
+
631
+ return Qtrue;
632
+ }
633
+
634
+ /*
635
+ * call-seq:
636
+ * cert.extensions => [extension...]
637
+ */
638
+ static VALUE
639
+ ossl_x509_get_extensions(VALUE self)
640
+ {
641
+ X509 *x509;
642
+ int count, i;
643
+ X509_EXTENSION *ext;
644
+ VALUE ary;
645
+
646
+ GetX509(self, x509);
647
+ count = X509_get_ext_count(x509);
648
+ if (count < 0) {
649
+ return rb_ary_new();
650
+ }
651
+ ary = rb_ary_new2(count);
652
+ for (i=0; i<count; i++) {
653
+ ext = X509_get_ext(x509, i); /* NO DUP - don't free! */
654
+ rb_ary_push(ary, ossl_x509ext_new(ext));
655
+ }
656
+
657
+ return ary;
658
+ }
659
+
660
+ /*
661
+ * call-seq:
662
+ * cert.extensions = [ext...] => [ext...]
663
+ */
664
+ static VALUE
665
+ ossl_x509_set_extensions(VALUE self, VALUE ary)
666
+ {
667
+ X509 *x509;
668
+ X509_EXTENSION *ext;
669
+ long i;
670
+
671
+ Check_Type(ary, T_ARRAY);
672
+ /* All ary's members should be X509Extension */
673
+ for (i=0; i<RARRAY_LEN(ary); i++) {
674
+ OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
675
+ }
676
+ GetX509(self, x509);
677
+ while ((ext = X509_delete_ext(x509, 0)))
678
+ X509_EXTENSION_free(ext);
679
+ for (i=0; i<RARRAY_LEN(ary); i++) {
680
+ ext = GetX509ExtPtr(RARRAY_AREF(ary, i));
681
+ if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext */
682
+ ossl_raise(eX509CertError, NULL);
683
+ }
684
+ }
685
+
686
+ return ary;
687
+ }
688
+
689
+ /*
690
+ * call-seq:
691
+ * cert.add_extension(extension) => extension
692
+ */
693
+ static VALUE
694
+ ossl_x509_add_extension(VALUE self, VALUE extension)
695
+ {
696
+ X509 *x509;
697
+ X509_EXTENSION *ext;
698
+
699
+ GetX509(self, x509);
700
+ ext = GetX509ExtPtr(extension);
701
+ if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */
702
+ ossl_raise(eX509CertError, NULL);
703
+ }
704
+
705
+ return extension;
706
+ }
707
+
708
+ static VALUE
709
+ ossl_x509_inspect(VALUE self)
710
+ {
711
+ return rb_sprintf("#<%"PRIsVALUE": subject=%+"PRIsVALUE", "
712
+ "issuer=%+"PRIsVALUE", serial=%+"PRIsVALUE", "
713
+ "not_before=%+"PRIsVALUE", not_after=%+"PRIsVALUE">",
714
+ rb_obj_class(self),
715
+ ossl_x509_get_subject(self),
716
+ ossl_x509_get_issuer(self),
717
+ ossl_x509_get_serial(self),
718
+ ossl_x509_get_not_before(self),
719
+ ossl_x509_get_not_after(self));
720
+ }
721
+
722
+ /*
723
+ * INIT
724
+ */
725
+ void
726
+ Init_ossl_x509cert(void)
727
+ {
728
+ #if 0
729
+ mOSSL = rb_define_module("OpenSSL");
730
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
731
+ mX509 = rb_define_module_under(mOSSL, "X509");
732
+ #endif
733
+
734
+ eX509CertError = rb_define_class_under(mX509, "CertificateError", eOSSLError);
735
+
736
+ /* Document-class: OpenSSL::X509::Certificate
737
+ *
738
+ * Implementation of an X.509 certificate as specified in RFC 5280.
739
+ * Provides access to a certificate's attributes and allows certificates
740
+ * to be read from a string, but also supports the creation of new
741
+ * certificates from scratch.
742
+ *
743
+ * === Reading a certificate from a file
744
+ *
745
+ * Certificate is capable of handling DER-encoded certificates and
746
+ * certificates encoded in OpenSSL's PEM format.
747
+ *
748
+ * raw = File.read "cert.cer" # DER- or PEM-encoded
749
+ * certificate = OpenSSL::X509::Certificate.new raw
750
+ *
751
+ * === Saving a certificate to a file
752
+ *
753
+ * A certificate may be encoded in DER format
754
+ *
755
+ * cert = ...
756
+ * File.open("cert.cer", "wb") { |f| f.print cert.to_der }
757
+ *
758
+ * or in PEM format
759
+ *
760
+ * cert = ...
761
+ * File.open("cert.pem", "wb") { |f| f.print cert.to_pem }
762
+ *
763
+ * X.509 certificates are associated with a private/public key pair,
764
+ * typically a RSA, DSA or ECC key (see also OpenSSL::PKey::RSA,
765
+ * OpenSSL::PKey::DSA and OpenSSL::PKey::EC), the public key itself is
766
+ * stored within the certificate and can be accessed in form of an
767
+ * OpenSSL::PKey. Certificates are typically used to be able to associate
768
+ * some form of identity with a key pair, for example web servers serving
769
+ * pages over HTTPs use certificates to authenticate themselves to the user.
770
+ *
771
+ * The public key infrastructure (PKI) model relies on trusted certificate
772
+ * authorities ("root CAs") that issue these certificates, so that end
773
+ * users need to base their trust just on a selected few authorities
774
+ * that themselves again vouch for subordinate CAs issuing their
775
+ * certificates to end users.
776
+ *
777
+ * The OpenSSL::X509 module provides the tools to set up an independent
778
+ * PKI, similar to scenarios where the 'openssl' command line tool is
779
+ * used for issuing certificates in a private PKI.
780
+ *
781
+ * === Creating a root CA certificate and an end-entity certificate
782
+ *
783
+ * First, we need to create a "self-signed" root certificate. To do so,
784
+ * we need to generate a key first. Please note that the choice of "1"
785
+ * as a serial number is considered a security flaw for real certificates.
786
+ * Secure choices are integers in the two-digit byte range and ideally
787
+ * not sequential but secure random numbers, steps omitted here to keep
788
+ * the example concise.
789
+ *
790
+ * root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key
791
+ * root_ca = OpenSSL::X509::Certificate.new
792
+ * root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
793
+ * root_ca.serial = 1
794
+ * root_ca.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA"
795
+ * root_ca.issuer = root_ca.subject # root CA's are "self-signed"
796
+ * root_ca.public_key = root_key.public_key
797
+ * root_ca.not_before = Time.now
798
+ * root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity
799
+ * ef = OpenSSL::X509::ExtensionFactory.new
800
+ * ef.subject_certificate = root_ca
801
+ * ef.issuer_certificate = root_ca
802
+ * root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
803
+ * root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
804
+ * root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
805
+ * root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
806
+ * root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
807
+ *
808
+ * The next step is to create the end-entity certificate using the root CA
809
+ * certificate.
810
+ *
811
+ * key = OpenSSL::PKey::RSA.new 2048
812
+ * cert = OpenSSL::X509::Certificate.new
813
+ * cert.version = 2
814
+ * cert.serial = 2
815
+ * cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby certificate"
816
+ * cert.issuer = root_ca.subject # root CA is the issuer
817
+ * cert.public_key = key.public_key
818
+ * cert.not_before = Time.now
819
+ * cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60 # 1 years validity
820
+ * ef = OpenSSL::X509::ExtensionFactory.new
821
+ * ef.subject_certificate = cert
822
+ * ef.issuer_certificate = root_ca
823
+ * cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
824
+ * cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
825
+ * cert.sign(root_key, OpenSSL::Digest::SHA256.new)
826
+ *
827
+ */
828
+ cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject);
829
+
830
+ rb_define_alloc_func(cX509Cert, ossl_x509_alloc);
831
+ rb_define_method(cX509Cert, "initialize", ossl_x509_initialize, -1);
832
+ rb_define_copy_func(cX509Cert, ossl_x509_copy);
833
+
834
+ rb_define_method(cX509Cert, "to_der", ossl_x509_to_der, 0);
835
+ rb_define_method(cX509Cert, "to_pem", ossl_x509_to_pem, 0);
836
+ rb_define_alias(cX509Cert, "to_s", "to_pem");
837
+ rb_define_method(cX509Cert, "to_text", ossl_x509_to_text, 0);
838
+ rb_define_method(cX509Cert, "version", ossl_x509_get_version, 0);
839
+ rb_define_method(cX509Cert, "version=", ossl_x509_set_version, 1);
840
+ rb_define_method(cX509Cert, "signature_algorithm", ossl_x509_get_signature_algorithm, 0);
841
+ rb_define_method(cX509Cert, "serial", ossl_x509_get_serial, 0);
842
+ rb_define_method(cX509Cert, "serial=", ossl_x509_set_serial, 1);
843
+ rb_define_method(cX509Cert, "subject", ossl_x509_get_subject, 0);
844
+ rb_define_method(cX509Cert, "subject=", ossl_x509_set_subject, 1);
845
+ rb_define_method(cX509Cert, "issuer", ossl_x509_get_issuer, 0);
846
+ rb_define_method(cX509Cert, "issuer=", ossl_x509_set_issuer, 1);
847
+ rb_define_method(cX509Cert, "not_before", ossl_x509_get_not_before, 0);
848
+ rb_define_method(cX509Cert, "not_before=", ossl_x509_set_not_before, 1);
849
+ rb_define_method(cX509Cert, "not_after", ossl_x509_get_not_after, 0);
850
+ rb_define_method(cX509Cert, "not_after=", ossl_x509_set_not_after, 1);
851
+ rb_define_method(cX509Cert, "public_key", ossl_x509_get_public_key, 0);
852
+ rb_define_method(cX509Cert, "public_key=", ossl_x509_set_public_key, 1);
853
+ rb_define_method(cX509Cert, "sign", ossl_x509_sign, 2);
854
+ rb_define_method(cX509Cert, "verify", ossl_x509_verify, 1);
855
+ rb_define_method(cX509Cert, "check_private_key", ossl_x509_check_private_key, 1);
856
+ rb_define_method(cX509Cert, "extensions", ossl_x509_get_extensions, 0);
857
+ rb_define_method(cX509Cert, "extensions=", ossl_x509_set_extensions, 1);
858
+ rb_define_method(cX509Cert, "add_extension", ossl_x509_add_extension, 1);
859
+ rb_define_method(cX509Cert, "inspect", ossl_x509_inspect, 0);
860
+ }