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
68VALUE mOCSP;
69VALUE eOCSPError;
70VALUE cOCSPReq;
71VALUE cOCSPRes;
72VALUE cOCSPBasicRes;
73VALUE cOCSPCertId;
74
75/*
76 * Public
77 */
78static VALUE
79ossl_ocspcertid_new(OCSP_CERTID *cid)
80{
81    VALUE obj;
82    WrapOCSPCertId(cOCSPCertId, obj, cid);
83    return obj;
84}
85
86/*
87 * OCSP::Resquest
88 */
89static VALUE
90ossl_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
102static VALUE
103ossl_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
124static VALUE
125ossl_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 */
158static VALUE
159ossl_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
172static VALUE
173ossl_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
186static VALUE
187ossl_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
209static VALUE
210ossl_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
237static VALUE
238ossl_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
258static VALUE
259ossl_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 */
281static VALUE
282ossl_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
298static VALUE
299ossl_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
311static VALUE
312ossl_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
333static VALUE
334ossl_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
345static VALUE
346ossl_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
357static VALUE
358ossl_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
372static VALUE
373ossl_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 */
395static VALUE
396ossl_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
408static VALUE
409ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self)
410{
411    return self;
412}
413
414static VALUE
415ossl_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
428static VALUE
429ossl_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
450static VALUE
451ossl_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++)
469	    OSSL_Check_Kind(RARRAY_PTR(ext)[i], cX509Ext);
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
518static VALUE
519ossl_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
563static VALUE
564ossl_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
593static VALUE
594ossl_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 */
617static VALUE
618ossl_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
630static VALUE
631ossl_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
660static VALUE
661ossl_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
673static VALUE
674ossl_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
686static VALUE
687ossl_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
696void
697Init_ossl_ocsp()
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 */
782void
783Init_ossl_ocsp()
784{
785}
786#endif
787