rubysl-openssl 0.0.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +0 -1
  3. data/.travis.yml +7 -0
  4. data/README.md +2 -2
  5. data/Rakefile +0 -1
  6. data/ext/rubysl/openssl/extconf.h +50 -0
  7. data/ext/rubysl/openssl/extconf.rb +144 -0
  8. data/ext/rubysl/openssl/openssl_missing.c +343 -0
  9. data/ext/rubysl/openssl/openssl_missing.h +191 -0
  10. data/ext/rubysl/openssl/ossl.c +552 -0
  11. data/ext/rubysl/openssl/ossl.h +233 -0
  12. data/ext/rubysl/openssl/ossl_asn1.c +1160 -0
  13. data/ext/rubysl/openssl/ossl_asn1.h +59 -0
  14. data/ext/rubysl/openssl/ossl_bio.c +86 -0
  15. data/ext/rubysl/openssl/ossl_bio.h +21 -0
  16. data/ext/rubysl/openssl/ossl_bn.c +852 -0
  17. data/ext/rubysl/openssl/ossl_bn.h +25 -0
  18. data/ext/rubysl/openssl/ossl_cipher.c +569 -0
  19. data/ext/rubysl/openssl/ossl_cipher.h +22 -0
  20. data/ext/rubysl/openssl/ossl_config.c +75 -0
  21. data/ext/rubysl/openssl/ossl_config.h +22 -0
  22. data/ext/rubysl/openssl/ossl_digest.c +259 -0
  23. data/ext/rubysl/openssl/ossl_digest.h +22 -0
  24. data/ext/rubysl/openssl/ossl_engine.c +411 -0
  25. data/ext/rubysl/openssl/ossl_engine.h +20 -0
  26. data/ext/rubysl/openssl/ossl_hmac.c +268 -0
  27. data/ext/rubysl/openssl/ossl_hmac.h +19 -0
  28. data/ext/rubysl/openssl/ossl_ns_spki.c +257 -0
  29. data/ext/rubysl/openssl/ossl_ns_spki.h +21 -0
  30. data/ext/rubysl/openssl/ossl_ocsp.c +769 -0
  31. data/ext/rubysl/openssl/ossl_ocsp.h +24 -0
  32. data/ext/rubysl/openssl/ossl_pkcs12.c +210 -0
  33. data/ext/rubysl/openssl/ossl_pkcs12.h +15 -0
  34. data/ext/rubysl/openssl/ossl_pkcs5.c +99 -0
  35. data/ext/rubysl/openssl/ossl_pkcs5.h +6 -0
  36. data/ext/rubysl/openssl/ossl_pkcs7.c +1039 -0
  37. data/ext/rubysl/openssl/ossl_pkcs7.h +22 -0
  38. data/ext/rubysl/openssl/ossl_pkey.c +240 -0
  39. data/ext/rubysl/openssl/ossl_pkey.h +141 -0
  40. data/ext/rubysl/openssl/ossl_pkey_dh.c +532 -0
  41. data/ext/rubysl/openssl/ossl_pkey_dsa.c +484 -0
  42. data/ext/rubysl/openssl/ossl_pkey_ec.c +1593 -0
  43. data/ext/rubysl/openssl/ossl_pkey_rsa.c +593 -0
  44. data/ext/rubysl/openssl/ossl_rand.c +202 -0
  45. data/ext/rubysl/openssl/ossl_rand.h +20 -0
  46. data/ext/rubysl/openssl/ossl_ssl.c +1484 -0
  47. data/ext/rubysl/openssl/ossl_ssl.h +36 -0
  48. data/ext/rubysl/openssl/ossl_ssl_session.c +307 -0
  49. data/ext/rubysl/openssl/ossl_version.h +16 -0
  50. data/ext/rubysl/openssl/ossl_x509.c +104 -0
  51. data/ext/rubysl/openssl/ossl_x509.h +114 -0
  52. data/ext/rubysl/openssl/ossl_x509attr.c +274 -0
  53. data/ext/rubysl/openssl/ossl_x509cert.c +764 -0
  54. data/ext/rubysl/openssl/ossl_x509crl.c +535 -0
  55. data/ext/rubysl/openssl/ossl_x509ext.c +458 -0
  56. data/ext/rubysl/openssl/ossl_x509name.c +399 -0
  57. data/ext/rubysl/openssl/ossl_x509req.c +466 -0
  58. data/ext/rubysl/openssl/ossl_x509revoked.c +229 -0
  59. data/ext/rubysl/openssl/ossl_x509store.c +625 -0
  60. data/ext/rubysl/openssl/ruby_missing.h +41 -0
  61. data/lib/openssl.rb +1 -0
  62. data/lib/openssl/bn.rb +35 -0
  63. data/lib/openssl/buffering.rb +241 -0
  64. data/lib/openssl/cipher.rb +65 -0
  65. data/lib/openssl/config.rb +316 -0
  66. data/lib/openssl/digest.rb +61 -0
  67. data/lib/openssl/net/ftptls.rb +53 -0
  68. data/lib/openssl/net/telnets.rb +251 -0
  69. data/lib/openssl/pkcs7.rb +25 -0
  70. data/lib/openssl/ssl-internal.rb +187 -0
  71. data/lib/openssl/ssl.rb +1 -0
  72. data/lib/openssl/x509-internal.rb +153 -0
  73. data/lib/openssl/x509.rb +1 -0
  74. data/lib/rubysl/openssl.rb +28 -0
  75. data/lib/rubysl/openssl/version.rb +5 -0
  76. data/rubysl-openssl.gemspec +19 -18
  77. data/spec/cipher_spec.rb +16 -0
  78. data/spec/config/freeze_spec.rb +17 -0
  79. data/spec/hmac/digest_spec.rb +15 -0
  80. data/spec/hmac/hexdigest_spec.rb +15 -0
  81. data/spec/random/pseudo_bytes_spec.rb +5 -0
  82. data/spec/random/random_bytes_spec.rb +5 -0
  83. data/spec/random/shared/random_bytes.rb +28 -0
  84. data/spec/shared/constants.rb +11 -0
  85. data/spec/x509/name/parse_spec.rb +47 -0
  86. metadata +153 -89
  87. data/lib/rubysl-openssl.rb +0 -7
  88. data/lib/rubysl-openssl/version.rb +0 -5
@@ -0,0 +1,114 @@
1
+ /*
2
+ * $Id: ossl_x509.h 11708 2007-02-12 23:01:19Z shyouhei $
3
+ * 'OpenSSL for Ruby' project
4
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
+ * All rights reserved.
6
+ */
7
+ /*
8
+ * This program is licenced under the same licence as Ruby.
9
+ * (See the file 'LICENCE'.)
10
+ */
11
+ #if !defined(_OSSL_X509_H_)
12
+ #define _OSSL_X509_H_
13
+
14
+ /*
15
+ * X509 main module
16
+ */
17
+ extern VALUE mX509;
18
+
19
+ void Init_ossl_x509(void);
20
+
21
+ /*
22
+ * X509Attr
23
+ */
24
+ extern VALUE cX509Attr;
25
+ extern VALUE eX509AttrError;
26
+
27
+ VALUE ossl_x509attr_new(X509_ATTRIBUTE *);
28
+ X509_ATTRIBUTE *DupX509AttrPtr(VALUE);
29
+ void Init_ossl_x509attr(void);
30
+
31
+ /*
32
+ * X509Cert
33
+ */
34
+ extern VALUE cX509Cert;
35
+ extern VALUE eX509CertError;
36
+
37
+ VALUE ossl_x509_new(X509 *);
38
+ VALUE ossl_x509_new_from_file(VALUE);
39
+ X509 *GetX509CertPtr(VALUE);
40
+ X509 *DupX509CertPtr(VALUE);
41
+ void Init_ossl_x509cert(void);
42
+
43
+ /*
44
+ * X509CRL
45
+ */
46
+ extern VALUE cX509CRL;
47
+ extern VALUE eX509CRLError;
48
+
49
+ VALUE ossl_x509crl_new(X509_CRL *);
50
+ X509_CRL *GetX509CRLPtr(VALUE);
51
+ X509_CRL *DupX509CRLPtr(VALUE);
52
+ void Init_ossl_x509crl(void);
53
+
54
+ /*
55
+ * X509Extension
56
+ */
57
+ extern VALUE cX509Ext;
58
+ extern VALUE cX509ExtFactory;
59
+ extern VALUE eX509ExtError;
60
+
61
+ VALUE ossl_x509ext_new(X509_EXTENSION *);
62
+ X509_EXTENSION *GetX509ExtPtr(VALUE);
63
+ X509_EXTENSION *DupX509ExtPtr(VALUE);
64
+ void Init_ossl_x509ext(void);
65
+
66
+ /*
67
+ * X509Name
68
+ */
69
+ extern VALUE cX509Name;
70
+ extern VALUE eX509NameError;
71
+
72
+ VALUE ossl_x509name_new(X509_NAME *);
73
+ X509_NAME *GetX509NamePtr(VALUE);
74
+ void Init_ossl_x509name(void);
75
+
76
+ /*
77
+ * X509Request
78
+ */
79
+ extern VALUE cX509Req;
80
+ extern VALUE eX509ReqError;
81
+
82
+ VALUE ossl_x509req_new(X509_REQ *);
83
+ X509_REQ *GetX509ReqPtr(VALUE);
84
+ X509_REQ *DupX509ReqPtr(VALUE);
85
+ void Init_ossl_x509req(void);
86
+
87
+ /*
88
+ * X509Revoked
89
+ */
90
+ extern VALUE cX509Rev;
91
+ extern VALUE eX509RevError;
92
+
93
+ VALUE ossl_x509revoked_new(X509_REVOKED *);
94
+ X509_REVOKED *DupX509RevokedPtr(VALUE);
95
+ void Init_ossl_x509revoked(void);
96
+
97
+ /*
98
+ * X509Store and X509StoreContext
99
+ */
100
+ extern VALUE cX509Store;
101
+ extern VALUE cX509StoreContext;
102
+ extern VALUE eX509StoreError;
103
+
104
+ VALUE ossl_x509store_new(X509_STORE *);
105
+ X509_STORE *GetX509StorePtr(VALUE);
106
+ X509_STORE *DupX509StorePtr(VALUE);
107
+
108
+ VALUE ossl_x509stctx_new(X509_STORE_CTX *);
109
+ VALUE ossl_x509stctx_clear_ptr(VALUE);
110
+ X509_STORE_CTX *GetX509StCtxtPtr(VALUE);
111
+
112
+ void Init_ossl_x509store(void);
113
+
114
+ #endif /* _OSSL_X509_H_ */
@@ -0,0 +1,274 @@
1
+ /*
2
+ * $Id$
3
+ * 'OpenSSL for Ruby' project
4
+ * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>
5
+ * All rights reserved.
6
+ */
7
+ /*
8
+ * This program is licenced under the same licence as Ruby.
9
+ * (See the file 'LICENCE'.)
10
+ */
11
+ #include "ossl.h"
12
+
13
+ #define WrapX509Attr(klass, obj, attr) do { \
14
+ if (!attr) { \
15
+ ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \
16
+ } \
17
+ obj = Data_Wrap_Struct(klass, 0, X509_ATTRIBUTE_free, attr); \
18
+ } while (0)
19
+ #define GetX509Attr(obj, attr) do { \
20
+ Data_Get_Struct(obj, X509_ATTRIBUTE, attr); \
21
+ if (!attr) { \
22
+ ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \
23
+ } \
24
+ } while (0)
25
+ #define SafeGetX509Attr(obj, attr) do { \
26
+ OSSL_Check_Kind(obj, cX509Attr); \
27
+ GetX509Attr(obj, attr); \
28
+ } while (0)
29
+
30
+ /*
31
+ * Classes
32
+ */
33
+ VALUE cX509Attr;
34
+ VALUE eX509AttrError;
35
+
36
+ /*
37
+ * Public
38
+ */
39
+ VALUE
40
+ ossl_x509attr_new(X509_ATTRIBUTE *attr)
41
+ {
42
+ X509_ATTRIBUTE *new;
43
+ VALUE obj;
44
+
45
+ if (!attr) {
46
+ new = X509_ATTRIBUTE_new();
47
+ } else {
48
+ new = X509_ATTRIBUTE_dup(attr);
49
+ }
50
+ if (!new) {
51
+ ossl_raise(eX509AttrError, NULL);
52
+ }
53
+ WrapX509Attr(cX509Attr, obj, new);
54
+
55
+ return obj;
56
+ }
57
+
58
+ X509_ATTRIBUTE *
59
+ DupX509AttrPtr(VALUE obj)
60
+ {
61
+ X509_ATTRIBUTE *attr, *new;
62
+
63
+ SafeGetX509Attr(obj, attr);
64
+ if (!(new = X509_ATTRIBUTE_dup(attr))) {
65
+ ossl_raise(eX509AttrError, NULL);
66
+ }
67
+
68
+ return new;
69
+ }
70
+
71
+ /*
72
+ * Private
73
+ */
74
+ static VALUE
75
+ ossl_x509attr_alloc(VALUE klass)
76
+ {
77
+ X509_ATTRIBUTE *attr;
78
+ VALUE obj;
79
+
80
+ if (!(attr = X509_ATTRIBUTE_new()))
81
+ ossl_raise(eX509AttrError, NULL);
82
+ WrapX509Attr(klass, obj, attr);
83
+
84
+ return obj;
85
+ }
86
+
87
+ /*
88
+ * call-seq:
89
+ * Attribute.new(oid [, value]) => attr
90
+ */
91
+ static VALUE
92
+ ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self)
93
+ {
94
+ VALUE oid, value;
95
+ X509_ATTRIBUTE *attr;
96
+ const unsigned char *p;
97
+
98
+ GetX509Attr(self, attr);
99
+ if(rb_scan_args(argc, argv, "11", &oid, &value) == 1){
100
+ oid = ossl_to_der_if_possible(oid);
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))){
105
+ ossl_raise(eX509AttrError, NULL);
106
+ }
107
+ return self;
108
+ }
109
+ rb_funcall(self, rb_intern("oid="), 1, oid);
110
+ rb_funcall(self, rb_intern("value="), 1, value);
111
+
112
+ return self;
113
+ }
114
+
115
+ /*
116
+ * call-seq:
117
+ * attr.oid = string => string
118
+ */
119
+ static VALUE
120
+ ossl_x509attr_set_oid(VALUE self, VALUE oid)
121
+ {
122
+ X509_ATTRIBUTE *attr;
123
+ ASN1_OBJECT *obj;
124
+ char *s;
125
+
126
+ s = StringValuePtr(oid);
127
+ obj = OBJ_txt2obj(s, 0);
128
+ if(!obj) obj = OBJ_txt2obj(s, 1);
129
+ if(!obj) ossl_raise(eX509AttrError, NULL);
130
+ GetX509Attr(self, attr);
131
+ X509_ATTRIBUTE_set1_object(attr, obj);
132
+
133
+ return oid;
134
+ }
135
+
136
+ /*
137
+ * call-seq:
138
+ * attr.oid => string
139
+ */
140
+ static VALUE
141
+ ossl_x509attr_get_oid(VALUE self)
142
+ {
143
+ X509_ATTRIBUTE *attr;
144
+ ASN1_OBJECT *oid;
145
+ BIO *out;
146
+ VALUE ret;
147
+ int nid;
148
+
149
+ GetX509Attr(self, attr);
150
+ oid = X509_ATTRIBUTE_get0_object(attr);
151
+ if ((nid = OBJ_obj2nid(oid)) != NID_undef)
152
+ ret = rb_str_new2(OBJ_nid2sn(nid));
153
+ else{
154
+ if (!(out = BIO_new(BIO_s_mem())))
155
+ ossl_raise(eX509AttrError, NULL);
156
+ i2a_ASN1_OBJECT(out, oid);
157
+ ret = ossl_membio2str(out);
158
+ }
159
+
160
+ return ret;
161
+ }
162
+
163
+ #if defined(HAVE_ST_X509_ATTRIBUTE_SINGLE) || defined(HAVE_ST_SINGLE)
164
+ # define OSSL_X509ATTR_IS_SINGLE(attr) ((attr)->single)
165
+ # define OSSL_X509ATTR_SET_SINGLE(attr) ((attr)->single = 1)
166
+ #else
167
+ # define OSSL_X509ATTR_IS_SINGLE(attr) (!(attr)->set)
168
+ # define OSSL_X509ATTR_SET_SINGLE(attr) ((attr)->set = 0)
169
+ #endif
170
+
171
+ /*
172
+ * call-seq:
173
+ * attr.value = asn1 => asn1
174
+ */
175
+ static VALUE
176
+ ossl_x509attr_set_value(VALUE self, VALUE value)
177
+ {
178
+ X509_ATTRIBUTE *attr;
179
+ ASN1_TYPE *a1type;
180
+
181
+ if(!(a1type = ossl_asn1_get_asn1type(value)))
182
+ ossl_raise(eASN1Error, "could not get ASN1_TYPE");
183
+ if(ASN1_TYPE_get(a1type) == V_ASN1_SEQUENCE){
184
+ ASN1_TYPE_free(a1type);
185
+ ossl_raise(eASN1Error, "couldn't set SEQUENCE for attribute value.");
186
+ }
187
+ GetX509Attr(self, attr);
188
+ if(attr->value.set){
189
+ if(OSSL_X509ATTR_IS_SINGLE(attr)) ASN1_TYPE_free(attr->value.single);
190
+ else sk_ASN1_TYPE_free(attr->value.set);
191
+ }
192
+ OSSL_X509ATTR_SET_SINGLE(attr);
193
+ attr->value.single = a1type;
194
+
195
+ return value;
196
+ }
197
+
198
+ /*
199
+ * call-seq:
200
+ * attr.value => asn1
201
+ */
202
+ static VALUE
203
+ ossl_x509attr_get_value(VALUE self)
204
+ {
205
+ X509_ATTRIBUTE *attr;
206
+ VALUE str, asn1;
207
+ long length;
208
+ unsigned char *p;
209
+
210
+ GetX509Attr(self, attr);
211
+ if(attr->value.ptr == NULL) return Qnil;
212
+ if(OSSL_X509ATTR_IS_SINGLE(attr)){
213
+ length = i2d_ASN1_TYPE(attr->value.single, NULL);
214
+ str = rb_str_new(0, length);
215
+ p = RSTRING_PTR(str);
216
+ i2d_ASN1_TYPE(attr->value.single, &p);
217
+ ossl_str_adjust(str, p);
218
+ }
219
+ else{
220
+ length = i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set,
221
+ (unsigned char **) NULL, i2d_ASN1_TYPE,
222
+ V_ASN1_SET, V_ASN1_UNIVERSAL, 0);
223
+ str = rb_str_new(0, length);
224
+ p = RSTRING_PTR(str);
225
+ i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set, &p,
226
+ i2d_ASN1_TYPE, V_ASN1_SET, V_ASN1_UNIVERSAL, 0);
227
+ ossl_str_adjust(str, p);
228
+ }
229
+ asn1 = rb_funcall(mASN1, rb_intern("decode"), 1, str);
230
+
231
+ return asn1;
232
+ }
233
+
234
+ /*
235
+ * call-seq:
236
+ * attr.to_der => string
237
+ */
238
+ static VALUE
239
+ ossl_x509attr_to_der(VALUE self)
240
+ {
241
+ X509_ATTRIBUTE *attr;
242
+ VALUE str;
243
+ int len;
244
+ unsigned char *p;
245
+
246
+ GetX509Attr(self, attr);
247
+ if((len = i2d_X509_ATTRIBUTE(attr, NULL)) <= 0)
248
+ ossl_raise(eX509AttrError, NULL);
249
+ str = rb_str_new(0, len);
250
+ p = RSTRING_PTR(str);
251
+ if(i2d_X509_ATTRIBUTE(attr, &p) <= 0)
252
+ ossl_raise(eX509AttrError, NULL);
253
+ rb_str_set_len(str, p - (unsigned char*)RSTRING_PTR(str));
254
+
255
+ return str;
256
+ }
257
+
258
+ /*
259
+ * X509_ATTRIBUTE init
260
+ */
261
+ void
262
+ Init_ossl_x509attr()
263
+ {
264
+ eX509AttrError = rb_define_class_under(mX509, "AttributeError", eOSSLError);
265
+
266
+ cX509Attr = rb_define_class_under(mX509, "Attribute", rb_cObject);
267
+ rb_define_alloc_func(cX509Attr, ossl_x509attr_alloc);
268
+ rb_define_method(cX509Attr, "initialize", ossl_x509attr_initialize, -1);
269
+ rb_define_method(cX509Attr, "oid=", ossl_x509attr_set_oid, 1);
270
+ rb_define_method(cX509Attr, "oid", ossl_x509attr_get_oid, 0);
271
+ rb_define_method(cX509Attr, "value=", ossl_x509attr_set_value, 1);
272
+ rb_define_method(cX509Attr, "value", ossl_x509attr_get_value, 0);
273
+ rb_define_method(cX509Attr, "to_der", ossl_x509attr_to_der, 0);
274
+ }
@@ -0,0 +1,764 @@
1
+ /*
2
+ * $Id$
3
+ * 'OpenSSL for Ruby' project
4
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
+ * All rights reserved.
6
+ */
7
+ /*
8
+ * This program is licenced under the same licence as Ruby.
9
+ * (See the file 'LICENCE'.)
10
+ */
11
+ #include "ossl.h"
12
+
13
+ #define WrapX509(klass, obj, x509) do { \
14
+ if (!x509) { \
15
+ ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \
16
+ } \
17
+ obj = Data_Wrap_Struct(klass, 0, X509_free, x509); \
18
+ } while (0)
19
+ #define GetX509(obj, x509) do { \
20
+ Data_Get_Struct(obj, X509, x509); \
21
+ if (!x509) { \
22
+ ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \
23
+ } \
24
+ } while (0)
25
+ #define SafeGetX509(obj, x509) do { \
26
+ OSSL_Check_Kind(obj, cX509Cert); \
27
+ GetX509(obj, x509); \
28
+ } while (0)
29
+
30
+ /*
31
+ * Classes
32
+ */
33
+ VALUE cX509Cert;
34
+ VALUE eX509CertError;
35
+
36
+ /*
37
+ * Public
38
+ */
39
+ VALUE
40
+ ossl_x509_new(X509 *x509)
41
+ {
42
+ X509 *new;
43
+ VALUE obj;
44
+
45
+ if (!x509) {
46
+ new = X509_new();
47
+ } else {
48
+ new = X509_dup(x509);
49
+ }
50
+ if (!new) {
51
+ ossl_raise(eX509CertError, NULL);
52
+ }
53
+ WrapX509(cX509Cert, obj, new);
54
+
55
+ return obj;
56
+ }
57
+
58
+ VALUE
59
+ ossl_x509_new_from_file(VALUE filename)
60
+ {
61
+ X509 *x509;
62
+ FILE *fp;
63
+ VALUE obj;
64
+
65
+ SafeStringValue(filename);
66
+ if (!(fp = fopen(RSTRING_PTR(filename), "r"))) {
67
+ ossl_raise(eX509CertError, "%s", strerror(errno));
68
+ }
69
+ x509 = PEM_read_X509(fp, NULL, NULL, NULL);
70
+ /*
71
+ * prepare for DER...
72
+ #if !defined(OPENSSL_NO_FP_API)
73
+ if (!x509) {
74
+ rewind(fp);
75
+
76
+ x509 = d2i_X509_fp(fp, NULL);
77
+ }
78
+ #endif
79
+ */
80
+ fclose(fp);
81
+ if (!x509) {
82
+ ossl_raise(eX509CertError, NULL);
83
+ }
84
+ WrapX509(cX509Cert, obj, x509);
85
+
86
+ return obj;
87
+ }
88
+
89
+ X509 *
90
+ GetX509CertPtr(VALUE obj)
91
+ {
92
+ X509 *x509;
93
+
94
+ SafeGetX509(obj, x509);
95
+
96
+ return x509;
97
+ }
98
+
99
+ X509 *
100
+ DupX509CertPtr(VALUE obj)
101
+ {
102
+ X509 *x509;
103
+
104
+ SafeGetX509(obj, x509);
105
+
106
+ CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
107
+
108
+ return x509;
109
+ }
110
+
111
+ /*
112
+ * Private
113
+ */
114
+ static VALUE
115
+ ossl_x509_alloc(VALUE klass)
116
+ {
117
+ X509 *x509;
118
+ VALUE obj;
119
+
120
+ x509 = X509_new();
121
+ if (!x509) ossl_raise(eX509CertError, NULL);
122
+
123
+ WrapX509(klass, obj, x509);
124
+
125
+ return obj;
126
+ }
127
+
128
+ /*
129
+ * call-seq:
130
+ * Certificate.new => cert
131
+ * Certificate.new(string) => cert
132
+ */
133
+ static VALUE
134
+ ossl_x509_initialize(int argc, VALUE *argv, VALUE self)
135
+ {
136
+ BIO *in;
137
+ X509 *x509;
138
+ VALUE arg;
139
+
140
+ if (rb_scan_args(argc, argv, "01", &arg) == 0) {
141
+ /* create just empty X509Cert */
142
+ return self;
143
+ }
144
+ arg = ossl_to_der_if_possible(arg);
145
+ in = ossl_obj2bio(arg);
146
+ x509 = PEM_read_bio_X509(in, (X509 **)&DATA_PTR(self), NULL, NULL);
147
+ if (!x509) {
148
+ BIO_reset(in);
149
+ x509 = d2i_X509_bio(in, (X509 **)&DATA_PTR(self));
150
+ }
151
+ BIO_free(in);
152
+ if (!x509) ossl_raise(eX509CertError, NULL);
153
+
154
+ return self;
155
+ }
156
+
157
+ static VALUE
158
+ ossl_x509_copy(VALUE self, VALUE other)
159
+ {
160
+ X509 *a, *b, *x509;
161
+
162
+ rb_check_frozen(self);
163
+ if (self == other) return self;
164
+
165
+ GetX509(self, a);
166
+ SafeGetX509(other, b);
167
+
168
+ x509 = X509_dup(b);
169
+ if (!x509) ossl_raise(eX509CertError, NULL);
170
+
171
+ DATA_PTR(self) = x509;
172
+ X509_free(a);
173
+
174
+ return self;
175
+ }
176
+
177
+ /*
178
+ * call-seq:
179
+ * cert.to_der => string
180
+ */
181
+ static VALUE
182
+ ossl_x509_to_der(VALUE self)
183
+ {
184
+ X509 *x509;
185
+ VALUE str;
186
+ long len;
187
+ unsigned char *p;
188
+
189
+ GetX509(self, x509);
190
+ if ((len = i2d_X509(x509, NULL)) <= 0)
191
+ ossl_raise(eX509CertError, NULL);
192
+ str = rb_str_new(0, len);
193
+ p = RSTRING_PTR(str);
194
+ if (i2d_X509(x509, &p) <= 0)
195
+ ossl_raise(eX509CertError, NULL);
196
+ ossl_str_adjust(str, p);
197
+
198
+ return str;
199
+ }
200
+
201
+ /*
202
+ * call-seq:
203
+ * cert.to_pem => string
204
+ */
205
+ static VALUE
206
+ ossl_x509_to_pem(VALUE self)
207
+ {
208
+ X509 *x509;
209
+ BIO *out;
210
+ VALUE str;
211
+
212
+ GetX509(self, x509);
213
+ out = BIO_new(BIO_s_mem());
214
+ if (!out) ossl_raise(eX509CertError, NULL);
215
+
216
+ if (!PEM_write_bio_X509(out, x509)) {
217
+ BIO_free(out);
218
+ ossl_raise(eX509CertError, NULL);
219
+ }
220
+ str = ossl_membio2str(out);
221
+
222
+ return str;
223
+ }
224
+
225
+ /*
226
+ * call-seq:
227
+ * cert.to_text => string
228
+ */
229
+ static VALUE
230
+ ossl_x509_to_text(VALUE self)
231
+ {
232
+ X509 *x509;
233
+ BIO *out;
234
+ VALUE str;
235
+
236
+ GetX509(self, x509);
237
+
238
+ out = BIO_new(BIO_s_mem());
239
+ if (!out) ossl_raise(eX509CertError, NULL);
240
+
241
+ if (!X509_print(out, x509)) {
242
+ BIO_free(out);
243
+ ossl_raise(eX509CertError, NULL);
244
+ }
245
+ str = ossl_membio2str(out);
246
+
247
+ return str;
248
+ }
249
+
250
+ #if 0
251
+ /*
252
+ * Makes from X509 X509_REQuest
253
+ */
254
+ static VALUE
255
+ ossl_x509_to_req(VALUE self)
256
+ {
257
+ X509 *x509;
258
+ X509_REQ *req;
259
+ VALUE obj;
260
+
261
+ GetX509(self, x509);
262
+ if (!(req = X509_to_X509_REQ(x509, NULL, EVP_md5()))) {
263
+ ossl_raise(eX509CertError, NULL);
264
+ }
265
+ obj = ossl_x509req_new(req);
266
+ X509_REQ_free(req);
267
+
268
+ return obj;
269
+ }
270
+ #endif
271
+
272
+ /*
273
+ * call-seq:
274
+ * cert.version => integer
275
+ */
276
+ static VALUE
277
+ ossl_x509_get_version(VALUE self)
278
+ {
279
+ X509 *x509;
280
+
281
+ GetX509(self, x509);
282
+
283
+ return LONG2NUM(X509_get_version(x509));
284
+ }
285
+
286
+ /*
287
+ * call-seq:
288
+ * cert.version = integer => integer
289
+ */
290
+ static VALUE
291
+ ossl_x509_set_version(VALUE self, VALUE version)
292
+ {
293
+ X509 *x509;
294
+ long ver;
295
+
296
+ if ((ver = NUM2LONG(version)) < 0) {
297
+ ossl_raise(eX509CertError, "version must be >= 0!");
298
+ }
299
+ GetX509(self, x509);
300
+ if (!X509_set_version(x509, ver)) {
301
+ ossl_raise(eX509CertError, NULL);
302
+ }
303
+
304
+ return version;
305
+ }
306
+
307
+ /*
308
+ * call-seq:
309
+ * cert.serial => integer
310
+ */
311
+ static VALUE
312
+ ossl_x509_get_serial(VALUE self)
313
+ {
314
+ X509 *x509;
315
+
316
+ GetX509(self, x509);
317
+
318
+ return asn1integer_to_num(X509_get_serialNumber(x509));
319
+ }
320
+
321
+ /*
322
+ * call-seq:
323
+ * cert.serial = integer => integer
324
+ */
325
+ static VALUE
326
+ ossl_x509_set_serial(VALUE self, VALUE num)
327
+ {
328
+ X509 *x509;
329
+
330
+ GetX509(self, x509);
331
+
332
+ x509->cert_info->serialNumber =
333
+ num_to_asn1integer(num, X509_get_serialNumber(x509));
334
+
335
+ return num;
336
+ }
337
+
338
+ /*
339
+ * call-seq:
340
+ * cert.signature_algorithm => string
341
+ */
342
+ static VALUE
343
+ ossl_x509_get_signature_algorithm(VALUE self)
344
+ {
345
+ X509 *x509;
346
+ BIO *out;
347
+ VALUE str;
348
+
349
+ GetX509(self, x509);
350
+ out = BIO_new(BIO_s_mem());
351
+ if (!out) ossl_raise(eX509CertError, NULL);
352
+
353
+ if (!i2a_ASN1_OBJECT(out, x509->cert_info->signature->algorithm)) {
354
+ BIO_free(out);
355
+ ossl_raise(eX509CertError, NULL);
356
+ }
357
+ str = ossl_membio2str(out);
358
+
359
+ return str;
360
+ }
361
+
362
+ /*
363
+ * call-seq:
364
+ * cert.subject => name
365
+ */
366
+ static VALUE
367
+ ossl_x509_get_subject(VALUE self)
368
+ {
369
+ X509 *x509;
370
+ X509_NAME *name;
371
+
372
+ GetX509(self, x509);
373
+ if (!(name = X509_get_subject_name(x509))) { /* NO DUP - don't free! */
374
+ ossl_raise(eX509CertError, NULL);
375
+ }
376
+
377
+ return ossl_x509name_new(name);
378
+ }
379
+
380
+ /*
381
+ * call-seq:
382
+ * cert.subject = name => name
383
+ */
384
+ static VALUE
385
+ ossl_x509_set_subject(VALUE self, VALUE subject)
386
+ {
387
+ X509 *x509;
388
+
389
+ GetX509(self, x509);
390
+ if (!X509_set_subject_name(x509, GetX509NamePtr(subject))) { /* DUPs name */
391
+ ossl_raise(eX509CertError, NULL);
392
+ }
393
+
394
+ return subject;
395
+ }
396
+
397
+ /*
398
+ * call-seq:
399
+ * cert.issuer => name
400
+ */
401
+ static VALUE
402
+ ossl_x509_get_issuer(VALUE self)
403
+ {
404
+ X509 *x509;
405
+ X509_NAME *name;
406
+
407
+ GetX509(self, x509);
408
+ if(!(name = X509_get_issuer_name(x509))) { /* NO DUP - don't free! */
409
+ ossl_raise(eX509CertError, NULL);
410
+ }
411
+
412
+ return ossl_x509name_new(name);
413
+ }
414
+
415
+ /*
416
+ * call-seq:
417
+ * cert.issuer = name => name
418
+ */
419
+ static VALUE
420
+ ossl_x509_set_issuer(VALUE self, VALUE issuer)
421
+ {
422
+ X509 *x509;
423
+
424
+ GetX509(self, x509);
425
+ if (!X509_set_issuer_name(x509, GetX509NamePtr(issuer))) { /* DUPs name */
426
+ ossl_raise(eX509CertError, NULL);
427
+ }
428
+
429
+ return issuer;
430
+ }
431
+
432
+ /*
433
+ * call-seq:
434
+ * cert.not_before => time
435
+ */
436
+ static VALUE
437
+ ossl_x509_get_not_before(VALUE self)
438
+ {
439
+ X509 *x509;
440
+ ASN1_UTCTIME *asn1time;
441
+
442
+ GetX509(self, x509);
443
+ if (!(asn1time = X509_get_notBefore(x509))) { /* NO DUP - don't free! */
444
+ ossl_raise(eX509CertError, NULL);
445
+ }
446
+
447
+ return asn1time_to_time(asn1time);
448
+ }
449
+
450
+ /*
451
+ * call-seq:
452
+ * cert.not_before = time => time
453
+ */
454
+ static VALUE
455
+ ossl_x509_set_not_before(VALUE self, VALUE time)
456
+ {
457
+ X509 *x509;
458
+ time_t sec;
459
+
460
+ sec = time_to_time_t(time);
461
+ GetX509(self, x509);
462
+ if (!X509_time_adj(X509_get_notBefore(x509), 0, &sec)) {
463
+ ossl_raise(eX509CertError, NULL);
464
+ }
465
+
466
+ return time;
467
+ }
468
+
469
+ /*
470
+ * call-seq:
471
+ * cert.not_after => time
472
+ */
473
+ static VALUE
474
+ ossl_x509_get_not_after(VALUE self)
475
+ {
476
+ X509 *x509;
477
+ ASN1_TIME *asn1time;
478
+
479
+ GetX509(self, x509);
480
+ if (!(asn1time = X509_get_notAfter(x509))) { /* NO DUP - don't free! */
481
+ ossl_raise(eX509CertError, NULL);
482
+ }
483
+
484
+ return asn1time_to_time(asn1time);
485
+ }
486
+
487
+ /*
488
+ * call-seq:
489
+ * cert.not_before = time => time
490
+ */
491
+ static VALUE
492
+ ossl_x509_set_not_after(VALUE self, VALUE time)
493
+ {
494
+ X509 *x509;
495
+ time_t sec;
496
+
497
+ sec = time_to_time_t(time);
498
+ GetX509(self, x509);
499
+ if (!X509_time_adj(X509_get_notAfter(x509), 0, &sec)) {
500
+ ossl_raise(eX509CertError, NULL);
501
+ }
502
+
503
+ return time;
504
+ }
505
+
506
+ /*
507
+ * call-seq:
508
+ * cert.public_key => key
509
+ */
510
+ static VALUE
511
+ ossl_x509_get_public_key(VALUE self)
512
+ {
513
+ X509 *x509;
514
+ EVP_PKEY *pkey;
515
+
516
+ GetX509(self, x509);
517
+ if (!(pkey = X509_get_pubkey(x509))) { /* adds an reference */
518
+ ossl_raise(eX509CertError, NULL);
519
+ }
520
+
521
+ return ossl_pkey_new(pkey); /* NO DUP - OK */
522
+ }
523
+
524
+ /*
525
+ * call-seq:
526
+ * cert.public_key = key => key
527
+ */
528
+ static VALUE
529
+ ossl_x509_set_public_key(VALUE self, VALUE key)
530
+ {
531
+ X509 *x509;
532
+
533
+ GetX509(self, x509);
534
+ if (!X509_set_pubkey(x509, GetPKeyPtr(key))) { /* DUPs pkey */
535
+ ossl_raise(eX509CertError, NULL);
536
+ }
537
+
538
+ return key;
539
+ }
540
+
541
+ /*
542
+ * call-seq:
543
+ * cert.sign(key, digest) => self
544
+ */
545
+ static VALUE
546
+ ossl_x509_sign(VALUE self, VALUE key, VALUE digest)
547
+ {
548
+ X509 *x509;
549
+ EVP_PKEY *pkey;
550
+ const EVP_MD *md;
551
+
552
+ pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
553
+ md = GetDigestPtr(digest);
554
+ GetX509(self, x509);
555
+ if (!X509_sign(x509, pkey, md)) {
556
+ ossl_raise(eX509CertError, NULL);
557
+ }
558
+
559
+ return self;
560
+ }
561
+
562
+ /*
563
+ * call-seq:
564
+ * cert.verify(key) => true | false
565
+ *
566
+ * Checks that cert signature is made with PRIVversion of this PUBLIC 'key'
567
+ */
568
+ static VALUE
569
+ ossl_x509_verify(VALUE self, VALUE key)
570
+ {
571
+ X509 *x509;
572
+ EVP_PKEY *pkey;
573
+ int i;
574
+
575
+ pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
576
+ GetX509(self, x509);
577
+ if ((i = X509_verify(x509, pkey)) < 0) {
578
+ ossl_raise(eX509CertError, NULL);
579
+ }
580
+ if (i > 0) {
581
+ return Qtrue;
582
+ }
583
+
584
+ return Qfalse;
585
+ }
586
+
587
+ /*
588
+ * call-seq:
589
+ * cert.check_private_key(key)
590
+ *
591
+ * Checks if 'key' is PRIV key for this cert
592
+ */
593
+ static VALUE
594
+ ossl_x509_check_private_key(VALUE self, VALUE key)
595
+ {
596
+ X509 *x509;
597
+ EVP_PKEY *pkey;
598
+
599
+ /* not needed private key, but should be */
600
+ pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
601
+ GetX509(self, x509);
602
+ if (!X509_check_private_key(x509, pkey)) {
603
+ OSSL_Warning("Check private key:%s", OSSL_ErrMsg());
604
+ return Qfalse;
605
+ }
606
+
607
+ return Qtrue;
608
+ }
609
+
610
+ /*
611
+ * call-seq:
612
+ * cert.extensions => [extension...]
613
+ */
614
+ static VALUE
615
+ ossl_x509_get_extensions(VALUE self)
616
+ {
617
+ X509 *x509;
618
+ int count, i;
619
+ X509_EXTENSION *ext;
620
+ VALUE ary;
621
+
622
+ GetX509(self, x509);
623
+ count = X509_get_ext_count(x509);
624
+ if (count < 0) {
625
+ return rb_ary_new();
626
+ }
627
+ ary = rb_ary_new2(count);
628
+ for (i=0; i<count; i++) {
629
+ ext = X509_get_ext(x509, i); /* NO DUP - don't free! */
630
+ rb_ary_push(ary, ossl_x509ext_new(ext));
631
+ }
632
+
633
+ return ary;
634
+ }
635
+
636
+ /*
637
+ * call-seq:
638
+ * cert.extensions = [ext...] => [ext...]
639
+ */
640
+ static VALUE
641
+ ossl_x509_set_extensions(VALUE self, VALUE ary)
642
+ {
643
+ X509 *x509;
644
+ X509_EXTENSION *ext;
645
+ int i;
646
+
647
+ Check_Type(ary, T_ARRAY);
648
+ /* All ary's members should be X509Extension */
649
+ for (i=0; i<RARRAY_LEN(ary); i++) {
650
+ OSSL_Check_Kind(rb_ary_entry(ary, i), cX509Ext);
651
+ }
652
+ GetX509(self, x509);
653
+ sk_X509_EXTENSION_pop_free(x509->cert_info->extensions, X509_EXTENSION_free);
654
+ x509->cert_info->extensions = NULL;
655
+ for (i=0; i<RARRAY_LEN(ary); i++) {
656
+ ext = DupX509ExtPtr(rb_ary_entry(ary, i));
657
+
658
+ if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */
659
+ X509_EXTENSION_free(ext);
660
+ ossl_raise(eX509CertError, NULL);
661
+ }
662
+ X509_EXTENSION_free(ext);
663
+ }
664
+
665
+ return ary;
666
+ }
667
+
668
+ /*
669
+ * call-seq:
670
+ * cert.add_extension(extension) => extension
671
+ */
672
+ static VALUE
673
+ ossl_x509_add_extension(VALUE self, VALUE extension)
674
+ {
675
+ X509 *x509;
676
+ X509_EXTENSION *ext;
677
+
678
+ GetX509(self, x509);
679
+ ext = DupX509ExtPtr(extension);
680
+ if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */
681
+ X509_EXTENSION_free(ext);
682
+ ossl_raise(eX509CertError, NULL);
683
+ }
684
+ X509_EXTENSION_free(ext);
685
+
686
+ return extension;
687
+ }
688
+
689
+ static VALUE
690
+ ossl_x509_inspect(VALUE self)
691
+ {
692
+ VALUE str;
693
+ const char *cname = rb_class2name(rb_obj_class(self));
694
+
695
+ str = rb_str_new2("#<");
696
+ rb_str_cat2(str, cname);
697
+ rb_str_cat2(str, " ");
698
+
699
+ rb_str_cat2(str, "subject=");
700
+ rb_str_append(str, rb_inspect(ossl_x509_get_subject(self)));
701
+ rb_str_cat2(str, ", ");
702
+
703
+ rb_str_cat2(str, "issuer=");
704
+ rb_str_append(str, rb_inspect(ossl_x509_get_issuer(self)));
705
+ rb_str_cat2(str, ", ");
706
+
707
+ rb_str_cat2(str, "serial=");
708
+ rb_str_append(str, rb_inspect(ossl_x509_get_serial(self)));
709
+ rb_str_cat2(str, ", ");
710
+
711
+ rb_str_cat2(str, "not_before=");
712
+ rb_str_append(str, rb_inspect(ossl_x509_get_not_before(self)));
713
+ rb_str_cat2(str, ", ");
714
+
715
+ rb_str_cat2(str, "not_after=");
716
+ rb_str_append(str, rb_inspect(ossl_x509_get_not_after(self)));
717
+
718
+ str = rb_str_cat2(str, ">");
719
+
720
+ return str;
721
+ }
722
+
723
+ /*
724
+ * INIT
725
+ */
726
+ void
727
+ Init_ossl_x509cert()
728
+ {
729
+ eX509CertError = rb_define_class_under(mX509, "CertificateError", eOSSLError);
730
+
731
+ cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject);
732
+
733
+ rb_define_alloc_func(cX509Cert, ossl_x509_alloc);
734
+ rb_define_method(cX509Cert, "initialize", ossl_x509_initialize, -1);
735
+ rb_define_copy_func(cX509Cert, ossl_x509_copy);
736
+
737
+ rb_define_method(cX509Cert, "to_der", ossl_x509_to_der, 0);
738
+ rb_define_method(cX509Cert, "to_pem", ossl_x509_to_pem, 0);
739
+ rb_define_alias(cX509Cert, "to_s", "to_pem");
740
+ rb_define_method(cX509Cert, "to_text", ossl_x509_to_text, 0);
741
+ rb_define_method(cX509Cert, "version", ossl_x509_get_version, 0);
742
+ rb_define_method(cX509Cert, "version=", ossl_x509_set_version, 1);
743
+ rb_define_method(cX509Cert, "signature_algorithm", ossl_x509_get_signature_algorithm, 0);
744
+ rb_define_method(cX509Cert, "serial", ossl_x509_get_serial, 0);
745
+ rb_define_method(cX509Cert, "serial=", ossl_x509_set_serial, 1);
746
+ rb_define_method(cX509Cert, "subject", ossl_x509_get_subject, 0);
747
+ rb_define_method(cX509Cert, "subject=", ossl_x509_set_subject, 1);
748
+ rb_define_method(cX509Cert, "issuer", ossl_x509_get_issuer, 0);
749
+ rb_define_method(cX509Cert, "issuer=", ossl_x509_set_issuer, 1);
750
+ rb_define_method(cX509Cert, "not_before", ossl_x509_get_not_before, 0);
751
+ rb_define_method(cX509Cert, "not_before=", ossl_x509_set_not_before, 1);
752
+ rb_define_method(cX509Cert, "not_after", ossl_x509_get_not_after, 0);
753
+ rb_define_method(cX509Cert, "not_after=", ossl_x509_set_not_after, 1);
754
+ rb_define_method(cX509Cert, "public_key", ossl_x509_get_public_key, 0);
755
+ rb_define_method(cX509Cert, "public_key=", ossl_x509_set_public_key, 1);
756
+ rb_define_method(cX509Cert, "sign", ossl_x509_sign, 2);
757
+ rb_define_method(cX509Cert, "verify", ossl_x509_verify, 1);
758
+ rb_define_method(cX509Cert, "check_private_key", ossl_x509_check_private_key, 1);
759
+ rb_define_method(cX509Cert, "extensions", ossl_x509_get_extensions, 0);
760
+ rb_define_method(cX509Cert, "extensions=", ossl_x509_set_extensions, 1);
761
+ rb_define_method(cX509Cert, "add_extension", ossl_x509_add_extension, 1);
762
+ rb_define_method(cX509Cert, "inspect", ossl_x509_inspect, 0);
763
+ }
764
+