Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

way to retrieve a OCTET STRING from a sequence? #52

Open
ferigis opened this issue Nov 10, 2022 · 5 comments
Open

way to retrieve a OCTET STRING from a sequence? #52

ferigis opened this issue Nov 10, 2022 · 5 comments

Comments

@ferigis
Copy link

ferigis commented Nov 10, 2022

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!

@voltone
Copy link
Owner

voltone commented Nov 11, 2022

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.

@ferigis
Copy link
Author

ferigis commented Nov 11, 2022

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>>

@voltone
Copy link
Owner

voltone commented Nov 11, 2022

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
Copy link
Owner

voltone commented Nov 11, 2022

(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 😈)

@ferigis
Copy link
Author

ferigis commented Nov 11, 2022

thanks a lot! you saved my day :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants