1 package club.wpia.gigi.ocsp;
3 import java.io.IOException;
4 import java.security.GeneralSecurityException;
5 import java.security.MessageDigest;
6 import java.security.PrivateKey;
7 import java.security.Signature;
8 import java.security.cert.CRLReason;
9 import java.security.cert.X509Certificate;
10 import java.util.Date;
12 import club.wpia.gigi.crypto.OCSPRequest;
13 import club.wpia.gigi.crypto.OCSPResponse;
14 import club.wpia.gigi.crypto.OCSPResponse.SingleResponse;
15 import club.wpia.gigi.dbObjects.CACertificate;
16 import club.wpia.gigi.dbObjects.Certificate;
17 import sun.security.provider.certpath.CertId;
20 * An instance that creates OCSP responses.
22 public class OCSPIssuer {
25 * The CA certificate to issue OCSP responses for.
27 private final X509Certificate target;
30 * The OCSP certificate for which we have the private key.
32 private final X509Certificate cert;
35 * The OCSP certificate's private key to sign the responses with.
37 private final PrivateKey key;
39 private final byte[] subjectKeyIdentifier;
41 public OCSPIssuer(X509Certificate target, X509Certificate x, PrivateKey key) throws IOException, GeneralSecurityException {
45 this.subjectKeyIdentifier = OCSPResponder.calcKeyHash(cert, MessageDigest.getInstance("SHA-1"));
48 public X509Certificate getTarget() {
52 public byte[] getKeyId() {
53 return subjectKeyIdentifier;
56 private SingleResponse respond(CertId id, Certificate cert) {
58 Date dt = cert.getRevocationDate();
60 return new OCSPResponse.SingleResponse(id, new Date(System.currentTimeMillis() - 10000), new Date(System.currentTimeMillis() + 10000), dt, CRLReason.UNSPECIFIED);
62 return new OCSPResponse.SingleResponse(id, new Date(System.currentTimeMillis() - 10000), new Date(System.currentTimeMillis() + 10000));
65 return new OCSPResponse.SingleResponse(id, new Date(System.currentTimeMillis() - 10000), new Date(System.currentTimeMillis() + 10000), true);
70 * Responds with the status of one certificate.
73 * the {@link OCSPRequest} to take the nonce from.
75 * The certificate for which to look up revocation information.
76 * @return the signed {@link OCSPResponse} in binary data.
77 * @throws GeneralSecurityException
82 public byte[] respondBytes(OCSPRequest req, CertId id) throws GeneralSecurityException, IOException {
83 Certificate tcert = Certificate.getBySerial(id.getSerialNumber().toString(16).toLowerCase());
85 return OCSPResponse.invalid();
87 CACertificate cc = tcert.getParent();
88 if ( !cc.getCertificate().getSubjectDN().equals(getTarget().getSubjectDN())) {
90 OCSPResponder.log.warning("OCSP request with different Issuer: Based on serial: " + cc.getCertificate().getSubjectDN() + " but based on request: " + getTarget().getSubjectDN());
91 return OCSPResponse.invalid();
94 SingleResponse[] responses = new OCSPResponse.SingleResponse[1];
95 responses[0] = respond(id, tcert);
97 OCSPResponse ocspResponse = new OCSPResponse(getKeyId(), responses);
98 if (cert != getTarget()) {
99 ocspResponse.setSigners(new X509Certificate[] {
103 ocspResponse.setSigners(new X509Certificate[] {
108 ocspResponse.updateNonce(req);
109 Signature s = Signature.getInstance("SHA512WithRSA");
111 return ocspResponse.produceResponce(s);