use of com.github.zhenwei.core.asn1.ocsp.CertID in project LinLong-Java by zhenwei1108.
the class PKCS12KeyStoreSpi method engineLoad.
public void engineLoad(InputStream stream, char[] password) throws IOException {
if (// just initialising
stream == null) {
return;
}
BufferedInputStream bufIn = new BufferedInputStream(stream);
bufIn.mark(10);
int head = bufIn.read();
if (head < 0) {
throw new EOFException("no data in keystore stream");
}
if (head != 0x30) {
throw new IOException("stream does not represent a PKCS12 key store");
}
bufIn.reset();
ASN1InputStream bIn = new ASN1InputStream(bufIn);
Pfx bag;
try {
bag = Pfx.getInstance(bIn.readObject());
} catch (Exception e) {
throw new IOException(e.getMessage());
}
ContentInfo info = bag.getAuthSafe();
Vector chain = new Vector();
boolean unmarkedKey = false;
boolean wrongPKCS12Zero = false;
if (// check the mac code
bag.getMacData() != null) {
if (password == null) {
throw new NullPointerException("no password supplied when one expected");
}
MacData mData = bag.getMacData();
DigestInfo dInfo = mData.getMac();
macAlgorithm = dInfo.getAlgorithmId();
byte[] salt = mData.getSalt();
itCount = validateIterationCount(mData.getIterationCount());
saltLength = salt.length;
byte[] data = ((ASN1OctetString) info.getContent()).getOctets();
try {
byte[] res = calculatePbeMac(macAlgorithm.getAlgorithm(), salt, itCount, password, false, data);
byte[] dig = dInfo.getDigest();
if (!Arrays.constantTimeAreEqual(res, dig)) {
if (password.length > 0) {
throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file.");
}
// Try with incorrect zero length password
res = calculatePbeMac(macAlgorithm.getAlgorithm(), salt, itCount, password, true, data);
if (!Arrays.constantTimeAreEqual(res, dig)) {
throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file.");
}
wrongPKCS12Zero = true;
}
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException("error constructing MAC: " + e.toString());
}
} else if (password != null && password.length != 0) {
if (!Properties.isOverrideSet("com.github.zhenwei.pkix.pkcs12.ignore_useless_passwd")) {
throw new IOException("password supplied for keystore that does not require one");
}
}
keys = new IgnoresCaseHashtable();
localIds = new IgnoresCaseHashtable();
if (info.getContentType().equals(data)) {
ASN1OctetString content = ASN1OctetString.getInstance(info.getContent());
AuthenticatedSafe authSafe = AuthenticatedSafe.getInstance(content.getOctets());
ContentInfo[] c = authSafe.getContentInfo();
for (int i = 0; i != c.length; i++) {
if (c[i].getContentType().equals(data)) {
ASN1OctetString authSafeContent = ASN1OctetString.getInstance(c[i].getContent());
ASN1Sequence seq = ASN1Sequence.getInstance(authSafeContent.getOctets());
for (int j = 0; j != seq.size(); j++) {
SafeBag b = SafeBag.getInstance(seq.getObjectAt(j));
if (b.getBagId().equals(pkcs8ShroudedKeyBag)) {
com.github.zhenwei.core.asn1.pkcs.EncryptedPrivateKeyInfo eIn = com.github.zhenwei.core.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
//
// set the attributes on the key
//
String alias = null;
ASN1OctetString localId = null;
if (b.getBagAttributes() != null) {
Enumeration e = b.getBagAttributes().getObjects();
while (e.hasMoreElements()) {
ASN1Sequence sq = (ASN1Sequence) e.nextElement();
ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier) sq.getObjectAt(0);
ASN1Set attrSet = (ASN1Set) sq.getObjectAt(1);
ASN1Primitive attr = null;
if (attrSet.size() > 0) {
attr = (ASN1Primitive) attrSet.getObjectAt(0);
if (privKey instanceof PKCS12BagAttributeCarrier) {
PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) privKey;
ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
if (existing != null) {
// OK, but the value has to be the same
if (!existing.toASN1Primitive().equals(attr)) {
throw new IOException("attempt to add existing attribute with different value");
}
} else {
bagAttr.setBagAttribute(aOid, attr);
}
}
}
if (aOid.equals(pkcs_9_at_friendlyName)) {
alias = ((ASN1BMPString) attr).getString();
keys.put(alias, privKey);
} else if (aOid.equals(pkcs_9_at_localKeyId)) {
localId = (ASN1OctetString) attr;
}
}
}
if (localId != null) {
String name = new String(Hex.encode(localId.getOctets()));
if (alias == null) {
keys.put(name, privKey);
} else {
localIds.put(alias, name);
}
} else {
unmarkedKey = true;
keys.put("unmarked", privKey);
}
} else if (b.getBagId().equals(certBag)) {
chain.addElement(b);
} else {
System.out.println("extra in data " + b.getBagId());
System.out.println(ASN1Dump.dumpAsString(b));
}
}
} else if (c[i].getContentType().equals(encryptedData)) {
EncryptedData d = EncryptedData.getInstance(c[i].getContent());
byte[] octets = cryptData(false, d.getEncryptionAlgorithm(), password, wrongPKCS12Zero, d.getContent().getOctets());
ASN1Sequence seq = ASN1Sequence.getInstance(octets);
for (int j = 0; j != seq.size(); j++) {
SafeBag b = SafeBag.getInstance(seq.getObjectAt(j));
if (b.getBagId().equals(certBag)) {
chain.addElement(b);
} else if (b.getBagId().equals(pkcs8ShroudedKeyBag)) {
com.github.zhenwei.core.asn1.pkcs.EncryptedPrivateKeyInfo eIn = com.github.zhenwei.core.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
//
// set the attributes on the key
//
PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) privKey;
String alias = null;
ASN1OctetString localId = null;
Enumeration e = b.getBagAttributes().getObjects();
while (e.hasMoreElements()) {
ASN1Sequence sq = (ASN1Sequence) e.nextElement();
ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier) sq.getObjectAt(0);
ASN1Set attrSet = (ASN1Set) sq.getObjectAt(1);
ASN1Primitive attr = null;
if (attrSet.size() > 0) {
attr = (ASN1Primitive) attrSet.getObjectAt(0);
ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
if (existing != null) {
// OK, but the value has to be the same
if (!existing.toASN1Primitive().equals(attr)) {
throw new IOException("attempt to add existing attribute with different value");
}
} else {
bagAttr.setBagAttribute(aOid, attr);
}
}
if (aOid.equals(pkcs_9_at_friendlyName)) {
alias = ((ASN1BMPString) attr).getString();
keys.put(alias, privKey);
} else if (aOid.equals(pkcs_9_at_localKeyId)) {
localId = (ASN1OctetString) attr;
}
}
String name = new String(Hex.encode(localId.getOctets()));
if (alias == null) {
keys.put(name, privKey);
} else {
localIds.put(alias, name);
}
} else if (b.getBagId().equals(keyBag)) {
com.github.zhenwei.core.asn1.pkcs.PrivateKeyInfo kInfo = com.github.zhenwei.core.asn1.pkcs.PrivateKeyInfo.getInstance(b.getBagValue());
PrivateKey privKey = WeGooProvider.getPrivateKey(kInfo);
//
// set the attributes on the key
//
PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) privKey;
String alias = null;
ASN1OctetString localId = null;
Enumeration e = b.getBagAttributes().getObjects();
while (e.hasMoreElements()) {
ASN1Sequence sq = ASN1Sequence.getInstance(e.nextElement());
ASN1ObjectIdentifier aOid = ASN1ObjectIdentifier.getInstance(sq.getObjectAt(0));
ASN1Set attrSet = ASN1Set.getInstance(sq.getObjectAt(1));
ASN1Primitive attr = null;
if (attrSet.size() > 0) {
attr = (ASN1Primitive) attrSet.getObjectAt(0);
ASN1Encodable existing = bagAttr.getBagAttribute(aOid);
if (existing != null) {
// OK, but the value has to be the same
if (!existing.toASN1Primitive().equals(attr)) {
throw new IOException("attempt to add existing attribute with different value");
}
} else {
bagAttr.setBagAttribute(aOid, attr);
}
if (aOid.equals(pkcs_9_at_friendlyName)) {
alias = ((ASN1BMPString) attr).getString();
keys.put(alias, privKey);
} else if (aOid.equals(pkcs_9_at_localKeyId)) {
localId = (ASN1OctetString) attr;
}
}
}
String name = new String(Hex.encode(localId.getOctets()));
if (alias == null) {
keys.put(name, privKey);
} else {
localIds.put(alias, name);
}
} else {
System.out.println("extra in encryptedData " + b.getBagId());
System.out.println(ASN1Dump.dumpAsString(b));
}
}
} else {
System.out.println("extra " + c[i].getContentType().getId());
System.out.println("extra " + ASN1Dump.dumpAsString(c[i].getContent()));
}
}
}
certs = new IgnoresCaseHashtable();
chainCerts = new Hashtable();
keyCerts = new Hashtable();
for (int i = 0; i != chain.size(); i++) {
SafeBag b = (SafeBag) chain.elementAt(i);
CertBag cb = CertBag.getInstance(b.getBagValue());
if (!cb.getCertId().equals(x509Certificate)) {
throw new RuntimeException("Unsupported certificate type: " + cb.getCertId());
}
Certificate cert;
try {
ByteArrayInputStream cIn = new ByteArrayInputStream(((ASN1OctetString) cb.getCertValue()).getOctets());
cert = certFact.generateCertificate(cIn);
} catch (Exception e) {
throw new RuntimeException(e.toString());
}
//
// set the attributes
//
ASN1OctetString localId = null;
String alias = null;
if (b.getBagAttributes() != null) {
Enumeration e = b.getBagAttributes().getObjects();
while (e.hasMoreElements()) {
ASN1Sequence sq = ASN1Sequence.getInstance(e.nextElement());
ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(sq.getObjectAt(0));
ASN1Set attrSet = ASN1Set.getInstance(sq.getObjectAt(1));
if (// sometimes this is empty!
attrSet.size() > 0) {
ASN1Primitive attr = (ASN1Primitive) attrSet.getObjectAt(0);
PKCS12BagAttributeCarrier bagAttr = null;
if (cert instanceof PKCS12BagAttributeCarrier) {
bagAttr = (PKCS12BagAttributeCarrier) cert;
ASN1Encodable existing = bagAttr.getBagAttribute(oid);
if (existing != null) {
// we've found more than one - one might be incorrect
if (oid.equals(pkcs_9_at_localKeyId)) {
String id = Hex.toHexString(((ASN1OctetString) attr).getOctets());
if (!(keys.keys.containsKey(id) || localIds.keys.containsKey(id))) {
// ignore this one - it's not valid
continue;
}
}
// OK, but the value has to be the same
if (!existing.toASN1Primitive().equals(attr)) {
throw new IOException("attempt to add existing attribute with different value");
}
} else {
bagAttr.setBagAttribute(oid, attr);
}
}
if (oid.equals(pkcs_9_at_friendlyName)) {
alias = ((ASN1BMPString) attr).getString();
} else if (oid.equals(pkcs_9_at_localKeyId)) {
localId = (ASN1OctetString) attr;
}
}
}
}
chainCerts.put(new CertId(cert.getPublicKey()), cert);
if (unmarkedKey) {
if (keyCerts.isEmpty()) {
String name = new String(Hex.encode(createSubjectKeyId(cert.getPublicKey()).getKeyIdentifier()));
keyCerts.put(name, cert);
keys.put(name, keys.remove("unmarked"));
}
} else {
//
if (localId != null) {
String name = new String(Hex.encode(localId.getOctets()));
keyCerts.put(name, cert);
}
if (alias != null) {
certs.put(alias, cert);
}
}
}
}
use of com.github.zhenwei.core.asn1.ocsp.CertID in project LinLong-Java by zhenwei1108.
the class ProvOcspRevocationChecker method check.
public void check(Certificate certificate) throws CertPathValidatorException {
X509Certificate cert = (X509Certificate) certificate;
Map<X509Certificate, byte[]> ocspResponses = parent.getOcspResponses();
URI ocspUri = parent.getOcspResponder();
if (ocspUri == null) {
if (this.ocspURL != null) {
try {
ocspUri = new URI(this.ocspURL);
} catch (URISyntaxException e) {
throw new CertPathValidatorException("configuration error: " + e.getMessage(), e, parameters.getCertPath(), parameters.getIndex());
}
} else {
ocspUri = getOcspResponderURI(cert);
}
}
byte[] nonce = null;
boolean preValidated = false;
if (ocspResponses.get(cert) == null && ocspUri != null) {
// if we're here we need to make a network access, if we haven't been given a URL explicitly block it.
if (ocspURL == null && parent.getOcspResponder() == null && !isEnabledOCSP) {
throw new RecoverableCertPathValidatorException("OCSP disabled by \"ocsp.enable\" setting", null, parameters.getCertPath(), parameters.getIndex());
}
com.github.zhenwei.core.asn1.x509.Certificate issuer = extractCert();
// TODO: configure hash algorithm
CertID id = createCertID(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), issuer, new ASN1Integer(cert.getSerialNumber()));
OCSPResponse response = OcspCache.getOcspResponse(id, parameters, ocspUri, parent.getOcspResponderCert(), parent.getOcspExtensions(), helper);
try {
ocspResponses.put(cert, response.getEncoded());
preValidated = true;
} catch (IOException e) {
throw new CertPathValidatorException("unable to encode OCSP response", e, parameters.getCertPath(), parameters.getIndex());
}
} else {
List exts = parent.getOcspExtensions();
for (int i = 0; i != exts.size(); i++) {
Extension ext = (Extension) exts.get(i);
byte[] value = ext.getValue();
if (OCSPObjectIdentifiers.id_pkix_ocsp_nonce.getId().equals(ext.getId())) {
nonce = value;
}
}
}
if (!ocspResponses.isEmpty()) {
OCSPResponse ocspResponse = OCSPResponse.getInstance(ocspResponses.get(cert));
ASN1Integer serialNumber = new ASN1Integer(cert.getSerialNumber());
if (ocspResponse != null) {
if (OCSPResponseStatus.SUCCESSFUL == ocspResponse.getResponseStatus().getIntValue()) {
ResponseBytes respBytes = ResponseBytes.getInstance(ocspResponse.getResponseBytes());
if (respBytes.getResponseType().equals(OCSPObjectIdentifiers.id_pkix_ocsp_basic)) {
try {
BasicOCSPResponse basicResp = BasicOCSPResponse.getInstance(respBytes.getResponse().getOctets());
if (preValidated || validatedOcspResponse(basicResp, parameters, nonce, parent.getOcspResponderCert(), helper)) {
ResponseData responseData = ResponseData.getInstance(basicResp.getTbsResponseData());
ASN1Sequence s = responseData.getResponses();
CertID certID = null;
for (int i = 0; i != s.size(); i++) {
SingleResponse resp = SingleResponse.getInstance(s.getObjectAt(i));
if (serialNumber.equals(resp.getCertID().getSerialNumber())) {
ASN1GeneralizedTime nextUp = resp.getNextUpdate();
if (nextUp != null && parameters.getValidDate().after(nextUp.getDate())) {
throw new ExtCertPathValidatorException("OCSP response expired");
}
if (certID == null || !certID.getHashAlgorithm().equals(resp.getCertID().getHashAlgorithm())) {
com.github.zhenwei.core.asn1.x509.Certificate issuer = extractCert();
certID = createCertID(resp.getCertID(), issuer, serialNumber);
}
if (certID.equals(resp.getCertID())) {
if (resp.getCertStatus().getTagNo() == 0) {
// we're good!
return;
}
if (resp.getCertStatus().getTagNo() == 1) {
RevokedInfo info = RevokedInfo.getInstance(resp.getCertStatus().getStatus());
CRLReason reason = info.getRevocationReason();
throw new CertPathValidatorException("certificate revoked, reason=(" + reason + "), date=" + info.getRevocationTime().getDate(), null, parameters.getCertPath(), parameters.getIndex());
}
throw new CertPathValidatorException("certificate revoked, details unknown", null, parameters.getCertPath(), parameters.getIndex());
}
}
}
}
} catch (CertPathValidatorException e) {
throw e;
} catch (Exception e) {
throw new CertPathValidatorException("unable to process OCSP response", e, parameters.getCertPath(), parameters.getIndex());
}
}
} else {
throw new CertPathValidatorException("OCSP response failed: " + ocspResponse.getResponseStatus().getValue(), null, parameters.getCertPath(), parameters.getIndex());
}
} else {
// TODO: add checking for the OCSP extension (properly vetted)
throw new RecoverableCertPathValidatorException("no OCSP response found for certificate", null, parameters.getCertPath(), parameters.getIndex());
}
} else {
throw new RecoverableCertPathValidatorException("no OCSP response found for any certificate", null, parameters.getCertPath(), parameters.getIndex());
}
}
use of com.github.zhenwei.core.asn1.ocsp.CertID in project xipki by xipki.
the class OcspBenchRequestor method buildRequest.
// method ask
private byte[] buildRequest(BigInteger[] serialNumbers) throws OcspRequestorException {
boolean canCache = (serialNumbers.length == 1) && !requestOptions.isUseNonce();
if (canCache) {
byte[] request = requests.get(serialNumbers[0]);
if (request != null) {
return request;
}
}
OCSPReqBuilder reqBuilder = new OCSPReqBuilder();
if (requestOptions.isUseNonce() || extensions != null) {
List<Extension> extns = new ArrayList<>(2);
if (requestOptions.isUseNonce()) {
Extension extn = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, new DEROctetString(nextNonce(requestOptions.getNonceLen())));
extns.add(extn);
}
if (extensions != null) {
for (Extension extn : extensions) {
extns.add(extn);
}
}
reqBuilder.setRequestExtensions(new Extensions(extns.toArray(extnType)));
}
try {
for (BigInteger serialNumber : serialNumbers) {
CertID certId = new CertID(issuerhashAlg, issuerNameHash, issuerKeyHash, new ASN1Integer(serialNumber));
reqBuilder.addRequest(new CertificateID(certId));
}
byte[] request = reqBuilder.build().getEncoded();
if (canCache) {
requests.put(serialNumbers[0], request);
}
return request;
} catch (OCSPException | IOException ex) {
throw new OcspRequestorException(ex.getMessage(), ex);
}
}
use of com.github.zhenwei.core.asn1.ocsp.CertID in project xipki by xipki.
the class AbstractOcspRequestor method buildRequest.
// method ask
private OCSPRequest buildRequest(X509Certificate caCert, BigInteger[] serialNumbers, byte[] nonce, RequestOptions requestOptions) throws OcspRequestorException {
HashAlgo hashAlgo = HashAlgo.getInstance(requestOptions.getHashAlgorithmId());
if (hashAlgo == null) {
throw new OcspRequestorException("unknown HashAlgo " + requestOptions.getHashAlgorithmId().getId());
}
List<AlgorithmIdentifier> prefSigAlgs = requestOptions.getPreferredSignatureAlgorithms();
XiOCSPReqBuilder reqBuilder = new XiOCSPReqBuilder();
List<Extension> extensions = new LinkedList<>();
if (nonce != null) {
extensions.add(new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, new DEROctetString(nonce)));
}
if (prefSigAlgs != null && prefSigAlgs.size() > 0) {
ASN1EncodableVector vec = new ASN1EncodableVector();
for (AlgorithmIdentifier algId : prefSigAlgs) {
vec.add(new DERSequence(algId));
}
ASN1Sequence extnValue = new DERSequence(vec);
Extension extn;
try {
extn = new Extension(ObjectIdentifiers.id_pkix_ocsp_prefSigAlgs, false, new DEROctetString(extnValue));
} catch (IOException ex) {
throw new OcspRequestorException(ex.getMessage(), ex);
}
extensions.add(extn);
}
if (CollectionUtil.isNonEmpty(extensions)) {
reqBuilder.setRequestExtensions(new Extensions(extensions.toArray(new Extension[0])));
}
try {
DEROctetString issuerNameHash = new DEROctetString(hashAlgo.hash(caCert.getSubjectX500Principal().getEncoded()));
TBSCertificate tbsCert;
try {
tbsCert = TBSCertificate.getInstance(caCert.getTBSCertificate());
} catch (CertificateEncodingException ex) {
throw new OcspRequestorException(ex);
}
DEROctetString issuerKeyHash = new DEROctetString(hashAlgo.hash(tbsCert.getSubjectPublicKeyInfo().getPublicKeyData().getOctets()));
for (BigInteger serialNumber : serialNumbers) {
CertID certId = new CertID(hashAlgo.getAlgorithmIdentifier(), issuerNameHash, issuerKeyHash, new ASN1Integer(serialNumber));
reqBuilder.addRequest(certId);
}
if (requestOptions.isSignRequest()) {
synchronized (signerLock) {
if (signer == null) {
if (StringUtil.isBlank(signerType)) {
throw new OcspRequestorException("signerType is not configured");
}
if (StringUtil.isBlank(signerConf)) {
throw new OcspRequestorException("signerConf is not configured");
}
X509Certificate cert = null;
if (StringUtil.isNotBlank(signerCertFile)) {
try {
cert = X509Util.parseCert(signerCertFile);
} catch (CertificateException ex) {
throw new OcspRequestorException("could not parse certificate " + signerCertFile + ": " + ex.getMessage());
}
}
try {
signer = getSecurityFactory().createSigner(signerType, new SignerConf(signerConf), cert);
} catch (Exception ex) {
throw new OcspRequestorException("could not create signer: " + ex.getMessage());
}
}
// end if
}
// end synchronized
reqBuilder.setRequestorName(signer.getBcCertificate().getSubject());
X509CertificateHolder[] certChain0 = signer.getBcCertificateChain();
Certificate[] certChain = new Certificate[certChain0.length];
for (int i = 0; i < certChain.length; i++) {
certChain[i] = certChain0[i].toASN1Structure();
}
ConcurrentBagEntrySigner signer0;
try {
signer0 = signer.borrowSigner();
} catch (NoIdleSignerException ex) {
throw new OcspRequestorException("NoIdleSignerException: " + ex.getMessage());
}
try {
return reqBuilder.build(signer0.value(), certChain);
} finally {
signer.requiteSigner(signer0);
}
} else {
return reqBuilder.build();
}
// end if
} catch (OCSPException | IOException ex) {
throw new OcspRequestorException(ex.getMessage(), ex);
}
}
use of com.github.zhenwei.core.asn1.ocsp.CertID in project xipki by xipki.
the class AbstractOcspRequestor method ask.
@Override
public OCSPResp ask(X509Cert issuerCert, BigInteger[] serialNumbers, URL responderUrl, RequestOptions requestOptions, ReqRespDebug debug) throws OcspResponseException, OcspRequestorException {
notNull(issuerCert, "issuerCert");
notNull(requestOptions, "requestOptions");
notNull(responderUrl, "responderUrl");
byte[] nonce = null;
if (requestOptions.isUseNonce()) {
nonce = nextNonce(requestOptions.getNonceLen());
}
OCSPRequest ocspReq = buildRequest(issuerCert, serialNumbers, nonce, requestOptions);
byte[] encodedReq;
try {
encodedReq = ocspReq.getEncoded();
} catch (IOException ex) {
throw new OcspRequestorException("could not encode OCSP request: " + ex.getMessage(), ex);
}
ReqRespPair msgPair = null;
if (debug != null) {
msgPair = new ReqRespPair();
debug.add(msgPair);
if (debug.saveRequest()) {
msgPair.setRequest(encodedReq);
}
}
byte[] encodedResp;
try {
encodedResp = send(encodedReq, responderUrl, requestOptions);
} catch (IOException ex) {
throw new OcspResponseException.ResponderUnreachable("IOException: " + ex.getMessage(), ex);
}
if (msgPair != null && debug.saveResponse()) {
msgPair.setResponse(encodedResp);
}
OCSPResp ocspResp;
try {
ocspResp = new OCSPResp(encodedResp);
} catch (IOException ex) {
throw new OcspResponseException.InvalidResponse("IOException: " + ex.getMessage(), ex);
}
Object respObject;
try {
respObject = ocspResp.getResponseObject();
} catch (OCSPException ex) {
throw new OcspResponseException.InvalidResponse("responseObject is invalid");
}
if (ocspResp.getStatus() != 0) {
return ocspResp;
}
if (!(respObject instanceof BasicOCSPResp)) {
return ocspResp;
}
BasicOCSPResp basicOcspResp = (BasicOCSPResp) respObject;
if (nonce != null) {
Extension nonceExtn = basicOcspResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
if (nonceExtn == null) {
if (!requestOptions.isAllowNoNonceInResponse()) {
throw new OcspResponseException.OcspNonceUnmatched(nonce, null);
}
} else {
byte[] receivedNonce = nonceExtn.getExtnValue().getOctets();
if (!Arrays.equals(nonce, receivedNonce)) {
throw new OcspResponseException.OcspNonceUnmatched(nonce, receivedNonce);
}
}
}
SingleResp[] singleResponses = basicOcspResp.getResponses();
if (singleResponses == null || singleResponses.length == 0) {
String msg = StringUtil.concat("response with no singleResponse is returned, expected is ", Integer.toString(serialNumbers.length));
throw new OcspResponseException.OcspTargetUnmatched(msg);
}
final int countSingleResponses = singleResponses.length;
if (countSingleResponses != serialNumbers.length) {
String msg = StringUtil.concat("response with ", Integer.toString(countSingleResponses), " singleResponse", (countSingleResponses > 1 ? "s" : ""), " is returned, expected is ", Integer.toString(serialNumbers.length));
throw new OcspResponseException.OcspTargetUnmatched(msg);
}
Request reqAt0 = Request.getInstance(ocspReq.getTbsRequest().getRequestList().getObjectAt(0));
CertID certId = reqAt0.getReqCert();
ASN1ObjectIdentifier issuerHashAlg = certId.getHashAlgorithm().getAlgorithm();
byte[] issuerKeyHash = certId.getIssuerKeyHash().getOctets();
byte[] issuerNameHash = certId.getIssuerNameHash().getOctets();
if (serialNumbers.length == 1) {
SingleResp singleResp = singleResponses[0];
CertificateID cid = singleResp.getCertID();
boolean issuerMatch = issuerHashAlg.equals(cid.getHashAlgOID()) && Arrays.equals(issuerKeyHash, cid.getIssuerKeyHash()) && Arrays.equals(issuerNameHash, cid.getIssuerNameHash());
if (!issuerMatch) {
throw new OcspResponseException.OcspTargetUnmatched("the issuer is not requested");
}
BigInteger serialNumber = cid.getSerialNumber();
if (!serialNumbers[0].equals(serialNumber)) {
throw new OcspResponseException.OcspTargetUnmatched("the serialNumber is not requested");
}
} else {
List<BigInteger> tmpSerials1 = Arrays.asList(serialNumbers);
List<BigInteger> tmpSerials2 = new ArrayList<>(tmpSerials1);
for (int i = 0; i < countSingleResponses; i++) {
SingleResp singleResp = singleResponses[i];
CertificateID cid = singleResp.getCertID();
boolean issuerMatch = issuerHashAlg.equals(cid.getHashAlgOID()) && Arrays.equals(issuerKeyHash, cid.getIssuerKeyHash()) && Arrays.equals(issuerNameHash, cid.getIssuerNameHash());
if (!issuerMatch) {
throw new OcspResponseException.OcspTargetUnmatched("the issuer specified in singleResponse[" + i + "] is not requested");
}
BigInteger serialNumber = cid.getSerialNumber();
if (!tmpSerials2.remove(serialNumber)) {
if (tmpSerials1.contains(serialNumber)) {
throw new OcspResponseException.OcspTargetUnmatched("serialNumber " + LogUtil.formatCsn(serialNumber) + "is contained in at least two singleResponses");
} else {
throw new OcspResponseException.OcspTargetUnmatched("serialNumber " + LogUtil.formatCsn(serialNumber) + " specified in singleResponse[" + i + "] is not requested");
}
}
}
// end for
}
return ocspResp;
}
Aggregations