rubysl-openssl 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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");
|