You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
4.1 KiB

  1. %% Vendored from hex_core v0.6.8, do not edit manually
  2. -module(r3_hex_registry).
  3. -export([
  4. encode_names/1,
  5. decode_names/2,
  6. encode_versions/1,
  7. decode_versions/2,
  8. encode_package/1,
  9. decode_package/3,
  10. sign_protobuf/2,
  11. decode_signed/1,
  12. decode_and_verify_signed/2,
  13. sign/2,
  14. verify/3
  15. ]).
  16. -include_lib("public_key/include/public_key.hrl").
  17. -type private_key() :: public_key:rsa_private_key() | binary().
  18. -type public_key() :: public_key:rsa_public_key() | binary().
  19. %%====================================================================
  20. %% API functions
  21. %%====================================================================
  22. %% @doc
  23. %% Encode Names message.
  24. encode_names(Names) ->
  25. r3_hex_pb_names:encode_msg(Names, 'Names').
  26. %% @doc
  27. %% Decode message created with encode_names/1.
  28. decode_names(Payload, no_verify) ->
  29. #{packages := Packages} = r3_hex_pb_names:decode_msg(Payload, 'Names'),
  30. {ok, Packages};
  31. decode_names(Payload, Repository) ->
  32. case r3_hex_pb_names:decode_msg(Payload, 'Names') of
  33. #{repository := Repository, packages := Packages} ->
  34. {ok, Packages};
  35. _ ->
  36. {error, unverified}
  37. end.
  38. %% @doc
  39. %% Encode Versions message.
  40. encode_versions(Versions) ->
  41. r3_hex_pb_versions:encode_msg(Versions, 'Versions').
  42. %% @doc
  43. %% Decode message created with encode_versions/1.
  44. decode_versions(Payload, no_verify) ->
  45. #{packages := Packages} = r3_hex_pb_versions:decode_msg(Payload, 'Versions'),
  46. {ok, Packages};
  47. decode_versions(Payload, Repository) ->
  48. case r3_hex_pb_versions:decode_msg(Payload, 'Versions') of
  49. #{repository := Repository, packages := Packages} ->
  50. {ok, Packages};
  51. _ ->
  52. {error, unverified}
  53. end.
  54. %% @doc
  55. %% Encode Package message.
  56. encode_package(Package) ->
  57. r3_hex_pb_package:encode_msg(Package, 'Package').
  58. %% @doc
  59. %% Decode message created with encode_package/1.
  60. decode_package(Payload, no_verify, no_verify) ->
  61. #{releases := Releases} = r3_hex_pb_package:decode_msg(Payload, 'Package'),
  62. {ok, Releases};
  63. decode_package(Payload, Repository, Package) ->
  64. case r3_hex_pb_package:decode_msg(Payload, 'Package') of
  65. #{repository := Repository, name := Package, releases := Releases} ->
  66. {ok, Releases};
  67. _ ->
  68. {error, unverified}
  69. end.
  70. %% @doc
  71. %% Encode Signed message.
  72. sign_protobuf(Payload, PrivateKey) ->
  73. Signature = sign(Payload, PrivateKey),
  74. r3_hex_pb_signed:encode_msg(#{payload => Payload, signature => Signature}, 'Signed').
  75. %% @doc
  76. %% Decode message created with sign_protobuf/2 without verification.
  77. decode_signed(Signed) ->
  78. r3_hex_pb_signed:decode_msg(Signed, 'Signed').
  79. %% @doc
  80. %% Decode message created with sign_protobuf/2 and verify it against public key.
  81. -spec decode_and_verify_signed(binary(), public_key()) -> {ok, binary()} | {error, term()}.
  82. decode_and_verify_signed(Signed, PublicKey) ->
  83. #{payload := Payload, signature := Signature} = decode_signed(Signed),
  84. case verify(Payload, Signature, PublicKey) of
  85. true -> {ok, Payload};
  86. false -> {error, unverified};
  87. {error, Reason} -> {error, Reason}
  88. end.
  89. %% @doc
  90. %% Signs binary with given private key.
  91. -spec sign(binary(), private_key()) -> binary().
  92. sign(Binary, PrivateKey) ->
  93. {ok, RSAPrivateKey} = key(PrivateKey),
  94. public_key:sign(Binary, sha512, RSAPrivateKey).
  95. %% @doc
  96. %% Verifies binary against signature and a public key.
  97. -spec verify(binary(), binary(), public_key()) -> boolean() | {error, term()}.
  98. verify(Binary, Signature, PublicKey) ->
  99. case key(PublicKey) of
  100. {ok, RSAPublicKey} -> public_key:verify(Binary, sha512, Signature, RSAPublicKey);
  101. {error, Reason} -> {error, Reason}
  102. end.
  103. %%====================================================================
  104. %% Internal functions
  105. %%====================================================================
  106. key(#'RSAPublicKey'{} = Key) ->
  107. {ok, Key};
  108. key(#'RSAPrivateKey'{} = Key) ->
  109. {ok, Key};
  110. key(Binary) when is_binary(Binary) ->
  111. case public_key:pem_decode(Binary) of
  112. [Entry | _] -> {ok, public_key:pem_entry_decode(Entry)};
  113. _ -> {error, bad_key}
  114. end.