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,399 @@
1
+ /*
2
+ * $Id: ossl_x509name.c 28367 2010-06-21 09:18:59Z shyouhei $
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 WrapX509Name(klass, obj, name) do { \
14
+ if (!name) { \
15
+ ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \
16
+ } \
17
+ obj = Data_Wrap_Struct(klass, 0, X509_NAME_free, name); \
18
+ } while (0)
19
+ #define GetX509Name(obj, name) do { \
20
+ Data_Get_Struct(obj, X509_NAME, name); \
21
+ if (!name) { \
22
+ ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \
23
+ } \
24
+ } while (0)
25
+ #define SafeGetX509Name(obj, name) do { \
26
+ OSSL_Check_Kind(obj, cX509Name); \
27
+ GetX509Name(obj, name); \
28
+ } while (0)
29
+
30
+ #define OBJECT_TYPE_TEMPLATE \
31
+ rb_const_get(cX509Name, rb_intern("OBJECT_TYPE_TEMPLATE"))
32
+ #define DEFAULT_OBJECT_TYPE \
33
+ rb_const_get(cX509Name, rb_intern("DEFAULT_OBJECT_TYPE"))
34
+
35
+ /*
36
+ * Classes
37
+ */
38
+ VALUE cX509Name;
39
+ VALUE eX509NameError;
40
+
41
+ /*
42
+ * Public
43
+ */
44
+ VALUE
45
+ ossl_x509name_new(X509_NAME *name)
46
+ {
47
+ X509_NAME *new;
48
+ VALUE obj;
49
+
50
+ if (!name) {
51
+ new = X509_NAME_new();
52
+ } else {
53
+ new = X509_NAME_dup(name);
54
+ }
55
+ if (!new) {
56
+ ossl_raise(eX509NameError, NULL);
57
+ }
58
+ WrapX509Name(cX509Name, obj, new);
59
+
60
+ return obj;
61
+ }
62
+
63
+ X509_NAME *
64
+ GetX509NamePtr(VALUE obj)
65
+ {
66
+ X509_NAME *name;
67
+
68
+ SafeGetX509Name(obj, name);
69
+
70
+ return name;
71
+ }
72
+
73
+ /*
74
+ * Private
75
+ */
76
+ static VALUE
77
+ ossl_x509name_alloc(VALUE klass)
78
+ {
79
+ X509_NAME *name;
80
+ VALUE obj;
81
+
82
+ if (!(name = X509_NAME_new())) {
83
+ ossl_raise(eX509NameError, NULL);
84
+ }
85
+ WrapX509Name(klass, obj, name);
86
+
87
+ return obj;
88
+ }
89
+
90
+ static int id_aref;
91
+ static VALUE ossl_x509name_add_entry(int, VALUE*, VALUE);
92
+ #define rb_aref(obj, key) rb_funcall(obj, id_aref, 1, key)
93
+
94
+ static VALUE
95
+ ossl_x509name_init_i(VALUE i, VALUE args)
96
+ {
97
+ VALUE self = rb_ary_entry(args, 0);
98
+ VALUE template = rb_ary_entry(args, 1);
99
+ VALUE entry[3];
100
+
101
+ Check_Type(i, T_ARRAY);
102
+ entry[0] = rb_ary_entry(i, 0);
103
+ entry[1] = rb_ary_entry(i, 1);
104
+ entry[2] = rb_ary_entry(i, 2);
105
+ if(NIL_P(entry[2])) entry[2] = rb_aref(template, entry[0]);
106
+ if(NIL_P(entry[2])) entry[2] = DEFAULT_OBJECT_TYPE;
107
+ ossl_x509name_add_entry(3, entry, self);
108
+
109
+ return Qnil;
110
+ }
111
+
112
+ /*
113
+ * call-seq:
114
+ * X509::Name.new => name
115
+ * X509::Name.new(string) => name
116
+ * X509::Name.new(dn) => name
117
+ * X509::Name.new(dn, template) => name
118
+ */
119
+ static VALUE
120
+ ossl_x509name_initialize(int argc, VALUE *argv, VALUE self)
121
+ {
122
+ X509_NAME *name;
123
+ VALUE arg, template;
124
+
125
+ GetX509Name(self, name);
126
+ if (rb_scan_args(argc, argv, "02", &arg, &template) == 0) {
127
+ return self;
128
+ }
129
+ else {
130
+ VALUE tmp = rb_check_array_type(arg);
131
+ if (!NIL_P(tmp)) {
132
+ VALUE args;
133
+ if(NIL_P(template)) template = OBJECT_TYPE_TEMPLATE;
134
+ args = rb_ary_new3(2, self, template);
135
+ rb_block_call(tmp, rb_intern("each"), 0, 0, ossl_x509name_init_i, args);
136
+ }
137
+ else{
138
+ const unsigned char *p;
139
+ VALUE str = ossl_to_der_if_possible(arg);
140
+ X509_NAME *x;
141
+ StringValue(str);
142
+ p = (unsigned char *)RSTRING_PTR(str);
143
+ x = d2i_X509_NAME(&name, &p, RSTRING_LEN(str));
144
+ DATA_PTR(self) = name;
145
+ if(!x){
146
+ ossl_raise(eX509NameError, NULL);
147
+ }
148
+ }
149
+ }
150
+
151
+ return self;
152
+ }
153
+
154
+ /*
155
+ * call-seq:
156
+ * name.add_entry(oid, value [, type]) => self
157
+ */
158
+ static
159
+ VALUE ossl_x509name_add_entry(int argc, VALUE *argv, VALUE self)
160
+ {
161
+ X509_NAME *name;
162
+ VALUE oid, value, type;
163
+
164
+ rb_scan_args(argc, argv, "21", &oid, &value, &type);
165
+ StringValue(oid);
166
+ StringValue(value);
167
+ if(NIL_P(type)) type = rb_aref(OBJECT_TYPE_TEMPLATE, oid);
168
+ GetX509Name(self, name);
169
+ if (!X509_NAME_add_entry_by_txt(name, RSTRING_PTR(oid), NUM2INT(type),
170
+ RSTRING_PTR(value), RSTRING_LEN(value), -1, 0)) {
171
+ ossl_raise(eX509NameError, NULL);
172
+ }
173
+
174
+ return self;
175
+ }
176
+
177
+ static VALUE
178
+ ossl_x509name_to_s_old(VALUE self)
179
+ {
180
+ X509_NAME *name;
181
+ char *buf;
182
+ VALUE str;
183
+
184
+ GetX509Name(self, name);
185
+ buf = X509_NAME_oneline(name, NULL, 0);
186
+ str = rb_str_new2(buf);
187
+ OPENSSL_free(buf);
188
+
189
+ return str;
190
+ }
191
+
192
+ /*
193
+ * call-seq:
194
+ * name.to_s => string
195
+ * name.to_s(integer) => string
196
+ */
197
+ static VALUE
198
+ ossl_x509name_to_s(int argc, VALUE *argv, VALUE self)
199
+ {
200
+ X509_NAME *name;
201
+ VALUE flag, str;
202
+ BIO *out;
203
+ unsigned long iflag;
204
+
205
+ rb_scan_args(argc, argv, "01", &flag);
206
+ if (NIL_P(flag))
207
+ return ossl_x509name_to_s_old(self);
208
+ else iflag = NUM2ULONG(flag);
209
+ if (!(out = BIO_new(BIO_s_mem())))
210
+ ossl_raise(eX509NameError, NULL);
211
+ GetX509Name(self, name);
212
+ if (!X509_NAME_print_ex(out, name, 0, iflag)){
213
+ BIO_free(out);
214
+ ossl_raise(eX509NameError, NULL);
215
+ }
216
+ str = ossl_membio2str(out);
217
+
218
+ return str;
219
+ }
220
+
221
+ /*
222
+ * call-seq:
223
+ * name.to_a => [[name, data, type], ...]
224
+ */
225
+ static VALUE
226
+ ossl_x509name_to_a(VALUE self)
227
+ {
228
+ X509_NAME *name;
229
+ X509_NAME_ENTRY *entry;
230
+ int i,entries;
231
+ char long_name[512];
232
+ const char *short_name;
233
+ VALUE ary, ret;
234
+
235
+ GetX509Name(self, name);
236
+ entries = X509_NAME_entry_count(name);
237
+ if (entries < 0) {
238
+ OSSL_Debug("name entries < 0!");
239
+ return rb_ary_new();
240
+ }
241
+ ret = rb_ary_new2(entries);
242
+ for (i=0; i<entries; i++) {
243
+ if (!(entry = X509_NAME_get_entry(name, i))) {
244
+ ossl_raise(eX509NameError, NULL);
245
+ }
246
+ if (!i2t_ASN1_OBJECT(long_name, sizeof(long_name), entry->object)) {
247
+ ossl_raise(eX509NameError, NULL);
248
+ }
249
+ short_name = OBJ_nid2sn(OBJ_ln2nid(long_name));
250
+ ary = rb_ary_new3(3, rb_str_new2(short_name),
251
+ rb_str_new(entry->value->data, entry->value->length),
252
+ INT2FIX(entry->value->type));
253
+ rb_ary_push(ret, ary);
254
+ }
255
+ return ret;
256
+ }
257
+
258
+ static int
259
+ ossl_x509name_cmp0(VALUE self, VALUE other)
260
+ {
261
+ X509_NAME *name1, *name2;
262
+
263
+ GetX509Name(self, name1);
264
+ SafeGetX509Name(other, name2);
265
+
266
+ return X509_NAME_cmp(name1, name2);
267
+ }
268
+
269
+ static VALUE
270
+ ossl_x509name_cmp(VALUE self, VALUE other)
271
+ {
272
+ int result;
273
+
274
+ result = ossl_x509name_cmp0(self, other);
275
+ if (result < 0) return INT2FIX(-1);
276
+ if (result > 1) return INT2FIX(1);
277
+
278
+ return INT2FIX(0);
279
+ }
280
+
281
+ static VALUE
282
+ ossl_x509name_eql(VALUE self, VALUE other)
283
+ {
284
+ int result;
285
+
286
+ if(CLASS_OF(other) != cX509Name) return Qfalse;
287
+ result = ossl_x509name_cmp0(self, other);
288
+
289
+ return (result == 0) ? Qtrue : Qfalse;
290
+ }
291
+
292
+ /*
293
+ * call-seq:
294
+ * name.hash => integer
295
+ */
296
+ static VALUE
297
+ ossl_x509name_hash(VALUE self)
298
+ {
299
+ X509_NAME *name;
300
+ unsigned long hash;
301
+
302
+ GetX509Name(self, name);
303
+
304
+ hash = X509_NAME_hash(name);
305
+
306
+ return ULONG2NUM(hash);
307
+ }
308
+
309
+ #ifdef HAVE_X509_NAME_HASH_OLD
310
+ /*
311
+ * call-seq:
312
+ * name.hash_old => integer
313
+ *
314
+ * hash_old returns MD5 based hash used in OpenSSL 0.9.X.
315
+ */
316
+ static VALUE
317
+ ossl_x509name_hash_old(VALUE self)
318
+ {
319
+ X509_NAME *name;
320
+ unsigned long hash;
321
+
322
+ GetX509Name(self, name);
323
+
324
+ hash = X509_NAME_hash_old(name);
325
+
326
+ return ULONG2NUM(hash);
327
+ }
328
+ #endif
329
+
330
+ /*
331
+ * call-seq:
332
+ * name.to_der => string
333
+ */
334
+ static VALUE
335
+ ossl_x509name_to_der(VALUE self)
336
+ {
337
+ X509_NAME *name;
338
+ VALUE str;
339
+ long len;
340
+ unsigned char *p;
341
+
342
+ GetX509Name(self, name);
343
+ if((len = i2d_X509_NAME(name, NULL)) <= 0)
344
+ ossl_raise(eX509NameError, NULL);
345
+ str = rb_str_new(0, len);
346
+ p = RSTRING_PTR(str);
347
+ if(i2d_X509_NAME(name, &p) <= 0)
348
+ ossl_raise(eX509NameError, NULL);
349
+ ossl_str_adjust(str, p);
350
+
351
+ return str;
352
+ }
353
+
354
+ /*
355
+ * INIT
356
+ */
357
+ void
358
+ Init_ossl_x509name()
359
+ {
360
+ VALUE utf8str, ptrstr, ia5str, hash;
361
+
362
+ id_aref = rb_intern("[]");
363
+ eX509NameError = rb_define_class_under(mX509, "NameError", eOSSLError);
364
+ cX509Name = rb_define_class_under(mX509, "Name", rb_cObject);
365
+
366
+ rb_define_alloc_func(cX509Name, ossl_x509name_alloc);
367
+ rb_define_method(cX509Name, "initialize", ossl_x509name_initialize, -1);
368
+ rb_define_method(cX509Name, "add_entry", ossl_x509name_add_entry, -1);
369
+ rb_define_method(cX509Name, "to_s", ossl_x509name_to_s, -1);
370
+ rb_define_method(cX509Name, "to_a", ossl_x509name_to_a, 0);
371
+ rb_define_method(cX509Name, "cmp", ossl_x509name_cmp, 1);
372
+ rb_define_alias(cX509Name, "<=>", "cmp");
373
+ rb_define_method(cX509Name, "eql?", ossl_x509name_eql, 1);
374
+ rb_define_method(cX509Name, "hash", ossl_x509name_hash, 0);
375
+ #ifdef HAVE_X509_NAME_HASH_OLD
376
+ rb_define_method(cX509Name, "hash_old", ossl_x509name_hash_old, 0);
377
+ #endif
378
+ rb_define_method(cX509Name, "to_der", ossl_x509name_to_der, 0);
379
+
380
+ utf8str = INT2NUM(V_ASN1_UTF8STRING);
381
+ ptrstr = INT2NUM(V_ASN1_PRINTABLESTRING);
382
+ ia5str = INT2NUM(V_ASN1_IA5STRING);
383
+ rb_define_const(cX509Name, "DEFAULT_OBJECT_TYPE", utf8str);
384
+ hash = rb_hash_new();
385
+ rb_funcall(hash, rb_intern("default="), 1, utf8str);
386
+ rb_hash_aset(hash, rb_str_new2("C"), ptrstr);
387
+ rb_hash_aset(hash, rb_str_new2("countryName"), ptrstr);
388
+ rb_hash_aset(hash, rb_str_new2("serialNumber"), ptrstr);
389
+ rb_hash_aset(hash, rb_str_new2("dnQualifier"), ptrstr);
390
+ rb_hash_aset(hash, rb_str_new2("DC"), ia5str);
391
+ rb_hash_aset(hash, rb_str_new2("domainComponent"), ia5str);
392
+ rb_hash_aset(hash, rb_str_new2("emailAddress"), ia5str);
393
+ rb_define_const(cX509Name, "OBJECT_TYPE_TEMPLATE", hash);
394
+
395
+ rb_define_const(cX509Name, "COMPAT", ULONG2NUM(XN_FLAG_COMPAT));
396
+ rb_define_const(cX509Name, "RFC2253", ULONG2NUM(XN_FLAG_RFC2253));
397
+ rb_define_const(cX509Name, "ONELINE", ULONG2NUM(XN_FLAG_ONELINE));
398
+ rb_define_const(cX509Name, "MULTILINE", ULONG2NUM(XN_FLAG_MULTILINE));
399
+ }
@@ -0,0 +1,466 @@
1
+ /*
2
+ * $Id: ossl_x509req.c 12496 2007-06-08 15:02:04Z technorama $
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 WrapX509Req(klass, obj, req) do { \
14
+ if (!req) { \
15
+ ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \
16
+ } \
17
+ obj = Data_Wrap_Struct(klass, 0, X509_REQ_free, req); \
18
+ } while (0)
19
+ #define GetX509Req(obj, req) do { \
20
+ Data_Get_Struct(obj, X509_REQ, req); \
21
+ if (!req) { \
22
+ ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \
23
+ } \
24
+ } while (0)
25
+ #define SafeGetX509Req(obj, req) do { \
26
+ OSSL_Check_Kind(obj, cX509Req); \
27
+ GetX509Req(obj, req); \
28
+ } while (0)
29
+
30
+ /*
31
+ * Classes
32
+ */
33
+ VALUE cX509Req;
34
+ VALUE eX509ReqError;
35
+
36
+ /*
37
+ * Public functions
38
+ */
39
+ VALUE
40
+ ossl_x509req_new(X509_REQ *req)
41
+ {
42
+ X509_REQ *new;
43
+ VALUE obj;
44
+
45
+ if (!req) {
46
+ new = X509_REQ_new();
47
+ } else {
48
+ new = X509_REQ_dup(req);
49
+ }
50
+ if (!new) {
51
+ ossl_raise(eX509ReqError, NULL);
52
+ }
53
+ WrapX509Req(cX509Req, obj, new);
54
+
55
+ return obj;
56
+ }
57
+
58
+ X509_REQ *
59
+ GetX509ReqPtr(VALUE obj)
60
+ {
61
+ X509_REQ *req;
62
+
63
+ SafeGetX509Req(obj, req);
64
+
65
+ return req;
66
+ }
67
+
68
+ X509_REQ *
69
+ DupX509ReqPtr(VALUE obj)
70
+ {
71
+ X509_REQ *req, *new;
72
+
73
+ SafeGetX509Req(obj, req);
74
+ if (!(new = X509_REQ_dup(req))) {
75
+ ossl_raise(eX509ReqError, NULL);
76
+ }
77
+
78
+ return new;
79
+ }
80
+
81
+ /*
82
+ * Private functions
83
+ */
84
+ static VALUE
85
+ ossl_x509req_alloc(VALUE klass)
86
+ {
87
+ X509_REQ *req;
88
+ VALUE obj;
89
+
90
+ if (!(req = X509_REQ_new())) {
91
+ ossl_raise(eX509ReqError, NULL);
92
+ }
93
+ WrapX509Req(klass, obj, req);
94
+
95
+ return obj;
96
+ }
97
+
98
+ static VALUE
99
+ ossl_x509req_initialize(int argc, VALUE *argv, VALUE self)
100
+ {
101
+ BIO *in;
102
+ X509_REQ *req;
103
+ VALUE arg;
104
+
105
+ if (rb_scan_args(argc, argv, "01", &arg) == 0) {
106
+ return self;
107
+ }
108
+ arg = ossl_to_der_if_possible(arg);
109
+ in = ossl_obj2bio(arg);
110
+ req = PEM_read_bio_X509_REQ(in, (X509_REQ **)&DATA_PTR(self), NULL, NULL);
111
+ if (!req) {
112
+ BIO_reset(in);
113
+ req = d2i_X509_REQ_bio(in, (X509_REQ **)&DATA_PTR(self));
114
+ }
115
+ BIO_free(in);
116
+ if (!req) ossl_raise(eX509ReqError, NULL);
117
+
118
+ return self;
119
+ }
120
+
121
+ static VALUE
122
+ ossl_x509req_copy(VALUE self, VALUE other)
123
+ {
124
+ X509_REQ *a, *b, *req;
125
+
126
+ rb_check_frozen(self);
127
+ if (self == other) return self;
128
+ GetX509Req(self, a);
129
+ SafeGetX509Req(other, b);
130
+ if (!(req = X509_REQ_dup(b))) {
131
+ ossl_raise(eX509ReqError, NULL);
132
+ }
133
+ X509_REQ_free(a);
134
+ DATA_PTR(self) = req;
135
+
136
+ return self;
137
+ }
138
+
139
+ static VALUE
140
+ ossl_x509req_to_pem(VALUE self)
141
+ {
142
+ X509_REQ *req;
143
+ BIO *out;
144
+ BUF_MEM *buf;
145
+ VALUE str;
146
+
147
+ GetX509Req(self, req);
148
+ if (!(out = BIO_new(BIO_s_mem()))) {
149
+ ossl_raise(eX509ReqError, NULL);
150
+ }
151
+ if (!PEM_write_bio_X509_REQ(out, req)) {
152
+ BIO_free(out);
153
+ ossl_raise(eX509ReqError, NULL);
154
+ }
155
+ BIO_get_mem_ptr(out, &buf);
156
+ str = rb_str_new(buf->data, buf->length);
157
+ BIO_free(out);
158
+
159
+ return str;
160
+ }
161
+
162
+ static VALUE
163
+ ossl_x509req_to_der(VALUE self)
164
+ {
165
+ X509_REQ *req;
166
+ VALUE str;
167
+ long len;
168
+ unsigned char *p;
169
+
170
+ GetX509Req(self, req);
171
+ if ((len = i2d_X509_REQ(req, NULL)) <= 0)
172
+ ossl_raise(eX509CertError, NULL);
173
+ str = rb_str_new(0, len);
174
+ p = RSTRING_PTR(str);
175
+ if (i2d_X509_REQ(req, &p) <= 0)
176
+ ossl_raise(eX509ReqError, NULL);
177
+ ossl_str_adjust(str, p);
178
+
179
+ return str;
180
+ }
181
+
182
+ static VALUE
183
+ ossl_x509req_to_text(VALUE self)
184
+ {
185
+ X509_REQ *req;
186
+ BIO *out;
187
+ BUF_MEM *buf;
188
+ VALUE str;
189
+
190
+ GetX509Req(self, req);
191
+ if (!(out = BIO_new(BIO_s_mem()))) {
192
+ ossl_raise(eX509ReqError, NULL);
193
+ }
194
+ if (!X509_REQ_print(out, req)) {
195
+ BIO_free(out);
196
+ ossl_raise(eX509ReqError, NULL);
197
+ }
198
+ BIO_get_mem_ptr(out, &buf);
199
+ str = rb_str_new(buf->data, buf->length);
200
+ BIO_free(out);
201
+
202
+ return str;
203
+ }
204
+
205
+ #if 0
206
+ /*
207
+ * Makes X509 from X509_REQuest
208
+ */
209
+ static VALUE
210
+ ossl_x509req_to_x509(VALUE self, VALUE days, VALUE key)
211
+ {
212
+ X509_REQ *req;
213
+ X509 *x509;
214
+
215
+ GetX509Req(self, req);
216
+ ...
217
+ if (!(x509 = X509_REQ_to_X509(req, d, pkey))) {
218
+ ossl_raise(eX509ReqError, NULL);
219
+ }
220
+
221
+ return ossl_x509_new(x509);
222
+ }
223
+ #endif
224
+
225
+ static VALUE
226
+ ossl_x509req_get_version(VALUE self)
227
+ {
228
+ X509_REQ *req;
229
+ long version;
230
+
231
+ GetX509Req(self, req);
232
+ version = X509_REQ_get_version(req);
233
+
234
+ return LONG2FIX(version);
235
+ }
236
+
237
+ static VALUE
238
+ ossl_x509req_set_version(VALUE self, VALUE version)
239
+ {
240
+ X509_REQ *req;
241
+ long ver;
242
+
243
+ if ((ver = FIX2LONG(version)) < 0) {
244
+ ossl_raise(eX509ReqError, "version must be >= 0!");
245
+ }
246
+ GetX509Req(self, req);
247
+ if (!X509_REQ_set_version(req, ver)) {
248
+ ossl_raise(eX509ReqError, NULL);
249
+ }
250
+
251
+ return version;
252
+ }
253
+
254
+ static VALUE
255
+ ossl_x509req_get_subject(VALUE self)
256
+ {
257
+ X509_REQ *req;
258
+ X509_NAME *name;
259
+
260
+ GetX509Req(self, req);
261
+ if (!(name = X509_REQ_get_subject_name(req))) { /* NO DUP - don't free */
262
+ ossl_raise(eX509ReqError, NULL);
263
+ }
264
+
265
+ return ossl_x509name_new(name);
266
+ }
267
+
268
+ static VALUE
269
+ ossl_x509req_set_subject(VALUE self, VALUE subject)
270
+ {
271
+ X509_REQ *req;
272
+
273
+ GetX509Req(self, req);
274
+ /* DUPs name */
275
+ if (!X509_REQ_set_subject_name(req, GetX509NamePtr(subject))) {
276
+ ossl_raise(eX509ReqError, NULL);
277
+ }
278
+
279
+ return subject;
280
+ }
281
+
282
+ static VALUE
283
+ ossl_x509req_get_signature_algorithm(VALUE self)
284
+ {
285
+ X509_REQ *req;
286
+ BIO *out;
287
+ BUF_MEM *buf;
288
+ VALUE str;
289
+
290
+ GetX509Req(self, req);
291
+
292
+ if (!(out = BIO_new(BIO_s_mem()))) {
293
+ ossl_raise(eX509ReqError, NULL);
294
+ }
295
+ if (!i2a_ASN1_OBJECT(out, req->sig_alg->algorithm)) {
296
+ BIO_free(out);
297
+ ossl_raise(eX509ReqError, NULL);
298
+ }
299
+ BIO_get_mem_ptr(out, &buf);
300
+ str = rb_str_new(buf->data, buf->length);
301
+ BIO_free(out);
302
+ return str;
303
+ }
304
+
305
+ static VALUE
306
+ ossl_x509req_get_public_key(VALUE self)
307
+ {
308
+ X509_REQ *req;
309
+ EVP_PKEY *pkey;
310
+
311
+ GetX509Req(self, req);
312
+ if (!(pkey = X509_REQ_get_pubkey(req))) { /* adds reference */
313
+ ossl_raise(eX509ReqError, NULL);
314
+ }
315
+
316
+ return ossl_pkey_new(pkey); /* NO DUP - OK */
317
+ }
318
+
319
+ static VALUE
320
+ ossl_x509req_set_public_key(VALUE self, VALUE key)
321
+ {
322
+ X509_REQ *req;
323
+ EVP_PKEY *pkey;
324
+
325
+ GetX509Req(self, req);
326
+ pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
327
+ if (!X509_REQ_set_pubkey(req, pkey)) {
328
+ ossl_raise(eX509ReqError, NULL);
329
+ }
330
+
331
+ return key;
332
+ }
333
+
334
+ static VALUE
335
+ ossl_x509req_sign(VALUE self, VALUE key, VALUE digest)
336
+ {
337
+ X509_REQ *req;
338
+ EVP_PKEY *pkey;
339
+ const EVP_MD *md;
340
+
341
+ GetX509Req(self, req);
342
+ pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
343
+ md = GetDigestPtr(digest);
344
+ if (!X509_REQ_sign(req, pkey, md)) {
345
+ ossl_raise(eX509ReqError, NULL);
346
+ }
347
+
348
+ return self;
349
+ }
350
+
351
+ /*
352
+ * Checks that cert signature is made with PRIVversion of this PUBLIC 'key'
353
+ */
354
+ static VALUE
355
+ ossl_x509req_verify(VALUE self, VALUE key)
356
+ {
357
+ X509_REQ *req;
358
+ EVP_PKEY *pkey;
359
+ int i;
360
+
361
+ GetX509Req(self, req);
362
+ pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
363
+ if ((i = X509_REQ_verify(req, pkey)) < 0) {
364
+ ossl_raise(eX509ReqError, NULL);
365
+ }
366
+ if (i > 0) {
367
+ return Qtrue;
368
+ }
369
+
370
+ return Qfalse;
371
+ }
372
+
373
+ static VALUE
374
+ ossl_x509req_get_attributes(VALUE self)
375
+ {
376
+ X509_REQ *req;
377
+ int count, i;
378
+ X509_ATTRIBUTE *attr;
379
+ VALUE ary;
380
+
381
+ GetX509Req(self, req);
382
+
383
+ count = X509_REQ_get_attr_count(req);
384
+ if (count < 0) {
385
+ OSSL_Debug("count < 0???");
386
+ return rb_ary_new();
387
+ }
388
+ ary = rb_ary_new2(count);
389
+ for (i=0; i<count; i++) {
390
+ attr = X509_REQ_get_attr(req, i);
391
+ rb_ary_push(ary, ossl_x509attr_new(attr));
392
+ }
393
+
394
+ return ary;
395
+ }
396
+
397
+ static VALUE
398
+ ossl_x509req_set_attributes(VALUE self, VALUE ary)
399
+ {
400
+ X509_REQ *req;
401
+ X509_ATTRIBUTE *attr;
402
+ int i;
403
+ VALUE item;
404
+
405
+ Check_Type(ary, T_ARRAY);
406
+ for (i=0;i<RARRAY_LEN(ary); i++) {
407
+ OSSL_Check_Kind(rb_ary_entry(ary, i), cX509Attr);
408
+ }
409
+ GetX509Req(self, req);
410
+ sk_X509_ATTRIBUTE_pop_free(req->req_info->attributes, X509_ATTRIBUTE_free);
411
+ req->req_info->attributes = NULL;
412
+ for (i=0;i<RARRAY_LEN(ary); i++) {
413
+ item = rb_ary_entry(ary, i);
414
+ attr = DupX509AttrPtr(item);
415
+ if (!X509_REQ_add1_attr(req, attr)) {
416
+ ossl_raise(eX509ReqError, NULL);
417
+ }
418
+ }
419
+ return ary;
420
+ }
421
+
422
+ static VALUE
423
+ ossl_x509req_add_attribute(VALUE self, VALUE attr)
424
+ {
425
+ X509_REQ *req;
426
+
427
+ GetX509Req(self, req);
428
+ if (!X509_REQ_add1_attr(req, DupX509AttrPtr(attr))) {
429
+ ossl_raise(eX509ReqError, NULL);
430
+ }
431
+
432
+ return attr;
433
+ }
434
+
435
+ /*
436
+ * X509_REQUEST init
437
+ */
438
+ void
439
+ Init_ossl_x509req()
440
+ {
441
+ eX509ReqError = rb_define_class_under(mX509, "RequestError", eOSSLError);
442
+
443
+ cX509Req = rb_define_class_under(mX509, "Request", rb_cObject);
444
+
445
+ rb_define_alloc_func(cX509Req, ossl_x509req_alloc);
446
+ rb_define_method(cX509Req, "initialize", ossl_x509req_initialize, -1);
447
+ rb_define_copy_func(cX509Req, ossl_x509req_copy);
448
+
449
+ rb_define_method(cX509Req, "to_pem", ossl_x509req_to_pem, 0);
450
+ rb_define_method(cX509Req, "to_der", ossl_x509req_to_der, 0);
451
+ rb_define_alias(cX509Req, "to_s", "to_pem");
452
+ rb_define_method(cX509Req, "to_text", ossl_x509req_to_text, 0);
453
+ rb_define_method(cX509Req, "version", ossl_x509req_get_version, 0);
454
+ rb_define_method(cX509Req, "version=", ossl_x509req_set_version, 1);
455
+ rb_define_method(cX509Req, "subject", ossl_x509req_get_subject, 0);
456
+ rb_define_method(cX509Req, "subject=", ossl_x509req_set_subject, 1);
457
+ rb_define_method(cX509Req, "signature_algorithm", ossl_x509req_get_signature_algorithm, 0);
458
+ rb_define_method(cX509Req, "public_key", ossl_x509req_get_public_key, 0);
459
+ rb_define_method(cX509Req, "public_key=", ossl_x509req_set_public_key, 1);
460
+ rb_define_method(cX509Req, "sign", ossl_x509req_sign, 2);
461
+ rb_define_method(cX509Req, "verify", ossl_x509req_verify, 1);
462
+ rb_define_method(cX509Req, "attributes", ossl_x509req_get_attributes, 0);
463
+ rb_define_method(cX509Req, "attributes=", ossl_x509req_set_attributes, 1);
464
+ rb_define_method(cX509Req, "add_attribute", ossl_x509req_add_attribute, 1);
465
+ }
466
+