Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions src/grisp_cryptoauth_cert.erl
Original file line number Diff line number Diff line change
Expand Up @@ -241,16 +241,24 @@ distinguished_name(Map) when is_map(Map) ->

%% There's no way to DER encode standard types using
%% standard modules, hence use undocumented 'OTP-PUB-KEY'
%% and some hackery
%% or 'OTP-PKIX' (Erlang 28 or younger) and some hackery

pkix_module() ->
case code:ensure_loaded('OTP-PKIX') of
{module, 'OTP-PKIX'} ->
'OTP-PKIX';
_ ->
'OTP-PUB-KEY'
end.

%% CertificateSerialNumber is derived from Integer
der_encode_Integer(Int) ->
<<T:8, _L:8, V/binary>> =
element(2, 'OTP-PUB-KEY':encode('CertificateSerialNumber', Int)),
element(2, (pkix_module()):encode('CertificateSerialNumber', Int)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By opening an erlang shell you can check this is not supported:

12> 'OTP-PKIX':encode('CertificateSerialNumber', 3333).
{error,{asn1,{{undefined_type,'CertificateSerialNumber'},
              [{'OTP-PKIX',encode_disp,2,
                           [{file,"../src/OTP-PKIX.erl"},{line,221}]},
               {'OTP-PKIX',encode,2,
                           [{file,"../src/OTP-PKIX.erl"},{line,134}]},
               {erl_eval,do_apply,7,[{file,"erl_eval.erl"},{line,924}]},
               {shell,exprs,7,[{file,"shell.erl"},{line,965}]},
               {shell,eval_exprs,7,[{file,"shell.erl"},{line,921}]},
               {shell,eval_loop,4,[{file,"shell.erl"},{line,906}]}]}}}

{T, V}.

der_decode_Integer(DER) ->
element(2, 'OTP-PUB-KEY':decode('CertificateSerialNumber',
element(2, (pkix_module()):decode('CertificateSerialNumber',
<<2, (byte_size(DER)):8, DER/binary>>)).


Expand All @@ -260,12 +268,12 @@ der_encode_GeneralizedTime({{Year, Month, Day}, _}) ->
{Int, Pad} <- [{Year, 4}, {Month, 2}, {Day, 2}]])
++ [48,48,48,48,48,48,90],
<<T:8, _L:8, V/binary>> =
element(2, 'OTP-PUB-KEY':encode('InvalidityDate', TimeString)),
element(2, (pkix_module()):encode('InvalidityDate', TimeString)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type InvalidityDate seams to be supported by the API

 public_key:der_encode('IvalidityDate', "ergreg").
** exception error: no function clause matching public_key:get_asn1_module('IvalidityDate') (public_key.erl:636)
     in function  public_key:der_encode/2 (public_key.erl:973)
15> public_key:der_encode('InvalidityDate', "ergreg").
** exception error: no case clause matching "ergreg"
     in function  'PKIX1Implicit-2009':'-getenc_CertExtensions/1-fun-0-'/3 (../src/PKIX1Implicit-2009.erl:3128)
     in call from pubkey_cert_records:'-encode_extensions/1-fun-0-'/1 (pubkey_cert_records.erl:488)
     in call from lists:map/2 (lists.erl:2385)
     in call from public_key:der_encode/2 (public_key.erl:970)
16>

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to put a correct InvalidityDate format in there I guess, I'll check how that would look like. But the type is definitely there.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh ...

3> grisp_cryptoauth_cert:der_encode_GeneralizedTime({{2025, 11, 18}, undefined}).
** exception error: no match of right hand side value
                    {asn1,{{undefined_type,'InvalidityDate'},
                           [{'OTP-PKIX',encode_disp,2,
                                        [{file,"../src/OTP-PKIX.erl"},{line,221}]},
                            {'OTP-PKIX',encode,2,
                                        [{file,"../src/OTP-PKIX.erl"},{line,134}]},
                            {grisp_cryptoauth_cert,der_encode_GeneralizedTime,1,
                                                   [{file,"grisp_cryptoauth_cert.erl"},{line,273}]},
                            {erl_eval,do_apply,7,[{file,"erl_eval.erl"},{line,924}]},
                            {shell,exprs,7,[{file,"shell.erl"},{line,965}]},
                            {shell,eval_exprs,7,[{file,"shell.erl"},{line,921}]},
                            {shell,eval_loop,4,[{file,"shell.erl"},{line,906}]}]}}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it needs a valid date, but at least public_key:der_encode( seams to support 'IvalidityDate', problem is with the others, expecially EmailAddress and CertificateSerialNumber, we will probably need to do something else for these

{T, V}.

der_decode_GeneralizedTime(DER) ->
[Y1,Y2,Y3,Y4,M1,M2,D1,D2,H1,H2,48,48,48,48,90] =
element(2, 'OTP-PUB-KEY':decode('InvalidityDate',
element(2, (pkix_module()):decode('InvalidityDate',
<<24, (byte_size(DER)):8, DER/binary>>)),
{{list_to_integer([Y1,Y2,Y3,Y4]),
list_to_integer([M1,M2]),
Expand All @@ -276,22 +284,22 @@ der_decode_GeneralizedTime(DER) ->
%% EmailAddress is derived from IA5String
der_encode_IA5String(String) ->
<<T:8, _L:8, V/binary>> =
element(2, 'OTP-PUB-KEY':encode('EmailAddress', String)),
element(2, (pkix_module()):encode('EmailAddress', String)),
{T, V}.

der_decode_IA5String(DER) ->
element(2, 'OTP-PUB-KEY':decode('EmailAddress',
element(2, (pkix_module()):decode('EmailAddress',
<<22, (byte_size(DER)):8, DER/binary>>)).


%% CertPolicyId is derived from ObjectIdentifier
der_encode_ObjectIdentifier(Id) ->
<<T:8, _L:8, V/binary>> =
element(2, 'OTP-PUB-KEY':encode('CertPolicyId', Id)),
element(2, (pkix_module()):encode('CertPolicyId', Id)),
{T, V}.

der_decode_ObjectIdentifier(DER) ->
element(2, 'OTP-PUB-KEY':decode('CertPolicyId',
element(2, (pkix_module()):decode('CertPolicyId',
<<6, (byte_size(DER)):8, DER/binary>>)).


Expand Down