/**
  * Returns whether the specified object equals to this instance.
  *
  * @param other the object to compare.
  * @return {@code true} if the specified object equals to this instance, otherwise {@code false}.
  */
 public boolean equals(Object other) {
   if (other == this) {
     return true;
   }
   if (!(other instanceof X509CRLEntry)) {
     return false;
   }
   X509CRLEntry obj = (X509CRLEntry) other;
   try {
     return Arrays.equals(getEncoded(), obj.getEncoded());
   } catch (CRLException e) {
     return false;
   }
 }
 /** @return the revocation reason code as defined in RevokedCertInfo.REVOCATION_REASON_... */
 public static int extractReasonCode(final X509CRLEntry crlEntry) {
   int reasonCode = RevokedCertInfo.REVOCATION_REASON_UNSPECIFIED;
   if (crlEntry.hasExtensions()) {
     final byte[] extensionValue = crlEntry.getExtensionValue(Extension.reasonCode.getId());
     try {
       final ASN1Enumerated reasonCodeExtension =
           ASN1Enumerated.getInstance(X509ExtensionUtil.fromExtensionValue(extensionValue));
       if (reasonCodeExtension != null) {
         reasonCode = reasonCodeExtension.getValue().intValue();
       }
     } catch (IOException e) {
       log.debug("Failed to parse reason code of CRLEntry: " + e.getMessage());
     }
   }
   return reasonCode;
 }
  protected static void getCertStatus(
      Date validDate, X509CRL crl, Object cert, CertStatus certStatus) throws AnnotatedException {
    X509CRLEntry crl_entry = null;

    boolean isIndirect;
    try {
      isIndirect = X509CRLObject.isIndirectCRL(crl);
    } catch (CRLException exception) {
      throw new AnnotatedException("Failed check for indirect CRL.", exception);
    }

    if (isIndirect) {
      crl_entry = crl.getRevokedCertificate(getSerialNumber(cert));

      if (crl_entry == null) {
        return;
      }

      X500Principal certIssuer = crl_entry.getCertificateIssuer();

      if (certIssuer == null) {
        certIssuer = getIssuerPrincipal(crl);
      }

      if (!getEncodedIssuerPrincipal(cert).equals(certIssuer)) {
        return;
      }
    } else if (!getEncodedIssuerPrincipal(cert).equals(getIssuerPrincipal(crl))) {
      return; // not for our issuer, ignore
    } else {
      crl_entry = crl.getRevokedCertificate(getSerialNumber(cert));

      if (crl_entry == null) {
        return;
      }
    }

    DEREnumerated reasonCode = null;
    if (crl_entry.hasExtensions()) {
      try {
        reasonCode =
            DEREnumerated.getInstance(
                CertPathValidatorUtilities.getExtensionValue(
                    crl_entry, X509Extension.reasonCode.getId()));
      } catch (Exception e) {
        throw new AnnotatedException("Reason code CRL entry extension could not be decoded.", e);
      }
    }

    // for reason keyCompromise, caCompromise, aACompromise or
    // unspecified
    if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime())
        || reasonCode == null
        || reasonCode.getValue().intValue() == 0
        || reasonCode.getValue().intValue() == 1
        || reasonCode.getValue().intValue() == 2
        || reasonCode.getValue().intValue() == 8) {

      // (i) or (j) (1)
      if (reasonCode != null) {
        certStatus.setCertStatus(reasonCode.getValue().intValue());
      }
      // (i) or (j) (2)
      else {
        certStatus.setCertStatus(CRLReason.unspecified);
      }
      certStatus.setRevocationDate(crl_entry.getRevocationDate());
    }
  }
  /** Test revocation and reactivation of certificates */
  @Test
  public void testRevokeAndUnrevoke() throws Exception {

    X509Certificate cert = createCert();
    try {
      // Create a new CRL again...
      assertTrue(publishingCrlSessionRemote.forceCRL(roleMgmgToken, testx509ca.getCAId()));
      // Check that our newly signed certificate is not present in a new CRL
      byte[] crl = crlStoreSession.getLastCRL(testx509ca.getSubjectDN(), false);
      assertNotNull("Could not get CRL", crl);
      X509CRL x509crl = CertTools.getCRLfromByteArray(crl);
      Set<? extends X509CRLEntry> revset = x509crl.getRevokedCertificates();
      if (revset != null) {
        Iterator<? extends X509CRLEntry> iter = revset.iterator();
        while (iter.hasNext()) {
          X509CRLEntry ce = iter.next();
          assertTrue(ce.getSerialNumber().compareTo(cert.getSerialNumber()) != 0);
        }
      } // If no revoked certificates exist at all, this test passed...

      certificateStoreSession.setRevokeStatus(
          roleMgmgToken, cert, RevokedCertInfo.REVOCATION_REASON_CERTIFICATEHOLD, null);
      // Create a new CRL again...
      assertTrue(publishingCrlSessionRemote.forceCRL(roleMgmgToken, testx509ca.getCAId()));
      // Check that our newly signed certificate IS present in a new CRL
      crl = crlStoreSession.getLastCRL(testx509ca.getSubjectDN(), false);
      assertNotNull("Could not get CRL", crl);
      x509crl = CertTools.getCRLfromByteArray(crl);
      revset = x509crl.getRevokedCertificates();
      assertNotNull(revset);
      Iterator<? extends X509CRLEntry> iter = revset.iterator();
      boolean found = false;
      while (iter.hasNext()) {
        X509CRLEntry ce = iter.next();
        if (ce.getSerialNumber().compareTo(cert.getSerialNumber()) == 0) {
          found = true;
          // TODO: verify the reason code
        }
      }
      assertTrue(
          "Certificate with serial " + cert.getSerialNumber().toString(16) + " not revoked", found);

      // Unrevoke the certificate that we just revoked
      certificateStoreSession.setRevokeStatus(
          roleMgmgToken, cert, RevokedCertInfo.NOT_REVOKED, null);
      // Create a new CRL again...
      assertTrue(publishingCrlSessionRemote.forceCRL(roleMgmgToken, testx509ca.getCAId()));
      // Check that our newly signed certificate IS NOT present in the new
      // CRL.
      crl = crlStoreSession.getLastCRL(testx509ca.getSubjectDN(), false);
      assertNotNull("Could not get CRL", crl);
      x509crl = CertTools.getCRLfromByteArray(crl);
      revset = x509crl.getRevokedCertificates();
      if (revset != null) {
        iter = revset.iterator();
        found = false;
        while (iter.hasNext()) {
          X509CRLEntry ce = iter.next();
          if (ce.getSerialNumber().compareTo(cert.getSerialNumber()) == 0) {
            found = true;
          }
        }
        assertFalse(found);
      } // If no revoked certificates exist at all, this test passed...

      certificateStoreSession.setRevokeStatus(
          roleMgmgToken, cert, RevokedCertInfo.REVOCATION_REASON_CACOMPROMISE, null);
      assertTrue(
          "Failed to revoke certificate!",
          certificateStoreSession.isRevoked(
              CertTools.getIssuerDN(cert), CertTools.getSerialNumber(cert)));
      // Create a new CRL again...
      assertTrue(publishingCrlSessionRemote.forceCRL(roleMgmgToken, testx509ca.getCAId()));
      // Check that our newly signed certificate IS present in a new CRL
      crl = crlStoreSession.getLastCRL(testx509ca.getSubjectDN(), false);
      assertNotNull("Could not get CRL", crl);
      x509crl = CertTools.getCRLfromByteArray(crl);
      revset = x509crl.getRevokedCertificates();
      iter = revset.iterator();
      found = false;
      while (iter.hasNext()) {
        X509CRLEntry ce = (X509CRLEntry) iter.next();
        if (ce.getSerialNumber().compareTo(cert.getSerialNumber()) == 0) {
          found = true;
          // TODO: verify the reason code
        }
      }
      assertTrue(found);

      certificateStoreSession.setRevokeStatus(
          roleMgmgToken, cert, RevokedCertInfo.NOT_REVOKED, null);
      assertTrue(
          "Was able to re-activate permanently revoked certificate!",
          certificateStoreSession.isRevoked(
              CertTools.getIssuerDN(cert), CertTools.getSerialNumber(cert)));
      // Create a new CRL again...
      assertTrue(publishingCrlSessionRemote.forceCRL(roleMgmgToken, testx509ca.getCAId()));
      // Check that our newly signed certificate is present in the new CRL,
      // because the revocation reason
      // was not CERTIFICATE_HOLD, we can only un-revoke certificates that are
      // on hold.
      crl = crlStoreSession.getLastCRL(testx509ca.getSubjectDN(), false);
      assertNotNull("Could not get CRL", crl);
      x509crl = CertTools.getCRLfromByteArray(crl);
      revset = x509crl.getRevokedCertificates();
      iter = revset.iterator();
      found = false;
      while (iter.hasNext()) {
        X509CRLEntry ce = (X509CRLEntry) iter.next();
        if (ce.getSerialNumber().compareTo(cert.getSerialNumber()) == 0) {
          found = true;
        }
      }
      assertTrue(found);
    } finally {
      internalCertificateStoreSession.removeCertificate(cert);
    }
  }