/*
* This file is part of rockframework.
*
* rockframework is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* rockframework is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>;.
*/
package br.net.woodstock.rockframework.security.cert.impl;
import java.math.BigInteger;
import java.util.Date;
import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.ocsp.BasicOCSPResp;
import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder;
import org.bouncycastle.cert.ocsp.CertificateID;
import org.bouncycastle.cert.ocsp.CertificateStatus;
import org.bouncycastle.cert.ocsp.OCSPReq;
import org.bouncycastle.cert.ocsp.OCSPResp;
import org.bouncycastle.cert.ocsp.OCSPRespBuilder;
import org.bouncycastle.cert.ocsp.Req;
import org.bouncycastle.cert.ocsp.RevokedStatus;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.DigestCalculator;
import org.bouncycastle.operator.DigestCalculatorProvider;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import br.net.woodstock.rockframework.security.cert.CertificateException;
import br.net.woodstock.rockframework.security.cert.OCSPGenerator;
import br.net.woodstock.rockframework.security.cert.OCSPRequest;
import br.net.woodstock.rockframework.security.cert.OCSPResponse;
import br.net.woodstock.rockframework.security.cert.RevokeReason;
import br.net.woodstock.rockframework.security.util.BouncyCastleProviderHelper;
public class BouncyCastleOCSPGenerator implements OCSPGenerator {
private static BouncyCastleOCSPGenerator instance = new BouncyCastleOCSPGenerator();
protected BouncyCastleOCSPGenerator() {
super();
}
@Override
public OCSPResponse generate(final OCSPRequest request) {
try {
BouncyCastleOCSPRequest bcRequest = new BouncyCastleOCSPRequest(request);
OCSPReq ocspReq = new OCSPReq(request.getRequest());
SubjectPublicKeyInfo keyInfo = SubjectPublicKeyInfo.getInstance(bcRequest.getIssuerCertificate().getPublicKey().getEncoded());
JcaDigestCalculatorProviderBuilder digestCalculatorProviderBuilder = new JcaDigestCalculatorProviderBuilder();
digestCalculatorProviderBuilder.setProvider(BouncyCastleProviderHelper.PROVIDER_NAME);
DigestCalculatorProvider digestCalculatorProvider = digestCalculatorProviderBuilder.build();
DigestCalculator digestCalculator = digestCalculatorProvider.get(CertificateID.HASH_SHA1);
BasicOCSPRespBuilder builder = new BasicOCSPRespBuilder(keyInfo, digestCalculator);
Extension ocspNonce = ocspReq.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
if (ocspNonce != null) {
builder.setResponseExtensions(new Extensions(new Extension[] { ocspNonce }));
}
Req[] list = ocspReq.getRequestList();
for (Req req : list) {
CertificateID certificateID = req.getCertID();
BigInteger serialNumber = certificateID.getSerialNumber();
RevokeReason reason = request.getValidator().validate(serialNumber);
if (reason == null) {
builder.addResponse(certificateID, CertificateStatus.GOOD);
} else {
builder.addResponse(certificateID, new RevokedStatus(new Date(), reason.getCode()));
}
}
JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder(bcRequest.getSignAlgorithm());
contentSignerBuilder.setProvider(BouncyCastleProviderHelper.PROVIDER_NAME);
ContentSigner contentSigner = contentSignerBuilder.build(bcRequest.getIssuerPrivateKey());
X509CertificateHolder[] chain = new X509CertificateHolder[] { new X509CertificateHolder(bcRequest.getIssuerCertificate().getEncoded()) };
BasicOCSPResp basicResp = builder.build(contentSigner, chain, new Date());
OCSPResp ocspResp = new OCSPRespBuilder().build(OCSPRespBuilder.SUCCESSFUL, basicResp);
OCSPResponse response = new OCSPResponse(ocspResp.getEncoded());
return response;
} catch (Exception e) {
throw new CertificateException(e);
}
}
public static BouncyCastleOCSPGenerator getInstance() {
return BouncyCastleOCSPGenerator.instance;
}
}