-
Notifications
You must be signed in to change notification settings - Fork 138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
For unknown certificates OCSP should have unknown CertStatus (part 2) #4534
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,12 +102,12 @@ | |
import com.netscape.certsrv.ca.CAEnabledException; | ||
import com.netscape.certsrv.ca.CAMissingCertException; | ||
import com.netscape.certsrv.ca.CAMissingKeyException; | ||
import com.netscape.certsrv.ca.CANotFoundException; | ||
import com.netscape.certsrv.ca.CANotLeafException; | ||
import com.netscape.certsrv.ca.CATypeException; | ||
import com.netscape.certsrv.ca.ECAException; | ||
import com.netscape.certsrv.ca.IssuerUnavailableException; | ||
import com.netscape.certsrv.cert.CertEnrollmentRequest; | ||
import com.netscape.certsrv.dbs.EDBRecordNotFoundException; | ||
import com.netscape.certsrv.dbs.certdb.CertId; | ||
import com.netscape.certsrv.logging.ILogger; | ||
import com.netscape.certsrv.logging.event.CRLSigningInfoEvent; | ||
|
@@ -1550,34 +1550,35 @@ public OCSPResponse validate(OCSPRequest request) | |
* CertID in the request. | ||
* | ||
* 2. If this CA is *not* the issuer, look up the issuer | ||
* by its DN in CAEngine. If not found, fail. If | ||
* found, dispatch to its 'validate' method. Otherwise | ||
* continue. | ||
* by its DN in CAEngine. If found, dispatch to its 'validate' | ||
* method. Otherwise continue. | ||
* | ||
* 3. If this CA is NOT the issuing CA, we locate the | ||
* issuing CA and dispatch to its 'validate' method. | ||
* Otherwise, we move forward to generate and sign the | ||
* aggregate OCSP response. | ||
*/ | ||
CertificateAuthority ocspCA = this; | ||
if (engine.getCAs().size() > 0 && tbsReq.getRequestCount() > 0) { | ||
for (CertificateAuthority ocspCA: engine.getCAs()) { | ||
Request req = tbsReq.getRequestAt(0); | ||
BigInteger serialNo = req.getCertID().getSerialNumber(); | ||
|
||
CertificateRepository certificateRepository = engine.getCertificateRepository(); | ||
X509CertImpl cert = certificateRepository.getX509Certificate(serialNo); | ||
|
||
X500Name certIssuerDN = (X500Name) cert.getIssuerDN(); | ||
ocspCA = engine.getCA(certIssuerDN); | ||
} | ||
|
||
if (ocspCA == null) { | ||
logger.error("CertificateAuthority: Could not locate issuing CA"); | ||
throw new CANotFoundException("Could not locate issuing CA"); | ||
CertID cid = req.getCertID(); | ||
byte[] nameHash = null; | ||
String digestName = cid.getDigestName(); | ||
if (digestName != null) { | ||
try { | ||
MessageDigest md = MessageDigest.getInstance(digestName); | ||
nameHash = md.digest(ocspCA.getSubjectObj().getX500Name().getEncoded()); | ||
} catch (NoSuchAlgorithmException | IOException e) { | ||
logger.info("CertificateAuthority: OCSP request hash algorithm " + digestName + " not recognised - "); | ||
} | ||
} | ||
if(Arrays.equals(nameHash, cid.getIssuerNameHash().toByteArray())) { | ||
if(ocspCA != this) { | ||
return ((IOCSPService) ocspCA).validate(request); | ||
} | ||
break; | ||
} | ||
} | ||
|
||
if (ocspCA != this) | ||
return ((IOCSPService) ocspCA).validate(request); | ||
|
||
logger.debug("CertificateAuthority: validating OCSP request"); | ||
|
||
|
@@ -1736,11 +1737,14 @@ private BasicOCSPResponse sign(ResponseData rd) throws EBaseException { | |
} | ||
} | ||
|
||
private SingleResponse processRequest(Request req) { | ||
public SingleResponse processRequest(Request req) { | ||
|
||
CAEngine engine = CAEngine.getInstance(); | ||
CertificateRepository certificateRepository = engine.getCertificateRepository(); | ||
|
||
X509CertImpl caCert = mSigningUnit.getCertImpl(); | ||
X509Key key = (X509Key) caCert.getPublicKey(); | ||
|
||
CertID cid = req.getCertID(); | ||
INTEGER serialNo = cid.getSerialNumber(); | ||
logger.debug("CertificateAuthority: processing request for cert 0x" + serialNo.toString(16)); | ||
|
@@ -1749,15 +1753,18 @@ private SingleResponse processRequest(Request req) { | |
GeneralizedTime thisUpdate = new GeneralizedTime(new Date()); | ||
|
||
byte[] nameHash = null; | ||
byte[] keyHash = null; | ||
String digestName = cid.getDigestName(); | ||
if (digestName != null) { | ||
try { | ||
MessageDigest md = MessageDigest.getInstance(digestName); | ||
nameHash = md.digest(mName.getEncoded()); | ||
keyHash = md.digest(key.getKey()); | ||
} catch (NoSuchAlgorithmException | IOException e) { | ||
} | ||
} | ||
if (!Arrays.equals(cid.getIssuerNameHash().toByteArray(), nameHash)) { | ||
if (!Arrays.equals(cid.getIssuerNameHash().toByteArray(), nameHash) || | ||
!Arrays.equals(cid.getIssuerKeyHash().toByteArray(), keyHash)) { | ||
// issuer of cert is not this CA (or we couldn't work | ||
// out whether it is or not due to unknown hash alg); | ||
// do not return status information for this cert | ||
|
@@ -1836,9 +1843,12 @@ private SingleResponse processRequest(Request req) { | |
} else { | ||
certStatus = new UnknownInfo(); | ||
} | ||
} catch (Exception e) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we sure there are no other type of exceptions? This catch all exception in general is a safety net in a pinch, if not the best practice. |
||
} catch (EDBRecordNotFoundException e) { | ||
// not found | ||
certStatus = new UnknownInfo(); // not issued not all | ||
certStatus = new GoodInfo(); // not issued not all | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. despite what's being said in RFC 6960 wrt "good" response, since this is inside the CA, who knows for sure that it is not a cert issued by itself, I think "unknown" is a better fit for this response (v.s. standalone ocsp who has no means of finding out). In the "note" area of the rfc in that section, it says ' the "unknown" status indicates that the status could not be determined by this responder' so making it "unknown" would be fine I think. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Last version of the spec suggest to provide reject status in this case (or good for backward compatibility) so the client does not have to look at other responders. I leave this decision to you. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @fmarco76 as a matter of fact, I had an about face after looking at the rfc more closely. It should return "revoked" in this case. However, not having time (minutes away from close of sprint) to find a handy way to construct a "revoked" response at the time, I opted to assign unknown to it. I think that's what the lab is expecting from the emails I received. Either way it's still better than returning "good". This is a rare case anyway, so we can leave it to the lab and patch it if needed. Thanks! |
||
} catch (EBaseException e) { | ||
// internal error | ||
certStatus = new UnknownInfo(); | ||
} | ||
|
||
return new SingleResponse( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fmarco76 I suggest that you request @frasertweedale for a review here since it seems have touched the lightweight CA area.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought, looking closely, although it added additional name/key hash checks, the code path should be the same for the lightweight CA case. I think it should be safe for v10.13 for now. We can hold off porting to other branches till we hear back from @frasertweedale
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the path is the same. The reason to look at the right CertificationAuthority is to get the correct DN and Public Key to verify. The improvement could be to perform the test for each certificate in the request.