Example usage for org.bouncycastle.cert X509CertificateHolder isValidOn

List of usage examples for org.bouncycastle.cert X509CertificateHolder isValidOn

Introduction

In this page you can find the example usage for org.bouncycastle.cert X509CertificateHolder isValidOn.

Prototype

public boolean isValidOn(Date date) 

Source Link

Document

Return whether or not this certificate is valid on a particular date.

Usage

From source file:CAModulePackage.CertificateHelper.java

/**
 *
 * @param cert - X.509 Certificate to be validated.
 * @param issuingCert - X.509 Certificate that signed the other Certificate.
 * @return - True if the Certificate is valid, False otherwise.
 *///from  www.  jav  a 2 s .com
public static boolean validateCert(X509CertificateHolder cert, X509CertificateHolder issuingCert) {
    JcaContentVerifierProviderBuilder builder = new JcaContentVerifierProviderBuilder();
    ContentVerifierProvider verifier = null;
    try {
        verifier = builder.build(issuingCert);
    } catch (OperatorCreationException e) {
        e.printStackTrace();
    } catch (CertificateException e) {
        e.printStackTrace();
    }

    if (!cert.isValidOn(new Date())) {
        return false;
    }

    try {
        if (!cert.isSignatureValid(verifier)) {
            return false;
        }
    } catch (CertException e) {
        e.printStackTrace();
    }

    return true;
}

From source file:net.maritimecloud.pki.ocsp.OCSPClient.java

License:Open Source License

public CertStatus getCertificateStatus() throws OCSPValidationException {
    try {// ww w.j  ava 2  s .com
        if (null == url) {
            throw new OCSPValidationException("Certificate not validated by OCSP");
        }

        byte[] encodedOcspRequest = generateOCSPRequest(issuer, certificate.getSerialNumber()).getEncoded();

        HttpURLConnection httpConnection;
        httpConnection = (HttpURLConnection) url.openConnection();
        httpConnection.setRequestProperty("Content-Type", "application/ocsp-request");
        httpConnection.setRequestProperty("Accept", "application/ocsp-response");
        httpConnection.setDoOutput(true);

        try (DataOutputStream dataOut = new DataOutputStream(
                new BufferedOutputStream(httpConnection.getOutputStream()))) {
            dataOut.write(encodedOcspRequest);
            dataOut.flush();
        }

        InputStream in = (InputStream) httpConnection.getContent();

        if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
            throw new OCSPValidationException(
                    "Received HTTP code != 200 [" + httpConnection.getResponseCode() + "]");
        }

        OCSPResp ocspResponse = new OCSPResp(in);
        BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();

        byte[] receivedNonce = basicResponse.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnId()
                .getEncoded();
        if (!Arrays.equals(receivedNonce, sentNonce)) {
            throw new OCSPValidationException("Nonce in ocsp response does not match nonce of ocsp request");
        }

        X509CertificateHolder certHolder = basicResponse.getCerts()[0];
        if (!basicResponse
                .isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(issuer))) {
            if (!certHolder.isValidOn(Date.from(Instant.now()))) {
                throw new OCSPValidationException("Certificate is not valid today!");
            }
            // Certificate must have a Key Purpose ID for authorized responders
            if (!ExtendedKeyUsage.fromExtensions(certHolder.getExtensions())
                    .hasKeyPurposeId(KeyPurposeId.id_kp_OCSPSigning)) {
                throw new OCSPValidationException(
                        "Certificate does not contain required extension (id_kp_OCSPSigning)");
            }
            // Certificate must be issued by the same CA of the certificate that we are verifying
            if (!certHolder.isSignatureValid(
                    new JcaContentVerifierProviderBuilder().setProvider("BC").build(issuer))) {
                throw new OCSPValidationException("Certificate is not signed by the same issuer");
            }
            // Validate signature in OCSP response
            if (!basicResponse.isSignatureValid(
                    new JcaContentVerifierProviderBuilder().setProvider("BC").build(certHolder))) {
                throw new OCSPValidationException("Could not validate OCSP response!");
            }
        } else {
            if (!certHolder.isValidOn(Date.from(Instant.now()))) {
                throw new OCSPValidationException("Certificate is not valid today!");
            }
        }

        // SCEE Certificate Policy (?)
        /*if (null == certHolder.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck) || null == certHolder.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck).getExtnId()) {
        throw new OCSPValidationException("Extension id_pkix_ocsp_nocheck not found in certificate");
        }*/

        SingleResp[] responses = basicResponse.getResponses();
        if (responses[0].getCertID().getSerialNumber().equals(certificate.getSerialNumber())) {
            CertificateStatus status = responses[0].getCertStatus();
            if (status == CertificateStatus.GOOD) {
                return CertStatus.GOOD;
            } else {

                if (status instanceof RevokedStatus) {
                    revokedStatus = (RevokedStatus) status;
                    return CertStatus.REVOKED;
                } else {
                    return CertStatus.UNKNOWN;
                }
            }
        } else {
            throw new OCSPValidationException(
                    "Serial number of certificate in response ocsp does not match certificate serial number");
        }
    } catch (CertificateEncodingException | OperatorCreationException | OCSPException | IOException ex) {
        throw new OCSPValidationException("Unable to perform validation through OCSP ("
                + certificate.getSubjectX500Principal().getName() + ")", ex);
    } catch (CertException | CertificateException ex) {
        throw new OCSPValidationException("Unable to perform validation through OCSP ("
                + certificate.getSubjectX500Principal().getName() + ")", ex);
    }
}

From source file:org.poreid.verify.ocsp.OCSPClient.java

License:Open Source License

public CertStatus getCertificateStatus() throws OCSPValidationException {
    try {//w  w  w.  ja v a  2  s  .c  o  m
        if (null == url) {
            throw new OCSPValidationException("Certificado no tem validao por OCSP");
        }

        byte[] encodedOcspRequest = generateOCSPRequest(issuer, certificate.getSerialNumber()).getEncoded();

        HttpURLConnection httpConnection;
        httpConnection = (HttpURLConnection) url.openConnection();
        httpConnection.setRequestProperty("Content-Type", "application/ocsp-request");
        httpConnection.setRequestProperty("Accept", "application/ocsp-response");
        httpConnection.setDoOutput(true);

        try (DataOutputStream dataOut = new DataOutputStream(
                new BufferedOutputStream(httpConnection.getOutputStream()))) {
            dataOut.write(encodedOcspRequest);
            dataOut.flush();
        }

        InputStream in = (InputStream) httpConnection.getContent();

        if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
            throw new OCSPValidationException(
                    "Cdigo HTTP recebido != 200 [" + httpConnection.getResponseCode() + "]");
        }

        OCSPResp ocspResponse = new OCSPResp(in);
        BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();

        byte[] receivedNonce = basicResponse.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnId()
                .getEncoded();
        if (!Arrays.equals(receivedNonce, sentNonce)) {
            throw new OCSPValidationException("Nonce na resposta ocsp no coincide com nonce do pedido ocsp");
        }

        X509CertificateHolder certHolder = basicResponse.getCerts()[0];
        if (!basicResponse
                .isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(issuer))) {
            if (!certHolder.isValidOn(Date.from(Instant.now()))) {
                throw new OCSPValidationException("Certificado no  vlido na data atual");
            }
            // Certificado tem de ter uma Key Purpose ID for authorized responders
            if (!ExtendedKeyUsage.fromExtensions(certHolder.getExtensions())
                    .hasKeyPurposeId(KeyPurposeId.id_kp_OCSPSigning)) {
                throw new OCSPValidationException(
                        "Certificado no contm extenso necessria (id_kp_OCSPSigning)");
            }
            // Certificado tem de ser emitido pela mesma CA do certificado que estamos a verificar
            if (!certHolder.isSignatureValid(
                    new JcaContentVerifierProviderBuilder().setProvider("BC").build(issuer))) {
                throw new OCSPValidationException("Certificado no  assinado pelo mesmo issuer");
            }
            // Validar assinatura na resposta ocsp
            if (!basicResponse.isSignatureValid(
                    new JcaContentVerifierProviderBuilder().setProvider("BC").build(certHolder))) {
                throw new OCSPValidationException("No foi possivel validar resposta ocsp");
            }
        } else {
            if (!certHolder.isValidOn(Date.from(Instant.now()))) {
                throw new OCSPValidationException("Certificado no  vlido na data atual");
            }
        }

        // Politica de Certificados do SCEE
        if (null == certHolder.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck).getExtnId()) {
            throw new OCSPValidationException(
                    "Extenso id_pkix_ocsp_nocheck no encontrada no certificado (Politica de Certificados do SCEE)");
        }

        SingleResp[] responses = basicResponse.getResponses();
        if (responses[0].getCertID().getSerialNumber().equals(certificate.getSerialNumber())) {
            CertificateStatus status = responses[0].getCertStatus();
            if (status == CertificateStatus.GOOD) {
                return CertStatus.GOOD;
            } else {

                if (status instanceof RevokedStatus) {
                    revokedStatus = (RevokedStatus) status;
                    return CertStatus.REVOKED;
                } else {
                    return CertStatus.UNKNOWN;
                }
            }
        } else {
            throw new OCSPValidationException(
                    "Nmero de srie do certificado na resposta ocsp no coincide com nmero de srie do certificado");
        }
    } catch (CertificateEncodingException | OperatorCreationException | OCSPException | IOException ex) {
        throw new OCSPValidationException("No foi possivel efetuar a validao atravs de OCSP ("
                + certificate.getSubjectX500Principal().getName() + ")", ex);
    } catch (CertException | CertificateException ex) {
        throw new OCSPValidationException("No foi possivel efetuar a validao atravs de OCSP ("
                + certificate.getSubjectX500Principal().getName() + ")", ex);
    }
}

From source file:org.xipki.ocsp.client.shell.OCSPStatusCommand.java

License:Open Source License

@Override
protected Object processResponse(final OCSPResp response, final X509Certificate respIssuer,
        final X509Certificate issuer, final List<BigInteger> serialNumbers,
        final Map<BigInteger, byte[]> encodedCerts) throws Exception {
    BasicOCSPResp basicResp = OCSPUtils.extractBasicOCSPResp(response);

    boolean extendedRevoke = basicResp.getExtension(OCSPRequestor.id_pkix_ocsp_extendedRevoke) != null;

    SingleResp[] singleResponses = basicResp.getResponses();

    int n = singleResponses == null ? 0 : singleResponses.length;
    if (n == 0) {
        throw new CmdFailure("received no status from server");
    }//from   ww w  .ja  v a  2 s  .  co  m

    if (n != serialNumbers.size()) {
        throw new CmdFailure("received status with " + n + " single responses from server, but "
                + serialNumbers.size() + " were requested");
    }

    Date[] thisUpdates = new Date[n];
    for (int i = 0; i < n; i++) {
        thisUpdates[i] = singleResponses[i].getThisUpdate();
    }

    // check the signature if available
    if (null == basicResp.getSignature()) {
        out("response is not signed");
    } else {
        X509CertificateHolder[] responderCerts = basicResp.getCerts();
        if (responderCerts == null || responderCerts.length < 1) {
            throw new CmdFailure("no responder certificate is contained in the response");
        }

        X509CertificateHolder respSigner = responderCerts[0];
        boolean validOn = true;
        for (Date thisUpdate : thisUpdates) {
            validOn = respSigner.isValidOn(thisUpdate);
            if (validOn == false) {
                throw new CmdFailure("responder certificate is not valid on " + thisUpdate);
            }
        }

        if (validOn) {
            PublicKey responderPubKey = KeyUtil.generatePublicKey(respSigner.getSubjectPublicKeyInfo());
            ContentVerifierProvider cvp = KeyUtil.getContentVerifierProvider(responderPubKey);
            boolean sigValid = basicResp.isSignatureValid(cvp);

            if (sigValid == false) {
                throw new CmdFailure("response is equipped with invalid signature");
            }

            // verify the OCSPResponse signer
            if (respIssuer != null) {
                boolean certValid = true;
                X509Certificate jceRespSigner = new X509CertificateObject(respSigner.toASN1Structure());
                if (X509Util.issues(respIssuer, jceRespSigner)) {
                    try {
                        jceRespSigner.verify(respIssuer.getPublicKey());
                    } catch (SignatureException e) {
                        certValid = false;
                    }
                }

                if (certValid == false) {
                    throw new CmdFailure(
                            "response is equipped with valid signature but the OCSP signer is not trusted");
                }
            } else {
                out("response is equipped with valid signature");
            }
        }

        if (verbose.booleanValue()) {
            out("responder is " + X509Util.getRFC4519Name(responderCerts[0].getSubject()));
        }
    }

    for (int i = 0; i < n; i++) {
        if (n > 1) {
            out("---------------------------- " + i + " ----------------------------");
        }
        SingleResp singleResp = singleResponses[i];
        BigInteger serialNumber = singleResp.getCertID().getSerialNumber();

        CertificateStatus singleCertStatus = singleResp.getCertStatus();

        String status;
        if (singleCertStatus == null) {
            status = "good";
        } else if (singleCertStatus instanceof RevokedStatus) {
            RevokedStatus revStatus = (RevokedStatus) singleCertStatus;
            Date revTime = revStatus.getRevocationTime();
            Date invTime = null;
            Extension ext = singleResp.getExtension(Extension.invalidityDate);
            if (ext != null) {
                invTime = ASN1GeneralizedTime.getInstance(ext.getParsedValue()).getDate();
            }

            if (revStatus.hasRevocationReason()) {
                int reason = revStatus.getRevocationReason();
                if (extendedRevoke && reason == CRLReason.CERTIFICATE_HOLD.getCode()
                        && revTime.getTime() == 0) {
                    status = "unknown (RFC6960)";
                } else {
                    StringBuilder sb = new StringBuilder("revoked, reason = ");
                    sb.append(CRLReason.forReasonCode(reason).getDescription());
                    sb.append(", revocationTime = ");
                    sb.append(revTime);
                    if (invTime != null) {
                        sb.append(", invalidityTime = ");
                        sb.append(invTime);
                    }
                    status = sb.toString();
                }
            } else {
                status = "revoked, no reason, revocationTime = " + revTime;
            }
        } else if (singleCertStatus instanceof UnknownStatus) {
            status = "unknown (RFC2560)";
        } else {
            status = "ERROR";
        }

        StringBuilder msg = new StringBuilder();
        msg.append("serialNumber: ").append(serialNumber);
        msg.append("\nCertificate status: ").append(status);

        if (verbose.booleanValue()) {
            msg.append("\nthisUpdate: " + singleResp.getThisUpdate());
            msg.append("\nnextUpdate: " + singleResp.getNextUpdate());

            Extension extension = singleResp.getExtension(ISISMTTObjectIdentifiers.id_isismtt_at_certHash);
            if (extension != null) {
                msg.append("\nCertHash is provided:\n");
                ASN1Encodable extensionValue = extension.getParsedValue();
                CertHash certHash = CertHash.getInstance(extensionValue);
                ASN1ObjectIdentifier hashAlgOid = certHash.getHashAlgorithm().getAlgorithm();
                byte[] hashValue = certHash.getCertificateHash();

                msg.append("\tHash algo : ").append(hashAlgOid.getId()).append("\n");
                msg.append("\tHash value: ").append(Hex.toHexString(hashValue)).append("\n");

                if (encodedCerts != null) {
                    byte[] encodedCert = encodedCerts.get(serialNumber);
                    MessageDigest md = MessageDigest.getInstance(hashAlgOid.getId());
                    byte[] expectedHashValue = md.digest(encodedCert);
                    if (Arrays.equals(expectedHashValue, hashValue)) {
                        msg.append("\tThis matches the requested certificate");
                    } else {
                        msg.append("\tThis differs from the requested certificate");
                    }
                }
            }

            extension = singleResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_archive_cutoff);
            if (extension != null) {
                ASN1Encodable extensionValue = extension.getParsedValue();
                ASN1GeneralizedTime time = ASN1GeneralizedTime.getInstance(extensionValue);
                msg.append("\nArchive-CutOff: ");
                msg.append(time.getTimeString());
            }

            AlgorithmIdentifier sigAlg = basicResp.getSignatureAlgorithmID();
            if (sigAlg == null) {
                msg.append(("\nresponse is not signed"));
            } else {
                String sigAlgName = AlgorithmUtil.getSignatureAlgoName(sigAlg);
                if (sigAlgName == null) {
                    sigAlgName = "unknown";
                }
                msg.append("\nresponse is signed with ").append(sigAlgName);
            }

            // extensions
            msg.append("\nExtensions: ");

            List<?> extensionOIDs = basicResp.getExtensionOIDs();
            if (extensionOIDs == null || extensionOIDs.size() == 0) {
                msg.append("-");
            } else {
                int size = extensionOIDs.size();
                for (int j = 0; j < size; j++) {
                    ASN1ObjectIdentifier extensionOID = (ASN1ObjectIdentifier) extensionOIDs.get(j);
                    String name = extensionOidNameMap.get(extensionOID);
                    msg.append(name == null ? extensionOID.getId() : name);
                    if (j != size - 1) {
                        msg.append(", ");
                    }
                }
            }
        }

        out(msg.toString());
    }
    out("");

    return null;
}

From source file:org.xipki.ocsp.qa.impl.OcspQAImpl.java

License:Open Source License

@Override
public ValidationResult checkOCSP(final OCSPResp response, final X509Certificate issuer,
        final List<BigInteger> serialNumbers, final Map<BigInteger, byte[]> encodedCerts,
        final OcspError expectedOcspError, final Map<BigInteger, OcspCertStatus> expectedOcspStatuses,
        final OcspResponseOption responseOption) {
    List<ValidationIssue> resultIssues = new LinkedList<ValidationIssue>();

    int status = response.getStatus();

    // Response status
    {/*from w  w  w. jav  a  2s  . c om*/
        ValidationIssue issue = new ValidationIssue("OCSP.STATUS", "response.status");
        resultIssues.add(issue);
        if (expectedOcspError != null) {
            if (status != expectedOcspError.getStatus()) {
                issue.setFailureMessage(
                        "is '" + status + "', but expected '" + expectedOcspError.getStatus() + "'");
            }
        } else {
            if (status != 0) {
                issue.setFailureMessage("is '" + status + "', but expected '0'");
            }
        }
    }

    if (status != 0) {
        return new ValidationResult(resultIssues);
    }

    ValidationIssue encodingIssue = new ValidationIssue("OCSP.ENCODING", "response encoding");
    resultIssues.add(encodingIssue);

    BasicOCSPResp basicResp;
    {
        try {
            basicResp = (BasicOCSPResp) response.getResponseObject();
        } catch (OCSPException e) {
            encodingIssue.setFailureMessage(e.getMessage());
            return new ValidationResult(resultIssues);
        }
    }

    SingleResp[] singleResponses = basicResp.getResponses();

    {
        ValidationIssue issue = new ValidationIssue("OCSP.RESPONSES.NUM", "number of single responses");
        resultIssues.add(issue);

        int n = singleResponses == null ? 0 : singleResponses.length;
        if (n == 0) {
            issue.setFailureMessage("received no status from server");
        } else if (n != serialNumbers.size()) {
            issue.setFailureMessage("is '" + n + "', but expected '" + serialNumbers.size() + "'");
        }

        if (issue.isFailed()) {
            return new ValidationResult(resultIssues);
        }
    }

    {
        boolean hasSignature = basicResp.getSignature() != null;

        {
            // check the signature if available
            ValidationIssue issue = new ValidationIssue("OCSP.SIG", "signature presence");
            resultIssues.add(issue);
            if (hasSignature == false) {
                issue.setFailureMessage("response is not signed");
            }
        }

        if (hasSignature) {
            {
                // signature algorithm
                ValidationIssue issue = new ValidationIssue("OCSP.SIG.ALG", "signature algorithm");
                resultIssues.add(issue);

                String expectedSigalgo = responseOption.getSignatureAlgName();
                if (expectedSigalgo != null) {
                    AlgorithmIdentifier sigAlg = basicResp.getSignatureAlgorithmID();
                    try {
                        String sigAlgName = AlgorithmUtil.getSignatureAlgoName(sigAlg);
                        if (AlgorithmUtil.equalsAlgoName(sigAlgName, expectedSigalgo) == false) {
                            issue.setFailureMessage(
                                    "is '" + sigAlgName + "', but expected '" + expectedSigalgo + "'");
                        }
                    } catch (NoSuchAlgorithmException e) {
                        issue.setFailureMessage("could not extract the signature algorithm");
                    }
                }
            }

            // signer certificate
            ValidationIssue sigSignerCertIssue = new ValidationIssue("OCSP.SIGNERCERT", "signer certificate");
            resultIssues.add(sigSignerCertIssue);

            // signature validation
            ValidationIssue sigValIssue = new ValidationIssue("OCSP.SIG.VALIDATION", "signature validation");
            resultIssues.add(sigValIssue);

            X509CertificateHolder[] responderCerts = basicResp.getCerts();
            if (responderCerts == null || responderCerts.length < 1) {
                sigSignerCertIssue.setFailureMessage("No responder certificate is contained in the response");
                sigValIssue.setFailureMessage("could not find certificate to validate signature");
            } else {
                X509CertificateHolder respSigner = responderCerts[0];

                ValidationIssue issue = new ValidationIssue("OCSP.SIGNERCERT.TRUST",
                        "signer certificate validation");
                resultIssues.add(issue);

                for (int i = 0; i < singleResponses.length; i++) {
                    SingleResp singleResp = singleResponses[i];
                    if (respSigner.isValidOn(singleResp.getThisUpdate()) == false) {
                        issue.setFailureMessage("responder certificate is not valid on the thisUpdate[ " + i
                                + "]" + singleResp.getThisUpdate());
                    }
                }

                if (issue.isFailed() == false) {
                    X509Certificate respIssuer = responseOption.getRespIssuer();
                    if (respIssuer != null) {
                        X509Certificate jceRespSigner;
                        try {
                            jceRespSigner = new X509CertificateObject(respSigner.toASN1Structure());
                            if (X509Util.issues(respIssuer, jceRespSigner)) {
                                jceRespSigner.verify(respIssuer.getPublicKey());
                            } else {
                                issue.setFailureMessage("responder signer is not trusted");
                            }
                        } catch (Exception e) {
                            issue.setFailureMessage("responder signer is not trusted");
                        }
                    }
                }

                try {
                    PublicKey responderPubKey = KeyUtil.generatePublicKey(respSigner.getSubjectPublicKeyInfo());
                    ContentVerifierProvider cvp = KeyUtil.getContentVerifierProvider(responderPubKey);
                    boolean sigValid = basicResp.isSignatureValid(cvp);
                    if (sigValid == false) {
                        sigValIssue.setFailureMessage("signature is invalid");
                    }
                } catch (Exception e) {
                    sigValIssue.setFailureMessage("error while validating signature");
                }
            }
        }
    }

    {
        // nonce
        Extension nonceExtn = basicResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
        resultIssues.add(checkOccurrence("OCSP.NONCE", nonceExtn, responseOption.getNonceOccurrence()));
    }

    boolean extendedRevoke = basicResp.getExtension(id_pkix_ocsp_extendedRevoke) != null;

    for (int i = 0; i < singleResponses.length; i++) {
        SingleResp singleResp = singleResponses[i];
        BigInteger serialNumber = singleResp.getCertID().getSerialNumber();
        OcspCertStatus expectedStatus = expectedOcspStatuses.get(serialNumber);

        byte[] encodedCert = null;
        if (encodedCerts != null) {
            encodedCert = encodedCerts.get(serialNumber);
        }

        List<ValidationIssue> issues = checkSingleCert(i, singleResp, expectedStatus, encodedCert,
                extendedRevoke, responseOption.getNextUpdateOccurrence(),
                responseOption.getCerthashOccurrence(), responseOption.getCerthashAlgId());
        resultIssues.addAll(issues);
    }

    return new ValidationResult(resultIssues);
}

From source file:org.xipki.pki.ocsp.client.shell.OcspStatusCmd.java

License:Open Source License

@Override
protected Object processResponse(final OCSPResp response, final X509Certificate respIssuer,
        final IssuerHash issuerHash, final List<BigInteger> serialNumbers,
        final Map<BigInteger, byte[]> encodedCerts) throws Exception {
    ParamUtil.requireNonNull("response", response);
    ParamUtil.requireNonNull("issuerHash", issuerHash);
    ParamUtil.requireNonNull("serialNumbers", serialNumbers);

    BasicOCSPResp basicResp = OcspUtils.extractBasicOcspResp(response);

    boolean extendedRevoke = basicResp.getExtension(ObjectIdentifiers.id_pkix_ocsp_extendedRevoke) != null;

    SingleResp[] singleResponses = basicResp.getResponses();

    if (singleResponses == null || singleResponses.length == 0) {
        throw new CmdFailure("received no status from server");
    }//  www  .j  a v  a2  s  .  c  om

    final int n = singleResponses.length;
    if (n != serialNumbers.size()) {
        throw new CmdFailure("received status with " + n + " single responses from server, but "
                + serialNumbers.size() + " were requested");
    }

    Date[] thisUpdates = new Date[n];
    for (int i = 0; i < n; i++) {
        thisUpdates[i] = singleResponses[i].getThisUpdate();
    }

    // check the signature if available
    if (null == basicResp.getSignature()) {
        println("response is not signed");
    } else {
        X509CertificateHolder[] responderCerts = basicResp.getCerts();
        if (responderCerts == null || responderCerts.length < 1) {
            throw new CmdFailure("no responder certificate is contained in the response");
        }

        ResponderID respId = basicResp.getResponderId().toASN1Primitive();
        X500Name respIdByName = respId.getName();
        byte[] respIdByKey = respId.getKeyHash();

        X509CertificateHolder respSigner = null;
        for (X509CertificateHolder cert : responderCerts) {
            if (respIdByName != null) {
                if (cert.getSubject().equals(respIdByName)) {
                    respSigner = cert;
                }
            } else {
                byte[] spkiSha1 = HashAlgoType.SHA1
                        .hash(cert.getSubjectPublicKeyInfo().getPublicKeyData().getBytes());
                if (Arrays.equals(respIdByKey, spkiSha1)) {
                    respSigner = cert;
                }
            }

            if (respSigner != null) {
                break;
            }
        }

        if (respSigner == null) {
            throw new CmdFailure("no responder certificate match the ResponderId");
        }

        boolean validOn = true;
        for (Date thisUpdate : thisUpdates) {
            validOn = respSigner.isValidOn(thisUpdate);
            if (!validOn) {
                throw new CmdFailure("responder certificate is not valid on " + thisUpdate);
            }
        }

        if (validOn) {
            PublicKey responderPubKey = KeyUtil.generatePublicKey(respSigner.getSubjectPublicKeyInfo());
            ContentVerifierProvider cvp = securityFactory.getContentVerifierProvider(responderPubKey);
            boolean sigValid = basicResp.isSignatureValid(cvp);

            if (!sigValid) {
                throw new CmdFailure("response is equipped with invalid signature");
            }

            // verify the OCSPResponse signer
            if (respIssuer != null) {
                boolean certValid = true;
                X509Certificate jceRespSigner = X509Util.toX509Cert(respSigner.toASN1Structure());
                if (X509Util.issues(respIssuer, jceRespSigner)) {
                    try {
                        jceRespSigner.verify(respIssuer.getPublicKey());
                    } catch (SignatureException ex) {
                        certValid = false;
                    }
                }

                if (!certValid) {
                    throw new CmdFailure("response is equipped with valid signature but the"
                            + " OCSP signer is not trusted");
                }
            } else {
                println("response is equipped with valid signature");
            } // end if(respIssuer)
        } // end if(validOn)

        if (verbose.booleanValue()) {
            println("responder is " + X509Util.getRfc4519Name(responderCerts[0].getSubject()));
        }
    } // end if

    for (int i = 0; i < n; i++) {
        if (n > 1) {
            println("---------------------------- " + i + "----------------------------");
        }
        SingleResp singleResp = singleResponses[i];
        CertificateStatus singleCertStatus = singleResp.getCertStatus();

        String status;
        if (singleCertStatus == null) {
            status = "good";
        } else if (singleCertStatus instanceof RevokedStatus) {
            RevokedStatus revStatus = (RevokedStatus) singleCertStatus;
            Date revTime = revStatus.getRevocationTime();
            Date invTime = null;
            Extension ext = singleResp.getExtension(Extension.invalidityDate);
            if (ext != null) {
                invTime = ASN1GeneralizedTime.getInstance(ext.getParsedValue()).getDate();
            }

            if (revStatus.hasRevocationReason()) {
                int reason = revStatus.getRevocationReason();
                if (extendedRevoke && reason == CrlReason.CERTIFICATE_HOLD.getCode()
                        && revTime.getTime() == 0) {
                    status = "unknown (RFC6960)";
                } else {
                    StringBuilder sb = new StringBuilder("revoked, reason = ");
                    sb.append(CrlReason.forReasonCode(reason).getDescription());
                    sb.append(", revocationTime = ").append(revTime);
                    if (invTime != null) {
                        sb.append(", invalidityTime = ").append(invTime);
                    }
                    status = sb.toString();
                }
            } else {
                status = "revoked, no reason, revocationTime = " + revTime;
            }
        } else if (singleCertStatus instanceof UnknownStatus) {
            status = "unknown (RFC2560)";
        } else {
            status = "ERROR";
        }

        StringBuilder msg = new StringBuilder();

        CertificateID certId = singleResp.getCertID();
        HashAlgoType hashAlgo = HashAlgoType.getNonNullHashAlgoType(certId.getHashAlgOID());
        boolean issuerMatch = issuerHash.match(hashAlgo, certId.getIssuerNameHash(), certId.getIssuerKeyHash());
        BigInteger serialNumber = certId.getSerialNumber();

        msg.append("issuer matched: ").append(issuerMatch);
        msg.append("\nserialNumber: ").append(LogUtil.formatCsn(serialNumber));
        msg.append("\nCertificate status: ").append(status);

        if (verbose.booleanValue()) {
            msg.append("\nthisUpdate: ").append(singleResp.getThisUpdate());
            msg.append("\nnextUpdate: ").append(singleResp.getNextUpdate());

            Extension extension = singleResp.getExtension(ISISMTTObjectIdentifiers.id_isismtt_at_certHash);
            if (extension != null) {
                msg.append("\nCertHash is provided:\n");
                ASN1Encodable extensionValue = extension.getParsedValue();
                CertHash certHash = CertHash.getInstance(extensionValue);
                ASN1ObjectIdentifier hashAlgOid = certHash.getHashAlgorithm().getAlgorithm();
                byte[] hashValue = certHash.getCertificateHash();

                msg.append("\tHash algo : ").append(hashAlgOid.getId()).append("\n");
                msg.append("\tHash value: ").append(Hex.toHexString(hashValue)).append("\n");

                if (encodedCerts != null) {
                    byte[] encodedCert = encodedCerts.get(serialNumber);
                    MessageDigest md = MessageDigest.getInstance(hashAlgOid.getId());
                    byte[] expectedHashValue = md.digest(encodedCert);
                    if (Arrays.equals(expectedHashValue, hashValue)) {
                        msg.append("\tThis matches the requested certificate");
                    } else {
                        msg.append("\tThis differs from the requested certificate");
                    }
                }
            } // end if (extension != null)

            extension = singleResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_archive_cutoff);
            if (extension != null) {
                ASN1Encodable extensionValue = extension.getParsedValue();
                ASN1GeneralizedTime time = ASN1GeneralizedTime.getInstance(extensionValue);
                msg.append("\nArchive-CutOff: ");
                msg.append(time.getTimeString());
            }

            AlgorithmIdentifier sigAlg = basicResp.getSignatureAlgorithmID();
            if (sigAlg == null) {
                msg.append(("\nresponse is not signed"));
            } else {
                String sigAlgName = AlgorithmUtil.getSignatureAlgoName(sigAlg);
                if (sigAlgName == null) {
                    sigAlgName = "unknown";
                }
                msg.append("\nresponse is signed with ").append(sigAlgName);
            }

            // extensions
            msg.append("\nExtensions: ");

            List<?> extensionOids = basicResp.getExtensionOIDs();
            if (extensionOids == null || extensionOids.size() == 0) {
                msg.append("-");
            } else {
                int size = extensionOids.size();
                for (int j = 0; j < size; j++) {
                    ASN1ObjectIdentifier extensionOid = (ASN1ObjectIdentifier) extensionOids.get(j);
                    String name = EXTENSION_OIDNAME_MAP.get(extensionOid);
                    if (name == null) {
                        msg.append(extensionOid.getId());
                    } else {
                        msg.append(name);
                    }
                    if (j != size - 1) {
                        msg.append(", ");
                    }
                }
            }
        } // end if (verbose.booleanValue())

        println(msg.toString());
    } // end for
    println("");

    return null;
}

From source file:org.xipki.pki.ocsp.qa.OcspQa.java

License:Open Source License

public ValidationResult checkOcsp(final OCSPResp response, final IssuerHash issuerHash,
        final List<BigInteger> serialNumbers, final Map<BigInteger, byte[]> encodedCerts,
        final OcspError expectedOcspError, final Map<BigInteger, OcspCertStatus> expectedOcspStatuses,
        final OcspResponseOption responseOption) {
    ParamUtil.requireNonNull("response", response);
    ParamUtil.requireNonEmpty("serialNumbers", serialNumbers);
    ParamUtil.requireNonEmpty("expectedOcspStatuses", expectedOcspStatuses);
    ParamUtil.requireNonNull("responseOption", responseOption);

    List<ValidationIssue> resultIssues = new LinkedList<ValidationIssue>();

    int status = response.getStatus();

    // Response status
    ValidationIssue issue = new ValidationIssue("OCSP.STATUS", "response.status");
    resultIssues.add(issue);/*  www.  j a va2 s .c  o  m*/
    if (expectedOcspError != null) {
        if (status != expectedOcspError.getStatus()) {
            issue.setFailureMessage(
                    "is '" + status + "', but expected '" + expectedOcspError.getStatus() + "'");
        }
    } else {
        if (status != 0) {
            issue.setFailureMessage("is '" + status + "', but expected '0'");
        }
    }

    if (status != 0) {
        return new ValidationResult(resultIssues);
    }

    ValidationIssue encodingIssue = new ValidationIssue("OCSP.ENCODING", "response encoding");
    resultIssues.add(encodingIssue);

    BasicOCSPResp basicResp;
    try {
        basicResp = (BasicOCSPResp) response.getResponseObject();
    } catch (OCSPException ex) {
        encodingIssue.setFailureMessage(ex.getMessage());
        return new ValidationResult(resultIssues);
    }

    SingleResp[] singleResponses = basicResp.getResponses();

    issue = new ValidationIssue("OCSP.RESPONSES.NUM", "number of single responses");
    resultIssues.add(issue);

    if (singleResponses == null || singleResponses.length == 0) {
        issue.setFailureMessage("received no status from server");
        return new ValidationResult(resultIssues);
    }

    final int n = singleResponses.length;
    if (n != serialNumbers.size()) {
        issue.setFailureMessage("is '" + n + "', but expected '" + serialNumbers.size() + "'");
        return new ValidationResult(resultIssues);
    }

    boolean hasSignature = basicResp.getSignature() != null;

    // check the signature if available
    issue = new ValidationIssue("OCSP.SIG", "signature presence");
    resultIssues.add(issue);
    if (!hasSignature) {
        issue.setFailureMessage("response is not signed");
    }

    if (hasSignature) {
        // signature algorithm
        issue = new ValidationIssue("OCSP.SIG.ALG", "signature algorithm");
        resultIssues.add(issue);

        String expectedSigalgo = responseOption.getSignatureAlgName();
        if (expectedSigalgo != null) {
            AlgorithmIdentifier sigAlg = basicResp.getSignatureAlgorithmID();
            try {
                String sigAlgName = AlgorithmUtil.getSignatureAlgoName(sigAlg);
                if (!AlgorithmUtil.equalsAlgoName(sigAlgName, expectedSigalgo)) {
                    issue.setFailureMessage("is '" + sigAlgName + "', but expected '" + expectedSigalgo + "'");
                }
            } catch (NoSuchAlgorithmException ex) {
                issue.setFailureMessage("could not extract the signature algorithm");
            }
        } // end if (expectedSigalgo != null)

        // signer certificate
        ValidationIssue sigSignerCertIssue = new ValidationIssue("OCSP.SIGNERCERT", "signer certificate");
        resultIssues.add(sigSignerCertIssue);

        // signature validation
        ValidationIssue sigValIssue = new ValidationIssue("OCSP.SIG.VALIDATION", "signature validation");
        resultIssues.add(sigValIssue);

        X509CertificateHolder respSigner = null;

        X509CertificateHolder[] responderCerts = basicResp.getCerts();
        if (responderCerts == null || responderCerts.length < 1) {
            sigSignerCertIssue.setFailureMessage("no responder certificate is contained in the response");
            sigValIssue.setFailureMessage("could not find certificate to validate signature");
        } else {
            ResponderID respId = basicResp.getResponderId().toASN1Primitive();
            X500Name respIdByName = respId.getName();
            byte[] respIdByKey = respId.getKeyHash();

            for (X509CertificateHolder cert : responderCerts) {
                if (respIdByName != null) {
                    if (cert.getSubject().equals(respIdByName)) {
                        respSigner = cert;
                    }
                } else {
                    byte[] spkiSha1 = HashAlgoType.SHA1
                            .hash(cert.getSubjectPublicKeyInfo().getPublicKeyData().getBytes());
                    if (Arrays.equals(respIdByKey, spkiSha1)) {
                        respSigner = cert;
                    }
                }

                if (respSigner != null) {
                    break;
                }
            }

            if (respSigner == null) {
                sigSignerCertIssue.setFailureMessage("no responder certificate match the ResponderId");
                sigValIssue.setFailureMessage(
                        "could not find certificate matching the" + " ResponderId to validate signature");
            }
        }

        if (respSigner != null) {
            issue = new ValidationIssue("OCSP.SIGNERCERT.TRUST", "signer certificate validation");
            resultIssues.add(issue);

            for (int i = 0; i < singleResponses.length; i++) {
                SingleResp singleResp = singleResponses[i];
                if (!respSigner.isValidOn(singleResp.getThisUpdate())) {
                    issue.setFailureMessage(
                            String.format("responder certificate is not valid on the thisUpdate[%d]: %s", i,
                                    singleResp.getThisUpdate()));
                }
            } // end for

            X509Certificate respIssuer = responseOption.getRespIssuer();
            if (!issue.isFailed() && respIssuer != null) {
                X509Certificate jceRespSigner;
                try {
                    jceRespSigner = X509Util.toX509Cert(respSigner.toASN1Structure());
                    if (X509Util.issues(respIssuer, jceRespSigner)) {
                        jceRespSigner.verify(respIssuer.getPublicKey());
                    } else {
                        issue.setFailureMessage("responder signer is not trusted");
                    }
                } catch (Exception ex) {
                    issue.setFailureMessage("responder signer is not trusted");
                }
            }

            try {
                PublicKey responderPubKey = KeyUtil.generatePublicKey(respSigner.getSubjectPublicKeyInfo());
                ContentVerifierProvider cvp = securityFactory.getContentVerifierProvider(responderPubKey);
                boolean sigValid = basicResp.isSignatureValid(cvp);
                if (!sigValid) {
                    sigValIssue.setFailureMessage("signature is invalid");
                }
            } catch (Exception ex) {
                sigValIssue.setFailureMessage("could not validate signature");
            }
        } // end if
    } // end if (hasSignature)

    // nonce
    Extension nonceExtn = basicResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
    resultIssues.add(checkOccurrence("OCSP.NONCE", nonceExtn, responseOption.getNonceOccurrence()));

    boolean extendedRevoke = basicResp.getExtension(ObjectIdentifiers.id_pkix_ocsp_extendedRevoke) != null;

    for (int i = 0; i < singleResponses.length; i++) {
        SingleResp singleResp = singleResponses[i];
        BigInteger serialNumber = singleResp.getCertID().getSerialNumber();
        OcspCertStatus expectedStatus = expectedOcspStatuses.get(serialNumber);

        byte[] encodedCert = null;
        if (encodedCerts != null) {
            encodedCert = encodedCerts.get(serialNumber);
        }

        List<ValidationIssue> issues = checkSingleCert(i, singleResp, issuerHash, expectedStatus, encodedCert,
                extendedRevoke, responseOption.getNextUpdateOccurrence(),
                responseOption.getCerthashOccurrence(), responseOption.getCerthashAlgId());
        resultIssues.addAll(issues);
    } // end for

    return new ValidationResult(resultIssues);
}