zig_example 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/ext/mkmf.rb +2734 -0
  3. data/ext/openssl/openssl_missing.c +40 -0
  4. data/ext/openssl/openssl_missing.h +238 -0
  5. data/ext/openssl/ossl.c +1295 -0
  6. data/ext/openssl/ossl.h +201 -0
  7. data/ext/openssl/ossl_asn1.c +1891 -0
  8. data/ext/openssl/ossl_asn1.h +62 -0
  9. data/ext/openssl/ossl_bio.c +42 -0
  10. data/ext/openssl/ossl_bio.h +16 -0
  11. data/ext/openssl/ossl_bn.c +1344 -0
  12. data/ext/openssl/ossl_bn.h +26 -0
  13. data/ext/openssl/ossl_cipher.c +1074 -0
  14. data/ext/openssl/ossl_cipher.h +20 -0
  15. data/ext/openssl/ossl_config.c +460 -0
  16. data/ext/openssl/ossl_config.h +16 -0
  17. data/ext/openssl/ossl_digest.c +425 -0
  18. data/ext/openssl/ossl_digest.h +20 -0
  19. data/ext/openssl/ossl_engine.c +568 -0
  20. data/ext/openssl/ossl_engine.h +19 -0
  21. data/ext/openssl/ossl_hmac.c +310 -0
  22. data/ext/openssl/ossl_hmac.h +18 -0
  23. data/ext/openssl/ossl_kdf.c +311 -0
  24. data/ext/openssl/ossl_kdf.h +6 -0
  25. data/ext/openssl/ossl_ns_spki.c +405 -0
  26. data/ext/openssl/ossl_ns_spki.h +19 -0
  27. data/ext/openssl/ossl_ocsp.c +1965 -0
  28. data/ext/openssl/ossl_ocsp.h +23 -0
  29. data/ext/openssl/ossl_pkcs12.c +275 -0
  30. data/ext/openssl/ossl_pkcs12.h +13 -0
  31. data/ext/openssl/ossl_pkcs7.c +1081 -0
  32. data/ext/openssl/ossl_pkcs7.h +36 -0
  33. data/ext/openssl/ossl_pkey.c +1624 -0
  34. data/ext/openssl/ossl_pkey.h +204 -0
  35. data/ext/openssl/ossl_pkey_dh.c +440 -0
  36. data/ext/openssl/ossl_pkey_dsa.c +359 -0
  37. data/ext/openssl/ossl_pkey_ec.c +1655 -0
  38. data/ext/openssl/ossl_pkey_rsa.c +579 -0
  39. data/ext/openssl/ossl_rand.c +200 -0
  40. data/ext/openssl/ossl_rand.h +18 -0
  41. data/ext/openssl/ossl_ssl.c +3142 -0
  42. data/ext/openssl/ossl_ssl.h +36 -0
  43. data/ext/openssl/ossl_ssl_session.c +331 -0
  44. data/ext/openssl/ossl_ts.c +1539 -0
  45. data/ext/openssl/ossl_ts.h +16 -0
  46. data/ext/openssl/ossl_x509.c +256 -0
  47. data/ext/openssl/ossl_x509.h +115 -0
  48. data/ext/openssl/ossl_x509attr.c +324 -0
  49. data/ext/openssl/ossl_x509cert.c +1002 -0
  50. data/ext/openssl/ossl_x509crl.c +545 -0
  51. data/ext/openssl/ossl_x509ext.c +490 -0
  52. data/ext/openssl/ossl_x509name.c +597 -0
  53. data/ext/openssl/ossl_x509req.c +444 -0
  54. data/ext/openssl/ossl_x509revoked.c +300 -0
  55. data/ext/openssl/ossl_x509store.c +986 -0
  56. data/ext/zigrb_100doors/build.zig +0 -12
  57. data/ext/zigrb_100doors/extconf.rb +2 -19
  58. data/ext/zigrb_ackermann/build.zig +0 -12
  59. data/ext/zigrb_ackermann/extconf.rb +2 -19
  60. data/ext/zigrb_lucas_lehmer/build.zig +53 -0
  61. data/ext/zigrb_lucas_lehmer/extconf.rb +3 -0
  62. data/ext/zigrb_lucas_lehmer/src/lucas_lehmer.c +60 -0
  63. data/ext/zigrb_lucas_lehmer/src/lucas_lehmer.h +1 -0
  64. data/ext/zigrb_lucas_lehmer/src/wrapper.zig +42 -0
  65. data/lib/zig_example/version.rb +1 -1
  66. data/lib/zig_example.rb +1 -0
  67. metadata +63 -3
@@ -0,0 +1,1965 @@
1
+ /*
2
+ * 'OpenSSL for Ruby' project
3
+ * Copyright (C) 2003 Michal Rokos <m.rokos@sh.cvut.cz>
4
+ * Copyright (C) 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
5
+ * All rights reserved.
6
+ */
7
+ /*
8
+ * This program is licensed under the same licence as Ruby.
9
+ * (See the file 'LICENCE'.)
10
+ */
11
+ #include "ossl.h"
12
+
13
+ #if !defined(OPENSSL_NO_OCSP)
14
+
15
+ #define NewOCSPReq(klass) \
16
+ TypedData_Wrap_Struct((klass), &ossl_ocsp_request_type, 0)
17
+ #define SetOCSPReq(obj, req) do { \
18
+ if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \
19
+ RTYPEDDATA_DATA(obj) = (req); \
20
+ } while (0)
21
+ #define GetOCSPReq(obj, req) do { \
22
+ TypedData_Get_Struct((obj), OCSP_REQUEST, &ossl_ocsp_request_type, (req)); \
23
+ if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \
24
+ } while (0)
25
+
26
+ #define NewOCSPRes(klass) \
27
+ TypedData_Wrap_Struct((klass), &ossl_ocsp_response_type, 0)
28
+ #define SetOCSPRes(obj, res) do { \
29
+ if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
30
+ RTYPEDDATA_DATA(obj) = (res); \
31
+ } while (0)
32
+ #define GetOCSPRes(obj, res) do { \
33
+ TypedData_Get_Struct((obj), OCSP_RESPONSE, &ossl_ocsp_response_type, (res)); \
34
+ if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
35
+ } while (0)
36
+
37
+ #define NewOCSPBasicRes(klass) \
38
+ TypedData_Wrap_Struct((klass), &ossl_ocsp_basicresp_type, 0)
39
+ #define SetOCSPBasicRes(obj, res) do { \
40
+ if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
41
+ RTYPEDDATA_DATA(obj) = (res); \
42
+ } while (0)
43
+ #define GetOCSPBasicRes(obj, res) do { \
44
+ TypedData_Get_Struct((obj), OCSP_BASICRESP, &ossl_ocsp_basicresp_type, (res)); \
45
+ if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
46
+ } while (0)
47
+
48
+ #define NewOCSPSingleRes(klass) \
49
+ TypedData_Wrap_Struct((klass), &ossl_ocsp_singleresp_type, 0)
50
+ #define SetOCSPSingleRes(obj, res) do { \
51
+ if(!(res)) ossl_raise(rb_eRuntimeError, "SingleResponse wasn't initialized!"); \
52
+ RTYPEDDATA_DATA(obj) = (res); \
53
+ } while (0)
54
+ #define GetOCSPSingleRes(obj, res) do { \
55
+ TypedData_Get_Struct((obj), OCSP_SINGLERESP, &ossl_ocsp_singleresp_type, (res)); \
56
+ if(!(res)) ossl_raise(rb_eRuntimeError, "SingleResponse wasn't initialized!"); \
57
+ } while (0)
58
+
59
+ #define NewOCSPCertId(klass) \
60
+ TypedData_Wrap_Struct((klass), &ossl_ocsp_certid_type, 0)
61
+ #define SetOCSPCertId(obj, cid) do { \
62
+ if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \
63
+ RTYPEDDATA_DATA(obj) = (cid); \
64
+ } while (0)
65
+ #define GetOCSPCertId(obj, cid) do { \
66
+ TypedData_Get_Struct((obj), OCSP_CERTID, &ossl_ocsp_certid_type, (cid)); \
67
+ if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \
68
+ } while (0)
69
+
70
+ VALUE mOCSP;
71
+ VALUE eOCSPError;
72
+ VALUE cOCSPReq;
73
+ VALUE cOCSPRes;
74
+ VALUE cOCSPBasicRes;
75
+ VALUE cOCSPSingleRes;
76
+ VALUE cOCSPCertId;
77
+
78
+ static void
79
+ ossl_ocsp_request_free(void *ptr)
80
+ {
81
+ OCSP_REQUEST_free(ptr);
82
+ }
83
+
84
+ static const rb_data_type_t ossl_ocsp_request_type = {
85
+ "OpenSSL/OCSP/REQUEST",
86
+ {
87
+ 0, ossl_ocsp_request_free,
88
+ },
89
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
90
+ };
91
+
92
+ static void
93
+ ossl_ocsp_response_free(void *ptr)
94
+ {
95
+ OCSP_RESPONSE_free(ptr);
96
+ }
97
+
98
+ static const rb_data_type_t ossl_ocsp_response_type = {
99
+ "OpenSSL/OCSP/RESPONSE",
100
+ {
101
+ 0, ossl_ocsp_response_free,
102
+ },
103
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
104
+ };
105
+
106
+ static void
107
+ ossl_ocsp_basicresp_free(void *ptr)
108
+ {
109
+ OCSP_BASICRESP_free(ptr);
110
+ }
111
+
112
+ static const rb_data_type_t ossl_ocsp_basicresp_type = {
113
+ "OpenSSL/OCSP/BASICRESP",
114
+ {
115
+ 0, ossl_ocsp_basicresp_free,
116
+ },
117
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
118
+ };
119
+
120
+ static void
121
+ ossl_ocsp_singleresp_free(void *ptr)
122
+ {
123
+ OCSP_SINGLERESP_free(ptr);
124
+ }
125
+
126
+ static const rb_data_type_t ossl_ocsp_singleresp_type = {
127
+ "OpenSSL/OCSP/SINGLERESP",
128
+ {
129
+ 0, ossl_ocsp_singleresp_free,
130
+ },
131
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
132
+ };
133
+
134
+ static void
135
+ ossl_ocsp_certid_free(void *ptr)
136
+ {
137
+ OCSP_CERTID_free(ptr);
138
+ }
139
+
140
+ static const rb_data_type_t ossl_ocsp_certid_type = {
141
+ "OpenSSL/OCSP/CERTID",
142
+ {
143
+ 0, ossl_ocsp_certid_free,
144
+ },
145
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
146
+ };
147
+
148
+ /*
149
+ * Public
150
+ */
151
+ static VALUE
152
+ ossl_ocspcertid_new(OCSP_CERTID *cid)
153
+ {
154
+ VALUE obj = NewOCSPCertId(cOCSPCertId);
155
+ SetOCSPCertId(obj, cid);
156
+ return obj;
157
+ }
158
+
159
+ /*
160
+ * OCSP::Request
161
+ */
162
+ static VALUE
163
+ ossl_ocspreq_alloc(VALUE klass)
164
+ {
165
+ OCSP_REQUEST *req;
166
+ VALUE obj;
167
+
168
+ obj = NewOCSPReq(klass);
169
+ if (!(req = OCSP_REQUEST_new()))
170
+ ossl_raise(eOCSPError, NULL);
171
+ SetOCSPReq(obj, req);
172
+
173
+ return obj;
174
+ }
175
+
176
+ static VALUE
177
+ ossl_ocspreq_initialize_copy(VALUE self, VALUE other)
178
+ {
179
+ OCSP_REQUEST *req, *req_old, *req_new;
180
+
181
+ rb_check_frozen(self);
182
+ GetOCSPReq(self, req_old);
183
+ GetOCSPReq(other, req);
184
+
185
+ req_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_REQUEST), req);
186
+ if (!req_new)
187
+ ossl_raise(eOCSPError, "ASN1_item_dup");
188
+
189
+ SetOCSPReq(self, req_new);
190
+ OCSP_REQUEST_free(req_old);
191
+
192
+ return self;
193
+ }
194
+
195
+ /*
196
+ * call-seq:
197
+ * OpenSSL::OCSP::Request.new -> request
198
+ * OpenSSL::OCSP::Request.new(request_der) -> request
199
+ *
200
+ * Creates a new OpenSSL::OCSP::Request. The request may be created empty or
201
+ * from a _request_der_ string.
202
+ */
203
+
204
+ static VALUE
205
+ ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self)
206
+ {
207
+ VALUE arg;
208
+ OCSP_REQUEST *req, *req_new;
209
+ const unsigned char *p;
210
+
211
+ rb_scan_args(argc, argv, "01", &arg);
212
+ if(!NIL_P(arg)){
213
+ GetOCSPReq(self, req);
214
+ arg = ossl_to_der_if_possible(arg);
215
+ StringValue(arg);
216
+ p = (unsigned char *)RSTRING_PTR(arg);
217
+ req_new = d2i_OCSP_REQUEST(NULL, &p, RSTRING_LEN(arg));
218
+ if (!req_new)
219
+ ossl_raise(eOCSPError, "d2i_OCSP_REQUEST");
220
+ SetOCSPReq(self, req_new);
221
+ OCSP_REQUEST_free(req);
222
+ }
223
+
224
+ return self;
225
+ }
226
+
227
+ /*
228
+ * call-seq:
229
+ * request.add_nonce(nonce = nil) -> request
230
+ *
231
+ * Adds a _nonce_ to the OCSP request. If no nonce is given a random one will
232
+ * be generated.
233
+ *
234
+ * The nonce is used to prevent replay attacks but some servers do not support
235
+ * it.
236
+ */
237
+
238
+ static VALUE
239
+ ossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self)
240
+ {
241
+ OCSP_REQUEST *req;
242
+ VALUE val;
243
+ int ret;
244
+
245
+ rb_scan_args(argc, argv, "01", &val);
246
+ if(NIL_P(val)) {
247
+ GetOCSPReq(self, req);
248
+ ret = OCSP_request_add1_nonce(req, NULL, -1);
249
+ }
250
+ else{
251
+ StringValue(val);
252
+ GetOCSPReq(self, req);
253
+ ret = OCSP_request_add1_nonce(req, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val));
254
+ }
255
+ if(!ret) ossl_raise(eOCSPError, NULL);
256
+
257
+ return self;
258
+ }
259
+
260
+ /*
261
+ * call-seq:
262
+ * request.check_nonce(response) -> result
263
+ *
264
+ * Checks the nonce validity for this request and _response_.
265
+ *
266
+ * The return value is one of the following:
267
+ *
268
+ * -1 :: nonce in request only.
269
+ * 0 :: nonces both present and not equal.
270
+ * 1 :: nonces present and equal.
271
+ * 2 :: nonces both absent.
272
+ * 3 :: nonce present in response only.
273
+ *
274
+ * For most responses, clients can check _result_ > 0. If a responder doesn't
275
+ * handle nonces <code>result.nonzero?</code> may be necessary. A result of
276
+ * <code>0</code> is always an error.
277
+ */
278
+
279
+ static VALUE
280
+ ossl_ocspreq_check_nonce(VALUE self, VALUE basic_resp)
281
+ {
282
+ OCSP_REQUEST *req;
283
+ OCSP_BASICRESP *bs;
284
+ int res;
285
+
286
+ GetOCSPReq(self, req);
287
+ GetOCSPBasicRes(basic_resp, bs);
288
+ res = OCSP_check_nonce(req, bs);
289
+
290
+ return INT2NUM(res);
291
+ }
292
+
293
+ /*
294
+ * call-seq:
295
+ * request.add_certid(certificate_id) -> request
296
+ *
297
+ * Adds _certificate_id_ to the request.
298
+ */
299
+
300
+ static VALUE
301
+ ossl_ocspreq_add_certid(VALUE self, VALUE certid)
302
+ {
303
+ OCSP_REQUEST *req;
304
+ OCSP_CERTID *id, *id_new;
305
+
306
+ GetOCSPReq(self, req);
307
+ GetOCSPCertId(certid, id);
308
+
309
+ if (!(id_new = OCSP_CERTID_dup(id)))
310
+ ossl_raise(eOCSPError, "OCSP_CERTID_dup");
311
+ if (!OCSP_request_add0_id(req, id_new)) {
312
+ OCSP_CERTID_free(id_new);
313
+ ossl_raise(eOCSPError, "OCSP_request_add0_id");
314
+ }
315
+
316
+ return self;
317
+ }
318
+
319
+ /*
320
+ * call-seq:
321
+ * request.certid -> [certificate_id, ...]
322
+ *
323
+ * Returns all certificate IDs in this request.
324
+ */
325
+
326
+ static VALUE
327
+ ossl_ocspreq_get_certid(VALUE self)
328
+ {
329
+ OCSP_REQUEST *req;
330
+ OCSP_ONEREQ *one;
331
+ OCSP_CERTID *id;
332
+ VALUE ary, tmp;
333
+ int i, count;
334
+
335
+ GetOCSPReq(self, req);
336
+ count = OCSP_request_onereq_count(req);
337
+ ary = (count > 0) ? rb_ary_new() : Qnil;
338
+ for(i = 0; i < count; i++){
339
+ one = OCSP_request_onereq_get0(req, i);
340
+ tmp = NewOCSPCertId(cOCSPCertId);
341
+ if(!(id = OCSP_CERTID_dup(OCSP_onereq_get0_id(one))))
342
+ ossl_raise(eOCSPError, NULL);
343
+ SetOCSPCertId(tmp, id);
344
+ rb_ary_push(ary, tmp);
345
+ }
346
+
347
+ return ary;
348
+ }
349
+
350
+ /*
351
+ * call-seq:
352
+ * request.sign(cert, key, certs = nil, flags = 0, digest = nil) -> self
353
+ *
354
+ * Signs this OCSP request using _cert_, _key_ and optional _digest_. If
355
+ * _digest_ is not specified, SHA-1 is used. _certs_ is an optional Array of
356
+ * additional certificates which are included in the request in addition to
357
+ * the signer certificate. Note that if _certs_ is +nil+ or not given, flag
358
+ * OpenSSL::OCSP::NOCERTS is enabled. Pass an empty array to include only the
359
+ * signer certificate.
360
+ *
361
+ * _flags_ is a bitwise OR of the following constants:
362
+ *
363
+ * OpenSSL::OCSP::NOCERTS::
364
+ * Don't include any certificates in the request. _certs_ will be ignored.
365
+ */
366
+ static VALUE
367
+ ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
368
+ {
369
+ VALUE signer_cert, signer_key, certs, flags, digest;
370
+ OCSP_REQUEST *req;
371
+ X509 *signer;
372
+ EVP_PKEY *key;
373
+ STACK_OF(X509) *x509s = NULL;
374
+ unsigned long flg = 0;
375
+ const EVP_MD *md;
376
+ int ret;
377
+
378
+ rb_scan_args(argc, argv, "23", &signer_cert, &signer_key, &certs, &flags, &digest);
379
+ GetOCSPReq(self, req);
380
+ signer = GetX509CertPtr(signer_cert);
381
+ key = GetPrivPKeyPtr(signer_key);
382
+ if (!NIL_P(flags))
383
+ flg = NUM2INT(flags);
384
+ if (NIL_P(digest))
385
+ md = NULL;
386
+ else
387
+ md = ossl_evp_get_digestbyname(digest);
388
+ if (NIL_P(certs))
389
+ flg |= OCSP_NOCERTS;
390
+ else
391
+ x509s = ossl_x509_ary2sk(certs);
392
+
393
+ ret = OCSP_request_sign(req, signer, key, md, x509s, flg);
394
+ sk_X509_pop_free(x509s, X509_free);
395
+ if (!ret) ossl_raise(eOCSPError, NULL);
396
+
397
+ return self;
398
+ }
399
+
400
+ /*
401
+ * call-seq:
402
+ * request.verify(certificates, store, flags = 0) -> true or false
403
+ *
404
+ * Verifies this request using the given _certificates_ and _store_.
405
+ * _certificates_ is an array of OpenSSL::X509::Certificate, _store_ is an
406
+ * OpenSSL::X509::Store.
407
+ *
408
+ * Note that +false+ is returned if the request does not have a signature.
409
+ * Use #signed? to check whether the request is signed or not.
410
+ */
411
+
412
+ static VALUE
413
+ ossl_ocspreq_verify(int argc, VALUE *argv, VALUE self)
414
+ {
415
+ VALUE certs, store, flags;
416
+ OCSP_REQUEST *req;
417
+ STACK_OF(X509) *x509s;
418
+ X509_STORE *x509st;
419
+ int flg, result;
420
+
421
+ rb_scan_args(argc, argv, "21", &certs, &store, &flags);
422
+ GetOCSPReq(self, req);
423
+ x509st = GetX509StorePtr(store);
424
+ flg = NIL_P(flags) ? 0 : NUM2INT(flags);
425
+ x509s = ossl_x509_ary2sk(certs);
426
+ result = OCSP_request_verify(req, x509s, x509st, flg);
427
+ sk_X509_pop_free(x509s, X509_free);
428
+ if (result <= 0)
429
+ ossl_clear_error();
430
+
431
+ return result > 0 ? Qtrue : Qfalse;
432
+ }
433
+
434
+ /*
435
+ * Returns this request as a DER-encoded string
436
+ */
437
+
438
+ static VALUE
439
+ ossl_ocspreq_to_der(VALUE self)
440
+ {
441
+ OCSP_REQUEST *req;
442
+ VALUE str;
443
+ unsigned char *p;
444
+ long len;
445
+
446
+ GetOCSPReq(self, req);
447
+ if((len = i2d_OCSP_REQUEST(req, NULL)) <= 0)
448
+ ossl_raise(eOCSPError, NULL);
449
+ str = rb_str_new(0, len);
450
+ p = (unsigned char *)RSTRING_PTR(str);
451
+ if(i2d_OCSP_REQUEST(req, &p) <= 0)
452
+ ossl_raise(eOCSPError, NULL);
453
+ ossl_str_adjust(str, p);
454
+
455
+ return str;
456
+ }
457
+
458
+ /*
459
+ * call-seq:
460
+ * request.signed? -> true or false
461
+ *
462
+ * Returns +true+ if the request is signed, +false+ otherwise. Note that the
463
+ * validity of the signature is *not* checked. Use #verify to verify that.
464
+ */
465
+ static VALUE
466
+ ossl_ocspreq_signed_p(VALUE self)
467
+ {
468
+ OCSP_REQUEST *req;
469
+
470
+ GetOCSPReq(self, req);
471
+ return OCSP_request_is_signed(req) ? Qtrue : Qfalse;
472
+ }
473
+
474
+ /*
475
+ * OCSP::Response
476
+ */
477
+
478
+ /* call-seq:
479
+ * OpenSSL::OCSP::Response.create(status, basic_response = nil) -> response
480
+ *
481
+ * Creates an OpenSSL::OCSP::Response from _status_ and _basic_response_.
482
+ */
483
+
484
+ static VALUE
485
+ ossl_ocspres_s_create(VALUE klass, VALUE status, VALUE basic_resp)
486
+ {
487
+ OCSP_BASICRESP *bs;
488
+ OCSP_RESPONSE *res;
489
+ VALUE obj;
490
+ int st = NUM2INT(status);
491
+
492
+ if(NIL_P(basic_resp)) bs = NULL;
493
+ else GetOCSPBasicRes(basic_resp, bs); /* NO NEED TO DUP */
494
+ obj = NewOCSPRes(klass);
495
+ if(!(res = OCSP_response_create(st, bs)))
496
+ ossl_raise(eOCSPError, NULL);
497
+ SetOCSPRes(obj, res);
498
+
499
+ return obj;
500
+ }
501
+
502
+ static VALUE
503
+ ossl_ocspres_alloc(VALUE klass)
504
+ {
505
+ OCSP_RESPONSE *res;
506
+ VALUE obj;
507
+
508
+ obj = NewOCSPRes(klass);
509
+ if(!(res = OCSP_RESPONSE_new()))
510
+ ossl_raise(eOCSPError, NULL);
511
+ SetOCSPRes(obj, res);
512
+
513
+ return obj;
514
+ }
515
+
516
+ static VALUE
517
+ ossl_ocspres_initialize_copy(VALUE self, VALUE other)
518
+ {
519
+ OCSP_RESPONSE *res, *res_old, *res_new;
520
+
521
+ rb_check_frozen(self);
522
+ GetOCSPRes(self, res_old);
523
+ GetOCSPRes(other, res);
524
+
525
+ res_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_RESPONSE), res);
526
+ if (!res_new)
527
+ ossl_raise(eOCSPError, "ASN1_item_dup");
528
+
529
+ SetOCSPRes(self, res_new);
530
+ OCSP_RESPONSE_free(res_old);
531
+
532
+ return self;
533
+ }
534
+
535
+ /*
536
+ * call-seq:
537
+ * OpenSSL::OCSP::Response.new -> response
538
+ * OpenSSL::OCSP::Response.new(response_der) -> response
539
+ *
540
+ * Creates a new OpenSSL::OCSP::Response. The response may be created empty or
541
+ * from a _response_der_ string.
542
+ */
543
+
544
+ static VALUE
545
+ ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self)
546
+ {
547
+ VALUE arg;
548
+ OCSP_RESPONSE *res, *res_new;
549
+ const unsigned char *p;
550
+
551
+ rb_scan_args(argc, argv, "01", &arg);
552
+ if(!NIL_P(arg)){
553
+ GetOCSPRes(self, res);
554
+ arg = ossl_to_der_if_possible(arg);
555
+ StringValue(arg);
556
+ p = (unsigned char *)RSTRING_PTR(arg);
557
+ res_new = d2i_OCSP_RESPONSE(NULL, &p, RSTRING_LEN(arg));
558
+ if (!res_new)
559
+ ossl_raise(eOCSPError, "d2i_OCSP_RESPONSE");
560
+ SetOCSPRes(self, res_new);
561
+ OCSP_RESPONSE_free(res);
562
+ }
563
+
564
+ return self;
565
+ }
566
+
567
+ /*
568
+ * call-seq:
569
+ * response.status -> Integer
570
+ *
571
+ * Returns the status of the response.
572
+ */
573
+
574
+ static VALUE
575
+ ossl_ocspres_status(VALUE self)
576
+ {
577
+ OCSP_RESPONSE *res;
578
+ int st;
579
+
580
+ GetOCSPRes(self, res);
581
+ st = OCSP_response_status(res);
582
+
583
+ return INT2NUM(st);
584
+ }
585
+
586
+ /*
587
+ * call-seq:
588
+ * response.status_string -> String
589
+ *
590
+ * Returns a status string for the response.
591
+ */
592
+
593
+ static VALUE
594
+ ossl_ocspres_status_string(VALUE self)
595
+ {
596
+ OCSP_RESPONSE *res;
597
+ int st;
598
+
599
+ GetOCSPRes(self, res);
600
+ st = OCSP_response_status(res);
601
+
602
+ return rb_str_new2(OCSP_response_status_str(st));
603
+ }
604
+
605
+ /*
606
+ * call-seq:
607
+ * response.basic
608
+ *
609
+ * Returns a BasicResponse for this response
610
+ */
611
+
612
+ static VALUE
613
+ ossl_ocspres_get_basic(VALUE self)
614
+ {
615
+ OCSP_RESPONSE *res;
616
+ OCSP_BASICRESP *bs;
617
+ VALUE ret;
618
+
619
+ GetOCSPRes(self, res);
620
+ ret = NewOCSPBasicRes(cOCSPBasicRes);
621
+ if(!(bs = OCSP_response_get1_basic(res)))
622
+ return Qnil;
623
+ SetOCSPBasicRes(ret, bs);
624
+
625
+ return ret;
626
+ }
627
+
628
+ /*
629
+ * call-seq:
630
+ * response.to_der -> String
631
+ *
632
+ * Returns this response as a DER-encoded string.
633
+ */
634
+
635
+ static VALUE
636
+ ossl_ocspres_to_der(VALUE self)
637
+ {
638
+ OCSP_RESPONSE *res;
639
+ VALUE str;
640
+ long len;
641
+ unsigned char *p;
642
+
643
+ GetOCSPRes(self, res);
644
+ if((len = i2d_OCSP_RESPONSE(res, NULL)) <= 0)
645
+ ossl_raise(eOCSPError, NULL);
646
+ str = rb_str_new(0, len);
647
+ p = (unsigned char *)RSTRING_PTR(str);
648
+ if(i2d_OCSP_RESPONSE(res, &p) <= 0)
649
+ ossl_raise(eOCSPError, NULL);
650
+ ossl_str_adjust(str, p);
651
+
652
+ return str;
653
+ }
654
+
655
+ /*
656
+ * OCSP::BasicResponse
657
+ */
658
+ static VALUE
659
+ ossl_ocspbres_alloc(VALUE klass)
660
+ {
661
+ OCSP_BASICRESP *bs;
662
+ VALUE obj;
663
+
664
+ obj = NewOCSPBasicRes(klass);
665
+ if(!(bs = OCSP_BASICRESP_new()))
666
+ ossl_raise(eOCSPError, NULL);
667
+ SetOCSPBasicRes(obj, bs);
668
+
669
+ return obj;
670
+ }
671
+
672
+ static VALUE
673
+ ossl_ocspbres_initialize_copy(VALUE self, VALUE other)
674
+ {
675
+ OCSP_BASICRESP *bs, *bs_old, *bs_new;
676
+
677
+ rb_check_frozen(self);
678
+ GetOCSPBasicRes(self, bs_old);
679
+ GetOCSPBasicRes(other, bs);
680
+
681
+ bs_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs);
682
+ if (!bs_new)
683
+ ossl_raise(eOCSPError, "ASN1_item_dup");
684
+
685
+ SetOCSPBasicRes(self, bs_new);
686
+ OCSP_BASICRESP_free(bs_old);
687
+
688
+ return self;
689
+ }
690
+
691
+ /*
692
+ * call-seq:
693
+ * OpenSSL::OCSP::BasicResponse.new(der_string = nil) -> basic_response
694
+ *
695
+ * Creates a new BasicResponse. If _der_string_ is given, decodes _der_string_
696
+ * as DER.
697
+ */
698
+
699
+ static VALUE
700
+ ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self)
701
+ {
702
+ VALUE arg;
703
+ OCSP_BASICRESP *res, *res_new;
704
+ const unsigned char *p;
705
+
706
+ rb_scan_args(argc, argv, "01", &arg);
707
+ if (!NIL_P(arg)) {
708
+ GetOCSPBasicRes(self, res);
709
+ arg = ossl_to_der_if_possible(arg);
710
+ StringValue(arg);
711
+ p = (unsigned char *)RSTRING_PTR(arg);
712
+ res_new = d2i_OCSP_BASICRESP(NULL, &p, RSTRING_LEN(arg));
713
+ if (!res_new)
714
+ ossl_raise(eOCSPError, "d2i_OCSP_BASICRESP");
715
+ SetOCSPBasicRes(self, res_new);
716
+ OCSP_BASICRESP_free(res);
717
+ }
718
+
719
+ return self;
720
+ }
721
+
722
+ /*
723
+ * call-seq:
724
+ * basic_response.copy_nonce(request) -> Integer
725
+ *
726
+ * Copies the nonce from _request_ into this response. Returns 1 on success
727
+ * and 0 on failure.
728
+ */
729
+
730
+ static VALUE
731
+ ossl_ocspbres_copy_nonce(VALUE self, VALUE request)
732
+ {
733
+ OCSP_BASICRESP *bs;
734
+ OCSP_REQUEST *req;
735
+ int ret;
736
+
737
+ GetOCSPBasicRes(self, bs);
738
+ GetOCSPReq(request, req);
739
+ ret = OCSP_copy_nonce(bs, req);
740
+
741
+ return INT2NUM(ret);
742
+ }
743
+
744
+ /*
745
+ * call-seq:
746
+ * basic_response.add_nonce(nonce = nil)
747
+ *
748
+ * Adds _nonce_ to this response. If no nonce was provided a random nonce
749
+ * will be added.
750
+ */
751
+
752
+ static VALUE
753
+ ossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self)
754
+ {
755
+ OCSP_BASICRESP *bs;
756
+ VALUE val;
757
+ int ret;
758
+
759
+ rb_scan_args(argc, argv, "01", &val);
760
+ if(NIL_P(val)) {
761
+ GetOCSPBasicRes(self, bs);
762
+ ret = OCSP_basic_add1_nonce(bs, NULL, -1);
763
+ }
764
+ else{
765
+ StringValue(val);
766
+ GetOCSPBasicRes(self, bs);
767
+ ret = OCSP_basic_add1_nonce(bs, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val));
768
+ }
769
+ if(!ret) ossl_raise(eOCSPError, NULL);
770
+
771
+ return self;
772
+ }
773
+
774
+ static VALUE
775
+ add_status_convert_time(VALUE obj)
776
+ {
777
+ ASN1_TIME *time;
778
+
779
+ if (RB_INTEGER_TYPE_P(obj))
780
+ time = X509_gmtime_adj(NULL, NUM2INT(obj));
781
+ else
782
+ time = ossl_x509_time_adjust(NULL, obj);
783
+
784
+ if (!time)
785
+ ossl_raise(eOCSPError, NULL);
786
+
787
+ return (VALUE)time;
788
+ }
789
+
790
+ /*
791
+ * call-seq:
792
+ * basic_response.add_status(certificate_id, status, reason, revocation_time, this_update, next_update, extensions) -> basic_response
793
+ *
794
+ * Adds a certificate status for _certificate_id_. _status_ is the status, and
795
+ * must be one of these:
796
+ *
797
+ * - OpenSSL::OCSP::V_CERTSTATUS_GOOD
798
+ * - OpenSSL::OCSP::V_CERTSTATUS_REVOKED
799
+ * - OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN
800
+ *
801
+ * _reason_ and _revocation_time_ can be given only when _status_ is
802
+ * OpenSSL::OCSP::V_CERTSTATUS_REVOKED. _reason_ describes the reason for the
803
+ * revocation, and must be one of OpenSSL::OCSP::REVOKED_STATUS_* constants.
804
+ * _revocation_time_ is the time when the certificate is revoked.
805
+ *
806
+ * _this_update_ and _next_update_ indicate the time at which the status is
807
+ * verified to be correct and the time at or before which newer information
808
+ * will be available, respectively. _next_update_ is optional.
809
+ *
810
+ * _extensions_ is an Array of OpenSSL::X509::Extension to be included in the
811
+ * SingleResponse. This is also optional.
812
+ *
813
+ * Note that the times, _revocation_time_, _this_update_ and _next_update_
814
+ * can be specified in either of Integer or Time object. If they are Integer, it
815
+ * is treated as the relative seconds from the current time.
816
+ */
817
+ static VALUE
818
+ ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
819
+ VALUE reason, VALUE revtime,
820
+ VALUE thisupd, VALUE nextupd, VALUE ext)
821
+ {
822
+ OCSP_BASICRESP *bs;
823
+ OCSP_SINGLERESP *single;
824
+ OCSP_CERTID *id;
825
+ ASN1_TIME *ths = NULL, *nxt = NULL, *rev = NULL;
826
+ int st, rsn = 0, error = 0, rstatus = 0;
827
+ long i;
828
+ VALUE tmp;
829
+
830
+ GetOCSPBasicRes(self, bs);
831
+ GetOCSPCertId(cid, id);
832
+ st = NUM2INT(status);
833
+ if (!NIL_P(ext)) { /* All ext's members must be X509::Extension */
834
+ ext = rb_check_array_type(ext);
835
+ for (i = 0; i < RARRAY_LEN(ext); i++)
836
+ OSSL_Check_Kind(RARRAY_AREF(ext, i), cX509Ext);
837
+ }
838
+
839
+ if (st == V_OCSP_CERTSTATUS_REVOKED) {
840
+ rsn = NUM2INT(reason);
841
+ tmp = rb_protect(add_status_convert_time, revtime, &rstatus);
842
+ if (rstatus) goto err;
843
+ rev = (ASN1_TIME *)tmp;
844
+ }
845
+
846
+ tmp = rb_protect(add_status_convert_time, thisupd, &rstatus);
847
+ if (rstatus) goto err;
848
+ ths = (ASN1_TIME *)tmp;
849
+
850
+ if (!NIL_P(nextupd)) {
851
+ tmp = rb_protect(add_status_convert_time, nextupd, &rstatus);
852
+ if (rstatus) goto err;
853
+ nxt = (ASN1_TIME *)tmp;
854
+ }
855
+
856
+ if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){
857
+ error = 1;
858
+ goto err;
859
+ }
860
+
861
+ if(!NIL_P(ext)){
862
+ X509_EXTENSION *x509ext;
863
+
864
+ for(i = 0; i < RARRAY_LEN(ext); i++){
865
+ x509ext = GetX509ExtPtr(RARRAY_AREF(ext, i));
866
+ if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){
867
+ error = 1;
868
+ goto err;
869
+ }
870
+ }
871
+ }
872
+
873
+ err:
874
+ ASN1_TIME_free(ths);
875
+ ASN1_TIME_free(nxt);
876
+ ASN1_TIME_free(rev);
877
+ if(error) ossl_raise(eOCSPError, NULL);
878
+ if(rstatus) rb_jump_tag(rstatus);
879
+
880
+ return self;
881
+ }
882
+
883
+ /*
884
+ * call-seq:
885
+ * basic_response.status -> statuses
886
+ *
887
+ * Returns an Array of statuses for this response. Each status contains a
888
+ * CertificateId, the status (0 for good, 1 for revoked, 2 for unknown), the
889
+ * reason for the status, the revocation time, the time of this update, the time
890
+ * for the next update and a list of OpenSSL::X509::Extension.
891
+ *
892
+ * This should be superseded by BasicResponse#responses and #find_response that
893
+ * return SingleResponse.
894
+ */
895
+ static VALUE
896
+ ossl_ocspbres_get_status(VALUE self)
897
+ {
898
+ OCSP_BASICRESP *bs;
899
+ OCSP_SINGLERESP *single;
900
+ OCSP_CERTID *cid;
901
+ ASN1_TIME *revtime, *thisupd, *nextupd;
902
+ int status, reason;
903
+ X509_EXTENSION *x509ext;
904
+ VALUE ret, ary, ext;
905
+ int count, ext_count, i, j;
906
+
907
+ GetOCSPBasicRes(self, bs);
908
+ ret = rb_ary_new();
909
+ count = OCSP_resp_count(bs);
910
+ for(i = 0; i < count; i++){
911
+ single = OCSP_resp_get0(bs, i);
912
+ if(!single) continue;
913
+
914
+ revtime = thisupd = nextupd = NULL;
915
+ status = OCSP_single_get0_status(single, &reason, &revtime,
916
+ &thisupd, &nextupd);
917
+ if(status < 0) continue;
918
+ if(!(cid = OCSP_CERTID_dup((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(single)))) /* FIXME */
919
+ ossl_raise(eOCSPError, NULL);
920
+ ary = rb_ary_new();
921
+ rb_ary_push(ary, ossl_ocspcertid_new(cid));
922
+ rb_ary_push(ary, INT2NUM(status));
923
+ rb_ary_push(ary, INT2NUM(reason));
924
+ rb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil);
925
+ rb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil);
926
+ rb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil);
927
+ ext = rb_ary_new();
928
+ ext_count = OCSP_SINGLERESP_get_ext_count(single);
929
+ for(j = 0; j < ext_count; j++){
930
+ x509ext = OCSP_SINGLERESP_get_ext(single, j);
931
+ rb_ary_push(ext, ossl_x509ext_new(x509ext));
932
+ }
933
+ rb_ary_push(ary, ext);
934
+ rb_ary_push(ret, ary);
935
+ }
936
+
937
+ return ret;
938
+ }
939
+
940
+ static VALUE ossl_ocspsres_new(OCSP_SINGLERESP *);
941
+
942
+ /*
943
+ * call-seq:
944
+ * basic_response.responses -> Array of SingleResponse
945
+ *
946
+ * Returns an Array of SingleResponse for this BasicResponse.
947
+ */
948
+
949
+ static VALUE
950
+ ossl_ocspbres_get_responses(VALUE self)
951
+ {
952
+ OCSP_BASICRESP *bs;
953
+ VALUE ret;
954
+ int count, i;
955
+
956
+ GetOCSPBasicRes(self, bs);
957
+ count = OCSP_resp_count(bs);
958
+ ret = rb_ary_new2(count);
959
+
960
+ for (i = 0; i < count; i++) {
961
+ OCSP_SINGLERESP *sres, *sres_new;
962
+
963
+ sres = OCSP_resp_get0(bs, i);
964
+ sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres);
965
+ if (!sres_new)
966
+ ossl_raise(eOCSPError, "ASN1_item_dup");
967
+
968
+ rb_ary_push(ret, ossl_ocspsres_new(sres_new));
969
+ }
970
+
971
+ return ret;
972
+ }
973
+
974
+
975
+ /*
976
+ * call-seq:
977
+ * basic_response.find_response(certificate_id) -> SingleResponse | nil
978
+ *
979
+ * Returns a SingleResponse whose CertId matches with _certificate_id_, or +nil+
980
+ * if this BasicResponse does not contain it.
981
+ */
982
+ static VALUE
983
+ ossl_ocspbres_find_response(VALUE self, VALUE target)
984
+ {
985
+ OCSP_BASICRESP *bs;
986
+ OCSP_SINGLERESP *sres, *sres_new;
987
+ OCSP_CERTID *id;
988
+ int n;
989
+
990
+ GetOCSPCertId(target, id);
991
+ GetOCSPBasicRes(self, bs);
992
+
993
+ if ((n = OCSP_resp_find(bs, id, -1)) == -1)
994
+ return Qnil;
995
+
996
+ sres = OCSP_resp_get0(bs, n);
997
+ sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres);
998
+ if (!sres_new)
999
+ ossl_raise(eOCSPError, "ASN1_item_dup");
1000
+
1001
+ return ossl_ocspsres_new(sres_new);
1002
+ }
1003
+
1004
+ /*
1005
+ * call-seq:
1006
+ * basic_response.sign(cert, key, certs = nil, flags = 0, digest = nil) -> self
1007
+ *
1008
+ * Signs this OCSP response using the _cert_, _key_ and optional _digest_. This
1009
+ * behaves in the similar way as OpenSSL::OCSP::Request#sign.
1010
+ *
1011
+ * _flags_ can include:
1012
+ * OpenSSL::OCSP::NOCERTS:: don't include certificates
1013
+ * OpenSSL::OCSP::NOTIME:: don't set producedAt
1014
+ * OpenSSL::OCSP::RESPID_KEY:: use signer's public key hash as responderID
1015
+ */
1016
+
1017
+ static VALUE
1018
+ ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
1019
+ {
1020
+ VALUE signer_cert, signer_key, certs, flags, digest;
1021
+ OCSP_BASICRESP *bs;
1022
+ X509 *signer;
1023
+ EVP_PKEY *key;
1024
+ STACK_OF(X509) *x509s = NULL;
1025
+ unsigned long flg = 0;
1026
+ const EVP_MD *md;
1027
+ int ret;
1028
+
1029
+ rb_scan_args(argc, argv, "23", &signer_cert, &signer_key, &certs, &flags, &digest);
1030
+ GetOCSPBasicRes(self, bs);
1031
+ signer = GetX509CertPtr(signer_cert);
1032
+ key = GetPrivPKeyPtr(signer_key);
1033
+ if (!NIL_P(flags))
1034
+ flg = NUM2INT(flags);
1035
+ if (NIL_P(digest))
1036
+ md = NULL;
1037
+ else
1038
+ md = ossl_evp_get_digestbyname(digest);
1039
+ if (NIL_P(certs))
1040
+ flg |= OCSP_NOCERTS;
1041
+ else
1042
+ x509s = ossl_x509_ary2sk(certs);
1043
+
1044
+ ret = OCSP_basic_sign(bs, signer, key, md, x509s, flg);
1045
+ sk_X509_pop_free(x509s, X509_free);
1046
+ if (!ret) ossl_raise(eOCSPError, NULL);
1047
+
1048
+ return self;
1049
+ }
1050
+
1051
+ /*
1052
+ * call-seq:
1053
+ * basic_response.verify(certificates, store, flags = 0) -> true or false
1054
+ *
1055
+ * Verifies the signature of the response using the given _certificates_ and
1056
+ * _store_. This works in the similar way as OpenSSL::OCSP::Request#verify.
1057
+ */
1058
+ static VALUE
1059
+ ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self)
1060
+ {
1061
+ VALUE certs, store, flags;
1062
+ OCSP_BASICRESP *bs;
1063
+ STACK_OF(X509) *x509s;
1064
+ X509_STORE *x509st;
1065
+ int flg, result;
1066
+
1067
+ rb_scan_args(argc, argv, "21", &certs, &store, &flags);
1068
+ GetOCSPBasicRes(self, bs);
1069
+ x509st = GetX509StorePtr(store);
1070
+ flg = NIL_P(flags) ? 0 : NUM2INT(flags);
1071
+ x509s = ossl_x509_ary2sk(certs);
1072
+ result = OCSP_basic_verify(bs, x509s, x509st, flg);
1073
+ sk_X509_pop_free(x509s, X509_free);
1074
+ if (result <= 0)
1075
+ ossl_clear_error();
1076
+
1077
+ return result > 0 ? Qtrue : Qfalse;
1078
+ }
1079
+
1080
+ /*
1081
+ * call-seq:
1082
+ * basic_response.to_der -> String
1083
+ *
1084
+ * Encodes this basic response into a DER-encoded string.
1085
+ */
1086
+ static VALUE
1087
+ ossl_ocspbres_to_der(VALUE self)
1088
+ {
1089
+ OCSP_BASICRESP *res;
1090
+ VALUE str;
1091
+ long len;
1092
+ unsigned char *p;
1093
+
1094
+ GetOCSPBasicRes(self, res);
1095
+ if ((len = i2d_OCSP_BASICRESP(res, NULL)) <= 0)
1096
+ ossl_raise(eOCSPError, NULL);
1097
+ str = rb_str_new(0, len);
1098
+ p = (unsigned char *)RSTRING_PTR(str);
1099
+ if (i2d_OCSP_BASICRESP(res, &p) <= 0)
1100
+ ossl_raise(eOCSPError, NULL);
1101
+ ossl_str_adjust(str, p);
1102
+
1103
+ return str;
1104
+ }
1105
+
1106
+ /*
1107
+ * OCSP::SingleResponse
1108
+ */
1109
+ static VALUE
1110
+ ossl_ocspsres_new(OCSP_SINGLERESP *sres)
1111
+ {
1112
+ VALUE obj;
1113
+
1114
+ obj = NewOCSPSingleRes(cOCSPSingleRes);
1115
+ SetOCSPSingleRes(obj, sres);
1116
+
1117
+ return obj;
1118
+ }
1119
+
1120
+ static VALUE
1121
+ ossl_ocspsres_alloc(VALUE klass)
1122
+ {
1123
+ OCSP_SINGLERESP *sres;
1124
+ VALUE obj;
1125
+
1126
+ obj = NewOCSPSingleRes(klass);
1127
+ if (!(sres = OCSP_SINGLERESP_new()))
1128
+ ossl_raise(eOCSPError, NULL);
1129
+ SetOCSPSingleRes(obj, sres);
1130
+
1131
+ return obj;
1132
+ }
1133
+
1134
+ /*
1135
+ * call-seq:
1136
+ * OpenSSL::OCSP::SingleResponse.new(der_string) -> SingleResponse
1137
+ *
1138
+ * Creates a new SingleResponse from _der_string_.
1139
+ */
1140
+ static VALUE
1141
+ ossl_ocspsres_initialize(VALUE self, VALUE arg)
1142
+ {
1143
+ OCSP_SINGLERESP *res, *res_new;
1144
+ const unsigned char *p;
1145
+
1146
+ arg = ossl_to_der_if_possible(arg);
1147
+ StringValue(arg);
1148
+ GetOCSPSingleRes(self, res);
1149
+
1150
+ p = (unsigned char*)RSTRING_PTR(arg);
1151
+ res_new = d2i_OCSP_SINGLERESP(NULL, &p, RSTRING_LEN(arg));
1152
+ if (!res_new)
1153
+ ossl_raise(eOCSPError, "d2i_OCSP_SINGLERESP");
1154
+ SetOCSPSingleRes(self, res_new);
1155
+ OCSP_SINGLERESP_free(res);
1156
+
1157
+ return self;
1158
+ }
1159
+
1160
+ static VALUE
1161
+ ossl_ocspsres_initialize_copy(VALUE self, VALUE other)
1162
+ {
1163
+ OCSP_SINGLERESP *sres, *sres_old, *sres_new;
1164
+
1165
+ rb_check_frozen(self);
1166
+ GetOCSPSingleRes(self, sres_old);
1167
+ GetOCSPSingleRes(other, sres);
1168
+
1169
+ sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres);
1170
+ if (!sres_new)
1171
+ ossl_raise(eOCSPError, "ASN1_item_dup");
1172
+
1173
+ SetOCSPSingleRes(self, sres_new);
1174
+ OCSP_SINGLERESP_free(sres_old);
1175
+
1176
+ return self;
1177
+ }
1178
+
1179
+ /*
1180
+ * call-seq:
1181
+ * single_response.check_validity(nsec = 0, maxsec = -1) -> true | false
1182
+ *
1183
+ * Checks the validity of thisUpdate and nextUpdate fields of this
1184
+ * SingleResponse. This checks the current time is within the range thisUpdate
1185
+ * to nextUpdate.
1186
+ *
1187
+ * It is possible that the OCSP request takes a few seconds or the time is not
1188
+ * accurate. To avoid rejecting a valid response, this method allows the times
1189
+ * to be within _nsec_ seconds of the current time.
1190
+ *
1191
+ * Some responders don't set the nextUpdate field. This may cause a very old
1192
+ * response to be considered valid. The _maxsec_ parameter can be used to limit
1193
+ * the age of responses.
1194
+ */
1195
+ static VALUE
1196
+ ossl_ocspsres_check_validity(int argc, VALUE *argv, VALUE self)
1197
+ {
1198
+ OCSP_SINGLERESP *sres;
1199
+ ASN1_GENERALIZEDTIME *this_update, *next_update;
1200
+ VALUE nsec_v, maxsec_v;
1201
+ int nsec, maxsec, status, ret;
1202
+
1203
+ rb_scan_args(argc, argv, "02", &nsec_v, &maxsec_v);
1204
+ nsec = NIL_P(nsec_v) ? 0 : NUM2INT(nsec_v);
1205
+ maxsec = NIL_P(maxsec_v) ? -1 : NUM2INT(maxsec_v);
1206
+
1207
+ GetOCSPSingleRes(self, sres);
1208
+ status = OCSP_single_get0_status(sres, NULL, NULL, &this_update, &next_update);
1209
+ if (status < 0)
1210
+ ossl_raise(eOCSPError, "OCSP_single_get0_status");
1211
+
1212
+ ret = OCSP_check_validity(this_update, next_update, nsec, maxsec);
1213
+
1214
+ if (ret)
1215
+ return Qtrue;
1216
+ else {
1217
+ ossl_clear_error();
1218
+ return Qfalse;
1219
+ }
1220
+ }
1221
+
1222
+ /*
1223
+ * call-seq:
1224
+ * single_response.certid -> CertificateId
1225
+ *
1226
+ * Returns the CertificateId for which this SingleResponse is.
1227
+ */
1228
+ static VALUE
1229
+ ossl_ocspsres_get_certid(VALUE self)
1230
+ {
1231
+ OCSP_SINGLERESP *sres;
1232
+ OCSP_CERTID *id;
1233
+
1234
+ GetOCSPSingleRes(self, sres);
1235
+ id = OCSP_CERTID_dup((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(sres)); /* FIXME */
1236
+
1237
+ return ossl_ocspcertid_new(id);
1238
+ }
1239
+
1240
+ /*
1241
+ * call-seq:
1242
+ * single_response.cert_status -> Integer
1243
+ *
1244
+ * Returns the status of the certificate identified by the certid.
1245
+ * The return value may be one of these constant:
1246
+ *
1247
+ * - V_CERTSTATUS_GOOD
1248
+ * - V_CERTSTATUS_REVOKED
1249
+ * - V_CERTSTATUS_UNKNOWN
1250
+ *
1251
+ * When the status is V_CERTSTATUS_REVOKED, the time at which the certificate
1252
+ * was revoked can be retrieved by #revocation_time.
1253
+ */
1254
+ static VALUE
1255
+ ossl_ocspsres_get_cert_status(VALUE self)
1256
+ {
1257
+ OCSP_SINGLERESP *sres;
1258
+ int status;
1259
+
1260
+ GetOCSPSingleRes(self, sres);
1261
+ status = OCSP_single_get0_status(sres, NULL, NULL, NULL, NULL);
1262
+ if (status < 0)
1263
+ ossl_raise(eOCSPError, "OCSP_single_get0_status");
1264
+
1265
+ return INT2NUM(status);
1266
+ }
1267
+
1268
+ /*
1269
+ * call-seq:
1270
+ * single_response.this_update -> Time
1271
+ */
1272
+ static VALUE
1273
+ ossl_ocspsres_get_this_update(VALUE self)
1274
+ {
1275
+ OCSP_SINGLERESP *sres;
1276
+ int status;
1277
+ ASN1_GENERALIZEDTIME *time;
1278
+
1279
+ GetOCSPSingleRes(self, sres);
1280
+ status = OCSP_single_get0_status(sres, NULL, NULL, &time, NULL);
1281
+ if (status < 0)
1282
+ ossl_raise(eOCSPError, "OCSP_single_get0_status");
1283
+ if (!time)
1284
+ return Qnil;
1285
+
1286
+ return asn1time_to_time(time);
1287
+ }
1288
+
1289
+ /*
1290
+ * call-seq:
1291
+ * single_response.next_update -> Time | nil
1292
+ */
1293
+ static VALUE
1294
+ ossl_ocspsres_get_next_update(VALUE self)
1295
+ {
1296
+ OCSP_SINGLERESP *sres;
1297
+ int status;
1298
+ ASN1_GENERALIZEDTIME *time;
1299
+
1300
+ GetOCSPSingleRes(self, sres);
1301
+ status = OCSP_single_get0_status(sres, NULL, NULL, NULL, &time);
1302
+ if (status < 0)
1303
+ ossl_raise(eOCSPError, "OCSP_single_get0_status");
1304
+ if (!time)
1305
+ return Qnil;
1306
+
1307
+ return asn1time_to_time(time);
1308
+ }
1309
+
1310
+ /*
1311
+ * call-seq:
1312
+ * single_response.revocation_time -> Time | nil
1313
+ */
1314
+ static VALUE
1315
+ ossl_ocspsres_get_revocation_time(VALUE self)
1316
+ {
1317
+ OCSP_SINGLERESP *sres;
1318
+ int status;
1319
+ ASN1_GENERALIZEDTIME *time;
1320
+
1321
+ GetOCSPSingleRes(self, sres);
1322
+ status = OCSP_single_get0_status(sres, NULL, &time, NULL, NULL);
1323
+ if (status < 0)
1324
+ ossl_raise(eOCSPError, "OCSP_single_get0_status");
1325
+ if (status != V_OCSP_CERTSTATUS_REVOKED)
1326
+ ossl_raise(eOCSPError, "certificate is not revoked");
1327
+ if (!time)
1328
+ return Qnil;
1329
+
1330
+ return asn1time_to_time(time);
1331
+ }
1332
+
1333
+ /*
1334
+ * call-seq:
1335
+ * single_response.revocation_reason -> Integer | nil
1336
+ */
1337
+ static VALUE
1338
+ ossl_ocspsres_get_revocation_reason(VALUE self)
1339
+ {
1340
+ OCSP_SINGLERESP *sres;
1341
+ int status, reason;
1342
+
1343
+ GetOCSPSingleRes(self, sres);
1344
+ status = OCSP_single_get0_status(sres, &reason, NULL, NULL, NULL);
1345
+ if (status < 0)
1346
+ ossl_raise(eOCSPError, "OCSP_single_get0_status");
1347
+ if (status != V_OCSP_CERTSTATUS_REVOKED)
1348
+ ossl_raise(eOCSPError, "certificate is not revoked");
1349
+
1350
+ return INT2NUM(reason);
1351
+ }
1352
+
1353
+ /*
1354
+ * call-seq:
1355
+ * single_response.extensions -> Array of X509::Extension
1356
+ */
1357
+ static VALUE
1358
+ ossl_ocspsres_get_extensions(VALUE self)
1359
+ {
1360
+ OCSP_SINGLERESP *sres;
1361
+ X509_EXTENSION *ext;
1362
+ int count, i;
1363
+ VALUE ary;
1364
+
1365
+ GetOCSPSingleRes(self, sres);
1366
+
1367
+ count = OCSP_SINGLERESP_get_ext_count(sres);
1368
+ ary = rb_ary_new2(count);
1369
+ for (i = 0; i < count; i++) {
1370
+ ext = OCSP_SINGLERESP_get_ext(sres, i);
1371
+ rb_ary_push(ary, ossl_x509ext_new(ext)); /* will dup */
1372
+ }
1373
+
1374
+ return ary;
1375
+ }
1376
+
1377
+ /*
1378
+ * call-seq:
1379
+ * single_response.to_der -> String
1380
+ *
1381
+ * Encodes this SingleResponse into a DER-encoded string.
1382
+ */
1383
+ static VALUE
1384
+ ossl_ocspsres_to_der(VALUE self)
1385
+ {
1386
+ OCSP_SINGLERESP *sres;
1387
+ VALUE str;
1388
+ long len;
1389
+ unsigned char *p;
1390
+
1391
+ GetOCSPSingleRes(self, sres);
1392
+ if ((len = i2d_OCSP_SINGLERESP(sres, NULL)) <= 0)
1393
+ ossl_raise(eOCSPError, NULL);
1394
+ str = rb_str_new(0, len);
1395
+ p = (unsigned char *)RSTRING_PTR(str);
1396
+ if (i2d_OCSP_SINGLERESP(sres, &p) <= 0)
1397
+ ossl_raise(eOCSPError, NULL);
1398
+ ossl_str_adjust(str, p);
1399
+
1400
+ return str;
1401
+ }
1402
+
1403
+
1404
+ /*
1405
+ * OCSP::CertificateId
1406
+ */
1407
+ static VALUE
1408
+ ossl_ocspcid_alloc(VALUE klass)
1409
+ {
1410
+ OCSP_CERTID *id;
1411
+ VALUE obj;
1412
+
1413
+ obj = NewOCSPCertId(klass);
1414
+ if(!(id = OCSP_CERTID_new()))
1415
+ ossl_raise(eOCSPError, NULL);
1416
+ SetOCSPCertId(obj, id);
1417
+
1418
+ return obj;
1419
+ }
1420
+
1421
+ static VALUE
1422
+ ossl_ocspcid_initialize_copy(VALUE self, VALUE other)
1423
+ {
1424
+ OCSP_CERTID *cid, *cid_old, *cid_new;
1425
+
1426
+ rb_check_frozen(self);
1427
+ GetOCSPCertId(self, cid_old);
1428
+ GetOCSPCertId(other, cid);
1429
+
1430
+ cid_new = OCSP_CERTID_dup(cid);
1431
+ if (!cid_new)
1432
+ ossl_raise(eOCSPError, "OCSP_CERTID_dup");
1433
+
1434
+ SetOCSPCertId(self, cid_new);
1435
+ OCSP_CERTID_free(cid_old);
1436
+
1437
+ return self;
1438
+ }
1439
+
1440
+ /*
1441
+ * call-seq:
1442
+ * OpenSSL::OCSP::CertificateId.new(subject, issuer, digest = nil) -> certificate_id
1443
+ * OpenSSL::OCSP::CertificateId.new(der_string) -> certificate_id
1444
+ * OpenSSL::OCSP::CertificateId.new(obj) -> certificate_id
1445
+ *
1446
+ * Creates a new OpenSSL::OCSP::CertificateId for the given _subject_ and
1447
+ * _issuer_ X509 certificates. The _digest_ is a digest algorithm that is used
1448
+ * to compute the hash values. This defaults to SHA-1.
1449
+ *
1450
+ * If only one argument is given, decodes it as DER representation of a
1451
+ * certificate ID or generates certificate ID from the object that responds to
1452
+ * the to_der method.
1453
+ */
1454
+ static VALUE
1455
+ ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self)
1456
+ {
1457
+ OCSP_CERTID *id, *newid;
1458
+ VALUE subject, issuer, digest;
1459
+
1460
+ GetOCSPCertId(self, id);
1461
+ if (rb_scan_args(argc, argv, "12", &subject, &issuer, &digest) == 1) {
1462
+ VALUE arg;
1463
+ const unsigned char *p;
1464
+
1465
+ arg = ossl_to_der_if_possible(subject);
1466
+ StringValue(arg);
1467
+ p = (unsigned char *)RSTRING_PTR(arg);
1468
+ newid = d2i_OCSP_CERTID(NULL, &p, RSTRING_LEN(arg));
1469
+ if (!newid)
1470
+ ossl_raise(eOCSPError, "d2i_OCSP_CERTID");
1471
+ }
1472
+ else {
1473
+ X509 *x509s, *x509i;
1474
+ const EVP_MD *md;
1475
+
1476
+ x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */
1477
+ x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */
1478
+ md = !NIL_P(digest) ? ossl_evp_get_digestbyname(digest) : NULL;
1479
+
1480
+ newid = OCSP_cert_to_id(md, x509s, x509i);
1481
+ if (!newid)
1482
+ ossl_raise(eOCSPError, "OCSP_cert_to_id");
1483
+ }
1484
+
1485
+ SetOCSPCertId(self, newid);
1486
+ OCSP_CERTID_free(id);
1487
+
1488
+ return self;
1489
+ }
1490
+
1491
+ /*
1492
+ * call-seq:
1493
+ * certificate_id.cmp(other) -> true or false
1494
+ *
1495
+ * Compares this certificate id with _other_ and returns +true+ if they are the
1496
+ * same.
1497
+ */
1498
+ static VALUE
1499
+ ossl_ocspcid_cmp(VALUE self, VALUE other)
1500
+ {
1501
+ OCSP_CERTID *id, *id2;
1502
+ int result;
1503
+
1504
+ GetOCSPCertId(self, id);
1505
+ GetOCSPCertId(other, id2);
1506
+ result = OCSP_id_cmp(id, id2);
1507
+
1508
+ return (result == 0) ? Qtrue : Qfalse;
1509
+ }
1510
+
1511
+ /*
1512
+ * call-seq:
1513
+ * certificate_id.cmp_issuer(other) -> true or false
1514
+ *
1515
+ * Compares this certificate id's issuer with _other_ and returns +true+ if
1516
+ * they are the same.
1517
+ */
1518
+
1519
+ static VALUE
1520
+ ossl_ocspcid_cmp_issuer(VALUE self, VALUE other)
1521
+ {
1522
+ OCSP_CERTID *id, *id2;
1523
+ int result;
1524
+
1525
+ GetOCSPCertId(self, id);
1526
+ GetOCSPCertId(other, id2);
1527
+ result = OCSP_id_issuer_cmp(id, id2);
1528
+
1529
+ return (result == 0) ? Qtrue : Qfalse;
1530
+ }
1531
+
1532
+ /*
1533
+ * call-seq:
1534
+ * certificate_id.serial -> Integer
1535
+ *
1536
+ * Returns the serial number of the certificate for which status is being
1537
+ * requested.
1538
+ */
1539
+ static VALUE
1540
+ ossl_ocspcid_get_serial(VALUE self)
1541
+ {
1542
+ OCSP_CERTID *id;
1543
+ ASN1_INTEGER *serial;
1544
+
1545
+ GetOCSPCertId(self, id);
1546
+ OCSP_id_get0_info(NULL, NULL, NULL, &serial, id);
1547
+
1548
+ return asn1integer_to_num(serial);
1549
+ }
1550
+
1551
+ /*
1552
+ * call-seq:
1553
+ * certificate_id.issuer_name_hash -> String
1554
+ *
1555
+ * Returns the issuerNameHash of this certificate ID, the hash of the
1556
+ * issuer's distinguished name calculated with the hashAlgorithm.
1557
+ */
1558
+ static VALUE
1559
+ ossl_ocspcid_get_issuer_name_hash(VALUE self)
1560
+ {
1561
+ OCSP_CERTID *id;
1562
+ ASN1_OCTET_STRING *name_hash;
1563
+ VALUE ret;
1564
+
1565
+ GetOCSPCertId(self, id);
1566
+ OCSP_id_get0_info(&name_hash, NULL, NULL, NULL, id);
1567
+
1568
+ ret = rb_str_new(NULL, name_hash->length * 2);
1569
+ ossl_bin2hex(name_hash->data, RSTRING_PTR(ret), name_hash->length);
1570
+
1571
+ return ret;
1572
+ }
1573
+
1574
+ /*
1575
+ * call-seq:
1576
+ * certificate_id.issuer_key_hash -> String
1577
+ *
1578
+ * Returns the issuerKeyHash of this certificate ID, the hash of the issuer's
1579
+ * public key.
1580
+ */
1581
+ static VALUE
1582
+ ossl_ocspcid_get_issuer_key_hash(VALUE self)
1583
+ {
1584
+ OCSP_CERTID *id;
1585
+ ASN1_OCTET_STRING *key_hash;
1586
+ VALUE ret;
1587
+
1588
+ GetOCSPCertId(self, id);
1589
+ OCSP_id_get0_info(NULL, NULL, &key_hash, NULL, id);
1590
+
1591
+ ret = rb_str_new(NULL, key_hash->length * 2);
1592
+ ossl_bin2hex(key_hash->data, RSTRING_PTR(ret), key_hash->length);
1593
+
1594
+ return ret;
1595
+ }
1596
+
1597
+ /*
1598
+ * call-seq:
1599
+ * certificate_id.hash_algorithm -> String
1600
+ *
1601
+ * Returns the ln (long name) of the hash algorithm used to generate
1602
+ * the issuerNameHash and the issuerKeyHash values.
1603
+ */
1604
+ static VALUE
1605
+ ossl_ocspcid_get_hash_algorithm(VALUE self)
1606
+ {
1607
+ OCSP_CERTID *id;
1608
+ ASN1_OBJECT *oid;
1609
+ BIO *out;
1610
+
1611
+ GetOCSPCertId(self, id);
1612
+ OCSP_id_get0_info(NULL, &oid, NULL, NULL, id);
1613
+
1614
+ if (!(out = BIO_new(BIO_s_mem())))
1615
+ ossl_raise(eOCSPError, "BIO_new");
1616
+
1617
+ if (!i2a_ASN1_OBJECT(out, oid)) {
1618
+ BIO_free(out);
1619
+ ossl_raise(eOCSPError, "i2a_ASN1_OBJECT");
1620
+ }
1621
+ return ossl_membio2str(out);
1622
+ }
1623
+
1624
+ /*
1625
+ * call-seq:
1626
+ * certificate_id.to_der -> String
1627
+ *
1628
+ * Encodes this certificate identifier into a DER-encoded string.
1629
+ */
1630
+ static VALUE
1631
+ ossl_ocspcid_to_der(VALUE self)
1632
+ {
1633
+ OCSP_CERTID *id;
1634
+ VALUE str;
1635
+ long len;
1636
+ unsigned char *p;
1637
+
1638
+ GetOCSPCertId(self, id);
1639
+ if ((len = i2d_OCSP_CERTID(id, NULL)) <= 0)
1640
+ ossl_raise(eOCSPError, NULL);
1641
+ str = rb_str_new(0, len);
1642
+ p = (unsigned char *)RSTRING_PTR(str);
1643
+ if (i2d_OCSP_CERTID(id, &p) <= 0)
1644
+ ossl_raise(eOCSPError, NULL);
1645
+ ossl_str_adjust(str, p);
1646
+
1647
+ return str;
1648
+ }
1649
+
1650
+ void
1651
+ Init_ossl_ocsp(void)
1652
+ {
1653
+ #if 0
1654
+ mOSSL = rb_define_module("OpenSSL");
1655
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
1656
+ #endif
1657
+
1658
+ /*
1659
+ * OpenSSL::OCSP implements Online Certificate Status Protocol requests
1660
+ * and responses.
1661
+ *
1662
+ * Creating and sending an OCSP request requires a subject certificate
1663
+ * that contains an OCSP URL in an authorityInfoAccess extension and the
1664
+ * issuer certificate for the subject certificate. First, load the issuer
1665
+ * and subject certificates:
1666
+ *
1667
+ * subject = OpenSSL::X509::Certificate.new subject_pem
1668
+ * issuer = OpenSSL::X509::Certificate.new issuer_pem
1669
+ *
1670
+ * To create the request we need to create a certificate ID for the
1671
+ * subject certificate so the CA knows which certificate we are asking
1672
+ * about:
1673
+ *
1674
+ * digest = OpenSSL::Digest.new('SHA1')
1675
+ * certificate_id =
1676
+ * OpenSSL::OCSP::CertificateId.new subject, issuer, digest
1677
+ *
1678
+ * Then create a request and add the certificate ID to it:
1679
+ *
1680
+ * request = OpenSSL::OCSP::Request.new
1681
+ * request.add_certid certificate_id
1682
+ *
1683
+ * Adding a nonce to the request protects against replay attacks but not
1684
+ * all CA process the nonce.
1685
+ *
1686
+ * request.add_nonce
1687
+ *
1688
+ * To submit the request to the CA for verification we need to extract the
1689
+ * OCSP URI from the subject certificate:
1690
+ *
1691
+ * ocsp_uris = subject.ocsp_uris
1692
+ *
1693
+ * require 'uri'
1694
+ *
1695
+ * ocsp_uri = URI ocsp_uris[0]
1696
+ *
1697
+ * To submit the request we'll POST the request to the OCSP URI (per RFC
1698
+ * 2560). Note that we only handle HTTP requests and don't handle any
1699
+ * redirects in this example, so this is insufficient for serious use.
1700
+ *
1701
+ * require 'net/http'
1702
+ *
1703
+ * http_response =
1704
+ * Net::HTTP.start ocsp_uri.hostname, ocsp.port do |http|
1705
+ * http.post ocsp_uri.path, request.to_der,
1706
+ * 'content-type' => 'application/ocsp-request'
1707
+ * end
1708
+ *
1709
+ * response = OpenSSL::OCSP::Response.new http_response.body
1710
+ * response_basic = response.basic
1711
+ *
1712
+ * First we check if the response has a valid signature. Without a valid
1713
+ * signature we cannot trust it. If you get a failure here you may be
1714
+ * missing a system certificate store or may be missing the intermediate
1715
+ * certificates.
1716
+ *
1717
+ * store = OpenSSL::X509::Store.new
1718
+ * store.set_default_paths
1719
+ *
1720
+ * unless response_basic.verify [], store then
1721
+ * raise 'response is not signed by a trusted certificate'
1722
+ * end
1723
+ *
1724
+ * The response contains the status information (success/fail). We can
1725
+ * display the status as a string:
1726
+ *
1727
+ * puts response.status_string #=> successful
1728
+ *
1729
+ * Next we need to know the response details to determine if the response
1730
+ * matches our request. First we check the nonce. Again, not all CAs
1731
+ * support a nonce. See Request#check_nonce for the meanings of the
1732
+ * return values.
1733
+ *
1734
+ * p request.check_nonce basic_response #=> value from -1 to 3
1735
+ *
1736
+ * Then extract the status information for the certificate from the basic
1737
+ * response.
1738
+ *
1739
+ * single_response = basic_response.find_response(certificate_id)
1740
+ *
1741
+ * unless single_response
1742
+ * raise 'basic_response does not have the status for the certificate'
1743
+ * end
1744
+ *
1745
+ * Then check the validity. A status issued in the future must be rejected.
1746
+ *
1747
+ * unless single_response.check_validity
1748
+ * raise 'this_update is in the future or next_update time has passed'
1749
+ * end
1750
+ *
1751
+ * case single_response.cert_status
1752
+ * when OpenSSL::OCSP::V_CERTSTATUS_GOOD
1753
+ * puts 'certificate is still valid'
1754
+ * when OpenSSL::OCSP::V_CERTSTATUS_REVOKED
1755
+ * puts "certificate has been revoked at #{single_response.revocation_time}"
1756
+ * when OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN
1757
+ * puts 'responder doesn't know about the certificate'
1758
+ * end
1759
+ */
1760
+
1761
+ mOCSP = rb_define_module_under(mOSSL, "OCSP");
1762
+
1763
+ /*
1764
+ * OCSP error class.
1765
+ */
1766
+
1767
+ eOCSPError = rb_define_class_under(mOCSP, "OCSPError", eOSSLError);
1768
+
1769
+ /*
1770
+ * An OpenSSL::OCSP::Request contains the certificate information for
1771
+ * determining if a certificate has been revoked or not. A Request can be
1772
+ * created for a certificate or from a DER-encoded request created
1773
+ * elsewhere.
1774
+ */
1775
+
1776
+ cOCSPReq = rb_define_class_under(mOCSP, "Request", rb_cObject);
1777
+ rb_define_alloc_func(cOCSPReq, ossl_ocspreq_alloc);
1778
+ rb_define_method(cOCSPReq, "initialize_copy", ossl_ocspreq_initialize_copy, 1);
1779
+ rb_define_method(cOCSPReq, "initialize", ossl_ocspreq_initialize, -1);
1780
+ rb_define_method(cOCSPReq, "add_nonce", ossl_ocspreq_add_nonce, -1);
1781
+ rb_define_method(cOCSPReq, "check_nonce", ossl_ocspreq_check_nonce, 1);
1782
+ rb_define_method(cOCSPReq, "add_certid", ossl_ocspreq_add_certid, 1);
1783
+ rb_define_method(cOCSPReq, "certid", ossl_ocspreq_get_certid, 0);
1784
+ rb_define_method(cOCSPReq, "signed?", ossl_ocspreq_signed_p, 0);
1785
+ rb_define_method(cOCSPReq, "sign", ossl_ocspreq_sign, -1);
1786
+ rb_define_method(cOCSPReq, "verify", ossl_ocspreq_verify, -1);
1787
+ rb_define_method(cOCSPReq, "to_der", ossl_ocspreq_to_der, 0);
1788
+
1789
+ /*
1790
+ * An OpenSSL::OCSP::Response contains the status of a certificate check
1791
+ * which is created from an OpenSSL::OCSP::Request.
1792
+ */
1793
+
1794
+ cOCSPRes = rb_define_class_under(mOCSP, "Response", rb_cObject);
1795
+ rb_define_singleton_method(cOCSPRes, "create", ossl_ocspres_s_create, 2);
1796
+ rb_define_alloc_func(cOCSPRes, ossl_ocspres_alloc);
1797
+ rb_define_method(cOCSPRes, "initialize_copy", ossl_ocspres_initialize_copy, 1);
1798
+ rb_define_method(cOCSPRes, "initialize", ossl_ocspres_initialize, -1);
1799
+ rb_define_method(cOCSPRes, "status", ossl_ocspres_status, 0);
1800
+ rb_define_method(cOCSPRes, "status_string", ossl_ocspres_status_string, 0);
1801
+ rb_define_method(cOCSPRes, "basic", ossl_ocspres_get_basic, 0);
1802
+ rb_define_method(cOCSPRes, "to_der", ossl_ocspres_to_der, 0);
1803
+
1804
+ /*
1805
+ * An OpenSSL::OCSP::BasicResponse contains the status of a certificate
1806
+ * check which is created from an OpenSSL::OCSP::Request. A
1807
+ * BasicResponse is more detailed than a Response.
1808
+ */
1809
+
1810
+ cOCSPBasicRes = rb_define_class_under(mOCSP, "BasicResponse", rb_cObject);
1811
+ rb_define_alloc_func(cOCSPBasicRes, ossl_ocspbres_alloc);
1812
+ rb_define_method(cOCSPBasicRes, "initialize_copy", ossl_ocspbres_initialize_copy, 1);
1813
+ rb_define_method(cOCSPBasicRes, "initialize", ossl_ocspbres_initialize, -1);
1814
+ rb_define_method(cOCSPBasicRes, "copy_nonce", ossl_ocspbres_copy_nonce, 1);
1815
+ rb_define_method(cOCSPBasicRes, "add_nonce", ossl_ocspbres_add_nonce, -1);
1816
+ rb_define_method(cOCSPBasicRes, "add_status", ossl_ocspbres_add_status, 7);
1817
+ rb_define_method(cOCSPBasicRes, "status", ossl_ocspbres_get_status, 0);
1818
+ rb_define_method(cOCSPBasicRes, "responses", ossl_ocspbres_get_responses, 0);
1819
+ rb_define_method(cOCSPBasicRes, "find_response", ossl_ocspbres_find_response, 1);
1820
+ rb_define_method(cOCSPBasicRes, "sign", ossl_ocspbres_sign, -1);
1821
+ rb_define_method(cOCSPBasicRes, "verify", ossl_ocspbres_verify, -1);
1822
+ rb_define_method(cOCSPBasicRes, "to_der", ossl_ocspbres_to_der, 0);
1823
+
1824
+ /*
1825
+ * An OpenSSL::OCSP::SingleResponse represents an OCSP SingleResponse
1826
+ * structure, which contains the basic information of the status of the
1827
+ * certificate.
1828
+ */
1829
+ cOCSPSingleRes = rb_define_class_under(mOCSP, "SingleResponse", rb_cObject);
1830
+ rb_define_alloc_func(cOCSPSingleRes, ossl_ocspsres_alloc);
1831
+ rb_define_method(cOCSPSingleRes, "initialize_copy", ossl_ocspsres_initialize_copy, 1);
1832
+ rb_define_method(cOCSPSingleRes, "initialize", ossl_ocspsres_initialize, 1);
1833
+ rb_define_method(cOCSPSingleRes, "check_validity", ossl_ocspsres_check_validity, -1);
1834
+ rb_define_method(cOCSPSingleRes, "certid", ossl_ocspsres_get_certid, 0);
1835
+ rb_define_method(cOCSPSingleRes, "cert_status", ossl_ocspsres_get_cert_status, 0);
1836
+ rb_define_method(cOCSPSingleRes, "this_update", ossl_ocspsres_get_this_update, 0);
1837
+ rb_define_method(cOCSPSingleRes, "next_update", ossl_ocspsres_get_next_update, 0);
1838
+ rb_define_method(cOCSPSingleRes, "revocation_time", ossl_ocspsres_get_revocation_time, 0);
1839
+ rb_define_method(cOCSPSingleRes, "revocation_reason", ossl_ocspsres_get_revocation_reason, 0);
1840
+ rb_define_method(cOCSPSingleRes, "extensions", ossl_ocspsres_get_extensions, 0);
1841
+ rb_define_method(cOCSPSingleRes, "to_der", ossl_ocspsres_to_der, 0);
1842
+
1843
+ /*
1844
+ * An OpenSSL::OCSP::CertificateId identifies a certificate to the CA so
1845
+ * that a status check can be performed.
1846
+ */
1847
+
1848
+ cOCSPCertId = rb_define_class_under(mOCSP, "CertificateId", rb_cObject);
1849
+ rb_define_alloc_func(cOCSPCertId, ossl_ocspcid_alloc);
1850
+ rb_define_method(cOCSPCertId, "initialize_copy", ossl_ocspcid_initialize_copy, 1);
1851
+ rb_define_method(cOCSPCertId, "initialize", ossl_ocspcid_initialize, -1);
1852
+ rb_define_method(cOCSPCertId, "cmp", ossl_ocspcid_cmp, 1);
1853
+ rb_define_method(cOCSPCertId, "cmp_issuer", ossl_ocspcid_cmp_issuer, 1);
1854
+ rb_define_method(cOCSPCertId, "serial", ossl_ocspcid_get_serial, 0);
1855
+ rb_define_method(cOCSPCertId, "issuer_name_hash", ossl_ocspcid_get_issuer_name_hash, 0);
1856
+ rb_define_method(cOCSPCertId, "issuer_key_hash", ossl_ocspcid_get_issuer_key_hash, 0);
1857
+ rb_define_method(cOCSPCertId, "hash_algorithm", ossl_ocspcid_get_hash_algorithm, 0);
1858
+ rb_define_method(cOCSPCertId, "to_der", ossl_ocspcid_to_der, 0);
1859
+
1860
+ /* Internal error in issuer */
1861
+ rb_define_const(mOCSP, "RESPONSE_STATUS_INTERNALERROR", INT2NUM(OCSP_RESPONSE_STATUS_INTERNALERROR));
1862
+
1863
+ /* Illegal confirmation request */
1864
+ rb_define_const(mOCSP, "RESPONSE_STATUS_MALFORMEDREQUEST", INT2NUM(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST));
1865
+
1866
+ /* The certificate was revoked for an unknown reason */
1867
+ rb_define_const(mOCSP, "REVOKED_STATUS_NOSTATUS", INT2NUM(OCSP_REVOKED_STATUS_NOSTATUS));
1868
+
1869
+ /* You must sign the request and resubmit */
1870
+ rb_define_const(mOCSP, "RESPONSE_STATUS_SIGREQUIRED", INT2NUM(OCSP_RESPONSE_STATUS_SIGREQUIRED));
1871
+
1872
+ /* Response has valid confirmations */
1873
+ rb_define_const(mOCSP, "RESPONSE_STATUS_SUCCESSFUL", INT2NUM(OCSP_RESPONSE_STATUS_SUCCESSFUL));
1874
+
1875
+ /* Try again later */
1876
+ rb_define_const(mOCSP, "RESPONSE_STATUS_TRYLATER", INT2NUM(OCSP_RESPONSE_STATUS_TRYLATER));
1877
+
1878
+ /* The certificate subject's name or other information changed */
1879
+ rb_define_const(mOCSP, "REVOKED_STATUS_AFFILIATIONCHANGED", INT2NUM(OCSP_REVOKED_STATUS_AFFILIATIONCHANGED));
1880
+
1881
+ /* This CA certificate was revoked due to a key compromise */
1882
+ rb_define_const(mOCSP, "REVOKED_STATUS_CACOMPROMISE", INT2NUM(OCSP_REVOKED_STATUS_CACOMPROMISE));
1883
+
1884
+ /* The certificate is on hold */
1885
+ rb_define_const(mOCSP, "REVOKED_STATUS_CERTIFICATEHOLD", INT2NUM(OCSP_REVOKED_STATUS_CERTIFICATEHOLD));
1886
+
1887
+ /* The certificate is no longer needed */
1888
+ rb_define_const(mOCSP, "REVOKED_STATUS_CESSATIONOFOPERATION", INT2NUM(OCSP_REVOKED_STATUS_CESSATIONOFOPERATION));
1889
+
1890
+ /* The certificate was revoked due to a key compromise */
1891
+ rb_define_const(mOCSP, "REVOKED_STATUS_KEYCOMPROMISE", INT2NUM(OCSP_REVOKED_STATUS_KEYCOMPROMISE));
1892
+
1893
+ /* The certificate was previously on hold and should now be removed from
1894
+ * the CRL */
1895
+ rb_define_const(mOCSP, "REVOKED_STATUS_REMOVEFROMCRL", INT2NUM(OCSP_REVOKED_STATUS_REMOVEFROMCRL));
1896
+
1897
+ /* The certificate was superseded by a new certificate */
1898
+ rb_define_const(mOCSP, "REVOKED_STATUS_SUPERSEDED", INT2NUM(OCSP_REVOKED_STATUS_SUPERSEDED));
1899
+
1900
+ /* Your request is unauthorized. */
1901
+ rb_define_const(mOCSP, "RESPONSE_STATUS_UNAUTHORIZED", INT2NUM(OCSP_RESPONSE_STATUS_UNAUTHORIZED));
1902
+
1903
+ /* The certificate was revoked for an unspecified reason */
1904
+ rb_define_const(mOCSP, "REVOKED_STATUS_UNSPECIFIED", INT2NUM(OCSP_REVOKED_STATUS_UNSPECIFIED));
1905
+
1906
+ /* Do not include certificates in the response */
1907
+ rb_define_const(mOCSP, "NOCERTS", INT2NUM(OCSP_NOCERTS));
1908
+
1909
+ /* Do not search certificates contained in the response for a signer */
1910
+ rb_define_const(mOCSP, "NOINTERN", INT2NUM(OCSP_NOINTERN));
1911
+
1912
+ /* Do not check the signature on the response */
1913
+ rb_define_const(mOCSP, "NOSIGS", INT2NUM(OCSP_NOSIGS));
1914
+
1915
+ /* Do not verify the certificate chain on the response */
1916
+ rb_define_const(mOCSP, "NOCHAIN", INT2NUM(OCSP_NOCHAIN));
1917
+
1918
+ /* Do not verify the response at all */
1919
+ rb_define_const(mOCSP, "NOVERIFY", INT2NUM(OCSP_NOVERIFY));
1920
+
1921
+ /* Do not check trust */
1922
+ rb_define_const(mOCSP, "NOEXPLICIT", INT2NUM(OCSP_NOEXPLICIT));
1923
+
1924
+ /* (This flag is not used by OpenSSL 1.0.1g) */
1925
+ rb_define_const(mOCSP, "NOCASIGN", INT2NUM(OCSP_NOCASIGN));
1926
+
1927
+ /* (This flag is not used by OpenSSL 1.0.1g) */
1928
+ rb_define_const(mOCSP, "NODELEGATED", INT2NUM(OCSP_NODELEGATED));
1929
+
1930
+ /* Do not make additional signing certificate checks */
1931
+ rb_define_const(mOCSP, "NOCHECKS", INT2NUM(OCSP_NOCHECKS));
1932
+
1933
+ /* Do not verify additional certificates */
1934
+ rb_define_const(mOCSP, "TRUSTOTHER", INT2NUM(OCSP_TRUSTOTHER));
1935
+
1936
+ /* Identify the response by signing the certificate key ID */
1937
+ rb_define_const(mOCSP, "RESPID_KEY", INT2NUM(OCSP_RESPID_KEY));
1938
+
1939
+ /* Do not include producedAt time in response */
1940
+ rb_define_const(mOCSP, "NOTIME", INT2NUM(OCSP_NOTIME));
1941
+
1942
+ /* Indicates the certificate is not revoked but does not necessarily mean
1943
+ * the certificate was issued or that this response is within the
1944
+ * certificate's validity interval */
1945
+ rb_define_const(mOCSP, "V_CERTSTATUS_GOOD", INT2NUM(V_OCSP_CERTSTATUS_GOOD));
1946
+ /* Indicates the certificate has been revoked either permanently or
1947
+ * temporarily (on hold). */
1948
+ rb_define_const(mOCSP, "V_CERTSTATUS_REVOKED", INT2NUM(V_OCSP_CERTSTATUS_REVOKED));
1949
+
1950
+ /* Indicates the responder does not know about the certificate being
1951
+ * requested. */
1952
+ rb_define_const(mOCSP, "V_CERTSTATUS_UNKNOWN", INT2NUM(V_OCSP_CERTSTATUS_UNKNOWN));
1953
+
1954
+ /* The responder ID is based on the key name. */
1955
+ rb_define_const(mOCSP, "V_RESPID_NAME", INT2NUM(V_OCSP_RESPID_NAME));
1956
+
1957
+ /* The responder ID is based on the public key. */
1958
+ rb_define_const(mOCSP, "V_RESPID_KEY", INT2NUM(V_OCSP_RESPID_KEY));
1959
+ }
1960
+ #else
1961
+ void
1962
+ Init_ossl_ocsp(void)
1963
+ {
1964
+ }
1965
+ #endif