Problem: Überprüfung eines X509-Zertifikates per OCSP-Abfrage, ob dieses gesperrt wurde:

Lösung:

Der OCSP-Client:

001public class OcspClientBouncyCastle
002{
003    /** root certificate */
004    private X509Certificate rootCert;
005    /** check certificate */
006    private X509Certificate checkCert;
007    /** <b style="color: black; background-color: rgb(255, 255, 102);">OCSP</b> URL */
008    private String url;
009 
010    private static final Logger logger = Logger.getLogger(OcspClientBouncyCastle.class);
011 
012    /**
013     * Creates an instance of an OcspClient that will be using BouncyCastle
014     */
015    public OcspClientBouncyCastle()
016    {
017 
018    }
019 
020    /**
021     * Generates an <b style="color: black; background-color: rgb(255, 255, 102);">OCSP</b> request using BouncyCastle.
022     * @param issuerCert - certificate of the issues.
023     * @param serialNumber - serial number.
024     * @return  an <b style="color: black; background-color: rgb(255, 255, 102);">OCSP</b> request
025     * @throws OCSPException
026     * @throws IOException
027     */
028    private  OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigInteger serialNumber) throws OCSPException, IOException
029    {
030        // Generate the id for the certificate we are looking for
031        CertificateID id        = new CertificateID(CertificateID.HASH_SHA1, issuerCert, serialNumber);
032 
033        // basic request generation with nonce
034        OCSPReqGenerator gen    = new OCSPReqGenerator();
035 
036        gen.addRequest(id);
037 
038        // create details for nonce extension
039        // to prevent Replay-Attacks
040        Vector oids     = new Vector();
041        Vector values   = new Vector();
042 
043        oids.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
044        values.add(new X509Extension(false, new DEROctetString(new DEROctetString(PdfEncryption.createDocumentId()).getEncoded())));
045 
046        gen.setRequestExtensions(new X509Extensions(oids, values));
047 
048        return gen.generate();
049    }
050 
051    /**
052     * Generates a {@link ErrorStatus}.
053     * @return the statuscode.
054     * @throws OCSPException
055     */
056    public int getOCSPStatus() throws OCSPException
057    {
058        try
059        {
060 
061            OCSPReq request         = generateOCSPRequest(rootCert, checkCert.getSerialNumber());
062            byte[] array            = request.getEncoded();
063            URL urlt                = new URL(url);
064            HttpURLConnection con   = (HttpURLConnection)urlt.openConnection();
065            con.setRequestProperty("Content-Type", "application/<b style="color: black; background-color: rgb(255, 255, 102);">ocsp</b>-request");
066            con.setRequestProperty("Accept", "application/<b style="color: black; background-color: rgb(255, 255, 102);">ocsp</b>-response");
067            con.setDoOutput(true);
068 
069            OutputStream out            = con.getOutputStream();
070            DataOutputStream dataOut    = new DataOutputStream(new BufferedOutputStream(out));
071            dataOut.write(array);
072            dataOut.flush();
073            dataOut.close();
074 
075            if (con.getResponseCode() / 100 != 2)
076                throw new OCSPException("Invalid HTTP response");
077 
078            //Get Response
079            InputStream in          = (InputStream) con.getContent();
080            OCSPResp ocspResponse       = new OCSPResp(in);
081 
082            if (ocspResponse.getStatus() != OCSPResponseStatus.SUCCESSFUL)
083                throw new OCSPException(ocspResponse.getStatus(),"Error in OCSPRequest/Response");
084 
085            BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
086            if (basicResponse != null)
087            {
088                SingleResp[] responses = basicResponse.getResponses();
089                if (responses.length == 1)
090                {
091                    SingleResp resp = responses[0];
092                    logger.info(" certificate number " + resp.getCertID().getSerialNumber());
093                    Object status   = resp.getCertStatus();
094 
095                    // Check the status of the response and adjust certificate
096                    if (status == CertificateStatus.GOOD)
097                    {
098                        logger.info("<b style="color: black; background-color: rgb(255, 255, 102);">OCSP</b>-Response-Status: OK!");
099//                      Die Antwort good muss aber nicht bedeuten, dass ein Zertifikat gültig exis-
100//                      tiert und nicht widerrufen worden ist. Diese Aussage könnte nur formuliert werden,
101//                      wenn der <b style="color: black; background-color: rgb(255, 255, 102);">OCSP</b>-Responder direkten Zugriff auf die Datenbank der Zertifizierungsstelle
102//                      hätte. Ist nur der Zugriff auf eine CRL vorhanden, kann der Responder lediglich sagen,
103//                      dass ein Zertifkat nicht widerrufen worden ist
104 
105                        return ErrorStatus.CERTIFICATE_OK;
106                    }
107                    else if (status instanceof org.bouncycastle.<b style="color: black; background-color: rgb(255, 255, 102);">ocsp</b>.RevokedStatus)
108                    {
109                            logger.info("Status Revoked");
110                          //ergebnis:fehlgeschlagen
111                            return ErrorStatus.CERTIFICATE_REVOKED;
112 
113                    } else if (status instanceof org.bouncycastle.<b style="color: black; background-color: rgb(255, 255, 102);">ocsp</b>.UnknownStatus)
114                    {
115                           logger.info("Status Unknown!");
116                         //ergebnis:unbekannt
117                            return ErrorStatus.CERTIFICATE_UNKNOWN;
118                    }
119                }
120            }
121 
122        }
123        catch (Exception ex)
124        {
125            logger.error(ex.getMessage());
126        }
127        return ErrorStatus.CERTIFICATE_UNKNOWN;
128    }
129 
130    public X509Certificate getRootCert()
131    {
132        return rootCert;
133    }
134 
135    public void setRootCert(X509Certificate rootCert)
136    {
137        this.rootCert = rootCert;
138    }
139 
140    public X509Certificate getCheckCert()
141    {
142        return checkCert;
143    }
144 
145    public void setCheckCert(X509Certificate checkCert)
146    {
147        this.checkCert = checkCert;
148    }
149 
150    public String getUrl()
151    {
152        return url;
153    }
154 
155    public void setUrl(String url)
156    {
157        this.url = url;
158    }
159 
160}

In Spring verdrahten und die getOCSPStatus()-Methode aufrufen. Vorher natürlich noch die Zertifikate sowie die URL für die Überprüfung übergeben. Diese steht im Zertifikat!


Tags: