use of org.xipki.security.CertRevocationInfo in project xipki by xipki.
the class CertStoreQueryExecutor method revokeCert.
// method addCrl
X509CertWithRevocationInfo revokeCert(NameId ca, BigInteger serialNumber, CertRevocationInfo revInfo, boolean force, boolean publishToDeltaCrlCache, CaIdNameMap idNameMap) throws OperationException, DataAccessException {
ParamUtil.requireNonNull("ca", ca);
ParamUtil.requireNonNull("serialNumber", serialNumber);
ParamUtil.requireNonNull("revInfo", revInfo);
X509CertWithRevocationInfo certWithRevInfo = getCertWithRevocationInfo(ca, serialNumber, idNameMap);
if (certWithRevInfo == null) {
LOG.warn("certificate with CA={} and serialNumber={} does not exist", ca.getName(), LogUtil.formatCsn(serialNumber));
return null;
}
CertRevocationInfo currentRevInfo = certWithRevInfo.getRevInfo();
if (currentRevInfo != null) {
CrlReason currentReason = currentRevInfo.getReason();
if (currentReason == CrlReason.CERTIFICATE_HOLD) {
if (revInfo.getReason() == CrlReason.CERTIFICATE_HOLD) {
throw new OperationException(ErrorCode.CERT_REVOKED, "certificate already revoked with the requested reason " + currentReason.getDescription());
} else {
revInfo.setRevocationTime(currentRevInfo.getRevocationTime());
revInfo.setInvalidityTime(currentRevInfo.getInvalidityTime());
}
} else if (!force) {
throw new OperationException(ErrorCode.CERT_REVOKED, "certificate already revoked with reason " + currentReason.getDescription());
}
}
long certId = certWithRevInfo.getCert().getCertId().longValue();
long revTimeSeconds = revInfo.getRevocationTime().getTime() / 1000;
Long invTimeSeconds = null;
if (revInfo.getInvalidityTime() != null) {
invTimeSeconds = revInfo.getInvalidityTime().getTime() / 1000;
}
PreparedStatement ps = borrowPreparedStatement(SQLs.SQL_REVOKE_CERT);
try {
int idx = 1;
ps.setLong(idx++, System.currentTimeMillis() / 1000);
setBoolean(ps, idx++, true);
ps.setLong(idx++, revTimeSeconds);
setLong(ps, idx++, invTimeSeconds);
ps.setInt(idx++, revInfo.getReason().getCode());
ps.setLong(idx++, certId);
int count = ps.executeUpdate();
if (count != 1) {
String message = (count > 1) ? count + " rows modified, but exactly one is expected" : "no row is modified, but exactly one is expected";
throw new OperationException(ErrorCode.SYSTEM_FAILURE, message);
}
} catch (SQLException ex) {
throw datasource.translate(SQLs.SQL_REVOKE_CERT, ex);
} finally {
releaseDbResources(ps, null);
}
if (publishToDeltaCrlCache) {
publishToDeltaCrlCache(ca, certWithRevInfo.getCert().getCert().getSerialNumber());
}
certWithRevInfo.setRevInfo(revInfo);
return certWithRevInfo;
}
use of org.xipki.security.CertRevocationInfo in project xipki by xipki.
the class CertStoreQueryExecutor method getCertWithRevocationInfo.
// method getCertForId
X509CertWithRevocationInfo getCertWithRevocationInfo(NameId ca, BigInteger serial, CaIdNameMap idNameMap) throws DataAccessException, OperationException {
ParamUtil.requireNonNull("ca", ca);
ParamUtil.requireNonNull("serial", serial);
ParamUtil.requireNonNull("idNameMap", idNameMap);
final String sql = sqls.sqlCertWithRevInfo;
long certId;
String b64Cert;
boolean revoked;
int revReason = 0;
long revTime = 0;
long revInvTime = 0;
int certprofileId = 0;
ResultSet rs = null;
PreparedStatement ps = borrowPreparedStatement(sql);
try {
int idx = 1;
ps.setInt(idx++, ca.getId());
ps.setString(idx++, serial.toString(16));
rs = ps.executeQuery();
if (!rs.next()) {
return null;
}
certId = rs.getLong("ID");
b64Cert = rs.getString("CERT");
certprofileId = rs.getInt("PID");
revoked = rs.getBoolean("REV");
if (revoked) {
revReason = rs.getInt("RR");
revTime = rs.getLong("RT");
revInvTime = rs.getLong("RIT");
}
} catch (SQLException ex) {
throw datasource.translate(sql, ex);
} finally {
releaseDbResources(ps, null);
}
byte[] certBytes = Base64.decodeFast(b64Cert);
X509Certificate cert;
try {
cert = X509Util.parseCert(certBytes);
} catch (CertificateException ex) {
throw new OperationException(ErrorCode.SYSTEM_FAILURE, ex);
}
CertRevocationInfo revInfo = null;
if (revoked) {
Date invalidityTime = (revInvTime == 0) ? null : new Date(1000 * revInvTime);
revInfo = new CertRevocationInfo(revReason, new Date(1000 * revTime), invalidityTime);
}
X509CertWithDbId certWithMeta = new X509CertWithDbId(cert, certBytes);
certWithMeta.setCertId(certId);
String profileName = idNameMap.getCertprofileName(certprofileId);
X509CertWithRevocationInfo ret = new X509CertWithRevocationInfo();
ret.setCertprofile(profileName);
ret.setCert(certWithMeta);
ret.setRevInfo(revInfo);
return ret;
}
use of org.xipki.security.CertRevocationInfo in project xipki by xipki.
the class CaManagerQueryExecutor method createCaInfo.
// method createResponder
X509CaInfo createCaInfo(String name, boolean masterMode, CertificateStore certstore) throws CaMgmtException {
final String sql = sqls.sqlSelectCa;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
stmt = prepareStatement(sql);
stmt.setString(1, name);
rs = stmt.executeQuery();
if (!rs.next()) {
throw new CaMgmtException("uknown CA " + name);
}
int artCode = rs.getInt("ART");
if (artCode != CertArt.X509PKC.getCode()) {
throw new CaMgmtException("CA " + name + " is not X509CA, and is not supported");
}
String crlUris = rs.getString("CRL_URIS");
String deltaCrlUris = rs.getString("DELTACRL_URIS");
CertRevocationInfo revocationInfo = null;
boolean revoked = rs.getBoolean("REV");
if (revoked) {
int revReason = rs.getInt("RR");
long revTime = rs.getInt("RT");
long revInvalidityTime = rs.getInt("RIT");
Date revInvTime = (revInvalidityTime == 0) ? null : new Date(revInvalidityTime * 1000);
revocationInfo = new CertRevocationInfo(revReason, new Date(revTime * 1000), revInvTime);
}
List<String> tmpCrlUris = null;
if (StringUtil.isNotBlank(crlUris)) {
tmpCrlUris = StringUtil.splitByComma(crlUris);
}
List<String> tmpDeltaCrlUris = null;
if (StringUtil.isNotBlank(deltaCrlUris)) {
tmpDeltaCrlUris = StringUtil.splitByComma(deltaCrlUris);
}
String ocspUris = rs.getString("OCSP_URIS");
List<String> tmpOcspUris = null;
if (StringUtil.isNotBlank(ocspUris)) {
tmpOcspUris = StringUtil.splitByComma(ocspUris);
}
String caCertUris = rs.getString("CACERT_URIS");
List<String> tmpCaCertUris = null;
if (StringUtil.isNotBlank(caCertUris)) {
tmpCaCertUris = StringUtil.splitByComma(caCertUris);
}
X509CaUris caUris = new X509CaUris(tmpCaCertUris, tmpOcspUris, tmpCrlUris, tmpDeltaCrlUris);
int id = rs.getInt("ID");
int serialNoSize = rs.getInt("SN_SIZE");
long nextCrlNo = rs.getLong("NEXT_CRLNO");
String signerType = rs.getString("SIGNER_TYPE");
String signerConf = rs.getString("SIGNER_CONF");
int numCrls = rs.getInt("NUM_CRLS");
int expirationPeriod = rs.getInt("EXPIRATION_PERIOD");
X509CaEntry entry = new X509CaEntry(new NameId(id, name), serialNoSize, nextCrlNo, signerType, signerConf, caUris, numCrls, expirationPeriod);
String b64cert = rs.getString("CERT");
X509Certificate cert = generateCert(b64cert);
entry.setCert(cert);
String status = rs.getString("STATUS");
CaStatus caStatus = CaStatus.forName(status);
entry.setStatus(caStatus);
String maxValidityS = rs.getString("MAX_VALIDITY");
CertValidity maxValidity = CertValidity.getInstance(maxValidityS);
entry.setMaxValidity(maxValidity);
int keepExpiredCertDays = rs.getInt("KEEP_EXPIRED_CERT_DAYS");
entry.setKeepExpiredCertInDays(keepExpiredCertDays);
String crlsignerName = rs.getString("CRLSIGNER_NAME");
if (StringUtil.isNotBlank(crlsignerName)) {
entry.setCrlSignerName(crlsignerName);
}
String responderName = rs.getString("RESPONDER_NAME");
if (StringUtil.isNotBlank(responderName)) {
entry.setResponderName(responderName);
}
String extraControl = rs.getString("EXTRA_CONTROL");
if (StringUtil.isNotBlank(extraControl)) {
entry.setExtraControl(new ConfPairs(extraControl).unmodifiable());
}
String cmpcontrolName = rs.getString("CMPCONTROL_NAME");
if (StringUtil.isNotBlank(cmpcontrolName)) {
entry.setCmpControlName(cmpcontrolName);
}
boolean duplicateKeyPermitted = (rs.getInt("DUPLICATE_KEY") != 0);
entry.setDuplicateKeyPermitted(duplicateKeyPermitted);
boolean duplicateSubjectPermitted = (rs.getInt("DUPLICATE_SUBJECT") != 0);
entry.setDuplicateSubjectPermitted(duplicateSubjectPermitted);
boolean saveReq = (rs.getInt("SAVE_REQ") != 0);
entry.setSaveRequest(saveReq);
int permission = rs.getInt("PERMISSION");
entry.setPermission(permission);
entry.setRevocationInfo(revocationInfo);
String validityModeS = rs.getString("VALIDITY_MODE");
ValidityMode validityMode = null;
if (validityModeS != null) {
validityMode = ValidityMode.forName(validityModeS);
}
if (validityMode == null) {
validityMode = ValidityMode.STRICT;
}
entry.setValidityMode(validityMode);
try {
return new X509CaInfo(entry, certstore);
} catch (OperationException ex) {
throw new CaMgmtException(ex);
}
} catch (SQLException ex) {
throw new CaMgmtException(datasource, sql, ex);
} finally {
datasource.releaseResources(stmt, rs);
}
}
use of org.xipki.security.CertRevocationInfo in project xipki by xipki.
the class OcspServerImpl method processCertReq.
// method ask
private OcspRespWithCacheInfo processCertReq(CertID certId, OCSPRespBuilder builder, ResponderImpl responder, RequestOption reqOpt, ResponseOption repOpt, OcspRespControl repControl) throws IOException {
HashAlgo reqHashAlgo = certId.getIssuer().hashAlgorithm();
if (!reqOpt.allows(reqHashAlgo)) {
LOG.warn("CertID.hashAlgorithm {} not allowed", reqHashAlgo);
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
}
CertStatusInfo certStatusInfo = null;
boolean exceptionOccurs = false;
BigInteger serial = certId.getSerialNumber();
Date now = new Date();
for (OcspStore store : responder.getStores()) {
try {
certStatusInfo = store.getCertStatus(now, certId.getIssuer(), serial, repOpt.isIncludeCerthash(), repOpt.isIncludeInvalidityDate(), responder.getResponderOption().isInheritCaRevocation());
if (certStatusInfo != null) {
break;
}
} catch (OcspStoreException ex) {
exceptionOccurs = true;
LogUtil.error(LOG, ex, "getCertStatus() of CertStatusStore " + store.getName());
}
}
if (certStatusInfo == null) {
if (exceptionOccurs) {
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.tryLater);
} else {
certStatusInfo = CertStatusInfo.getIssuerUnknownCertStatusInfo(new Date(), null);
}
}
// end if
// certStatusInfo must not be null in any case, since at least one store is configured
Date thisUpdate = certStatusInfo.getThisUpdate();
if (thisUpdate == null) {
thisUpdate = new Date();
}
Date nextUpdate = certStatusInfo.getNextUpdate();
List<Extension> extensions = new LinkedList<>();
boolean unknownAsRevoked = false;
byte[] certStatus;
switch(certStatusInfo.getCertStatus()) {
case GOOD:
certStatus = bytes_certstatus_good;
break;
case ISSUER_UNKNOWN:
repControl.canCacheInfo = false;
certStatus = bytes_certstatus_unknown;
break;
case UNKNOWN:
case IGNORE:
repControl.canCacheInfo = false;
if (responder.getResponderOption().getMode() == OcspMode.RFC2560) {
certStatus = bytes_certstatus_unknown;
} else {
// (ocspMode == OCSPMode.RFC6960)
unknownAsRevoked = true;
certStatus = bytes_certstatus_rfc6960_unknown;
}
break;
case REVOKED:
CertRevocationInfo revInfo = certStatusInfo.getRevocationInfo();
certStatus = Template.getEncodeRevokedInfo(repOpt.isIncludeRevReason() ? revInfo.getReason() : null, revInfo.getRevocationTime());
Date invalidityDate = revInfo.getInvalidityTime();
if (repOpt.isIncludeInvalidityDate() && invalidityDate != null && !invalidityDate.equals(revInfo.getRevocationTime())) {
extensions.add(Template.getInvalidityDateExtension(invalidityDate));
}
break;
default:
throw new RuntimeException("unknown CertificateStatus:" + certStatusInfo.getCertStatus());
}
if (responder.getResponderOption().getMode() != OcspMode.RFC2560) {
repControl.includeExtendedRevokeExtension = true;
}
byte[] certHash = certStatusInfo.getCertHash();
if (certHash != null) {
extensions.add(Template.getCertHashExtension(certStatusInfo.getCertHashAlgo(), certHash));
}
if (certStatusInfo.getArchiveCutOff() != null) {
extensions.add(Template.getArchiveOffExtension(certStatusInfo.getArchiveCutOff()));
}
if (LOG.isDebugEnabled()) {
String certStatusText = null;
if (Arrays.equals(certStatus, bytes_certstatus_good)) {
certStatusText = "good";
} else if (Arrays.equals(certStatus, bytes_certstatus_unknown)) {
certStatusText = "unknown";
} else if (Arrays.equals(certStatus, bytes_certstatus_rfc6960_unknown)) {
certStatusText = "RFC6969_unknown";
} else {
certStatusText = unknownAsRevoked ? "unknown_as_revoked" : "revoked";
}
String msg = StringUtil.concatObjectsCap(250, "issuer: ", certId.getIssuer(), ", serialNumber: ", LogUtil.formatCsn(certId.getSerialNumber()), ", certStatus: ", certStatusText, ", thisUpdate: ", thisUpdate, ", nextUpdate: ", nextUpdate);
StringBuilder sb = new StringBuilder(msg.length() + 80);
sb.append(msg);
if (certHash != null) {
sb.append(", certHash: ").append(Hex.encode(certHash));
}
LOG.debug(sb.toString());
}
if (CollectionUtil.isEmpty(extensions)) {
builder.addResponse(certId, certStatus, thisUpdate, nextUpdate, null);
} else {
builder.addResponse(certId, certStatus, thisUpdate, nextUpdate, new Extensions(extensions));
}
repControl.cacheThisUpdate = Math.max(repControl.cacheThisUpdate, thisUpdate.getTime());
if (nextUpdate != null) {
repControl.cacheNextUpdate = Math.min(repControl.cacheNextUpdate, nextUpdate.getTime());
}
return null;
}
use of org.xipki.security.CertRevocationInfo in project xipki by xipki.
the class CrlDbCertStatusStore method initializeStore.
private synchronized void initializeStore(DataSourceWrapper datasource) {
if (crlUpdateInProcess.get()) {
return;
}
crlUpdateInProcess.set(true);
Boolean updateCrlSuccessful = null;
File updateMeFile = new File(crlFilename + ".UPDATEME");
if (!updateMeFile.exists()) {
LOG.info("The CRL will not be updated. Create new file {} to force the update", updateMeFile.getAbsolutePath());
crlUpdated = true;
crlUpdateFailed = false;
return;
}
try {
File fullCrlFile = new File(crlFilename);
if (!fullCrlFile.exists()) {
// file does not exist
LOG.warn("CRL File {} does not exist", crlFilename);
return;
}
LOG.info("UPDATE_CERTSTORE: a newer CRL is available");
updateCrlSuccessful = false;
X509CRL crl = X509Util.parseCrl(crlFilename);
File revFile = new File(crlFilename + ".revocation");
CertRevocationInfo caRevInfo = null;
if (revFile.exists()) {
Properties props = new Properties();
FileInputStream is = new FileInputStream(revFile);
try {
props.load(is);
} finally {
is.close();
}
String str = props.getProperty(KEY_CA_REVOCATION_TIME);
if (StringUtil.isNotBlank(str)) {
Date revocationTime = DateUtil.parseUtcTimeyyyyMMddhhmmss(str);
Date invalidityTime = null;
str = props.getProperty(KEY_CA_INVALIDITY_TIME);
if (StringUtil.isNotBlank(str)) {
invalidityTime = DateUtil.parseUtcTimeyyyyMMddhhmmss(str);
}
caRevInfo = new CertRevocationInfo(CrlReason.UNSPECIFIED, revocationTime, invalidityTime);
}
}
ImportCrl importCrl = new ImportCrl(datasource, useUpdateDatesFromCrl, crl, crlUrl, caCert, issuerCert, caRevInfo, certsDirName);
updateCrlSuccessful = importCrl.importCrlToOcspDb();
crlUpdated = true;
if (updateCrlSuccessful) {
crlUpdateFailed = false;
LOG.info("updated CertStore {} successfully", name);
} else {
crlUpdateFailed = true;
LOG.error("updating CertStore {} failed", name);
}
} catch (Throwable th) {
LogUtil.error(LOG, th, "could not execute initializeStore()");
crlUpdateFailed = true;
crlUpdated = true;
} finally {
updateMeFile.delete();
crlUpdateInProcess.set(false);
if (updateCrlSuccessful != null) {
if (updateCrlSuccessful.booleanValue()) {
LOG.info("UPDATE_CRL: successful");
} else {
LOG.warn("UPDATE_CRL: failed");
}
}
}
}
Aggregations