Ruby 1.9.3p327(2012-11-10revision37606)
|
00001 /* 00002 * $Id: ossl_ocsp.c 31166 2011-03-24 07:29:21Z naruse $ 00003 * 'OpenSSL for Ruby' project 00004 * Copyright (C) 2003 Michal Rokos <m.rokos@sh.cvut.cz> 00005 * Copyright (C) 2003 GOTOU Yuuzou <gotoyuzo@notwork.org> 00006 * All rights reserved. 00007 */ 00008 /* 00009 * This program is licenced under the same licence as Ruby. 00010 * (See the file 'LICENCE'.) 00011 */ 00012 #include "ossl.h" 00013 00014 #if defined(OSSL_OCSP_ENABLED) 00015 00016 #define WrapOCSPReq(klass, obj, req) do { \ 00017 if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \ 00018 (obj) = Data_Wrap_Struct((klass), 0, OCSP_REQUEST_free, (req)); \ 00019 } while (0) 00020 #define GetOCSPReq(obj, req) do { \ 00021 Data_Get_Struct((obj), OCSP_REQUEST, (req)); \ 00022 if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \ 00023 } while (0) 00024 #define SafeGetOCSPReq(obj, req) do { \ 00025 OSSL_Check_Kind((obj), cOCSPReq); \ 00026 GetOCSPReq((obj), (req)); \ 00027 } while (0) 00028 00029 #define WrapOCSPRes(klass, obj, res) do { \ 00030 if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ 00031 (obj) = Data_Wrap_Struct((klass), 0, OCSP_RESPONSE_free, (res)); \ 00032 } while (0) 00033 #define GetOCSPRes(obj, res) do { \ 00034 Data_Get_Struct((obj), OCSP_RESPONSE, (res)); \ 00035 if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ 00036 } while (0) 00037 #define SafeGetOCSPRes(obj, res) do { \ 00038 OSSL_Check_Kind((obj), cOCSPRes); \ 00039 GetOCSPRes((obj), (res)); \ 00040 } while (0) 00041 00042 #define WrapOCSPBasicRes(klass, obj, res) do { \ 00043 if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ 00044 (obj) = Data_Wrap_Struct((klass), 0, OCSP_BASICRESP_free, (res)); \ 00045 } while (0) 00046 #define GetOCSPBasicRes(obj, res) do { \ 00047 Data_Get_Struct((obj), OCSP_BASICRESP, (res)); \ 00048 if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ 00049 } while (0) 00050 #define SafeGetOCSPBasicRes(obj, res) do { \ 00051 OSSL_Check_Kind((obj), cOCSPBasicRes); \ 00052 GetOCSPBasicRes((obj), (res)); \ 00053 } while (0) 00054 00055 #define WrapOCSPCertId(klass, obj, cid) do { \ 00056 if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \ 00057 (obj) = Data_Wrap_Struct((klass), 0, OCSP_CERTID_free, (cid)); \ 00058 } while (0) 00059 #define GetOCSPCertId(obj, cid) do { \ 00060 Data_Get_Struct((obj), OCSP_CERTID, (cid)); \ 00061 if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \ 00062 } while (0) 00063 #define SafeGetOCSPCertId(obj, cid) do { \ 00064 OSSL_Check_Kind((obj), cOCSPCertId); \ 00065 GetOCSPCertId((obj), (cid)); \ 00066 } while (0) 00067 00068 VALUE mOCSP; 00069 VALUE eOCSPError; 00070 VALUE cOCSPReq; 00071 VALUE cOCSPRes; 00072 VALUE cOCSPBasicRes; 00073 VALUE cOCSPCertId; 00074 00075 /* 00076 * Public 00077 */ 00078 static VALUE 00079 ossl_ocspcertid_new(OCSP_CERTID *cid) 00080 { 00081 VALUE obj; 00082 WrapOCSPCertId(cOCSPCertId, obj, cid); 00083 return obj; 00084 } 00085 00086 /* 00087 * OCSP::Resquest 00088 */ 00089 static VALUE 00090 ossl_ocspreq_alloc(VALUE klass) 00091 { 00092 OCSP_REQUEST *req; 00093 VALUE obj; 00094 00095 if (!(req = OCSP_REQUEST_new())) 00096 ossl_raise(eOCSPError, NULL); 00097 WrapOCSPReq(klass, obj, req); 00098 00099 return obj; 00100 } 00101 00102 static VALUE 00103 ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self) 00104 { 00105 VALUE arg; 00106 const unsigned char *p; 00107 00108 rb_scan_args(argc, argv, "01", &arg); 00109 if(!NIL_P(arg)){ 00110 OCSP_REQUEST *req = DATA_PTR(self), *x; 00111 arg = ossl_to_der_if_possible(arg); 00112 StringValue(arg); 00113 p = (unsigned char*)RSTRING_PTR(arg); 00114 x = d2i_OCSP_REQUEST(&req, &p, RSTRING_LEN(arg)); 00115 DATA_PTR(self) = req; 00116 if(!x){ 00117 ossl_raise(eOCSPError, "cannot load DER encoded request"); 00118 } 00119 } 00120 00121 return self; 00122 } 00123 00124 static VALUE 00125 ossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self) 00126 { 00127 OCSP_REQUEST *req; 00128 VALUE val; 00129 int ret; 00130 00131 rb_scan_args(argc, argv, "01", &val); 00132 if(NIL_P(val)) { 00133 GetOCSPReq(self, req); 00134 ret = OCSP_request_add1_nonce(req, NULL, -1); 00135 } 00136 else{ 00137 StringValue(val); 00138 GetOCSPReq(self, req); 00139 ret = OCSP_request_add1_nonce(req, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val)); 00140 } 00141 if(!ret) ossl_raise(eOCSPError, NULL); 00142 00143 return self; 00144 } 00145 00146 /* Check nonce validity in a request and response. 00147 * Return value reflects result: 00148 * 1: nonces present and equal. 00149 * 2: nonces both absent. 00150 * 3: nonce present in response only. 00151 * 0: nonces both present and not equal. 00152 * -1: nonce in request only. 00153 * 00154 * For most responders clients can check return > 0. 00155 * If responder doesn't handle nonces return != 0 may be 00156 * necessary. return == 0 is always an error. 00157 */ 00158 static VALUE 00159 ossl_ocspreq_check_nonce(VALUE self, VALUE basic_resp) 00160 { 00161 OCSP_REQUEST *req; 00162 OCSP_BASICRESP *bs; 00163 int res; 00164 00165 GetOCSPReq(self, req); 00166 SafeGetOCSPBasicRes(basic_resp, bs); 00167 res = OCSP_check_nonce(req, bs); 00168 00169 return INT2NUM(res); 00170 } 00171 00172 static VALUE 00173 ossl_ocspreq_add_certid(VALUE self, VALUE certid) 00174 { 00175 OCSP_REQUEST *req; 00176 OCSP_CERTID *id; 00177 00178 GetOCSPReq(self, req); 00179 GetOCSPCertId(certid, id); 00180 if(!OCSP_request_add0_id(req, OCSP_CERTID_dup(id))) 00181 ossl_raise(eOCSPError, NULL); 00182 00183 return self; 00184 } 00185 00186 static VALUE 00187 ossl_ocspreq_get_certid(VALUE self) 00188 { 00189 OCSP_REQUEST *req; 00190 OCSP_ONEREQ *one; 00191 OCSP_CERTID *id; 00192 VALUE ary, tmp; 00193 int i, count; 00194 00195 GetOCSPReq(self, req); 00196 count = OCSP_request_onereq_count(req); 00197 ary = (count > 0) ? rb_ary_new() : Qnil; 00198 for(i = 0; i < count; i++){ 00199 one = OCSP_request_onereq_get0(req, i); 00200 if(!(id = OCSP_CERTID_dup(OCSP_onereq_get0_id(one)))) 00201 ossl_raise(eOCSPError, NULL); 00202 WrapOCSPCertId(cOCSPCertId, tmp, id); 00203 rb_ary_push(ary, tmp); 00204 } 00205 00206 return ary; 00207 } 00208 00209 static VALUE 00210 ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self) 00211 { 00212 VALUE signer_cert, signer_key, certs, flags; 00213 OCSP_REQUEST *req; 00214 X509 *signer; 00215 EVP_PKEY *key; 00216 STACK_OF(X509) *x509s; 00217 unsigned long flg; 00218 int ret; 00219 00220 rb_scan_args(argc, argv, "22", &signer_cert, &signer_key, &certs, &flags); 00221 signer = GetX509CertPtr(signer_cert); 00222 key = GetPrivPKeyPtr(signer_key); 00223 flg = NIL_P(flags) ? 0 : NUM2INT(flags); 00224 if(NIL_P(certs)){ 00225 x509s = sk_X509_new_null(); 00226 flags |= OCSP_NOCERTS; 00227 } 00228 else x509s = ossl_x509_ary2sk(certs); 00229 GetOCSPReq(self, req); 00230 ret = OCSP_request_sign(req, signer, key, EVP_sha1(), x509s, flg); 00231 sk_X509_pop_free(x509s, X509_free); 00232 if(!ret) ossl_raise(eOCSPError, NULL); 00233 00234 return self; 00235 } 00236 00237 static VALUE 00238 ossl_ocspreq_verify(int argc, VALUE *argv, VALUE self) 00239 { 00240 VALUE certs, store, flags; 00241 OCSP_REQUEST *req; 00242 STACK_OF(X509) *x509s; 00243 X509_STORE *x509st; 00244 int flg, result; 00245 00246 rb_scan_args(argc, argv, "21", &certs, &store, &flags); 00247 x509st = GetX509StorePtr(store); 00248 flg = NIL_P(flags) ? 0 : NUM2INT(flags); 00249 x509s = ossl_x509_ary2sk(certs); 00250 GetOCSPReq(self, req); 00251 result = OCSP_request_verify(req, x509s, x509st, flg); 00252 sk_X509_pop_free(x509s, X509_free); 00253 if(!result) rb_warn("%s", ERR_error_string(ERR_peek_error(), NULL)); 00254 00255 return result ? Qtrue : Qfalse; 00256 } 00257 00258 static VALUE 00259 ossl_ocspreq_to_der(VALUE self) 00260 { 00261 OCSP_REQUEST *req; 00262 VALUE str; 00263 unsigned char *p; 00264 long len; 00265 00266 GetOCSPReq(self, req); 00267 if((len = i2d_OCSP_REQUEST(req, NULL)) <= 0) 00268 ossl_raise(eOCSPError, NULL); 00269 str = rb_str_new(0, len); 00270 p = (unsigned char *)RSTRING_PTR(str); 00271 if(i2d_OCSP_REQUEST(req, &p) <= 0) 00272 ossl_raise(eOCSPError, NULL); 00273 ossl_str_adjust(str, p); 00274 00275 return str; 00276 } 00277 00278 /* 00279 * OCSP::Response 00280 */ 00281 static VALUE 00282 ossl_ocspres_s_create(VALUE klass, VALUE status, VALUE basic_resp) 00283 { 00284 OCSP_BASICRESP *bs; 00285 OCSP_RESPONSE *res; 00286 VALUE obj; 00287 int st = NUM2INT(status); 00288 00289 if(NIL_P(basic_resp)) bs = NULL; 00290 else GetOCSPBasicRes(basic_resp, bs); /* NO NEED TO DUP */ 00291 if(!(res = OCSP_response_create(st, bs))) 00292 ossl_raise(eOCSPError, NULL); 00293 WrapOCSPRes(klass, obj, res); 00294 00295 return obj; 00296 } 00297 00298 static VALUE 00299 ossl_ocspres_alloc(VALUE klass) 00300 { 00301 OCSP_RESPONSE *res; 00302 VALUE obj; 00303 00304 if(!(res = OCSP_RESPONSE_new())) 00305 ossl_raise(eOCSPError, NULL); 00306 WrapOCSPRes(klass, obj, res); 00307 00308 return obj; 00309 } 00310 00311 static VALUE 00312 ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self) 00313 { 00314 VALUE arg; 00315 const unsigned char *p; 00316 00317 rb_scan_args(argc, argv, "01", &arg); 00318 if(!NIL_P(arg)){ 00319 OCSP_RESPONSE *res = DATA_PTR(self), *x; 00320 arg = ossl_to_der_if_possible(arg); 00321 StringValue(arg); 00322 p = (unsigned char *)RSTRING_PTR(arg); 00323 x = d2i_OCSP_RESPONSE(&res, &p, RSTRING_LEN(arg)); 00324 DATA_PTR(self) = res; 00325 if(!x){ 00326 ossl_raise(eOCSPError, "cannot load DER encoded response"); 00327 } 00328 } 00329 00330 return self; 00331 } 00332 00333 static VALUE 00334 ossl_ocspres_status(VALUE self) 00335 { 00336 OCSP_RESPONSE *res; 00337 int st; 00338 00339 GetOCSPRes(self, res); 00340 st = OCSP_response_status(res); 00341 00342 return INT2NUM(st); 00343 } 00344 00345 static VALUE 00346 ossl_ocspres_status_string(VALUE self) 00347 { 00348 OCSP_RESPONSE *res; 00349 int st; 00350 00351 GetOCSPRes(self, res); 00352 st = OCSP_response_status(res); 00353 00354 return rb_str_new2(OCSP_response_status_str(st)); 00355 } 00356 00357 static VALUE 00358 ossl_ocspres_get_basic(VALUE self) 00359 { 00360 OCSP_RESPONSE *res; 00361 OCSP_BASICRESP *bs; 00362 VALUE ret; 00363 00364 GetOCSPRes(self, res); 00365 if(!(bs = OCSP_response_get1_basic(res))) 00366 return Qnil; 00367 WrapOCSPBasicRes(cOCSPBasicRes, ret, bs); 00368 00369 return ret; 00370 } 00371 00372 static VALUE 00373 ossl_ocspres_to_der(VALUE self) 00374 { 00375 OCSP_RESPONSE *res; 00376 VALUE str; 00377 long len; 00378 unsigned char *p; 00379 00380 GetOCSPRes(self, res); 00381 if((len = i2d_OCSP_RESPONSE(res, NULL)) <= 0) 00382 ossl_raise(eOCSPError, NULL); 00383 str = rb_str_new(0, len); 00384 p = (unsigned char *)RSTRING_PTR(str); 00385 if(i2d_OCSP_RESPONSE(res, &p) <= 0) 00386 ossl_raise(eOCSPError, NULL); 00387 ossl_str_adjust(str, p); 00388 00389 return str; 00390 } 00391 00392 /* 00393 * OCSP::BasicResponse 00394 */ 00395 static VALUE 00396 ossl_ocspbres_alloc(VALUE klass) 00397 { 00398 OCSP_BASICRESP *bs; 00399 VALUE obj; 00400 00401 if(!(bs = OCSP_BASICRESP_new())) 00402 ossl_raise(eOCSPError, NULL); 00403 WrapOCSPBasicRes(klass, obj, bs); 00404 00405 return obj; 00406 } 00407 00408 static VALUE 00409 ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self) 00410 { 00411 return self; 00412 } 00413 00414 static VALUE 00415 ossl_ocspbres_copy_nonce(VALUE self, VALUE request) 00416 { 00417 OCSP_BASICRESP *bs; 00418 OCSP_REQUEST *req; 00419 int ret; 00420 00421 GetOCSPBasicRes(self, bs); 00422 SafeGetOCSPReq(request, req); 00423 ret = OCSP_copy_nonce(bs, req); 00424 00425 return INT2NUM(ret); 00426 } 00427 00428 static VALUE 00429 ossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self) 00430 { 00431 OCSP_BASICRESP *bs; 00432 VALUE val; 00433 int ret; 00434 00435 rb_scan_args(argc, argv, "01", &val); 00436 if(NIL_P(val)) { 00437 GetOCSPBasicRes(self, bs); 00438 ret = OCSP_basic_add1_nonce(bs, NULL, -1); 00439 } 00440 else{ 00441 StringValue(val); 00442 GetOCSPBasicRes(self, bs); 00443 ret = OCSP_basic_add1_nonce(bs, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val)); 00444 } 00445 if(!ret) ossl_raise(eOCSPError, NULL); 00446 00447 return self; 00448 } 00449 00450 static VALUE 00451 ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status, 00452 VALUE reason, VALUE revtime, 00453 VALUE thisupd, VALUE nextupd, VALUE ext) 00454 { 00455 OCSP_BASICRESP *bs; 00456 OCSP_SINGLERESP *single; 00457 OCSP_CERTID *id; 00458 int st, rsn; 00459 ASN1_TIME *ths, *nxt, *rev; 00460 int error, i, rstatus = 0; 00461 VALUE tmp; 00462 00463 st = NUM2INT(status); 00464 rsn = NIL_P(status) ? 0 : NUM2INT(reason); 00465 if(!NIL_P(ext)){ 00466 /* All ary's members should be X509Extension */ 00467 Check_Type(ext, T_ARRAY); 00468 for (i = 0; i < RARRAY_LEN(ext); i++) 00469 OSSL_Check_Kind(RARRAY_PTR(ext)[i], cX509Ext); 00470 } 00471 00472 error = 0; 00473 ths = nxt = rev = NULL; 00474 if(!NIL_P(revtime)){ 00475 tmp = rb_protect(rb_Integer, revtime, &rstatus); 00476 if(rstatus) goto err; 00477 rev = X509_gmtime_adj(NULL, NUM2INT(tmp)); 00478 } 00479 tmp = rb_protect(rb_Integer, thisupd, &rstatus); 00480 if(rstatus) goto err; 00481 ths = X509_gmtime_adj(NULL, NUM2INT(tmp)); 00482 tmp = rb_protect(rb_Integer, nextupd, &rstatus); 00483 if(rstatus) goto err; 00484 nxt = X509_gmtime_adj(NULL, NUM2INT(tmp)); 00485 00486 GetOCSPBasicRes(self, bs); 00487 SafeGetOCSPCertId(cid, id); 00488 if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){ 00489 error = 1; 00490 goto err; 00491 } 00492 00493 if(!NIL_P(ext)){ 00494 X509_EXTENSION *x509ext; 00495 sk_X509_EXTENSION_pop_free(single->singleExtensions, X509_EXTENSION_free); 00496 single->singleExtensions = NULL; 00497 for(i = 0; i < RARRAY_LEN(ext); i++){ 00498 x509ext = DupX509ExtPtr(RARRAY_PTR(ext)[i]); 00499 if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){ 00500 X509_EXTENSION_free(x509ext); 00501 error = 1; 00502 goto err; 00503 } 00504 X509_EXTENSION_free(x509ext); 00505 } 00506 } 00507 00508 err: 00509 ASN1_TIME_free(ths); 00510 ASN1_TIME_free(nxt); 00511 ASN1_TIME_free(rev); 00512 if(error) ossl_raise(eOCSPError, NULL); 00513 if(rstatus) rb_jump_tag(rstatus); 00514 00515 return self; 00516 } 00517 00518 static VALUE 00519 ossl_ocspbres_get_status(VALUE self) 00520 { 00521 OCSP_BASICRESP *bs; 00522 OCSP_SINGLERESP *single; 00523 OCSP_CERTID *cid; 00524 ASN1_TIME *revtime, *thisupd, *nextupd; 00525 int status, reason; 00526 X509_EXTENSION *x509ext; 00527 VALUE ret, ary, ext; 00528 int count, ext_count, i, j; 00529 00530 GetOCSPBasicRes(self, bs); 00531 ret = rb_ary_new(); 00532 count = OCSP_resp_count(bs); 00533 for(i = 0; i < count; i++){ 00534 single = OCSP_resp_get0(bs, i); 00535 if(!single) continue; 00536 00537 revtime = thisupd = nextupd = NULL; 00538 status = OCSP_single_get0_status(single, &reason, &revtime, 00539 &thisupd, &nextupd); 00540 if(status < 0) continue; 00541 if(!(cid = OCSP_CERTID_dup(single->certId))) 00542 ossl_raise(eOCSPError, NULL); 00543 ary = rb_ary_new(); 00544 rb_ary_push(ary, ossl_ocspcertid_new(cid)); 00545 rb_ary_push(ary, INT2NUM(status)); 00546 rb_ary_push(ary, INT2NUM(reason)); 00547 rb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil); 00548 rb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil); 00549 rb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil); 00550 ext = rb_ary_new(); 00551 ext_count = OCSP_SINGLERESP_get_ext_count(single); 00552 for(j = 0; j < ext_count; j++){ 00553 x509ext = OCSP_SINGLERESP_get_ext(single, j); 00554 rb_ary_push(ext, ossl_x509ext_new(x509ext)); 00555 } 00556 rb_ary_push(ary, ext); 00557 rb_ary_push(ret, ary); 00558 } 00559 00560 return ret; 00561 } 00562 00563 static VALUE 00564 ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self) 00565 { 00566 VALUE signer_cert, signer_key, certs, flags; 00567 OCSP_BASICRESP *bs; 00568 X509 *signer; 00569 EVP_PKEY *key; 00570 STACK_OF(X509) *x509s; 00571 unsigned long flg; 00572 int ret; 00573 00574 rb_scan_args(argc, argv, "22", &signer_cert, &signer_key, &certs, &flags); 00575 signer = GetX509CertPtr(signer_cert); 00576 key = GetPrivPKeyPtr(signer_key); 00577 flg = NIL_P(flags) ? 0 : NUM2INT(flags); 00578 if(NIL_P(certs)){ 00579 x509s = sk_X509_new_null(); 00580 flg |= OCSP_NOCERTS; 00581 } 00582 else{ 00583 x509s = ossl_x509_ary2sk(certs); 00584 } 00585 GetOCSPBasicRes(self, bs); 00586 ret = OCSP_basic_sign(bs, signer, key, EVP_sha1(), x509s, flg); 00587 sk_X509_pop_free(x509s, X509_free); 00588 if(!ret) ossl_raise(eOCSPError, NULL); 00589 00590 return self; 00591 } 00592 00593 static VALUE 00594 ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self) 00595 { 00596 VALUE certs, store, flags, result; 00597 OCSP_BASICRESP *bs; 00598 STACK_OF(X509) *x509s; 00599 X509_STORE *x509st; 00600 int flg; 00601 00602 rb_scan_args(argc, argv, "21", &certs, &store, &flags); 00603 x509st = GetX509StorePtr(store); 00604 flg = NIL_P(flags) ? 0 : NUM2INT(flags); 00605 x509s = ossl_x509_ary2sk(certs); 00606 GetOCSPBasicRes(self, bs); 00607 result = OCSP_basic_verify(bs, x509s, x509st, flg) > 0 ? Qtrue : Qfalse; 00608 sk_X509_pop_free(x509s, X509_free); 00609 if(!result) rb_warn("%s", ERR_error_string(ERR_peek_error(), NULL)); 00610 00611 return result; 00612 } 00613 00614 /* 00615 * OCSP::CertificateId 00616 */ 00617 static VALUE 00618 ossl_ocspcid_alloc(VALUE klass) 00619 { 00620 OCSP_CERTID *id; 00621 VALUE obj; 00622 00623 if(!(id = OCSP_CERTID_new())) 00624 ossl_raise(eOCSPError, NULL); 00625 WrapOCSPCertId(klass, obj, id); 00626 00627 return obj; 00628 } 00629 00630 static VALUE 00631 ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self) 00632 { 00633 OCSP_CERTID *id, *newid; 00634 X509 *x509s, *x509i; 00635 VALUE subject, issuer, digest; 00636 const EVP_MD *md; 00637 00638 if (rb_scan_args(argc, argv, "21", &subject, &issuer, &digest) == 0) { 00639 return self; 00640 } 00641 00642 x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */ 00643 x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */ 00644 00645 if (!NIL_P(digest)) { 00646 md = GetDigestPtr(digest); 00647 newid = OCSP_cert_to_id(md, x509s, x509i); 00648 } else { 00649 newid = OCSP_cert_to_id(NULL, x509s, x509i); 00650 } 00651 if(!newid) 00652 ossl_raise(eOCSPError, NULL); 00653 GetOCSPCertId(self, id); 00654 OCSP_CERTID_free(id); 00655 RDATA(self)->data = newid; 00656 00657 return self; 00658 } 00659 00660 static VALUE 00661 ossl_ocspcid_cmp(VALUE self, VALUE other) 00662 { 00663 OCSP_CERTID *id, *id2; 00664 int result; 00665 00666 GetOCSPCertId(self, id); 00667 SafeGetOCSPCertId(other, id2); 00668 result = OCSP_id_cmp(id, id2); 00669 00670 return (result == 0) ? Qtrue : Qfalse; 00671 } 00672 00673 static VALUE 00674 ossl_ocspcid_cmp_issuer(VALUE self, VALUE other) 00675 { 00676 OCSP_CERTID *id, *id2; 00677 int result; 00678 00679 GetOCSPCertId(self, id); 00680 SafeGetOCSPCertId(other, id2); 00681 result = OCSP_id_issuer_cmp(id, id2); 00682 00683 return (result == 0) ? Qtrue : Qfalse; 00684 } 00685 00686 static VALUE 00687 ossl_ocspcid_get_serial(VALUE self) 00688 { 00689 OCSP_CERTID *id; 00690 00691 GetOCSPCertId(self, id); 00692 00693 return asn1integer_to_num(id->serialNumber); 00694 } 00695 00696 void 00697 Init_ossl_ocsp() 00698 { 00699 mOCSP = rb_define_module_under(mOSSL, "OCSP"); 00700 00701 eOCSPError = rb_define_class_under(mOCSP, "OCSPError", eOSSLError); 00702 00703 cOCSPReq = rb_define_class_under(mOCSP, "Request", rb_cObject); 00704 rb_define_alloc_func(cOCSPReq, ossl_ocspreq_alloc); 00705 rb_define_method(cOCSPReq, "initialize", ossl_ocspreq_initialize, -1); 00706 rb_define_method(cOCSPReq, "add_nonce", ossl_ocspreq_add_nonce, -1); 00707 rb_define_method(cOCSPReq, "check_nonce", ossl_ocspreq_check_nonce, 1); 00708 rb_define_method(cOCSPReq, "add_certid", ossl_ocspreq_add_certid, 1); 00709 rb_define_method(cOCSPReq, "certid", ossl_ocspreq_get_certid, 0); 00710 rb_define_method(cOCSPReq, "sign", ossl_ocspreq_sign, -1); 00711 rb_define_method(cOCSPReq, "verify", ossl_ocspreq_verify, -1); 00712 rb_define_method(cOCSPReq, "to_der", ossl_ocspreq_to_der, 0); 00713 00714 cOCSPRes = rb_define_class_under(mOCSP, "Response", rb_cObject); 00715 rb_define_singleton_method(cOCSPRes, "create", ossl_ocspres_s_create, 2); 00716 rb_define_alloc_func(cOCSPRes, ossl_ocspres_alloc); 00717 rb_define_method(cOCSPRes, "initialize", ossl_ocspres_initialize, -1); 00718 rb_define_method(cOCSPRes, "status", ossl_ocspres_status, 0); 00719 rb_define_method(cOCSPRes, "status_string", ossl_ocspres_status_string, 0); 00720 rb_define_method(cOCSPRes, "basic", ossl_ocspres_get_basic, 0); 00721 rb_define_method(cOCSPRes, "to_der", ossl_ocspres_to_der, 0); 00722 00723 cOCSPBasicRes = rb_define_class_under(mOCSP, "BasicResponse", rb_cObject); 00724 rb_define_alloc_func(cOCSPBasicRes, ossl_ocspbres_alloc); 00725 rb_define_method(cOCSPBasicRes, "initialize", ossl_ocspbres_initialize, -1); 00726 rb_define_method(cOCSPBasicRes, "copy_nonce", ossl_ocspbres_copy_nonce, 1); 00727 rb_define_method(cOCSPBasicRes, "add_nonce", ossl_ocspbres_add_nonce, -1); 00728 rb_define_method(cOCSPBasicRes, "add_status", ossl_ocspbres_add_status, 7); 00729 rb_define_method(cOCSPBasicRes, "status", ossl_ocspbres_get_status, 0); 00730 rb_define_method(cOCSPBasicRes, "sign", ossl_ocspbres_sign, -1); 00731 rb_define_method(cOCSPBasicRes, "verify", ossl_ocspbres_verify, -1); 00732 00733 cOCSPCertId = rb_define_class_under(mOCSP, "CertificateId", rb_cObject); 00734 rb_define_alloc_func(cOCSPCertId, ossl_ocspcid_alloc); 00735 rb_define_method(cOCSPCertId, "initialize", ossl_ocspcid_initialize, -1); 00736 rb_define_method(cOCSPCertId, "cmp", ossl_ocspcid_cmp, 1); 00737 rb_define_method(cOCSPCertId, "cmp_issuer", ossl_ocspcid_cmp_issuer, 1); 00738 rb_define_method(cOCSPCertId, "serial", ossl_ocspcid_get_serial, 0); 00739 00740 #define DefOCSPConst(x) rb_define_const(mOCSP, #x, INT2NUM(OCSP_##x)) 00741 00742 DefOCSPConst(RESPONSE_STATUS_SUCCESSFUL); 00743 DefOCSPConst(RESPONSE_STATUS_MALFORMEDREQUEST); 00744 DefOCSPConst(RESPONSE_STATUS_INTERNALERROR); 00745 DefOCSPConst(RESPONSE_STATUS_TRYLATER); 00746 DefOCSPConst(RESPONSE_STATUS_SIGREQUIRED); 00747 DefOCSPConst(RESPONSE_STATUS_UNAUTHORIZED); 00748 00749 DefOCSPConst(REVOKED_STATUS_NOSTATUS); 00750 DefOCSPConst(REVOKED_STATUS_UNSPECIFIED); 00751 DefOCSPConst(REVOKED_STATUS_KEYCOMPROMISE); 00752 DefOCSPConst(REVOKED_STATUS_CACOMPROMISE); 00753 DefOCSPConst(REVOKED_STATUS_AFFILIATIONCHANGED); 00754 DefOCSPConst(REVOKED_STATUS_SUPERSEDED); 00755 DefOCSPConst(REVOKED_STATUS_CESSATIONOFOPERATION); 00756 DefOCSPConst(REVOKED_STATUS_CERTIFICATEHOLD); 00757 DefOCSPConst(REVOKED_STATUS_REMOVEFROMCRL); 00758 00759 DefOCSPConst(NOCERTS); 00760 DefOCSPConst(NOINTERN); 00761 DefOCSPConst(NOSIGS); 00762 DefOCSPConst(NOCHAIN); 00763 DefOCSPConst(NOVERIFY); 00764 DefOCSPConst(NOEXPLICIT); 00765 DefOCSPConst(NOCASIGN); 00766 DefOCSPConst(NODELEGATED); 00767 DefOCSPConst(NOCHECKS); 00768 DefOCSPConst(TRUSTOTHER); 00769 DefOCSPConst(RESPID_KEY); 00770 DefOCSPConst(NOTIME); 00771 00772 #define DefOCSPVConst(x) rb_define_const(mOCSP, "V_" #x, INT2NUM(V_OCSP_##x)) 00773 00774 DefOCSPVConst(CERTSTATUS_GOOD); 00775 DefOCSPVConst(CERTSTATUS_REVOKED); 00776 DefOCSPVConst(CERTSTATUS_UNKNOWN); 00777 DefOCSPVConst(RESPID_NAME); 00778 DefOCSPVConst(RESPID_KEY); 00779 } 00780 00781 #else /* ! OSSL_OCSP_ENABLED */ 00782 void 00783 Init_ossl_ocsp() 00784 { 00785 } 00786 #endif 00787