nhpip

nhpip

Decoding an X.509 certificate

Hi,

I’ve got a project where I have to decode an X.509 certificate. I’m using Erlang’s public_key module to decode either a PEM or DER file. I get back a beautiful Erlang record. I know I can use Record for this purpose, but that seems overkill. I want to avoid adding yet another library.

Anyone got any recommendations for nicely extracting items out of a nested tuple in Elixir?

Thanks

Marked As Solved

nhpip

nhpip

Thanks. I ended up using the X509 library. Took 5 lines of code.

Also Liked

voltone

voltone

Recent OTP versions support generating code from ASN.1 that produces and accepts maps:

iex(1)> path = ~c"path/to/source/of/otp/lib/public_key/asn1/OTP-PUB-KEY.set.asn"
iex(2)> :asn1ct.compile(path, [:maps])
iex(3)> :code.load_abs(~c"OTP-PUB-KEY")
iex(4)> {:ok, cert} = :"OTP-PUB-KEY".decode(:"Certificate", der)
{:ok,
 %{
   signature: <<133, 191, 235, 15, 159, 223, 81, 127, 179, 46, 167, 62, 52, 82,
     250, 40, 4, 169, 130, 49, 63, 172, 36, 83, 164, 138, 162, 50, 233, 76, 254,
     50, 216, 144, 27, 209, 244, 68, 99, 74, 40, 207, 201, 3, 50, 87, 71, ...>>,
   tbsCertificate: %{
     version: :v3,
     signature: %{
       algorithm: {1, 2, 840, 113549, 1, 1, 11},
       parameters: <<5, 0>>
     },
     extensions: [
       %{
         critical: true,
         extnID: {2, 5, 29, 19},
         extnValue: <<48, 6, 1, 1, 255, 2, 1, 1>>
       },
       %{critical: true, extnID: {2, 5, 29, 15}, extnValue: <<3, 2, 1, 134>>},
       %{
         critical: false,
         extnID: {2, 5, 29, 14},
         extnValue: <<4, 20, 103, 184, 255, 213, 187, 5, 43, 104, 112, 7, 148,
           46, 97, 212, 57, 234, 235, 127, 203, 121>>
       },
       %{
         critical: false,
         extnID: {2, 5, 29, 35},
         extnValue: <<48, 22, 128, 20, 103, 184, 255, 213, 187, 5, 43, 104, 112,
           7, 148, 46, 97, 212, 57, 234, 235, 127, 203, 121>>
       }
     ],
     serialNumber: 4655353446208655840,
     issuer: {:rdnSequence,
      [
        [%{type: {2, 5, 4, 6}, value: <<19, 2, 85, 83>>}],
        [%{type: {2, 5, 4, 8}, value: <<12, 2, 78, 84>>}],
        [%{type: {2, 5, 4, 7}, value: "\f\vSpringfield"}],
        [%{type: {2, 5, 4, 10}, value: "\f\tACME Inc."}]
      ]},
     validity: %{
       notBefore: {:utcTime, ~c"220525065848Z"},
       notAfter: {:utcTime, ~c"470525070348Z"}
     },
     subject: {:rdnSequence,
      [
        [%{type: {2, 5, 4, 6}, value: <<19, 2, 85, 83>>}],
        [%{type: {2, 5, 4, 8}, value: <<12, 2, 78, 84>>}],
        [%{type: {2, 5, 4, 7}, value: "\f\vSpringfield"}],
        [%{type: {2, 5, 4, 10}, value: "\f\tACME Inc."}]
      ]},
     subjectPublicKeyInfo: %{
       algorithm: %{
         algorithm: {1, 2, 840, 113549, 1, 1, 1},
         parameters: <<5, 0>>
       },
       subjectPublicKey: <<48, 130, 1, 10, 2, 130, 1, 1, 0, 180, 114, 112, 36,
         255, 225, 242, 197, 38, 146, 113, 132, 20, 169, 223, 175, 93, 149, 110,
         209, 12, 217, 199, 112, 222, 188, 84, ...>>
     }
   },
   signatureAlgorithm: %{
     algorithm: {1, 2, 840, 113549, 1, 1, 11},
     parameters: <<5, 0>>
   }
 }}
iex(5)> cert.tbsCertificate.validity.notAfter
{:utcTime, ~c"470525070348Z"}
D4no0

D4no0

Pattern matching, using elem/2, are you looking for anything in particular?

I would recommend to use x509 library though, it’s really neat library written by @voltone. When you start decoding things by hand, that code is really hard to comprehend afterwards, better use a well tested library instead IMO.

voltone

voltone

You could use get_in/2 and Access.elem/1, e.g.

iex(1)> tbs = 1
iex(2)> validity = 5
iex(3)> not_after = 2
iex(4)> get_in(cert, [Access.elem(tbs), Access.elem(validity), Access.elem(not_after)])
{:utcTime, ~c"470525070659Z"}

But I also like @D4no0 's suggestion :slight_smile:

Where Next?

Popular in Questions Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 42842 311
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35953 110
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement