defmodule Braintree.Webhook.Digest do
@moduledoc """
This module provides convenience methods to help validate Braintree signatures and associated payloads for webhooks.
"""
@doc """
A wrapper function that does a secure comparision accounting for timing attacks.
"""
@spec secure_compare(String.t(), String.t()) :: boolean()
def secure_compare(left, right) when is_binary(left) and is_binary(right) do
Plug.Crypto.secure_compare(left, right)
end
def secure_compare(_, _), do: false
@doc """
Returns the message as a hex-encoded string to validate it matches the signature from the braintree webhook event.
"""
@spec hexdigest(String.t() | nil, String.t() | nil) :: String.t()
def hexdigest(nil, _), do: ""
def hexdigest(_, nil), do: ""
def hexdigest(private_key, message) do
key_digest = :crypto.hash(:sha, private_key)
:sha
|> hmac(key_digest, message)
|> Base.encode16(case: :lower)
end
if System.otp_release() >= "22" do
defp hmac(digest, key, data), do: :crypto.mac(:hmac, digest, key, data)
else
defp hmac(digest, key, data), do: :crypto.hmac(digest, key, data)
end
end