Search in sources :

Example 1 with MessageDecodingException

use of org.xipki.scep.exception.MessageDecodingException in project xipki by xipki.

the class ScepResponder method servicePkiOperation0.

private PkiMessage servicePkiOperation0(DecodedPkiMessage req, AuditEvent event) throws MessageDecodingException, CaException {
    TransactionId tid = req.getTransactionId();
    PkiMessage rep = new PkiMessage(tid, MessageType.CertRep, Nonce.randomNonce());
    rep.setPkiStatus(PkiStatus.SUCCESS);
    rep.setRecipientNonce(req.getSenderNonce());
    if (req.getFailureMessage() != null) {
        return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badRequest);
    }
    Boolean bo = req.isSignatureValid();
    if (bo != null && !bo.booleanValue()) {
        return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badMessageCheck);
    }
    bo = req.isDecryptionSuccessful();
    if (bo != null && !bo.booleanValue()) {
        return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badRequest);
    }
    Date signingTime = req.getSigningTime();
    if (maxSigningTimeBiasInMs > 0) {
        boolean isTimeBad = false;
        if (signingTime == null) {
            isTimeBad = true;
        } else {
            long now = System.currentTimeMillis();
            long diff = now - signingTime.getTime();
            if (diff < 0) {
                diff = -1 * diff;
            }
            isTimeBad = diff > maxSigningTimeBiasInMs;
        }
        if (isTimeBad) {
            return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badTime);
        }
    }
    // check the digest algorithm
    String oid = req.getDigestAlgorithm().getId();
    ScepHashAlgo hashAlgo = ScepHashAlgo.forNameOrOid(oid);
    if (hashAlgo == null) {
        LOG.warn("tid={}: unknown digest algorithm {}", tid, oid);
        return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badAlg);
    }
    // end if
    boolean supported = false;
    if (hashAlgo == ScepHashAlgo.SHA1) {
        if (caCaps.containsCapability(CaCapability.SHA1)) {
            supported = true;
        }
    } else if (hashAlgo == ScepHashAlgo.SHA256) {
        if (caCaps.containsCapability(CaCapability.SHA256)) {
            supported = true;
        }
    } else if (hashAlgo == ScepHashAlgo.SHA512) {
        if (caCaps.containsCapability(CaCapability.SHA512)) {
            supported = true;
        }
    } else if (hashAlgo == ScepHashAlgo.MD5) {
        if (control.isUseInsecureAlg()) {
            supported = true;
        }
    }
    if (!supported) {
        LOG.warn("tid={}: unsupported digest algorithm {}", tid, oid);
        return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badAlg);
    }
    // end if
    // check the content encryption algorithm
    ASN1ObjectIdentifier encOid = req.getContentEncryptionAlgorithm();
    if (CMSAlgorithm.DES_EDE3_CBC.equals(encOid)) {
        if (!caCaps.containsCapability(CaCapability.DES3)) {
            LOG.warn("tid={}: encryption with DES3 algorithm is not permitted", tid, encOid);
            return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badAlg);
        }
    } else if (AES_ENC_ALGS.contains(encOid)) {
        if (!caCaps.containsCapability(CaCapability.AES)) {
            LOG.warn("tid={}: encryption with AES algorithm {} is not permitted", tid, encOid);
            return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badAlg);
        }
    } else if (CMSAlgorithm.DES_CBC.equals(encOid)) {
        if (!control.isUseInsecureAlg()) {
            LOG.warn("tid={}: encryption with DES algorithm {} is not permitted", tid, encOid);
            return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badAlg);
        }
    } else {
        LOG.warn("tid={}: encryption with algorithm {} is not permitted", tid, encOid);
        return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badAlg);
    }
    if (rep.getPkiStatus() == PkiStatus.FAILURE) {
        return rep;
    }
    MessageType messageType = req.getMessageType();
    switch(messageType) {
        case PKCSReq:
            boolean selfSigned = req.getSignatureCert().getIssuerX500Principal().equals(req.getSignatureCert().getIssuerX500Principal());
            CertificationRequest csr = CertificationRequest.getInstance(req.getMessageData());
            if (selfSigned) {
                X500Name name = X500Name.getInstance(req.getSignatureCert().getSubjectX500Principal().getEncoded());
                if (!name.equals(csr.getCertificationRequestInfo().getSubject())) {
                    LOG.warn("tid={}: self-signed cert.subject != CSR.subject", tid);
                    return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badRequest);
                }
            }
            String challengePwd = getChallengePassword(csr.getCertificationRequestInfo());
            if (challengePwd == null || !control.getSecret().equals(challengePwd)) {
                LOG.warn("challengePassword is not trusted");
                return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badRequest);
            }
            Certificate cert;
            try {
                cert = caEmulator.generateCert(csr);
            } catch (Exception ex) {
                throw new CaException("system failure: " + ex.getMessage(), ex);
            }
            if (cert != null && control.isPendingCert()) {
                rep.setPkiStatus(PkiStatus.PENDING);
            } else if (cert != null) {
                ContentInfo messageData = createSignedData(cert);
                rep.setMessageData(messageData);
            } else {
                buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badCertId);
            }
            break;
        case CertPoll:
            IssuerAndSubject is = IssuerAndSubject.getInstance(req.getMessageData());
            cert = caEmulator.pollCert(is.getIssuer(), is.getSubject());
            if (cert != null) {
                rep.setMessageData(createSignedData(cert));
            } else {
                buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badCertId);
            }
            break;
        case GetCert:
            IssuerAndSerialNumber isn = IssuerAndSerialNumber.getInstance(req.getMessageData());
            cert = caEmulator.getCert(isn.getName(), isn.getSerialNumber().getValue());
            if (cert != null) {
                rep.setMessageData(createSignedData(cert));
            } else {
                buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badCertId);
            }
            break;
        case RenewalReq:
            if (!caCaps.containsCapability(CaCapability.Renewal)) {
                buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badRequest);
            } else {
                csr = CertificationRequest.getInstance(req.getMessageData());
                try {
                    cert = caEmulator.generateCert(csr);
                } catch (Exception ex) {
                    throw new CaException("system failure: " + ex.getMessage(), ex);
                }
                if (cert != null) {
                    rep.setMessageData(createSignedData(cert));
                } else {
                    rep.setPkiStatus(PkiStatus.FAILURE);
                    rep.setFailInfo(FailInfo.badCertId);
                }
            }
            break;
        case UpdateReq:
            if (!caCaps.containsCapability(CaCapability.Update)) {
                buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badRequest);
            } else {
                csr = CertificationRequest.getInstance(req.getMessageData());
                try {
                    cert = caEmulator.generateCert(csr);
                } catch (Exception ex) {
                    throw new CaException("system failure: " + ex.getMessage(), ex);
                }
                if (cert != null) {
                    rep.setMessageData(createSignedData(cert));
                } else {
                    buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badCertId);
                }
            }
            break;
        case GetCRL:
            isn = IssuerAndSerialNumber.getInstance(req.getMessageData());
            CertificateList crl;
            try {
                crl = caEmulator.getCrl(isn.getName(), isn.getSerialNumber().getValue());
            } catch (Exception ex) {
                throw new CaException("system failure: " + ex.getMessage(), ex);
            }
            if (crl != null) {
                rep.setMessageData(createSignedData(crl));
            } else {
                buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badCertId);
            }
            break;
        default:
            buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badRequest);
    }
    return rep;
}
Also used : IssuerAndSerialNumber(org.bouncycastle.asn1.cms.IssuerAndSerialNumber) ScepHashAlgo(org.xipki.scep.crypto.ScepHashAlgo) CertificateList(org.bouncycastle.asn1.x509.CertificateList) ASN1String(org.bouncycastle.asn1.ASN1String) X500Name(org.bouncycastle.asn1.x500.X500Name) Date(java.util.Date) CMSException(org.bouncycastle.cms.CMSException) MessageDecodingException(org.xipki.scep.exception.MessageDecodingException) CertificateException(java.security.cert.CertificateException) IssuerAndSubject(org.xipki.scep.message.IssuerAndSubject) TransactionId(org.xipki.scep.transaction.TransactionId) DecodedPkiMessage(org.xipki.scep.message.DecodedPkiMessage) PkiMessage(org.xipki.scep.message.PkiMessage) ContentInfo(org.bouncycastle.asn1.cms.ContentInfo) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier) MessageType(org.xipki.scep.transaction.MessageType) CertificationRequest(org.bouncycastle.asn1.pkcs.CertificationRequest) X509Certificate(java.security.cert.X509Certificate) Certificate(org.bouncycastle.asn1.x509.Certificate)

Example 2 with MessageDecodingException

use of org.xipki.scep.exception.MessageDecodingException in project xipki by xipki.

the class Client method decode.

private DecodedPkiMessage decode(CMSSignedData pkiMessage, PrivateKey recipientKey, X509Certificate recipientCert) throws ScepClientException {
    DecodedPkiMessage resp;
    try {
        resp = DecodedPkiMessage.decode(pkiMessage, recipientKey, recipientCert, responseSignerCerts);
    } catch (MessageDecodingException ex) {
        throw new ScepClientException(ex);
    }
    if (resp.getFailureMessage() != null) {
        throw new ScepClientException("Error: " + resp.getFailureMessage());
    }
    Boolean bo = resp.isSignatureValid();
    if (bo != null && !bo.booleanValue()) {
        throw new ScepClientException("Signature is invalid");
    }
    bo = resp.isDecryptionSuccessful();
    if (bo != null && !bo.booleanValue()) {
        throw new ScepClientException("Decryption failed");
    }
    Date signingTime = resp.getSigningTime();
    long maxSigningTimeBias = getMaxSigningTimeBiasInMs();
    if (maxSigningTimeBias > 0) {
        if (signingTime == null) {
            throw new ScepClientException("CMS signingTime attribute is not present");
        }
        long now = System.currentTimeMillis();
        long diff = now - signingTime.getTime();
        if (diff < 0) {
            diff = -1 * diff;
        }
        if (diff > maxSigningTimeBias) {
            throw new ScepClientException("CMS signingTime is out of permitted period");
        }
    }
    if (!resp.getSignatureCert().equals(authorityCertStore.getSignatureCert())) {
        throw new ScepClientException("the signature certificate must not be trusted");
    }
    return resp;
}
Also used : MessageDecodingException(org.xipki.scep.exception.MessageDecodingException) ScepClientException(org.xipki.scep.client.exception.ScepClientException) DecodedPkiMessage(org.xipki.scep.message.DecodedPkiMessage) Date(java.util.Date)

Example 3 with MessageDecodingException

use of org.xipki.scep.exception.MessageDecodingException in project xipki by xipki.

the class HttpScepServlet method service0.

private void service0(HttpServletRequest req, HttpServletResponse resp, boolean viaPost) throws ServletException, IOException {
    AuditServiceRegister auditServiceRegister = ServletHelper.getAuditServiceRegister();
    if (auditServiceRegister == null) {
        LOG.error("ServletHelper.auditServiceRegister not configured");
        sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
    }
    ResponderManager responderManager = ServletHelper.getResponderManager();
    if (responderManager == null) {
        LOG.error("ServletHelper.responderManager not configured");
        sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
    }
    String path = StringUtil.getRelativeRequestUri(req.getServletPath(), req.getRequestURI());
    String scepName = null;
    String certProfileName = null;
    if (path.length() > 1) {
        String scepPath = path;
        if (scepPath.endsWith(CGI_PROGRAM)) {
            // skip also the first char (which is always '/')
            String tpath = scepPath.substring(1, scepPath.length() - CGI_PROGRAM_LEN);
            String[] tokens = tpath.split("/");
            if (tokens.length == 2) {
                scepName = tokens[0];
                certProfileName = tokens[1].toLowerCase();
            }
        }
    // end if
    }
    if (scepName == null || certProfileName == null) {
        sendError(resp, HttpServletResponse.SC_NOT_FOUND);
        return;
    }
    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 {
        Scep responder = responderManager.getScep(scepName);
        if (responder == null || !responder.isOnService() || !responder.supportsCertProfile(certProfileName)) {
            auditMessage = "unknown SCEP '" + scepName + "/" + certProfileName + "'";
            LOG.warn(auditMessage);
            auditStatus = AuditStatus.FAILED;
            sendError(resp, HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        String operation = req.getParameter("operation");
        event.addEventData(CaAuditConstants.NAME_SCEP_operation, operation);
        if ("PKIOperation".equalsIgnoreCase(operation)) {
            CMSSignedData reqMessage;
            // parse the request
            try {
                byte[] content;
                if (viaPost) {
                    content = IoUtil.read(req.getInputStream());
                } else {
                    String b64 = req.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;
                sendError(resp, HttpServletResponse.SC_BAD_REQUEST);
                return;
            }
            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;
                sendError(resp, HttpServletResponse.SC_BAD_REQUEST);
                return;
            } catch (OperationException ex) {
                ErrorCode code = ex.getErrorCode();
                int httpCode;
                switch(code) {
                    case ALREADY_ISSUED:
                    case CERT_REVOKED:
                    case CERT_UNREVOKED:
                        httpCode = HttpServletResponse.SC_FORBIDDEN;
                        break;
                    case BAD_CERT_TEMPLATE:
                    case BAD_REQUEST:
                    case BAD_POP:
                    case INVALID_EXTENSION:
                    case UNKNOWN_CERT:
                    case UNKNOWN_CERT_PROFILE:
                        httpCode = HttpServletResponse.SC_BAD_REQUEST;
                        break;
                    case NOT_PERMITTED:
                        httpCode = HttpServletResponse.SC_UNAUTHORIZED;
                        break;
                    case SYSTEM_UNAVAILABLE:
                        httpCode = HttpServletResponse.SC_SERVICE_UNAVAILABLE;
                        break;
                    case CRL_FAILURE:
                    case DATABASE_FAILURE:
                    case SYSTEM_FAILURE:
                        httpCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
                        break;
                    default:
                        httpCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
                        break;
                }
                auditMessage = ex.getMessage();
                LogUtil.error(LOG, ex, auditMessage);
                auditStatus = AuditStatus.FAILED;
                sendError(resp, httpCode);
                return;
            }
            byte[] bodyBytes = ci.getEncoded();
            sendOKResponse(resp, CT_RESPONSE, bodyBytes);
        } else if (Operation.GetCACaps.getCode().equalsIgnoreCase(operation)) {
            // CA-Ident is ignored
            byte[] caCapsBytes = responder.getCaCaps().getBytes();
            sendOKResponse(resp, ScepConstants.CT_TEXT_PLAIN, caCapsBytes);
        } else if (Operation.GetCACert.getCode().equalsIgnoreCase(operation)) {
            // CA-Ident is ignored
            byte[] respBytes = responder.getCaCertResp().getBytes();
            sendOKResponse(resp, ScepConstants.CT_X509_CA_RA_CERT, respBytes);
        } else if (Operation.GetNextCACert.getCode().equalsIgnoreCase(operation)) {
            auditMessage = "SCEP operation '" + operation + "' is not permitted";
            auditStatus = AuditStatus.FAILED;
            sendError(resp, HttpServletResponse.SC_FORBIDDEN);
            return;
        } else {
            auditMessage = "unknown SCEP operation '" + operation + "'";
            auditStatus = AuditStatus.FAILED;
            sendError(resp, HttpServletResponse.SC_BAD_REQUEST);
            return;
        }
    } 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";
        sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    } finally {
        audit(auditService, event, auditLevel, auditStatus, auditMessage);
    }
}
Also used : AuditLevel(org.xipki.audit.AuditLevel) ResponderManager(org.xipki.ca.server.api.ResponderManager) CMSSignedData(org.bouncycastle.cms.CMSSignedData) Date(java.util.Date) ServletException(javax.servlet.ServletException) MessageDecodingException(org.xipki.scep.exception.MessageDecodingException) IOException(java.io.IOException) EOFException(java.io.EOFException) OperationException(org.xipki.ca.api.OperationException) AuditStatus(org.xipki.audit.AuditStatus) MessageDecodingException(org.xipki.scep.exception.MessageDecodingException) ContentInfo(org.bouncycastle.asn1.cms.ContentInfo) EOFException(java.io.EOFException) AuditEvent(org.xipki.audit.AuditEvent) ErrorCode(org.xipki.ca.api.OperationException.ErrorCode) Scep(org.xipki.ca.server.api.Scep) AuditServiceRegister(org.xipki.audit.AuditServiceRegister) AuditService(org.xipki.audit.AuditService) OperationException(org.xipki.ca.api.OperationException)

Example 4 with MessageDecodingException

use of org.xipki.scep.exception.MessageDecodingException 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);
    }
}
Also used : HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) AuditLevel(org.xipki.audit.AuditLevel) CMSSignedData(org.bouncycastle.cms.CMSSignedData) Date(java.util.Date) MessageDecodingException(org.xipki.scep.exception.MessageDecodingException) IOException(java.io.IOException) EOFException(java.io.EOFException) OperationException(org.xipki.ca.api.OperationException) AuditStatus(org.xipki.audit.AuditStatus) MessageDecodingException(org.xipki.scep.exception.MessageDecodingException) ContentInfo(org.bouncycastle.asn1.cms.ContentInfo) EOFException(java.io.EOFException) AuditEvent(org.xipki.audit.AuditEvent) ErrorCode(org.xipki.ca.api.OperationException.ErrorCode) Scep(org.xipki.ca.server.api.Scep) HttpVersion(io.netty.handler.codec.http.HttpVersion) AuditService(org.xipki.audit.AuditService) HttpMethod(io.netty.handler.codec.http.HttpMethod) OperationException(org.xipki.ca.api.OperationException)

Example 5 with MessageDecodingException

use of org.xipki.scep.exception.MessageDecodingException in project xipki by xipki.

the class ScepServlet method service.

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    boolean post;
    String method = req.getMethod();
    if ("GET".equals(method)) {
        post = false;
    } else if ("POST".equals(method)) {
        post = true;
    } else {
        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
        return;
    }
    AuditEvent event = new AuditEvent();
    event.setName(ScepAuditConstants.NAME_PERF);
    event.putEventData(ScepAuditConstants.NAME_servletPath, req.getServletPath());
    AuditLevel auditLevel = AuditLevel.INFO;
    String auditMessage = null;
    try {
        CaCaps caCaps = responder.getCaCaps();
        if (post && !caCaps.containsCapability(CaCapability.POSTPKIOperation)) {
            auditMessage = "HTTP POST is not supported";
            auditLevel = AuditLevel.ERROR;
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }
        String operation = req.getParameter("operation");
        event.putEventData(ScepAuditConstants.NAME_operation, operation);
        if ("PKIOperation".equalsIgnoreCase(operation)) {
            CMSSignedData reqMessage;
            // parse the request
            try {
                byte[] content = post ? ScepUtil.read(req.getInputStream()) : Base64.decode(req.getParameter("message"));
                reqMessage = new CMSSignedData(content);
            } catch (Exception ex) {
                auditMessage = "invalid request";
                auditLevel = AuditLevel.ERROR;
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
                return;
            }
            ContentInfo ci;
            try {
                ci = responder.servicePkiOperation(reqMessage, event);
            } catch (MessageDecodingException ex) {
                auditMessage = "could not decrypt and/or verify the request";
                auditLevel = AuditLevel.ERROR;
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
                return;
            } catch (CaException ex) {
                auditMessage = "system internal error";
                auditLevel = AuditLevel.ERROR;
                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                return;
            }
            byte[] respBytes = ci.getEncoded();
            sendToResponse(resp, CT_RESPONSE, respBytes);
        } else if (Operation.GetCACaps.getCode().equalsIgnoreCase(operation)) {
            // CA-Ident is ignored
            byte[] caCapsBytes = responder.getCaCaps().getBytes();
            sendToResponse(resp, ScepConstants.CT_TEXT_PLAIN, caCapsBytes);
        } else if (Operation.GetCACert.getCode().equalsIgnoreCase(operation)) {
            // CA-Ident is ignored
            byte[] respBytes;
            String ct;
            if (responder.getRaEmulator() == null) {
                ct = ScepConstants.CT_X509_CA_CERT;
                respBytes = responder.getCaEmulator().getCaCertBytes();
            } else {
                ct = ScepConstants.CT_X509_CA_RA_CERT;
                CMSSignedDataGenerator cmsSignedDataGen = new CMSSignedDataGenerator();
                try {
                    cmsSignedDataGen.addCertificate(new X509CertificateHolder(responder.getCaEmulator().getCaCert()));
                    ct = ScepConstants.CT_X509_CA_RA_CERT;
                    cmsSignedDataGen.addCertificate(new X509CertificateHolder(responder.getRaEmulator().getRaCert()));
                    CMSSignedData degenerateSignedData = cmsSignedDataGen.generate(new CMSAbsentContent());
                    respBytes = degenerateSignedData.getEncoded();
                } catch (CMSException ex) {
                    auditMessage = "system internal error";
                    auditLevel = AuditLevel.ERROR;
                    resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    return;
                }
            }
            sendToResponse(resp, ct, respBytes);
        } else if (Operation.GetNextCACert.getCode().equalsIgnoreCase(operation)) {
            if (responder.getNextCaAndRa() == null) {
                auditMessage = "SCEP operation '" + operation + "' is not permitted";
                auditLevel = AuditLevel.ERROR;
                resp.sendError(HttpServletResponse.SC_FORBIDDEN);
                return;
            }
            try {
                NextCaMessage nextCaMsg = new NextCaMessage();
                nextCaMsg.setCaCert(ScepUtil.toX509Cert(responder.getNextCaAndRa().getCaCert()));
                if (responder.getNextCaAndRa().getRaCert() != null) {
                    X509Certificate raCert = ScepUtil.toX509Cert(responder.getNextCaAndRa().getRaCert());
                    nextCaMsg.setRaCerts(Arrays.asList(raCert));
                }
                ContentInfo signedData = responder.encode(nextCaMsg);
                byte[] respBytes = signedData.getEncoded();
                sendToResponse(resp, ScepConstants.CT_X509_NEXT_CA_CERT, respBytes);
            } catch (Exception ex) {
                auditMessage = "system internal error";
                auditLevel = AuditLevel.ERROR;
                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            }
        } else {
            auditMessage = "unknown SCEP operation '" + operation + "'";
            auditLevel = AuditLevel.ERROR;
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
        }
    // end if ("PKIOperation".equalsIgnoreCase(operation))
    } catch (EOFException ex) {
        LOG.warn("connection reset by peer", ex);
        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    } catch (Throwable th) {
        LOG.error("Throwable thrown, this should not happen!", th);
        auditLevel = AuditLevel.ERROR;
        auditMessage = "internal error";
        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    } finally {
        if (event.getLevel() != AuditLevel.ERROR) {
            event.setLevel(auditLevel);
        }
        if (auditMessage != null) {
            event.putEventData("error", auditMessage);
        }
        event.log(LOG);
    }
// end try
}
Also used : CMSSignedDataGenerator(org.bouncycastle.cms.CMSSignedDataGenerator) CMSAbsentContent(org.bouncycastle.cms.CMSAbsentContent) AuditLevel(org.xipki.scep.serveremulator.AuditEvent.AuditLevel) CMSSignedData(org.bouncycastle.cms.CMSSignedData) NextCaMessage(org.xipki.scep.message.NextCaMessage) ServletException(javax.servlet.ServletException) CMSException(org.bouncycastle.cms.CMSException) MessageDecodingException(org.xipki.scep.exception.MessageDecodingException) IOException(java.io.IOException) EOFException(java.io.EOFException) X509Certificate(java.security.cert.X509Certificate) MessageDecodingException(org.xipki.scep.exception.MessageDecodingException) CaCaps(org.xipki.scep.message.CaCaps) ContentInfo(org.bouncycastle.asn1.cms.ContentInfo) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) EOFException(java.io.EOFException) CMSException(org.bouncycastle.cms.CMSException)

Aggregations

MessageDecodingException (org.xipki.scep.exception.MessageDecodingException)10 Date (java.util.Date)7 CMSException (org.bouncycastle.cms.CMSException)7 ContentInfo (org.bouncycastle.asn1.cms.ContentInfo)6 X509Certificate (java.security.cert.X509Certificate)5 CMSSignedData (org.bouncycastle.cms.CMSSignedData)5 CertificateException (java.security.cert.CertificateException)4 EOFException (java.io.EOFException)3 IOException (java.io.IOException)3 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)3 X509CertificateHolder (org.bouncycastle.cert.X509CertificateHolder)3 ServletException (javax.servlet.ServletException)2 ASN1Encodable (org.bouncycastle.asn1.ASN1Encodable)2 ASN1String (org.bouncycastle.asn1.ASN1String)2 AttributeTable (org.bouncycastle.asn1.cms.AttributeTable)2 IssuerAndSerialNumber (org.bouncycastle.asn1.cms.IssuerAndSerialNumber)2 CertificationRequest (org.bouncycastle.asn1.pkcs.CertificationRequest)2 CMSTypedData (org.bouncycastle.cms.CMSTypedData)2 SignerId (org.bouncycastle.cms.SignerId)2 SignerInformation (org.bouncycastle.cms.SignerInformation)2