mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	 609103dbb5
			
		
	
	
		609103dbb5
		
	
	
	
	
		
			
			Import Ruby/OpenSSL 2.1.0.beta1. The full commit log since v2.0.5 (imported by r59567) can be found at: https://github.com/ruby/openssl/compare/v2.0.5...v2.1.0.beta1 ---------------------------------------------------------------- Antonio Terceiro (1): test/test_ssl: explicitly accept TLS 1.1 in corresponding test Colby Swandale (1): document using secure protocol to fetch git master in Bundler Colton Jenkins (1): Add fips_mode_get to return fips_mode Kazuki Yamaguchi (85): Start preparing for 2.1.0 Remove support for OpenSSL 0.9.8 and 1.0.0 bn: refine tests bn: implement unary {plus,minus} operators for OpenSSL::BN bn: implement OpenSSL::BN#negative? Don't define main() when built with --enable-debug test: let OpenSSL::TestCase include OpenSSL::TestUtils test: prepare test PKey instances on demand Add OpenSSL.print_mem_leaks Enable OSSL_MDEBUG on CI builds ssl: move default DH parameters from OpenSSL::PKey::DH Make exceptions with the same format regardless of OpenSSL.debug ssl: show reason of 'certificate verify error' in exception message ssl: remove OpenSSL::ExtConfig::TLS_DH_anon_WITH_AES_256_GCM_SHA384 ssl: do not confuse different ex_data index registries ssl: assume SSL/SSL_CTX always have a valid reference to the Ruby object Fix RDoc markup ssl: suppress compiler warning ext/openssl/deprecation.rb: remove broken-apple-openssl extconf.rb: print informative message if OpenSSL can't be found Rakefile: compile the extension before test kdf: introduce OpenSSL::KDF module ossl.h: add NUM2UINT64T() macro kdf: add scrypt Expand rb_define_copy_func() macro Expand FPTR_TO_FD() macro Remove SafeGet*() macros cipher: rename GetCipherPtr() to ossl_evp_get_cipherbyname() digest: rename GetDigestPtr() to ossl_evp_get_digestbyname() Add ossl_str_new(), an exception-safe rb_str_new() bio: simplify ossl_membio2str() using ossl_str_new() Remove unused functions and macros Drop support for LibreSSL 2.3 ocsp: add OpenSSL::OCSP::Request#signed? asn1: infinite length -> indefinite length asn1: rearrange tests ssl: remove a needless NULL check in SSL::SSLContext#ciphers ssl: return nil in SSL::SSLSocket#cipher if session is not started asn1: remove an unnecessary function prototype asn1: require tag information when instantiating generic type asn1: initialize 'unused_bits' attribute of BitString with 0 asn1: check for illegal 'unused_bits' value of BitString asn1: disallow NULL to be passed to asn1time_to_time() asn1: avoid truncating OID in OpenSSL::ASN1::ObjectId#oid asn1: allow constructed encoding with definite length form asn1: prohibit indefinite length form for primitive encoding asn1: allow tag number to be >= 32 for universal tag class asn1: use ossl_asn1_tag() asn1: clean up OpenSSL::ASN1::Constructive#to_der asn1: harmonize OpenSSL::ASN1::*#to_der asn1: prevent EOC octets from being in the middle of the content asn1: do not treat EOC octets as part of content octets x509name: add 'loc' and 'set' kwargs to OpenSSL::X509::Name#add_entry ssl: do not call session_remove_cb during GC Backport "Merge branch 'topic/test-memory-leak'" to maint cipher: update the documentation for Cipher#auth_tag= Rakefile: let sync:to_ruby know about test/openssl/fixtures test: fix formatting test/utils: remove OpenSSL::TestUtils.silent test/utils: add SSLTestCase#tls12_supported? test/utils: have start_server yield only the port number test/utils: do not set ecdh_curves in start_server test/utils: let server_loop close socket test/utils: improve error handling in start_server test/utils: add OpenSSL::TestUtils.openssl? and .libressl? test/utils: do not use DSA certificates in SSL tests test/test_ssl: remove test_invalid_shutdown_by_gc test/test_ssl: move test_multibyte_read_write to test_pair test/test_ssl_session: rearrange tests test/test_pair, test/test_ssl: fix for TLS 1.3 ssl: remove useless call to rb_thread_wait_fd() ssl: fix NPN support ssl: mark OpenSSL::SSL::SSLContext::DEFAULT_{1024,2048} as private ssl: use 2048-bit group in the default tmp_dh_cb ssl: ensure that SSL option flags are non-negative ssl: update OpenSSL::SSL::OP_* flags ssl: prefer TLS_method() over SSLv23_method() ssl: add SSLContext#min_version= and #max_version= ssl: rework SSLContext#ssl_version= test/test_x509name: change script encoding to ASCII-8BIT x509name: refactor OpenSSL::X509::Name#to_s x509name: add OpenSSL::X509::Name#to_utf8 x509name: add OpenSSL::X509::Name#inspect x509name: update regexp in OpenSSL::X509::Name.parse Ruby/OpenSSL 2.1.0.beta1 Marcus Stollsteimer (1): Fix rdoc for core Integer class nobu (4): [DOC] {read,write}_nonblock with exception: false [DOC] keyword argument _exception_ [DOC] mark up literals Revert r57690 except for read_nonblock git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59734 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			2018 lines
		
	
	
	
		
			54 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2018 lines
		
	
	
	
		
			54 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * 'OpenSSL for Ruby' project
 | |
|  * Copyright (C) 2003  Michal Rokos <m.rokos@sh.cvut.cz>
 | |
|  * Copyright (C) 2003  GOTOU Yuuzou <gotoyuzo@notwork.org>
 | |
|  * All rights reserved.
 | |
|  */
 | |
| /*
 | |
|  * This program is licensed under the same licence as Ruby.
 | |
|  * (See the file 'LICENCE'.)
 | |
|  */
 | |
| #include "ossl.h"
 | |
| 
 | |
| #if !defined(OPENSSL_NO_OCSP)
 | |
| 
 | |
| #define NewOCSPReq(klass) \
 | |
|     TypedData_Wrap_Struct((klass), &ossl_ocsp_request_type, 0)
 | |
| #define SetOCSPReq(obj, req) do { \
 | |
|     if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \
 | |
|     RTYPEDDATA_DATA(obj) = (req); \
 | |
| } while (0)
 | |
| #define GetOCSPReq(obj, req) do { \
 | |
|     TypedData_Get_Struct((obj), OCSP_REQUEST, &ossl_ocsp_request_type, (req)); \
 | |
|     if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \
 | |
| } while (0)
 | |
| 
 | |
| #define NewOCSPRes(klass) \
 | |
|     TypedData_Wrap_Struct((klass), &ossl_ocsp_response_type, 0)
 | |
| #define SetOCSPRes(obj, res) do { \
 | |
|     if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
 | |
|     RTYPEDDATA_DATA(obj) = (res); \
 | |
| } while (0)
 | |
| #define GetOCSPRes(obj, res) do { \
 | |
|     TypedData_Get_Struct((obj), OCSP_RESPONSE, &ossl_ocsp_response_type, (res)); \
 | |
|     if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
 | |
| } while (0)
 | |
| 
 | |
| #define NewOCSPBasicRes(klass) \
 | |
|     TypedData_Wrap_Struct((klass), &ossl_ocsp_basicresp_type, 0)
 | |
| #define SetOCSPBasicRes(obj, res) do { \
 | |
|     if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
 | |
|     RTYPEDDATA_DATA(obj) = (res); \
 | |
| } while (0)
 | |
| #define GetOCSPBasicRes(obj, res) do { \
 | |
|     TypedData_Get_Struct((obj), OCSP_BASICRESP, &ossl_ocsp_basicresp_type, (res)); \
 | |
|     if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
 | |
| } while (0)
 | |
| 
 | |
| #define NewOCSPSingleRes(klass) \
 | |
|     TypedData_Wrap_Struct((klass), &ossl_ocsp_singleresp_type, 0)
 | |
| #define SetOCSPSingleRes(obj, res) do { \
 | |
|     if(!(res)) ossl_raise(rb_eRuntimeError, "SingleResponse wasn't initialized!"); \
 | |
|     RTYPEDDATA_DATA(obj) = (res); \
 | |
| } while (0)
 | |
| #define GetOCSPSingleRes(obj, res) do { \
 | |
|     TypedData_Get_Struct((obj), OCSP_SINGLERESP, &ossl_ocsp_singleresp_type, (res)); \
 | |
|     if(!(res)) ossl_raise(rb_eRuntimeError, "SingleResponse wasn't initialized!"); \
 | |
| } while (0)
 | |
| 
 | |
| #define NewOCSPCertId(klass) \
 | |
|     TypedData_Wrap_Struct((klass), &ossl_ocsp_certid_type, 0)
 | |
| #define SetOCSPCertId(obj, cid) do { \
 | |
|     if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \
 | |
|     RTYPEDDATA_DATA(obj) = (cid); \
 | |
| } while (0)
 | |
| #define GetOCSPCertId(obj, cid) do { \
 | |
|     TypedData_Get_Struct((obj), OCSP_CERTID, &ossl_ocsp_certid_type, (cid)); \
 | |
|     if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \
 | |
| } while (0)
 | |
| 
 | |
| VALUE mOCSP;
 | |
| VALUE eOCSPError;
 | |
| VALUE cOCSPReq;
 | |
| VALUE cOCSPRes;
 | |
| VALUE cOCSPBasicRes;
 | |
| VALUE cOCSPSingleRes;
 | |
| VALUE cOCSPCertId;
 | |
| 
 | |
| static void
 | |
| ossl_ocsp_request_free(void *ptr)
 | |
| {
 | |
|     OCSP_REQUEST_free(ptr);
 | |
| }
 | |
| 
 | |
| static const rb_data_type_t ossl_ocsp_request_type = {
 | |
|     "OpenSSL/OCSP/REQUEST",
 | |
|     {
 | |
| 	0, ossl_ocsp_request_free,
 | |
|     },
 | |
|     0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
 | |
| };
 | |
| 
 | |
| static void
 | |
| ossl_ocsp_response_free(void *ptr)
 | |
| {
 | |
|     OCSP_RESPONSE_free(ptr);
 | |
| }
 | |
| 
 | |
| static const rb_data_type_t ossl_ocsp_response_type = {
 | |
|     "OpenSSL/OCSP/RESPONSE",
 | |
|     {
 | |
| 	0, ossl_ocsp_response_free,
 | |
|     },
 | |
|     0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
 | |
| };
 | |
| 
 | |
| static void
 | |
| ossl_ocsp_basicresp_free(void *ptr)
 | |
| {
 | |
|     OCSP_BASICRESP_free(ptr);
 | |
| }
 | |
| 
 | |
| static const rb_data_type_t ossl_ocsp_basicresp_type = {
 | |
|     "OpenSSL/OCSP/BASICRESP",
 | |
|     {
 | |
| 	0, ossl_ocsp_basicresp_free,
 | |
|     },
 | |
|     0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
 | |
| };
 | |
| 
 | |
| static void
 | |
| ossl_ocsp_singleresp_free(void *ptr)
 | |
| {
 | |
|     OCSP_SINGLERESP_free(ptr);
 | |
| }
 | |
| 
 | |
| static const rb_data_type_t ossl_ocsp_singleresp_type = {
 | |
|     "OpenSSL/OCSP/SINGLERESP",
 | |
|     {
 | |
| 	0, ossl_ocsp_singleresp_free,
 | |
|     },
 | |
|     0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
 | |
| };
 | |
| 
 | |
| static void
 | |
| ossl_ocsp_certid_free(void *ptr)
 | |
| {
 | |
|     OCSP_CERTID_free(ptr);
 | |
| }
 | |
| 
 | |
| static const rb_data_type_t ossl_ocsp_certid_type = {
 | |
|     "OpenSSL/OCSP/CERTID",
 | |
|     {
 | |
| 	0, ossl_ocsp_certid_free,
 | |
|     },
 | |
|     0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * Public
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspcertid_new(OCSP_CERTID *cid)
 | |
| {
 | |
|     VALUE obj = NewOCSPCertId(cOCSPCertId);
 | |
|     SetOCSPCertId(obj, cid);
 | |
|     return obj;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * OCSP::Resquest
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspreq_alloc(VALUE klass)
 | |
| {
 | |
|     OCSP_REQUEST *req;
 | |
|     VALUE obj;
 | |
| 
 | |
|     obj = NewOCSPReq(klass);
 | |
|     if (!(req = OCSP_REQUEST_new()))
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     SetOCSPReq(obj, req);
 | |
| 
 | |
|     return obj;
 | |
| }
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspreq_initialize_copy(VALUE self, VALUE other)
 | |
| {
 | |
|     OCSP_REQUEST *req, *req_old, *req_new;
 | |
| 
 | |
|     rb_check_frozen(self);
 | |
|     GetOCSPReq(self, req_old);
 | |
|     GetOCSPReq(other, req);
 | |
| 
 | |
|     req_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_REQUEST), req);
 | |
|     if (!req_new)
 | |
| 	ossl_raise(eOCSPError, "ASN1_item_dup");
 | |
| 
 | |
|     SetOCSPReq(self, req_new);
 | |
|     OCSP_REQUEST_free(req_old);
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   OpenSSL::OCSP::Request.new              -> request
 | |
|  *   OpenSSL::OCSP::Request.new(request_der) -> request
 | |
|  *
 | |
|  * Creates a new OpenSSL::OCSP::Request.  The request may be created empty or
 | |
|  * from a _request_der_ string.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self)
 | |
| {
 | |
|     VALUE arg;
 | |
|     OCSP_REQUEST *req, *req_new;
 | |
|     const unsigned char *p;
 | |
| 
 | |
|     rb_scan_args(argc, argv, "01", &arg);
 | |
|     if(!NIL_P(arg)){
 | |
| 	GetOCSPReq(self, req);
 | |
| 	arg = ossl_to_der_if_possible(arg);
 | |
| 	StringValue(arg);
 | |
| 	p = (unsigned char *)RSTRING_PTR(arg);
 | |
| 	req_new = d2i_OCSP_REQUEST(NULL, &p, RSTRING_LEN(arg));
 | |
| 	if (!req_new)
 | |
| 	    ossl_raise(eOCSPError, "d2i_OCSP_REQUEST");
 | |
| 	SetOCSPReq(self, req_new);
 | |
| 	OCSP_REQUEST_free(req);
 | |
|     }
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   request.add_nonce(nonce = nil) -> request
 | |
|  *
 | |
|  * Adds a _nonce_ to the OCSP request.  If no nonce is given a random one will
 | |
|  * be generated.
 | |
|  *
 | |
|  * The nonce is used to prevent replay attacks but some servers do not support
 | |
|  * it.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self)
 | |
| {
 | |
|     OCSP_REQUEST *req;
 | |
|     VALUE val;
 | |
|     int ret;
 | |
| 
 | |
|     rb_scan_args(argc, argv, "01", &val);
 | |
|     if(NIL_P(val)) {
 | |
| 	GetOCSPReq(self, req);
 | |
| 	ret = OCSP_request_add1_nonce(req, NULL, -1);
 | |
|     }
 | |
|     else{
 | |
| 	StringValue(val);
 | |
| 	GetOCSPReq(self, req);
 | |
| 	ret = OCSP_request_add1_nonce(req, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val));
 | |
|     }
 | |
|     if(!ret) ossl_raise(eOCSPError, NULL);
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   request.check_nonce(response) -> result
 | |
|  *
 | |
|  * Checks the nonce validity for this request and _response_.
 | |
|  *
 | |
|  * The return value is one of the following:
 | |
|  *
 | |
|  * -1 :: nonce in request only.
 | |
|  *  0 :: nonces both present and not equal.
 | |
|  *  1 :: nonces present and equal.
 | |
|  *  2 :: nonces both absent.
 | |
|  *  3 :: nonce present in response only.
 | |
|  *
 | |
|  * For most responses, clients can check _result_ > 0.  If a responder doesn't
 | |
|  * handle nonces <code>result.nonzero?</code> may be necessary.  A result of
 | |
|  * <code>0</code> is always an error.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspreq_check_nonce(VALUE self, VALUE basic_resp)
 | |
| {
 | |
|     OCSP_REQUEST *req;
 | |
|     OCSP_BASICRESP *bs;
 | |
|     int res;
 | |
| 
 | |
|     GetOCSPReq(self, req);
 | |
|     GetOCSPBasicRes(basic_resp, bs);
 | |
|     res = OCSP_check_nonce(req, bs);
 | |
| 
 | |
|     return INT2NUM(res);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   request.add_certid(certificate_id) -> request
 | |
|  *
 | |
|  * Adds _certificate_id_ to the request.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspreq_add_certid(VALUE self, VALUE certid)
 | |
| {
 | |
|     OCSP_REQUEST *req;
 | |
|     OCSP_CERTID *id, *id_new;
 | |
| 
 | |
|     GetOCSPReq(self, req);
 | |
|     GetOCSPCertId(certid, id);
 | |
| 
 | |
|     if (!(id_new = OCSP_CERTID_dup(id)))
 | |
| 	ossl_raise(eOCSPError, "OCSP_CERTID_dup");
 | |
|     if (!OCSP_request_add0_id(req, id_new)) {
 | |
| 	OCSP_CERTID_free(id_new);
 | |
| 	ossl_raise(eOCSPError, "OCSP_request_add0_id");
 | |
|     }
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   request.certid -> [certificate_id, ...]
 | |
|  *
 | |
|  * Returns all certificate IDs in this request.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspreq_get_certid(VALUE self)
 | |
| {
 | |
|     OCSP_REQUEST *req;
 | |
|     OCSP_ONEREQ *one;
 | |
|     OCSP_CERTID *id;
 | |
|     VALUE ary, tmp;
 | |
|     int i, count;
 | |
| 
 | |
|     GetOCSPReq(self, req);
 | |
|     count = OCSP_request_onereq_count(req);
 | |
|     ary = (count > 0) ? rb_ary_new() : Qnil;
 | |
|     for(i = 0; i < count; i++){
 | |
| 	one = OCSP_request_onereq_get0(req, i);
 | |
| 	tmp = NewOCSPCertId(cOCSPCertId);
 | |
| 	if(!(id = OCSP_CERTID_dup(OCSP_onereq_get0_id(one))))
 | |
| 	    ossl_raise(eOCSPError, NULL);
 | |
| 	SetOCSPCertId(tmp, id);
 | |
| 	rb_ary_push(ary, tmp);
 | |
|     }
 | |
| 
 | |
|     return ary;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   request.sign(cert, key, certs = nil, flags = 0, digest = nil) -> self
 | |
|  *
 | |
|  * Signs this OCSP request using _cert_, _key_ and optional _digest_. If
 | |
|  * _digest_ is not specified, SHA-1 is used. _certs_ is an optional Array of
 | |
|  * additional certificates which are included in the request in addition to
 | |
|  * the signer certificate. Note that if _certs_ is +nil+ or not given, flag
 | |
|  * OpenSSL::OCSP::NOCERTS is enabled. Pass an empty array to include only the
 | |
|  * signer certificate.
 | |
|  *
 | |
|  * _flags_ is a bitwise OR of the following constants:
 | |
|  *
 | |
|  * OpenSSL::OCSP::NOCERTS::
 | |
|  *   Don't include any certificates in the request. _certs_ will be ignored.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
 | |
| {
 | |
|     VALUE signer_cert, signer_key, certs, flags, digest;
 | |
|     OCSP_REQUEST *req;
 | |
|     X509 *signer;
 | |
|     EVP_PKEY *key;
 | |
|     STACK_OF(X509) *x509s = NULL;
 | |
|     unsigned long flg = 0;
 | |
|     const EVP_MD *md;
 | |
|     int ret;
 | |
| 
 | |
|     rb_scan_args(argc, argv, "23", &signer_cert, &signer_key, &certs, &flags, &digest);
 | |
|     GetOCSPReq(self, req);
 | |
|     signer = GetX509CertPtr(signer_cert);
 | |
|     key = GetPrivPKeyPtr(signer_key);
 | |
|     if (!NIL_P(flags))
 | |
| 	flg = NUM2INT(flags);
 | |
|     if (NIL_P(digest))
 | |
| 	md = EVP_sha1();
 | |
|     else
 | |
| 	md = ossl_evp_get_digestbyname(digest);
 | |
|     if (NIL_P(certs))
 | |
| 	flg |= OCSP_NOCERTS;
 | |
|     else
 | |
| 	x509s = ossl_x509_ary2sk(certs);
 | |
| 
 | |
|     ret = OCSP_request_sign(req, signer, key, md, x509s, flg);
 | |
|     sk_X509_pop_free(x509s, X509_free);
 | |
|     if (!ret) ossl_raise(eOCSPError, NULL);
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   request.verify(certificates, store, flags = 0) -> true or false
 | |
|  *
 | |
|  * Verifies this request using the given _certificates_ and _store_.
 | |
|  * _certificates_ is an array of OpenSSL::X509::Certificate, _store_ is an
 | |
|  * OpenSSL::X509::Store.
 | |
|  *
 | |
|  * Note that +false+ is returned if the request does not have a signature.
 | |
|  * Use #signed? to check whether the request is signed or not.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspreq_verify(int argc, VALUE *argv, VALUE self)
 | |
| {
 | |
|     VALUE certs, store, flags;
 | |
|     OCSP_REQUEST *req;
 | |
|     STACK_OF(X509) *x509s;
 | |
|     X509_STORE *x509st;
 | |
|     int flg, result;
 | |
| 
 | |
|     rb_scan_args(argc, argv, "21", &certs, &store, &flags);
 | |
|     GetOCSPReq(self, req);
 | |
|     x509st = GetX509StorePtr(store);
 | |
|     flg = NIL_P(flags) ? 0 : NUM2INT(flags);
 | |
|     x509s = ossl_x509_ary2sk(certs);
 | |
|     result = OCSP_request_verify(req, x509s, x509st, flg);
 | |
|     sk_X509_pop_free(x509s, X509_free);
 | |
|     if (result <= 0)
 | |
| 	ossl_clear_error();
 | |
| 
 | |
|     return result > 0 ? Qtrue : Qfalse;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Returns this request as a DER-encoded string
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspreq_to_der(VALUE self)
 | |
| {
 | |
|     OCSP_REQUEST *req;
 | |
|     VALUE str;
 | |
|     unsigned char *p;
 | |
|     long len;
 | |
| 
 | |
|     GetOCSPReq(self, req);
 | |
|     if((len = i2d_OCSP_REQUEST(req, NULL)) <= 0)
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     str = rb_str_new(0, len);
 | |
|     p = (unsigned char *)RSTRING_PTR(str);
 | |
|     if(i2d_OCSP_REQUEST(req, &p) <= 0)
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     ossl_str_adjust(str, p);
 | |
| 
 | |
|     return str;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *    request.signed? -> true or false
 | |
|  *
 | |
|  * Returns +true+ if the request is signed, +false+ otherwise. Note that the
 | |
|  * validity of the signature is *not* checked. Use #verify to verify that.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspreq_signed_p(VALUE self)
 | |
| {
 | |
|     OCSP_REQUEST *req;
 | |
| 
 | |
|     GetOCSPReq(self, req);
 | |
|     return OCSP_request_is_signed(req) ? Qtrue : Qfalse;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * OCSP::Response
 | |
|  */
 | |
| 
 | |
| /* call-seq:
 | |
|  *   OpenSSL::OCSP::Response.create(status, basic_response = nil) -> response
 | |
|  *
 | |
|  * Creates an OpenSSL::OCSP::Response from _status_ and _basic_response_.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspres_s_create(VALUE klass, VALUE status, VALUE basic_resp)
 | |
| {
 | |
|     OCSP_BASICRESP *bs;
 | |
|     OCSP_RESPONSE *res;
 | |
|     VALUE obj;
 | |
|     int st = NUM2INT(status);
 | |
| 
 | |
|     if(NIL_P(basic_resp)) bs = NULL;
 | |
|     else GetOCSPBasicRes(basic_resp, bs); /* NO NEED TO DUP */
 | |
|     obj = NewOCSPRes(klass);
 | |
|     if(!(res = OCSP_response_create(st, bs)))
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     SetOCSPRes(obj, res);
 | |
| 
 | |
|     return obj;
 | |
| }
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspres_alloc(VALUE klass)
 | |
| {
 | |
|     OCSP_RESPONSE *res;
 | |
|     VALUE obj;
 | |
| 
 | |
|     obj = NewOCSPRes(klass);
 | |
|     if(!(res = OCSP_RESPONSE_new()))
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     SetOCSPRes(obj, res);
 | |
| 
 | |
|     return obj;
 | |
| }
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspres_initialize_copy(VALUE self, VALUE other)
 | |
| {
 | |
|     OCSP_RESPONSE *res, *res_old, *res_new;
 | |
| 
 | |
|     rb_check_frozen(self);
 | |
|     GetOCSPRes(self, res_old);
 | |
|     GetOCSPRes(other, res);
 | |
| 
 | |
|     res_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_RESPONSE), res);
 | |
|     if (!res_new)
 | |
| 	ossl_raise(eOCSPError, "ASN1_item_dup");
 | |
| 
 | |
|     SetOCSPRes(self, res_new);
 | |
|     OCSP_RESPONSE_free(res_old);
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   OpenSSL::OCSP::Response.new               -> response
 | |
|  *   OpenSSL::OCSP::Response.new(response_der) -> response
 | |
|  *
 | |
|  * Creates a new OpenSSL::OCSP::Response.  The response may be created empty or
 | |
|  * from a _response_der_ string.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self)
 | |
| {
 | |
|     VALUE arg;
 | |
|     OCSP_RESPONSE *res, *res_new;
 | |
|     const unsigned char *p;
 | |
| 
 | |
|     rb_scan_args(argc, argv, "01", &arg);
 | |
|     if(!NIL_P(arg)){
 | |
| 	GetOCSPRes(self, res);
 | |
| 	arg = ossl_to_der_if_possible(arg);
 | |
| 	StringValue(arg);
 | |
| 	p = (unsigned char *)RSTRING_PTR(arg);
 | |
| 	res_new = d2i_OCSP_RESPONSE(NULL, &p, RSTRING_LEN(arg));
 | |
| 	if (!res_new)
 | |
| 	    ossl_raise(eOCSPError, "d2i_OCSP_RESPONSE");
 | |
| 	SetOCSPRes(self, res_new);
 | |
| 	OCSP_RESPONSE_free(res);
 | |
|     }
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   response.status -> Integer
 | |
|  *
 | |
|  * Returns the status of the response.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspres_status(VALUE self)
 | |
| {
 | |
|     OCSP_RESPONSE *res;
 | |
|     int st;
 | |
| 
 | |
|     GetOCSPRes(self, res);
 | |
|     st = OCSP_response_status(res);
 | |
| 
 | |
|     return INT2NUM(st);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   response.status_string -> String
 | |
|  *
 | |
|  * Returns a status string for the response.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspres_status_string(VALUE self)
 | |
| {
 | |
|     OCSP_RESPONSE *res;
 | |
|     int st;
 | |
| 
 | |
|     GetOCSPRes(self, res);
 | |
|     st = OCSP_response_status(res);
 | |
| 
 | |
|     return rb_str_new2(OCSP_response_status_str(st));
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   response.basic
 | |
|  *
 | |
|  * Returns a BasicResponse for this response
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspres_get_basic(VALUE self)
 | |
| {
 | |
|     OCSP_RESPONSE *res;
 | |
|     OCSP_BASICRESP *bs;
 | |
|     VALUE ret;
 | |
| 
 | |
|     GetOCSPRes(self, res);
 | |
|     ret = NewOCSPBasicRes(cOCSPBasicRes);
 | |
|     if(!(bs = OCSP_response_get1_basic(res)))
 | |
| 	return Qnil;
 | |
|     SetOCSPBasicRes(ret, bs);
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   response.to_der -> String
 | |
|  *
 | |
|  * Returns this response as a DER-encoded string.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspres_to_der(VALUE self)
 | |
| {
 | |
|     OCSP_RESPONSE *res;
 | |
|     VALUE str;
 | |
|     long len;
 | |
|     unsigned char *p;
 | |
| 
 | |
|     GetOCSPRes(self, res);
 | |
|     if((len = i2d_OCSP_RESPONSE(res, NULL)) <= 0)
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     str = rb_str_new(0, len);
 | |
|     p = (unsigned char *)RSTRING_PTR(str);
 | |
|     if(i2d_OCSP_RESPONSE(res, &p) <= 0)
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     ossl_str_adjust(str, p);
 | |
| 
 | |
|     return str;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * OCSP::BasicResponse
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspbres_alloc(VALUE klass)
 | |
| {
 | |
|     OCSP_BASICRESP *bs;
 | |
|     VALUE obj;
 | |
| 
 | |
|     obj = NewOCSPBasicRes(klass);
 | |
|     if(!(bs = OCSP_BASICRESP_new()))
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     SetOCSPBasicRes(obj, bs);
 | |
| 
 | |
|     return obj;
 | |
| }
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspbres_initialize_copy(VALUE self, VALUE other)
 | |
| {
 | |
|     OCSP_BASICRESP *bs, *bs_old, *bs_new;
 | |
| 
 | |
|     rb_check_frozen(self);
 | |
|     GetOCSPBasicRes(self, bs_old);
 | |
|     GetOCSPBasicRes(other, bs);
 | |
| 
 | |
|     bs_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs);
 | |
|     if (!bs_new)
 | |
| 	ossl_raise(eOCSPError, "ASN1_item_dup");
 | |
| 
 | |
|     SetOCSPBasicRes(self, bs_new);
 | |
|     OCSP_BASICRESP_free(bs_old);
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   OpenSSL::OCSP::BasicResponse.new(der_string = nil) -> basic_response
 | |
|  *
 | |
|  * Creates a new BasicResponse. If _der_string_ is given, decodes _der_string_
 | |
|  * as DER.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self)
 | |
| {
 | |
|     VALUE arg;
 | |
|     OCSP_BASICRESP *res, *res_new;
 | |
|     const unsigned char *p;
 | |
| 
 | |
|     rb_scan_args(argc, argv, "01", &arg);
 | |
|     if (!NIL_P(arg)) {
 | |
| 	GetOCSPBasicRes(self, res);
 | |
| 	arg = ossl_to_der_if_possible(arg);
 | |
| 	StringValue(arg);
 | |
| 	p = (unsigned char *)RSTRING_PTR(arg);
 | |
| 	res_new = d2i_OCSP_BASICRESP(NULL, &p, RSTRING_LEN(arg));
 | |
| 	if (!res_new)
 | |
| 	    ossl_raise(eOCSPError, "d2i_OCSP_BASICRESP");
 | |
| 	SetOCSPBasicRes(self, res_new);
 | |
| 	OCSP_BASICRESP_free(res);
 | |
|     }
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   basic_response.copy_nonce(request) -> Integer
 | |
|  *
 | |
|  * Copies the nonce from _request_ into this response.  Returns 1 on success
 | |
|  * and 0 on failure.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspbres_copy_nonce(VALUE self, VALUE request)
 | |
| {
 | |
|     OCSP_BASICRESP *bs;
 | |
|     OCSP_REQUEST *req;
 | |
|     int ret;
 | |
| 
 | |
|     GetOCSPBasicRes(self, bs);
 | |
|     GetOCSPReq(request, req);
 | |
|     ret = OCSP_copy_nonce(bs, req);
 | |
| 
 | |
|     return INT2NUM(ret);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   basic_response.add_nonce(nonce = nil)
 | |
|  *
 | |
|  * Adds _nonce_ to this response.  If no nonce was provided a random nonce
 | |
|  * will be added.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self)
 | |
| {
 | |
|     OCSP_BASICRESP *bs;
 | |
|     VALUE val;
 | |
|     int ret;
 | |
| 
 | |
|     rb_scan_args(argc, argv, "01", &val);
 | |
|     if(NIL_P(val)) {
 | |
| 	GetOCSPBasicRes(self, bs);
 | |
| 	ret = OCSP_basic_add1_nonce(bs, NULL, -1);
 | |
|     }
 | |
|     else{
 | |
| 	StringValue(val);
 | |
| 	GetOCSPBasicRes(self, bs);
 | |
| 	ret = OCSP_basic_add1_nonce(bs, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val));
 | |
|     }
 | |
|     if(!ret) ossl_raise(eOCSPError, NULL);
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| static VALUE
 | |
| add_status_convert_time(VALUE obj)
 | |
| {
 | |
|     ASN1_TIME *time;
 | |
| 
 | |
|     if (RB_INTEGER_TYPE_P(obj))
 | |
| 	time = X509_gmtime_adj(NULL, NUM2INT(obj));
 | |
|     else
 | |
| 	time = ossl_x509_time_adjust(NULL, obj);
 | |
| 
 | |
|     if (!time)
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
| 
 | |
|     return (VALUE)time;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   basic_response.add_status(certificate_id, status, reason, revocation_time, this_update, next_update, extensions) -> basic_response
 | |
|  *
 | |
|  * Adds a certificate status for _certificate_id_. _status_ is the status, and
 | |
|  * must be one of these:
 | |
|  *
 | |
|  * - OpenSSL::OCSP::V_CERTSTATUS_GOOD
 | |
|  * - OpenSSL::OCSP::V_CERTSTATUS_REVOKED
 | |
|  * - OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN
 | |
|  *
 | |
|  * _reason_ and _revocation_time_ can be given only when _status_ is
 | |
|  * OpenSSL::OCSP::V_CERTSTATUS_REVOKED. _reason_ describes the reason for the
 | |
|  * revocation, and must be one of OpenSSL::OCSP::REVOKED_STATUS_* constants.
 | |
|  * _revocation_time_ is the time when the certificate is revoked.
 | |
|  *
 | |
|  * _this_update_ and _next_update_ indicate the time at which ths status is
 | |
|  * verified to be correct and the time at or before which newer information
 | |
|  * will be available, respectively. _next_update_ is optional.
 | |
|  *
 | |
|  * _extensions_ is an Array of OpenSSL::X509::Extension to be included in the
 | |
|  * SingleResponse. This is also optional.
 | |
|  *
 | |
|  * Note that the times, _revocation_time_, _this_update_ and _next_update_
 | |
|  * can be specified in either of Integer or Time object. If they are Integer, it
 | |
|  * is treated as the relative seconds from the current time.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
 | |
| 			 VALUE reason, VALUE revtime,
 | |
| 			 VALUE thisupd, VALUE nextupd, VALUE ext)
 | |
| {
 | |
|     OCSP_BASICRESP *bs;
 | |
|     OCSP_SINGLERESP *single;
 | |
|     OCSP_CERTID *id;
 | |
|     ASN1_TIME *ths = NULL, *nxt = NULL, *rev = NULL;
 | |
|     int st, rsn = 0, error = 0, rstatus = 0;
 | |
|     long i;
 | |
|     VALUE tmp;
 | |
| 
 | |
|     GetOCSPBasicRes(self, bs);
 | |
|     GetOCSPCertId(cid, id);
 | |
|     st = NUM2INT(status);
 | |
|     if (!NIL_P(ext)) { /* All ext's members must be X509::Extension */
 | |
| 	ext = rb_check_array_type(ext);
 | |
| 	for (i = 0; i < RARRAY_LEN(ext); i++)
 | |
| 	    OSSL_Check_Kind(RARRAY_AREF(ext, i), cX509Ext);
 | |
|     }
 | |
| 
 | |
|     if (st == V_OCSP_CERTSTATUS_REVOKED) {
 | |
| 	rsn = NUM2INT(reason);
 | |
| 	tmp = rb_protect(add_status_convert_time, revtime, &rstatus);
 | |
| 	if (rstatus) goto err;
 | |
| 	rev = (ASN1_TIME *)tmp;
 | |
|     }
 | |
| 
 | |
|     tmp = rb_protect(add_status_convert_time, thisupd, &rstatus);
 | |
|     if (rstatus) goto err;
 | |
|     ths = (ASN1_TIME *)tmp;
 | |
| 
 | |
|     if (!NIL_P(nextupd)) {
 | |
| 	tmp = rb_protect(add_status_convert_time, nextupd, &rstatus);
 | |
| 	if (rstatus) goto err;
 | |
| 	nxt = (ASN1_TIME *)tmp;
 | |
|     }
 | |
| 
 | |
|     if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){
 | |
| 	error = 1;
 | |
| 	goto err;
 | |
|     }
 | |
| 
 | |
|     if(!NIL_P(ext)){
 | |
| 	X509_EXTENSION *x509ext;
 | |
| 
 | |
| 	for(i = 0; i < RARRAY_LEN(ext); i++){
 | |
| 	    x509ext = GetX509ExtPtr(RARRAY_AREF(ext, i));
 | |
| 	    if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){
 | |
| 		error = 1;
 | |
| 		goto err;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|  err:
 | |
|     ASN1_TIME_free(ths);
 | |
|     ASN1_TIME_free(nxt);
 | |
|     ASN1_TIME_free(rev);
 | |
|     if(error) ossl_raise(eOCSPError, NULL);
 | |
|     if(rstatus) rb_jump_tag(rstatus);
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   basic_response.status -> statuses
 | |
|  *
 | |
|  * Returns an Array of statuses for this response.  Each status contains a
 | |
|  * CertificateId, the status (0 for good, 1 for revoked, 2 for unknown), the
 | |
|  * reason for the status, the revocation time, the time of this update, the time
 | |
|  * for the next update and a list of OpenSSL::X509::Extension.
 | |
|  *
 | |
|  * This should be superseded by BasicResponse#responses and #find_response that
 | |
|  * return SingleResponse.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspbres_get_status(VALUE self)
 | |
| {
 | |
|     OCSP_BASICRESP *bs;
 | |
|     OCSP_SINGLERESP *single;
 | |
|     OCSP_CERTID *cid;
 | |
|     ASN1_TIME *revtime, *thisupd, *nextupd;
 | |
|     int status, reason;
 | |
|     X509_EXTENSION *x509ext;
 | |
|     VALUE ret, ary, ext;
 | |
|     int count, ext_count, i, j;
 | |
| 
 | |
|     GetOCSPBasicRes(self, bs);
 | |
|     ret = rb_ary_new();
 | |
|     count = OCSP_resp_count(bs);
 | |
|     for(i = 0; i < count; i++){
 | |
| 	single = OCSP_resp_get0(bs, i);
 | |
| 	if(!single) continue;
 | |
| 
 | |
| 	revtime = thisupd = nextupd = NULL;
 | |
| 	status = OCSP_single_get0_status(single, &reason, &revtime,
 | |
| 					 &thisupd, &nextupd);
 | |
| 	if(status < 0) continue;
 | |
| 	if(!(cid = OCSP_CERTID_dup((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(single)))) /* FIXME */
 | |
| 	    ossl_raise(eOCSPError, NULL);
 | |
| 	ary = rb_ary_new();
 | |
| 	rb_ary_push(ary, ossl_ocspcertid_new(cid));
 | |
| 	rb_ary_push(ary, INT2NUM(status));
 | |
| 	rb_ary_push(ary, INT2NUM(reason));
 | |
| 	rb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil);
 | |
| 	rb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil);
 | |
| 	rb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil);
 | |
| 	ext = rb_ary_new();
 | |
| 	ext_count = OCSP_SINGLERESP_get_ext_count(single);
 | |
| 	for(j = 0; j < ext_count; j++){
 | |
| 	    x509ext = OCSP_SINGLERESP_get_ext(single, j);
 | |
| 	    rb_ary_push(ext, ossl_x509ext_new(x509ext));
 | |
| 	}
 | |
| 	rb_ary_push(ary, ext);
 | |
| 	rb_ary_push(ret, ary);
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| static VALUE ossl_ocspsres_new(OCSP_SINGLERESP *);
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   basic_response.responses -> Array of SingleResponse
 | |
|  *
 | |
|  * Returns an Array of SingleResponse for this BasicResponse.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspbres_get_responses(VALUE self)
 | |
| {
 | |
|     OCSP_BASICRESP *bs;
 | |
|     VALUE ret;
 | |
|     int count, i;
 | |
| 
 | |
|     GetOCSPBasicRes(self, bs);
 | |
|     count = OCSP_resp_count(bs);
 | |
|     ret = rb_ary_new2(count);
 | |
| 
 | |
|     for (i = 0; i < count; i++) {
 | |
| 	OCSP_SINGLERESP *sres, *sres_new;
 | |
| 
 | |
| 	sres = OCSP_resp_get0(bs, i);
 | |
| 	sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres);
 | |
| 	if (!sres_new)
 | |
| 	    ossl_raise(eOCSPError, "ASN1_item_dup");
 | |
| 
 | |
| 	rb_ary_push(ret, ossl_ocspsres_new(sres_new));
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   basic_response.find_response(certificate_id) -> SingleResponse | nil
 | |
|  *
 | |
|  * Returns a SingleResponse whose CertId matches with _certificate_id_, or +nil+
 | |
|  * if this BasicResponse does not contain it.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspbres_find_response(VALUE self, VALUE target)
 | |
| {
 | |
|     OCSP_BASICRESP *bs;
 | |
|     OCSP_SINGLERESP *sres, *sres_new;
 | |
|     OCSP_CERTID *id;
 | |
|     int n;
 | |
| 
 | |
|     GetOCSPCertId(target, id);
 | |
|     GetOCSPBasicRes(self, bs);
 | |
| 
 | |
|     if ((n = OCSP_resp_find(bs, id, -1)) == -1)
 | |
| 	return Qnil;
 | |
| 
 | |
|     sres = OCSP_resp_get0(bs, n);
 | |
|     sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres);
 | |
|     if (!sres_new)
 | |
| 	ossl_raise(eOCSPError, "ASN1_item_dup");
 | |
| 
 | |
|     return ossl_ocspsres_new(sres_new);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   basic_response.sign(cert, key, certs = nil, flags = 0, digest = nil) -> self
 | |
|  *
 | |
|  * Signs this OCSP response using the _cert_, _key_ and optional _digest_. This
 | |
|  * behaves in the similar way as OpenSSL::OCSP::Request#sign.
 | |
|  *
 | |
|  * _flags_ can include:
 | |
|  * OpenSSL::OCSP::NOCERTS::    don't include certificates
 | |
|  * OpenSSL::OCSP::NOTIME::     don't set producedAt
 | |
|  * OpenSSL::OCSP::RESPID_KEY:: use signer's public key hash as responderID
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
 | |
| {
 | |
|     VALUE signer_cert, signer_key, certs, flags, digest;
 | |
|     OCSP_BASICRESP *bs;
 | |
|     X509 *signer;
 | |
|     EVP_PKEY *key;
 | |
|     STACK_OF(X509) *x509s = NULL;
 | |
|     unsigned long flg = 0;
 | |
|     const EVP_MD *md;
 | |
|     int ret;
 | |
| 
 | |
|     rb_scan_args(argc, argv, "23", &signer_cert, &signer_key, &certs, &flags, &digest);
 | |
|     GetOCSPBasicRes(self, bs);
 | |
|     signer = GetX509CertPtr(signer_cert);
 | |
|     key = GetPrivPKeyPtr(signer_key);
 | |
|     if (!NIL_P(flags))
 | |
| 	flg = NUM2INT(flags);
 | |
|     if (NIL_P(digest))
 | |
| 	md = EVP_sha1();
 | |
|     else
 | |
| 	md = ossl_evp_get_digestbyname(digest);
 | |
|     if (NIL_P(certs))
 | |
| 	flg |= OCSP_NOCERTS;
 | |
|     else
 | |
| 	x509s = ossl_x509_ary2sk(certs);
 | |
| 
 | |
|     ret = OCSP_basic_sign(bs, signer, key, md, x509s, flg);
 | |
|     sk_X509_pop_free(x509s, X509_free);
 | |
|     if (!ret) ossl_raise(eOCSPError, NULL);
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   basic_response.verify(certificates, store, flags = 0) -> true or false
 | |
|  *
 | |
|  * Verifies the signature of the response using the given _certificates_ and
 | |
|  * _store_. This works in the similar way as OpenSSL::OCSP::Request#verify.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self)
 | |
| {
 | |
|     VALUE certs, store, flags;
 | |
|     OCSP_BASICRESP *bs;
 | |
|     STACK_OF(X509) *x509s;
 | |
|     X509_STORE *x509st;
 | |
|     int flg, result;
 | |
| 
 | |
|     rb_scan_args(argc, argv, "21", &certs, &store, &flags);
 | |
|     GetOCSPBasicRes(self, bs);
 | |
|     x509st = GetX509StorePtr(store);
 | |
|     flg = NIL_P(flags) ? 0 : NUM2INT(flags);
 | |
|     x509s = ossl_x509_ary2sk(certs);
 | |
| #if (OPENSSL_VERSION_NUMBER < 0x1000202fL) || defined(LIBRESSL_VERSION_NUMBER)
 | |
|     /*
 | |
|      * OpenSSL had a bug that it doesn't use the certificates in x509s for
 | |
|      * verifying the chain. This can be a problem when the response is signed by
 | |
|      * a certificate issued by an intermediate CA.
 | |
|      *
 | |
|      *       root_ca
 | |
|      *         |
 | |
|      *   intermediate_ca
 | |
|      *         |-------------|
 | |
|      *     end_entity    ocsp_signer
 | |
|      *
 | |
|      * When the certificate hierarchy is like this, and the response contains
 | |
|      * only ocsp_signer certificate, the following code wrongly fails.
 | |
|      *
 | |
|      *   store = OpenSSL::X509::Store.new; store.add_cert(root_ca)
 | |
|      *   basic_response.verify([intermediate_ca], store)
 | |
|      *
 | |
|      * So add the certificates in x509s to the embedded certificates list first.
 | |
|      *
 | |
|      * This is fixed in OpenSSL 0.9.8zg, 1.0.0s, 1.0.1n, 1.0.2b. But it still
 | |
|      * exists in LibreSSL 2.1.10, 2.2.9, 2.3.6, 2.4.1.
 | |
|      */
 | |
|     if (!(flg & (OCSP_NOCHAIN | OCSP_NOVERIFY)) &&
 | |
| 	sk_X509_num(x509s) && sk_X509_num(bs->certs)) {
 | |
| 	int i;
 | |
| 
 | |
| 	bs = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs);
 | |
| 	if (!bs) {
 | |
| 	    sk_X509_pop_free(x509s, X509_free);
 | |
| 	    ossl_raise(eOCSPError, "ASN1_item_dup");
 | |
| 	}
 | |
| 
 | |
| 	for (i = 0; i < sk_X509_num(x509s); i++) {
 | |
| 	    if (!OCSP_basic_add1_cert(bs, sk_X509_value(x509s, i))) {
 | |
| 		sk_X509_pop_free(x509s, X509_free);
 | |
| 		OCSP_BASICRESP_free(bs);
 | |
| 		ossl_raise(eOCSPError, "OCSP_basic_add1_cert");
 | |
| 	    }
 | |
| 	}
 | |
| 	result = OCSP_basic_verify(bs, x509s, x509st, flg);
 | |
| 	OCSP_BASICRESP_free(bs);
 | |
|     }
 | |
|     else {
 | |
| 	result = OCSP_basic_verify(bs, x509s, x509st, flg);
 | |
|     }
 | |
| #else
 | |
|     result = OCSP_basic_verify(bs, x509s, x509st, flg);
 | |
| #endif
 | |
|     sk_X509_pop_free(x509s, X509_free);
 | |
|     if (result <= 0)
 | |
| 	ossl_clear_error();
 | |
| 
 | |
|     return result > 0 ? Qtrue : Qfalse;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   basic_response.to_der -> String
 | |
|  *
 | |
|  * Encodes this basic response into a DER-encoded string.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspbres_to_der(VALUE self)
 | |
| {
 | |
|     OCSP_BASICRESP *res;
 | |
|     VALUE str;
 | |
|     long len;
 | |
|     unsigned char *p;
 | |
| 
 | |
|     GetOCSPBasicRes(self, res);
 | |
|     if ((len = i2d_OCSP_BASICRESP(res, NULL)) <= 0)
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     str = rb_str_new(0, len);
 | |
|     p = (unsigned char *)RSTRING_PTR(str);
 | |
|     if (i2d_OCSP_BASICRESP(res, &p) <= 0)
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     ossl_str_adjust(str, p);
 | |
| 
 | |
|     return str;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * OCSP::SingleResponse
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspsres_new(OCSP_SINGLERESP *sres)
 | |
| {
 | |
|     VALUE obj;
 | |
| 
 | |
|     obj = NewOCSPSingleRes(cOCSPSingleRes);
 | |
|     SetOCSPSingleRes(obj, sres);
 | |
| 
 | |
|     return obj;
 | |
| }
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspsres_alloc(VALUE klass)
 | |
| {
 | |
|     OCSP_SINGLERESP *sres;
 | |
|     VALUE obj;
 | |
| 
 | |
|     obj = NewOCSPSingleRes(klass);
 | |
|     if (!(sres = OCSP_SINGLERESP_new()))
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     SetOCSPSingleRes(obj, sres);
 | |
| 
 | |
|     return obj;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   OpenSSL::OCSP::SingleResponse.new(der_string) -> SingleResponse
 | |
|  *
 | |
|  * Creates a new SingleResponse from _der_string_.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspsres_initialize(VALUE self, VALUE arg)
 | |
| {
 | |
|     OCSP_SINGLERESP *res, *res_new;
 | |
|     const unsigned char *p;
 | |
| 
 | |
|     arg = ossl_to_der_if_possible(arg);
 | |
|     StringValue(arg);
 | |
|     GetOCSPSingleRes(self, res);
 | |
| 
 | |
|     p = (unsigned char*)RSTRING_PTR(arg);
 | |
|     res_new = d2i_OCSP_SINGLERESP(NULL, &p, RSTRING_LEN(arg));
 | |
|     if (!res_new)
 | |
| 	ossl_raise(eOCSPError, "d2i_OCSP_SINGLERESP");
 | |
|     SetOCSPSingleRes(self, res_new);
 | |
|     OCSP_SINGLERESP_free(res);
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspsres_initialize_copy(VALUE self, VALUE other)
 | |
| {
 | |
|     OCSP_SINGLERESP *sres, *sres_old, *sres_new;
 | |
| 
 | |
|     rb_check_frozen(self);
 | |
|     GetOCSPSingleRes(self, sres_old);
 | |
|     GetOCSPSingleRes(other, sres);
 | |
| 
 | |
|     sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres);
 | |
|     if (!sres_new)
 | |
| 	ossl_raise(eOCSPError, "ASN1_item_dup");
 | |
| 
 | |
|     SetOCSPSingleRes(self, sres_new);
 | |
|     OCSP_SINGLERESP_free(sres_old);
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   single_response.check_validity(nsec = 0, maxsec = -1) -> true | false
 | |
|  *
 | |
|  * Checks the validity of thisUpdate and nextUpdate fields of this
 | |
|  * SingleResponse. This checks the current time is within the range thisUpdate
 | |
|  * to nextUpdate.
 | |
|  *
 | |
|  * It is possible that the OCSP request takes a few seconds or the time is not
 | |
|  * accurate. To avoid rejecting a valid response, this method allows the times
 | |
|  * to be within _nsec_ seconds of the current time.
 | |
|  *
 | |
|  * Some responders don't set the nextUpdate field. This may cause a very old
 | |
|  * response to be considered valid. The _maxsec_ parameter can be used to limit
 | |
|  * the age of responses.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspsres_check_validity(int argc, VALUE *argv, VALUE self)
 | |
| {
 | |
|     OCSP_SINGLERESP *sres;
 | |
|     ASN1_GENERALIZEDTIME *this_update, *next_update;
 | |
|     VALUE nsec_v, maxsec_v;
 | |
|     int nsec, maxsec, status, ret;
 | |
| 
 | |
|     rb_scan_args(argc, argv, "02", &nsec_v, &maxsec_v);
 | |
|     nsec = NIL_P(nsec_v) ? 0 : NUM2INT(nsec_v);
 | |
|     maxsec = NIL_P(maxsec_v) ? -1 : NUM2INT(maxsec_v);
 | |
| 
 | |
|     GetOCSPSingleRes(self, sres);
 | |
|     status = OCSP_single_get0_status(sres, NULL, NULL, &this_update, &next_update);
 | |
|     if (status < 0)
 | |
| 	ossl_raise(eOCSPError, "OCSP_single_get0_status");
 | |
| 
 | |
|     ret = OCSP_check_validity(this_update, next_update, nsec, maxsec);
 | |
| 
 | |
|     if (ret)
 | |
| 	return Qtrue;
 | |
|     else {
 | |
| 	ossl_clear_error();
 | |
| 	return Qfalse;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   single_response.certid -> CertificateId
 | |
|  *
 | |
|  * Returns the CertificateId for which this SingleResponse is.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspsres_get_certid(VALUE self)
 | |
| {
 | |
|     OCSP_SINGLERESP *sres;
 | |
|     OCSP_CERTID *id;
 | |
| 
 | |
|     GetOCSPSingleRes(self, sres);
 | |
|     id = OCSP_CERTID_dup((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(sres)); /* FIXME */
 | |
| 
 | |
|     return ossl_ocspcertid_new(id);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   single_response.cert_status -> Integer
 | |
|  *
 | |
|  * Returns the status of the certificate identified by the certid.
 | |
|  * The return value may be one of these constant:
 | |
|  *
 | |
|  * - V_CERTSTATUS_GOOD
 | |
|  * - V_CERTSTATUS_REVOKED
 | |
|  * - V_CERTSTATUS_UNKNOWN
 | |
|  *
 | |
|  * When the status is V_CERTSTATUS_REVOKED, the time at which the certificate
 | |
|  * was revoked can be retrieved by #revocation_time.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspsres_get_cert_status(VALUE self)
 | |
| {
 | |
|     OCSP_SINGLERESP *sres;
 | |
|     int status;
 | |
| 
 | |
|     GetOCSPSingleRes(self, sres);
 | |
|     status = OCSP_single_get0_status(sres, NULL, NULL, NULL, NULL);
 | |
|     if (status < 0)
 | |
| 	ossl_raise(eOCSPError, "OCSP_single_get0_status");
 | |
| 
 | |
|     return INT2NUM(status);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   single_response.this_update -> Time
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspsres_get_this_update(VALUE self)
 | |
| {
 | |
|     OCSP_SINGLERESP *sres;
 | |
|     int status;
 | |
|     ASN1_GENERALIZEDTIME *time;
 | |
| 
 | |
|     GetOCSPSingleRes(self, sres);
 | |
|     status = OCSP_single_get0_status(sres, NULL, NULL, &time, NULL);
 | |
|     if (status < 0)
 | |
| 	ossl_raise(eOCSPError, "OCSP_single_get0_status");
 | |
|     if (!time)
 | |
| 	return Qnil;
 | |
| 
 | |
|     return asn1time_to_time(time);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   single_response.next_update -> Time | nil
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspsres_get_next_update(VALUE self)
 | |
| {
 | |
|     OCSP_SINGLERESP *sres;
 | |
|     int status;
 | |
|     ASN1_GENERALIZEDTIME *time;
 | |
| 
 | |
|     GetOCSPSingleRes(self, sres);
 | |
|     status = OCSP_single_get0_status(sres, NULL, NULL, NULL, &time);
 | |
|     if (status < 0)
 | |
| 	ossl_raise(eOCSPError, "OCSP_single_get0_status");
 | |
|     if (!time)
 | |
| 	return Qnil;
 | |
| 
 | |
|     return asn1time_to_time(time);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   single_response.revocation_time -> Time | nil
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspsres_get_revocation_time(VALUE self)
 | |
| {
 | |
|     OCSP_SINGLERESP *sres;
 | |
|     int status;
 | |
|     ASN1_GENERALIZEDTIME *time;
 | |
| 
 | |
|     GetOCSPSingleRes(self, sres);
 | |
|     status = OCSP_single_get0_status(sres, NULL, &time, NULL, NULL);
 | |
|     if (status < 0)
 | |
| 	ossl_raise(eOCSPError, "OCSP_single_get0_status");
 | |
|     if (status != V_OCSP_CERTSTATUS_REVOKED)
 | |
| 	ossl_raise(eOCSPError, "certificate is not revoked");
 | |
|     if (!time)
 | |
| 	return Qnil;
 | |
| 
 | |
|     return asn1time_to_time(time);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   single_response.revocation_reason -> Integer | nil
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspsres_get_revocation_reason(VALUE self)
 | |
| {
 | |
|     OCSP_SINGLERESP *sres;
 | |
|     int status, reason;
 | |
| 
 | |
|     GetOCSPSingleRes(self, sres);
 | |
|     status = OCSP_single_get0_status(sres, &reason, NULL, NULL, NULL);
 | |
|     if (status < 0)
 | |
| 	ossl_raise(eOCSPError, "OCSP_single_get0_status");
 | |
|     if (status != V_OCSP_CERTSTATUS_REVOKED)
 | |
| 	ossl_raise(eOCSPError, "certificate is not revoked");
 | |
| 
 | |
|     return INT2NUM(reason);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   single_response.extensions -> Array of X509::Extension
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspsres_get_extensions(VALUE self)
 | |
| {
 | |
|     OCSP_SINGLERESP *sres;
 | |
|     X509_EXTENSION *ext;
 | |
|     int count, i;
 | |
|     VALUE ary;
 | |
| 
 | |
|     GetOCSPSingleRes(self, sres);
 | |
| 
 | |
|     count = OCSP_SINGLERESP_get_ext_count(sres);
 | |
|     ary = rb_ary_new2(count);
 | |
|     for (i = 0; i < count; i++) {
 | |
| 	ext = OCSP_SINGLERESP_get_ext(sres, i);
 | |
| 	rb_ary_push(ary, ossl_x509ext_new(ext)); /* will dup */
 | |
|     }
 | |
| 
 | |
|     return ary;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   single_response.to_der -> String
 | |
|  *
 | |
|  * Encodes this SingleResponse into a DER-encoded string.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspsres_to_der(VALUE self)
 | |
| {
 | |
|     OCSP_SINGLERESP *sres;
 | |
|     VALUE str;
 | |
|     long len;
 | |
|     unsigned char *p;
 | |
| 
 | |
|     GetOCSPSingleRes(self, sres);
 | |
|     if ((len = i2d_OCSP_SINGLERESP(sres, NULL)) <= 0)
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     str = rb_str_new(0, len);
 | |
|     p = (unsigned char *)RSTRING_PTR(str);
 | |
|     if (i2d_OCSP_SINGLERESP(sres, &p) <= 0)
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     ossl_str_adjust(str, p);
 | |
| 
 | |
|     return str;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * OCSP::CertificateId
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspcid_alloc(VALUE klass)
 | |
| {
 | |
|     OCSP_CERTID *id;
 | |
|     VALUE obj;
 | |
| 
 | |
|     obj = NewOCSPCertId(klass);
 | |
|     if(!(id = OCSP_CERTID_new()))
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     SetOCSPCertId(obj, id);
 | |
| 
 | |
|     return obj;
 | |
| }
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspcid_initialize_copy(VALUE self, VALUE other)
 | |
| {
 | |
|     OCSP_CERTID *cid, *cid_old, *cid_new;
 | |
| 
 | |
|     rb_check_frozen(self);
 | |
|     GetOCSPCertId(self, cid_old);
 | |
|     GetOCSPCertId(other, cid);
 | |
| 
 | |
|     cid_new = OCSP_CERTID_dup(cid);
 | |
|     if (!cid_new)
 | |
| 	ossl_raise(eOCSPError, "OCSP_CERTID_dup");
 | |
| 
 | |
|     SetOCSPCertId(self, cid_new);
 | |
|     OCSP_CERTID_free(cid_old);
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   OpenSSL::OCSP::CertificateId.new(subject, issuer, digest = nil) -> certificate_id
 | |
|  *   OpenSSL::OCSP::CertificateId.new(der_string)                    -> certificate_id
 | |
|  *
 | |
|  * Creates a new OpenSSL::OCSP::CertificateId for the given _subject_ and
 | |
|  * _issuer_ X509 certificates.  The _digest_ is a digest algorithm that is used
 | |
|  * to compute the hash values. This defaults to SHA-1.
 | |
|  *
 | |
|  * If only one argument is given, decodes it as DER representation of a
 | |
|  * certificate ID.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self)
 | |
| {
 | |
|     OCSP_CERTID *id, *newid;
 | |
|     VALUE subject, issuer, digest;
 | |
| 
 | |
|     GetOCSPCertId(self, id);
 | |
|     if (rb_scan_args(argc, argv, "12", &subject, &issuer, &digest) == 1) {
 | |
| 	VALUE arg;
 | |
| 	const unsigned char *p;
 | |
| 
 | |
| 	arg = ossl_to_der_if_possible(subject);
 | |
| 	StringValue(arg);
 | |
| 	p = (unsigned char *)RSTRING_PTR(arg);
 | |
| 	newid = d2i_OCSP_CERTID(NULL, &p, RSTRING_LEN(arg));
 | |
| 	if (!newid)
 | |
| 	    ossl_raise(eOCSPError, "d2i_OCSP_CERTID");
 | |
|     }
 | |
|     else {
 | |
| 	X509 *x509s, *x509i;
 | |
| 	const EVP_MD *md;
 | |
| 
 | |
| 	x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */
 | |
| 	x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */
 | |
| 	md = !NIL_P(digest) ? ossl_evp_get_digestbyname(digest) : NULL;
 | |
| 
 | |
| 	newid = OCSP_cert_to_id(md, x509s, x509i);
 | |
| 	if (!newid)
 | |
| 	    ossl_raise(eOCSPError, "OCSP_cert_to_id");
 | |
|     }
 | |
| 
 | |
|     SetOCSPCertId(self, newid);
 | |
|     OCSP_CERTID_free(id);
 | |
| 
 | |
|     return self;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   certificate_id.cmp(other) -> true or false
 | |
|  *
 | |
|  * Compares this certificate id with _other_ and returns +true+ if they are the
 | |
|  * same.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspcid_cmp(VALUE self, VALUE other)
 | |
| {
 | |
|     OCSP_CERTID *id, *id2;
 | |
|     int result;
 | |
| 
 | |
|     GetOCSPCertId(self, id);
 | |
|     GetOCSPCertId(other, id2);
 | |
|     result = OCSP_id_cmp(id, id2);
 | |
| 
 | |
|     return (result == 0) ? Qtrue : Qfalse;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   certificate_id.cmp_issuer(other) -> true or false
 | |
|  *
 | |
|  * Compares this certificate id's issuer with _other_ and returns +true+ if
 | |
|  * they are the same.
 | |
|  */
 | |
| 
 | |
| static VALUE
 | |
| ossl_ocspcid_cmp_issuer(VALUE self, VALUE other)
 | |
| {
 | |
|     OCSP_CERTID *id, *id2;
 | |
|     int result;
 | |
| 
 | |
|     GetOCSPCertId(self, id);
 | |
|     GetOCSPCertId(other, id2);
 | |
|     result = OCSP_id_issuer_cmp(id, id2);
 | |
| 
 | |
|     return (result == 0) ? Qtrue : Qfalse;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   certificate_id.serial -> Integer
 | |
|  *
 | |
|  * Returns the serial number of the certificate for which status is being
 | |
|  * requested.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspcid_get_serial(VALUE self)
 | |
| {
 | |
|     OCSP_CERTID *id;
 | |
|     ASN1_INTEGER *serial;
 | |
| 
 | |
|     GetOCSPCertId(self, id);
 | |
|     OCSP_id_get0_info(NULL, NULL, NULL, &serial, id);
 | |
| 
 | |
|     return asn1integer_to_num(serial);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   certificate_id.issuer_name_hash -> String
 | |
|  *
 | |
|  * Returns the issuerNameHash of this certificate ID, the hash of the
 | |
|  * issuer's distinguished name calculated with the hashAlgorithm.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspcid_get_issuer_name_hash(VALUE self)
 | |
| {
 | |
|     OCSP_CERTID *id;
 | |
|     ASN1_OCTET_STRING *name_hash;
 | |
|     VALUE ret;
 | |
| 
 | |
|     GetOCSPCertId(self, id);
 | |
|     OCSP_id_get0_info(&name_hash, NULL, NULL, NULL, id);
 | |
| 
 | |
|     ret = rb_str_new(NULL, name_hash->length * 2);
 | |
|     ossl_bin2hex(name_hash->data, RSTRING_PTR(ret), name_hash->length);
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   certificate_id.issuer_key_hash -> String
 | |
|  *
 | |
|  * Returns the issuerKeyHash of this certificate ID, the hash of the issuer's
 | |
|  * public key.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspcid_get_issuer_key_hash(VALUE self)
 | |
| {
 | |
|     OCSP_CERTID *id;
 | |
|     ASN1_OCTET_STRING *key_hash;
 | |
|     VALUE ret;
 | |
| 
 | |
|     GetOCSPCertId(self, id);
 | |
|     OCSP_id_get0_info(NULL, NULL, &key_hash, NULL, id);
 | |
| 
 | |
|     ret = rb_str_new(NULL, key_hash->length * 2);
 | |
|     ossl_bin2hex(key_hash->data, RSTRING_PTR(ret), key_hash->length);
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   certificate_id.hash_algorithm -> String
 | |
|  *
 | |
|  * Returns the ln (long name) of the hash algorithm used to generate
 | |
|  * the issuerNameHash and the issuerKeyHash values.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspcid_get_hash_algorithm(VALUE self)
 | |
| {
 | |
|     OCSP_CERTID *id;
 | |
|     ASN1_OBJECT *oid;
 | |
|     BIO *out;
 | |
| 
 | |
|     GetOCSPCertId(self, id);
 | |
|     OCSP_id_get0_info(NULL, &oid, NULL, NULL, id);
 | |
| 
 | |
|     if (!(out = BIO_new(BIO_s_mem())))
 | |
| 	ossl_raise(eOCSPError, "BIO_new");
 | |
| 
 | |
|     if (!i2a_ASN1_OBJECT(out, oid)) {
 | |
| 	BIO_free(out);
 | |
| 	ossl_raise(eOCSPError, "i2a_ASN1_OBJECT");
 | |
|     }
 | |
|     return ossl_membio2str(out);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * call-seq:
 | |
|  *   certificate_id.to_der -> String
 | |
|  *
 | |
|  * Encodes this certificate identifier into a DER-encoded string.
 | |
|  */
 | |
| static VALUE
 | |
| ossl_ocspcid_to_der(VALUE self)
 | |
| {
 | |
|     OCSP_CERTID *id;
 | |
|     VALUE str;
 | |
|     long len;
 | |
|     unsigned char *p;
 | |
| 
 | |
|     GetOCSPCertId(self, id);
 | |
|     if ((len = i2d_OCSP_CERTID(id, NULL)) <= 0)
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     str = rb_str_new(0, len);
 | |
|     p = (unsigned char *)RSTRING_PTR(str);
 | |
|     if (i2d_OCSP_CERTID(id, &p) <= 0)
 | |
| 	ossl_raise(eOCSPError, NULL);
 | |
|     ossl_str_adjust(str, p);
 | |
| 
 | |
|     return str;
 | |
| }
 | |
| 
 | |
| void
 | |
| Init_ossl_ocsp(void)
 | |
| {
 | |
| #if 0
 | |
|     mOSSL = rb_define_module("OpenSSL");
 | |
|     eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
 | |
| #endif
 | |
| 
 | |
|     /*
 | |
|      * OpenSSL::OCSP implements Online Certificate Status Protocol requests
 | |
|      * and responses.
 | |
|      *
 | |
|      * Creating and sending an OCSP request requires a subject certificate
 | |
|      * that contains an OCSP URL in an authorityInfoAccess extension and the
 | |
|      * issuer certificate for the subject certificate.  First, load the issuer
 | |
|      * and subject certificates:
 | |
|      *
 | |
|      *   subject = OpenSSL::X509::Certificate.new subject_pem
 | |
|      *   issuer  = OpenSSL::X509::Certificate.new issuer_pem
 | |
|      *
 | |
|      * To create the request we need to create a certificate ID for the
 | |
|      * subject certificate so the CA knows which certificate we are asking
 | |
|      * about:
 | |
|      *
 | |
|      *   digest = OpenSSL::Digest::SHA1.new
 | |
|      *   certificate_id =
 | |
|      *     OpenSSL::OCSP::CertificateId.new subject, issuer, digest
 | |
|      *
 | |
|      * Then create a request and add the certificate ID to it:
 | |
|      *
 | |
|      *   request = OpenSSL::OCSP::Request.new
 | |
|      *   request.add_certid certificate_id
 | |
|      *
 | |
|      * Adding a nonce to the request protects against replay attacks but not
 | |
|      * all CA process the nonce.
 | |
|      *
 | |
|      *   request.add_nonce
 | |
|      *
 | |
|      * To submit the request to the CA for verification we need to extract the
 | |
|      * OCSP URI from the subject certificate:
 | |
|      *
 | |
|      *   authority_info_access = subject.extensions.find do |extension|
 | |
|      *     extension.oid == 'authorityInfoAccess'
 | |
|      *   end
 | |
|      *
 | |
|      *   descriptions = authority_info_access.value.split "\n"
 | |
|      *   ocsp = descriptions.find do |description|
 | |
|      *     description.start_with? 'OCSP'
 | |
|      *   end
 | |
|      *
 | |
|      *   require 'uri'
 | |
|      *
 | |
|      *   ocsp_uri = URI ocsp[/URI:(.*)/, 1]
 | |
|      *
 | |
|      * To submit the request we'll POST the request to the OCSP URI (per RFC
 | |
|      * 2560).  Note that we only handle HTTP requests and don't handle any
 | |
|      * redirects in this example, so this is insufficient for serious use.
 | |
|      *
 | |
|      *   require 'net/http'
 | |
|      *
 | |
|      *   http_response =
 | |
|      *     Net::HTTP.start ocsp_uri.hostname, ocsp.port do |http|
 | |
|      *       http.post ocsp_uri.path, request.to_der,
 | |
|      *                 'content-type' => 'application/ocsp-request'
 | |
|      *   end
 | |
|      *
 | |
|      *   response = OpenSSL::OCSP::Response.new http_response.body
 | |
|      *   response_basic = response.basic
 | |
|      *
 | |
|      * First we check if the response has a valid signature.  Without a valid
 | |
|      * signature we cannot trust it.  If you get a failure here you may be
 | |
|      * missing a system certificate store or may be missing the intermediate
 | |
|      * certificates.
 | |
|      *
 | |
|      *   store = OpenSSL::X509::Store.new
 | |
|      *   store.set_default_paths
 | |
|      *
 | |
|      *   unless response_basic.verify [], store then
 | |
|      *     raise 'response is not signed by a trusted certificate'
 | |
|      *   end
 | |
|      *
 | |
|      * The response contains the status information (success/fail).  We can
 | |
|      * display the status as a string:
 | |
|      *
 | |
|      *   puts response.status_string #=> successful
 | |
|      *
 | |
|      * Next we need to know the response details to determine if the response
 | |
|      * matches our request.  First we check the nonce.  Again, not all CAs
 | |
|      * support a nonce.  See Request#check_nonce for the meanings of the
 | |
|      * return values.
 | |
|      *
 | |
|      *   p request.check_nonce basic_response #=> value from -1 to 3
 | |
|      *
 | |
|      * Then extract the status information for the certificate from the basic
 | |
|      * response.
 | |
|      *
 | |
|      *   single_response = basic_response.find_response(certificate_id)
 | |
|      *
 | |
|      *   unless single_response
 | |
|      *     raise 'basic_response does not have the status for the certificiate'
 | |
|      *   end
 | |
|      *
 | |
|      * Then check the validity. A status issued in the future must be rejected.
 | |
|      *
 | |
|      *   unless single_response.check_validity
 | |
|      *     raise 'this_update is in the future or next_update time has passed'
 | |
|      *   end
 | |
|      *
 | |
|      *   case single_response.cert_status
 | |
|      *   when OpenSSL::OCSP::V_CERTSTATUS_GOOD
 | |
|      *     puts 'certificate is still valid'
 | |
|      *   when OpenSSL::OCSP::V_CERTSTATUS_REVOKED
 | |
|      *     puts "certificate has been revoked at #{single_response.revocation_time}"
 | |
|      *   when OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN
 | |
|      *     puts 'responder doesn't know about the certificate'
 | |
|      *   end
 | |
|      */
 | |
| 
 | |
|     mOCSP = rb_define_module_under(mOSSL, "OCSP");
 | |
| 
 | |
|     /*
 | |
|      * OCSP error class.
 | |
|      */
 | |
| 
 | |
|     eOCSPError = rb_define_class_under(mOCSP, "OCSPError", eOSSLError);
 | |
| 
 | |
|     /*
 | |
|      * An OpenSSL::OCSP::Request contains the certificate information for
 | |
|      * determining if a certificate has been revoked or not.  A Request can be
 | |
|      * created for a certificate or from a DER-encoded request created
 | |
|      * elsewhere.
 | |
|      */
 | |
| 
 | |
|     cOCSPReq = rb_define_class_under(mOCSP, "Request", rb_cObject);
 | |
|     rb_define_alloc_func(cOCSPReq, ossl_ocspreq_alloc);
 | |
|     rb_define_method(cOCSPReq, "initialize_copy", ossl_ocspreq_initialize_copy, 1);
 | |
|     rb_define_method(cOCSPReq, "initialize", ossl_ocspreq_initialize, -1);
 | |
|     rb_define_method(cOCSPReq, "add_nonce", ossl_ocspreq_add_nonce, -1);
 | |
|     rb_define_method(cOCSPReq, "check_nonce", ossl_ocspreq_check_nonce, 1);
 | |
|     rb_define_method(cOCSPReq, "add_certid", ossl_ocspreq_add_certid, 1);
 | |
|     rb_define_method(cOCSPReq, "certid", ossl_ocspreq_get_certid, 0);
 | |
|     rb_define_method(cOCSPReq, "signed?", ossl_ocspreq_signed_p, 0);
 | |
|     rb_define_method(cOCSPReq, "sign", ossl_ocspreq_sign, -1);
 | |
|     rb_define_method(cOCSPReq, "verify", ossl_ocspreq_verify, -1);
 | |
|     rb_define_method(cOCSPReq, "to_der", ossl_ocspreq_to_der, 0);
 | |
| 
 | |
|     /*
 | |
|      * An OpenSSL::OCSP::Response contains the status of a certificate check
 | |
|      * which is created from an OpenSSL::OCSP::Request.
 | |
|      */
 | |
| 
 | |
|     cOCSPRes = rb_define_class_under(mOCSP, "Response", rb_cObject);
 | |
|     rb_define_singleton_method(cOCSPRes, "create", ossl_ocspres_s_create, 2);
 | |
|     rb_define_alloc_func(cOCSPRes, ossl_ocspres_alloc);
 | |
|     rb_define_method(cOCSPRes, "initialize_copy", ossl_ocspres_initialize_copy, 1);
 | |
|     rb_define_method(cOCSPRes, "initialize", ossl_ocspres_initialize, -1);
 | |
|     rb_define_method(cOCSPRes, "status", ossl_ocspres_status, 0);
 | |
|     rb_define_method(cOCSPRes, "status_string", ossl_ocspres_status_string, 0);
 | |
|     rb_define_method(cOCSPRes, "basic", ossl_ocspres_get_basic, 0);
 | |
|     rb_define_method(cOCSPRes, "to_der", ossl_ocspres_to_der, 0);
 | |
| 
 | |
|     /*
 | |
|      * An OpenSSL::OCSP::BasicResponse contains the status of a certificate
 | |
|      * check which is created from an OpenSSL::OCSP::Request.  A
 | |
|      * BasicResponse is more detailed than a Response.
 | |
|      */
 | |
| 
 | |
|     cOCSPBasicRes = rb_define_class_under(mOCSP, "BasicResponse", rb_cObject);
 | |
|     rb_define_alloc_func(cOCSPBasicRes, ossl_ocspbres_alloc);
 | |
|     rb_define_method(cOCSPBasicRes, "initialize_copy", ossl_ocspbres_initialize_copy, 1);
 | |
|     rb_define_method(cOCSPBasicRes, "initialize", ossl_ocspbres_initialize, -1);
 | |
|     rb_define_method(cOCSPBasicRes, "copy_nonce", ossl_ocspbres_copy_nonce, 1);
 | |
|     rb_define_method(cOCSPBasicRes, "add_nonce", ossl_ocspbres_add_nonce, -1);
 | |
|     rb_define_method(cOCSPBasicRes, "add_status", ossl_ocspbres_add_status, 7);
 | |
|     rb_define_method(cOCSPBasicRes, "status", ossl_ocspbres_get_status, 0);
 | |
|     rb_define_method(cOCSPBasicRes, "responses", ossl_ocspbres_get_responses, 0);
 | |
|     rb_define_method(cOCSPBasicRes, "find_response", ossl_ocspbres_find_response, 1);
 | |
|     rb_define_method(cOCSPBasicRes, "sign", ossl_ocspbres_sign, -1);
 | |
|     rb_define_method(cOCSPBasicRes, "verify", ossl_ocspbres_verify, -1);
 | |
|     rb_define_method(cOCSPBasicRes, "to_der", ossl_ocspbres_to_der, 0);
 | |
| 
 | |
|     /*
 | |
|      * An OpenSSL::OCSP::SingleResponse represents an OCSP SingleResponse
 | |
|      * structure, which contains the basic information of the status of the
 | |
|      * certificate.
 | |
|      */
 | |
|     cOCSPSingleRes = rb_define_class_under(mOCSP, "SingleResponse", rb_cObject);
 | |
|     rb_define_alloc_func(cOCSPSingleRes, ossl_ocspsres_alloc);
 | |
|     rb_define_method(cOCSPSingleRes, "initialize_copy", ossl_ocspsres_initialize_copy, 1);
 | |
|     rb_define_method(cOCSPSingleRes, "initialize", ossl_ocspsres_initialize, 1);
 | |
|     rb_define_method(cOCSPSingleRes, "check_validity", ossl_ocspsres_check_validity, -1);
 | |
|     rb_define_method(cOCSPSingleRes, "certid", ossl_ocspsres_get_certid, 0);
 | |
|     rb_define_method(cOCSPSingleRes, "cert_status", ossl_ocspsres_get_cert_status, 0);
 | |
|     rb_define_method(cOCSPSingleRes, "this_update", ossl_ocspsres_get_this_update, 0);
 | |
|     rb_define_method(cOCSPSingleRes, "next_update", ossl_ocspsres_get_next_update, 0);
 | |
|     rb_define_method(cOCSPSingleRes, "revocation_time", ossl_ocspsres_get_revocation_time, 0);
 | |
|     rb_define_method(cOCSPSingleRes, "revocation_reason", ossl_ocspsres_get_revocation_reason, 0);
 | |
|     rb_define_method(cOCSPSingleRes, "extensions", ossl_ocspsres_get_extensions, 0);
 | |
|     rb_define_method(cOCSPSingleRes, "to_der", ossl_ocspsres_to_der, 0);
 | |
| 
 | |
|     /*
 | |
|      * An OpenSSL::OCSP::CertificateId identifies a certificate to the CA so
 | |
|      * that a status check can be performed.
 | |
|      */
 | |
| 
 | |
|     cOCSPCertId = rb_define_class_under(mOCSP, "CertificateId", rb_cObject);
 | |
|     rb_define_alloc_func(cOCSPCertId, ossl_ocspcid_alloc);
 | |
|     rb_define_method(cOCSPCertId, "initialize_copy", ossl_ocspcid_initialize_copy, 1);
 | |
|     rb_define_method(cOCSPCertId, "initialize", ossl_ocspcid_initialize, -1);
 | |
|     rb_define_method(cOCSPCertId, "cmp", ossl_ocspcid_cmp, 1);
 | |
|     rb_define_method(cOCSPCertId, "cmp_issuer", ossl_ocspcid_cmp_issuer, 1);
 | |
|     rb_define_method(cOCSPCertId, "serial", ossl_ocspcid_get_serial, 0);
 | |
|     rb_define_method(cOCSPCertId, "issuer_name_hash", ossl_ocspcid_get_issuer_name_hash, 0);
 | |
|     rb_define_method(cOCSPCertId, "issuer_key_hash", ossl_ocspcid_get_issuer_key_hash, 0);
 | |
|     rb_define_method(cOCSPCertId, "hash_algorithm", ossl_ocspcid_get_hash_algorithm, 0);
 | |
|     rb_define_method(cOCSPCertId, "to_der", ossl_ocspcid_to_der, 0);
 | |
| 
 | |
|     /* Internal error in issuer */
 | |
|     rb_define_const(mOCSP, "RESPONSE_STATUS_INTERNALERROR", INT2NUM(OCSP_RESPONSE_STATUS_INTERNALERROR));
 | |
| 
 | |
|     /* Illegal confirmation request */
 | |
|     rb_define_const(mOCSP, "RESPONSE_STATUS_MALFORMEDREQUEST", INT2NUM(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST));
 | |
| 
 | |
|     /* The certificate was revoked for an unknown reason */
 | |
|     rb_define_const(mOCSP, "REVOKED_STATUS_NOSTATUS", INT2NUM(OCSP_REVOKED_STATUS_NOSTATUS));
 | |
| 
 | |
|     /* You must sign the request and resubmit */
 | |
|     rb_define_const(mOCSP, "RESPONSE_STATUS_SIGREQUIRED", INT2NUM(OCSP_RESPONSE_STATUS_SIGREQUIRED));
 | |
| 
 | |
|     /* Response has valid confirmations */
 | |
|     rb_define_const(mOCSP, "RESPONSE_STATUS_SUCCESSFUL", INT2NUM(OCSP_RESPONSE_STATUS_SUCCESSFUL));
 | |
| 
 | |
|     /* Try again later */
 | |
|     rb_define_const(mOCSP, "RESPONSE_STATUS_TRYLATER", INT2NUM(OCSP_RESPONSE_STATUS_TRYLATER));
 | |
| 
 | |
|     /* The certificate subject's name or other information changed */
 | |
|     rb_define_const(mOCSP, "REVOKED_STATUS_AFFILIATIONCHANGED", INT2NUM(OCSP_REVOKED_STATUS_AFFILIATIONCHANGED));
 | |
| 
 | |
|     /* This CA certificate was revoked due to a key compromise */
 | |
|     rb_define_const(mOCSP, "REVOKED_STATUS_CACOMPROMISE", INT2NUM(OCSP_REVOKED_STATUS_CACOMPROMISE));
 | |
| 
 | |
|     /* The certificate is on hold */
 | |
|     rb_define_const(mOCSP, "REVOKED_STATUS_CERTIFICATEHOLD", INT2NUM(OCSP_REVOKED_STATUS_CERTIFICATEHOLD));
 | |
| 
 | |
|     /* The certificate is no longer needed */
 | |
|     rb_define_const(mOCSP, "REVOKED_STATUS_CESSATIONOFOPERATION", INT2NUM(OCSP_REVOKED_STATUS_CESSATIONOFOPERATION));
 | |
| 
 | |
|     /* The certificate was revoked due to a key compromise */
 | |
|     rb_define_const(mOCSP, "REVOKED_STATUS_KEYCOMPROMISE", INT2NUM(OCSP_REVOKED_STATUS_KEYCOMPROMISE));
 | |
| 
 | |
|     /* The certificate was previously on hold and should now be removed from
 | |
|      * the CRL */
 | |
|     rb_define_const(mOCSP, "REVOKED_STATUS_REMOVEFROMCRL", INT2NUM(OCSP_REVOKED_STATUS_REMOVEFROMCRL));
 | |
| 
 | |
|     /* The certificate was superseded by a new certificate */
 | |
|     rb_define_const(mOCSP, "REVOKED_STATUS_SUPERSEDED", INT2NUM(OCSP_REVOKED_STATUS_SUPERSEDED));
 | |
| 
 | |
|     /* Your request is unauthorized. */
 | |
|     rb_define_const(mOCSP, "RESPONSE_STATUS_UNAUTHORIZED", INT2NUM(OCSP_RESPONSE_STATUS_UNAUTHORIZED));
 | |
| 
 | |
|     /* The certificate was revoked for an unspecified reason */
 | |
|     rb_define_const(mOCSP, "REVOKED_STATUS_UNSPECIFIED", INT2NUM(OCSP_REVOKED_STATUS_UNSPECIFIED));
 | |
| 
 | |
|     /* Do not include certificates in the response */
 | |
|     rb_define_const(mOCSP, "NOCERTS", INT2NUM(OCSP_NOCERTS));
 | |
| 
 | |
|     /* Do not search certificates contained in the response for a signer */
 | |
|     rb_define_const(mOCSP, "NOINTERN", INT2NUM(OCSP_NOINTERN));
 | |
| 
 | |
|     /* Do not check the signature on the response */
 | |
|     rb_define_const(mOCSP, "NOSIGS", INT2NUM(OCSP_NOSIGS));
 | |
| 
 | |
|     /* Do not verify the certificate chain on the response */
 | |
|     rb_define_const(mOCSP, "NOCHAIN", INT2NUM(OCSP_NOCHAIN));
 | |
| 
 | |
|     /* Do not verify the response at all */
 | |
|     rb_define_const(mOCSP, "NOVERIFY", INT2NUM(OCSP_NOVERIFY));
 | |
| 
 | |
|     /* Do not check trust */
 | |
|     rb_define_const(mOCSP, "NOEXPLICIT", INT2NUM(OCSP_NOEXPLICIT));
 | |
| 
 | |
|     /* (This flag is not used by OpenSSL 1.0.1g) */
 | |
|     rb_define_const(mOCSP, "NOCASIGN", INT2NUM(OCSP_NOCASIGN));
 | |
| 
 | |
|     /* (This flag is not used by OpenSSL 1.0.1g) */
 | |
|     rb_define_const(mOCSP, "NODELEGATED", INT2NUM(OCSP_NODELEGATED));
 | |
| 
 | |
|     /* Do not make additional signing certificate checks */
 | |
|     rb_define_const(mOCSP, "NOCHECKS", INT2NUM(OCSP_NOCHECKS));
 | |
| 
 | |
|     /* Do not verify additional certificates */
 | |
|     rb_define_const(mOCSP, "TRUSTOTHER", INT2NUM(OCSP_TRUSTOTHER));
 | |
| 
 | |
|     /* Identify the response by signing the certificate key ID */
 | |
|     rb_define_const(mOCSP, "RESPID_KEY", INT2NUM(OCSP_RESPID_KEY));
 | |
| 
 | |
|     /* Do not include producedAt time in response */
 | |
|     rb_define_const(mOCSP, "NOTIME", INT2NUM(OCSP_NOTIME));
 | |
| 
 | |
|     /* Indicates the certificate is not revoked but does not necessarily mean
 | |
|      * the certificate was issued or that this response is within the
 | |
|      * certificate's validity interval */
 | |
|     rb_define_const(mOCSP, "V_CERTSTATUS_GOOD", INT2NUM(V_OCSP_CERTSTATUS_GOOD));
 | |
|     /* Indicates the certificate has been revoked either permanently or
 | |
|      * temporarily (on hold). */
 | |
|     rb_define_const(mOCSP, "V_CERTSTATUS_REVOKED", INT2NUM(V_OCSP_CERTSTATUS_REVOKED));
 | |
| 
 | |
|     /* Indicates the responder does not know about the certificate being
 | |
|      * requested. */
 | |
|     rb_define_const(mOCSP, "V_CERTSTATUS_UNKNOWN", INT2NUM(V_OCSP_CERTSTATUS_UNKNOWN));
 | |
| 
 | |
|     /* The responder ID is based on the key name. */
 | |
|     rb_define_const(mOCSP, "V_RESPID_NAME", INT2NUM(V_OCSP_RESPID_NAME));
 | |
| 
 | |
|     /* The responder ID is based on the public key. */
 | |
|     rb_define_const(mOCSP, "V_RESPID_KEY", INT2NUM(V_OCSP_RESPID_KEY));
 | |
| }
 | |
| #else
 | |
| void
 | |
| Init_ossl_ocsp(void)
 | |
| {
 | |
| }
 | |
| #endif
 |