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