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.
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");