Example usage for org.bouncycastle.asn1.x500 X500Name equals

List of usage examples for org.bouncycastle.asn1.x500 X500Name equals

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.x500 X500Name equals.

Prototype

public boolean equals(Object obj) 

Source Link

Document

test for equality - note: case is ignored.

Usage

From source file:org.jscep.client.Client.java

License:Open Source License

/**
 * Sends a CSR to the SCEP server for enrolling in a PKI.
 * <p>//from   ww w  .  j  a  v  a2  s .  c  o  m
 * This method enrols the provider <tt>CertificationRequest</tt> into the
 * PKI represented by the SCEP server.
 *
 * @param identity
 *            the identity of the client.
 * @param key
 *            the private key to sign the SCEP request.
 * @param csr
 *            the CSR to enrol.
 * @param profile
 *            the SCEP server profile.
 * @return the certificate store returned by the server.
 * @throws ClientException
 *             if any client error occurs.
 * @throws TransactionException
 *             if there is a problem with the SCEP transaction.
 * @see CertStoreInspector
 */
public EnrollmentResponse enrol(final X509Certificate identity, final PrivateKey key,
        final PKCS10CertificationRequest csr, final String profile)
        throws ClientException, TransactionException {
    LOGGER.debug("Enrolling certificate with CA");

    if (isSelfSigned(identity)) {
        LOGGER.debug("Certificate is self-signed");
        X500Name csrSubject = csr.getSubject();
        X500Name idSubject = X500Utils.toX500Name(identity.getSubjectX500Principal());

        if (!csrSubject.equals(idSubject)) {
            LOGGER.error(
                    "The self-signed certificate MUST use the same subject name as in the PKCS#10 request.");
        }
    }
    // TRANSACTIONAL
    // Certificate enrollment
    final Transport transport = createTransport(profile);
    PkiMessageEncoder encoder = getEncoder(identity, key, profile);
    PkiMessageDecoder decoder = getDecoder(identity, key, profile);
    final EnrollmentTransaction trans = new EnrollmentTransaction(transport, encoder, decoder, csr);

    try {
        MessageDigest digest = getCaCapabilities(profile).getStrongestMessageDigest();
        byte[] hash = digest.digest(csr.getEncoded());

        LOGGER.debug("{} PKCS#10 Fingerprint: [{}]", digest.getAlgorithm(), new String(Hex.encodeHex(hash)));
    } catch (IOException e) {
        LOGGER.error("Error getting encoded CSR", e);
    }

    return send(trans);
}

From source file:org.keycloak.common.util.OCSPUtils.java

License:Apache License

private static void verifyResponse(BasicOCSPResp basicOcspResponse, X509Certificate issuerCertificate,
        X509Certificate responderCertificate, byte[] requestNonce, Date date)
        throws NoSuchProviderException, NoSuchAlgorithmException, CertificateNotYetValidException,
        CertificateExpiredException, CertPathValidatorException {

    List<X509CertificateHolder> certs = new ArrayList<>(Arrays.asList(basicOcspResponse.getCerts()));
    X509Certificate signingCert = null;

    try {//from www  .j  a  v  a2s.  c  om
        certs.add(new JcaX509CertificateHolder(issuerCertificate));
        if (responderCertificate != null) {
            certs.add(new JcaX509CertificateHolder(responderCertificate));
        }
    } catch (CertificateEncodingException e) {
        e.printStackTrace();
    }
    if (certs.size() > 0) {

        X500Name responderName = basicOcspResponse.getResponderId().toASN1Primitive().getName();
        byte[] responderKey = basicOcspResponse.getResponderId().toASN1Primitive().getKeyHash();

        if (responderName != null) {
            logger.log(Level.INFO, "Responder Name: {0}", responderName.toString());
            for (X509CertificateHolder certHolder : certs) {
                try {
                    X509Certificate tempCert = new JcaX509CertificateConverter().setProvider("BC")
                            .getCertificate(certHolder);
                    X500Name respName = new X500Name(tempCert.getSubjectX500Principal().getName());
                    if (responderName.equals(respName)) {
                        signingCert = tempCert;
                        logger.log(Level.INFO,
                                "Found a certificate whose principal \"{0}\" matches the responder name \"{1}\"",
                                new Object[] { tempCert.getSubjectDN().getName(), responderName.toString() });
                        break;
                    }
                } catch (CertificateException e) {
                    logger.log(Level.FINE, e.getMessage());
                }
            }
        } else if (responderKey != null) {
            SubjectKeyIdentifier responderSubjectKey = new SubjectKeyIdentifier(responderKey);
            logger.log(Level.INFO, "Responder Key: {0}", Arrays.toString(responderKey));
            for (X509CertificateHolder certHolder : certs) {
                try {
                    X509Certificate tempCert = new JcaX509CertificateConverter().setProvider("BC")
                            .getCertificate(certHolder);

                    SubjectKeyIdentifier subjectKeyIdentifier = null;
                    if (certHolder.getExtensions() != null) {
                        subjectKeyIdentifier = SubjectKeyIdentifier.fromExtensions(certHolder.getExtensions());
                    }

                    if (subjectKeyIdentifier != null) {
                        logger.log(Level.INFO, "Certificate: {0}\nSubject Key Id: {1}",
                                new Object[] { tempCert.getSubjectDN().getName(),
                                        Arrays.toString(subjectKeyIdentifier.getKeyIdentifier()) });
                    }

                    if (subjectKeyIdentifier != null && responderSubjectKey.equals(subjectKeyIdentifier)) {
                        signingCert = tempCert;
                        logger.log(Level.INFO,
                                "Found a signer certificate \"{0}\" with the subject key extension value matching the responder key",
                                signingCert.getSubjectDN().getName());

                        break;
                    }

                    subjectKeyIdentifier = new JcaX509ExtensionUtils()
                            .createSubjectKeyIdentifier(tempCert.getPublicKey());
                    if (responderSubjectKey.equals(subjectKeyIdentifier)) {
                        signingCert = tempCert;
                        logger.log(Level.INFO,
                                "Found a certificate \"{0}\" with the subject key matching the OCSP responder key",
                                signingCert.getSubjectDN().getName());
                        break;
                    }

                } catch (CertificateException e) {
                    logger.log(Level.FINE, e.getMessage());
                }
            }
        }
    }
    if (signingCert != null) {
        if (signingCert.equals(issuerCertificate)) {
            logger.log(Level.INFO, "OCSP response is signed by the target''s Issuing CA");
        } else if (responderCertificate != null && signingCert.equals(responderCertificate)) {
            // https://www.ietf.org/rfc/rfc2560.txt
            // 2.6  OCSP Signature Authority Delegation
            // - The responder certificate is issued to the responder by CA
            logger.log(Level.INFO, "OCSP response is signed by an authorized responder certificate");
        } else {
            // 4.2.2.2  Authorized Responders
            // 3. Includes a value of id-ad-ocspSigning in an ExtendedKeyUsage
            // extension and is issued by the CA that issued the certificate in
            // question."
            if (!signingCert.getIssuerX500Principal().equals(issuerCertificate.getSubjectX500Principal())) {
                logger.log(Level.INFO, "Signer certificate''s Issuer: {0}\nIssuer certificate''s Subject: {1}",
                        new Object[] { signingCert.getIssuerX500Principal().getName(),
                                issuerCertificate.getSubjectX500Principal().getName() });
                throw new CertPathValidatorException(
                        "Responder\'s certificate is not authorized to sign OCSP responses");
            }
            try {
                List<String> purposes = signingCert.getExtendedKeyUsage();
                if (purposes != null && !purposes.contains(KeyPurposeId.id_kp_OCSPSigning.getId())) {
                    logger.log(Level.INFO, "OCSPSigning extended usage is not set");
                    throw new CertPathValidatorException(
                            "Responder\'s certificate not valid for signing OCSP responses");
                }
            } catch (CertificateParsingException e) {
                logger.log(Level.FINE, "Failed to get certificate''s extended key usage extension\n{0}",
                        e.getMessage());
            }
            if (date == null) {
                signingCert.checkValidity();
            } else {
                signingCert.checkValidity(date);
            }
            try {
                Extension noOCSPCheck = new JcaX509CertificateHolder(signingCert)
                        .getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck);
                // TODO If the extension is present, the OCSP client can trust the
                // responder's certificate for the lifetime of the certificate.
                logger.log(Level.INFO, "OCSP no-check extension is {0} present",
                        noOCSPCheck == null ? "not" : "");
            } catch (CertificateEncodingException e) {
                logger.log(Level.FINE, "Certificate encoding exception: {0}", e.getMessage());
            }

            try {
                signingCert.verify(issuerCertificate.getPublicKey());
                logger.log(Level.INFO, "OCSP response is signed by an Authorized Responder");

            } catch (GeneralSecurityException ex) {
                signingCert = null;
            }
        }
    }
    if (signingCert == null) {
        throw new CertPathValidatorException("Unable to verify OCSP Response\'s signature");
    } else {
        if (!verifySignature(basicOcspResponse, signingCert)) {
            throw new CertPathValidatorException("Error verifying OCSP Response\'s signature");
        } else {
            Extension responseNonce = basicOcspResponse.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
            if (responseNonce != null && requestNonce != null
                    && !Arrays.equals(requestNonce, responseNonce.getExtnValue().getOctets())) {
                throw new CertPathValidatorException("Nonces do not match.");
            } else {
                // See Sun's OCSP implementation.
                // https://www.ietf.org/rfc/rfc2560.txt, if nextUpdate is not set,
                // the responder is indicating that newer update is avilable all the time
                long current = date == null ? System.currentTimeMillis() : date.getTime();
                Date stop = new Date(current + (long) TIME_SKEW);
                Date start = new Date(current - (long) TIME_SKEW);

                Iterator<SingleResp> iter = Arrays.asList(basicOcspResponse.getResponses()).iterator();
                SingleResp singleRes = null;
                do {
                    if (!iter.hasNext()) {
                        return;
                    }
                    singleRes = iter.next();
                } while (!stop.before(singleRes.getThisUpdate())
                        && !start.after(singleRes.getNextUpdate() != null ? singleRes.getNextUpdate()
                                : singleRes.getThisUpdate()));

                throw new CertPathValidatorException(
                        "Response is unreliable: its validity interval is out-of-date");
            }
        }
    }
}

From source file:org.signserver.module.mrtdsodsigner.MRTDSODSigner.java

License:Open Source License

private X509Certificate findIssuerCert(Collection<Certificate> chain, X509Certificate sodCert) {
    X509Certificate result = null;
    final X500Name issuer = JcaX500NameUtil.getIssuer(sodCert);
    if (log.isDebugEnabled()) {
        final StringBuilder buff = new StringBuilder();
        buff.append("Looking for ");
        buff.append(issuer);/*  w w w  . j  a v a2 s.  c  o  m*/
        log.debug(buff.toString());
    }
    for (Certificate cert : chain) {
        if (cert instanceof X509Certificate) {
            final X509Certificate x509 = (X509Certificate) cert;
            final X500Name subject = JcaX500NameUtil.getSubject(x509);
            if (issuer.equals(subject)) {
                result = (X509Certificate) cert;
                if (log.isDebugEnabled()) {
                    log.debug("Found issuer");
                }
                break;
            } else {
                if (log.isDebugEnabled()) {
                    final StringBuilder buff = new StringBuilder();
                    buff.append(issuer);
                    buff.append("!=");
                    buff.append(subject);
                    log.debug(buff.toString());
                }
            }
        }
    }
    return result;
}

From source file:org.xipki.ca.api.profile.x509.X509CertUtil.java

License:Open Source License

public static CRLDistPoint createCRLDistributionPoints(final List<String> crlUris, final X500Name caSubject,
        final X500Name crlSignerSubject) throws IOException, CertprofileException {
    if (CollectionUtil.isEmpty(crlUris)) {
        return null;
    }//  www .  ja v  a 2  s.c  o  m

    int n = crlUris.size();
    DistributionPoint[] points = new DistributionPoint[1];

    GeneralName[] names = new GeneralName[n];
    for (int i = 0; i < n; i++) {
        names[i] = new GeneralName(GeneralName.uniformResourceIdentifier, crlUris.get(i));
    }
    // Distribution Point
    GeneralNames gns = new GeneralNames(names);
    DistributionPointName pointName = new DistributionPointName(gns);

    GeneralNames crlIssuer = null;
    if (crlSignerSubject != null && crlSignerSubject.equals(caSubject) == false) {
        GeneralName crlIssuerName = new GeneralName(crlSignerSubject);
        crlIssuer = new GeneralNames(crlIssuerName);
    }

    points[0] = new DistributionPoint(pointName, null, crlIssuer);

    return new CRLDistPoint(points);
}

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

License:Open Source License

@Override
public Map<String, CertIdOrError> revokeCerts(final RevokeCertRequestType request,
        final RequestResponseDebug debug) throws CAClientException, PKIErrorException {
    ParamChecker.assertNotNull("request", request);

    List<RevokeCertRequestEntryType> requestEntries = request.getRequestEntries();
    if (CollectionUtil.isEmpty(requestEntries)) {
        return Collections.emptyMap();
    }//  w w  w.  j  a va2 s. c  om

    X500Name issuer = requestEntries.get(0).getIssuer();
    for (int i = 1; i < requestEntries.size(); i++) {
        if (issuer.equals(requestEntries.get(i).getIssuer()) == false) {
            throw new PKIErrorException(PKIStatus.REJECTION, PKIFailureInfo.badRequest,
                    "revoking certificates issued by more than one CA is not allowed");
        }
    }

    final String caName = getCaNameByIssuer(issuer);
    X509CmpRequestor cmpRequestor = casMap.get(caName).getRequestor();
    RevokeCertResultType result;
    try {
        result = cmpRequestor.revokeCertificate(request, debug);
    } catch (CmpRequestorException e) {
        throw new CAClientException(e.getMessage(), e);
    }

    return parseRevokeCertResult(result);
}

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

License:Open Source License

@Override
public Map<String, CertIdOrError> unrevokeCerts(final UnrevokeOrRemoveCertRequestType request,
        final RequestResponseDebug debug) throws CAClientException, PKIErrorException {
    ParamChecker.assertNotNull("request", request);

    List<IssuerSerialEntryType> requestEntries = request.getRequestEntries();
    if (CollectionUtil.isEmpty(requestEntries)) {
        return Collections.emptyMap();
    }//from w w w . j av a2 s  .  c om

    X500Name issuer = requestEntries.get(0).getIssuer();
    for (int i = 1; i < requestEntries.size(); i++) {
        if (issuer.equals(requestEntries.get(i).getIssuer()) == false) {
            throw new PKIErrorException(PKIStatus.REJECTION, PKIFailureInfo.badRequest,
                    "unrevoking certificates issued by more than one CA is not allowed");
        }
    }

    final String caName = getCaNameByIssuer(issuer);
    X509CmpRequestor cmpRequestor = casMap.get(caName).getRequestor();
    RevokeCertResultType result;
    try {
        result = cmpRequestor.unrevokeCertificate(request, debug);
    } catch (CmpRequestorException e) {
        throw new CAClientException(e.getMessage(), e);
    }

    return parseRevokeCertResult(result);
}

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

License:Open Source License

@Override
public Map<String, CertIdOrError> removeCerts(final UnrevokeOrRemoveCertRequestType request,
        final RequestResponseDebug debug) throws CAClientException, PKIErrorException {
    ParamChecker.assertNotNull("request", request);

    List<IssuerSerialEntryType> requestEntries = request.getRequestEntries();
    if (CollectionUtil.isEmpty(requestEntries)) {
        return Collections.emptyMap();
    }/* w  w  w . j  av a  2s.  co  m*/

    X500Name issuer = requestEntries.get(0).getIssuer();
    for (int i = 1; i < requestEntries.size(); i++) {
        if (issuer.equals(requestEntries.get(i).getIssuer()) == false) {
            throw new PKIErrorException(PKIStatus.REJECTION, PKIFailureInfo.badRequest,
                    "removing certificates issued by more than one CA is not allowed");
        }
    }

    final String caName = getCaNameByIssuer(issuer);
    X509CmpRequestor cmpRequestor = casMap.get(caName).getRequestor();
    RevokeCertResultType result;
    try {
        result = cmpRequestor.removeCertificate(request, debug);
    } catch (CmpRequestorException e) {
        throw new CAClientException(e.getMessage(), e);
    }

    return parseRevokeCertResult(result);
}

From source file:org.xipki.ca.qa.impl.X509CertprofileQAImpl.java

License:Open Source License

private void checkExtensionIssuerKeyIdentifier(final StringBuilder failureMsg, final byte[] extensionValue,
        final X509IssuerInfo issuerInfo) {
    AuthorityKeyIdentifier asn1 = AuthorityKeyIdentifier.getInstance(extensionValue);
    byte[] keyIdentifier = asn1.getKeyIdentifier();
    if (keyIdentifier == null) {
        failureMsg.append("keyIdentifier is 'absent' but expected 'present'");
        failureMsg.append("; ");
    } else if (Arrays.equals(issuerInfo.getSubjectKeyIdentifier(), keyIdentifier) == false) {
        failureMsg.append("keyIdentifier is '" + hex(keyIdentifier) + "' but expected '"
                + hex(issuerInfo.getSubjectKeyIdentifier()) + "'");
        failureMsg.append("; ");
    }//from  ww  w .  jav  a2s. c om

    BigInteger serialNumber = asn1.getAuthorityCertSerialNumber();
    GeneralNames names = asn1.getAuthorityCertIssuer();

    if (includeIssuerAndSerialInAKI) {
        if (serialNumber == null) {
            failureMsg.append("authorityCertSerialNumber is 'absent' but expected 'present'");
            failureMsg.append("; ");
        } else {
            if (issuerInfo.getCert().getSerialNumber().equals(serialNumber) == false) {
                failureMsg.append("authorityCertSerialNumber is '" + serialNumber + "' but expected '"
                        + issuerInfo.getCert().getSerialNumber() + "'");
                failureMsg.append("; ");
            }
        }

        if (names == null) {
            failureMsg.append("authorityCertIssuer is 'absent' but expected 'present'");
            failureMsg.append("; ");
        } else {
            GeneralName[] genNames = names.getNames();
            X500Name x500GenName = null;
            for (GeneralName genName : genNames) {
                if (genName.getTagNo() != GeneralName.directoryName) {
                    continue;
                }

                if (x500GenName != null) {
                    failureMsg.append(
                            "authorityCertIssuer contains at least two directoryName " + "but expected one");
                    failureMsg.append("; ");
                    break;
                } else {
                    x500GenName = (X500Name) genName.getName();
                }
            }

            if (x500GenName == null) {
                failureMsg.append("authorityCertIssuer does not contain directoryName but expected one");
                failureMsg.append("; ");
            } else {
                X500Name caSubject = issuerInfo.getBcCert().getTBSCertificate().getSubject();
                if (caSubject.equals(x500GenName) == false) {
                    failureMsg.append("authorityCertIssuer is '" + x500GenName.toString() + "' but expected '"
                            + caSubject.toString() + "'");
                    failureMsg.append("; ");
                }
            }
        }
    } else {
        if (serialNumber != null) {
            failureMsg.append("authorityCertSerialNumber is 'absent' but expected 'present'");
            failureMsg.append("; ");
        }

        if (names != null) {
            failureMsg.append("authorityCertIssuer is 'absent' but expected 'present'");
            failureMsg.append("; ");
        }
    }
}

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

License:Open Source License

private X509CertificateInfo intern_generateCertificate(final boolean requestedByRA,
        final RequestorInfo requestor, final String certprofileLocalName, final String user,
        X500Name requestedSubject, SubjectPublicKeyInfo publicKeyInfo, Date notBefore, Date notAfter,
        final org.bouncycastle.asn1.x509.Extensions extensions, final boolean keyUpdate)
        throws OperationException {
    if (caInfo.getRevocationInfo() != null) {
        throw new OperationException(ErrorCode.NOT_PERMITTED, "CA is revoked");
    }/*  w ww .ja  v a 2 s. c  o m*/

    IdentifiedX509Certprofile certprofile = getX509Certprofile(certprofileLocalName);

    if (certprofile == null) {
        throw new OperationException(ErrorCode.UNKNOWN_CERT_PROFILE,
                "unknown cert profile " + certprofileLocalName);
    }

    ConcurrentContentSigner signer = caInfo.getSigner(certprofile.getSignatureAlgorithms());
    if (signer == null) {
        throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                "CA does not support any signature algorithm restricted by the cert profile");
    }

    final String certprofileName = certprofile.getName();
    if (certprofile.getVersion() != X509CertVersion.V3) {
        throw new OperationException(ErrorCode.SYSTEM_FAILURE, "unknown cert version " + certprofile);
    }

    if (certprofile.isOnlyForRA() && requestedByRA == false) {
        throw new OperationException(ErrorCode.INSUFFICIENT_PERMISSION,
                "profile " + certprofileName + " not applied to non-RA");
    }

    requestedSubject = removeEmptyRDNs(requestedSubject);

    if (certprofile.isSerialNumberInReqPermitted() == false) {
        RDN[] rdns = requestedSubject.getRDNs(ObjectIdentifiers.DN_SN);
        if (rdns != null && rdns.length > 0) {
            throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE,
                    "subjectDN SerialNumber in request is not permitted");
        }
    }

    notBefore = certprofile.getNotBefore(notBefore);
    if (notBefore == null) {
        notBefore = new Date();
    }

    if (certprofile.hasMidnightNotBefore()) {
        notBefore = setToMidnight(notBefore, certprofile.getTimezone());
    }

    if (notBefore.before(caInfo.getNotBefore())) {
        notBefore = caInfo.getNotBefore();
        if (certprofile.hasMidnightNotBefore()) {
            notBefore = setToMidnight(new Date(notBefore.getTime() + DAY), certprofile.getTimezone());
        }
    }

    long t = caInfo.getNoNewCertificateAfter();
    if (notBefore.getTime() > t) {
        throw new OperationException(ErrorCode.NOT_PERMITTED,
                "CA is not permitted to issue certifate after " + new Date(t));
    }

    try {
        publicKeyInfo = X509Util.toRfc3279Style(publicKeyInfo);
    } catch (InvalidKeySpecException e) {
        throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "invalid SubjectPublicKeyInfo");
    }

    // public key
    try {
        publicKeyInfo = certprofile.checkPublicKey(publicKeyInfo);
    } catch (BadCertTemplateException e) {
        throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, e.getMessage());
    }

    Date gSMC_KFirstNotBefore = null;
    if (certprofile.getSpecialCertprofileBehavior() == SpecialX509CertprofileBehavior.gematik_gSMC_K) {
        gSMC_KFirstNotBefore = notBefore;

        RDN[] cnRDNs = requestedSubject.getRDNs(ObjectIdentifiers.DN_CN);
        if (cnRDNs != null && cnRDNs.length > 0) {
            String requestedCN = X509Util.rdnValueToString(cnRDNs[0].getFirst().getValue());
            Long gsmckFirstNotBeforeInSecond = certstore.getNotBeforeOfFirstCertStartsWithCN(requestedCN,
                    certprofileName);
            if (gsmckFirstNotBeforeInSecond != null) {
                gSMC_KFirstNotBefore = new Date(gsmckFirstNotBeforeInSecond * MS_PER_SECOND);
            }

            // append the commonName with '-' + yyyyMMdd
            SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMdd");
            dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
            String yyyyMMdd = dateF.format(gSMC_KFirstNotBefore);
            String suffix = "-" + yyyyMMdd;

            // append the -yyyyMMdd to the commonName
            RDN[] rdns = requestedSubject.getRDNs();
            for (int i = 0; i < rdns.length; i++) {
                if (ObjectIdentifiers.DN_CN.equals(rdns[i].getFirst().getType())) {
                    rdns[i] = new RDN(ObjectIdentifiers.DN_CN, new DERUTF8String(requestedCN + suffix));
                }
            }
            requestedSubject = new X500Name(rdns);
        }
    } // end if

    // subject
    SubjectInfo subjectInfo;
    try {
        subjectInfo = certprofile.getSubject(requestedSubject);
    } catch (CertprofileException e) {
        throw new OperationException(ErrorCode.SYSTEM_FAILURE, "exception in cert profile " + certprofileName);
    } catch (BadCertTemplateException e) {
        throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, e.getMessage());
    }

    X500Name grantedSubject = subjectInfo.getGrantedSubject();

    // make sure that the grantedSubject does not equal the CA's subject
    if (grantedSubject.equals(caInfo.getPublicCAInfo().getX500Subject())) {
        throw new OperationException(ErrorCode.ALREADY_ISSUED,
                "certificate with the same subject as CA is not allowed");
    }

    DuplicationMode keyMode = caInfo.getDuplicateKeyMode();
    if (keyMode == DuplicationMode.PERMITTED && certprofile.isDuplicateKeyPermitted() == false) {
        keyMode = DuplicationMode.FORBIDDEN_WITHIN_PROFILE;
    }

    DuplicationMode subjectMode = caInfo.getDuplicateSubjectMode();
    if (subjectMode == DuplicationMode.PERMITTED && certprofile.isDuplicateSubjectPermitted() == false) {
        subjectMode = DuplicationMode.FORBIDDEN_WITHIN_PROFILE;
    }

    String sha1FpSubject = X509Util.sha1sum_canonicalized_name(grantedSubject);
    String grandtedSubjectText = X509Util.getRFC4519Name(grantedSubject);

    byte[] subjectPublicKeyData = publicKeyInfo.getPublicKeyData().getBytes();
    String sha1FpPublicKey = SecurityUtil.sha1sum(subjectPublicKeyData);

    if (keyUpdate) {
        CertStatus certStatus = certstore.getCertStatusForSubject(caInfo.getCertificate(), grantedSubject);
        if (certStatus == CertStatus.Revoked) {
            throw new OperationException(ErrorCode.CERT_REVOKED);
        } else if (certStatus == CertStatus.Unknown) {
            throw new OperationException(ErrorCode.UNKNOWN_CERT);
        }
    } else {
        // try to get certificate with the same subject, key and certificate profile
        SubjectKeyProfileBundle bundle = certstore.getLatestCert(caInfo.getCertificate(), sha1FpSubject,
                sha1FpPublicKey, certprofileName);

        if (bundle != null) {
            /*
             * If there exists a certificate whose public key, subject and profile match the request,
             * returns the certificate if it is not revoked, otherwise OperationException with
             * ErrorCode CERT_REVOKED will be thrown
             */
            if (bundle.isRevoked()) {
                throw new OperationException(ErrorCode.CERT_REVOKED);
            } else {
                X509CertWithDBCertId issuedCert = certstore.getCertForId(bundle.getCertId());
                if (issuedCert == null) {
                    throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                            "could not find certificate in table RAWCERT for CERT_ID " + bundle.getCertId());
                } else {
                    X509CertificateInfo certInfo;
                    try {
                        certInfo = new X509CertificateInfo(issuedCert, caInfo.getCertificate(),
                                subjectPublicKeyData, certprofileName);
                    } catch (CertificateEncodingException e) {
                        throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                                "could not construct CertificateInfo: " + e.getMessage());
                    }
                    certInfo.setAlreadyIssued(true);
                    return certInfo;
                }
            }
        } // end if(bundle)

        if (keyMode != DuplicationMode.PERMITTED) {
            if (keyMode == DuplicationMode.FORBIDDEN) {
                if (certstore.isCertForKeyIssued(caInfo.getCertificate(), sha1FpPublicKey)) {
                    throw new OperationException(ErrorCode.ALREADY_ISSUED,
                            "certificate for the given public key already issued");
                }
            } else if (keyMode == DuplicationMode.FORBIDDEN_WITHIN_PROFILE) {
                if (certstore.isCertForKeyIssued(caInfo.getCertificate(), sha1FpPublicKey, certprofileName)) {
                    throw new OperationException(ErrorCode.ALREADY_ISSUED,
                            "certificate for the given public key and profile " + certprofileName
                                    + " already issued");
                }
            } else {
                throw new RuntimeException("should not reach here, unknown key DuplicationMode " + keyMode);
            }
        } // end if(keyMode)

        if (subjectMode != DuplicationMode.PERMITTED) {
            final boolean incSerial = certprofile.incSerialNumberIfSubjectExists();
            final boolean certIssued;
            if (subjectMode == DuplicationMode.FORBIDDEN) {
                certIssued = certstore.isCertForSubjectIssued(caInfo.getCertificate(), sha1FpSubject);
                if (certIssued && incSerial == false) {
                    throw new OperationException(ErrorCode.ALREADY_ISSUED,
                            "certificate for the given subject " + grandtedSubjectText + " already issued");
                }
            } else if (subjectMode == DuplicationMode.FORBIDDEN_WITHIN_PROFILE) {
                certIssued = certstore.isCertForSubjectIssued(caInfo.getCertificate(), sha1FpSubject,
                        certprofileName);
                if (certIssued && incSerial == false) {
                    throw new OperationException(ErrorCode.ALREADY_ISSUED, "certificate for the given subject "
                            + grandtedSubjectText + " and profile " + certprofileName + " already issued");
                }
            } else {
                throw new RuntimeException("should not reach here, unknown subject DuplicationMode " + keyMode);
            } // end if(subjectMode)

            if (certIssued) {
                String latestSN;
                try {
                    Object[] objs = incSerialNumber(certprofile, grantedSubject, null);
                    latestSN = certstore.getLatestSN((X500Name) objs[0]);
                } catch (BadFormatException e) {
                    throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                            "BadFormatException: " + e.getMessage());
                }

                boolean foundUniqueSubject = false;
                // maximal 100 tries
                for (int i = 0; i < 100; i++) {
                    try {
                        Object[] objs = incSerialNumber(certprofile, grantedSubject, latestSN);
                        grantedSubject = (X500Name) objs[0];
                        latestSN = (String) objs[1];
                    } catch (BadFormatException e) {
                        throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                                "BadFormatException: " + e.getMessage());
                    }

                    foundUniqueSubject = (certstore.certIssuedForSubject(caInfo.getCertificate(),
                            X509Util.sha1sum_canonicalized_name(grantedSubject)) == false);
                    if (foundUniqueSubject) {
                        break;
                    }
                }

                if (foundUniqueSubject == false) {
                    throw new OperationException(ErrorCode.ALREADY_ISSUED,
                            "certificate for the given subject " + grandtedSubjectText + " and profile "
                                    + certprofileName
                                    + " already issued, and could not create new unique serial number");
                }
            } // end if(certIssued)
        }
    } // end if(subjectMode != DuplicationMode.PERMITTED)

    try {
        boolean addedCertInProcess = certstore.addCertInProcess(sha1FpPublicKey, sha1FpSubject);
        if (addedCertInProcess == false) {
            throw new OperationException(ErrorCode.ALREADY_ISSUED, "certificate with the given subject "
                    + grandtedSubjectText + " and/or public key already in process");
        }

        StringBuilder msgBuilder = new StringBuilder();

        if (subjectInfo.getWarning() != null) {
            msgBuilder.append(", ").append(subjectInfo.getWarning());
        }

        CertValidity validity = certprofile.getValidity();

        if (validity == null) {
            validity = caInfo.getMaxValidity();
        } else if (validity.compareTo(caInfo.getMaxValidity()) > 0) {
            validity = caInfo.getMaxValidity();
        }

        Date maxNotAfter = validity.add(notBefore);
        Date origMaxNotAfter = maxNotAfter;

        if (certprofile.getSpecialCertprofileBehavior() == SpecialX509CertprofileBehavior.gematik_gSMC_K) {
            String s = certprofile.getParameter(SpecialX509CertprofileBehavior.PARAMETER_MAXLIFTIME);
            long maxLifetimeInDays = Long.parseLong(s);
            Date maxLifetime = new Date(
                    gSMC_KFirstNotBefore.getTime() + maxLifetimeInDays * DAY - MS_PER_SECOND);
            if (maxNotAfter.after(maxLifetime)) {
                maxNotAfter = maxLifetime;
            }
        }

        if (notAfter != null) {
            if (notAfter.after(maxNotAfter)) {
                notAfter = maxNotAfter;
                msgBuilder.append(", NotAfter modified");
            }
        } else {
            notAfter = maxNotAfter;
        }

        if (notAfter.after(caInfo.getNotAfter())) {
            ValidityMode mode = caInfo.getValidityMode();
            if (mode == ValidityMode.CUTOFF) {
                notAfter = caInfo.getNotAfter();
            } else if (mode == ValidityMode.STRICT) {
                throw new OperationException(ErrorCode.NOT_PERMITTED,
                        "notAfter outside of CA's validity is not permitted");
            } else if (mode == ValidityMode.LAX) {
                // permitted
            } else {
                throw new RuntimeException("should not reach here, unknown CA ValidityMode " + mode);
            } // end if(mode)
        } // end if(notAfter)

        if (certprofile.hasMidnightNotBefore() && maxNotAfter.equals(origMaxNotAfter) == false) {
            Calendar c = Calendar.getInstance(certprofile.getTimezone());
            c.setTime(new Date(notAfter.getTime() - DAY));
            c.set(Calendar.HOUR_OF_DAY, 23);
            c.set(Calendar.MINUTE, 59);
            c.set(Calendar.SECOND, 59);
            c.set(Calendar.MILLISECOND, 0);
            notAfter = c.getTime();
        }

        try {
            RdnUpperBounds.checkUpperBounds(grantedSubject);
        } catch (BadCertTemplateException e) {
            throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, e.getMessage());
        }

        X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(
                caInfo.getPublicCAInfo().getX500Subject(), caInfo.nextSerial(), notBefore, notAfter,
                grantedSubject, publicKeyInfo);

        X509CertificateInfo ret;

        try {
            X509CrlSignerEntryWrapper crlSigner = getCrlSigner();
            X509Certificate crlSignerCert = crlSigner == null ? null : crlSigner.getCert();

            ExtensionValues extensionTuples = certprofile.getExtensions(requestedSubject, extensions,
                    publicKeyInfo, caInfo.getPublicCAInfo(), crlSignerCert);
            if (extensionTuples != null) {
                for (ASN1ObjectIdentifier extensionType : extensionTuples.getExtensionTypes()) {
                    ExtensionValue extValue = extensionTuples.getExtensionValue(extensionType);
                    certBuilder.addExtension(extensionType, extValue.isCritical(), extValue.getValue());
                }
            }

            ContentSigner contentSigner;
            try {
                contentSigner = signer.borrowContentSigner();
            } catch (NoIdleSignerException e) {
                throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                        "NoIdleSignerException: " + e.getMessage());
            }

            Certificate bcCert;
            try {
                bcCert = certBuilder.build(contentSigner).toASN1Structure();
            } finally {
                signer.returnContentSigner(contentSigner);
            }

            byte[] encodedCert = bcCert.getEncoded();

            X509Certificate cert = (X509Certificate) cf
                    .engineGenerateCertificate(new ByteArrayInputStream(encodedCert));
            if (verifySignature(cert) == false) {
                throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                        "could not verify the signature of generated certificate");
            }

            X509CertWithDBCertId certWithMeta = new X509CertWithDBCertId(cert, encodedCert);

            ret = new X509CertificateInfo(certWithMeta, caInfo.getCertificate(), subjectPublicKeyData,
                    certprofileName);
            ret.setUser(user);
            ret.setRequestor(requestor);

            if (intern_publishCertificate(ret) == 1) {
                throw new OperationException(ErrorCode.SYSTEM_FAILURE, "could not save certificate");
            }
        } catch (BadCertTemplateException e) {
            throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, e.getMessage());
        } catch (Throwable t2) {
            final String message = "could not generate certificate";
            if (LOG.isErrorEnabled()) {
                LOG.error(LogUtil.buildExceptionLogFormat(message), t2.getClass().getName(), t2.getMessage());
            }
            LOG.debug(message, t2);

            throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                    t2.getClass().getName() + ": " + t2.getMessage());
        }

        if (msgBuilder.length() > 2) {
            ret.setWarningMessage(msgBuilder.substring(2));
        }

        return ret;
    } finally {
        try {
            certstore.delteCertInProcess(sha1FpPublicKey, sha1FpSubject);
        } catch (OperationException e) {
        }
    }
}

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 {/*w  ww  .  j  a v  a  2 s  .c o  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());
}