All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.henricook.tls.x509.CertificateStatusProvider.scala Maven / Gradle / Ivy

The newest version!
package com.henricook.tls.x509

import com.henricook.tls.TLS
import com.henricook.tls.x509.crl.CRL
import com.henricook.tls.TLS
import com.henricook.tls.TLS.Certificate
import com.henricook.tls.x509.crl.CRL
import com.henricook.tls.x509.ocsp.OCSP
import org.bouncycastle.cert.X509CRLHolder

import scala.collection.concurrent.TrieMap

/**
  * Certificate revocation status provider trait
  */
trait CertificateStatusProvider {

  /**
    * Is certificate revoked
    * @param certificate Certificate
    * @param issuer Issuer certificate
    * @return Is certificate revoked
    */
  def isRevoked(certificate: TLS.Certificate, issuer: TLS.Certificate): Boolean
}

object CertificateStatusProvider {

  /**
    * CRL-based certificate status provider
    * @note Uses internet for verification and caches the result
    */
  val CRL: CertificateStatusProvider = new CRLOnlineCertificateStatusProvider()

  /**
    * OCSP-based certificate status provider
    * @note Uses internet for verification and caches the result
    */
  val OCSP: CertificateStatusProvider =
    new OCSPOnlineCertificateStatusProvider()

  /**
    * Always valid certificate status provider
    */
  object AlwaysValid extends CertificateStatusProvider {
    override def isRevoked(
        certificate: Certificate,
        issuer: Certificate
    ): Boolean = false
  }
}

class CRLOnlineCertificateStatusProvider extends CertificateStatusProvider {
  protected val cache =
    TrieMap.empty[(Seq[String], Certificate), Seq[X509CRLHolder]]

  protected def loadCRL(
      certificate: Certificate,
      issuer: Certificate
  ): Seq[X509CRLHolder] = {
    cache.getOrElseUpdate(
      X509Utils.getCrlDistributionUrls(issuer) → issuer,
      CRL.getRevocationLists(certificate, issuer)
    )
  }

  override def isRevoked(
      certificate: Certificate,
      issuer: Certificate
  ): Boolean = {
    loadCRL(certificate, issuer).exists(
      crl ⇒ CRL.verify(crl, issuer) && CRL.contains(crl, certificate)
    )
  }
}

class OCSPOnlineCertificateStatusProvider extends CertificateStatusProvider {
  protected val cache = TrieMap.empty[Certificate, Option[OCSP.Status]]

  protected def loadOCSP(
      certificate: Certificate,
      issuer: Certificate
  ): Option[OCSP.Status] = {
    cache.getOrElseUpdate(certificate, OCSP.getStatus(certificate, issuer))
  }

  override def isRevoked(
      certificate: Certificate,
      issuer: Certificate
  ): Boolean = {
    loadOCSP(certificate, issuer).exists(_.isRevoked)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy