Packages

An HTTP signature and digest header library for ActivityPub applications

Current section

Files

Jump to
hypersig src public_key_ffi.erl
Raw

src/public_key_ffi.erl

% SPDX-FileCopyrightText: 2025 Emerald <emerald@emeraldgreen.dev>
%
% SPDX-License-Identifier: GPL-3.0-or-later
-module(public_key_ffi).
-export([generate_key_pair/0, decode_public_key/1, decode_private_key/1, encode_public_key/1, encode_private_key/1, do_sign/2, do_verify/3 ]).
-include_lib("public_key/include/public_key.hrl").
encode_public_key(Ent) ->
Entry = public_key:pem_entry_encode('RSAPublicKey', Ent),
public_key:pem_encode([Entry]).
encode_private_key(Ent) ->
Entry = public_key:pem_entry_encode('RSAPrivateKey', Ent),
public_key:pem_encode([Entry]).
decode_public_key(Pem) ->
case do_decode_pem(Pem) of
{ok, Key} -> case Key of
Key = #'RSAPublicKey'{ } -> {ok, Key};
_Other -> {error, expected_public_key}
end;
Other -> Other
end.
decode_private_key(Pem) ->
case do_decode_pem(Pem) of
{ok, Key} -> case Key of
Key = #'RSAPrivateKey'{ } -> {ok, Key};
_Other -> {error, expected_private_key}
end;
Other -> Other
end.
do_decode_pem(Pem) ->
[PemEntry] = public_key:pem_decode(Pem),
case public_key:pem_entry_decode(PemEntry) of
Key = #'RSAPublicKey'{ } -> {ok, Key};
Key = #'RSAPrivateKey'{ } -> {ok, Key};
_ -> {error, unexpected_key_format}
end.
do_sign(Message, Key) ->
try
{ok, public_key:sign(Message, sha256, Key)}
catch
_:Reason:_ -> {error, {runtime_error, Reason }}
end.
do_verify(Message, Signature, Key) ->
try
{ok, public_key:verify(Message, sha256, Signature, Key)}
catch
_:Reason:_ -> {error, {runtime_error, Reason}}
end.
generate_key_pair() ->
case public_key:generate_key({rsa, 2048, 65537}) of
PrivateKey = #'RSAPrivateKey'{ } ->
PublicKey = #'RSAPublicKey'{
modulus = PrivateKey#'RSAPrivateKey'.modulus,
publicExponent = PrivateKey#'RSAPrivateKey'.publicExponent
},
{ok, {PublicKey, PrivateKey}};
_ -> {error, unexpected_key_format}
end.