x509 icon indicating copy to clipboard operation
x509 copied to clipboard

way to retrieve a OCTET STRING from a sequence?

Open ferigis opened this issue 3 years ago • 5 comments

hello!

Thanks for this amazing library, it helped me a lot!

I am integrating with Apple Attest service, basically, one of the steps says this:

Obtain the value of the credCert extension with OID 1.2.840.113635.100.8.2, which is a DER-encoded ASN.1 sequence.

I think I got it doing this:

cred_cert |> Certificate.extensions() |> Extension.find({1, 2, 840, 113635, 100, 8, 2})

and that returns a tuple like this:

{:Extension, {1, 2, 840, 113635, 100, 8, 2}, false,  <<48, ...>>}

According to them, I have to "Decode the sequence and extract the single octet string that it contains".

I have been testing a lot but I have no idea how to decode that to the string they mention, do you know if there is a way to achieve that using your library?

Thanks!

ferigis avatar Nov 10 '22 18:11 ferigis

The DER encoded octet string is the last element in the tuple (or rather, Extension record), starting with <<48, ...>>. You'd have to either generate a parser based on the ASN.1 syntax for that field, or in this case it may be simpler to build it by hand (it's supposed to be just a string inside a sequence). If you can send me an example of the full binary value I can probably tell you how you'd decode it with Elixir binary parsing.

voltone avatar Nov 11 '22 13:11 voltone

hi @voltone ! thanks for your time :)

This is a real example of the octet binary:

<<48, 36, 161, 34, 4, 32, 71, 220, 233, 192, 153, 72, 52, 227, 112, 240, 147,
  240, 245, 86, 159, 50, 3, 152, 97, 81, 206, 97, 45, 66, 15, 176, 144, 184, 34,
  97, 10, 171>>

ferigis avatar Nov 11 '22 13:11 ferigis

Ok, so assuming the nonce length is always 32 bytes, and therefore none of the ASN.1 entities will every require multi-byte length encoding (which is needed for structures >127 bytes, IIRC), you should be able to do:

{:Extension, _oid, _critical, der} = Extension.find(extensions, {1, 2, 840, 113635, 100, 8, 2})
<<48, _outer_len::8, 161, len::8, seq::binary-size(len)>> = der
<<4, len::8, nonce::binary-size(len), _rest::binary>> = seq

Now you have the nonce value, and it will ignore any other values Apple may at some point add to that sequence. Again, as long as the overall structure doesn't get too big.

If you want a more robust parser you'd have to take the ASN.1 e.g. from here and use something like https://hex.pm/packages/asn1_compiler to generate a parser from it...

voltone avatar Nov 11 '22 14:11 voltone

(If you don't care about robustness in case of changes on Apple's side at all, you could just do nonce = String.slice(ext_value, -32, 32), of course 😈)

voltone avatar Nov 11 '22 14:11 voltone

thanks a lot! you saved my day :)

ferigis avatar Nov 11 '22 14:11 ferigis