class CertValidator::RealOcspValidator

Attributes

ca[R]
certificate[R]
logger[RW]

Public Class Methods

new(cert, ca) click to toggle source
# File lib/cert_validator/ocsp/real_validator.rb, line 14
def initialize(cert, ca)
  @certificate = cert
  @ca = ca

  @extractor = Extractor.new @certificate
end

Public Instance Methods

available?() click to toggle source
# File lib/cert_validator/ocsp/real_validator.rb, line 21
def available?
  @extractor.has_ocsp_extension?
end
valid?() click to toggle source
# File lib/cert_validator/ocsp/real_validator.rb, line 25
def valid?
  return false unless available?

  begin
    validate!
  rescue => e
    log e
    return false
  end
  
  return true
end
validate!() click to toggle source
# File lib/cert_validator/ocsp/real_validator.rb, line 38
def validate!
  raise FetchError.new unless http_body = fetch(request_uri)
  
  body = OpenSSL::OCSP::Response.new http_body

  check_ocsp_response body
  check_ocsp_payload body.basic.status.first
end

Private Instance Methods

cert_id() click to toggle source
# File lib/cert_validator/ocsp/real_validator.rb, line 113
def cert_id
  @cert_id ||= OpenSSL::OCSP::CertificateId.new certificate, ca
end
check_ocsp_payload(status) click to toggle source
# File lib/cert_validator/ocsp/real_validator.rb, line 67
def check_ocsp_payload(status)
  unless status[0].serial == certificate.serial
    raise SerialMisatch(got, expected) 
  end

  validity_range = (status[4]..status[5])
  unless validity_range.cover? Time.now
    raise NotValidNow.new(validity_range)
  end

  raise Revoked if status[1] == 1
  raise UnexpectedStatus(status[1]) if status[1] != 0
  
  return true
end
check_ocsp_response(body) click to toggle source
# File lib/cert_validator/ocsp/real_validator.rb, line 54
def check_ocsp_response(body)
  raise NonzeroStatus.new(body.status) unless body.status == 0
  raise ResponseMismatch.new unless body.basic.verify *verify_args
  raise MissingStatus.new unless body.basic.status.first

  # http://rdoc.info/stdlib/openssl/OpenSSL/OCSP/Request:check_nonce
  # greater than zero is acceptable
  nonce_result = req.check_nonce body.basic
  raise UnacceptableNonce.new(nonce_result) unless nonce_result > 0

  return true
end
fetch(uri) click to toggle source
# File lib/cert_validator/ocsp/real_validator.rb, line 106
def fetch(uri)
  resp = Net::HTTP.get_response URI(uri)
  return resp.body if resp.code == '200'

  return nil
end
log(msg) click to toggle source
# File lib/cert_validator/ocsp/real_validator.rb, line 48
def log(msg)
  return unless logger

  logger.info msg
end
req() click to toggle source
# File lib/cert_validator/ocsp/real_validator.rb, line 90
def req
  return @req if defined? @req

  @req = OpenSSL::OCSP::Request.new
  @req.add_nonce
  @req.add_certid cert_id

  return @req
end
request_uri() click to toggle source
# File lib/cert_validator/ocsp/real_validator.rb, line 100
def request_uri
  return @request_uri if defined? @request_uri
  pem = Base64.encode64(req.to_der).strip
  return @request_uri = URI(@extractor.endpoint + '/' + URI.encode_www_form_component(pem))
end
verify_args() click to toggle source
# File lib/cert_validator/ocsp/real_validator.rb, line 83
def verify_args
  store = OpenSSL::X509::Store.new
  store.add_cert ca

  [[ca], store]
end