Example usage for org.bouncycastle.cert.ocsp SingleResp getExtension

List of usage examples for org.bouncycastle.cert.ocsp SingleResp getExtension

Introduction

In this page you can find the example usage for org.bouncycastle.cert.ocsp SingleResp getExtension.

Prototype

public Extension getExtension(ASN1ObjectIdentifier oid) 

Source Link

Usage

From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpTest.java

License:Open Source License

/**
 * This test tests that the OCSP response contains the extension "id_pkix_ocsp_archive_cutoff" if "ocsp.expiredcert.retentionperiod" 
 * is set in the condfiguration file//from   w w  w .ja va  2s. c om
 * 
 * @throws Exception
 */
@Test
public void testExpiredCertArchiveCutoffExtension() throws Exception {

    final String username = "expiredCertUsername";
    String cpname = "ValidityCertProfile";
    String eepname = "ValidityEEProfile";
    X509Certificate xcert = null;

    CertificateProfileSessionRemote certProfSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(CertificateProfileSessionRemote.class);
    EndEntityProfileSessionRemote eeProfSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(EndEntityProfileSessionRemote.class);

    try {
        if (certProfSession.getCertificateProfile(cpname) == null) {
            final CertificateProfile cp = new CertificateProfile(
                    CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER);
            cp.setAllowValidityOverride(true);
            try {
                certProfSession.addCertificateProfile(admin, cpname, cp);
            } catch (CertificateProfileExistsException e) {
                log.error("Certificate profile exists: ", e);
            }
        }
        final int cpId = certProfSession.getCertificateProfileId(cpname);
        if (eeProfSession.getEndEntityProfile(eepname) == null) {
            final EndEntityProfile eep = new EndEntityProfile(true);
            eep.setValue(EndEntityProfile.AVAILCERTPROFILES, 0, "" + cpId);
            try {
                eeProfSession.addEndEntityProfile(admin, eepname, eep);
            } catch (EndEntityProfileExistsException e) {
                log.error("Could not create end entity profile.", e);
            }
        }
        final int eepId = eeProfSession.getEndEntityProfileId(eepname);

        if (!endEntityManagementSession.existsUser(username)) {
            endEntityManagementSession.addUser(admin, username, "foo123", "CN=expiredCertUsername", null,
                    "ocsptest@anatom.se", false, eepId, cpId, EndEntityTypes.ENDUSER.toEndEntityType(),
                    SecConst.TOKEN_SOFT_PEM, 0, caid);
            log.debug("created user: expiredCertUsername, foo123, CN=expiredCertUsername");
        } else {
            log.debug("User expiredCertUsername already exists.");
            EndEntityInformation userData = new EndEntityInformation(username, "CN=expiredCertUsername", caid,
                    null, "ocsptest@anatom.se", EndEntityConstants.STATUS_NEW,
                    EndEntityTypes.ENDUSER.toEndEntityType(), eepId, cpId, null, null, SecConst.TOKEN_SOFT_PEM,
                    0, null);
            userData.setPassword("foo123");
            endEntityManagementSession.changeUser(admin, userData, false);
            log.debug("Reset status to NEW");
        }

        // Generate certificate for the new user
        KeyPair keys = KeyTools.genKeys("512", "RSA");
        long now = (new Date()).getTime();
        long notAfter = now + 1000;
        xcert = (X509Certificate) signSession.createCertificate(admin, username, "foo123",
                new PublicKeyWrapper(keys.getPublic()), -1, new Date(), new Date(notAfter));
        assertNotNull("Failed to create new certificate", xcert);

        Thread.sleep(2000L); // wait for the certificate to expire

        // -------- Testing with default config value

        OCSPReqBuilder gen = new OCSPReqBuilder();
        gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), cacert,
                xcert.getSerialNumber()));
        OCSPReq req = gen.build();
        BasicOCSPResp response = helper.sendOCSPGet(req.getEncoded(), null, OCSPRespBuilder.SUCCESSFUL, 200);
        assertNotNull("Could not retrieve response, test could not continue.", response);
        SingleResp resp = response.getResponses()[0];
        Extension singleExtension = resp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_archive_cutoff);
        assertNotNull("No extension sent with reply", singleExtension);

        ASN1GeneralizedTime extvalue = ASN1GeneralizedTime.getInstance(singleExtension.getParsedValue());
        long expectedValue = (new Date()).getTime() - (31536000L * 1000);
        long actualValue = extvalue.getDate().getTime();
        long diff = expectedValue - actualValue;
        assertTrue("Wrong archive cutoff value.", diff < 60000);

        // -------- Send a request where id_pkix_ocsp_archive_cutoff SHOULD NOT be used
        // set ocsp configuration
        Map<String, String> map = new HashMap<String, String>();
        map.put(OcspConfiguration.EXPIREDCERT_RETENTIONPERIOD, "-1");
        this.helper.alterConfig(map);

        gen = new OCSPReqBuilder();
        gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), cacert,
                xcert.getSerialNumber()));
        req = gen.build();
        response = helper.sendOCSPGet(req.getEncoded(), null, OCSPRespBuilder.SUCCESSFUL, 200);
        assertNotNull("Could not retrieve response, test could not continue.", response);
        resp = response.getResponses()[0];
        singleExtension = resp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_archive_cutoff);
        assertNull("The wrong extension was sent with reply", singleExtension);

        // ------------ Send a request where id_pkix_ocsp_archive_cutoff SHOULD be used
        // set ocsp configuration
        map = new HashMap<String, String>();
        map.put(OcspConfiguration.EXPIREDCERT_RETENTIONPERIOD, "63072000"); // 2 years
        this.helper.alterConfig(map);

        gen = new OCSPReqBuilder();
        gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), cacert,
                xcert.getSerialNumber()));
        req = gen.build();
        response = helper.sendOCSPGet(req.getEncoded(), null, OCSPRespBuilder.SUCCESSFUL, 200);
        assertNotNull("Could not retrieve response, test could not continue.", response);
        resp = response.getResponses()[0];
        singleExtension = resp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_archive_cutoff);
        assertNotNull("No extension sent with reply", singleExtension);

        extvalue = ASN1GeneralizedTime.getInstance(singleExtension.getParsedValue());
        expectedValue = (new Date()).getTime() - (63072000L * 1000);
        actualValue = extvalue.getDate().getTime();
        diff = expectedValue - actualValue;
        assertTrue("Wrong archive cutoff value.", diff < 60000);

    } finally {
        endEntityManagementSession.revokeAndDeleteUser(admin, username, CRLReason.unspecified);
        eeProfSession.removeEndEntityProfile(admin, eepname);
        certProfSession.removeCertificateProfile(admin, cpname);
    }
}

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");
    }//  w  w w  .ja va2 s . c  o 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

private List<ValidationIssue> checkSingleCert(final int index, final SingleResp singleResp,
        final OcspCertStatus expectedStatus, final byte[] encodedCert, final boolean extendedRevoke,
        final Occurrence nextupdateOccurrence, final Occurrence certhashOccurrence,
        final ASN1ObjectIdentifier certhashAlg) {
    List<ValidationIssue> issues = new LinkedList<>();
    {/*from   w  ww.  j av  a  2 s  .  co  m*/
        // status
        ValidationIssue issue = new ValidationIssue("OCSP.RESPONSE." + index + ".STATUS", "certificate status");
        issues.add(issue);

        CertificateStatus singleCertStatus = singleResp.getCertStatus();

        OcspCertStatus status = null;
        if (singleCertStatus == null) {
            status = OcspCertStatus.good;
        } else if (singleCertStatus instanceof RevokedStatus) {
            RevokedStatus revStatus = (RevokedStatus) singleCertStatus;
            Date revTime = revStatus.getRevocationTime();

            if (revStatus.hasRevocationReason()) {
                int reason = revStatus.getRevocationReason();
                if (extendedRevoke && reason == CRLReason.CERTIFICATE_HOLD.getCode()
                        && revTime.getTime() == 0) {
                    status = OcspCertStatus.unknown;
                } else {
                    CRLReason revocationReason = CRLReason.forReasonCode(reason);
                    switch (revocationReason) {
                    case UNSPECIFIED:
                        status = OcspCertStatus.unspecified;
                        break;
                    case KEY_COMPROMISE:
                        status = OcspCertStatus.keyCompromise;
                        break;
                    case CA_COMPROMISE:
                        status = OcspCertStatus.cACompromise;
                        break;
                    case AFFILIATION_CHANGED:
                        status = OcspCertStatus.affiliationChanged;
                        break;
                    case SUPERSEDED:
                        status = OcspCertStatus.superseded;
                        break;
                    case CERTIFICATE_HOLD:
                        status = OcspCertStatus.certificateHold;
                        break;
                    case REMOVE_FROM_CRL:
                        status = OcspCertStatus.removeFromCRL;
                        break;
                    case PRIVILEGE_WITHDRAWN:
                        status = OcspCertStatus.privilegeWithdrawn;
                        break;
                    case AA_COMPROMISE:
                        status = OcspCertStatus.aACompromise;
                        break;
                    default:
                        issue.setFailureMessage("should not reach here, unknwon CRLReason " + revocationReason);
                        break;
                    }
                }
            } else {
                status = OcspCertStatus.rev_noreason;
            }
        } else if (singleCertStatus instanceof UnknownStatus) {
            status = OcspCertStatus.issuerUnknown;
        } else {
            issue.setFailureMessage("unknown certstatus: " + singleCertStatus.getClass().getName());
        }

        if (issue.isFailed() == false && expectedStatus != status) {
            issue.setFailureMessage("is='" + status + "', but expected='" + expectedStatus + "'");
        }
    }

    {
        // nextUpdate
        Date nextUpdate = singleResp.getNextUpdate();
        checkOccurrence("OCSP.RESPONSE." + index + ".NEXTUPDATE", nextUpdate, nextupdateOccurrence);
    }

    Extension extension = singleResp.getExtension(ISISMTTObjectIdentifiers.id_isismtt_at_certHash);
    {
        checkOccurrence("OCSP.RESPONSE." + index + ".CERTHASh", extension, certhashOccurrence);
    }

    if (extension != null) {
        ASN1Encodable extensionValue = extension.getParsedValue();
        CertHash certHash = CertHash.getInstance(extensionValue);
        ASN1ObjectIdentifier hashAlgOid = certHash.getHashAlgorithm().getAlgorithm();
        if (certhashAlg != null) {
            // certHash algorithm
            ValidationIssue issue = new ValidationIssue("OCSP.RESPONSE." + index + ".CERTHASH.ALG",
                    "certhash algorithm");
            issues.add(issue);

            ASN1ObjectIdentifier is = certHash.getHashAlgorithm().getAlgorithm();
            if (certhashAlg.equals(is) == false) {
                issue.setFailureMessage("is '" + is.getId() + "', but expected '" + certhashAlg.getId() + "'");
            }
        }

        byte[] hashValue = certHash.getCertificateHash();
        if (encodedCert != null) {
            ValidationIssue issue = new ValidationIssue("OCSP.RESPONSE." + index + ".CERTHASH.VALIDITY",
                    "certhash validity");
            issues.add(issue);

            try {
                MessageDigest md = MessageDigest.getInstance(hashAlgOid.getId());
                byte[] expectedHashValue = md.digest(encodedCert);
                if (Arrays.equals(expectedHashValue, hashValue) == false) {
                    issue.setFailureMessage("certHash does not match the requested certificate");
                }
            } catch (NoSuchAlgorithmException e) {
                issue.setFailureMessage("NoSuchAlgorithm " + hashAlgOid.getId());
            }
        }
    }

    return issues;
}

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");
    }//from  w w  w. j a  va  2s  . c  o m

    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

private List<ValidationIssue> checkSingleCert(final int index, final SingleResp singleResp,
        final IssuerHash issuerHash, final OcspCertStatus expectedStatus, final byte[] encodedCert,
        final boolean extendedRevoke, final Occurrence nextupdateOccurrence,
        final Occurrence certhashOccurrence, final ASN1ObjectIdentifier certhashAlg) {
    List<ValidationIssue> issues = new LinkedList<>();

    // issuer hash
    ValidationIssue issue = new ValidationIssue("OCSP.RESPONSE." + index + ".ISSUER", "certificate issuer");
    issues.add(issue);/*from  w  ww .ja va 2 s  . c o m*/

    CertificateID certId = singleResp.getCertID();
    HashAlgoType hashAlgo = HashAlgoType.getHashAlgoType(certId.getHashAlgOID());
    if (hashAlgo == null) {
        issue.setFailureMessage("unknown hash algorithm " + certId.getHashAlgOID().getId());
    } else {
        if (!issuerHash.match(hashAlgo, certId.getIssuerNameHash(), certId.getIssuerKeyHash())) {
            issue.setFailureMessage("issuer not match");
        }
    }

    // status
    issue = new ValidationIssue("OCSP.RESPONSE." + index + ".STATUS", "certificate status");
    issues.add(issue);

    CertificateStatus singleCertStatus = singleResp.getCertStatus();

    OcspCertStatus status = null;
    if (singleCertStatus == null) {
        status = OcspCertStatus.good;
    } else if (singleCertStatus instanceof RevokedStatus) {
        RevokedStatus revStatus = (RevokedStatus) singleCertStatus;
        Date revTime = revStatus.getRevocationTime();

        if (revStatus.hasRevocationReason()) {
            int reason = revStatus.getRevocationReason();
            if (extendedRevoke && reason == CrlReason.CERTIFICATE_HOLD.getCode() && revTime.getTime() == 0) {
                status = OcspCertStatus.unknown;
            } else {
                CrlReason revocationReason = CrlReason.forReasonCode(reason);
                switch (revocationReason) {
                case UNSPECIFIED:
                    status = OcspCertStatus.unspecified;
                    break;
                case KEY_COMPROMISE:
                    status = OcspCertStatus.keyCompromise;
                    break;
                case CA_COMPROMISE:
                    status = OcspCertStatus.cACompromise;
                    break;
                case AFFILIATION_CHANGED:
                    status = OcspCertStatus.affiliationChanged;
                    break;
                case SUPERSEDED:
                    status = OcspCertStatus.superseded;
                    break;
                case CERTIFICATE_HOLD:
                    status = OcspCertStatus.certificateHold;
                    break;
                case REMOVE_FROM_CRL:
                    status = OcspCertStatus.removeFromCRL;
                    break;
                case PRIVILEGE_WITHDRAWN:
                    status = OcspCertStatus.privilegeWithdrawn;
                    break;
                case AA_COMPROMISE:
                    status = OcspCertStatus.aACompromise;
                    break;
                default:
                    issue.setFailureMessage("should not reach here, unknown CRLReason " + revocationReason);
                    break;
                }
            } // end if
        } else {
            status = OcspCertStatus.rev_noreason;
        } // end if (revStatus.hasRevocationReason())
    } else if (singleCertStatus instanceof UnknownStatus) {
        status = OcspCertStatus.issuerUnknown;
    } else {
        issue.setFailureMessage("unknown certstatus: " + singleCertStatus.getClass().getName());
    }

    if (!issue.isFailed() && expectedStatus != status) {
        issue.setFailureMessage("is='" + status + "', but expected='" + expectedStatus + "'");
    }

    // nextUpdate
    Date nextUpdate = singleResp.getNextUpdate();
    checkOccurrence("OCSP.RESPONSE." + index + ".NEXTUPDATE", nextUpdate, nextupdateOccurrence);

    Extension extension = singleResp.getExtension(ISISMTTObjectIdentifiers.id_isismtt_at_certHash);
    checkOccurrence("OCSP.RESPONSE." + index + ".CERTHASH", extension, certhashOccurrence);

    if (extension != null) {
        ASN1Encodable extensionValue = extension.getParsedValue();
        CertHash certHash = CertHash.getInstance(extensionValue);
        ASN1ObjectIdentifier hashAlgOid = certHash.getHashAlgorithm().getAlgorithm();
        if (certhashAlg != null) {
            // certHash algorithm
            issue = new ValidationIssue("OCSP.RESPONSE." + index + ".CHASH.ALG", "certhash algorithm");
            issues.add(issue);

            ASN1ObjectIdentifier is = certHash.getHashAlgorithm().getAlgorithm();
            if (!certhashAlg.equals(is)) {
                issue.setFailureMessage("is '" + is.getId() + "', but expected '" + certhashAlg.getId() + "'");
            }
        }

        byte[] hashValue = certHash.getCertificateHash();
        if (encodedCert != null) {
            issue = new ValidationIssue("OCSP.RESPONSE." + index + ".CHASH.VALIDITY", "certhash validity");
            issues.add(issue);

            try {
                MessageDigest md = MessageDigest.getInstance(hashAlgOid.getId());
                byte[] expectedHashValue = md.digest(encodedCert);
                if (!Arrays.equals(expectedHashValue, hashValue)) {
                    issue.setFailureMessage("certhash does not match the requested certificate");
                }
            } catch (NoSuchAlgorithmException ex) {
                issue.setFailureMessage("NoSuchAlgorithm " + hashAlgOid.getId());
            }
        } // end if(encodedCert != null)
    } // end if (extension != null)

    return issues;
}