Example usage for org.bouncycastle.asn1.cmp PKIMessage getEncoded

List of usage examples for org.bouncycastle.asn1.cmp PKIMessage getEncoded

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.cmp PKIMessage getEncoded.

Prototype

public byte[] getEncoded() throws IOException 

Source Link

Document

Return the default BER or DER encoding for this object.

Usage

From source file:org.ejbca.core.protocol.cmp.CmpRaThrowAwayTest.java

License:Open Source License

@Test
public void testLegacyEncodedRequestOverride() throws Exception {
    reconfigureCA(false, false, false);/*ww w .  j  a  v a  2  s. c o m*/
    // Setup "Allow subject DN override" and "Allow certificate serial number override" in used cert profile
    reconfigureCertificateProfile(true, true);
    final String issuerDn = CertTools.getSubjectDN(getTestCACert(TESTCA_NAME));
    final X500Name issuerX500Name = new X500Name(issuerDn);
    final org.bouncycastle.asn1.crmf.CertTemplateBuilder certTemplate = new org.bouncycastle.asn1.crmf.CertTemplateBuilder();
    certTemplate.setIssuer(issuerX500Name);
    final KeyPair keyPair = KeyTools.genKeys("1024", AlgorithmConstants.KEYALGORITHM_RSA);
    final String serialNumber = "88883311121333FF33012345";
    final byte[] transactionId = new byte[16];
    final byte[] senderNonce = new byte[16];
    final Random random = new Random();
    random.nextBytes(transactionId);
    random.nextBytes(senderNonce);
    final String subjectDn = "C=SE,O=PrimeKey,OU=Labs,CN=Sec_" + serialNumber;
    final X500Name subjectX500Name = CertTools.stringToBcX500Name(subjectDn, new TeletexNamingStyle(), false);
    certTemplate.setSubject(subjectX500Name);
    final byte[] bytes = keyPair.getPublic().getEncoded();
    final ByteArrayInputStream bIn = new ByteArrayInputStream(bytes);
    final org.bouncycastle.asn1.ASN1InputStream asn1InputStream = new org.bouncycastle.asn1.ASN1InputStream(
            bIn);
    final org.bouncycastle.asn1.x509.SubjectPublicKeyInfo keyInfo = new org.bouncycastle.asn1.x509.SubjectPublicKeyInfo(
            (org.bouncycastle.asn1.ASN1Sequence) asn1InputStream.readObject());
    asn1InputStream.close();
    certTemplate.setPublicKey(keyInfo);
    // Request a custom certificate serial number
    certTemplate.setSerialNumber(new ASN1Integer(new BigInteger(serialNumber, 16)));
    final org.bouncycastle.asn1.crmf.ProofOfPossession myProofOfPossession = new org.bouncycastle.asn1.crmf.ProofOfPossession();
    final CertRequest certRequest = new CertRequest(4, certTemplate.build(), null);
    final AttributeTypeAndValue[] avs = { new AttributeTypeAndValue(CRMFObjectIdentifiers.id_regCtrl_regToken,
            new DERUTF8String(PBE_SECRET)) };
    final CertReqMsg certReqMsg = new CertReqMsg(certRequest, myProofOfPossession, avs);
    final CertReqMessages certReqMessages = new CertReqMessages(certReqMsg);
    PKIHeaderBuilder pkiHeader = new PKIHeaderBuilder(2, new GeneralName(subjectX500Name),
            new GeneralName(new X500Name(issuerDn)));
    pkiHeader.setMessageTime(new ASN1GeneralizedTime(new Date()));
    pkiHeader.setSenderNonce(new DEROctetString(senderNonce));
    pkiHeader.setTransactionID(new DEROctetString(transactionId));
    pkiHeader.setProtectionAlg(null);
    final DEROctetString senderKID = null;
    pkiHeader.setSenderKID(senderKID);
    final PKIBody pkiBody = new PKIBody(0, certReqMessages);
    final PKIMessage pkiMessage = new PKIMessage(pkiHeader.build(), pkiBody);
    final PKIMessage req = protectPKIMessage(pkiMessage, false, PBE_SECRET, "unusedKeyId", 567);
    assertNotNull("Request was not created properly.", req);
    final CertReqMessages initializationRequest = (CertReqMessages) req.getBody().getContent();
    final int requestId = initializationRequest.toCertReqMsgArray()[0].getCertReq().getCertReqId().getValue()
            .intValue();
    final byte[] reqBytes = req.getEncoded();
    final byte[] cmpResponse = sendCmpHttp(reqBytes, 200, configAlias);
    final X509Certificate cert = checkCmpCertRepMessage(subjectX500Name, this.caCertificate, cmpResponse,
            requestId);
    LOG.debug("Request:\n" + new String(CertTools.getPEMFromCertificateRequest(certRequest.getEncoded())));
    LOG.debug("Result:\n" + new String(
            CertTools.getPemFromCertificateChain(new ArrayList<Certificate>(Arrays.asList(cert)))));
    final byte[] requestSubjectyX500Principal = cert.getSubjectX500Principal().getEncoded();
    final byte[] responeSubjectyX500Principal = subjectX500Name.getEncoded();
    assertTrue("Requested X500Name was not returned the same way as requested.",
            Arrays.equals(requestSubjectyX500Principal, responeSubjectyX500Principal));
    // We cannot assume that the unique serial number index is enabled, and hence we cant be sure that our serial number override was allowed, but at least we can print it
    LOG.info("Requested serial number: " + serialNumber);
    LOG.info("Response serial number:  " + CertTools.getSerialNumberAsString(cert));
}

From source file:org.xipki.ca.client.impl.CAClientImpl.java

License:Open Source License

@Override
public byte[] envelope(final CertRequest certRequest, final ProofOfPossession pop, final String profileName,
        String caName, final String username) throws CAClientException {
    if (caName == null) {
        // detect the CA name
        caName = getCANameForProfile(profileName);
        if (caName == null) {
            throw new CAClientException("cert profile " + profileName + " is not supported by any CA");
        }/*ww w.  j  ava2  s .c  om*/
    } else {
        checkCertprofileSupportInCA(profileName, caName);
    }

    CAConf ca = casMap.get(caName);
    if (ca == null) {
        throw new CAClientException("could not find CA named " + caName);
    }

    PKIMessage pkiMessage;
    try {
        pkiMessage = ca.getRequestor().envelope(certRequest, pop, profileName, username);
    } catch (CmpRequestorException e) {
        throw new CAClientException("CmpRequestorException: " + e.getMessage(), e);
    }

    try {
        return pkiMessage.getEncoded();
    } catch (IOException e) {
        throw new CAClientException("IOException: " + e.getMessage(), e);
    }
}

From source file:org.xipki.ca.client.impl.CAClientImpl.java

License:Open Source License

@Override
public byte[] envelopeRevocation(final X500Name issuer, final BigInteger serial, final int reason)
        throws CAClientException {
    final String id = "cert-1";
    RevokeCertRequestEntryType entry = new RevokeCertRequestEntryType(id, issuer, serial, reason, null);
    RevokeCertRequestType request = new RevokeCertRequestType();
    request.addRequestEntry(entry);//from   w  ww .j a  v a 2  s .c om

    String caName = getCaNameByIssuer(issuer);
    X509CmpRequestor cmpRequestor = casMap.get(caName).getRequestor();

    try {
        PKIMessage pkiMessage = cmpRequestor.envelopeRevocation(request);
        return pkiMessage.getEncoded();
    } catch (CmpRequestorException | IOException e) {
        throw new CAClientException(e.getMessage(), e);
    }
}

From source file:org.xipki.ca.client.impl.CmpRequestor.java

License:Open Source License

protected PKIResponse signAndSend(final PKIMessage request, final RequestResponseDebug debug)
        throws CmpRequestorException {
    PKIMessage _request;
    if (signRequest) {
        _request = sign(request);//  ww w  .j a  v  a2s. c  o m
    } else {
        _request = request;
    }

    if (responderCert == null) {
        throw new CmpRequestorException("CMP responder is not configured");
    }

    byte[] encodedRequest;
    try {
        encodedRequest = _request.getEncoded();
    } catch (IOException e) {
        LOG.error("error while encode the PKI request {}", _request);
        throw new CmpRequestorException(e.getMessage(), e);
    }

    RequestResponsePair reqResp = null;
    if (debug != null) {
        reqResp = new RequestResponsePair();
        debug.add(reqResp);
        reqResp.setRequest(encodedRequest);
    }

    byte[] encodedResponse;
    try {
        encodedResponse = send(encodedRequest);
    } catch (IOException e) {
        LOG.error("error while send the PKI request {} to server", _request);
        throw new CmpRequestorException("TRANSPORT_ERROR", e);
    }

    if (reqResp != null) {
        reqResp.setResponse(encodedResponse);
    }

    GeneralPKIMessage response;
    try {
        response = new GeneralPKIMessage(encodedResponse);
    } catch (IOException e) {
        if (LOG.isErrorEnabled()) {
            LOG.error("error while decode the received PKI message: {}", Hex.toHexString(encodedResponse));
        }
        throw new CmpRequestorException(e.getMessage(), e);
    }

    PKIHeader respHeader = response.getHeader();
    ASN1OctetString tid = respHeader.getTransactionID();
    GeneralName recipient = respHeader.getRecipient();
    if (sender.equals(recipient) == false) {
        LOG.warn("tid={}: unknown CMP requestor '{}'", tid, recipient);
    }

    PKIResponse ret = new PKIResponse(response);
    if (response.hasProtection()) {
        try {
            ProtectionVerificationResult verifyProtection = verifyProtection(Hex.toHexString(tid.getOctets()),
                    response, responderCert);
            ret.setProtectionVerificationResult(verifyProtection);
        } catch (InvalidKeyException | OperatorCreationException | CMPException e) {
            throw new CmpRequestorException(e.getMessage(), e);
        }
    } else if (signRequest) {
        PKIBody respBody = response.getBody();
        int bodyType = respBody.getType();
        if (bodyType != PKIBody.TYPE_ERROR) {
            throw new CmpRequestorException("response is not signed");
        }
    }

    return ret;
}

From source file:org.xipki.commons.security.pkcs11.proxy.ProxyP11Module.java

License:Open Source License

ASN1Encodable send(final int action, final ASN1Encodable content) throws P11TokenException {
    ASN1EncodableVector vec = new ASN1EncodableVector();
    vec.add(new ASN1Integer(version));
    vec.add(new ASN1Integer(action));
    vec.add((content != null) ? content : DERNull.INSTANCE);
    InfoTypeAndValue itvReq = new InfoTypeAndValue(ObjectIdentifiers.id_xipki_cmp_cmpGenmsg,
            new DERSequence(vec));

    GenMsgContent genMsgContent = new GenMsgContent(itvReq);
    PKIHeader header = buildPkiHeader(null);
    PKIBody body = new PKIBody(PKIBody.TYPE_GEN_MSG, genMsgContent);
    PKIMessage request = new PKIMessage(header, body);

    byte[] encodedRequest;
    try {//from   w ww  . j av a 2  s. com
        encodedRequest = request.getEncoded();
    } catch (IOException ex) {
        final String msg = "could not encode the PKI request";
        LOG.error(msg + " {}", request);
        throw new P11TokenException(msg + ": " + ex.getMessage(), ex);
    }

    byte[] encodedResponse;
    try {
        encodedResponse = send(encodedRequest);
    } catch (IOException ex) {
        final String msg = "could not send the PKI request";
        LOG.error(msg + " {}", request);
        throw new P11TokenException(msg + ": " + ex.getMessage(), ex);
    }

    GeneralPKIMessage response;
    try {
        response = new GeneralPKIMessage(encodedResponse);
    } catch (IOException ex) {
        final String msg = "could not decode the received PKI message";
        LOG.error(msg + ": {}", Hex.toHexString(encodedResponse));
        throw new P11TokenException(msg + ": " + ex.getMessage(), ex);
    }

    PKIHeader respHeader = response.getHeader();
    ASN1OctetString tid = respHeader.getTransactionID();
    GeneralName rec = respHeader.getRecipient();
    if (!sender.equals(rec)) {
        LOG.warn("tid={}: unknown CMP requestor '{}'", tid, rec);
    }

    return extractItvInfoValue(action, response);
}

From source file:org.xipki.pki.ca.client.impl.CaClientImpl.java

License:Open Source License

@Override
public byte[] envelope(final CertRequest certRequest, final ProofOfPossession pop, final String profileName,
        final String caName, final String username) throws CaClientException {
    ParamUtil.requireNonNull("certRequest", certRequest);
    ParamUtil.requireNonNull("pop", pop);
    ParamUtil.requireNonNull("profileName", profileName);

    doInit(false);//www. j  a  v  a 2  s.  c o m
    String tmpCaName = caName;
    if (tmpCaName == null) {
        // detect the CA name
        tmpCaName = getCaNameForProfile(profileName);
        if (tmpCaName == null) {
            throw new CaClientException("certprofile " + profileName + " is not supported by any CA");
        }
    } else {
        checkCertprofileSupportInCa(profileName, tmpCaName);
    }

    CaConf ca = casMap.get(tmpCaName.trim());
    if (ca == null) {
        throw new CaClientException("could not find CA named " + tmpCaName);
    }

    PKIMessage pkiMessage;
    try {
        pkiMessage = ca.getRequestor().envelope(certRequest, pop, profileName, username);
    } catch (CmpRequestorException ex) {
        throw new CaClientException("CmpRequestorException: " + ex.getMessage(), ex);
    }

    try {
        return pkiMessage.getEncoded();
    } catch (IOException ex) {
        throw new CaClientException("IOException: " + ex.getMessage(), ex);
    }
}

From source file:org.xipki.pki.ca.client.impl.CaClientImpl.java

License:Open Source License

@Override
public byte[] envelopeRevocation(final X500Name issuer, final BigInteger serial, final int reason)
        throws CaClientException {
    ParamUtil.requireNonNull("issuer", issuer);

    doInit(false);/*w ww .ja v a2s.c  om*/
    final String id = "cert-1";
    RevokeCertRequestEntry entry = new RevokeCertRequestEntry(id, issuer, serial, reason, null);
    RevokeCertRequest request = new RevokeCertRequest();
    request.addRequestEntry(entry);

    String caName = getCaNameByIssuer(issuer);
    X509CmpRequestor cmpRequestor = casMap.get(caName).getRequestor();

    try {
        PKIMessage pkiMessage = cmpRequestor.envelopeRevocation(request);
        return pkiMessage.getEncoded();
    } catch (CmpRequestorException | IOException ex) {
        throw new CaClientException(ex.getMessage(), ex);
    }
}

From source file:org.xipki.pki.ca.client.impl.CmpRequestor.java

License:Open Source License

protected PkiResponse signAndSend(final PKIMessage request, final RequestResponseDebug debug)
        throws CmpRequestorException {
    ParamUtil.requireNonNull("request", request);

    PKIMessage tmpRequest = (signRequest) ? sign(request) : request;

    byte[] encodedRequest;
    try {//  w w w .j a v  a2s.co  m
        encodedRequest = tmpRequest.getEncoded();
    } catch (IOException ex) {
        LOG.error("could not encode the PKI request {}", tmpRequest);
        throw new CmpRequestorException(ex.getMessage(), ex);
    }

    RequestResponsePair reqResp = null;
    if (debug != null) {
        reqResp = new RequestResponsePair();
        debug.add(reqResp);
        reqResp.setRequest(encodedRequest);
    }

    byte[] encodedResponse;
    try {
        encodedResponse = send(encodedRequest);
    } catch (IOException ex) {
        LOG.error("could not send the PKI request {} to server", tmpRequest);
        throw new CmpRequestorException("TRANSPORT_ERROR", ex);
    }

    if (reqResp != null) {
        reqResp.setResponse(encodedResponse);
    }

    GeneralPKIMessage response;
    try {
        response = new GeneralPKIMessage(encodedResponse);
    } catch (IOException ex) {
        LOG.error("could not decode the received PKI message: {}", Hex.toHexString(encodedResponse));
        throw new CmpRequestorException(ex.getMessage(), ex);
    }

    PKIHeader respHeader = response.getHeader();
    ASN1OctetString tid = respHeader.getTransactionID();
    GeneralName rec = respHeader.getRecipient();
    if (!sender.equals(rec)) {
        LOG.warn("tid={}: unknown CMP requestor '{}'", tid, rec);
    }

    PkiResponse ret = new PkiResponse(response);
    if (response.hasProtection()) {
        try {
            ProtectionVerificationResult verifyProtection = verifyProtection(Hex.toHexString(tid.getOctets()),
                    response);
            ret.setProtectionVerificationResult(verifyProtection);
        } catch (InvalidKeyException | OperatorCreationException | CMPException ex) {
            throw new CmpRequestorException(ex.getMessage(), ex);
        }
    } else if (signRequest) {
        PKIBody respBody = response.getBody();
        int bodyType = respBody.getType();
        if (bodyType != PKIBody.TYPE_ERROR) {
            throw new CmpRequestorException("response is not signed");
        }
    }

    return ret;
}

From source file:org.xipki.pki.ca.server.impl.cmp.X509CaCmpResponder.java

License:Open Source License

private List<CertResponse> generateCertificates(final List<CertTemplateData> certTemplates,
        final List<ASN1Integer> certReqIds, final CmpRequestorInfo requestor, final String user,
        final ASN1OctetString tid, final boolean keyUpdate, final PKIMessage request, CmpControl cmpControl,
        final String msgId, final AuditEvent event) {
    X509Ca ca = getCa();/*w w  w  . j  a  v a2s.co  m*/

    final int n = certTemplates.size();
    List<CertResponse> ret = new ArrayList<>(n);

    if (cmpControl.isGroupEnroll()) {
        try {
            List<X509CertificateInfo> certInfos;
            if (keyUpdate) {
                certInfos = ca.regenerateCertificates(certTemplates, requestor.isRa(), requestor, user,
                        RequestType.CMP, tid.getOctets(), msgId);
            } else {
                certInfos = ca.generateCertificates(certTemplates, requestor.isRa(), requestor, user,
                        RequestType.CMP, tid.getOctets(), msgId);
            }

            // save the request
            Long reqDbId = null;
            if (ca.getCaInfo().isSaveRequest()) {
                try {
                    byte[] encodedRequest = request.getEncoded();
                    reqDbId = ca.addRequest(encodedRequest);
                } catch (Exception ex) {
                    LOG.warn("could not save request");
                }
            }

            for (int i = 0; i < n; i++) {
                X509CertificateInfo certInfo = certInfos.get(i);
                ret.add(postProcessCertInfo(certReqIds.get(i), certInfo, tid, cmpControl));
                if (reqDbId != null) {
                    ca.addRequestCert(reqDbId, certInfo.getCert().getCertId());
                }
            }
        } catch (OperationException ex) {
            for (int i = 0; i < n; i++) {
                ret.add(postProcessException(certReqIds.get(i), ex));
            }
        }
    } else {
        Long reqDbId = null;
        boolean savingRequestFailed = false;

        for (int i = 0; i < n; i++) {
            CertTemplateData certTemplate = certTemplates.get(i);
            ASN1Integer certReqId = certReqIds.get(i);

            X509CertificateInfo certInfo;
            try {
                if (keyUpdate) {
                    certInfo = ca.regenerateCertificate(certTemplate, requestor.isRa(), requestor, user,
                            RequestType.CMP, tid.getOctets(), msgId);
                } else {
                    certInfo = ca.generateCertificate(certTemplate, requestor.isRa(), requestor, user,
                            RequestType.CMP, tid.getOctets(), msgId);
                }

                if (ca.getCaInfo().isSaveRequest()) {
                    if (reqDbId == null && !savingRequestFailed) {
                        try {
                            byte[] encodedRequest = request.getEncoded();
                            reqDbId = ca.addRequest(encodedRequest);
                        } catch (Exception ex) {
                            savingRequestFailed = true;
                            LOG.warn("could not save request");
                        }
                    }

                    if (reqDbId != null) {
                        ca.addRequestCert(reqDbId, certInfo.getCert().getCertId());
                    }
                }

                ret.add(postProcessCertInfo(certReqId, certInfo, tid, cmpControl));
            } catch (OperationException ex) {
                ret.add(postProcessException(certReqId, ex));
            }
        }
    }

    return ret;
}

From source file:org.xipki.pki.ca.server.impl.cmp.X509CaCmpResponder.java

License:Open Source License

private PKIBody unRevokeRemoveCertificates(final PKIMessage request, final RevReqContent rr,
        final Permission permission, final CmpControl cmpControl, final String msgId) {
    RevDetails[] revContent = rr.toRevDetailsArray();

    RevRepContentBuilder repContentBuilder = new RevRepContentBuilder();
    final int n = revContent.length;
    // test the request
    for (int i = 0; i < n; i++) {
        RevDetails revDetails = revContent[i];

        CertTemplate certDetails = revDetails.getCertDetails();
        X500Name issuer = certDetails.getIssuer();
        ASN1Integer serialNumber = certDetails.getSerialNumber();

        try {/*from   ww  w  .j  a  v a  2s .c o  m*/
            X500Name caSubject = getCa().getCaInfo().getCertificate().getSubjectAsX500Name();

            if (issuer == null) {
                return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                        "issuer is not present");
            }

            if (!issuer.equals(caSubject)) {
                return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                        "issuer does not target at the CA");
            }

            if (serialNumber == null) {
                return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                        "serialNumber is not present");
            }

            if (certDetails.getSigningAlg() != null || certDetails.getValidity() != null
                    || certDetails.getSubject() != null || certDetails.getPublicKey() != null
                    || certDetails.getIssuerUID() != null || certDetails.getSubjectUID() != null) {
                return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                        "only version, issuer and serialNumber in RevDetails.certDetails are "
                                + "allowed, but more is specified");
            }

            if (certDetails.getExtensions() == null) {
                if (cmpControl.isRrAkiRequired()) {
                    return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                            "issuer's AKI not present");
                }
            } else {
                Extensions exts = certDetails.getExtensions();
                ASN1ObjectIdentifier[] oids = exts.getCriticalExtensionOIDs();
                if (oids != null) {
                    for (ASN1ObjectIdentifier oid : oids) {
                        if (!Extension.authorityKeyIdentifier.equals(oid)) {
                            return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                                    "unknown critical extension " + oid.getId());
                        }
                    }
                }

                Extension ext = exts.getExtension(Extension.authorityKeyIdentifier);
                if (ext == null) {
                    return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                            "issuer's AKI not present");
                } else {
                    AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance(ext.getParsedValue());

                    if (aki.getKeyIdentifier() == null) {
                        return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                                "issuer's AKI not present");
                    }

                    boolean issuerMatched = true;

                    byte[] caSki = getCa().getCaInfo().getCertificate().getSubjectKeyIdentifier();
                    if (Arrays.equals(caSki, aki.getKeyIdentifier())) {
                        issuerMatched = false;
                    }

                    if (issuerMatched && aki.getAuthorityCertSerialNumber() != null) {
                        BigInteger caSerial = getCa().getCaInfo().getSerialNumber();
                        if (!caSerial.equals(aki.getAuthorityCertSerialNumber())) {
                            issuerMatched = false;
                        }
                    }

                    if (issuerMatched && aki.getAuthorityCertIssuer() != null) {
                        GeneralName[] names = aki.getAuthorityCertIssuer().getNames();
                        for (GeneralName name : names) {
                            if (name.getTagNo() != GeneralName.directoryName) {
                                issuerMatched = false;
                                break;
                            }

                            if (!caSubject.equals(name.getName())) {
                                issuerMatched = false;
                                break;
                            }
                        }
                    }

                    if (!issuerMatched) {
                        return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                                "issuer does not target at the CA");
                    }
                }
            }
        } catch (IllegalArgumentException ex) {
            return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badRequest,
                    "the request is not invalid");
        }
    } // end for

    byte[] encodedRequest = null;
    if (getCa().getCaInfo().isSaveRequest()) {
        try {
            encodedRequest = request.getEncoded();
        } catch (IOException ex) {
            LOG.warn("could not encode request");
        }
    }

    Long reqDbId = null;

    for (int i = 0; i < n; i++) {
        RevDetails revDetails = revContent[i];

        CertTemplate certDetails = revDetails.getCertDetails();
        ASN1Integer serialNumber = certDetails.getSerialNumber();
        // serialNumber is not null due to the check in the previous for-block.

        X500Name caSubject = getCa().getCaInfo().getCertificate().getSubjectAsX500Name();
        BigInteger snBigInt = serialNumber.getPositiveValue();
        CertId certId = new CertId(new GeneralName(caSubject), serialNumber);

        PKIStatusInfo status;

        try {
            Object returnedObj = null;
            Long certDbId = null;
            X509Ca ca = getCa();
            if (Permission.UNREVOKE_CERT == permission) {
                // unrevoke
                returnedObj = ca.unrevokeCertificate(snBigInt, msgId);
                if (returnedObj != null) {
                    certDbId = ((X509CertWithDbId) returnedObj).getCertId();
                }
            } else if (Permission.REMOVE_CERT == permission) {
                // remove
                returnedObj = ca.removeCertificate(snBigInt, msgId);
            } else {
                // revoke
                Date invalidityDate = null;
                CrlReason reason = null;

                Extensions crlDetails = revDetails.getCrlEntryDetails();
                if (crlDetails != null) {
                    ASN1ObjectIdentifier extId = Extension.reasonCode;
                    ASN1Encodable extValue = crlDetails.getExtensionParsedValue(extId);
                    if (extValue != null) {
                        int reasonCode = ASN1Enumerated.getInstance(extValue).getValue().intValue();
                        reason = CrlReason.forReasonCode(reasonCode);
                    }

                    extId = Extension.invalidityDate;
                    extValue = crlDetails.getExtensionParsedValue(extId);
                    if (extValue != null) {
                        try {
                            invalidityDate = ASN1GeneralizedTime.getInstance(extValue).getDate();
                        } catch (ParseException ex) {
                            throw new OperationException(ErrorCode.INVALID_EXTENSION,
                                    "invalid extension " + extId.getId());
                        }
                    }
                } // end if (crlDetails)

                if (reason == null) {
                    reason = CrlReason.UNSPECIFIED;
                }

                returnedObj = ca.revokeCertificate(snBigInt, reason, invalidityDate, msgId);
                if (returnedObj != null) {
                    certDbId = ((X509CertWithRevocationInfo) returnedObj).getCert().getCertId();
                }
            } // end if (permission)

            if (returnedObj == null) {
                throw new OperationException(ErrorCode.UNKNOWN_CERT, "cert not exists");
            }

            if (certDbId != null && ca.getCaInfo().isSaveRequest()) {
                if (reqDbId == null) {
                    reqDbId = ca.addRequest(encodedRequest);
                }
                ca.addRequestCert(reqDbId, certDbId);
            }
            status = new PKIStatusInfo(PKIStatus.granted);
        } catch (OperationException ex) {
            ErrorCode code = ex.getErrorCode();
            LOG.warn("{} certificate, OperationException: code={}, message={}", permission.name(), code.name(),
                    ex.getErrorMessage());
            String errorMessage;
            switch (code) {
            case DATABASE_FAILURE:
            case SYSTEM_FAILURE:
                errorMessage = code.name();
                break;
            default:
                errorMessage = code.name() + ": " + ex.getErrorMessage();
                break;
            } // end switch code

            int failureInfo = getPKiFailureInfo(ex);
            status = generateRejectionStatus(failureInfo, errorMessage);
        } // end try

        repContentBuilder.add(status, certId);
    } // end for

    return new PKIBody(PKIBody.TYPE_REVOCATION_REP, repContentBuilder.build());
}