rubysl-openssl 1.0.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +5 -6
- data/ext/rubysl/openssl/.gitignore +3 -0
- data/ext/rubysl/openssl/deprecation.rb +21 -0
- data/ext/rubysl/openssl/extconf.rb +45 -32
- data/ext/rubysl/openssl/openssl_missing.c +20 -7
- data/ext/rubysl/openssl/openssl_missing.h +22 -15
- data/ext/rubysl/openssl/ossl.c +610 -61
- data/ext/rubysl/openssl/ossl.h +31 -17
- data/ext/rubysl/openssl/ossl_asn1.c +974 -183
- data/ext/rubysl/openssl/ossl_asn1.h +3 -3
- data/ext/rubysl/openssl/ossl_bio.c +4 -3
- data/ext/rubysl/openssl/ossl_bio.h +1 -1
- data/ext/rubysl/openssl/ossl_bn.c +32 -28
- data/ext/rubysl/openssl/ossl_bn.h +1 -1
- data/ext/rubysl/openssl/ossl_cipher.c +494 -93
- data/ext/rubysl/openssl/ossl_cipher.h +1 -1
- data/ext/rubysl/openssl/ossl_config.c +4 -5
- data/ext/rubysl/openssl/ossl_config.h +1 -1
- data/ext/rubysl/openssl/ossl_digest.c +206 -24
- data/ext/rubysl/openssl/ossl_digest.h +1 -1
- data/ext/rubysl/openssl/ossl_engine.c +48 -26
- data/ext/rubysl/openssl/ossl_engine.h +1 -1
- data/ext/rubysl/openssl/ossl_hmac.c +40 -38
- data/ext/rubysl/openssl/ossl_hmac.h +1 -1
- data/ext/rubysl/openssl/ossl_ns_spki.c +157 -25
- data/ext/rubysl/openssl/ossl_ns_spki.h +1 -1
- data/ext/rubysl/openssl/ossl_ocsp.c +57 -40
- data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs12.c +15 -13
- data/ext/rubysl/openssl/ossl_pkcs12.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs5.c +108 -18
- data/ext/rubysl/openssl/ossl_pkcs7.c +44 -37
- data/ext/rubysl/openssl/ossl_pkcs7.h +1 -1
- data/ext/rubysl/openssl/ossl_pkey.c +211 -15
- data/ext/rubysl/openssl/ossl_pkey.h +19 -9
- data/ext/rubysl/openssl/ossl_pkey_dh.c +180 -47
- data/ext/rubysl/openssl/ossl_pkey_dsa.c +184 -47
- data/ext/rubysl/openssl/ossl_pkey_ec.c +177 -93
- data/ext/rubysl/openssl/ossl_pkey_rsa.c +209 -102
- data/ext/rubysl/openssl/ossl_rand.c +15 -15
- data/ext/rubysl/openssl/ossl_rand.h +1 -1
- data/ext/rubysl/openssl/ossl_ssl.c +939 -192
- data/ext/rubysl/openssl/ossl_ssl.h +6 -6
- data/ext/rubysl/openssl/ossl_ssl_session.c +78 -62
- data/ext/rubysl/openssl/ossl_version.h +2 -2
- data/ext/rubysl/openssl/ossl_x509.c +1 -1
- data/ext/rubysl/openssl/ossl_x509.h +1 -1
- data/ext/rubysl/openssl/ossl_x509attr.c +20 -19
- data/ext/rubysl/openssl/ossl_x509cert.c +169 -67
- data/ext/rubysl/openssl/ossl_x509crl.c +41 -39
- data/ext/rubysl/openssl/ossl_x509ext.c +51 -38
- data/ext/rubysl/openssl/ossl_x509name.c +139 -29
- data/ext/rubysl/openssl/ossl_x509req.c +42 -40
- data/ext/rubysl/openssl/ossl_x509revoked.c +20 -20
- data/ext/rubysl/openssl/ossl_x509store.c +99 -47
- data/ext/rubysl/openssl/ruby_missing.h +3 -16
- data/lib/openssl/bn.rb +19 -19
- data/lib/openssl/buffering.rb +222 -14
- data/lib/openssl/cipher.rb +20 -20
- data/lib/openssl/config.rb +1 -4
- data/lib/openssl/digest.rb +47 -19
- data/lib/openssl/ssl.rb +197 -1
- data/lib/openssl/x509.rb +162 -1
- data/lib/rubysl/openssl.rb +4 -8
- data/lib/rubysl/openssl/version.rb +1 -1
- data/rubysl-openssl.gemspec +1 -2
- metadata +16 -34
- data/ext/rubysl/openssl/extconf.h +0 -50
- data/lib/openssl/net/ftptls.rb +0 -53
- data/lib/openssl/net/telnets.rb +0 -251
- data/lib/openssl/pkcs7.rb +0 -25
- data/lib/openssl/ssl-internal.rb +0 -187
- data/lib/openssl/x509-internal.rb +0 -153
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* $Id
|
2
|
+
* $Id$
|
3
3
|
* 'OpenSSL for Ruby' project
|
4
4
|
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
5
5
|
* All rights reserved.
|
@@ -12,17 +12,17 @@
|
|
12
12
|
#define _OSSL_SSL_H_
|
13
13
|
|
14
14
|
#define GetSSLSession(obj, sess) do { \
|
15
|
-
Data_Get_Struct(obj, SSL_SESSION, sess); \
|
16
|
-
if (!sess) { \
|
15
|
+
Data_Get_Struct((obj), SSL_SESSION, (sess)); \
|
16
|
+
if (!(sess)) { \
|
17
17
|
ossl_raise(rb_eRuntimeError, "SSL Session wasn't initialized."); \
|
18
18
|
} \
|
19
19
|
} while (0)
|
20
20
|
|
21
21
|
#define SafeGetSSLSession(obj, sess) do { \
|
22
|
-
OSSL_Check_Kind(obj, cSSLSession); \
|
23
|
-
GetSSLSession(obj, sess); \
|
22
|
+
OSSL_Check_Kind((obj), cSSLSession); \
|
23
|
+
GetSSLSession((obj), (sess)); \
|
24
24
|
} while (0)
|
25
|
-
|
25
|
+
|
26
26
|
extern VALUE mSSL;
|
27
27
|
extern VALUE eSSLError;
|
28
28
|
extern VALUE cSSLSocket;
|
@@ -5,17 +5,17 @@
|
|
5
5
|
#include "ossl.h"
|
6
6
|
|
7
7
|
#define GetSSLSession(obj, sess) do { \
|
8
|
-
Data_Get_Struct(obj, SSL_SESSION, sess); \
|
9
|
-
if (!sess) { \
|
8
|
+
Data_Get_Struct((obj), SSL_SESSION, (sess)); \
|
9
|
+
if (!(sess)) { \
|
10
10
|
ossl_raise(rb_eRuntimeError, "SSL Session wasn't initialized."); \
|
11
11
|
} \
|
12
12
|
} while (0)
|
13
13
|
|
14
14
|
#define SafeGetSSLSession(obj, sess) do { \
|
15
|
-
OSSL_Check_Kind(obj, cSSLSession); \
|
16
|
-
GetSSLSession(obj, sess); \
|
15
|
+
OSSL_Check_Kind((obj), cSSLSession); \
|
16
|
+
GetSSLSession((obj), (sess)); \
|
17
17
|
} while (0)
|
18
|
-
|
18
|
+
|
19
19
|
|
20
20
|
VALUE cSSLSession;
|
21
21
|
static VALUE eSSLSession;
|
@@ -36,8 +36,6 @@ static VALUE ossl_ssl_session_alloc(VALUE klass)
|
|
36
36
|
static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1)
|
37
37
|
{
|
38
38
|
SSL_SESSION *ctx = NULL;
|
39
|
-
VALUE obj;
|
40
|
-
unsigned char *p;
|
41
39
|
|
42
40
|
if (RDATA(self)->data)
|
43
41
|
ossl_raise(eSSLSession, "SSL Session already initialized");
|
@@ -55,7 +53,7 @@ static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1)
|
|
55
53
|
ctx = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
|
56
54
|
|
57
55
|
if (!ctx) {
|
58
|
-
|
56
|
+
OSSL_BIO_reset(in);
|
59
57
|
ctx = d2i_SSL_SESSION_bio(in, NULL);
|
60
58
|
}
|
61
59
|
|
@@ -74,6 +72,16 @@ static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1)
|
|
74
72
|
return self;
|
75
73
|
}
|
76
74
|
|
75
|
+
#if HAVE_SSL_SESSION_CMP == 0
|
76
|
+
int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b)
|
77
|
+
{
|
78
|
+
if (a->ssl_version != b->ssl_version ||
|
79
|
+
a->session_id_length != b->session_id_length)
|
80
|
+
return 1;
|
81
|
+
return memcmp(a->session_id,b-> session_id, a->session_id_length);
|
82
|
+
}
|
83
|
+
#endif
|
84
|
+
|
77
85
|
/*
|
78
86
|
* call-seq:
|
79
87
|
* session1 == session2 -> boolean
|
@@ -86,18 +94,9 @@ static VALUE ossl_ssl_session_eq(VALUE val1, VALUE val2)
|
|
86
94
|
GetSSLSession(val1, ctx1);
|
87
95
|
SafeGetSSLSession(val2, ctx2);
|
88
96
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
* comparing so we should not depend on it. Just compare sessions
|
93
|
-
* by version and id.
|
94
|
-
*/
|
95
|
-
if ((ctx1->ssl_version == ctx2->ssl_version) &&
|
96
|
-
(ctx1->session_id_length == ctx2->session_id_length) &&
|
97
|
-
(memcmp(ctx1->session_id, ctx2->session_id, ctx1->session_id_length) == 0)) {
|
98
|
-
return Qtrue;
|
99
|
-
} else {
|
100
|
-
return Qfalse;
|
97
|
+
switch (SSL_SESSION_cmp(ctx1, ctx2)) {
|
98
|
+
case 0: return Qtrue;
|
99
|
+
default: return Qfalse;
|
101
100
|
}
|
102
101
|
}
|
103
102
|
|
@@ -105,11 +104,13 @@ static VALUE ossl_ssl_session_eq(VALUE val1, VALUE val2)
|
|
105
104
|
* call-seq:
|
106
105
|
* session.time -> Time
|
107
106
|
*
|
107
|
+
* Gets start time of the session.
|
108
|
+
*
|
108
109
|
*/
|
109
110
|
static VALUE ossl_ssl_session_get_time(VALUE self)
|
110
111
|
{
|
111
112
|
SSL_SESSION *ctx;
|
112
|
-
|
113
|
+
time_t t;
|
113
114
|
|
114
115
|
GetSSLSession(self, ctx);
|
115
116
|
|
@@ -118,53 +119,67 @@ static VALUE ossl_ssl_session_get_time(VALUE self)
|
|
118
119
|
if (t == 0)
|
119
120
|
return Qnil;
|
120
121
|
|
121
|
-
return rb_funcall(rb_cTime, rb_intern("at"), 1,
|
122
|
+
return rb_funcall(rb_cTime, rb_intern("at"), 1, TIMET2NUM(t));
|
122
123
|
}
|
123
124
|
|
124
125
|
/*
|
125
126
|
* call-seq:
|
126
127
|
* session.timeout -> integer
|
127
128
|
*
|
128
|
-
*
|
129
|
+
* Gets how long until the session expires in seconds.
|
129
130
|
*
|
130
131
|
*/
|
131
132
|
static VALUE ossl_ssl_session_get_timeout(VALUE self)
|
132
133
|
{
|
133
134
|
SSL_SESSION *ctx;
|
134
|
-
|
135
|
+
time_t t;
|
135
136
|
|
136
137
|
GetSSLSession(self, ctx);
|
137
138
|
|
138
139
|
t = SSL_SESSION_get_timeout(ctx);
|
139
140
|
|
140
|
-
return
|
141
|
+
return TIMET2NUM(t);
|
141
142
|
}
|
142
143
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
t = NUM2LONG(time_v); \
|
160
|
-
\
|
161
|
-
SSL_SESSION_set_##func(ctx, t); \
|
162
|
-
\
|
163
|
-
return ossl_ssl_session_get_##func(self); \
|
144
|
+
/*
|
145
|
+
* call-seq:
|
146
|
+
* session.time=(Time) -> Time
|
147
|
+
* session.time=(integer) -> Time
|
148
|
+
*
|
149
|
+
* Sets start time of the session. Time resolution is in seconds.
|
150
|
+
*
|
151
|
+
*/
|
152
|
+
static VALUE ossl_ssl_session_set_time(VALUE self, VALUE time_v)
|
153
|
+
{
|
154
|
+
SSL_SESSION *ctx;
|
155
|
+
long t;
|
156
|
+
|
157
|
+
GetSSLSession(self, ctx);
|
158
|
+
if (rb_obj_is_instance_of(time_v, rb_cTime)) {
|
159
|
+
time_v = rb_funcall(time_v, rb_intern("to_i"), 0);
|
164
160
|
}
|
161
|
+
t = NUM2LONG(time_v);
|
162
|
+
SSL_SESSION_set_time(ctx, t);
|
163
|
+
return ossl_ssl_session_get_time(self);
|
164
|
+
}
|
165
165
|
|
166
|
-
|
167
|
-
|
166
|
+
/*
|
167
|
+
* call-seq:
|
168
|
+
* session.timeout=(integer) -> integer
|
169
|
+
*
|
170
|
+
* Sets how long until the session expires in seconds.
|
171
|
+
*
|
172
|
+
*/
|
173
|
+
static VALUE ossl_ssl_session_set_timeout(VALUE self, VALUE time_v)
|
174
|
+
{
|
175
|
+
SSL_SESSION *ctx;
|
176
|
+
long t;
|
177
|
+
|
178
|
+
GetSSLSession(self, ctx);
|
179
|
+
t = NUM2LONG(time_v);
|
180
|
+
SSL_SESSION_set_timeout(ctx, t);
|
181
|
+
return ossl_ssl_session_get_timeout(self);
|
182
|
+
}
|
168
183
|
|
169
184
|
#ifdef HAVE_SSL_SESSION_GET_ID
|
170
185
|
/*
|
@@ -196,20 +211,21 @@ static VALUE ossl_ssl_session_get_id(VALUE self)
|
|
196
211
|
static VALUE ossl_ssl_session_to_der(VALUE self)
|
197
212
|
{
|
198
213
|
SSL_SESSION *ctx;
|
199
|
-
unsigned char
|
214
|
+
unsigned char *p;
|
200
215
|
int len;
|
216
|
+
VALUE str;
|
201
217
|
|
202
218
|
GetSSLSession(self, ctx);
|
203
|
-
|
204
|
-
|
205
|
-
len = i2d_SSL_SESSION(ctx, &p);
|
206
|
-
|
207
|
-
if (len <= 0)
|
219
|
+
len = i2d_SSL_SESSION(ctx, NULL);
|
220
|
+
if (len <= 0) {
|
208
221
|
ossl_raise(eSSLSession, "i2d_SSL_SESSION");
|
209
|
-
|
210
|
-
ossl_raise(eSSLSession, "i2d_SSL_SESSION too large");
|
222
|
+
}
|
211
223
|
|
212
|
-
|
224
|
+
str = rb_str_new(0, len);
|
225
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
226
|
+
i2d_SSL_SESSION(ctx, &p);
|
227
|
+
ossl_str_adjust(str, p);
|
228
|
+
return str;
|
213
229
|
}
|
214
230
|
|
215
231
|
/*
|
@@ -225,7 +241,7 @@ static VALUE ossl_ssl_session_to_pem(VALUE self)
|
|
225
241
|
BUF_MEM *buf;
|
226
242
|
VALUE str;
|
227
243
|
int i;
|
228
|
-
|
244
|
+
|
229
245
|
GetSSLSession(self, ctx);
|
230
246
|
|
231
247
|
if (!(out = BIO_new(BIO_s_mem()))) {
|
@@ -257,7 +273,7 @@ static VALUE ossl_ssl_session_to_text(VALUE self)
|
|
257
273
|
BIO *out;
|
258
274
|
BUF_MEM *buf;
|
259
275
|
VALUE str;
|
260
|
-
|
276
|
+
|
261
277
|
GetSSLSession(self, ctx);
|
262
278
|
|
263
279
|
if (!(out = BIO_new(BIO_s_mem()))) {
|
@@ -275,12 +291,12 @@ static VALUE ossl_ssl_session_to_text(VALUE self)
|
|
275
291
|
|
276
292
|
return str;
|
277
293
|
}
|
278
|
-
|
294
|
+
|
279
295
|
|
280
296
|
void Init_ossl_ssl_session(void)
|
281
297
|
{
|
282
|
-
#if 0
|
283
|
-
mOSSL = rb_define_module("OpenSSL");
|
298
|
+
#if 0
|
299
|
+
mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
|
284
300
|
mSSL = rb_define_module_under(mOSSL, "SSL");
|
285
301
|
#endif
|
286
302
|
cSSLSession = rb_define_class_under(mSSL, "Session", rb_cObject);
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* $Id
|
2
|
+
* $Id$
|
3
3
|
* 'OpenSSL for Ruby' project
|
4
4
|
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
5
5
|
* All rights reserved.
|
@@ -11,6 +11,6 @@
|
|
11
11
|
#if !defined(_OSSL_VERSION_H_)
|
12
12
|
#define _OSSL_VERSION_H_
|
13
13
|
|
14
|
-
#define OSSL_VERSION "1.
|
14
|
+
#define OSSL_VERSION "1.1.0"
|
15
15
|
|
16
16
|
#endif /* _OSSL_VERSION_H_ */
|
@@ -11,20 +11,20 @@
|
|
11
11
|
#include "ossl.h"
|
12
12
|
|
13
13
|
#define WrapX509Attr(klass, obj, attr) do { \
|
14
|
-
if (!attr) { \
|
14
|
+
if (!(attr)) { \
|
15
15
|
ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \
|
16
16
|
} \
|
17
|
-
obj = Data_Wrap_Struct(klass, 0, X509_ATTRIBUTE_free, attr); \
|
17
|
+
(obj) = Data_Wrap_Struct((klass), 0, X509_ATTRIBUTE_free, (attr)); \
|
18
18
|
} while (0)
|
19
19
|
#define GetX509Attr(obj, attr) do { \
|
20
|
-
Data_Get_Struct(obj, X509_ATTRIBUTE, attr); \
|
21
|
-
if (!attr) { \
|
20
|
+
Data_Get_Struct((obj), X509_ATTRIBUTE, (attr)); \
|
21
|
+
if (!(attr)) { \
|
22
22
|
ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \
|
23
23
|
} \
|
24
24
|
} while (0)
|
25
25
|
#define SafeGetX509Attr(obj, attr) do { \
|
26
|
-
OSSL_Check_Kind(obj, cX509Attr); \
|
27
|
-
GetX509Attr(obj, attr); \
|
26
|
+
OSSL_Check_Kind((obj), cX509Attr); \
|
27
|
+
GetX509Attr((obj), (attr)); \
|
28
28
|
} while (0)
|
29
29
|
|
30
30
|
/*
|
@@ -41,7 +41,7 @@ ossl_x509attr_new(X509_ATTRIBUTE *attr)
|
|
41
41
|
{
|
42
42
|
X509_ATTRIBUTE *new;
|
43
43
|
VALUE obj;
|
44
|
-
|
44
|
+
|
45
45
|
if (!attr) {
|
46
46
|
new = X509_ATTRIBUTE_new();
|
47
47
|
} else {
|
@@ -77,7 +77,7 @@ ossl_x509attr_alloc(VALUE klass)
|
|
77
77
|
X509_ATTRIBUTE *attr;
|
78
78
|
VALUE obj;
|
79
79
|
|
80
|
-
if (!(attr = X509_ATTRIBUTE_new()))
|
80
|
+
if (!(attr = X509_ATTRIBUTE_new()))
|
81
81
|
ossl_raise(eX509AttrError, NULL);
|
82
82
|
WrapX509Attr(klass, obj, attr);
|
83
83
|
|
@@ -92,16 +92,17 @@ static VALUE
|
|
92
92
|
ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self)
|
93
93
|
{
|
94
94
|
VALUE oid, value;
|
95
|
-
X509_ATTRIBUTE *attr;
|
95
|
+
X509_ATTRIBUTE *attr, *x;
|
96
96
|
const unsigned char *p;
|
97
97
|
|
98
98
|
GetX509Attr(self, attr);
|
99
99
|
if(rb_scan_args(argc, argv, "11", &oid, &value) == 1){
|
100
100
|
oid = ossl_to_der_if_possible(oid);
|
101
101
|
StringValue(oid);
|
102
|
-
p = (
|
103
|
-
|
104
|
-
|
102
|
+
p = (unsigned char *)RSTRING_PTR(oid);
|
103
|
+
x = d2i_X509_ATTRIBUTE(&attr, &p, RSTRING_LEN(oid));
|
104
|
+
DATA_PTR(self) = attr;
|
105
|
+
if(!x){
|
105
106
|
ossl_raise(eX509AttrError, NULL);
|
106
107
|
}
|
107
108
|
return self;
|
@@ -122,14 +123,14 @@ ossl_x509attr_set_oid(VALUE self, VALUE oid)
|
|
122
123
|
X509_ATTRIBUTE *attr;
|
123
124
|
ASN1_OBJECT *obj;
|
124
125
|
char *s;
|
125
|
-
|
126
|
+
|
126
127
|
s = StringValuePtr(oid);
|
127
128
|
obj = OBJ_txt2obj(s, 0);
|
128
129
|
if(!obj) obj = OBJ_txt2obj(s, 1);
|
129
130
|
if(!obj) ossl_raise(eX509AttrError, NULL);
|
130
131
|
GetX509Attr(self, attr);
|
131
132
|
X509_ATTRIBUTE_set1_object(attr, obj);
|
132
|
-
|
133
|
+
|
133
134
|
return oid;
|
134
135
|
}
|
135
136
|
|
@@ -156,7 +157,7 @@ ossl_x509attr_get_oid(VALUE self)
|
|
156
157
|
i2a_ASN1_OBJECT(out, oid);
|
157
158
|
ret = ossl_membio2str(out);
|
158
159
|
}
|
159
|
-
|
160
|
+
|
160
161
|
return ret;
|
161
162
|
}
|
162
163
|
|
@@ -212,7 +213,7 @@ ossl_x509attr_get_value(VALUE self)
|
|
212
213
|
if(OSSL_X509ATTR_IS_SINGLE(attr)){
|
213
214
|
length = i2d_ASN1_TYPE(attr->value.single, NULL);
|
214
215
|
str = rb_str_new(0, length);
|
215
|
-
p = RSTRING_PTR(str);
|
216
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
216
217
|
i2d_ASN1_TYPE(attr->value.single, &p);
|
217
218
|
ossl_str_adjust(str, p);
|
218
219
|
}
|
@@ -221,7 +222,7 @@ ossl_x509attr_get_value(VALUE self)
|
|
221
222
|
(unsigned char **) NULL, i2d_ASN1_TYPE,
|
222
223
|
V_ASN1_SET, V_ASN1_UNIVERSAL, 0);
|
223
224
|
str = rb_str_new(0, length);
|
224
|
-
p = RSTRING_PTR(str);
|
225
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
225
226
|
i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set, &p,
|
226
227
|
i2d_ASN1_TYPE, V_ASN1_SET, V_ASN1_UNIVERSAL, 0);
|
227
228
|
ossl_str_adjust(str, p);
|
@@ -247,10 +248,10 @@ ossl_x509attr_to_der(VALUE self)
|
|
247
248
|
if((len = i2d_X509_ATTRIBUTE(attr, NULL)) <= 0)
|
248
249
|
ossl_raise(eX509AttrError, NULL);
|
249
250
|
str = rb_str_new(0, len);
|
250
|
-
p = RSTRING_PTR(str);
|
251
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
251
252
|
if(i2d_X509_ATTRIBUTE(attr, &p) <= 0)
|
252
253
|
ossl_raise(eX509AttrError, NULL);
|
253
|
-
rb_str_set_len(str, p - (unsigned char*)RSTRING_PTR(str));
|
254
|
+
rb_str_set_len(str, p - (unsigned char*)RSTRING_PTR(str));
|
254
255
|
|
255
256
|
return str;
|
256
257
|
}
|
@@ -11,20 +11,20 @@
|
|
11
11
|
#include "ossl.h"
|
12
12
|
|
13
13
|
#define WrapX509(klass, obj, x509) do { \
|
14
|
-
if (!x509) { \
|
14
|
+
if (!(x509)) { \
|
15
15
|
ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \
|
16
16
|
} \
|
17
|
-
obj = Data_Wrap_Struct(klass, 0, X509_free, x509); \
|
17
|
+
(obj) = Data_Wrap_Struct((klass), 0, X509_free, (x509)); \
|
18
18
|
} while (0)
|
19
19
|
#define GetX509(obj, x509) do { \
|
20
|
-
Data_Get_Struct(obj, X509, x509); \
|
21
|
-
if (!x509) { \
|
20
|
+
Data_Get_Struct((obj), X509, (x509)); \
|
21
|
+
if (!(x509)) { \
|
22
22
|
ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \
|
23
23
|
} \
|
24
24
|
} while (0)
|
25
25
|
#define SafeGetX509(obj, x509) do { \
|
26
|
-
OSSL_Check_Kind(obj, cX509Cert); \
|
27
|
-
GetX509(obj, x509); \
|
26
|
+
OSSL_Check_Kind((obj), cX509Cert); \
|
27
|
+
GetX509((obj), (x509)); \
|
28
28
|
} while (0)
|
29
29
|
|
30
30
|
/*
|
@@ -51,11 +51,11 @@ ossl_x509_new(X509 *x509)
|
|
51
51
|
ossl_raise(eX509CertError, NULL);
|
52
52
|
}
|
53
53
|
WrapX509(cX509Cert, obj, new);
|
54
|
-
|
54
|
+
|
55
55
|
return obj;
|
56
56
|
}
|
57
57
|
|
58
|
-
VALUE
|
58
|
+
VALUE
|
59
59
|
ossl_x509_new_from_file(VALUE filename)
|
60
60
|
{
|
61
61
|
X509 *x509;
|
@@ -66,11 +66,13 @@ ossl_x509_new_from_file(VALUE filename)
|
|
66
66
|
if (!(fp = fopen(RSTRING_PTR(filename), "r"))) {
|
67
67
|
ossl_raise(eX509CertError, "%s", strerror(errno));
|
68
68
|
}
|
69
|
+
rb_update_max_fd(fileno(fp));
|
69
70
|
x509 = PEM_read_X509(fp, NULL, NULL, NULL);
|
70
71
|
/*
|
71
72
|
* prepare for DER...
|
72
73
|
#if !defined(OPENSSL_NO_FP_API)
|
73
74
|
if (!x509) {
|
75
|
+
(void)ERR_get_error();
|
74
76
|
rewind(fp);
|
75
77
|
|
76
78
|
x509 = d2i_X509_fp(fp, NULL);
|
@@ -90,9 +92,9 @@ X509 *
|
|
90
92
|
GetX509CertPtr(VALUE obj)
|
91
93
|
{
|
92
94
|
X509 *x509;
|
93
|
-
|
95
|
+
|
94
96
|
SafeGetX509(obj, x509);
|
95
|
-
|
97
|
+
|
96
98
|
return x509;
|
97
99
|
}
|
98
100
|
|
@@ -100,18 +102,18 @@ X509 *
|
|
100
102
|
DupX509CertPtr(VALUE obj)
|
101
103
|
{
|
102
104
|
X509 *x509;
|
103
|
-
|
105
|
+
|
104
106
|
SafeGetX509(obj, x509);
|
105
|
-
|
107
|
+
|
106
108
|
CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
|
107
|
-
|
109
|
+
|
108
110
|
return x509;
|
109
111
|
}
|
110
112
|
|
111
113
|
/*
|
112
114
|
* Private
|
113
115
|
*/
|
114
|
-
static VALUE
|
116
|
+
static VALUE
|
115
117
|
ossl_x509_alloc(VALUE klass)
|
116
118
|
{
|
117
119
|
X509 *x509;
|
@@ -130,11 +132,11 @@ ossl_x509_alloc(VALUE klass)
|
|
130
132
|
* Certificate.new => cert
|
131
133
|
* Certificate.new(string) => cert
|
132
134
|
*/
|
133
|
-
static VALUE
|
135
|
+
static VALUE
|
134
136
|
ossl_x509_initialize(int argc, VALUE *argv, VALUE self)
|
135
137
|
{
|
136
138
|
BIO *in;
|
137
|
-
X509 *x509;
|
139
|
+
X509 *x509, *x = DATA_PTR(self);
|
138
140
|
VALUE arg;
|
139
141
|
|
140
142
|
if (rb_scan_args(argc, argv, "01", &arg) == 0) {
|
@@ -143,14 +145,16 @@ ossl_x509_initialize(int argc, VALUE *argv, VALUE self)
|
|
143
145
|
}
|
144
146
|
arg = ossl_to_der_if_possible(arg);
|
145
147
|
in = ossl_obj2bio(arg);
|
146
|
-
x509 = PEM_read_bio_X509(in,
|
148
|
+
x509 = PEM_read_bio_X509(in, &x, NULL, NULL);
|
149
|
+
DATA_PTR(self) = x;
|
147
150
|
if (!x509) {
|
148
|
-
|
149
|
-
x509 = d2i_X509_bio(in,
|
151
|
+
OSSL_BIO_reset(in);
|
152
|
+
x509 = d2i_X509_bio(in, &x);
|
153
|
+
DATA_PTR(self) = x;
|
150
154
|
}
|
151
155
|
BIO_free(in);
|
152
156
|
if (!x509) ossl_raise(eX509CertError, NULL);
|
153
|
-
|
157
|
+
|
154
158
|
return self;
|
155
159
|
}
|
156
160
|
|
@@ -158,7 +162,7 @@ static VALUE
|
|
158
162
|
ossl_x509_copy(VALUE self, VALUE other)
|
159
163
|
{
|
160
164
|
X509 *a, *b, *x509;
|
161
|
-
|
165
|
+
|
162
166
|
rb_check_frozen(self);
|
163
167
|
if (self == other) return self;
|
164
168
|
|
@@ -167,7 +171,7 @@ ossl_x509_copy(VALUE self, VALUE other)
|
|
167
171
|
|
168
172
|
x509 = X509_dup(b);
|
169
173
|
if (!x509) ossl_raise(eX509CertError, NULL);
|
170
|
-
|
174
|
+
|
171
175
|
DATA_PTR(self) = x509;
|
172
176
|
X509_free(a);
|
173
177
|
|
@@ -178,7 +182,7 @@ ossl_x509_copy(VALUE self, VALUE other)
|
|
178
182
|
* call-seq:
|
179
183
|
* cert.to_der => string
|
180
184
|
*/
|
181
|
-
static VALUE
|
185
|
+
static VALUE
|
182
186
|
ossl_x509_to_der(VALUE self)
|
183
187
|
{
|
184
188
|
X509 *x509;
|
@@ -190,11 +194,11 @@ ossl_x509_to_der(VALUE self)
|
|
190
194
|
if ((len = i2d_X509(x509, NULL)) <= 0)
|
191
195
|
ossl_raise(eX509CertError, NULL);
|
192
196
|
str = rb_str_new(0, len);
|
193
|
-
p = RSTRING_PTR(str);
|
197
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
194
198
|
if (i2d_X509(x509, &p) <= 0)
|
195
199
|
ossl_raise(eX509CertError, NULL);
|
196
200
|
ossl_str_adjust(str, p);
|
197
|
-
|
201
|
+
|
198
202
|
return str;
|
199
203
|
}
|
200
204
|
|
@@ -202,13 +206,13 @@ ossl_x509_to_der(VALUE self)
|
|
202
206
|
* call-seq:
|
203
207
|
* cert.to_pem => string
|
204
208
|
*/
|
205
|
-
static VALUE
|
209
|
+
static VALUE
|
206
210
|
ossl_x509_to_pem(VALUE self)
|
207
211
|
{
|
208
212
|
X509 *x509;
|
209
213
|
BIO *out;
|
210
214
|
VALUE str;
|
211
|
-
|
215
|
+
|
212
216
|
GetX509(self, x509);
|
213
217
|
out = BIO_new(BIO_s_mem());
|
214
218
|
if (!out) ossl_raise(eX509CertError, NULL);
|
@@ -232,7 +236,7 @@ ossl_x509_to_text(VALUE self)
|
|
232
236
|
X509 *x509;
|
233
237
|
BIO *out;
|
234
238
|
VALUE str;
|
235
|
-
|
239
|
+
|
236
240
|
GetX509(self, x509);
|
237
241
|
|
238
242
|
out = BIO_new(BIO_s_mem());
|
@@ -251,7 +255,7 @@ ossl_x509_to_text(VALUE self)
|
|
251
255
|
/*
|
252
256
|
* Makes from X509 X509_REQuest
|
253
257
|
*/
|
254
|
-
static VALUE
|
258
|
+
static VALUE
|
255
259
|
ossl_x509_to_req(VALUE self)
|
256
260
|
{
|
257
261
|
X509 *x509;
|
@@ -273,13 +277,13 @@ ossl_x509_to_req(VALUE self)
|
|
273
277
|
* call-seq:
|
274
278
|
* cert.version => integer
|
275
279
|
*/
|
276
|
-
static VALUE
|
280
|
+
static VALUE
|
277
281
|
ossl_x509_get_version(VALUE self)
|
278
282
|
{
|
279
283
|
X509 *x509;
|
280
284
|
|
281
285
|
GetX509(self, x509);
|
282
|
-
|
286
|
+
|
283
287
|
return LONG2NUM(X509_get_version(x509));
|
284
288
|
}
|
285
289
|
|
@@ -287,7 +291,7 @@ ossl_x509_get_version(VALUE self)
|
|
287
291
|
* call-seq:
|
288
292
|
* cert.version = integer => integer
|
289
293
|
*/
|
290
|
-
static VALUE
|
294
|
+
static VALUE
|
291
295
|
ossl_x509_set_version(VALUE self, VALUE version)
|
292
296
|
{
|
293
297
|
X509 *x509;
|
@@ -308,13 +312,13 @@ ossl_x509_set_version(VALUE self, VALUE version)
|
|
308
312
|
* call-seq:
|
309
313
|
* cert.serial => integer
|
310
314
|
*/
|
311
|
-
static VALUE
|
315
|
+
static VALUE
|
312
316
|
ossl_x509_get_serial(VALUE self)
|
313
317
|
{
|
314
318
|
X509 *x509;
|
315
319
|
|
316
320
|
GetX509(self, x509);
|
317
|
-
|
321
|
+
|
318
322
|
return asn1integer_to_num(X509_get_serialNumber(x509));
|
319
323
|
}
|
320
324
|
|
@@ -322,7 +326,7 @@ ossl_x509_get_serial(VALUE self)
|
|
322
326
|
* call-seq:
|
323
327
|
* cert.serial = integer => integer
|
324
328
|
*/
|
325
|
-
static VALUE
|
329
|
+
static VALUE
|
326
330
|
ossl_x509_set_serial(VALUE self, VALUE num)
|
327
331
|
{
|
328
332
|
X509 *x509;
|
@@ -331,7 +335,7 @@ ossl_x509_set_serial(VALUE self, VALUE num)
|
|
331
335
|
|
332
336
|
x509->cert_info->serialNumber =
|
333
337
|
num_to_asn1integer(num, X509_get_serialNumber(x509));
|
334
|
-
|
338
|
+
|
335
339
|
return num;
|
336
340
|
}
|
337
341
|
|
@@ -339,7 +343,7 @@ ossl_x509_set_serial(VALUE self, VALUE num)
|
|
339
343
|
* call-seq:
|
340
344
|
* cert.signature_algorithm => string
|
341
345
|
*/
|
342
|
-
static VALUE
|
346
|
+
static VALUE
|
343
347
|
ossl_x509_get_signature_algorithm(VALUE self)
|
344
348
|
{
|
345
349
|
X509 *x509;
|
@@ -363,12 +367,12 @@ ossl_x509_get_signature_algorithm(VALUE self)
|
|
363
367
|
* call-seq:
|
364
368
|
* cert.subject => name
|
365
369
|
*/
|
366
|
-
static VALUE
|
370
|
+
static VALUE
|
367
371
|
ossl_x509_get_subject(VALUE self)
|
368
372
|
{
|
369
373
|
X509 *x509;
|
370
374
|
X509_NAME *name;
|
371
|
-
|
375
|
+
|
372
376
|
GetX509(self, x509);
|
373
377
|
if (!(name = X509_get_subject_name(x509))) { /* NO DUP - don't free! */
|
374
378
|
ossl_raise(eX509CertError, NULL);
|
@@ -381,11 +385,11 @@ ossl_x509_get_subject(VALUE self)
|
|
381
385
|
* call-seq:
|
382
386
|
* cert.subject = name => name
|
383
387
|
*/
|
384
|
-
static VALUE
|
388
|
+
static VALUE
|
385
389
|
ossl_x509_set_subject(VALUE self, VALUE subject)
|
386
390
|
{
|
387
391
|
X509 *x509;
|
388
|
-
|
392
|
+
|
389
393
|
GetX509(self, x509);
|
390
394
|
if (!X509_set_subject_name(x509, GetX509NamePtr(subject))) { /* DUPs name */
|
391
395
|
ossl_raise(eX509CertError, NULL);
|
@@ -398,7 +402,7 @@ ossl_x509_set_subject(VALUE self, VALUE subject)
|
|
398
402
|
* call-seq:
|
399
403
|
* cert.issuer => name
|
400
404
|
*/
|
401
|
-
static VALUE
|
405
|
+
static VALUE
|
402
406
|
ossl_x509_get_issuer(VALUE self)
|
403
407
|
{
|
404
408
|
X509 *x509;
|
@@ -416,7 +420,7 @@ ossl_x509_get_issuer(VALUE self)
|
|
416
420
|
* call-seq:
|
417
421
|
* cert.issuer = name => name
|
418
422
|
*/
|
419
|
-
static VALUE
|
423
|
+
static VALUE
|
420
424
|
ossl_x509_set_issuer(VALUE self, VALUE issuer)
|
421
425
|
{
|
422
426
|
X509 *x509;
|
@@ -433,7 +437,7 @@ ossl_x509_set_issuer(VALUE self, VALUE issuer)
|
|
433
437
|
* call-seq:
|
434
438
|
* cert.not_before => time
|
435
439
|
*/
|
436
|
-
static VALUE
|
440
|
+
static VALUE
|
437
441
|
ossl_x509_get_not_before(VALUE self)
|
438
442
|
{
|
439
443
|
X509 *x509;
|
@@ -451,12 +455,12 @@ ossl_x509_get_not_before(VALUE self)
|
|
451
455
|
* call-seq:
|
452
456
|
* cert.not_before = time => time
|
453
457
|
*/
|
454
|
-
static VALUE
|
458
|
+
static VALUE
|
455
459
|
ossl_x509_set_not_before(VALUE self, VALUE time)
|
456
460
|
{
|
457
461
|
X509 *x509;
|
458
462
|
time_t sec;
|
459
|
-
|
463
|
+
|
460
464
|
sec = time_to_time_t(time);
|
461
465
|
GetX509(self, x509);
|
462
466
|
if (!X509_time_adj(X509_get_notBefore(x509), 0, &sec)) {
|
@@ -470,7 +474,7 @@ ossl_x509_set_not_before(VALUE self, VALUE time)
|
|
470
474
|
* call-seq:
|
471
475
|
* cert.not_after => time
|
472
476
|
*/
|
473
|
-
static VALUE
|
477
|
+
static VALUE
|
474
478
|
ossl_x509_get_not_after(VALUE self)
|
475
479
|
{
|
476
480
|
X509 *x509;
|
@@ -486,14 +490,14 @@ ossl_x509_get_not_after(VALUE self)
|
|
486
490
|
|
487
491
|
/*
|
488
492
|
* call-seq:
|
489
|
-
* cert.
|
493
|
+
* cert.not_after = time => time
|
490
494
|
*/
|
491
|
-
static VALUE
|
495
|
+
static VALUE
|
492
496
|
ossl_x509_set_not_after(VALUE self, VALUE time)
|
493
497
|
{
|
494
498
|
X509 *x509;
|
495
499
|
time_t sec;
|
496
|
-
|
500
|
+
|
497
501
|
sec = time_to_time_t(time);
|
498
502
|
GetX509(self, x509);
|
499
503
|
if (!X509_time_adj(X509_get_notAfter(x509), 0, &sec)) {
|
@@ -507,7 +511,7 @@ ossl_x509_set_not_after(VALUE self, VALUE time)
|
|
507
511
|
* call-seq:
|
508
512
|
* cert.public_key => key
|
509
513
|
*/
|
510
|
-
static VALUE
|
514
|
+
static VALUE
|
511
515
|
ossl_x509_get_public_key(VALUE self)
|
512
516
|
{
|
513
517
|
X509 *x509;
|
@@ -525,7 +529,7 @@ ossl_x509_get_public_key(VALUE self)
|
|
525
529
|
* call-seq:
|
526
530
|
* cert.public_key = key => key
|
527
531
|
*/
|
528
|
-
static VALUE
|
532
|
+
static VALUE
|
529
533
|
ossl_x509_set_public_key(VALUE self, VALUE key)
|
530
534
|
{
|
531
535
|
X509 *x509;
|
@@ -542,7 +546,7 @@ ossl_x509_set_public_key(VALUE self, VALUE key)
|
|
542
546
|
* call-seq:
|
543
547
|
* cert.sign(key, digest) => self
|
544
548
|
*/
|
545
|
-
static VALUE
|
549
|
+
static VALUE
|
546
550
|
ossl_x509_sign(VALUE self, VALUE key, VALUE digest)
|
547
551
|
{
|
548
552
|
X509 *x509;
|
@@ -565,7 +569,7 @@ ossl_x509_sign(VALUE self, VALUE key, VALUE digest)
|
|
565
569
|
*
|
566
570
|
* Checks that cert signature is made with PRIVversion of this PUBLIC 'key'
|
567
571
|
*/
|
568
|
-
static VALUE
|
572
|
+
static VALUE
|
569
573
|
ossl_x509_verify(VALUE self, VALUE key)
|
570
574
|
{
|
571
575
|
X509 *x509;
|
@@ -576,7 +580,7 @@ ossl_x509_verify(VALUE self, VALUE key)
|
|
576
580
|
GetX509(self, x509);
|
577
581
|
if ((i = X509_verify(x509, pkey)) < 0) {
|
578
582
|
ossl_raise(eX509CertError, NULL);
|
579
|
-
}
|
583
|
+
}
|
580
584
|
if (i > 0) {
|
581
585
|
return Qtrue;
|
582
586
|
}
|
@@ -590,12 +594,12 @@ ossl_x509_verify(VALUE self, VALUE key)
|
|
590
594
|
*
|
591
595
|
* Checks if 'key' is PRIV key for this cert
|
592
596
|
*/
|
593
|
-
static VALUE
|
597
|
+
static VALUE
|
594
598
|
ossl_x509_check_private_key(VALUE self, VALUE key)
|
595
599
|
{
|
596
600
|
X509 *x509;
|
597
601
|
EVP_PKEY *pkey;
|
598
|
-
|
602
|
+
|
599
603
|
/* not needed private key, but should be */
|
600
604
|
pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
|
601
605
|
GetX509(self, x509);
|
@@ -611,7 +615,7 @@ ossl_x509_check_private_key(VALUE self, VALUE key)
|
|
611
615
|
* call-seq:
|
612
616
|
* cert.extensions => [extension...]
|
613
617
|
*/
|
614
|
-
static VALUE
|
618
|
+
static VALUE
|
615
619
|
ossl_x509_get_extensions(VALUE self)
|
616
620
|
{
|
617
621
|
X509 *x509;
|
@@ -637,13 +641,13 @@ ossl_x509_get_extensions(VALUE self)
|
|
637
641
|
* call-seq:
|
638
642
|
* cert.extensions = [ext...] => [ext...]
|
639
643
|
*/
|
640
|
-
static VALUE
|
644
|
+
static VALUE
|
641
645
|
ossl_x509_set_extensions(VALUE self, VALUE ary)
|
642
646
|
{
|
643
647
|
X509 *x509;
|
644
648
|
X509_EXTENSION *ext;
|
645
649
|
int i;
|
646
|
-
|
650
|
+
|
647
651
|
Check_Type(ary, T_ARRAY);
|
648
652
|
/* All ary's members should be X509Extension */
|
649
653
|
for (i=0; i<RARRAY_LEN(ary); i++) {
|
@@ -654,7 +658,7 @@ ossl_x509_set_extensions(VALUE self, VALUE ary)
|
|
654
658
|
x509->cert_info->extensions = NULL;
|
655
659
|
for (i=0; i<RARRAY_LEN(ary); i++) {
|
656
660
|
ext = DupX509ExtPtr(rb_ary_entry(ary, i));
|
657
|
-
|
661
|
+
|
658
662
|
if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */
|
659
663
|
X509_EXTENSION_free(ext);
|
660
664
|
ossl_raise(eX509CertError, NULL);
|
@@ -669,12 +673,12 @@ ossl_x509_set_extensions(VALUE self, VALUE ary)
|
|
669
673
|
* call-seq:
|
670
674
|
* cert.add_extension(extension) => extension
|
671
675
|
*/
|
672
|
-
static VALUE
|
676
|
+
static VALUE
|
673
677
|
ossl_x509_add_extension(VALUE self, VALUE extension)
|
674
678
|
{
|
675
679
|
X509 *x509;
|
676
680
|
X509_EXTENSION *ext;
|
677
|
-
|
681
|
+
|
678
682
|
GetX509(self, x509);
|
679
683
|
ext = DupX509ExtPtr(extension);
|
680
684
|
if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */
|
@@ -723,17 +727,115 @@ ossl_x509_inspect(VALUE self)
|
|
723
727
|
/*
|
724
728
|
* INIT
|
725
729
|
*/
|
726
|
-
void
|
730
|
+
void
|
727
731
|
Init_ossl_x509cert()
|
728
732
|
{
|
733
|
+
|
734
|
+
#if 0
|
735
|
+
mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
|
736
|
+
mX509 = rb_define_module_under(mOSSL, "X509");
|
737
|
+
#endif
|
738
|
+
|
729
739
|
eX509CertError = rb_define_class_under(mX509, "CertificateError", eOSSLError);
|
730
|
-
|
740
|
+
|
741
|
+
/* Document-class: OpenSSL::X509::Certificate
|
742
|
+
*
|
743
|
+
* Implementation of an X.509 certificate as specified in RFC 5280.
|
744
|
+
* Provides access to a certificate's attributes and allows certificates
|
745
|
+
* to be read from a string, but also supports the creation of new
|
746
|
+
* certificates from scratch.
|
747
|
+
*
|
748
|
+
* === Reading a certificate from a file
|
749
|
+
*
|
750
|
+
* Certificate is capable of handling DER-encoded certificates and
|
751
|
+
* certificates encoded in OpenSSL's PEM format.
|
752
|
+
*
|
753
|
+
* raw = File.read "cert.cer" # DER- or PEM-encoded
|
754
|
+
* certificate = OpenSSL::X509::Certificate.new raw
|
755
|
+
*
|
756
|
+
* === Saving a certificate to a file
|
757
|
+
*
|
758
|
+
* A certificate may be encoded in DER format
|
759
|
+
*
|
760
|
+
* cert = ...
|
761
|
+
* File.open("cert.cer", "wb") { |f| f.print cert.to_der }
|
762
|
+
*
|
763
|
+
* or in PEM format
|
764
|
+
*
|
765
|
+
* cert = ...
|
766
|
+
* File.open("cert.pem", "wb") { |f| f.print cert.to_pem }
|
767
|
+
*
|
768
|
+
* X.509 certificates are associated with a private/public key pair,
|
769
|
+
* typically a RSA, DSA or ECC key (see also OpenSSL::PKey::RSA,
|
770
|
+
* OpenSSL::PKey::DSA and OpenSSL::PKey::EC), the public key itself is
|
771
|
+
* stored within the certificate and can be accessed in form of an
|
772
|
+
* OpenSSL::PKey. Certificates are typically used to be able to associate
|
773
|
+
* some form of identity with a key pair, for example web servers serving
|
774
|
+
* pages over HTTPs use certificates to authenticate themselves to the user.
|
775
|
+
*
|
776
|
+
* The public key infrastructure (PKI) model relies on trusted certificate
|
777
|
+
* authorities ("root CAs") that issue these certificates, so that end
|
778
|
+
* users need to base their trust just on a selected few authorities
|
779
|
+
* that themselves again vouch for subordinate CAs issuing their
|
780
|
+
* certificates to end users.
|
781
|
+
*
|
782
|
+
* The OpenSSL::X509 module provides the tools to set up an independent
|
783
|
+
* PKI, similar to scenarios where the 'openssl' command line tool is
|
784
|
+
* used for issuing certificates in a private PKI.
|
785
|
+
*
|
786
|
+
* === Creating a root CA certificate and an end-entity certificate
|
787
|
+
*
|
788
|
+
* First, we need to create a "self-signed" root certificate. To do so,
|
789
|
+
* we need to generate a key first. Please note that the choice of "1"
|
790
|
+
* as a serial number is considered a security flaw for real certificates.
|
791
|
+
* Secure choices are integers in the two-digit byte range and ideally
|
792
|
+
* not sequential but secure random numbers, steps omitted here to keep
|
793
|
+
* the example concise.
|
794
|
+
*
|
795
|
+
* root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key
|
796
|
+
* root_ca = OpenSSL::X509::Certificate.new
|
797
|
+
* root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
|
798
|
+
* root_ca.serial = 1
|
799
|
+
* root_ca.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA"
|
800
|
+
* root_ca.issuer = root_ca.subject # root CA's are "self-signed"
|
801
|
+
* root_ca.public_key = root_key.public_key
|
802
|
+
* root_ca.not_before = Time.now
|
803
|
+
* root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity
|
804
|
+
* ef = OpenSSL::X509::ExtensionFactory.new
|
805
|
+
* ef.subject_certificate = root_ca
|
806
|
+
* ef.issuer_certificate = root_ca
|
807
|
+
* root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
|
808
|
+
* root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
|
809
|
+
* root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
|
810
|
+
* root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
|
811
|
+
* root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
|
812
|
+
*
|
813
|
+
* The next step is to create the end-entity certificate using the root CA
|
814
|
+
* certificate.
|
815
|
+
*
|
816
|
+
* key = OpenSSL::PKey::RSA.new 2048
|
817
|
+
* cert = OpenSSL::X509::Certificate.new
|
818
|
+
* cert.version = 2
|
819
|
+
* cert.serial = 2
|
820
|
+
* cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby certificate"
|
821
|
+
* cert.issuer = root_ca.subject # root CA is the issuer
|
822
|
+
* cert.public_key = key.public_key
|
823
|
+
* cert.not_before = Time.now
|
824
|
+
* cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60 # 1 years validity
|
825
|
+
* ef = OpenSSL::X509::ExtensionFactory.new
|
826
|
+
* ef.subject_certificate = cert
|
827
|
+
* ef.issuer_certificate = root_ca
|
828
|
+
* cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
|
829
|
+
* cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
|
830
|
+
* cert.sign(root_key, OpenSSL::Digest::SHA256.new)
|
831
|
+
*
|
832
|
+
*/
|
731
833
|
cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject);
|
732
|
-
|
834
|
+
|
733
835
|
rb_define_alloc_func(cX509Cert, ossl_x509_alloc);
|
734
836
|
rb_define_method(cX509Cert, "initialize", ossl_x509_initialize, -1);
|
735
837
|
rb_define_copy_func(cX509Cert, ossl_x509_copy);
|
736
|
-
|
838
|
+
|
737
839
|
rb_define_method(cX509Cert, "to_der", ossl_x509_to_der, 0);
|
738
840
|
rb_define_method(cX509Cert, "to_pem", ossl_x509_to_pem, 0);
|
739
841
|
rb_define_alias(cX509Cert, "to_s", "to_pem");
|