Add certificate expiration to the ke response
This commit is contained in:
parent
ac3b7ebcc7
commit
01ab1c1d54
|
@ -0,0 +1,35 @@
|
||||||
|
defmodule Chronoscope.NTS.Certificate do
|
||||||
|
def expiration_date(certificate) do
|
||||||
|
{:Validity, _, {:utcTime, expiration}} =
|
||||||
|
certificate
|
||||||
|
|> X509.Certificate.from_der!()
|
||||||
|
|> X509.Certificate.validity()
|
||||||
|
|
||||||
|
cert_time_to_iso8601(expiration)
|
||||||
|
end
|
||||||
|
|
||||||
|
def cert_time_to_iso8601(cert_time) do
|
||||||
|
captures =
|
||||||
|
Regex.named_captures(
|
||||||
|
~r/^(?<year>\d\d)(?<month>\d\d)(?<day>\d\d)(?<hour>\d\d)(?<minute>\d\d)(?<second>\d\d)Z$/,
|
||||||
|
to_string(cert_time)
|
||||||
|
)
|
||||||
|
|
||||||
|
"#{short_year_to_full_year(captures["year"])}-#{captures["month"]}-#{captures["day"]}T#{captures["hour"]}:#{captures["minute"]}:#{captures["second"]}Z"
|
||||||
|
end
|
||||||
|
|
||||||
|
defp short_year_to_full_year(short_year) do
|
||||||
|
{century, current_year} =
|
||||||
|
DateTime.utc_now().year
|
||||||
|
|> to_string()
|
||||||
|
|> String.split_at(-2)
|
||||||
|
|
||||||
|
if String.to_integer(short_year) >= String.to_integer(current_year) do
|
||||||
|
century <> short_year
|
||||||
|
else
|
||||||
|
century
|
||||||
|
|> String.to_integer()
|
||||||
|
|> then(&"#{&1 + 1}#{short_year}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,7 @@
|
||||||
defmodule Chronoscope.NTS.KeyEstablishmentClient do
|
defmodule Chronoscope.NTS.KeyEstablishmentClient do
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
alias Chronoscope.NTS.Certificate
|
||||||
alias Chronoscope.NTS.KeyEstablishmentRequest
|
alias Chronoscope.NTS.KeyEstablishmentRequest
|
||||||
alias Chronoscope.NTS.KeyEstablishmentResponse
|
alias Chronoscope.NTS.KeyEstablishmentResponse
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ defmodule Chronoscope.NTS.KeyEstablishmentClient do
|
||||||
:ssl.close(socket)
|
:ssl.close(socket)
|
||||||
|
|
||||||
case KeyEstablishmentResponse.parse(response) do
|
case KeyEstablishmentResponse.parse(response) do
|
||||||
{:ok, x} -> {:ok, Map.put(x, :cert_expiration, certificate_expiration(peercert))}
|
{:ok, parsed_response} -> {:ok, Map.put(parsed_response, :cert_expiration, Certificate.expiration_date(peercert))}
|
||||||
# todo - indicate errors in server response
|
# todo - indicate errors in server response
|
||||||
error -> error
|
error -> error
|
||||||
end
|
end
|
||||||
|
@ -52,13 +53,4 @@ defmodule Chronoscope.NTS.KeyEstablishmentClient do
|
||||||
{:error, :timeout}
|
{:error, :timeout}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp certificate_expiration(certificate) do
|
|
||||||
{:Validity, _, {:utcTime, expiration}} =
|
|
||||||
certificate
|
|
||||||
|> X509.Certificate.from_der!()
|
|
||||||
|> X509.Certificate.validity()
|
|
||||||
|
|
||||||
expiration
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,7 +22,7 @@ defmodule ChronoscopeWeb.API.V1.NTS.KeyEstablishmentController do
|
||||||
|
|
||||||
defp format_response(response) do
|
defp format_response(response) do
|
||||||
response
|
response
|
||||||
|> Map.take([:aead_algorithms, :cookie_length, :cookies, :next_protocols, :port, :server])
|
|> Map.take([:aead_algorithms, :cert_expiration, :cookie_length, :cookies, :next_protocols, :port, :server])
|
||||||
|> Map.update(:cookies, 0, &length/1)
|
|> Map.update(:cookies, 0, &length/1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
defmodule Chronoscope.NTS.CertificateTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
|
||||||
|
import Chronoscope.NTS.Certificate
|
||||||
|
|
||||||
|
test "parses the expiration date of a certificate" do
|
||||||
|
{:ok, expiration, _} =
|
||||||
|
:secp256r1
|
||||||
|
|> X509.PrivateKey.new_ec()
|
||||||
|
|> X509.Certificate.self_signed("/C=US/ST=CA/L=San Francisco/O=Acme/CN=Test", validity: 12)
|
||||||
|
|> X509.Certificate.to_der()
|
||||||
|
|> expiration_date()
|
||||||
|
|> DateTime.from_iso8601()
|
||||||
|
|
||||||
|
assert DateTime.diff(expiration, DateTime.utc_now(), :day) == 12
|
||||||
|
end
|
||||||
|
|
||||||
|
# todo - mock current time
|
||||||
|
test "converts certificate datetime to iso8601" do
|
||||||
|
assert cert_time_to_iso8601("240326110000Z") == "2024-03-26T11:00:00Z"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "handles century rollover" do
|
||||||
|
assert cert_time_to_iso8601("010326110000Z") == "2101-03-26T11:00:00Z"
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue