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,21 @@
1
+ /*
2
+ * $Id: ossl_ns_spki.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_NS_SPKI_H_)
12
+ #define _OSSL_NS_SPKI_H_
13
+
14
+ extern VALUE mNetscape;
15
+ extern VALUE cSPKI;
16
+ extern VALUE eSPKIError;
17
+
18
+ void Init_ossl_ns_spki(void);
19
+
20
+ #endif /* _OSSL_NS_SPKI_H_ */
21
+
@@ -0,0 +1,769 @@
1
+ /*
2
+ * $Id$
3
+ * 'OpenSSL for Ruby' project
4
+ * Copyright (C) 2003 Michal Rokos <m.rokos@sh.cvut.cz>
5
+ * Copyright (C) 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
6
+ * All rights reserved.
7
+ */
8
+ /*
9
+ * This program is licenced under the same licence as Ruby.
10
+ * (See the file 'LICENCE'.)
11
+ */
12
+ #include "ossl.h"
13
+
14
+ #if defined(OSSL_OCSP_ENABLED)
15
+
16
+ #define WrapOCSPReq(klass, obj, req) do { \
17
+ if(!req) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \
18
+ obj = Data_Wrap_Struct(klass, 0, OCSP_REQUEST_free, req); \
19
+ } while (0)
20
+ #define GetOCSPReq(obj, req) do { \
21
+ Data_Get_Struct(obj, OCSP_REQUEST, req); \
22
+ if(!req) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \
23
+ } while (0)
24
+ #define SafeGetOCSPReq(obj, req) do { \
25
+ OSSL_Check_Kind(obj, cOCSPReq); \
26
+ GetOCSPReq(obj, req); \
27
+ } while (0)
28
+
29
+ #define WrapOCSPRes(klass, obj, res) do { \
30
+ if(!res) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
31
+ obj = Data_Wrap_Struct(klass, 0, OCSP_RESPONSE_free, res); \
32
+ } while (0)
33
+ #define GetOCSPRes(obj, res) do { \
34
+ Data_Get_Struct(obj, OCSP_RESPONSE, res); \
35
+ if(!res) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
36
+ } while (0)
37
+ #define SafeGetOCSPRes(obj, res) do { \
38
+ OSSL_Check_Kind(obj, cOCSPRes); \
39
+ GetOCSPRes(obj, res); \
40
+ } while (0)
41
+
42
+ #define WrapOCSPBasicRes(klass, obj, res) do { \
43
+ if(!res) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
44
+ obj = Data_Wrap_Struct(klass, 0, OCSP_BASICRESP_free, res); \
45
+ } while (0)
46
+ #define GetOCSPBasicRes(obj, res) do { \
47
+ Data_Get_Struct(obj, OCSP_BASICRESP, res); \
48
+ if(!res) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
49
+ } while (0)
50
+ #define SafeGetOCSPBasicRes(obj, res) do { \
51
+ OSSL_Check_Kind(obj, cOCSPBasicRes); \
52
+ GetOCSPBasicRes(obj, res); \
53
+ } while (0)
54
+
55
+ #define WrapOCSPCertId(klass, obj, cid) do { \
56
+ if(!cid) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \
57
+ obj = Data_Wrap_Struct(klass, 0, OCSP_CERTID_free, cid); \
58
+ } while (0)
59
+ #define GetOCSPCertId(obj, cid) do { \
60
+ Data_Get_Struct(obj, OCSP_CERTID, cid); \
61
+ if(!cid) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \
62
+ } while (0)
63
+ #define SafeGetOCSPCertId(obj, cid) do { \
64
+ OSSL_Check_Kind(obj, cOCSPCertId); \
65
+ GetOCSPCertId(obj, cid); \
66
+ } while (0)
67
+
68
+ VALUE mOCSP;
69
+ VALUE eOCSPError;
70
+ VALUE cOCSPReq;
71
+ VALUE cOCSPRes;
72
+ VALUE cOCSPBasicRes;
73
+ VALUE cOCSPCertId;
74
+
75
+ /*
76
+ * Public
77
+ */
78
+ static VALUE
79
+ ossl_ocspcertid_new(OCSP_CERTID *cid)
80
+ {
81
+ VALUE obj;
82
+ WrapOCSPCertId(cOCSPCertId, obj, cid);
83
+ return obj;
84
+ }
85
+
86
+ /*
87
+ * OCSP::Resquest
88
+ */
89
+ static VALUE
90
+ ossl_ocspreq_alloc(VALUE klass)
91
+ {
92
+ OCSP_REQUEST *req;
93
+ VALUE obj;
94
+
95
+ if (!(req = OCSP_REQUEST_new()))
96
+ ossl_raise(eOCSPError, NULL);
97
+ WrapOCSPReq(klass, obj, req);
98
+
99
+ return obj;
100
+ }
101
+
102
+ static VALUE
103
+ ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self)
104
+ {
105
+ VALUE arg;
106
+ const unsigned char *p;
107
+
108
+ rb_scan_args(argc, argv, "01", &arg);
109
+ if(!NIL_P(arg)){
110
+ arg = ossl_to_der_if_possible(arg);
111
+ StringValue(arg);
112
+ p = (const unsigned char*)RSTRING_PTR(arg);
113
+ if(!d2i_OCSP_REQUEST((OCSP_REQUEST**)&DATA_PTR(self), &p,
114
+ RSTRING_LEN(arg))){
115
+ ossl_raise(eOCSPError, "cannot load DER encoded request");
116
+ }
117
+ }
118
+
119
+ return self;
120
+ }
121
+
122
+ static VALUE
123
+ ossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self)
124
+ {
125
+ OCSP_REQUEST *req;
126
+ VALUE val;
127
+ int ret;
128
+
129
+ rb_scan_args(argc, argv, "01", &val);
130
+ if(NIL_P(val)) {
131
+ GetOCSPReq(self, req);
132
+ ret = OCSP_request_add1_nonce(req, NULL, -1);
133
+ }
134
+ else{
135
+ StringValue(val);
136
+ GetOCSPReq(self, req);
137
+ ret = OCSP_request_add1_nonce(req, RSTRING_PTR(val), RSTRING_LEN(val));
138
+ }
139
+ if(!ret) ossl_raise(eOCSPError, NULL);
140
+
141
+ return self;
142
+ }
143
+
144
+ /* Check nonce validity in a request and response.
145
+ * Return value reflects result:
146
+ * 1: nonces present and equal.
147
+ * 2: nonces both absent.
148
+ * 3: nonce present in response only.
149
+ * 0: nonces both present and not equal.
150
+ * -1: nonce in request only.
151
+ *
152
+ * For most responders clients can check return > 0.
153
+ * If responder doesn't handle nonces return != 0 may be
154
+ * necessary. return == 0 is always an error.
155
+ */
156
+ static VALUE
157
+ ossl_ocspreq_check_nonce(VALUE self, VALUE basic_resp)
158
+ {
159
+ OCSP_REQUEST *req;
160
+ OCSP_BASICRESP *bs;
161
+ int res;
162
+
163
+ GetOCSPReq(self, req);
164
+ SafeGetOCSPBasicRes(basic_resp, bs);
165
+ res = OCSP_check_nonce(req, bs);
166
+
167
+ return INT2NUM(res);
168
+ }
169
+
170
+ static VALUE
171
+ ossl_ocspreq_add_certid(VALUE self, VALUE certid)
172
+ {
173
+ OCSP_REQUEST *req;
174
+ OCSP_CERTID *id;
175
+
176
+ GetOCSPReq(self, req);
177
+ GetOCSPCertId(certid, id);
178
+ if(!OCSP_request_add0_id(req, OCSP_CERTID_dup(id)))
179
+ ossl_raise(eOCSPError, NULL);
180
+
181
+ return self;
182
+ }
183
+
184
+ static VALUE
185
+ ossl_ocspreq_get_certid(VALUE self)
186
+ {
187
+ OCSP_REQUEST *req;
188
+ OCSP_ONEREQ *one;
189
+ OCSP_CERTID *id;
190
+ VALUE ary, tmp;
191
+ int i, count;
192
+
193
+ GetOCSPReq(self, req);
194
+ count = OCSP_request_onereq_count(req);
195
+ ary = (count > 0) ? rb_ary_new() : Qnil;
196
+ for(i = 0; i < count; i++){
197
+ one = OCSP_request_onereq_get0(req, i);
198
+ if(!(id = OCSP_CERTID_dup(OCSP_onereq_get0_id(one))))
199
+ ossl_raise(eOCSPError, NULL);
200
+ WrapOCSPCertId(cOCSPCertId, tmp, id);
201
+ rb_ary_push(ary, tmp);
202
+ }
203
+
204
+ return ary;
205
+ }
206
+
207
+ static VALUE
208
+ ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
209
+ {
210
+ VALUE signer_cert, signer_key, certs, flags;
211
+ OCSP_REQUEST *req;
212
+ X509 *signer;
213
+ EVP_PKEY *key;
214
+ STACK_OF(X509) *x509s;
215
+ unsigned long flg;
216
+ int ret;
217
+
218
+ rb_scan_args(argc, argv, "22", &signer_cert, &signer_key, &certs, &flags);
219
+ signer = GetX509CertPtr(signer_cert);
220
+ key = GetPrivPKeyPtr(signer_key);
221
+ flg = NIL_P(flags) ? 0 : NUM2INT(flags);
222
+ if(NIL_P(certs)){
223
+ x509s = sk_X509_new_null();
224
+ flags |= OCSP_NOCERTS;
225
+ }
226
+ else x509s = ossl_x509_ary2sk(certs);
227
+ GetOCSPReq(self, req);
228
+ ret = OCSP_request_sign(req, signer, key, EVP_sha1(), x509s, flg);
229
+ sk_X509_pop_free(x509s, X509_free);
230
+ if(!ret) ossl_raise(eOCSPError, NULL);
231
+
232
+ return self;
233
+ }
234
+
235
+ static VALUE
236
+ ossl_ocspreq_verify(int argc, VALUE *argv, VALUE self)
237
+ {
238
+ VALUE certs, store, flags;
239
+ OCSP_REQUEST *req;
240
+ STACK_OF(X509) *x509s;
241
+ X509_STORE *x509st;
242
+ int flg, result;
243
+
244
+ rb_scan_args(argc, argv, "21", &certs, &store, &flags);
245
+ x509st = GetX509StorePtr(store);
246
+ flg = NIL_P(flags) ? 0 : INT2NUM(flags);
247
+ x509s = ossl_x509_ary2sk(certs);
248
+ GetOCSPReq(self, req);
249
+ result = OCSP_request_verify(req, x509s, x509st, flg);
250
+ sk_X509_pop_free(x509s, X509_free);
251
+ if(!result) rb_warn("%s", ERR_error_string(ERR_peek_error(), NULL));
252
+
253
+ return result ? Qtrue : Qfalse;
254
+ }
255
+
256
+ static VALUE
257
+ ossl_ocspreq_to_der(VALUE self)
258
+ {
259
+ OCSP_REQUEST *req;
260
+ VALUE str;
261
+ unsigned char *p;
262
+ long len;
263
+
264
+ GetOCSPReq(self, req);
265
+ if((len = i2d_OCSP_REQUEST(req, NULL)) <= 0)
266
+ ossl_raise(eOCSPError, NULL);
267
+ str = rb_str_new(0, len);
268
+ p = RSTRING_PTR(str);
269
+ if(i2d_OCSP_REQUEST(req, &p) <= 0)
270
+ ossl_raise(eOCSPError, NULL);
271
+ ossl_str_adjust(str, p);
272
+
273
+ return str;
274
+ }
275
+
276
+ /*
277
+ * OCSP::Response
278
+ */
279
+ static VALUE
280
+ ossl_ocspres_s_create(VALUE klass, VALUE status, VALUE basic_resp)
281
+ {
282
+ OCSP_BASICRESP *bs;
283
+ OCSP_RESPONSE *res;
284
+ VALUE obj;
285
+ int st = NUM2INT(status);
286
+
287
+ if(NIL_P(basic_resp)) bs = NULL;
288
+ else GetOCSPBasicRes(basic_resp, bs); /* NO NEED TO DUP */
289
+ if(!(res = OCSP_response_create(st, bs)))
290
+ ossl_raise(eOCSPError, NULL);
291
+ WrapOCSPRes(klass, obj, res);
292
+
293
+ return obj;
294
+ }
295
+
296
+ static VALUE
297
+ ossl_ocspres_alloc(VALUE klass)
298
+ {
299
+ OCSP_RESPONSE *res;
300
+ VALUE obj;
301
+
302
+ if(!(res = OCSP_RESPONSE_new()))
303
+ ossl_raise(eOCSPError, NULL);
304
+ WrapOCSPRes(klass, obj, res);
305
+
306
+ return obj;
307
+ }
308
+
309
+ static VALUE
310
+ ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self)
311
+ {
312
+ VALUE arg;
313
+ const unsigned char *p;
314
+
315
+ rb_scan_args(argc, argv, "01", &arg);
316
+ if(!NIL_P(arg)){
317
+ arg = ossl_to_der_if_possible(arg);
318
+ StringValue(arg);
319
+ p = (const unsigned char*) RSTRING_PTR(arg);
320
+ if(!d2i_OCSP_RESPONSE((OCSP_RESPONSE**)&DATA_PTR(self), &p,
321
+ RSTRING_LEN(arg))){
322
+ ossl_raise(eOCSPError, "cannot load DER encoded response");
323
+ }
324
+ }
325
+
326
+ return self;
327
+ }
328
+
329
+ static VALUE
330
+ ossl_ocspres_status(VALUE self)
331
+ {
332
+ OCSP_RESPONSE *res;
333
+ int st;
334
+
335
+ GetOCSPRes(self, res);
336
+ st = OCSP_response_status(res);
337
+
338
+ return INT2NUM(st);
339
+ }
340
+
341
+ static VALUE
342
+ ossl_ocspres_status_string(VALUE self)
343
+ {
344
+ OCSP_RESPONSE *res;
345
+ int st;
346
+
347
+ GetOCSPRes(self, res);
348
+ st = OCSP_response_status(res);
349
+
350
+ return rb_str_new2(OCSP_response_status_str(st));
351
+ }
352
+
353
+ static VALUE
354
+ ossl_ocspres_get_basic(VALUE self)
355
+ {
356
+ OCSP_RESPONSE *res;
357
+ OCSP_BASICRESP *bs;
358
+ VALUE ret;
359
+
360
+ GetOCSPRes(self, res);
361
+ if(!(bs = OCSP_response_get1_basic(res)))
362
+ return Qnil;
363
+ WrapOCSPBasicRes(cOCSPBasicRes, ret, bs);
364
+
365
+ return ret;
366
+ }
367
+
368
+ static VALUE
369
+ ossl_ocspres_to_der(VALUE self)
370
+ {
371
+ OCSP_RESPONSE *res;
372
+ VALUE str;
373
+ long len;
374
+ unsigned char *p;
375
+
376
+ GetOCSPRes(self, res);
377
+ if((len = i2d_OCSP_RESPONSE(res, NULL)) <= 0)
378
+ ossl_raise(eOCSPError, NULL);
379
+ str = rb_str_new(0, len);
380
+ p = RSTRING_PTR(str);
381
+ if(i2d_OCSP_RESPONSE(res, &p) <= 0)
382
+ ossl_raise(eOCSPError, NULL);
383
+ ossl_str_adjust(str, p);
384
+
385
+ return str;
386
+ }
387
+
388
+ /*
389
+ * OCSP::BasicResponse
390
+ */
391
+ static VALUE
392
+ ossl_ocspbres_alloc(VALUE klass)
393
+ {
394
+ OCSP_BASICRESP *bs;
395
+ VALUE obj;
396
+
397
+ if(!(bs = OCSP_BASICRESP_new()))
398
+ ossl_raise(eOCSPError, NULL);
399
+ WrapOCSPBasicRes(klass, obj, bs);
400
+
401
+ return obj;
402
+ }
403
+
404
+ static VALUE
405
+ ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self)
406
+ {
407
+ return self;
408
+ }
409
+
410
+ static VALUE
411
+ ossl_ocspbres_copy_nonce(VALUE self, VALUE request)
412
+ {
413
+ OCSP_BASICRESP *bs;
414
+ OCSP_REQUEST *req;
415
+ int ret;
416
+
417
+ GetOCSPBasicRes(self, bs);
418
+ SafeGetOCSPReq(request, req);
419
+ ret = OCSP_copy_nonce(bs, req);
420
+
421
+ return INT2NUM(ret);
422
+ }
423
+
424
+ static VALUE
425
+ ossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self)
426
+ {
427
+ OCSP_BASICRESP *bs;
428
+ VALUE val;
429
+ int ret;
430
+
431
+ rb_scan_args(argc, argv, "01", &val);
432
+ if(NIL_P(val)) {
433
+ GetOCSPBasicRes(self, bs);
434
+ ret = OCSP_basic_add1_nonce(bs, NULL, -1);
435
+ }
436
+ else{
437
+ StringValue(val);
438
+ GetOCSPBasicRes(self, bs);
439
+ ret = OCSP_basic_add1_nonce(bs, RSTRING_PTR(val), RSTRING_LEN(val));
440
+ }
441
+ if(!ret) ossl_raise(eOCSPError, NULL);
442
+
443
+ return self;
444
+ }
445
+
446
+ static VALUE
447
+ ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
448
+ VALUE reason, VALUE revtime,
449
+ VALUE thisupd, VALUE nextupd, VALUE ext)
450
+ {
451
+ OCSP_BASICRESP *bs;
452
+ OCSP_SINGLERESP *single;
453
+ OCSP_CERTID *id;
454
+ int st, rsn;
455
+ ASN1_TIME *ths, *nxt, *rev;
456
+ int error, i, rstatus = 0;
457
+ VALUE tmp;
458
+
459
+ st = NUM2INT(status);
460
+ rsn = NIL_P(status) ? 0 : NUM2INT(reason);
461
+ if(!NIL_P(ext)){
462
+ /* All ary's members should be X509Extension */
463
+ Check_Type(ext, T_ARRAY);
464
+ for (i = 0; i < RARRAY_LEN(ext); i++)
465
+ OSSL_Check_Kind(rb_ary_entry(ext, i), cX509Ext);
466
+ }
467
+
468
+ error = 0;
469
+ ths = nxt = rev = NULL;
470
+ if(!NIL_P(revtime)){
471
+ tmp = rb_protect(rb_Integer, revtime, &rstatus);
472
+ if(rstatus) goto err;
473
+ rev = X509_gmtime_adj(NULL, NUM2INT(tmp));
474
+ }
475
+ tmp = rb_protect(rb_Integer, thisupd, &rstatus);
476
+ if(rstatus) goto err;
477
+ ths = X509_gmtime_adj(NULL, NUM2INT(tmp));
478
+ tmp = rb_protect(rb_Integer, nextupd, &rstatus);
479
+ if(rstatus) goto err;
480
+ nxt = X509_gmtime_adj(NULL, NUM2INT(tmp));
481
+
482
+ GetOCSPBasicRes(self, bs);
483
+ SafeGetOCSPCertId(cid, id);
484
+ if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){
485
+ error = 1;
486
+ goto err;
487
+ }
488
+
489
+ if(!NIL_P(ext)){
490
+ X509_EXTENSION *x509ext;
491
+ sk_X509_EXTENSION_pop_free(single->singleExtensions, X509_EXTENSION_free);
492
+ single->singleExtensions = NULL;
493
+ for(i = 0; i < RARRAY_LEN(ext); i++){
494
+ x509ext = DupX509ExtPtr(rb_ary_entry(ext, i));
495
+ if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){
496
+ X509_EXTENSION_free(x509ext);
497
+ error = 1;
498
+ goto err;
499
+ }
500
+ X509_EXTENSION_free(x509ext);
501
+ }
502
+ }
503
+
504
+ err:
505
+ ASN1_TIME_free(ths);
506
+ ASN1_TIME_free(nxt);
507
+ ASN1_TIME_free(rev);
508
+ if(error) ossl_raise(eOCSPError, NULL);
509
+ if(rstatus) rb_jump_tag(rstatus);
510
+
511
+ return self;
512
+ }
513
+
514
+ static VALUE
515
+ ossl_ocspbres_get_status(VALUE self)
516
+ {
517
+ OCSP_BASICRESP *bs;
518
+ OCSP_SINGLERESP *single;
519
+ OCSP_CERTID *cid;
520
+ ASN1_TIME *revtime, *thisupd, *nextupd;
521
+ int status, reason;
522
+ X509_EXTENSION *x509ext;
523
+ VALUE ret, ary, ext;
524
+ int count, ext_count, i, j;
525
+
526
+ GetOCSPBasicRes(self, bs);
527
+ ret = rb_ary_new();
528
+ count = OCSP_resp_count(bs);
529
+ for(i = 0; i < count; i++){
530
+ single = OCSP_resp_get0(bs, i);
531
+ if(!single) continue;
532
+
533
+ revtime = thisupd = nextupd = NULL;
534
+ status = OCSP_single_get0_status(single, &reason, &revtime,
535
+ &thisupd, &nextupd);
536
+ if(status < 0) continue;
537
+ if(!(cid = OCSP_CERTID_dup(single->certId)))
538
+ ossl_raise(eOCSPError, NULL);
539
+ ary = rb_ary_new();
540
+ rb_ary_push(ary, ossl_ocspcertid_new(cid));
541
+ rb_ary_push(ary, INT2NUM(status));
542
+ rb_ary_push(ary, INT2NUM(reason));
543
+ rb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil);
544
+ rb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil);
545
+ rb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil);
546
+ ext = rb_ary_new();
547
+ ext_count = OCSP_SINGLERESP_get_ext_count(single);
548
+ for(j = 0; j < ext_count; j++){
549
+ x509ext = OCSP_SINGLERESP_get_ext(single, j);
550
+ rb_ary_push(ext, ossl_x509ext_new(x509ext));
551
+ }
552
+ rb_ary_push(ary, ext);
553
+ rb_ary_push(ret, ary);
554
+ }
555
+
556
+ return ret;
557
+ }
558
+
559
+ static VALUE
560
+ ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
561
+ {
562
+ VALUE signer_cert, signer_key, certs, flags;
563
+ OCSP_BASICRESP *bs;
564
+ X509 *signer;
565
+ EVP_PKEY *key;
566
+ STACK_OF(X509) *x509s;
567
+ unsigned long flg;
568
+ int ret;
569
+
570
+ rb_scan_args(argc, argv, "22", &signer_cert, &signer_key, &certs, &flags);
571
+ signer = GetX509CertPtr(signer_cert);
572
+ key = GetPrivPKeyPtr(signer_key);
573
+ flg = NIL_P(flags) ? 0 : NUM2INT(flags);
574
+ if(NIL_P(certs)){
575
+ x509s = sk_X509_new_null();
576
+ flg |= OCSP_NOCERTS;
577
+ }
578
+ else{
579
+ x509s = ossl_x509_ary2sk(certs);
580
+ }
581
+ GetOCSPBasicRes(self, bs);
582
+ ret = OCSP_basic_sign(bs, signer, key, EVP_sha1(), x509s, flg);
583
+ sk_X509_pop_free(x509s, X509_free);
584
+ if(!ret) ossl_raise(eOCSPError, NULL);
585
+
586
+ return self;
587
+ }
588
+
589
+ static VALUE
590
+ ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self)
591
+ {
592
+ VALUE certs, store, flags, result;
593
+ OCSP_BASICRESP *bs;
594
+ STACK_OF(X509) *x509s;
595
+ X509_STORE *x509st;
596
+ int flg;
597
+
598
+ rb_scan_args(argc, argv, "21", &certs, &store, &flags);
599
+ x509st = GetX509StorePtr(store);
600
+ flg = NIL_P(flags) ? 0 : INT2NUM(flags);
601
+ x509s = ossl_x509_ary2sk(certs);
602
+ GetOCSPBasicRes(self, bs);
603
+ result = OCSP_basic_verify(bs, x509s, x509st, flg) > 0 ? Qtrue : Qfalse;
604
+ sk_X509_pop_free(x509s, X509_free);
605
+ if(!result) rb_warn("%s", ERR_error_string(ERR_peek_error(), NULL));
606
+
607
+ return result;
608
+ }
609
+
610
+ /*
611
+ * OCSP::CertificateId
612
+ */
613
+ static VALUE
614
+ ossl_ocspcid_alloc(VALUE klass)
615
+ {
616
+ OCSP_CERTID *id;
617
+ VALUE obj;
618
+
619
+ if(!(id = OCSP_CERTID_new()))
620
+ ossl_raise(eOCSPError, NULL);
621
+ WrapOCSPCertId(klass, obj, id);
622
+
623
+ return obj;
624
+ }
625
+
626
+ static VALUE
627
+ ossl_ocspcid_initialize(VALUE self, VALUE subject, VALUE issuer)
628
+ {
629
+ OCSP_CERTID *id, *newid;
630
+ X509 *x509s, *x509i;
631
+
632
+ x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */
633
+ x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */
634
+ if(!(newid = OCSP_cert_to_id(NULL, x509s, x509i)))
635
+ ossl_raise(eOCSPError, NULL);
636
+ GetOCSPCertId(self, id);
637
+ OCSP_CERTID_free(id);
638
+ RDATA(self)->data = newid;
639
+
640
+ return self;
641
+ }
642
+
643
+ static VALUE
644
+ ossl_ocspcid_cmp(VALUE self, VALUE other)
645
+ {
646
+ OCSP_CERTID *id, *id2;
647
+ int result;
648
+
649
+ GetOCSPCertId(self, id);
650
+ SafeGetOCSPCertId(other, id2);
651
+ result = OCSP_id_cmp(id, id2);
652
+
653
+ return (result == 0) ? Qtrue : Qfalse;
654
+ }
655
+
656
+ static VALUE
657
+ ossl_ocspcid_cmp_issuer(VALUE self, VALUE other)
658
+ {
659
+ OCSP_CERTID *id, *id2;
660
+ int result;
661
+
662
+ GetOCSPCertId(self, id);
663
+ SafeGetOCSPCertId(other, id2);
664
+ result = OCSP_id_issuer_cmp(id, id2);
665
+
666
+ return (result == 0) ? Qtrue : Qfalse;
667
+ }
668
+
669
+ static VALUE
670
+ ossl_ocspcid_get_serial(VALUE self)
671
+ {
672
+ OCSP_CERTID *id;
673
+
674
+ GetOCSPCertId(self, id);
675
+
676
+ return asn1integer_to_num(id->serialNumber);
677
+ }
678
+
679
+ void
680
+ Init_ossl_ocsp()
681
+ {
682
+ mOCSP = rb_define_module_under(mOSSL, "OCSP");
683
+
684
+ eOCSPError = rb_define_class_under(mOCSP, "OCSPError", eOSSLError);
685
+
686
+ cOCSPReq = rb_define_class_under(mOCSP, "Request", rb_cObject);
687
+ rb_define_alloc_func(cOCSPReq, ossl_ocspreq_alloc);
688
+ rb_define_method(cOCSPReq, "initialize", ossl_ocspreq_initialize, -1);
689
+ rb_define_method(cOCSPReq, "add_nonce", ossl_ocspreq_add_nonce, -1);
690
+ rb_define_method(cOCSPReq, "check_nonce", ossl_ocspreq_check_nonce, 1);
691
+ rb_define_method(cOCSPReq, "add_certid", ossl_ocspreq_add_certid, 1);
692
+ rb_define_method(cOCSPReq, "certid", ossl_ocspreq_get_certid, 0);
693
+ rb_define_method(cOCSPReq, "sign", ossl_ocspreq_sign, -1);
694
+ rb_define_method(cOCSPReq, "verify", ossl_ocspreq_verify, -1);
695
+ rb_define_method(cOCSPReq, "to_der", ossl_ocspreq_to_der, 0);
696
+
697
+ cOCSPRes = rb_define_class_under(mOCSP, "Response", rb_cObject);
698
+ rb_define_singleton_method(cOCSPRes, "create", ossl_ocspres_s_create, 2);
699
+ rb_define_alloc_func(cOCSPRes, ossl_ocspres_alloc);
700
+ rb_define_method(cOCSPRes, "initialize", ossl_ocspres_initialize, -1);
701
+ rb_define_method(cOCSPRes, "status", ossl_ocspres_status, 0);
702
+ rb_define_method(cOCSPRes, "status_string", ossl_ocspres_status_string, 0);
703
+ rb_define_method(cOCSPRes, "basic", ossl_ocspres_get_basic, 0);
704
+ rb_define_method(cOCSPRes, "to_der", ossl_ocspres_to_der, 0);
705
+
706
+ cOCSPBasicRes = rb_define_class_under(mOCSP, "BasicResponse", rb_cObject);
707
+ rb_define_alloc_func(cOCSPBasicRes, ossl_ocspbres_alloc);
708
+ rb_define_method(cOCSPBasicRes, "initialize", ossl_ocspbres_initialize, -1);
709
+ rb_define_method(cOCSPBasicRes, "copy_nonce", ossl_ocspbres_copy_nonce, 1);
710
+ rb_define_method(cOCSPBasicRes, "add_nonce", ossl_ocspbres_add_nonce, -1);
711
+ rb_define_method(cOCSPBasicRes, "add_status", ossl_ocspbres_add_status, 7);
712
+ rb_define_method(cOCSPBasicRes, "status", ossl_ocspbres_get_status, 0);
713
+ rb_define_method(cOCSPBasicRes, "sign", ossl_ocspbres_sign, -1);
714
+ rb_define_method(cOCSPBasicRes, "verify", ossl_ocspbres_verify, -1);
715
+
716
+ cOCSPCertId = rb_define_class_under(mOCSP, "CertificateId", rb_cObject);
717
+ rb_define_alloc_func(cOCSPCertId, ossl_ocspcid_alloc);
718
+ rb_define_method(cOCSPCertId, "initialize", ossl_ocspcid_initialize, 2);
719
+ rb_define_method(cOCSPCertId, "cmp", ossl_ocspcid_cmp, 1);
720
+ rb_define_method(cOCSPCertId, "cmp_issuer", ossl_ocspcid_cmp_issuer, 1);
721
+ rb_define_method(cOCSPCertId, "serial", ossl_ocspcid_get_serial, 0);
722
+
723
+ #define DefOCSPConst(x) rb_define_const(mOCSP, #x, INT2NUM(OCSP_##x))
724
+
725
+ DefOCSPConst(RESPONSE_STATUS_SUCCESSFUL);
726
+ DefOCSPConst(RESPONSE_STATUS_MALFORMEDREQUEST);
727
+ DefOCSPConst(RESPONSE_STATUS_INTERNALERROR);
728
+ DefOCSPConst(RESPONSE_STATUS_TRYLATER);
729
+ DefOCSPConst(RESPONSE_STATUS_SIGREQUIRED);
730
+ DefOCSPConst(RESPONSE_STATUS_UNAUTHORIZED);
731
+
732
+ DefOCSPConst(REVOKED_STATUS_NOSTATUS);
733
+ DefOCSPConst(REVOKED_STATUS_UNSPECIFIED);
734
+ DefOCSPConst(REVOKED_STATUS_KEYCOMPROMISE);
735
+ DefOCSPConst(REVOKED_STATUS_CACOMPROMISE);
736
+ DefOCSPConst(REVOKED_STATUS_AFFILIATIONCHANGED);
737
+ DefOCSPConst(REVOKED_STATUS_SUPERSEDED);
738
+ DefOCSPConst(REVOKED_STATUS_CESSATIONOFOPERATION);
739
+ DefOCSPConst(REVOKED_STATUS_CERTIFICATEHOLD);
740
+ DefOCSPConst(REVOKED_STATUS_REMOVEFROMCRL);
741
+
742
+ DefOCSPConst(NOCERTS);
743
+ DefOCSPConst(NOINTERN);
744
+ DefOCSPConst(NOSIGS);
745
+ DefOCSPConst(NOCHAIN);
746
+ DefOCSPConst(NOVERIFY);
747
+ DefOCSPConst(NOEXPLICIT);
748
+ DefOCSPConst(NOCASIGN);
749
+ DefOCSPConst(NODELEGATED);
750
+ DefOCSPConst(NOCHECKS);
751
+ DefOCSPConst(TRUSTOTHER);
752
+ DefOCSPConst(RESPID_KEY);
753
+ DefOCSPConst(NOTIME);
754
+
755
+ #define DefOCSPVConst(x) rb_define_const(mOCSP, "V_" #x, INT2NUM(V_OCSP_##x))
756
+
757
+ DefOCSPVConst(CERTSTATUS_GOOD);
758
+ DefOCSPVConst(CERTSTATUS_REVOKED);
759
+ DefOCSPVConst(CERTSTATUS_UNKNOWN);
760
+ DefOCSPVConst(RESPID_NAME);
761
+ DefOCSPVConst(RESPID_KEY);
762
+ }
763
+
764
+ #else /* ! OSSL_OCSP_ENABLED */
765
+ void
766
+ Init_ossl_ocsp()
767
+ {
768
+ }
769
+ #endif