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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -6
  3. data/ext/rubysl/openssl/.gitignore +3 -0
  4. data/ext/rubysl/openssl/deprecation.rb +21 -0
  5. data/ext/rubysl/openssl/extconf.rb +45 -32
  6. data/ext/rubysl/openssl/openssl_missing.c +20 -7
  7. data/ext/rubysl/openssl/openssl_missing.h +22 -15
  8. data/ext/rubysl/openssl/ossl.c +610 -61
  9. data/ext/rubysl/openssl/ossl.h +31 -17
  10. data/ext/rubysl/openssl/ossl_asn1.c +974 -183
  11. data/ext/rubysl/openssl/ossl_asn1.h +3 -3
  12. data/ext/rubysl/openssl/ossl_bio.c +4 -3
  13. data/ext/rubysl/openssl/ossl_bio.h +1 -1
  14. data/ext/rubysl/openssl/ossl_bn.c +32 -28
  15. data/ext/rubysl/openssl/ossl_bn.h +1 -1
  16. data/ext/rubysl/openssl/ossl_cipher.c +494 -93
  17. data/ext/rubysl/openssl/ossl_cipher.h +1 -1
  18. data/ext/rubysl/openssl/ossl_config.c +4 -5
  19. data/ext/rubysl/openssl/ossl_config.h +1 -1
  20. data/ext/rubysl/openssl/ossl_digest.c +206 -24
  21. data/ext/rubysl/openssl/ossl_digest.h +1 -1
  22. data/ext/rubysl/openssl/ossl_engine.c +48 -26
  23. data/ext/rubysl/openssl/ossl_engine.h +1 -1
  24. data/ext/rubysl/openssl/ossl_hmac.c +40 -38
  25. data/ext/rubysl/openssl/ossl_hmac.h +1 -1
  26. data/ext/rubysl/openssl/ossl_ns_spki.c +157 -25
  27. data/ext/rubysl/openssl/ossl_ns_spki.h +1 -1
  28. data/ext/rubysl/openssl/ossl_ocsp.c +57 -40
  29. data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
  30. data/ext/rubysl/openssl/ossl_pkcs12.c +15 -13
  31. data/ext/rubysl/openssl/ossl_pkcs12.h +1 -1
  32. data/ext/rubysl/openssl/ossl_pkcs5.c +108 -18
  33. data/ext/rubysl/openssl/ossl_pkcs7.c +44 -37
  34. data/ext/rubysl/openssl/ossl_pkcs7.h +1 -1
  35. data/ext/rubysl/openssl/ossl_pkey.c +211 -15
  36. data/ext/rubysl/openssl/ossl_pkey.h +19 -9
  37. data/ext/rubysl/openssl/ossl_pkey_dh.c +180 -47
  38. data/ext/rubysl/openssl/ossl_pkey_dsa.c +184 -47
  39. data/ext/rubysl/openssl/ossl_pkey_ec.c +177 -93
  40. data/ext/rubysl/openssl/ossl_pkey_rsa.c +209 -102
  41. data/ext/rubysl/openssl/ossl_rand.c +15 -15
  42. data/ext/rubysl/openssl/ossl_rand.h +1 -1
  43. data/ext/rubysl/openssl/ossl_ssl.c +939 -192
  44. data/ext/rubysl/openssl/ossl_ssl.h +6 -6
  45. data/ext/rubysl/openssl/ossl_ssl_session.c +78 -62
  46. data/ext/rubysl/openssl/ossl_version.h +2 -2
  47. data/ext/rubysl/openssl/ossl_x509.c +1 -1
  48. data/ext/rubysl/openssl/ossl_x509.h +1 -1
  49. data/ext/rubysl/openssl/ossl_x509attr.c +20 -19
  50. data/ext/rubysl/openssl/ossl_x509cert.c +169 -67
  51. data/ext/rubysl/openssl/ossl_x509crl.c +41 -39
  52. data/ext/rubysl/openssl/ossl_x509ext.c +51 -38
  53. data/ext/rubysl/openssl/ossl_x509name.c +139 -29
  54. data/ext/rubysl/openssl/ossl_x509req.c +42 -40
  55. data/ext/rubysl/openssl/ossl_x509revoked.c +20 -20
  56. data/ext/rubysl/openssl/ossl_x509store.c +99 -47
  57. data/ext/rubysl/openssl/ruby_missing.h +3 -16
  58. data/lib/openssl/bn.rb +19 -19
  59. data/lib/openssl/buffering.rb +222 -14
  60. data/lib/openssl/cipher.rb +20 -20
  61. data/lib/openssl/config.rb +1 -4
  62. data/lib/openssl/digest.rb +47 -19
  63. data/lib/openssl/ssl.rb +197 -1
  64. data/lib/openssl/x509.rb +162 -1
  65. data/lib/rubysl/openssl.rb +4 -8
  66. data/lib/rubysl/openssl/version.rb +1 -1
  67. data/rubysl-openssl.gemspec +1 -2
  68. metadata +16 -34
  69. data/ext/rubysl/openssl/extconf.h +0 -50
  70. data/lib/openssl/net/ftptls.rb +0 -53
  71. data/lib/openssl/net/telnets.rb +0 -251
  72. data/lib/openssl/pkcs7.rb +0 -25
  73. data/lib/openssl/ssl-internal.rb +0 -187
  74. data/lib/openssl/x509-internal.rb +0 -153
@@ -1,5 +1,5 @@
1
1
  /*
2
- * $Id: ossl_ssl.h 12496 2007-06-08 15:02:04Z technorama $
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
- BIO_reset(in);
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
- * OpenSSL 1.0.0betas do not have non-static SSL_SESSION_cmp.
91
- * ssl_session_cmp (was SSL_SESSION_cmp in 0.9.8) is for lhash
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
- long t;
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, LONG2NUM(t));
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
- * How long until the session expires in seconds.
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
- long t;
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 LONG2NUM(t);
141
+ return TIMET2NUM(t);
141
142
  }
142
143
 
143
- #define SSLSESSION_SET_TIME(func) \
144
- static VALUE ossl_ssl_session_set_##func(VALUE self, VALUE time_v) \
145
- { \
146
- SSL_SESSION *ctx; \
147
- long t; \
148
- \
149
- GetSSLSession(self, ctx); \
150
- \
151
- if (rb_obj_is_instance_of(time_v, rb_cTime)) { \
152
- time_v = rb_funcall(time_v, rb_intern("to_i"), 0); \
153
- } else if (FIXNUM_P(time_v)) { \
154
- ; \
155
- } else { \
156
- rb_raise(rb_eArgError, "unknown type"); \
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
- SSLSESSION_SET_TIME(time)
167
- SSLSESSION_SET_TIME(timeout)
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 buf[1024*10], *p;
214
+ unsigned char *p;
200
215
  int len;
216
+ VALUE str;
201
217
 
202
218
  GetSSLSession(self, ctx);
203
-
204
- p = buf;
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
- else if (len >= sizeof(buf))
210
- ossl_raise(eSSLSession, "i2d_SSL_SESSION too large");
222
+ }
211
223
 
212
- return rb_str_new((const char *) p, len);
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 /* let rdoc know about mOSSL */
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: ossl_version.h 11708 2007-02-12 23:01:19Z shyouhei $
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.0.0"
14
+ #define OSSL_VERSION "1.1.0"
15
15
 
16
16
  #endif /* _OSSL_VERSION_H_ */
@@ -1,5 +1,5 @@
1
1
  /*
2
- * $Id: ossl_x509.c 11708 2007-02-12 23:01:19Z shyouhei $
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.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * $Id: ossl_x509.h 11708 2007-02-12 23:01:19Z shyouhei $
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,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 = (const unsigned char*) RSTRING_PTR(oid);
103
- if(!d2i_X509_ATTRIBUTE((X509_ATTRIBUTE**)&DATA_PTR(self),
104
- &p, RSTRING_LEN(oid))){
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, (X509 **)&DATA_PTR(self), NULL, NULL);
148
+ x509 = PEM_read_bio_X509(in, &x, NULL, NULL);
149
+ DATA_PTR(self) = x;
147
150
  if (!x509) {
148
- BIO_reset(in);
149
- x509 = d2i_X509_bio(in, (X509 **)&DATA_PTR(self));
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.not_before = time => time
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");