Module: OpenSSL::OCSP
| Relationships & Source Files | |
| Namespace Children | |
|
Classes:
| |
|
Exceptions:
| |
| Defined in: | ext/openssl/ossl_ocsp.c |
Overview
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:
= subject.extensions.find do |extension|
extension.oid == 'authorityInfoAccess'
end
descriptions = .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
Constant Summary
-
NOCASIGN =
# File 'ext/openssl/ossl_ocsp.c', line 1978
(This flag is not used by
::OpenSSL1.0.1g)INT2NUM(OCSP_NOCASIGN)
-
NOCERTS =
# File 'ext/openssl/ossl_ocsp.c', line 1960
Do not include certificates in the response
INT2NUM(OCSP_NOCERTS)
-
NOCHAIN =
# File 'ext/openssl/ossl_ocsp.c', line 1969
Do not verify the certificate chain on the response
INT2NUM(OCSP_NOCHAIN)
-
NOCHECKS =
# File 'ext/openssl/ossl_ocsp.c', line 1984
Do not make additional signing certificate checks
INT2NUM(OCSP_NOCHECKS)
-
NODELEGATED =
# File 'ext/openssl/ossl_ocsp.c', line 1981
(This flag is not used by
::OpenSSL1.0.1g)INT2NUM(OCSP_NODELEGATED)
-
NOEXPLICIT =
# File 'ext/openssl/ossl_ocsp.c', line 1975
Do not check trust
INT2NUM(OCSP_NOEXPLICIT)
-
NOINTERN =
# File 'ext/openssl/ossl_ocsp.c', line 1963
Do not search certificates contained in the response for a signer
INT2NUM(OCSP_NOINTERN)
-
NOSIGS =
# File 'ext/openssl/ossl_ocsp.c', line 1966
Do not check the signature on the response
INT2NUM(OCSP_NOSIGS)
-
NOTIME =
# File 'ext/openssl/ossl_ocsp.c', line 1993
Do not include producedAt time in response
INT2NUM(OCSP_NOTIME)
-
NOVERIFY =
# File 'ext/openssl/ossl_ocsp.c', line 1972
Do not verify the response at all
INT2NUM(OCSP_NOVERIFY)
-
RESPID_KEY =
# File 'ext/openssl/ossl_ocsp.c', line 1990
Identify the response by signing the certificate key ID
INT2NUM(OCSP_RESPID_KEY)
-
RESPONSE_STATUS_INTERNALERROR =
# File 'ext/openssl/ossl_ocsp.c', line 1914
Internal error in issuer
INT2NUM(OCSP_RESPONSE_STATUS_INTERNALERROR)
-
RESPONSE_STATUS_MALFORMEDREQUEST =
# File 'ext/openssl/ossl_ocsp.c', line 1917
Illegal confirmation request
INT2NUM(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST)
-
RESPONSE_STATUS_SIGREQUIRED =
# File 'ext/openssl/ossl_ocsp.c', line 1923
You must sign the request and resubmit
INT2NUM(OCSP_RESPONSE_STATUS_SIGREQUIRED)
-
RESPONSE_STATUS_SUCCESSFUL =
# File 'ext/openssl/ossl_ocsp.c', line 1926
OCSP::Responsehas valid confirmationsINT2NUM(OCSP_RESPONSE_STATUS_SUCCESSFUL)
-
RESPONSE_STATUS_TRYLATER =
# File 'ext/openssl/ossl_ocsp.c', line 1929
Try again later
INT2NUM(OCSP_RESPONSE_STATUS_TRYLATER)
-
RESPONSE_STATUS_UNAUTHORIZED =
# File 'ext/openssl/ossl_ocsp.c', line 1954
Your request is unauthorized.
INT2NUM(OCSP_RESPONSE_STATUS_UNAUTHORIZED)
-
REVOKED_STATUS_AFFILIATIONCHANGED =
# File 'ext/openssl/ossl_ocsp.c', line 1932
The certificate subject’s name or other information changed
INT2NUM(OCSP_REVOKED_STATUS_AFFILIATIONCHANGED)
-
REVOKED_STATUS_CACOMPROMISE =
# File 'ext/openssl/ossl_ocsp.c', line 1935
This CA certificate was revoked due to a key compromise
INT2NUM(OCSP_REVOKED_STATUS_CACOMPROMISE)
-
REVOKED_STATUS_CERTIFICATEHOLD =
# File 'ext/openssl/ossl_ocsp.c', line 1938
The certificate is on hold
INT2NUM(OCSP_REVOKED_STATUS_CERTIFICATEHOLD)
-
REVOKED_STATUS_CESSATIONOFOPERATION =
# File 'ext/openssl/ossl_ocsp.c', line 1941
The certificate is no longer needed
INT2NUM(OCSP_REVOKED_STATUS_CESSATIONOFOPERATION)
-
REVOKED_STATUS_KEYCOMPROMISE =
# File 'ext/openssl/ossl_ocsp.c', line 1944
The certificate was revoked due to a key compromise
INT2NUM(OCSP_REVOKED_STATUS_KEYCOMPROMISE)
-
REVOKED_STATUS_NOSTATUS =
# File 'ext/openssl/ossl_ocsp.c', line 1920
The certificate was revoked for an unknown reason
INT2NUM(OCSP_REVOKED_STATUS_NOSTATUS)
-
REVOKED_STATUS_REMOVEFROMCRL =
# File 'ext/openssl/ossl_ocsp.c', line 1948
The certificate was previously on hold and should now be removed from the CRL
INT2NUM(OCSP_REVOKED_STATUS_REMOVEFROMCRL)
-
REVOKED_STATUS_SUPERSEDED =
# File 'ext/openssl/ossl_ocsp.c', line 1951
The certificate was superseded by a new certificate
INT2NUM(OCSP_REVOKED_STATUS_SUPERSEDED)
-
REVOKED_STATUS_UNSPECIFIED =
# File 'ext/openssl/ossl_ocsp.c', line 1957
The certificate was revoked for an unspecified reason
INT2NUM(OCSP_REVOKED_STATUS_UNSPECIFIED)
-
TRUSTOTHER =
# File 'ext/openssl/ossl_ocsp.c', line 1987
Do not verify additional certificates
INT2NUM(OCSP_TRUSTOTHER)
-
V_CERTSTATUS_GOOD =
# File 'ext/openssl/ossl_ocsp.c', line 1998
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
INT2NUM(V_OCSP_CERTSTATUS_GOOD)
-
V_CERTSTATUS_REVOKED =
# File 'ext/openssl/ossl_ocsp.c', line 2001
Indicates the certificate has been revoked either permanently or temporarily (on hold).
INT2NUM(V_OCSP_CERTSTATUS_REVOKED)
-
V_CERTSTATUS_UNKNOWN =
# File 'ext/openssl/ossl_ocsp.c', line 2005
Indicates the responder does not know about the certificate being requested.
INT2NUM(V_OCSP_CERTSTATUS_UNKNOWN)
-
V_RESPID_KEY =
# File 'ext/openssl/ossl_ocsp.c', line 2011
The responder ID is based on the public key.
INT2NUM(V_OCSP_RESPID_KEY)
-
V_RESPID_NAME =
# File 'ext/openssl/ossl_ocsp.c', line 2008
The responder ID is based on the key name.
INT2NUM(V_OCSP_RESPID_NAME)