Ich erstellte einen OCSP-Client, der Bouncy Castle API verwendet. Ich habe Probleme beim Ermitteln des Zertifikatsstatus (ob er widerrufen wurde oder nicht) aus der OCSP-Antwort, die ich erhalte. Der von resp.getCertStatus() zurückgegebene Wert ist immer null. So erstelle ich die OCSP-Anfrage.OCSP-Antwort gibt keinen Zertifikatsstatus
private OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigInteger serialNumber)
throws CertificateVerificationException {
//Add provider BC
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
try {
// CertID structure is used to uniquely identify certificates that are the subject of
// an OCSP request or response and has an ASN.1 definition. CertID structure is defined in RFC 2560
CertificateID id = new CertificateID(CertificateID.HASH_SHA1, issuerCert, serialNumber);
// basic request generation with nonce
OCSPReqGenerator generator = new OCSPReqGenerator();
generator.addRequest(id);
// create details for nonce extension. The nonce extension is used to bind
// a request to a response to prevent replay attacks. As the name implies,
// the nonce value is something that the client should only use once within a reasonably small period.
BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis());
Vector objectIdentifiers = new Vector();
Vector values = new Vector();
//to create the request Extension
objectIdentifiers.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
values.add(new X509Extension(false, new DEROctetString(nonce.toByteArray())));
generator.setRequestExtensions(new X509Extensions(objectIdentifiers, values));
return generator.generate();
}
catch (OCSPException e) {
e.printStackTrace();
throw new CertificateVerificationException("Cannot generate OSCP Request with the given certificate",e);
}
}
Ich bekomme die OCSP-Antwort von der Service-URL wie folgt.
private OCSPResp getOCSPResponce(String serviceUrl, OCSPReq request) throws CertificateVerificationException {
try {
byte[] array = request.getEncoded();
if (serviceUrl.startsWith("http")) {
HttpURLConnection con;
URL url = new URL(serviceUrl);
con = (HttpURLConnection) url.openConnection();
con.setRequestProperty("Content-Type", "application/ocsp-request");
con.setRequestProperty("Accept", "application/ocsp-response");
con.setDoOutput(true);
OutputStream out = con.getOutputStream();
DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(out));
dataOut.write(array);
dataOut.flush();
dataOut.close();
//Get Response
InputStream in = (InputStream) con.getContent();
OCSPResp ocspResponse = new OCSPResp(in);
return ocspResponse;
}
else {
throw new CertificateVerificationException("Only http is supported for ocsp calls");
}
} catch (IOException e) {
e.printStackTrace();
throw new CertificateVerificationException("Cannot get ocspResponse from url: "+ serviceUrl, e);
}
}
Der Sperrstatus wird wie folgt überprüft. Hier sollte das SingleResp-Objekt (resp) aus dem BasicOCSPResp-Objekt (basicResponse) den Status des Zertifikats haben (gut, widerrufen oder unbekannt). Aber hier ist der Status immer Null.
public void checkRevocationStatus(X509Certificate peerCert, X509Certificate issuerCert)
throws CertificateVerificationException {
try {
OCSPReq request = generateOCSPRequest(issuerCert, peerCert.getSerialNumber());
List<String> locations = getAIALocations(peerCert);
Iterator it = locations.iterator();
if (it.hasNext()) {
String serviceUrl = (String) it.next();
OCSPResp ocspResponse = getOCSPResponce(serviceUrl, request);
if(OCSPRespStatus.SUCCESSFUL==ocspResponse.getStatus())
System.out.println("server gave response fine");
BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
SingleResp[] responses = (basicResponse==null) ? null : basicResponse.getResponses();
if (responses!=null && responses.length == 1) {
SingleResp resp = responses[0];
Object status = resp.getCertStatus();
if(status!=null) {
if (status == CertificateStatus.GOOD) {
System.out.println("OCSP Status is good!");
} else if (status instanceof org.bouncycastle.ocsp.RevokedStatus) {
System.out.println("OCSP Status is revoked!");
} else if (status instanceof org.bouncycastle.ocsp.UnknownStatus) {
System.out.println("OCSP Status is unknown!");
}
}
}
}
}
catch (Exception e) {
System.out.println(e);
}
}
Ich schätze Ihre Hilfe sehr. Danke vielmals.