[erlang-questions] public_key:pem_decode/1 and public_key:verify/4

Ingela Andin <>
Mon Jan 24 11:51:40 CET 2011

Hi Seth!

Thank you very much for working on this.  I have looked at your branch
and my thoughts are the following.

I think that the decoding of  'SubjectPublicKeyInfo',  from
pem_decode_public_key, should rather be handled in the
function pem_entry_decode. As I think the normal thing is that you
want the actual key and not a 'SubjectPublicKeyInfo', that would
mean just a little more decoding is done by pem_entry_decode. (You can
match on the 'SubjectPublicKeyInfo' in the function head to
create a clause for this.)
It will not then be a 100 % symmetric with pem_entry_encode but I
think  that is ok, it could be mentioned in the documentation.
Another reason that this is a good idea is that it will not then be
sensitive to that the public_key is the only entry in the file.
PEM files may contain several entries which is not handled by your function.

When it comes to the function der_decode_publick_key I am not sure it
is needed as I think it
is uncommon that you end up with a "DER-blob" that you do not know how
it is encoded.

Regards Ingela Erlang/OTP team - Ericssson AB

2011/1/24 Seth Falcon <>:
> Hi,
> On Fri, Jan 21, 2011 at 12:48 AM, Ingela Andin <> wrote:
>> Well PEM-files that only BEGIN PUBLIC KEY and not BEGIN RSA PUBLIC
>> KEY are using another ASN1 spec and can contain both RSA and DSA
>> keys. It seems that it is the ASN1-spec SubjectPublicKeyInfo from
>> PKIXExplicit88.asn1 also part of public_key.
> Thanks, that was a very useful hint :-)
> I can now read RSA public key PEM files as generated by openssl.
> Here's the recipe (assuming stock public_key module):
>    read_rsa_public_key(Key) ->
>        Bin = erlang:iolist_to_binary(public_key_lines(re:split(Key,
> "\n"), [])),
>        Spki = public_key:der_decode('SubjectPublicKeyInfo',
> base64:mime_decode(Bin)),
>        {_, _, {0, KeyDer}} = Spki,
>        public_key:der_decode('RSAPublicKey', KeyDer).
>    public_key_lines([<<"-----BEGIN PUBLIC KEY-----">>|Rest], Acc) ->
>        public_key_lines(Rest, Acc);
>    public_key_lines([<<"-----END PUBLIC KEY-----">>|Rest], Acc) ->
>        lists:reverse(Acc);
>    public_key_lines([Line|Rest], Acc) ->
>        public_key_lines(Rest, [Line|Acc]).
> I have a patch to the public_key module that makes this easier by
> introducing three new functions: public_key_type/1,
> pem_decode_public_key/1, and der_decode_public_key/1.
> public_key_type takes either a SubjectPublicKeyInfo record (as
> returned by der_decode/2 when given type 'SubjectPublicKeyInfo') or
> the algorithm id tuple that is a part of the 'SubjectPublicKeyInfo'
> record.  It is a wrapper for
> pubkey_cert_records:supportedPublicKeyAlgorithms/1.
> pem_decode_public_key
>    takes a PEM binary and in the case that pem_decode(PEM) returns
>    'SubjectPublicKeyInfo', it determines the public key type and does
>    der_decode so that the return value is the public key in a form
>    usable by functions like public_key:decrypt_public/2.  If the PEM
>    does not contain 'SubjectPublicKeyInfo', then it is passed through
>    unchanged.  I think this would be useful for Joakim's use case.
> der_decode_public_key
>    behaves similarly, but is given the DER encoded version of the
>    public key to start with.  Here, as I understand it, the problem
>    is a bit stickier because you can't know what type it is.  So it
>    tries each of ['SubjectPublicKeyInfo', 'RSAPublicKey',
>    'DSAPublicKey'] and returns similar to pem_decode_public_key.
> I've put the work-in-progress on a branch here:
>    https://github.com/seth/otp/tree/sf/rsa_pub_key
> I'm not sure if this is going in the right direction, so wrote this up
> (sorry for the length) to get some feedback.  I'm willing to make
> adjustments and spend time polishing a patch if there is some
> agreement on general direction.
> Best,
> + seth
> --
> Seth Falcon | @sfalcon | http://userprimary.net/

More information about the erlang-questions mailing list