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