View Source http_message_signatures (http_message_signatures v1.0.0-alpha.1)

Verify / Sign HTTP requests / responses using HTTP Message Signatures

RFC draft-ietf-httpbis-message-signatures-19 - https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures

Summary

Functions

Sign a HTTP request / response

Sign a HTTP request / response using JOSE JWS

Verify HTTP request / response signatures

Verify HTTP request / response signatures using JOSE JWS

Types

-type body() :: iolist() | binary().
Link to this type

component/0

View Source (since 1.0.0)
-type component() ::
    method | target_uri | authority | scheme | request_target | path | query | query_params |
    status | request_response |
    binary().
Link to this type

header/0

View Source (since 1.0.0)
-type header() :: {Field :: [byte()], Value :: header_value()}.
Link to this type

header_value/0

View Source (since 1.0.0)
-type header_value() :: binary() | iolist().
Link to this type

headers/0

View Source (since 1.0.0)
-type headers() :: [header()].
Link to this type

method/0

View Source (since 1.0.0)
-type method() :: head | get | put | patch | post | trace | options | delete.
Link to this type

parameters/0

View Source (since 1.0.0)
-type parameters() ::
    [{created, calendar:datetime()} |
     {expires, calendar:datetime()} |
     {nonce, binary()} |
     {alg, binary()} |
     {keyid, binary()} |
     {tag, binary()}].
Link to this type

request/0

View Source (since 1.0.0)
-type request() :: #{url := url(), method := method(), headers => headers(), body => body()}.
Link to this type

response/0

View Source (since 1.0.0)
-type response() :: #{status := status(), headers => headers(), body => body()}.
Link to this type

sign_base_options/0

View Source (since 1.0.0)
-type sign_base_options() ::
    #{expires => calendar:datetime(),
      created => calendar:datetime(),
      nonce => binary(),
      alg => binary(),
      keyid := binary(),
      tag => binary(),
      components => [component()],
      key => binary()}.
Link to this type

sign_jws_options/0

View Source (since 1.0.0)
-type sign_jws_options() ::
    #{expires => calendar:datetime(),
      created => calendar:datetime(),
      nonce => binary(),
      keyid := binary(),
      tag => binary(),
      components => [component()],
      key => binary()}.
Link to this type

sign_options/0

View Source (since 1.0.0)
-type sign_options() ::
    #{expires => calendar:datetime(),
      created => calendar:datetime(),
      nonce => binary(),
      alg := binary(),
      keyid := binary(),
      tag => binary(),
      components => [component()],
      key => binary(),
      signer := signer()}.
Link to this type

signer/0

View Source (since 1.0.0)
-type signer() :: fun((Data :: iolist() | binary()) -> binary()).
Link to this type

status/0

View Source (since 1.0.0)
-type status() :: 100..599.
-type url() :: uri_string:uri_string().
Link to this type

verifier/0

View Source (since 1.0.0)
-type verifier() :: verifier(term()).
Link to this type

verifier/1

View Source (since 1.0.0)
-type verifier(Reason) ::
    fun((Data :: iolist() | binary(), Signature :: binary(), Parameters :: parameters()) ->
            ok | {error, Reason}).
Link to this type

verify_error_reason/0

View Source (since 1.0.0)
-type verify_error_reason() ::
    {parse_error, Type :: signature | input, Subject :: binary(), ErrorDescription :: binary()}.
Link to this type

verify_options/0

View Source (since 1.0.0)
-type verify_options() :: verify_options(term()).
Link to this type

verify_options/1

View Source (since 1.0.0)
-type verify_options(VerifierErrorReason) :: #{verifier := verifier(VerifierErrorReason)}.

Functions

Link to this function

sign(Message, Options)

View Source (since 1.0.0)
-spec sign(Message, Options) -> Message
        when Message :: request() | response(), Options :: sign_options().

Sign a HTTP request / response

Example

  Request = #{
    method => get,
    url => <<"https://example.com/path?queryString">>,
    headers => [{"content-type", "text/plain"}]
  },
 
  SignedRequest = http_message_signatures:sign(
    Request,
    #{
      components => [method, path, <<"content-type">>],
      key => <<"sig1">>,
      signer => fun(Data) ->
        execute_signature(Data)
      end
    }
  ).
Link to this function

sign_jws(Message, Jwk, Options)

View Source (since 1.0.0)
-spec sign_jws(Message, Jwk, Options) -> Message
            when
                Message :: request() | response(),
                Jwk :: jose_jwk:key(),
                Options :: sign_jws_options().

Sign a HTTP request / response using JOSE JWS

Example

  Request = #{
    method => get,
    url => <<"https://example.com/path?queryString">>,
    headers => [{"content-type", "text/plain"}]
  },
 
  SignedRequest = http_message_signatures:sign_jws(
    Request,
    jose_jwk:from_pem_file("path-to-priv.pem"),
    #{
      components => [method, path, <<"content-type">>],
      key => <<"sig1">>
    }
  ).
Link to this function

verify(Message, Options)

View Source (since 1.0.0)
-spec verify(Message, Options) -> {ok, SignatureParameters} | {error, Reason}
          when
              Message :: request() | response(),
              Options :: verify_options(VerifierErrorReason),
              Reason :: VerifierErrorReason | verify_error_reason(),
              SignatureParameters :: #{KeyId := {[component()], parameters()}},
              KeyId :: binary().

Verify HTTP request / response signatures

Example

  SignedRequest = #{
    %% Get the signed request from somewhere
  },
 
  {ok, #{<<"sig1">> := {Components, Parameters}} = http_message_signatures:verify(
    SignedRequest,
    #{
      verifier => fun(Data, Signature, SignatureParameters) ->
        case execute_signature_verification(Data) of
          true -> ok;
          false -> {error, invalid_signature}
        end
      end
    }
  ).
Link to this function

verify_jws(Message, Jwk)

View Source (since 1.0.0)
-spec verify_jws(Message, Jwk) -> {ok, SignatureParameters} | {error, Reason}
              when
                  Message :: request() | response(),
                  Jwk :: jose_jwk:key(),
                  Reason ::
                      signature_input_mismatch | invalid_signature | none_alg_used |
                      verify_error_reason(),
                  SignatureParameters :: #{KeyId := {[component()], parameters()}},
                  KeyId :: binary().

Verify HTTP request / response signatures using JOSE JWS

Example

  SignedRequest = #{
    %% Get the signed request from somewhere
  },
 
  {ok, #{<<"sig1">> := {Components, Parameters}} = http_message_signatures:verify_jws(
    SignedRequest,
    jose_jwk:from_pem_file("path-to-pub.pem")
  ).