use of org.xipki.ca.api.OperationException in project xipki by xipki.
the class CertStoreQueryExecutor method addCert.
// constructor
void addCert(NameId ca, X509CertWithDbId certificate, byte[] encodedSubjectPublicKey, NameId certProfile, NameId requestor, Integer userId, RequestType reqType, byte[] transactionId, X500Name reqSubject) throws DataAccessException, OperationException {
ParamUtil.requireNonNull("ca", ca);
ParamUtil.requireNonNull("certificate", certificate);
ParamUtil.requireNonNull("certProfile", certProfile);
ParamUtil.requireNonNull("requestor", requestor);
long certId = idGenerator.nextId();
X509Certificate cert = certificate.getCert();
long fpPk = FpIdCalculator.hash(encodedSubjectPublicKey);
String subjectText = X509Util.cutText(certificate.getSubject(), maxX500nameLen);
long fpSubject = X509Util.fpCanonicalizedName(cert.getSubjectX500Principal());
String reqSubjectText = null;
Long fpReqSubject = null;
if (reqSubject != null) {
fpReqSubject = X509Util.fpCanonicalizedName(reqSubject);
if (fpSubject == fpReqSubject) {
fpReqSubject = null;
} else {
reqSubjectText = X509Util.cutX500Name(CaUtil.sortX509Name(reqSubject), maxX500nameLen);
}
}
String b64FpCert = base64Fp(certificate.getEncodedCert());
String b64Cert = Base64.encodeToString(certificate.getEncodedCert());
String tid = (transactionId == null) ? null : Base64.encodeToString(transactionId);
long currentTimeSeconds = System.currentTimeMillis() / 1000;
BigInteger serialNumber = cert.getSerialNumber();
long notBeforeSeconds = cert.getNotBefore().getTime() / 1000;
long notAfterSeconds = cert.getNotAfter().getTime() / 1000;
Connection conn = null;
PreparedStatement[] pss = borrowPreparedStatements(SQLs.SQL_ADD_CERT, SQLs.SQL_ADD_CRAW);
try {
PreparedStatement psAddcert = pss[0];
// all statements have the same connection
conn = psAddcert.getConnection();
// cert
int idx = 2;
psAddcert.setInt(idx++, CertArt.X509PKC.getCode());
psAddcert.setLong(idx++, currentTimeSeconds);
psAddcert.setString(idx++, serialNumber.toString(16));
psAddcert.setString(idx++, subjectText);
psAddcert.setLong(idx++, fpSubject);
setLong(psAddcert, idx++, fpReqSubject);
psAddcert.setLong(idx++, notBeforeSeconds);
psAddcert.setLong(idx++, notAfterSeconds);
setBoolean(psAddcert, idx++, false);
psAddcert.setInt(idx++, certProfile.getId());
psAddcert.setInt(idx++, ca.getId());
setInt(psAddcert, idx++, requestor.getId());
setInt(psAddcert, idx++, userId);
psAddcert.setLong(idx++, fpPk);
boolean isEeCert = cert.getBasicConstraints() == -1;
psAddcert.setInt(idx++, isEeCert ? 1 : 0);
psAddcert.setInt(idx++, reqType.getCode());
psAddcert.setString(idx++, tid);
// rawcert
PreparedStatement psAddRawcert = pss[1];
idx = 2;
psAddRawcert.setString(idx++, b64FpCert);
psAddRawcert.setString(idx++, reqSubjectText);
psAddRawcert.setString(idx++, b64Cert);
certificate.setCertId(certId);
psAddcert.setLong(1, certId);
psAddRawcert.setLong(1, certId);
final boolean origAutoCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
String sql = null;
try {
sql = SQLs.SQL_ADD_CERT;
psAddcert.executeUpdate();
sql = SQLs.SQL_ADD_CRAW;
psAddRawcert.executeUpdate();
sql = "(commit add cert to CA certstore)";
conn.commit();
} catch (Throwable th) {
conn.rollback();
// more secure
datasource.deleteFromTable(null, "CRAW", "CID", certId);
datasource.deleteFromTable(null, "CERT", "ID", certId);
if (th instanceof SQLException) {
LOG.error("datasource {} could not add certificate with id {}: {}", datasource.getName(), certId, th.getMessage());
throw datasource.translate(sql, (SQLException) th);
} else {
throw new OperationException(ErrorCode.SYSTEM_FAILURE, th);
}
} finally {
conn.setAutoCommit(origAutoCommit);
}
} catch (SQLException ex) {
throw datasource.translate(null, ex);
} finally {
try {
for (PreparedStatement ps : pss) {
releaseStatement(ps);
}
} finally {
if (conn != null) {
datasource.returnConnection(conn);
}
}
}
}
use of org.xipki.ca.api.OperationException in project xipki by xipki.
the class CertStoreQueryExecutor method getCertForId.
// method getCertForId
X509CertWithDbId getCertForId(long certId) throws DataAccessException, OperationException {
final String sql = sqls.sqlRawCertForId;
String b64Cert;
ResultSet rs = null;
PreparedStatement ps = borrowPreparedStatement(sql);
try {
ps.setLong(1, certId);
rs = ps.executeQuery();
if (!rs.next()) {
return null;
}
b64Cert = rs.getString("CERT");
} catch (SQLException ex) {
throw datasource.translate(sql, ex);
} finally {
releaseDbResources(ps, rs);
}
if (b64Cert == null) {
return null;
}
byte[] encodedCert = Base64.decodeFast(b64Cert);
X509Certificate cert;
try {
cert = X509Util.parseCert(encodedCert);
} catch (CertificateException ex) {
throw new OperationException(ErrorCode.SYSTEM_FAILURE, ex);
}
return new X509CertWithDbId(cert, encodedCert);
}
use of org.xipki.ca.api.OperationException in project xipki by xipki.
the class CertStoreQueryExecutor method getCertificateInfo.
// method getCertWithRevocationInfo
X509CertificateInfo getCertificateInfo(NameId ca, X509Cert caCert, BigInteger serial, CaIdNameMap idNameMap) throws DataAccessException, OperationException, CertificateException {
ParamUtil.requireNonNull("ca", ca);
ParamUtil.requireNonNull("caCert", caCert);
ParamUtil.requireNonNull("idNameMap", idNameMap);
ParamUtil.requireNonNull("serial", serial);
final String sql = sqls.sqlCertInfo;
String b64Cert;
boolean revoked;
int revReason = 0;
long revTime = 0;
long revInvTime = 0;
int certprofileId;
int requestorId;
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;
}
b64Cert = rs.getString("CERT");
certprofileId = rs.getInt("PID");
requestorId = rs.getInt("RID");
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, rs);
}
try {
byte[] encodedCert = Base64.decodeFast(b64Cert);
X509Certificate cert = X509Util.parseCert(encodedCert);
X509CertWithDbId certWithMeta = new X509CertWithDbId(cert, encodedCert);
byte[] subjectPublicKeyInfo = Certificate.getInstance(encodedCert).getTBSCertificate().getSubjectPublicKeyInfo().getEncoded();
X509CertificateInfo certInfo = new X509CertificateInfo(certWithMeta, ca, caCert, subjectPublicKeyInfo, idNameMap.getCertprofile(certprofileId), idNameMap.getRequestor(requestorId));
if (!revoked) {
return certInfo;
}
Date invalidityTime = (revInvTime == 0) ? null : new Date(revInvTime * 1000);
CertRevocationInfo revInfo = new CertRevocationInfo(revReason, new Date(revTime * 1000), invalidityTime);
certInfo.setRevocationInfo(revInfo);
return certInfo;
} catch (IOException ex) {
LOG.warn("getCertificateInfo()", ex);
throw new OperationException(ErrorCode.SYSTEM_FAILURE, ex);
}
}
use of org.xipki.ca.api.OperationException in project xipki by xipki.
the class CertStoreQueryExecutor method unrevokeCert.
// method revokeSuspendedCert
X509CertWithDbId unrevokeCert(NameId ca, BigInteger serialNumber, boolean force, boolean publishToDeltaCrlCache, CaIdNameMap idNamMap) throws OperationException, DataAccessException {
ParamUtil.requireNonNull("ca", ca);
ParamUtil.requireNonNull("serialNumber", serialNumber);
X509CertWithRevocationInfo certWithRevInfo = getCertWithRevocationInfo(ca, serialNumber, idNamMap);
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) {
throw new OperationException(ErrorCode.CERT_UNREVOKED, "certificate is not revoked");
}
CrlReason currentReason = currentRevInfo.getReason();
if (!force) {
if (currentReason != CrlReason.CERTIFICATE_HOLD) {
throw new OperationException(ErrorCode.NOT_PERMITTED, "could not unrevoke certificate revoked with reason " + currentReason.getDescription());
}
}
final String sql = "UPDATE CERT SET LUPDATE=?,REV=?,RT=?,RIT=?,RR=? WHERE ID=?";
long certId = certWithRevInfo.getCert().getCertId().longValue();
long currentTimeSeconds = System.currentTimeMillis() / 1000;
PreparedStatement ps = borrowPreparedStatement(sql);
try {
int idx = 1;
ps.setLong(idx++, currentTimeSeconds);
setBoolean(ps, idx++, false);
ps.setNull(idx++, Types.INTEGER);
ps.setNull(idx++, Types.INTEGER);
ps.setNull(idx++, Types.INTEGER);
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(sql, ex);
} finally {
releaseDbResources(ps, null);
}
if (publishToDeltaCrlCache) {
publishToDeltaCrlCache(ca, certWithRevInfo.getCert().getCert().getSerialNumber());
}
return certWithRevInfo.getCert();
}
use of org.xipki.ca.api.OperationException in project xipki by xipki.
the class HttpScepServlet method service.
@Override
public FullHttpResponse service(FullHttpRequest request, ServletURI servletUri, SSLSession sslSession, SslReverseProxyMode sslReverseProxyMode) throws Exception {
HttpVersion version = request.protocolVersion();
HttpMethod method = request.method();
boolean viaPost;
if (method == HttpMethod.POST) {
viaPost = true;
} else if (method == HttpMethod.GET) {
viaPost = false;
} else {
return createErrorResponse(version, HttpResponseStatus.METHOD_NOT_ALLOWED);
}
String scepName = null;
String certProfileName = null;
if (servletUri.getPath().length() > 1) {
String scepPath = servletUri.getPath();
if (scepPath.endsWith(CGI_PROGRAM)) {
// skip also the first char (which is always '/')
String path = scepPath.substring(1, scepPath.length() - CGI_PROGRAM_LEN);
String[] tokens = path.split("/");
if (tokens.length == 2) {
scepName = tokens[0];
certProfileName = tokens[1].toLowerCase();
}
}
// end if
}
if (scepName == null || certProfileName == null) {
return createErrorResponse(version, HttpResponseStatus.NOT_FOUND);
}
AuditService auditService = auditServiceRegister.getAuditService();
AuditEvent event = new AuditEvent(new Date());
event.setApplicationName("SCEP");
event.setName(CaAuditConstants.NAME_PERF);
event.addEventData(CaAuditConstants.NAME_SCEP_name, scepName + "/" + certProfileName);
event.addEventData(CaAuditConstants.NAME_reqType, RequestType.SCEP.name());
String msgId = RandomUtil.nextHexLong();
event.addEventData(CaAuditConstants.NAME_mid, msgId);
AuditLevel auditLevel = AuditLevel.INFO;
AuditStatus auditStatus = AuditStatus.SUCCESSFUL;
String auditMessage = null;
try {
if (responderManager == null) {
auditMessage = "responderManager in servlet not configured";
LOG.error(auditMessage);
auditLevel = AuditLevel.ERROR;
auditStatus = AuditStatus.FAILED;
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
Scep responder = responderManager.getScep(scepName);
if (responder == null || !responder.isOnService() || !responder.supportsCertProfile(certProfileName)) {
auditMessage = "unknown SCEP '" + scepName + "/" + certProfileName + "'";
LOG.warn(auditMessage);
auditStatus = AuditStatus.FAILED;
return createErrorResponse(version, HttpResponseStatus.NOT_FOUND);
}
String operation = servletUri.getParameter("operation");
event.addEventData(CaAuditConstants.NAME_SCEP_operation, operation);
if ("PKIOperation".equalsIgnoreCase(operation)) {
CMSSignedData reqMessage;
// parse the request
try {
byte[] content;
if (viaPost) {
content = readContent(request);
} else {
String b64 = servletUri.getParameter("message");
content = Base64.decode(b64);
}
reqMessage = new CMSSignedData(content);
} catch (Exception ex) {
final String msg = "invalid request";
LogUtil.error(LOG, ex, msg);
auditMessage = msg;
auditStatus = AuditStatus.FAILED;
return createErrorResponse(version, HttpResponseStatus.BAD_REQUEST);
}
ContentInfo ci;
try {
ci = responder.servicePkiOperation(reqMessage, certProfileName, msgId, event);
} catch (MessageDecodingException ex) {
final String msg = "could not decrypt and/or verify the request";
LogUtil.error(LOG, ex, msg);
auditMessage = msg;
auditStatus = AuditStatus.FAILED;
return createErrorResponse(version, HttpResponseStatus.BAD_REQUEST);
} catch (OperationException ex) {
ErrorCode code = ex.getErrorCode();
HttpResponseStatus httpCode;
switch(code) {
case ALREADY_ISSUED:
case CERT_REVOKED:
case CERT_UNREVOKED:
httpCode = HttpResponseStatus.FORBIDDEN;
break;
case BAD_CERT_TEMPLATE:
case BAD_REQUEST:
case BAD_POP:
case INVALID_EXTENSION:
case UNKNOWN_CERT:
case UNKNOWN_CERT_PROFILE:
httpCode = HttpResponseStatus.BAD_REQUEST;
break;
case NOT_PERMITTED:
httpCode = HttpResponseStatus.UNAUTHORIZED;
break;
case SYSTEM_UNAVAILABLE:
httpCode = HttpResponseStatus.SERVICE_UNAVAILABLE;
break;
case CRL_FAILURE:
case DATABASE_FAILURE:
case SYSTEM_FAILURE:
httpCode = HttpResponseStatus.INTERNAL_SERVER_ERROR;
break;
default:
httpCode = HttpResponseStatus.INTERNAL_SERVER_ERROR;
break;
}
auditMessage = ex.getMessage();
LogUtil.error(LOG, ex, auditMessage);
auditStatus = AuditStatus.FAILED;
return createErrorResponse(version, httpCode);
}
byte[] bodyBytes = ci.getEncoded();
return createOKResponse(version, CT_RESPONSE, bodyBytes);
} else if (Operation.GetCACaps.getCode().equalsIgnoreCase(operation)) {
// CA-Ident is ignored
byte[] caCapsBytes = responder.getCaCaps().getBytes();
return createOKResponse(version, ScepConstants.CT_TEXT_PLAIN, caCapsBytes);
} else if (Operation.GetCACert.getCode().equalsIgnoreCase(operation)) {
// CA-Ident is ignored
byte[] respBytes = responder.getCaCertResp().getBytes();
return createOKResponse(version, ScepConstants.CT_X509_CA_RA_CERT, respBytes);
} else if (Operation.GetNextCACert.getCode().equalsIgnoreCase(operation)) {
auditMessage = "SCEP operation '" + operation + "' is not permitted";
auditStatus = AuditStatus.FAILED;
return createErrorResponse(version, HttpResponseStatus.FORBIDDEN);
} else {
auditMessage = "unknown SCEP operation '" + operation + "'";
auditStatus = AuditStatus.FAILED;
return createErrorResponse(version, HttpResponseStatus.BAD_REQUEST);
}
} catch (Throwable th) {
if (th instanceof EOFException) {
final String msg = "connection reset by peer";
if (LOG.isWarnEnabled()) {
LogUtil.warn(LOG, th, msg);
}
LOG.debug(msg, th);
} else {
LOG.error("Throwable thrown, this should not happen!", th);
}
auditLevel = AuditLevel.ERROR;
auditStatus = AuditStatus.FAILED;
auditMessage = "internal error";
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
} finally {
audit(auditService, event, auditLevel, auditStatus, auditMessage);
}
}
Aggregations