Sat.Certificados.Ocsp (sat_certificados v4.0.1)

Copy Markdown

Validación OCSP (Online Certificate Status Protocol — RFC 6960) contra el responder del SAT.

El SAT expone https://cfdi.sat.gob.mx/edofiel para consultar el estado (GOOD / REVOKED) de un certificado en línea. Para validar un certificado de un contribuyente se necesitan tres certificados:

  1. subject: el cert del contribuyente que estás verificando.
  2. issuer: el cert raíz del SAT que lo emitió (AC4 o AC5).
  3. ocsp: el cert que firma la respuesta del responder OCSP del SAT.

Ejemplo

{:ok, subject} = Certificate.from_file("contribuyente.cer")
{:ok, issuer}  = Certificate.from_file("AC5_SAT.cer")
{:ok, ocsp_c}  = Certificate.from_file("ocsp.ac5_sat.cer")

ocsp = Ocsp.new!("https://cfdi.sat.gob.mx/edofiel", issuer, subject, ocsp_c)
{:ok, %{status: status, revocation_time: t}} = Ocsp.verify(ocsp)

Parsing offline

Las funciones parse_response_status/1 y parse_certificate_status/1 permiten inspeccionar respuestas OCSP grabadas en archivo, útiles para pruebas sin red.

Tests

La suite de este paquete incluye tests offline (parsing de respuestas OCSP grabadas en packages/files/certificados/efirma/{revoked,tryLater}.der) que corren siempre con mix test.

El test que pega al endpoint en vivo del SAT está marcado con @tag :online y no corre por default para evitar requerir red en CI. Para ejecutarlo:

mix test --include online

Lo recomendado es dejarlo así: el test online es flaky (depende de la disponibilidad del responder del SAT) y los offline ya cubren toda la lógica de parseo y verificación de firma.

Summary

Functions

Construye una struct %Ocsp{} validando la URL.

Como new/4, pero lanza ArgumentError si la URL es inválida.

Extrae %{status, revocation_time?} desde el DER de una BasicOCSPResponse. Útil para inspeccionar respuestas pre-grabadas.

Parsea el responseStatus (primer campo de OCSPResponse, RFC 6960 §4.2.1) desde el DER. Útil para inspeccionar respuestas pre-grabadas.

Construye la solicitud OCSP, la POSTea al endpoint, parsea la respuesta y devuelve el estado del certificado del contribuyente.

Types

cert_status_result()

@type cert_status_result() :: %{
  :status => status(),
  optional(:revocation_time) => DateTime.t()
}

status()

@type status() :: :good | :revoked | :unknown | :undefined

t()

@type t() :: %Sat.Certificados.Ocsp{
  issuer: Sat.Certificados.Certificate.t(),
  ocsp_cert: Sat.Certificados.Certificate.t(),
  subject: Sat.Certificados.Certificate.t(),
  url: String.t()
}

verify_response()

@type verify_response() :: %{
  :status => status(),
  optional(:revocation_time) => DateTime.t(),
  ocsp_request_base64: String.t(),
  ocsp_response_base64: String.t()
}

Functions

new(url, issuer, subject, ocsp_cert)

@spec new(
  String.t(),
  Sat.Certificados.Certificate.t(),
  Sat.Certificados.Certificate.t(),
  Sat.Certificados.Certificate.t()
) :: {:ok, t()} | {:error, :invalid_url}

Construye una struct %Ocsp{} validando la URL.

new!(url, issuer, subject, ocsp_cert)

Como new/4, pero lanza ArgumentError si la URL es inválida.

parse_certificate_status(basic_der)

@spec parse_certificate_status(binary()) :: cert_status_result()

Extrae %{status, revocation_time?} desde el DER de una BasicOCSPResponse. Útil para inspeccionar respuestas pre-grabadas.

parse_response_status(der)

@spec parse_response_status(binary()) :: status() | :try_later | :successful | atom()

Parsea el responseStatus (primer campo de OCSPResponse, RFC 6960 §4.2.1) desde el DER. Útil para inspeccionar respuestas pre-grabadas.

verify(ocsp)

@spec verify(t()) :: {:ok, verify_response()} | {:error, term()}

Construye la solicitud OCSP, la POSTea al endpoint, parsea la respuesta y devuelve el estado del certificado del contribuyente.

Lanza si el servicio responde error o si la firma de la respuesta no corresponde al ocsp_cert.