2013-02-26 96 views
7

我使用Bouncy castle API创建了一个OCSP客户端。我在从OCSP响应中获得证书状态(说明是否撤销证书状态)时遇到了麻烦。从resp.getCertStatus()返回的值始终为空。 这就是我创建OCSP请求的方式。OCSP响应不提供证书状态

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); 
    } 
} 

我从服务URL获得OCSP响应,如下所示。

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); 
    } 
} 

撤销状态检查如下。这里来自BasicOCSPResp对象(basicResponse)的SingleResp对象(resp)应该具有证书的状态(好的,已撤销的或未知的)。但是这里的状态总是空的。

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); 
    } 
} 

我真的很感激你的帮忙。非常感谢。

回答

6

其实,如果你看看CertificateStatus.GOOD的实际值,你会发现它实际上是空的。换句话说,resp.getCertStatus()返回null表示GOOD。

所以你可能只需要拿出(状态!=空)检查。