Example usage for org.bouncycastle.asn1.crmf CertTemplate getIssuer

List of usage examples for org.bouncycastle.asn1.crmf CertTemplate getIssuer

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.crmf CertTemplate getIssuer.

Prototype

public X500Name getIssuer() 

Source Link

Usage

From source file:org.ejbca.core.protocol.cmp.authentication.HMACAuthenticationModule.java

License:Open Source License

@Override
/*//from   w  ww  .  j  a v  a 2s  .com
 * Verifies that 'msg' is sent by a trusted source. 
 * 
 * In RA mode:
 *      - A globally configured shared secret for all CAs will be used to authenticate the message.
 *      - If the globally shared secret fails, the password set in the CA will be used to authenticate the message.
 *  In client mode, the clear-text password set in the pre-registered end entity in the database will be used to 
 *  authenticate the message. 
 * 
 * When successful, the authentication string will be set to the password that was successfully used in authenticating the message.
 */
public boolean verifyOrExtract(final PKIMessage msg, final String username) {

    if (msg == null) {
        this.errorMessage = "No PKIMessage was found";
        return false;
    }

    if ((msg.getProtection() == null) || (msg.getHeader().getProtectionAlg() == null)) {
        this.errorMessage = "PKI Message is not athenticated properly. No HMAC protection was found.";
        return false;
    }

    try {
        verifyer = new CmpPbeVerifyer(msg);
    } catch (Exception e) {
        this.errorMessage = "Could not create CmpPbeVerifyer. " + e.getMessage();
        return false;
    }

    if (verifyer == null) {
        this.errorMessage = "Could not create CmpPbeVerifyer Object";
        return false;
    }

    if (this.cmpConfiguration.getRAMode(this.confAlias)) { //RA mode
        if (LOG.isDebugEnabled()) {
            LOG.debug("Verifying HMAC in RA mode");
        }

        // Check that the value of KeyId from the request is allowed 
        // Note that this restriction only applies to HMAC and not EndEntityCertificate because in the later, the use of profiles can be restricted through 
        // Administrator privileges. Other authentication modules are not used in RA mode
        if (StringUtils.equals(cmpConfiguration.getRAEEProfile(confAlias), "KeyId")
                || StringUtils.equals(cmpConfiguration.getRACertProfile(confAlias), "KeyId")) {
            final String keyId = CmpMessageHelper.getStringFromOctets(msg.getHeader().getSenderKID());
            if (StringUtils.equals(keyId, "EMPTY") || StringUtils.equals(keyId, "ENDUSER")) {
                errorMessage = "Unaccepted KeyId '" + keyId + "' in CMP request";
                LOG.info(errorMessage);
                return false;
            }
        }

        // If we use a globally configured shared secret for all CAs we check it right away
        String authSecret = globalSharedSecret;

        if (globalSharedSecret != null) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Verifying message using Global Shared secret");
            }
            try {
                if (verifyer.verify(authSecret)) {
                    this.password = authSecret;
                } else {
                    String errmsg = INTRES.getLocalizedMessage("cmp.errorauthmessage", "Global auth secret");
                    LOG.info(errmsg); // info because this is something we should expect and we handle it
                    if (verifyer.getErrMsg() != null) {
                        errmsg = verifyer.getErrMsg();
                        LOG.info(errmsg);
                    }
                }
            } catch (InvalidKeyException e) {
                this.errorMessage = e.getLocalizedMessage();
                if (LOG.isDebugEnabled()) {
                    LOG.debug(this.errorMessage, e);
                }
                return false;
            } catch (NoSuchAlgorithmException e) {
                this.errorMessage = e.getLocalizedMessage();
                if (LOG.isDebugEnabled()) {
                    LOG.debug(this.errorMessage, e);
                }
                return false;
            } catch (NoSuchProviderException e) {
                this.errorMessage = e.getLocalizedMessage();
                if (LOG.isDebugEnabled()) {
                    LOG.debug(this.errorMessage, e);
                }
                return false;
            }
        }

        // If password is null, then we failed verification using global shared secret
        if (this.password == null) {

            if (cainfo instanceof X509CAInfo) {
                authSecret = ((X509CAInfo) cainfo).getCmpRaAuthSecret();

                if (StringUtils.isNotEmpty(authSecret)) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Verify message using 'CMP RA Authentication Secret' from CA '"
                                + cainfo.getName() + "'.");
                    }
                    try {
                        if (verifyer.verify(authSecret)) {
                            this.password = authSecret;
                        } else {
                            // info because this is something we should expect and we handle it
                            LOG.info(INTRES.getLocalizedMessage("cmp.errorauthmessage",
                                    "Auth secret for CA=" + cainfo.getName()));
                            if (verifyer.getErrMsg() != null) {
                                LOG.info(verifyer.getErrMsg());
                            }
                        }
                    } catch (InvalidKeyException e) {
                        this.errorMessage = INTRES.getLocalizedMessage("cmp.errorgeneral");
                        LOG.error(this.errorMessage, e);
                        return false;
                    } catch (NoSuchAlgorithmException e) {
                        this.errorMessage = INTRES.getLocalizedMessage("cmp.errorgeneral");
                        LOG.error(this.errorMessage, e);
                        return false;
                    } catch (NoSuchProviderException e) {
                        this.errorMessage = INTRES.getLocalizedMessage("cmp.errorgeneral");
                        LOG.error(this.errorMessage, e);
                        return false;
                    }
                } else {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("CMP password is null from CA '" + cainfo.getName() + "'.");
                    }
                }
            }
        }

        // If password is still null, then we have failed verification with CA authentication secret too.
        if (password == null) {
            this.errorMessage = "Failed to verify message using both Global Shared Secret and CMP RA Authentication Secret";
            return false;
        }

    } else { //client mode
        if (LOG.isDebugEnabled()) {
            LOG.debug("Verifying HMAC in Client mode");
        }
        //If client mode, we try to get the pre-registered endentity from the DB, and if there is a 
        //clear text password we check HMAC using this password.
        EndEntityInformation userdata = null;
        String subjectDN = null;

        try {
            if (username != null) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Searching for an end entity with username='" + username + "'.");
                }
                userdata = this.eeAccessSession.findUser(admin, username);
            } else {
                // No username given, so we try to find from subject/issuerDN from the certificate request
                final CertTemplate certTemp = getCertTemplate(msg);
                subjectDN = certTemp.getSubject().toString();

                String issuerDN = null;
                final X500Name issuer = certTemp.getIssuer();
                if ((issuer != null) && (subjectDN != null)) {
                    issuerDN = issuer.toString();
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Searching for an end entity with SubjectDN='" + subjectDN + "' and isserDN='"
                                + issuerDN + "'");
                    }

                    List<EndEntityInformation> userdataList = eeAccessSession
                            .findUserBySubjectAndIssuerDN(this.admin, subjectDN, issuerDN);
                    userdata = userdataList.get(0);
                    if (userdataList.size() > 1) {
                        LOG.warn("Multiple end entities with subject DN " + subjectDN + " and issuer DN"
                                + issuerDN + " were found. This may lead to unexpected behavior.");
                    }
                } else if (subjectDN != null) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Searching for an end entity with SubjectDN='" + subjectDN + "'.");
                    }
                    List<EndEntityInformation> userdataList = this.eeAccessSession.findUserBySubjectDN(admin,
                            subjectDN);
                    if (userdataList.size() > 0) {
                        userdata = userdataList.get(0);
                    }
                    if (userdataList.size() > 1) {
                        LOG.warn("Multiple end entities with subject DN " + subjectDN
                                + " were found. This may lead to unexpected behavior.");
                    }
                }
            }
        } catch (AuthorizationDeniedException e) {
            LOG.info("No EndEntity with subjectDN '" + subjectDN + "' could be found. "
                    + e.getLocalizedMessage());
        }

        if (userdata != null) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Comparing HMAC password authentication for user '" + userdata.getUsername() + "'.");
            }

            final String eepassword = userdata.getPassword();
            if (StringUtils.isNotEmpty(eepassword)) {
                try {
                    if (verifyer.verify(eepassword)) {
                        this.password = eepassword;
                    } else {
                        String errmsg = INTRES.getLocalizedMessage("cmp.errorauthmessage",
                                userdata.getUsername());
                        LOG.info(errmsg); // info because this is something we should expect and we handle it
                        if (verifyer.getErrMsg() != null) {
                            errmsg = verifyer.getErrMsg();
                            LOG.info(errmsg);
                        }
                        this.errorMessage = errmsg;
                        return false;
                    }
                } catch (InvalidKeyException e) {
                    this.errorMessage = INTRES.getLocalizedMessage("cmp.errorgeneral");
                    LOG.error(this.errorMessage, e);
                    return false;
                } catch (NoSuchAlgorithmException e) {
                    this.errorMessage = INTRES.getLocalizedMessage("cmp.errorgeneral");
                    LOG.error(this.errorMessage, e);
                    return false;
                } catch (NoSuchProviderException e) {
                    this.errorMessage = INTRES.getLocalizedMessage("cmp.errorgeneral");
                    LOG.error(this.errorMessage, e);
                    return false;
                }
            } else {
                this.errorMessage = "No clear text password for user '" + userdata.getUsername()
                        + "', not possible to check authentication.";
                return false;
            }
        } else {
            LOG.info(INTRES.getLocalizedMessage("ra.errorentitynotexist",
                    StringUtils.isNotEmpty(username) ? username : subjectDN));
            this.errorMessage = INTRES.getLocalizedMessage("ra.wrongusernameorpassword");
            return false;
        }
    }

    return this.password != null;
}

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

License:Open Source License

@Override
public String getIssuerDN() {
    String ret = null;//  w w w  . jav  a 2s . c  o m
    final CertTemplate templ = getReq().getCertReq().getCertTemplate();
    final X500Name name = templ.getIssuer();
    if (name != null) {
        ret = CertTools.stringToBCDNString(name.toString());
    } else {
        ret = defaultCADN;
    }
    if (log.isDebugEnabled()) {
        log.debug("Issuer DN is: " + ret);
    }
    return ret;
}

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

License:Open Source License

public GeneralCmpMessage(final PKIMessage msg) {
    final PKIBody body = msg.getBody();
    final int tag = body.getType();
    if (tag == 19) {
        // this is a PKIConfirmContent
        if (log.isDebugEnabled()) {
            log.debug("Received a PKIConfirm message");
        }/*from ww  w  .j av  a2  s. c o m*/
        // This is a null message, so there is nothing to get here
        //DERNull obj = body.getConf();
    }
    if (tag == 24) {
        // this is a CertConfirmContent
        if (log.isDebugEnabled()) {
            log.debug("Received a Cert Confirm message");
        }
        final CertConfirmContent obj = (CertConfirmContent) body.getContent();
        CertStatus cs;
        try {
            cs = CertStatus.getInstance(obj.toASN1Primitive());
        } catch (Exception e) {
            cs = CertStatus.getInstance(((DERSequence) obj.toASN1Primitive()).getObjectAt(0));
        }
        final PKIStatusInfo status = cs.getStatusInfo();
        if (status != null) {
            final int st = status.getStatus().intValue();
            if (st != 0) {
                final String errMsg = intres.getLocalizedMessage("cmp.errorcertconfirmstatus",
                        Integer.valueOf(st));
                log.error(errMsg);
                // TODO: if it is rejected, we should revoke the cert?
            }
        }
    }
    if (tag == 11) {
        // this is a RevReqContent,
        if (log.isDebugEnabled()) {
            log.debug("Received a RevReqContent");
        }
        final RevReqContent rr = (RevReqContent) body.getContent();
        RevDetails rd;
        try {
            rd = rr.toRevDetailsArray()[0];
        } catch (Exception e) {
            log.debug(
                    "Could not parse the revocation request. Trying to parse it as novosec generated message.");
            rd = CmpMessageHelper.getNovosecRevDetails(rr);
            log.debug("Succeeded in parsing the novosec generated request.");
        }
        final CertTemplate ct = rd.getCertDetails();
        final ASN1Integer serno = ct.getSerialNumber();
        final X500Name issuer = ct.getIssuer();
        if ((serno != null) && (issuer != null)) {
            final String errMsg = intres.getLocalizedMessage("cmp.receivedrevreq", issuer.toString(),
                    serno.getValue().toString(16));
            log.info(errMsg);
        } else {
            final String errMsg = intres.getLocalizedMessage("cmp.receivedrevreqnoissuer");
            log.info(errMsg);
        }
    }
    setMessage(msg);
    final PKIHeader header = msg.getHeader();
    if (header.getTransactionID() != null) {
        final byte[] val = header.getTransactionID().getOctets();
        if (val != null) {
            setTransactionId(new String(Base64.encode(val)));
        }
    }
    if (header.getSenderNonce() != null) {
        final byte[] val = header.getSenderNonce().getOctets();
        if (val != null) {
            setSenderNonce(new String(Base64.encode(val)));
        }
    }
    setRecipient(header.getRecipient());
    setSender(header.getSender());
}

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

License:Open Source License

public ResponseMessage handleMessage(final BaseCmpMessage msg, boolean authenticated) {
    if (LOG.isTraceEnabled()) {
        LOG.trace(">handleMessage");
    }//w  w w. j av  a  2  s .  c  om

    CA ca = null;
    try {
        final String caDN = msg.getHeader().getRecipient().getName().toString();
        final int caId = CertTools.stringToBCDNString(caDN).hashCode();
        if (LOG.isDebugEnabled()) {
            LOG.debug("CA DN is '" + caDN + "' and resulting caId is " + caId
                    + ", after CertTools.stringToBCDNString conversion.");
        }
        ca = caSession.getCA(admin, caId);
    } catch (CADoesntExistsException e) {
        final String errMsg = "CA with DN '" + msg.getHeader().getRecipient().getName().toString()
                + "' is unknown";
        LOG.info(errMsg);
        return CmpMessageHelper.createUnprotectedErrorMessage(msg, ResponseStatus.FAILURE, FailInfo.BAD_REQUEST,
                errMsg);
    } catch (AuthorizationDeniedException e) {
        LOG.info(INTRES.getLocalizedMessage(CMP_ERRORGENERAL, e.getMessage()), e);
        return CmpMessageHelper.createUnprotectedErrorMessage(msg, ResponseStatus.FAILURE,
                FailInfo.INCORRECT_DATA, e.getMessage());
    }

    ResponseMessage resp = null;
    // if version == 1 it is cmp1999 and we should not return a message back
    // Try to find a HMAC/SHA1 protection key
    final String keyId = CmpMessageHelper.getStringFromOctets(msg.getHeader().getSenderKID());
    ResponseStatus status = ResponseStatus.FAILURE;
    FailInfo failInfo = FailInfo.BAD_MESSAGE_CHECK;
    String failText = null;

    //Verify the authenticity of the message
    final VerifyPKIMessage messageVerifyer = new VerifyPKIMessage(ca.getCAInfo(), this.confAlias, admin,
            caSession, endEntityAccessSession, certificateStoreSession, authorizationSession,
            endEntityProfileSession, authenticationProviderSession, endEntityManagementSession,
            this.cmpConfiguration);
    ICMPAuthenticationModule authenticationModule = messageVerifyer
            .getUsedAuthenticationModule(msg.getMessage(), null, authenticated);
    if (authenticationModule == null) {
        LOG.info(messageVerifyer.getErrorMessage());
        return CmpMessageHelper.createUnprotectedErrorMessage(msg, ResponseStatus.FAILURE,
                FailInfo.BAD_MESSAGE_CHECK, messageVerifyer.getErrorMessage());
    }

    // If authentication was correct, we will now try to find the certificate to revoke
    final PKIMessage pkimsg = msg.getMessage();
    final PKIBody body = pkimsg.getBody();
    final RevReqContent rr = (RevReqContent) body.getContent();
    RevDetails rd;
    try {
        rd = rr.toRevDetailsArray()[0];
    } catch (Exception e) {
        LOG.debug("Could not parse the revocation request. Trying to parse it as novosec generated message.");
        rd = CmpMessageHelper.getNovosecRevDetails(rr);
        LOG.debug("Succeeded in parsing the novosec generated request.");
    }
    final CertTemplate ct = rd.getCertDetails();
    final ASN1Integer serno = ct.getSerialNumber();
    final X500Name issuer = ct.getIssuer();
    // Get the revocation reason. 
    // For CMPv1 this can be a simple DERBitString or it can be a requested CRL Entry Extension
    // If there exists CRL Entry Extensions we will use that, because it's the only thing allowed in CMPv2
    int reason = RevokedCertInfo.REVOCATION_REASON_UNSPECIFIED;
    final ASN1OctetString reasonoctets = rd.getCrlEntryDetails().getExtension(Extension.reasonCode)
            .getExtnValue();
    DERBitString reasonbits;
    try {
        reasonbits = new DERBitString(reasonoctets.getEncoded());
    } catch (IOException e1) {
        LOG.info(INTRES.getLocalizedMessage(CMP_ERRORGENERAL, e1.getMessage()), e1);
        return CmpMessageHelper.createUnprotectedErrorMessage(msg, ResponseStatus.FAILURE,
                FailInfo.INCORRECT_DATA, e1.getMessage());
    }
    if (reasonbits != null) {
        reason = CertTools.bitStringToRevokedCertInfo(reasonbits);
        if (LOG.isDebugEnabled()) {
            LOG.debug("CMPv1 revocation reason: " + reason);
        }
    }
    final Extensions crlExt = rd.getCrlEntryDetails();
    if (crlExt != null) {
        final Extension ext = crlExt.getExtension(Extension.reasonCode);
        if (ext != null) {
            try {
                final ASN1InputStream ai = new ASN1InputStream(ext.getExtnValue().getOctets());
                final ASN1Primitive obj = ai.readObject();
                final ASN1Enumerated crlreason = ASN1Enumerated.getInstance(obj);
                // RevokedCertInfo.REVOCATION_REASON_AACOMPROMISE are the same integer values as the CRL reason extension code
                reason = crlreason.getValue().intValue();
                if (LOG.isDebugEnabled()) {
                    LOG.debug("CRLReason extension: " + reason);
                }
                ai.close();
            } catch (IOException e) {
                LOG.info("Exception parsin CRL reason extension: ", e);
            }
        } else {
            if (LOG.isDebugEnabled()) {
                LOG.debug("No CRL reason code extension present.");
            }
        }
    } else {
        if (LOG.isDebugEnabled()) {
            LOG.debug("No CRL entry extensions present");
        }
    }

    if ((serno != null) && (issuer != null)) {
        final String iMsg = INTRES.getLocalizedMessage("cmp.receivedrevreq", issuer.toString(),
                serno.getValue().toString(16));
        LOG.info(iMsg);
        try {
            endEntityManagementSession.revokeCert(admin, serno.getValue(), issuer.toString(), reason);
            status = ResponseStatus.SUCCESS;
        } catch (AuthorizationDeniedException e) {
            failInfo = FailInfo.NOT_AUTHORIZED;
            final String errMsg = INTRES.getLocalizedMessage("cmp.errornotauthrevoke", issuer.toString(),
                    serno.getValue().toString(16));
            failText = errMsg;
            LOG.info(failText);
        } catch (FinderException e) {
            failInfo = FailInfo.BAD_CERTIFICATE_ID;
            final String errMsg = INTRES.getLocalizedMessage("cmp.errorcertnofound", issuer.toString(),
                    serno.getValue().toString(16));
            failText = errMsg;
            // This is already info logged in endEntityManagementSession.revokeCert
            // LOG.info(failText);
        } catch (WaitingForApprovalException e) {
            status = ResponseStatus.GRANTED_WITH_MODS;
        } catch (ApprovalException e) {
            failInfo = FailInfo.BAD_REQUEST;
            final String errMsg = INTRES.getLocalizedMessage("cmp.erroralreadyrequested");
            failText = errMsg;
            LOG.info(failText);
        } catch (AlreadyRevokedException e) {
            failInfo = FailInfo.BAD_REQUEST;
            final String errMsg = INTRES.getLocalizedMessage("cmp.erroralreadyrevoked");
            failText = errMsg;
            // This is already info logged in endEntityManagementSession.revokeCert
            // LOG.info(failText);
        }
    } else {
        failInfo = FailInfo.BAD_CERTIFICATE_ID;
        final String errMsg = INTRES.getLocalizedMessage("cmp.errormissingissuerrevoke", issuer.toString(),
                serno.getValue().toString(16));
        failText = errMsg;
        LOG.info(failText);
    }

    if (LOG.isDebugEnabled()) {
        LOG.debug("Creating a PKI revocation message response");
    }
    final CmpRevokeResponseMessage rresp = new CmpRevokeResponseMessage();
    rresp.setRecipientNonce(msg.getSenderNonce());
    rresp.setSenderNonce(new String(Base64.encode(CmpMessageHelper.createSenderNonce())));
    rresp.setSender(msg.getRecipient());
    rresp.setRecipient(msg.getSender());
    rresp.setTransactionId(msg.getTransactionId());
    rresp.setFailInfo(failInfo);
    rresp.setFailText(failText);
    rresp.setStatus(status);

    if (StringUtils.equals(responseProtection, "pbe")) {
        final HMACAuthenticationModule hmacmodule = (HMACAuthenticationModule) authenticationModule;
        final String owfAlg = hmacmodule.getCmpPbeVerifyer().getOwfOid();
        final String macAlg = hmacmodule.getCmpPbeVerifyer().getMacOid();
        final int iterationCount = 1024;
        final String cmpRaAuthSecret = hmacmodule.getAuthenticationString();

        if ((owfAlg != null) && (macAlg != null) && (keyId != null) && (cmpRaAuthSecret != null)) {
            // Set all protection parameters
            if (LOG.isDebugEnabled()) {
                LOG.debug(responseProtection + ", " + owfAlg + ", " + macAlg + ", " + keyId + ", "
                        + cmpRaAuthSecret);
            }
            rresp.setPbeParameters(keyId, cmpRaAuthSecret, owfAlg, macAlg, iterationCount);
        }
    } else if (StringUtils.equals(responseProtection, "signature")) {
        try {
            final CryptoToken cryptoToken = cryptoTokenSession
                    .getCryptoToken(ca.getCAToken().getCryptoTokenId());
            final String aliasCertSign = ca.getCAToken()
                    .getAliasFromPurpose(CATokenConstants.CAKEYPURPOSE_CERTSIGN);
            rresp.setSignKeyInfo(ca.getCertificateChain(), cryptoToken.getPrivateKey(aliasCertSign),
                    cryptoToken.getSignProviderName());
            if (msg.getHeader().getProtectionAlg() != null) {
                rresp.setPreferredDigestAlg(AlgorithmTools
                        .getDigestFromSigAlg(msg.getHeader().getProtectionAlg().getAlgorithm().getId()));
            }
        } catch (CryptoTokenOfflineException e) {
            LOG.error(e.getLocalizedMessage(), e);
        }
    }
    resp = rresp;
    try {
        resp.create();
    } catch (InvalidKeyException e) {
        String errMsg = INTRES.getLocalizedMessage("cmp.errorgeneral");
        LOG.error(errMsg, e);
    } catch (NoSuchAlgorithmException e) {
        String errMsg = INTRES.getLocalizedMessage("cmp.errorgeneral");
        LOG.error(errMsg, e);
    } catch (NoSuchProviderException e) {
        String errMsg = INTRES.getLocalizedMessage("cmp.errorgeneral");
        LOG.error(errMsg, e);
    } catch (CertificateEncodingException e) {
        String errMsg = INTRES.getLocalizedMessage("cmp.errorgeneral");
        LOG.error(errMsg, e);
    } catch (CRLException e) {
        String errMsg = INTRES.getLocalizedMessage("cmp.errorgeneral");
        LOG.error(errMsg, e);
    }

    return resp;
}

From source file:org.xipki.ca.server.impl.X509CACmpResponder.java

License:Open Source License

private PKIBody revokeOrUnrevokeOrRemoveCertificates(final RevReqContent rr, final AuditEvent auditEvent,
        final Permission permission) {
    RevDetails[] revContent = rr.toRevDetailsArray();

    RevRepContentBuilder repContentBuilder = new RevRepContentBuilder();

    final int n = revContent.length;
    // test the reques
    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  w  w w  . java 2  s .  co  m
            X500Name caSubject = getCA().getCAInfo().getCertificate().getSubjectAsX500Name();

            if (issuer == null) {
                return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                        "issuer is not present");
            } else if (issuer.equals(caSubject) == false) {
                return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                        "issuer not targets at the CA");
            } else if (serialNumber == null) {
                return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                        "serialNumber is not present");
            } else if (certDetails.getSigningAlg() != null || certDetails.getValidity() != null
                    || certDetails.getSubject() != null || certDetails.getPublicKey() != null
                    || certDetails.getIssuerUID() != null || certDetails.getSubjectUID() != null
                    || certDetails.getExtensions() != null) {
                return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                        "only version, issuer and serialNumber in RevDetails.certDetails are allowed, "
                                + "but more is specified");
            }
        } catch (IllegalArgumentException e) {
            return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.badRequest,
                    "the request is not invalid");
        }
    }

    for (int i = 0; i < n; i++) {
        AuditChildEvent childAuditEvent = null;
        if (auditEvent != null) {
            childAuditEvent = new AuditChildEvent();
            auditEvent.addChildAuditEvent(childAuditEvent);
        }

        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);

        if (childAuditEvent != null) {
            AuditEventData eventData = new AuditEventData("serialNumber", snBigInt.toString());
            childAuditEvent.addEventData(eventData);
        }

        PKIStatusInfo status;

        try {
            Object returnedObj = null;
            X509CA ca = getCA();
            if (Permission.UNREVOKE_CERT == permission) {
                // unrevoke
                returnedObj = ca.unrevokeCertificate(snBigInt);
            } else if (Permission.REMOVE_CERT == permission) {
                // remove
                returnedObj = ca.removeCertificate(snBigInt);
            } 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) extValue).getValue().intValue();
                        reason = CRLReason.forReasonCode(reasonCode);
                    }

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

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

                if (childAuditEvent != null) {
                    childAuditEvent.addEventData(new AuditEventData("reason", reason.getDescription()));
                    if (invalidityDate != null) {
                        String value;
                        synchronized (dateFormat) {
                            value = dateFormat.format(invalidityDate);
                        }
                        childAuditEvent.addEventData(new AuditEventData("invalidityDate", value));
                    }
                }

                returnedObj = ca.revokeCertificate(snBigInt, reason, invalidityDate);
            } // end if(permission)

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

            status = new PKIStatusInfo(PKIStatus.granted);
            if (childAuditEvent != null) {
                childAuditEvent.setStatus(AuditStatus.SUCCESSFUL);
            }
        } catch (OperationException e) {
            ErrorCode code = e.getErrorCode();
            LOG.warn("{} certificate, OperationException: code={}, message={}",
                    new Object[] { permission.name(), code.name(), e.getErrorMessage() });

            String auditMessage;

            int failureInfo;
            switch (code) {
            case BAD_REQUEST:
                failureInfo = PKIFailureInfo.badRequest;
                auditMessage = "BAD_REQUEST";
                break;
            case CERT_REVOKED:
                failureInfo = PKIFailureInfo.certRevoked;
                auditMessage = "CERT_REVOKED";
                break;
            case CERT_UNREVOKED:
                failureInfo = PKIFailureInfo.notAuthorized;
                auditMessage = "CERT_UNREVOKED";
                break;
            case DATABASE_FAILURE:
                failureInfo = PKIFailureInfo.systemFailure;
                auditMessage = "DATABASE_FAILURE";
                break;
            case INVALID_EXTENSION:
                failureInfo = PKIFailureInfo.unacceptedExtension;
                auditMessage = "INVALID_EXTENSION";
                break;
            case INSUFFICIENT_PERMISSION:
                failureInfo = PKIFailureInfo.notAuthorized;
                auditMessage = "INSUFFICIENT_PERMISSION";
                break;
            case NOT_PERMITTED:
                failureInfo = PKIFailureInfo.notAuthorized;
                auditMessage = "NOT_PERMITTED";
                break;
            case SYSTEM_FAILURE:
                failureInfo = PKIFailureInfo.systemFailure;
                auditMessage = "System_Failure";
                break;
            case SYSTEM_UNAVAILABLE:
                failureInfo = PKIFailureInfo.systemUnavail;
                auditMessage = "System_Unavailable";
                break;
            case UNKNOWN_CERT:
                failureInfo = PKIFailureInfo.badCertId;
                auditMessage = "UNKNOWN_CERT";
                break;
            default:
                failureInfo = PKIFailureInfo.systemFailure;
                auditMessage = "InternalErrorCode " + e.getErrorCode();
                break;
            } // end switch(code)

            if (childAuditEvent != null) {
                childAuditEvent.setStatus(AuditStatus.FAILED);
                childAuditEvent.addEventData(new AuditEventData("message", auditMessage));
            }

            String errorMessage;
            switch (code) {
            case DATABASE_FAILURE:
            case SYSTEM_FAILURE:
                errorMessage = code.name();
                break;
            default:
                errorMessage = code.name() + ": " + e.getErrorMessage();
                break;
            } // end switch(code)

            status = generateCmpRejectionStatus(failureInfo, errorMessage);
        } // end try

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

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

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 {/*www .j  a  v a  2  s .co 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());
}