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

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

Introduction

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

Prototype

public X500Name getSubject() 

Source Link

Usage

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

License:Open Source License

@Override
/*//from  w w  w. j a v a2 s.c  o  m
 * 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 X500Name getRequestX500Name() {
    final CertTemplate templ = getReq().getCertReq().getCertTemplate();
    X500Name name = templ.getSubject();
    if (name != null) {
        name = new X500Name(new CeSecoreNameStyle(), name);
    }//from   w  ww.  ja  v  a  2 s.  c  om
    if (log.isDebugEnabled()) {
        log.debug("Request X500Name is: " + name);
    }
    return name;
}

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

License:Open Source License

public String getSubjectDN() {
    String ret = null;//from   w w w.j av a 2  s.  c om
    final CertTemplate templ = getReq().getCertReq().getCertTemplate();
    final X500Name name = templ.getSubject();
    if (name != null) {
        ret = CertTools.stringToBCDNString(name.toString());
    }
    return ret;
}

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

License:Open Source License

private CertRepMessage processCertReqMessages(final CmpRequestorInfo requestor, final String user,
        final ASN1OctetString tid, final PKIHeader reqHeader, final CertReqMessages kur,
        final boolean keyUpdate, final long confirmWaitTime, final boolean sendCaCert,
        final AuditEvent auditEvent) throws InsuffientPermissionException {
    CmpRequestorInfo _requestor = (CmpRequestorInfo) requestor;

    CertReqMsg[] certReqMsgs = kur.toCertReqMsgArray();
    CertResponse[] certResponses = new CertResponse[certReqMsgs.length];

    for (int i = 0; i < certReqMsgs.length; i++) {
        AuditChildEvent childAuditEvent = null;
        if (auditEvent != null) {
            childAuditEvent = new AuditChildEvent();
            auditEvent.addChildAuditEvent(childAuditEvent);
        }//w  w  w .  j a v a 2s.  co  m

        CertReqMsg reqMsg = certReqMsgs[i];
        CertificateRequestMessage req = new CertificateRequestMessage(reqMsg);
        ASN1Integer certReqId = reqMsg.getCertReq().getCertReqId();
        if (childAuditEvent != null) {
            childAuditEvent
                    .addEventData(new AuditEventData("certReqId", certReqId.getPositiveValue().toString()));
        }

        if (req.hasProofOfPossession() == false) {
            PKIStatusInfo status = generateCmpRejectionStatus(PKIFailureInfo.badPOP, null);
            certResponses[i] = new CertResponse(certReqId, status);

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

        if (verifyPOP(req, _requestor.isRA()) == false) {
            LOG.warn("could not validate POP for requst {}", certReqId.getValue());
            PKIStatusInfo status = generateCmpRejectionStatus(PKIFailureInfo.badPOP, null);
            certResponses[i] = new CertResponse(certReqId, status);
            if (childAuditEvent != null) {
                childAuditEvent.setStatus(AuditStatus.FAILED);
                childAuditEvent.addEventData(new AuditEventData("message", "invalid POP"));
            }
            continue;
        }

        CertTemplate certTemp = req.getCertTemplate();
        Extensions extensions = certTemp.getExtensions();
        X500Name subject = certTemp.getSubject();
        SubjectPublicKeyInfo publicKeyInfo = certTemp.getPublicKey();
        OptionalValidity validity = certTemp.getValidity();

        try {
            CmpUtf8Pairs keyvalues = CmpUtil.extract(reqMsg.getRegInfo());
            String certprofileName = keyvalues == null ? null
                    : keyvalues.getValue(CmpUtf8Pairs.KEY_CERT_PROFILE);
            if (certprofileName == null) {
                throw new CMPException("no certificate profile is specified");
            }

            if (childAuditEvent != null) {
                childAuditEvent.addEventData(new AuditEventData("certprofile", certprofileName));
            }

            checkPermission(_requestor, certprofileName);
            certResponses[i] = generateCertificate(_requestor, user, tid, certReqId, subject, publicKeyInfo,
                    validity, extensions, certprofileName, keyUpdate, confirmWaitTime, childAuditEvent);
        } catch (CMPException e) {
            final String message = "generateCertificate";
            if (LOG.isWarnEnabled()) {
                LOG.warn(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage());
            }
            LOG.debug(message, e);

            certResponses[i] = new CertResponse(certReqId,
                    generateCmpRejectionStatus(PKIFailureInfo.badCertTemplate, e.getMessage()));

            if (childAuditEvent != null) {
                childAuditEvent.setStatus(AuditStatus.FAILED);
                childAuditEvent.addEventData(new AuditEventData("message", "badCertTemplate"));
            }
        } // end try
    } // end for

    CMPCertificate[] caPubs = sendCaCert ? new CMPCertificate[] { getCA().getCAInfo().getCertInCMPFormat() }
            : null;
    return new CertRepMessage(caPubs, certResponses);
}

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  ww  w . ja v  a2s.c om*/
            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 CertRepMessage processCertReqMessages(final PKIMessage request, final CmpRequestorInfo requestor,
        final String user, final ASN1OctetString tid, final PKIHeader reqHeader, final CertReqMessages kur,
        final boolean keyUpdate, final CmpControl cmpControl, final String msgId, final AuditEvent event) {
    CmpRequestorInfo tmpRequestor = (CmpRequestorInfo) requestor;

    CertReqMsg[] certReqMsgs = kur.toCertReqMsgArray();
    final int n = certReqMsgs.length;

    Map<Integer, CertTemplateData> certTemplateDatas = new HashMap<>(n * 10 / 6);
    Map<Integer, CertResponse> certResponses = new HashMap<>(n * 10 / 6);
    Map<Integer, ASN1Integer> certReqIds = new HashMap<>(n * 10 / 6);

    // pre-process requests
    for (int i = 0; i < n; i++) {
        if (cmpControl.isGroupEnroll() && certTemplateDatas.size() != i) {
            // last certReqMsg cannot be used to enroll certificate
            break;
        }/*from  www. j a  v  a2  s. c  om*/

        CertReqMsg reqMsg = certReqMsgs[i];
        CertificateRequestMessage req = new CertificateRequestMessage(reqMsg);
        ASN1Integer certReqId = reqMsg.getCertReq().getCertReqId();
        certReqIds.put(i, certReqId);

        if (!req.hasProofOfPossession()) {
            certResponses.put(i, buildErrorCertResponse(certReqId, PKIFailureInfo.badPOP, "no POP", null));
            continue;
        }

        if (!verifyPopo(req, tmpRequestor.isRa())) {
            LOG.warn("could not validate POP for request {}", certReqId.getValue());
            certResponses.put(i, buildErrorCertResponse(certReqId, PKIFailureInfo.badPOP, "invalid POP", null));
            continue;
        }

        CmpUtf8Pairs keyvalues = CmpUtil.extract(reqMsg.getRegInfo());
        String certprofileName = (keyvalues == null) ? null : keyvalues.getValue(CmpUtf8Pairs.KEY_CERT_PROFILE);
        if (certprofileName == null) {
            String msg = "no certificate profile";
            certResponses.put(i, buildErrorCertResponse(certReqId, PKIFailureInfo.badCertTemplate, msg));
            continue;
        }

        if (!isCertProfilePermitted(tmpRequestor, certprofileName)) {
            String msg = "certprofile " + certprofileName + " is not allowed";
            certResponses.put(i, buildErrorCertResponse(certReqId, PKIFailureInfo.notAuthorized, msg));
            continue;
        }

        CertTemplate certTemp = req.getCertTemplate();
        OptionalValidity validity = certTemp.getValidity();

        Date notBefore = null;
        Date notAfter = null;
        if (validity != null) {
            Time time = validity.getNotBefore();
            if (time != null) {
                notBefore = time.getDate();
            }
            time = validity.getNotAfter();
            if (time != null) {
                notAfter = time.getDate();
            }
        }

        CertTemplateData certTempData = new CertTemplateData(certTemp.getSubject(), certTemp.getPublicKey(),
                notBefore, notAfter, certTemp.getExtensions(), certprofileName);
        certTemplateDatas.put(i, certTempData);
    } // end for

    if (certResponses.size() == n) {
        // all error
        CertResponse[] certResps = new CertResponse[n];
        for (int i = 0; i < n; i++) {
            certResps[i] = certResponses.get(i);
        }
        return new CertRepMessage(null, certResps);
    }

    if (cmpControl.isGroupEnroll() && certTemplateDatas.size() != n) {
        // at least one certRequest cannot be used to enroll certificate
        int lastFailureIndex = certTemplateDatas.size();
        BigInteger failCertReqId = certReqIds.get(lastFailureIndex).getPositiveValue();
        CertResponse failCertResp = certResponses.get(lastFailureIndex);
        PKIStatus failStatus = PKIStatus.getInstance(new ASN1Integer(failCertResp.getStatus().getStatus()));
        PKIFailureInfo failureInfo = new PKIFailureInfo(failCertResp.getStatus().getFailInfo());

        CertResponse[] certResps = new CertResponse[n];

        for (int i = 0; i < n; i++) {
            if (i == lastFailureIndex) {
                certResps[i] = failCertResp;
                continue;
            }

            ASN1Integer certReqId = certReqIds.get(i);
            String msg = "error in certReq " + failCertReqId;
            PKIStatusInfo tmpStatus = generateRejectionStatus(failStatus, failureInfo.intValue(), msg);
            certResps[i] = new CertResponse(certReqId, tmpStatus);
        }

        return new CertRepMessage(null, certResps);
    }

    final int k = certTemplateDatas.size();
    List<CertTemplateData> certTemplateList = new ArrayList<>(k);
    List<ASN1Integer> certReqIdList = new ArrayList<>(k);
    Map<Integer, Integer> reqIndexToCertIndexMap = new HashMap<>(k * 10 / 6);

    for (int i = 0; i < n; i++) {
        if (!certTemplateDatas.containsKey(i)) {
            continue;
        }

        certTemplateList.add(certTemplateDatas.get(i));
        certReqIdList.add(certReqIds.get(i));
        reqIndexToCertIndexMap.put(i, certTemplateList.size() - 1);
    }

    List<CertResponse> generateCertResponses = generateCertificates(certTemplateList, certReqIdList,
            tmpRequestor, user, tid, keyUpdate, request, cmpControl, msgId, event);
    boolean anyCertEnrolled = false;

    CertResponse[] certResps = new CertResponse[n];
    for (int i = 0; i < n; i++) {
        if (certResponses.containsKey(i)) {
            certResps[i] = certResponses.get(i);
        } else {
            int respIndex = reqIndexToCertIndexMap.get(i);
            certResps[i] = generateCertResponses.get(respIndex);
            if (!anyCertEnrolled && certResps[i].getCertifiedKeyPair() != null) {
                anyCertEnrolled = true;
            }
        }
    }

    CMPCertificate[] caPubs = null;
    if (anyCertEnrolled && cmpControl.isSendCaCert()) {
        caPubs = new CMPCertificate[] { getCa().getCaInfo().getCertInCmpFormat() };
    }

    return new CertRepMessage(caPubs, certResps);
}

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  ava 2  s. c  om
            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());
}