Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
5HT committed Nov 1, 2024
1 parent 90c8379 commit d773ac6
Show file tree
Hide file tree
Showing 4 changed files with 249 additions and 27 deletions.
26 changes: 12 additions & 14 deletions lib/services/crt.ex
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,14 @@ defmodule CA.CRT do
:erlang.tuple_to_list(:oid.decode(x))),'.')) end, list)
end

def mapOids(list) do
:lists.map(fn x ->
:erlang.iolist_to_binary(:string.join(:lists.map(fn y -> :erlang.integer_to_list(y) end,
:erlang.tuple_to_list(x)),'.')) end, list)
end
def mapOid(x) do :erlang.iolist_to_binary(:string.join(:lists.map(fn y -> :erlang.integer_to_list(y) end, :erlang.tuple_to_list(x)),'.')) end
def mapOids(list) do :lists.map(fn x -> mapOid(x) end, list) end
def isString(bin) do :lists.foldl(fn x, acc when x < 20 -> acc + 1 ; _, acc -> acc end, 0, :erlang.binary_to_list(bin)) <= 0 end

def oid({1,3,6,1,5,5,7,1,1}, v), do: {:authorityInfoAccess, pair(v,[])}
def oid({1,3,6,1,4,1,11129,2,4,2}, v), do: {:signedCertificateTimestamp, :base64.encode(hd(pair(v,[])))}
def oid({1,3,6,1,5,5,7,1,11},v), do: {:subjectInfoAccess, pair(v,[])}
def oid({1,3,6,1,5,5,7,1,3}, v), do: {:qcStatements, mapOidsDecode(v)}
def oid({1,3,6,1,5,5,7,1,3}, v), do: {:qcStatements, :lists.map(fn x -> case isString(x) do false -> mapOid(:oid.decode(x)) ; true -> x end end, v) }
def oid({2,5,29,9},v), do: {:subjectDirectoryAttributes, pair(v,[])}
def oid({2,5,29,14},v), do: {:subjectKeyIdentifier, :base64.encode(hd(pair(v,[])))}
def oid({2,5,29,15},[v]), do: {:keyUsage, CA.EST.decodeKeyUsage(<<3,2,v::binary>>) }
Expand All @@ -63,7 +61,7 @@ defmodule CA.CRT do
def oid({2,5,29,37},v), do: {:extKeyUsage, mapOids(:lists.map(fn x -> :oid.decode(x) end, v)) }
def oid({2,5,29,19},v), do: {:basicConstraints, v}
def oid({2,5,29,31},v), do: {:cRLDistributionPoints, pair(v,[])}
def oid({2,5,29,32},v), do: {:certificatePolicies, mapOids(:lists.map(fn x -> :oid.decode(x) end, v))}
def oid({2,5,29,32},v), do: {:certificatePolicies, :lists.map(fn x -> case isString(x) do false -> mapOid(:oid.decode(x)) ; true -> x end end, v) }
def oid({2,5,29,35},v), do: {:authorityKeyIdentifier, :base64.encode(hd(pair(v,[])))}
def oid({2,5,29,46},v), do: {:freshestCRL, pair(v,[])}
def oid({1,2,840,113549,1,9,3},v), do: {:contentType, CA.AT.oid(CA.EST.decodeObjectIdentifier(v)) }
Expand Down Expand Up @@ -117,15 +115,15 @@ defmodule CA.CRT do
def flat(code,k,acc) when is_list(k), do: [:lists.map(fn x -> flat(code,x,acc) end, k)|acc]
def flat(_code,k,acc) when is_binary(k), do: [k|acc]

def rdn({2, 5, 4, 3}), do: "commonName" # commonName
def rdn({2, 5, 4, 4}), do: "surename" # sn
def rdn({2, 5, 4, 3}), do: "cn" # "commonName"
def rdn({2, 5, 4, 4}), do: "sn" # "surename"
def rdn({2, 5, 4, 5}), do: "serialNumber"
def rdn({2, 5, 4, 6}), do: "country" # c
def rdn({2, 5, 4, 7}), do: "localityName" # l
def rdn({2, 5, 4, 6}), do: "c" # "country"
def rdn({2, 5, 4, 7}), do: "l" # "localityName"
def rdn({2, 5, 4, 8}), do: "stateOrProvinceName"
def rdn({0,9,2342,19200300,100,1,25}), do: "domainComponen" # dc
def rdn({2, 5, 4, 10}), do: "organization" # o
def rdn({2, 5, 4, 11}), do: "organizationalUnit" # ou
def rdn({0,9,2342,19200300,100,1,25}), do: "dc" # "domainComponen"
def rdn({2, 5, 4, 10}), do: "o" # "organization"
def rdn({2, 5, 4, 11}), do: "ou" # "organizationalUnit"
def rdn({2, 5, 4, 12}), do: "title"
def rdn({2, 5, 4, 13}), do: "description"
def rdn({2, 5, 4, 14}), do: "device"
Expand Down
25 changes: 13 additions & 12 deletions lib/services/est.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@ defmodule CA.EST do
plug :dispatch
plug Plug.Parsers, parsers: [:json], json_decoder: Jason

def integer(x) do {:ok, v} = :"EST".encode(:Int, x) ; v end
def decodeInteger(x) do {:ok, v} = :"EST".decode(:Int, x) ; v end
def objectIdentifier(x) do {:ok, v} = :"EST".encode(:OID, x) ; v end
def decodeObjectIdentifier(x) do {:ok, v} = :"EST".decode(:OID, x) ; v end
def extension(x) do {:ok, v} = :"EST".encode(:Extension, x) ; v end
def integer(x) do {:ok, v} = :"EST".encode(:Int, x) ; v end
def decodeInteger(x) do {:ok, v} = :"EST".decode(:Int, x) ; v end
def objectIdentifier(x) do {:ok, v} = :"EST".encode(:OID, x) ; v end
def decodeObjectIdentifier(x) do {:ok, v} = :"EST".decode(:OID, x) ; v end
def extension(x) do {:ok, v} = :"EST".encode(:Extension, x) ; v end

def basicConstraints() do {:ok, v} = :"PKIX1Implicit-2009".encode(:BasicConstraints, {:BasicConstraints, false, :asn1_NOVALUE}) ; v end
def keyUsage(list) do {:ok, v} = :"PKIX1Implicit-2009".encode(:KeyUsage, list) ; v end
def decodeKeyPurposeId(list) do {:ok, v} = :"PKIX1Implicit-2009".decode(:KeyPurposeId, list) ; v end
def decodeKeyUsage(list) do {:ok, v} = :"PKIX1Implicit-2009".decode(:KeyUsage, list) ; v end
def extendedKeyUsage(list) do {:ok, v} = :"PKIX1Implicit-2009".encode(:ExtKeyUsageSyntax, list) ; v end
def decodeExtendedKeyUsage(list) do {:ok, v} = :"PKIX1Implicit-2009".decode(:ExtKeyUsageSyntax, list) ; v end
def decodePolicyInformation(list) do {:ok, v} = :"PKIX1Implicit-2009".decode(:PolicyInformation, list) ; v end
def basicConstraints() do {:ok, v} = :"PKIX1Implicit-2009".encode(:BasicConstraints, {:BasicConstraints, false, :asn1_NOVALUE}) ; v end
def keyUsage(list) do {:ok, v} = :"PKIX1Implicit-2009".encode(:KeyUsage, list) ; v end
def decodeKeyPurposeId(list) do {:ok, v} = :"PKIX1Implicit-2009".decode(:KeyPurposeId, list) ; v end
def decodeKeyUsage(list) do {:ok, v} = :"PKIX1Implicit-2009".decode(:KeyUsage, list) ; v end
def extendedKeyUsage(list) do {:ok, v} = :"PKIX1Implicit-2009".encode(:ExtKeyUsageSyntax, list) ; v end
def decodeExtendedKeyUsage(list) do {:ok, v} = :"PKIX1Implicit-2009".decode(:ExtKeyUsageSyntax, list) ; v end
def decodePolicy(list) do {:ok, v} = :"PKIX1Implicit-2009".decode(:PolicyInformation, list) ; v end
def decodeQCS(list) do {:ok, v} = :KEP.decode(:QCStatement, list) ; v end

def start() do
children = [ { Bandit, scheme: :http, port: 8047, plug: __MODULE__ } ]
Expand Down
13 changes: 13 additions & 0 deletions priv/csr/KEP.asn1
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,19 @@ SingleResponse ::= SEQUENCE {
nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
singleExtensions [1] EXPLICIT Extensions OPTIONAL }

QCStatements ::= SEQUENCE OF QCStatement
QCStatement ::= SEQUENCE {
statementId OBJECT IDENTIFIER,
statementInfo ANY DEFINED BY statementId OPTIONAL
}

MonetaryValue::= SEQUENCE {
currency Iso4217CurrencyCode,
amount INTEGER,
exponent INTEGER
}

Iso4217CurrencyCode ::= CHOICE { alphabetic PrintableString }

MessageImprint ::= SEQUENCE {
hashAlgorithm AlgorithmIdentifier,
Expand Down
212 changes: 211 additions & 1 deletion src/KEP.erl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
-compile(nowarn_unused_vars).
-dialyzer(no_improper_lists).
-dialyzer(no_match).
-include_lib("ca/include/KEP.hrl").
-include("KEP.hrl").
-asn1_info([{vsn,'5.0.17'},
{module,'KEP'},
{options,[warnings,ber,errors,
Expand Down Expand Up @@ -105,6 +105,10 @@ enc_CertID/2,
enc_CertStatus/2,
enc_RevokedInfo/2,
enc_SingleResponse/2,
enc_QCStatements/2,
enc_QCStatement/2,
enc_MonetaryValue/2,
enc_Iso4217CurrencyCode/2,
enc_MessageImprint/2,
enc_TimeStampReq/2,
enc_TimeStampResp/2,
Expand Down Expand Up @@ -204,6 +208,10 @@ dec_CertID/2,
dec_CertStatus/2,
dec_RevokedInfo/2,
dec_SingleResponse/2,
dec_QCStatements/2,
dec_QCStatement/2,
dec_MonetaryValue/2,
dec_Iso4217CurrencyCode/2,
dec_MessageImprint/2,
dec_TimeStampReq/2,
dec_TimeStampResp/2,
Expand Down Expand Up @@ -366,6 +374,10 @@ encode_disp('CertID', Data) -> enc_CertID(Data);
encode_disp('CertStatus', Data) -> enc_CertStatus(Data);
encode_disp('RevokedInfo', Data) -> enc_RevokedInfo(Data);
encode_disp('SingleResponse', Data) -> enc_SingleResponse(Data);
encode_disp('QCStatements', Data) -> enc_QCStatements(Data);
encode_disp('QCStatement', Data) -> enc_QCStatement(Data);
encode_disp('MonetaryValue', Data) -> enc_MonetaryValue(Data);
encode_disp('Iso4217CurrencyCode', Data) -> enc_Iso4217CurrencyCode(Data);
encode_disp('MessageImprint', Data) -> enc_MessageImprint(Data);
encode_disp('TimeStampReq', Data) -> enc_TimeStampReq(Data);
encode_disp('TimeStampResp', Data) -> enc_TimeStampResp(Data);
Expand Down Expand Up @@ -464,6 +476,10 @@ decode_disp('CertID', Data) -> dec_CertID(Data);
decode_disp('CertStatus', Data) -> dec_CertStatus(Data);
decode_disp('RevokedInfo', Data) -> dec_RevokedInfo(Data);
decode_disp('SingleResponse', Data) -> dec_SingleResponse(Data);
decode_disp('QCStatements', Data) -> dec_QCStatements(Data);
decode_disp('QCStatement', Data) -> dec_QCStatement(Data);
decode_disp('MonetaryValue', Data) -> dec_MonetaryValue(Data);
decode_disp('Iso4217CurrencyCode', Data) -> dec_Iso4217CurrencyCode(Data);
decode_disp('MessageImprint', Data) -> dec_MessageImprint(Data);
decode_disp('TimeStampReq', Data) -> dec_TimeStampReq(Data);
decode_disp('TimeStampResp', Data) -> dec_TimeStampResp(Data);
Expand Down Expand Up @@ -4865,6 +4881,200 @@ Res1 = {'SingleResponse',Term1,Term2,Term3,Term4,Term5},
Res1.


%%================================
%% QCStatements
%%================================
enc_QCStatements(Val) ->
enc_QCStatements(Val, [<<48>>]).

enc_QCStatements(Val, TagIn) ->
{EncBytes,EncLen} = 'enc_QCStatements_components'(Val,[],0),
encode_tags(TagIn, EncBytes, EncLen).

'enc_QCStatements_components'([], AccBytes, AccLen) ->
{lists:reverse(AccBytes),AccLen};

'enc_QCStatements_components'([H|T],AccBytes, AccLen) ->
{EncBytes,EncLen} = 'enc_QCStatement'(H, [<<48>>]),
'enc_QCStatements_components'(T,[EncBytes|AccBytes], AccLen + EncLen).



dec_QCStatements(Tlv) ->
dec_QCStatements(Tlv, [16]).

dec_QCStatements(Tlv, TagIn) ->
%%-------------------------------------------------
%% decode tag and length
%%-------------------------------------------------
Tlv1 = match_tags(Tlv, TagIn),
['dec_QCStatement'(V1, [16]) || V1 <- Tlv1].




%%================================
%% QCStatement
%%================================
enc_QCStatement(Val) ->
enc_QCStatement(Val, [<<48>>]).

enc_QCStatement(Val, TagIn) ->
{_,Cindex1,Cindex2} = Val,

%%-------------------------------------------------
%% attribute statementId(1) with type OBJECT IDENTIFIER
%%-------------------------------------------------
{EncBytes1,EncLen1} = encode_object_identifier(Cindex1, [<<6>>]),

%%-------------------------------------------------
%% attribute statementInfo(2) with type ASN1_OPEN_TYPE OPTIONAL
%%-------------------------------------------------
{EncBytes2,EncLen2} = case Cindex2 of
asn1_NOVALUE -> {<<>>,0};
_ ->
encode_open_type(Cindex2, [])
end,

BytesSoFar = [EncBytes1, EncBytes2],
LenSoFar = EncLen1 + EncLen2,
encode_tags(TagIn, BytesSoFar, LenSoFar).


dec_QCStatement(Tlv) ->
dec_QCStatement(Tlv, [16]).

dec_QCStatement(Tlv, TagIn) ->
%%-------------------------------------------------
%% decode tag and length
%%-------------------------------------------------
Tlv1 = match_tags(Tlv, TagIn),

%%-------------------------------------------------
%% attribute statementId(1) with type OBJECT IDENTIFIER
%%-------------------------------------------------
[V1|Tlv2] = Tlv1,
Term1 = decode_object_identifier(V1, [6]),

%%-------------------------------------------------
%% attribute statementInfo(2) with type ASN1_OPEN_TYPE OPTIONAL
%%-------------------------------------------------
{Term2,Tlv3} = case Tlv2 of
[V2|TempTlv3] ->
{decode_open_type_as_binary(V2, []), TempTlv3};
_ ->
{ asn1_NOVALUE, Tlv2}
end,

case Tlv3 of
[] -> true;_ -> exit({error,{asn1, {unexpected,Tlv3}}}) % extra fields not allowed
end,
Res1 = {'QCStatement',Term1,Term2},
Res1.


%%================================
%% MonetaryValue
%%================================
enc_MonetaryValue(Val) ->
enc_MonetaryValue(Val, [<<48>>]).

enc_MonetaryValue(Val, TagIn) ->
{_,Cindex1,Cindex2,Cindex3} = Val,

%%-------------------------------------------------
%% attribute currency(1) External KEP:Iso4217CurrencyCode
%%-------------------------------------------------
{EncBytes1,EncLen1} = 'enc_Iso4217CurrencyCode'(Cindex1, []),

%%-------------------------------------------------
%% attribute amount(2) with type INTEGER
%%-------------------------------------------------
{EncBytes2,EncLen2} = encode_integer(Cindex2, [<<2>>]),

%%-------------------------------------------------
%% attribute exponent(3) with type INTEGER
%%-------------------------------------------------
{EncBytes3,EncLen3} = encode_integer(Cindex3, [<<2>>]),

BytesSoFar = [EncBytes1, EncBytes2, EncBytes3],
LenSoFar = EncLen1 + EncLen2 + EncLen3,
encode_tags(TagIn, BytesSoFar, LenSoFar).


dec_MonetaryValue(Tlv) ->
dec_MonetaryValue(Tlv, [16]).

dec_MonetaryValue(Tlv, TagIn) ->
%%-------------------------------------------------
%% decode tag and length
%%-------------------------------------------------
Tlv1 = match_tags(Tlv, TagIn),

%%-------------------------------------------------
%% attribute currency(1) External KEP:Iso4217CurrencyCode
%%-------------------------------------------------
[V1|Tlv2] = Tlv1,
Term1 = 'dec_Iso4217CurrencyCode'(V1, []),

%%-------------------------------------------------
%% attribute amount(2) with type INTEGER
%%-------------------------------------------------
[V2|Tlv3] = Tlv2,
Term2 = decode_integer(V2, [2]),

%%-------------------------------------------------
%% attribute exponent(3) with type INTEGER
%%-------------------------------------------------
[V3|Tlv4] = Tlv3,
Term3 = decode_integer(V3, [2]),

case Tlv4 of
[] -> true;_ -> exit({error,{asn1, {unexpected,Tlv4}}}) % extra fields not allowed
end,
Res1 = {'MonetaryValue',Term1,Term2,Term3},
Res1.


%%================================
%% Iso4217CurrencyCode
%%================================
enc_Iso4217CurrencyCode(Val) ->
enc_Iso4217CurrencyCode(Val, []).

enc_Iso4217CurrencyCode(Val, TagIn) ->
{EncBytes,EncLen} = case element(1,Val) of
alphabetic ->
encode_restricted_string(element(2,Val), [<<19>>]);
Else ->
exit({error,{asn1,{invalid_choice_type,Else}}})
end,

encode_tags(TagIn, EncBytes, EncLen).




dec_Iso4217CurrencyCode(Tlv) ->
dec_Iso4217CurrencyCode(Tlv, []).

dec_Iso4217CurrencyCode(Tlv, TagIn) ->
Tlv1 = match_tags(Tlv, TagIn),
case (case Tlv1 of [CtempTlv1] -> CtempTlv1; _ -> Tlv1 end) of

%% 'alphabetic'
{19, V1} ->
{alphabetic, begin
binary_to_list(decode_restricted_string(V1, []))
end
};

Else ->
exit({error,{asn1,{invalid_choice_tag,Else}}})
end
.


%%================================
%% MessageImprint
%%================================
Expand Down

0 comments on commit d773ac6

Please sign in to comment.