use of com.github.zhenwei.core.asn1.x509.Extensions in project xipki by xipki.
the class O2tChecker method checkExtnPolicyConstraints.
void checkExtnPolicyConstraints(StringBuilder failureMsg, byte[] extnValue, Extensions requestedExtns, ExtensionControl extnControl) {
PolicyConstraints conf = caller.getPolicyConstraints();
if (conf == null) {
caller.checkConstantExtnValue(Extension.policyConstraints, failureMsg, extnValue, requestedExtns, extnControl);
return;
}
org.bouncycastle.asn1.x509.PolicyConstraints isPolicyConstraints = org.bouncycastle.asn1.x509.PolicyConstraints.getInstance(extnValue);
Integer expRequireExplicitPolicy = conf.getRequireExplicitPolicy();
BigInteger bigInt = isPolicyConstraints.getRequireExplicitPolicyMapping();
Integer isRequireExplicitPolicy = (bigInt == null) ? null : bigInt.intValue();
boolean match = true;
if (expRequireExplicitPolicy == null) {
if (isRequireExplicitPolicy != null) {
match = false;
}
} else if (!expRequireExplicitPolicy.equals(isRequireExplicitPolicy)) {
match = false;
}
if (!match) {
addViolation(failureMsg, "requireExplicitPolicy", isRequireExplicitPolicy, expRequireExplicitPolicy);
}
Integer expInhibitPolicyMapping = conf.getInhibitPolicyMapping();
bigInt = isPolicyConstraints.getInhibitPolicyMapping();
Integer isInhibitPolicyMapping = (bigInt == null) ? null : bigInt.intValue();
match = true;
if (expInhibitPolicyMapping == null) {
if (isInhibitPolicyMapping != null) {
match = false;
}
} else if (!expInhibitPolicyMapping.equals(isInhibitPolicyMapping)) {
match = false;
}
if (!match) {
addViolation(failureMsg, "inhibitPolicyMapping", isInhibitPolicyMapping, expInhibitPolicyMapping);
}
}
use of com.github.zhenwei.core.asn1.x509.Extensions 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) {
extns.addAll(Arrays.asList(extensions));
}
reqBuilder.setRequestExtensions(new Extensions(extns.toArray(extnType)));
}
try {
for (BigInteger serialNumber : serialNumbers) {
CertID certId = new CertID(issuerhashAlg.getAlgorithmIdentifier(), 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.x509.Extensions in project xipki by xipki.
the class A2gChecker method checkExtnBiometricInfo.
// method checkExtnBasicConstraints
void checkExtnBiometricInfo(StringBuilder failureMsg, byte[] extnValue, Extensions requestedExtns) {
BiometricInfoOption conf = getCertprofile().extensions().getBiometricInfo();
if (conf == null) {
failureMsg.append("extension is present but not expected; ");
return;
}
ASN1Encodable extInRequest = null;
if (requestedExtns != null) {
extInRequest = requestedExtns.getExtensionParsedValue(Extension.biometricInfo);
}
if (extInRequest == null) {
failureMsg.append("extension is present but not expected; ");
return;
}
ASN1Sequence extValueInReq = ASN1Sequence.getInstance(extInRequest);
final int expSize = extValueInReq.size();
ASN1Sequence extValue = ASN1Sequence.getInstance(extnValue);
final int isSize = extValue.size();
if (isSize != expSize) {
addViolation(failureMsg, "number of biometricData", isSize, expSize);
return;
}
for (int i = 0; i < expSize; i++) {
BiometricData isData = BiometricData.getInstance(extValue.getObjectAt(i));
BiometricData expData = BiometricData.getInstance(extValueInReq.getObjectAt(i));
TypeOfBiometricData isType = isData.getTypeOfBiometricData();
TypeOfBiometricData expType = expData.getTypeOfBiometricData();
if (!isType.equals(expType)) {
String isStr = isType.isPredefined() ? Integer.toString(isType.getPredefinedBiometricType()) : isType.getBiometricDataOid().getId();
String expStr = expType.isPredefined() ? Integer.toString(expType.getPredefinedBiometricType()) : expType.getBiometricDataOid().getId();
addViolation(failureMsg, "biometricData[" + i + "].typeOfBiometricData", isStr, expStr);
}
HashAlgo hashAlgo;
try {
hashAlgo = HashAlgo.getInstance(expData.getHashAlgorithm());
} catch (NoSuchAlgorithmException e) {
hashAlgo = null;
failureMsg.append("biometricData[").append(i).append("].biometricDataHash of the request has incorrect syntax; ");
}
if (hashAlgo != null) {
if (!hashAlgo.getAlgorithmIdentifier().equals(isData.getHashAlgorithm())) {
try {
addViolation(failureMsg, "biometricData[" + i + "].hashAlgorithm", Hex.encode(isData.getHashAlgorithm().getEncoded()), Hex.encode(hashAlgo.getAlgorithmIdentifier().getEncoded()));
} catch (Exception ex) {
failureMsg.append("biometricData[").append(i).append("].biometricDataHash: could not encode; ");
}
}
}
byte[] isBytes = isData.getBiometricDataHash().getOctets();
byte[] expBytes = expData.getBiometricDataHash().getOctets();
if (!Arrays.equals(isBytes, expBytes)) {
addViolation(failureMsg, "biometricData[" + i + "].biometricDataHash", hex(isBytes), hex(expBytes));
}
DERIA5String str = isData.getSourceDataUri();
String isSourceDataUri = (str == null) ? null : str.getString();
String expSourceDataUri = null;
if (conf.getSourceDataUriOccurrence() != TripleState.forbidden) {
str = expData.getSourceDataUri();
expSourceDataUri = (str == null) ? null : str.getString();
}
if (expSourceDataUri == null) {
if (isSourceDataUri != null) {
addViolation(failureMsg, "biometricData[" + i + "].sourceDataUri", "present", "absent");
}
} else {
if (isSourceDataUri == null) {
failureMsg.append("biometricData[").append(i).append("].sourceDataUri is 'absent'");
failureMsg.append(" but expected 'present'; ");
} else if (!isSourceDataUri.equals(expSourceDataUri)) {
addViolation(failureMsg, "biometricData[" + i + "].sourceDataUri", isSourceDataUri, expSourceDataUri);
}
}
}
}
use of com.github.zhenwei.core.asn1.x509.Extensions in project xipki by xipki.
the class A2gChecker method checkExtnExtendedKeyUsage.
// method checkExtnCrlDistributionPoints
void checkExtnExtendedKeyUsage(StringBuilder failureMsg, byte[] extnValue, Extensions requestedExtns, ExtensionControl extnControl) {
Set<String> isUsages = new HashSet<>();
org.bouncycastle.asn1.x509.ExtendedKeyUsage keyusage = org.bouncycastle.asn1.x509.ExtendedKeyUsage.getInstance(extnValue);
KeyPurposeId[] usages = keyusage.getUsages();
if (usages != null) {
for (KeyPurposeId usage : usages) {
isUsages.add(usage.getId());
}
}
Set<String> expectedUsages = new HashSet<>();
Set<ExtKeyUsageControl> requiredExtKeyusage = caller.getExtKeyusage(true);
if (requiredExtKeyusage != null) {
for (ExtKeyUsageControl usage : requiredExtKeyusage) {
expectedUsages.add(usage.getExtKeyUsage().getId());
}
}
Set<ExtKeyUsageControl> optionalExtKeyusage = caller.getExtKeyusage(false);
if (requestedExtns != null && extnControl.isRequest() && isNotEmpty(optionalExtKeyusage)) {
Extension extension = requestedExtns.getExtension(Extension.extendedKeyUsage);
if (extension != null) {
org.bouncycastle.asn1.x509.ExtendedKeyUsage reqKeyUsage = org.bouncycastle.asn1.x509.ExtendedKeyUsage.getInstance(extension.getParsedValue());
for (ExtKeyUsageControl k : optionalExtKeyusage) {
if (reqKeyUsage.hasKeyPurposeId(KeyPurposeId.getInstance(k.getExtKeyUsage()))) {
expectedUsages.add(k.getExtKeyUsage().getId());
}
}
}
}
if (isEmpty(expectedUsages)) {
byte[] constantExtValue = caller.getConstantExtensionValue(Extension.extendedKeyUsage);
if (constantExtValue != null) {
expectedUsages = getExtKeyUsage(constantExtValue);
}
}
Set<String> diffs = strInBnotInA(expectedUsages, isUsages);
if (isNotEmpty(diffs)) {
failureMsg.append("usages ").append(diffs).append(" are present but not expected; ");
}
diffs = strInBnotInA(isUsages, expectedUsages);
if (isNotEmpty(diffs)) {
failureMsg.append("usages ").append(diffs).append(" are absent but are required; ");
}
}
use of com.github.zhenwei.core.asn1.x509.Extensions in project xipki by xipki.
the class OcspServerImpl method answer.
// method close
@Override
public OcspRespWithCacheInfo answer(Responder responder2, byte[] request, boolean viaGet) {
ResponderImpl responder = (ResponderImpl) responder2;
RequestOption reqOpt = responder.getRequestOption();
int version;
try {
version = OcspRequest.readRequestVersion(request);
} catch (EncodingException ex) {
String message = "could not extract version from request";
LOG.warn(message);
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
}
if (!reqOpt.isVersionAllowed(version)) {
String message = "invalid request version " + version;
LOG.warn(message);
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
}
ResponseSigner signer = responder.getSigner();
OcspServerConf.ResponseOption repOpt = responder.getResponseOption();
try {
Object reqOrRrrorResp = checkSignature(request, reqOpt);
if (reqOrRrrorResp instanceof OcspRespWithCacheInfo) {
// error
return (OcspRespWithCacheInfo) reqOrRrrorResp;
}
OcspRequest req = (OcspRequest) reqOrRrrorResp;
List<CertID> requestList = req.getRequestList();
int requestsSize = requestList.size();
if (requestsSize > reqOpt.getMaxRequestListCount()) {
String message = requestsSize + " entries in RequestList, but maximal " + reqOpt.getMaxRequestListCount() + " is allowed";
LOG.warn(message);
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
}
// -----begin license -----
if (!license.isValid()) {
LOG.error("License not valid, need new license");
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.internalError);
}
if (!license.grantAllCAs()) {
for (CertID cid : requestList) {
for (OcspStore store : responder.getStores()) {
X509Cert caCert = store.getIssuerCert(cid.getIssuer());
if (caCert == null) {
continue;
}
String issuerSubject = caCert.getSubjectRfc4519Text();
boolean granted = license.grant(issuerSubject);
if (!granted) {
LOG.error("Not granted for CA {}, need new license", issuerSubject);
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.internalError);
}
}
}
}
license.regulateSpeed();
// -----end license-----
OcspRespControl repControl = new OcspRespControl();
repControl.canCacheInfo = true;
List<ExtendedExtension> reqExtensions = req.getExtensions();
List<Extension> respExtensions = new LinkedList<>();
ExtendedExtension ocspRespExtn = removeExtension(reqExtensions, OID.ID_PKIX_OCSP_RESPONSE);
if (ocspRespExtn != null) {
boolean containsBasic = ocspRespExtn.equalsExtnValue(encodedAcceptableResponses_Basic);
if (!containsBasic) {
// we need to parse the extension
byte[] extnValue = new byte[ocspRespExtn.getExtnValueLength()];
ocspRespExtn.writeExtnValue(extnValue, 0);
ASN1Sequence seq = ASN1Sequence.getInstance(extnValue);
final int size = seq.size();
for (int i = 0; i < size; i++) {
ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(i));
if (OCSPObjectIdentifiers.id_pkix_ocsp_basic.equals(oid)) {
containsBasic = true;
break;
}
}
}
if (!containsBasic) {
LOG.warn("basic OCSP response is not accepted by the client");
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
}
}
ExtendedExtension nonceExtn = removeExtension(reqExtensions, OID.ID_PKIX_OCSP_NONCE);
if (nonceExtn != null) {
if (reqOpt.getNonceOccurrence() == QuadrupleState.forbidden) {
LOG.warn("nonce forbidden, but is present in the request");
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
}
if (reqOpt.getNonceOccurrence() == QuadrupleState.ignore) {
nonceExtn = null;
} else {
int len = nonceExtn.getExtnValueLength();
int min = reqOpt.getNonceMinLen();
int max = reqOpt.getNonceMaxLen();
if (len < min || len > max) {
LOG.warn("length of nonce {} not within [{},{}]", len, min, max);
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
}
repControl.canCacheInfo = false;
if (nonceExtn.isCritical()) {
respExtensions.add(nonceExtn.revertCritical());
} else {
respExtensions.add(nonceExtn);
}
}
} else {
if (reqOpt.getNonceOccurrence() == QuadrupleState.required) {
LOG.warn("nonce required, but is not present in the request");
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
}
}
ConcurrentContentSigner concurrentSigner = null;
if (responder.getResponderOption().getMode() != OcspMode.RFC2560) {
ExtendedExtension extn = removeExtension(reqExtensions, OID.ID_PKIX_OCSP_PREFSIGALGS);
if (extn != null) {
ASN1InputStream asn1Stream = new ASN1InputStream(extn.getExtnValueStream());
List<AlgorithmIdentifier> prefSigAlgs;
try {
ASN1Sequence seq = ASN1Sequence.getInstance(asn1Stream.readObject());
final int size = seq.size();
prefSigAlgs = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
prefSigAlgs.add(AlgorithmIdentifier.getInstance(seq.getObjectAt(i)));
}
} finally {
asn1Stream.close();
}
concurrentSigner = signer.getSignerForPreferredSigAlgs(prefSigAlgs);
}
}
if (!reqExtensions.isEmpty()) {
boolean flag = false;
for (ExtendedExtension m : reqExtensions) {
if (m.isCritical()) {
flag = true;
break;
}
}
if (flag) {
if (LOG.isWarnEnabled()) {
List<OID> oids = new LinkedList<>();
for (ExtendedExtension m : reqExtensions) {
if (m.isCritical()) {
oids.add(m.getExtnType());
}
}
LOG.warn("could not process critical request extensions: {}", oids);
}
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
}
}
if (concurrentSigner == null) {
concurrentSigner = signer.getFirstSigner();
}
SignAlgo cacheDbSigAlg = null;
BigInteger cacheDbSerialNumber = null;
IssuerEntry cacheDbIssuer = null;
boolean canCacheDb = (requestsSize == 1) && (responseCacher != null) && (nonceExtn == null) && responseCacher.isOnService();
if (canCacheDb) {
// try to find the cached response
CertID certId = requestList.get(0);
HashAlgo reqHashAlgo = certId.getIssuer().hashAlgorithm();
if (!reqOpt.allows(reqHashAlgo)) {
LOG.warn("CertID.hashAlgorithm {} not allowed", reqHashAlgo != null ? reqHashAlgo : certId.getIssuer().hashAlgorithmOID());
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
}
cacheDbSigAlg = concurrentSigner.getAlgorithm();
cacheDbIssuer = responseCacher.getIssuer(certId.getIssuer());
cacheDbSerialNumber = certId.getSerialNumber();
if (cacheDbIssuer != null) {
OcspRespWithCacheInfo cachedResp = responseCacher.getOcspResponse(cacheDbIssuer.getId(), cacheDbSerialNumber, cacheDbSigAlg);
if (cachedResp != null) {
boolean granted = license.grant(cacheDbIssuer.getCert().getSubjectRfc4519Text());
if (granted) {
return cachedResp;
} else {
LOG.error("Not granted, new license needed");
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
}
}
} else if (master) {
// store the issuer certificate in cache database.
X509Cert issuerCert = null;
for (OcspStore store : responder.getStores()) {
issuerCert = store.getIssuerCert(certId.getIssuer());
if (issuerCert != null) {
break;
}
}
if (issuerCert != null) {
cacheDbIssuer = responseCacher.storeIssuer(issuerCert);
}
}
if (cacheDbIssuer == null) {
canCacheDb = false;
}
}
ResponderID responderId = signer.getResponderId(repOpt.isResponderIdByName());
OCSPRespBuilder builder = new OCSPRespBuilder(responderId);
boolean unknownAsRevoked = false;
AtomicBoolean unknownAsRevoked0 = new AtomicBoolean(false);
for (CertID certID : requestList) {
OcspRespWithCacheInfo failureOcspResp = processCertReq(unknownAsRevoked0, certID, builder, responder, reqOpt, repOpt, repControl);
if (failureOcspResp != null) {
return failureOcspResp;
}
if (unknownAsRevoked0.get()) {
unknownAsRevoked = true;
}
}
if (unknownAsRevoked && repControl.includeExtendedRevokeExtension) {
respExtensions.add(extension_pkix_ocsp_extendedRevoke);
}
if (!respExtensions.isEmpty()) {
builder.setResponseExtensions(new Extensions(respExtensions));
}
TaggedCertSequence certsInResp;
EmbedCertsMode certsMode = repOpt.getEmbedCertsMode();
if (certsMode == EmbedCertsMode.SIGNER) {
certsInResp = signer.getSequenceOfCert();
} else if (certsMode == EmbedCertsMode.NONE) {
certsInResp = null;
} else {
// certsMode == EmbedCertsMode.SIGNER_AND_CA
certsInResp = signer.getSequenceOfCertChain();
}
Date producedAt = new Date();
byte[] encodeOcspResponse;
try {
encodeOcspResponse = builder.buildOCSPResponse(concurrentSigner, certsInResp, producedAt);
} catch (NoIdleSignerException ex) {
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.tryLater);
} catch (OCSPException ex) {
LogUtil.error(LOG, ex, "answer() basicOcspBuilder.build");
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.internalError);
}
long producedAtSeconds = producedAt.getTime() / 1000;
// cache response in database
if (canCacheDb && repControl.canCacheInfo) {
// Don't cache the response with status UNKNOWN, since this may result in DDoS
// of storage
responseCacher.storeOcspResponse(cacheDbIssuer.getId(), cacheDbSerialNumber, producedAtSeconds, repControl.cacheNextUpdate, cacheDbSigAlg, encodeOcspResponse);
}
if (viaGet && repControl.canCacheInfo) {
ResponseCacheInfo cacheInfo = new ResponseCacheInfo(producedAtSeconds);
if (repControl.cacheNextUpdate != Long.MAX_VALUE) {
cacheInfo.setNextUpdate(repControl.cacheNextUpdate);
}
return new OcspRespWithCacheInfo(encodeOcspResponse, cacheInfo);
} else {
return new OcspRespWithCacheInfo(encodeOcspResponse, null);
}
} catch (Throwable th) {
LogUtil.error(LOG, th);
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.internalError);
}
}
Aggregations