OCSP Responders
A CA can delegate the signing of OCSP responses to a separate key pair, this is configured under the OCSP Responders page in the UI.
Certificate Specification
An OCSP responder uses a local key pair (defined in a Crypto Token), which in turn must be signed by the CA that the OCSP responder is answering for. Additionally, the certificate profile for this certificate must define the following:
- The certificate must have Key Usage: Digital Signature.
- The certificate must have Extended Key Usage: OCSPSigner.
- The certificate normally has the OCSP No Check extension enabled.
- The list of trusted certificates will be used to validate the OCSP request signature (if a signature is required).
- Additionally, a key binding can be used to sign responses for certificates issued by other CAs. They can be added to a list using the EJBCA CA GUI or EJBCA CLI. You can assign a CA to a maximum of one key binding.
Global OCSP Properties
The following covers global OCSP properties.
The Default Responder
The default responder is the valid CA or OCSP Keybinding set to sign responses to requests that come in for unknown issuers.
For all unknown issuers, the default responder will reply with an 'UNKNOWN' response. For external CAs without dedicated OCSP keybindings, the default responder will perform standard OCSP lookups. Be aware that this may cause unexpected behavior in the case of where an inactivated (due to responder certificate being revoked or expiring) keybinding exists, and that keybinding has a different behavior in regards to unknown certificates than the default responder.
If no default responder is defined, is defined incorrectly, or the chosen responder doesn't have a certificate, the responder will reply "Unauthorized" (as per RFC2560) with a null payload.
Enabling the NONCE Extension in OCSP Replies from CAs
The OCSP NONCE extension (as defined in RFC6960 4.4.1) allows the mitigation of replay attacks by including a nonce sent in with the OCSP request as part of the signed response. The NONCE extension can be enabled individually for OCSP Responders, or set globally for CA's acting as their own responders here.
Responder ID Type for CAs
As defined in RFC6960 4.2.1, the responder ID type can be set as keyhash or name. For individual OCSP responders, this is configured per responder, but for CAs acting as their own responder, this is chosen globally here.
OCSP Signing Cache Update
Controls if the OCSP signing cache update is enabled or not. The default is that the cache update is disabled (Enable OCSP signing cache update is cleared).
Prior to EJBCA 7.4.1, the cache update was enabled by default, and searching for missing entries for unknown CAs in the cache was always performed. Note that it only comes into effect when new CAs are created or already existing CAs are renewed. If the old behavior is needed, the Enable OCSP signing cache update option must be selected to enable OCSP signing cache update.
Enable OCSP Cache Headers for Unauthorized Responses
By default, responses with the status Unauthorized do not include any cache headers. By enabling this option, unauthorized responses will contain a no-cache header.
OCSP Responder Properties
This section described the properties set for each responder
General Properties
Property | Description |
---|---|
Id | Unique identifying number. |
Name | A unique and human readable name. |
Crypto Token | The Crypto Token where we reference a key pair. |
Key Pair Alias | A reference to the currently used key pair in the specified Crypto Token. |
Signature Algorithm | The signature algorithm user during signing, for example the signing of an OCSP response. |
Next Key Pair Alias | A reference to the next key pair to use in the specified Crypto Token when renewing. |
Request Signers
Each OCSP Responder can be set to require requests to be signed. If enabled (by setting Request must be signed with a trusted certificate below), the OCSP responder will accept requests signed by a key pair certified by any known CA.
This can be further restricted to individual CAs, or down to individual certificates issued by those CAs.
Note that Request must be signed with a trusted certificate must be checked for this setting to have effect.
OCSP Response Delegation
While not a common use case, an OCSP Responder can also be configured to answer requests for certificates issued by other CAs.
By selecting CAs from the list and clicking Add, the responder will respond to OCSP requests addressed to those CAs.
This feature can be used for signing responses for any CA. For example, if for the following chain of RootCA → SubCALevel1 → SubCALevel2 → SubCALevel3, the SubCaLevel2 is used to issue the OCSP responder, then the RootCA, SubCALevel1, and SubCALevel3 can be added to this list of the corresponding responder. Note that there is no need to add SubCaLevel2 to the list as the responder will automatically sign responses for it. Additionally, if there are CAs like SomeOtherRootCA, AnotherRootCA → AnotherSubCA, then they can also be added to the list. Any external CA or CAs signed by external CAs are also supported and the functionality is available for both CAs and VAs.
Responses generated on behalf of other CAs can be verified using OpenSSL by a command similar to the following:
ocsp on behalf verification
openssl ocsp -url http://localhost:8080/ejbca/publicweb/status/ocsp -issuer 'Issuer_of_end_entity.cacert.pem' -cert entity-certificate-chain.pem -req_text -resp_text -VAfile ocsp-responder-cert.pem -CAfile issuer-of-ocsp-keybinding.cacert.pem
Hence, the -issuer
argument is for the issuer of the end entity. The -CAfile
is the issuer of the OCSP responder certificate, while -cert
is the certificate for which the OCSP inquiry is to be done, and -VAfile
is the OCSP responder certificate.
OCSP Specific Properties
Property | Description |
---|---|
Non existing is good | If true a certificate that does not exist in the database, but is issued by a CA known to the VA, it will be treated as not revoked. Default (when both this value and value of "Non existing is revoked" are false) is to treat it as "unknown". Since the OCSP responders database normally contains all issued certificate this gives sensible values (in line with RFC6960) to "ok", "revoked" and "unknown" certificates. Setting this value to true is useful if you want an External OCSP responder database to only contain revoked certificates, and not all certificates. In this case, the responder will answer "ok" to requests for certificates that do not exist in the database. |
Non existing is revoked | If true a certificate that does not exist in the database, but is issued by a CA known to the VA, it will be treated as revoked; the revocation reason will be "Certificate Hold" and the revocation time is January 1st, 1970. Default (when this value and value of "Non existing is good" are false) is to treat it as "unknown". |
Non existing is unauthorized | If true a certificate that does not exist in the database, but is issued by a CA known to the VA, the VA will respond with an unsigned "Unauthorized" message to show that it is unable to process the request. The advantage to this configuration is that it doesn't require the VA to perform a signature, mitigating the risk of DOS attacks by swamping the VA with OCSP requests for unknown serial numbers. |
Max-Age HTTP header (seconds) | A hint to caching proxies when using HTTP GET for how long to retain a response, and should be set to a value lesser than or equal to the response validity. A value of 0 means no caching. |
Request must be signed with a trusted certificate | When true, request signatures will be checked against the list of trusted certificates or trust anchors. |
Response validity (seconds) | How long the OCSP response is valid and may be used. A value of 0 means that there is always a newer response available. |
ResponderID | Defines the ResponderID type included in the response. The ResponderID is either a Name (SubjectDN of the signing certificate used for response) or Keyhash (SHA-1 digest of the public key of the signing certificate used for response). |
Include signing certificate in response | When true, the signing certificate will be included in the response. |
Include certificate chain in response | When true, the entire certificate chain, except for the root CA certificate, will be included in the response (note that this is only applicable if 'Include signing certificate in response' is true). |
Enable nonce in response | When true, if the OCSP request contains a nonce, the response will contain a nonce as well. If false, a nonce will never be in the response, even if one is included in the request. |
Omit reason code if revocation reason is unspecified (CABF compliance) | Enabled by default. CA/B Forum Baseline Requirements 1.7.1+ require that reason code is omitted when it is Unspecified. Disable the property to disregard this requirement. |
Extensions
OCSP extensions are chosen individually per responder as per below.
Extensions that require no request input (such as CertHash) are always returned if enabled, whether specified in the request or not.
nonce
Nonce is the only standard extension defined, and is not configured here but in the general properties above. The nonce allows a client to verify that a response really is in response to the specific requests, and not a replayed response. It is recommended that if the OCSP requests contain the nonce extension, the OCSP response also contains the nonce. EJBCA includes the nonce from the client requests in the server response if the requests contain a nonce. The OCSP nonce extension can be disabled both per OCSP Keybinding, and also globally for all CAs acting as their own OCSP responders. Disabling nonces globally will not affect whether OCSP keybindings use the nonce extension in their responses.
Fnr-Unid Mapping Extension
For information on the Unid functionality, see Unid FNR.
CertHash OCSP Extension
For information on the CertHash functionality, see CertificateHash.
Archive Cutoff Extension
The archive cutoff extension is defined in RFC 6960 section 4.4.4 and is used to "contribute to a proof that a digital signature was (or was not) reliable on the date it was produced even if the certificate needed to validate the signature has long since expired".
The timestamp in the archive cutoff extension can be derived either from the time the OCSP response was produced (as described in RFC6960) or from the notBefore
date in the issuer's CA certificate (as mandated by ETSI EN 319 411-2, CSS-6.3.10-08).
The archive cutoff extension was previously configured in the EJBCA properties file ocsp.properties
using the ocsp.expiredcert.retentionperiod
property. As of EJBCA 7.3, the archive cutoff extension is instead configured in the user interface using an OCSP key binding.
The archive cutoff extension is only present in OCSP responses when an OCSP key binding is configured for the CA. For more information and configuration instructions, see Archive Cutoff.
OCSP Audit and Transaction Logging
The OCSP responder does normally not log anything for performance reasons. However, it is possible to enable logging according to your needs by configuring the OCSP audit log and the OCSP transaction log.
Enabling this feature enables the Audit and/or Transaction logging for all OCSP Key Bindings.
Audit logging will be logged at DEBUG level from the class org.cesecore.certificates.ocsp.logging.AuditLogger.
Transaction logging will be logged at DEBUG level from the class org.cesecore.certificates.ocsp.logging.TransactionLogger.
Example of Log Messages
Log messages are written on DEBUG level for both OCSP transaction logging and OCSP audit logging. OCSP transaction log messages are logged by org.cesecore.certificates.ocsp.logging.TransactionLogger
and OCSP audit log messages are logged by org.cesecore.certificates.ocsp.logging.AuditLogger
.
The log messages will look like the following, using the default settings in standalone.xml
:
2021-05-10 16:57:58,093 DEBUG [org.cesecore.certificates.ocsp.logging.AuditLogger] (default task-1) <log message goes here>
2021-05-10 17:40:42,323 DEBUG [org.cesecore.certificates.ocsp.logging.TransactionLogger] (default task-1) <log message goes here>
Using the default setting for transaction logging in the UI.
${SESSION_ID};${LOG_ID};${STATUS};${REQ_NAME}"${CLIENT_IP}";"${SIGN_ISSUER_NAME_DN}";"${SIGN_SUBJECT_NAME}";${SIGN_SERIAL_NO};"${LOG_TIME}";${REPLY_TIME};${NUM_CERT_ID};0;0;0;0;0;0;0;"${ISSUER_NAME_DN}";${ISSUER_NAME_HASH};${ISSUER_KEY};${DIGEST_ALGOR};${SERIAL_NOHEX};${CERT_STATUS};${CERT_PROFILE_ID};${FORWARDED_FOR}
A log entry like the following is logged.
08:14:36,789 DEBUG [org.cesecore.certificates.ocsp.logging.TransactionLogger] (default task-2) 7f4c11397f000101489d61ffc1cf1ccc;5;0;0"127.0.0.1";"0";"0";0;"2021-05-31 06:14:36.782+0000";7;1;0;0;0;0;0;0;0;"CN=Management CA,O=PK-DM,C=AE";27cbed5e54a990ccd30f644e3715c75b1decfdee;bb689f7058d62ab4b8c13866fac3cf8fc1986ada;1.3.14.3.2.26;21d26108348624ad3df3ef1171c3ca84a5c337fe;1;0;
Using the default setting for audit logging in the UI.
SESSION_ID:${SESSION_ID};LOG ID:${LOG_ID};"${LOG_TIME}";TIME TO PROCESS:${REPLY_TIME};\nOCSP REQUEST:\n"${OCSPREQUEST}";\nOCSP RESPONSE:\n"${OCSPRESPONSE}";\nSTATUS:${STATUS}
A log entry like the following is logged (full request and response hex encoding cut for readability).
08:19:48,014 DEBUG [org.cesecore.certificates.ocsp.logging.AuditLogger] (default task-2) SESSION_ID:7f4c11397f000101489d61ffc1cf1ccc;LOG ID:5;"2021-05-31 06:14:36.782+0000";TIME TO PROCESS:5;\nOCSP REQUEST:\n"307a30...e068b5";\nOCSP RESPONSE:\n"308205...2cd2f1";\nSTATUS:0
Variables
The log messages written to the OCSP transaction log and OCSP audit log can be customized using variables.
Valid values for audit logging are:
Audit Log Value | Description |
---|---|
${LOG_ID} | An integer identifying that starts from 1 and is increased for every received request. |
${SESSION_ID} | A random 32 Byte long String generated when the OCSP responder is started. |
${OCSPREQUEST} | The (hex encoded) byte[] OCSP request that came with the HTTP request. |
${OCSPRESPONSE} | The (hex encoded) byte[] OCSP response that was included in the HTTP response. |
Valid variables for transaction logging are:
Variable | Explanation |
---|---|
${LOG_ID} | An integer identifying that starts from 1 and is increased for every received request. |
${SESSION_ID} | A random 32 Byte long String generated when the OCSP responder is started. |
The IP address of the client making the request. | |
${STATUS} | The status of the OCSP request. Possible values are:
|
${PROCESS_TIME} | Records the total time a request takes to process, excluding the time it takes to read the request. |
${REQ_NAME} | The Bouncy Castle-normalized subject distinguished name of the client making the request. |
${REQ_NAME_RAW} | The unnormalized subject distinguished name of the client making the request. |
${SIGN_ISSUER_NAME_DN} | The Bouncy Castle-normalized issuer distinguished name of the certificate used to sign the request. |
${SIGN_SUBJECT_NAME} | The Bouncy Castle-normalized subject distinguished name of the certificate used to sign the request. |
${SIGN_SERIAL_NO} | The serial number of the certificate used to sign the request. |
${NUM_CERT_ID} | The number of certificates to check the revocation status for. |
${ISSUER_NAME_DN} | The Bouncy Castle-normalized issuer distinguished name of the requested certificate. |
${ISSUER_NAME_DN_RAW} | The unnormalized issuer distinguished name of the requested certificate. |
${ISSUER_NAME_HASH} | The hash of the issuer's subject distinguished name. |
${ISSUER_KEY} | The public key of the issuer for the requested certificate. |
${DIGEST_ALGOR} | The hash algorithm used to hash the issuer's key and the issuer's name. |
${SERIAL_NOHEX} | The serial number of the requested certificate. |
${CERT_STATUS} | The revocation status of the requested certificate, as defined in RFC 6960. For example:
|
${CERT_PROFILE_ID} | The ID number of the certificate profile used to issue the requested certificate. |
${FORWARDED_FOR} | The HTTP X-Forwarded-For header value. |
${REV_REASON} | The revocation reason for the requested certificate as specified in RFC 5280 Section 5.3.1, or -1, if not revoked. Set to 6 (certificateHold) when certificate is unknown, even if the status returned is good. |
Note that ${LOG_ID}
are the same in both the OCSP audit log and the OCSP transaction log for any request. This means they can be cross-referenced. You can retrieve information from the transaction log and verify that the information is valid by using the audit log.
Configuring Output Files for OCSP Logging
For JBoss and WildFly you can configure logging in JBOSS_HOME/standalone/configuration/standalone.xml to put the transaction and audit logs in separate files. An example is:
<periodic-rotating-file-handler name="OCSPTRANSACTION" autoflush="true">
<formatter>
<pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
<file relative-to="jboss.server.log.dir" path="transactions.log"/>
<suffix value=".yyyy-MM-dd"/>
<append value="true"/>
</periodic-rotating-file-handler>
<periodic-rotating-file-handler name="OCSPAUDIT" autoflush="true">
<formatter>
<pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
<file relative-to="jboss.server.log.dir" path="audit.log"/>
<suffix value=".yyyy-MM-dd"/>
<append value="true"/>
</periodic-rotating-file-handler>
<logger category="org.cesecore.certificates.ocsp.logging.TransactionLogger" use-parent-handlers="false">
<level name="DEBUG"/>
<handlers>
<handler name="OCSPTRANSACTION"/>
</handlers>
</logger>
<logger category="org.cesecore.certificates.ocsp.logging.AuditLogger" use-parent-handlers="false">
<level name="DEBUG"/>
<handlers>
<handler name="OCSPAUDIT"/>
</handlers>
</logger>