Current section

Files

Jump to
saltpack lib saltpack.ex
Raw

lib/saltpack.ex

defmodule Saltpack do
@moduledoc """
saltpack implementation
https://saltpack.org/
Handling complete, ASCII-armored messages at rest.
"""
@typedoc """
a public or private key
"""
@type key :: binary
@typedoc """
desired key variety
"""
@type key_variety :: :encrypt | :sign
@typedoc """
signature mode
"""
@type signature_mode :: :attached | :detached
@doc """
generate a new `{private, public}` key pair
"""
@spec new_key_pair(key_variety) :: {key, key}
def new_key_pair(kv \\ :encrypt), do: Kcl.generate_key_pair(kv)
@doc """
encrypt a new message
`recipients` should contain a list of all recipient public keys.
An entry may be `nil` for anonymous recipients.
"""
@spec encrypt_message(binary, [key], key, key, Saltpack.Armor.formatting_options) :: binary
def encrypt_message(message, recipients, private, public \\ nil, opts \\ []) do
Saltpack.Crypt.create_message(message, recipients, private, public)
|> Saltpack.Armor.armor_message("ENCRYPTED MESSAGE", opts)
end
@doc """
sign a new message
This is presently considerably slower than encrypting a same-sized message and
has slightly different calling semantics. Where possible, `encrypt_message/5` should
be preferred.
"""
@spec sign_message(binary, key, key, signature_mode, Saltpack.Armor.formatting_options) :: binary
def sign_message(message, private, public \\ nil, mode \\ :attached, opts \\ [])
def sign_message(message, private, public, :attached, opts) do
Saltpack.Sign.create_message(message, private, 1, public)
|> Saltpack.Armor.armor_message("SIGNED MESSAGE", opts)
end
def sign_message(message, private, public, :detached, opts) do
Saltpack.Sign.create_message(message, private, 2, public)
|> Saltpack.Armor.armor_message("DETACHED SIGNATURE", opts)
end
@doc """
armor a new message
"""
@spec armor_message(binary, Saltpack.Armor.formatting_options) :: binary
def armor_message(message, opts \\ []), do: message |> Saltpack.Armor.armor_message("MESSAGE", opts)
@doc """
open a saltpack message
This may fail in spectacular ways with messages which are not properly
formatted for the supplied key.
Opening a detached signature with `plaintext` will return the signing public key.
All other forms return the decoded contents upon validation.
"""
@spec open_message(binary, key, binary) :: binary
def open_message(message, key \\ nil, plaintext \\ nil) do
case message |> Saltpack.Armor.dearmor_message do
{"ENCRYPTEDMESSAGE", msg} -> Saltpack.Crypt.open_message(msg, key)
{"SIGNEDMESSAGE", msg} -> Saltpack.Sign.open_message(msg, nil)
{"DETACHEDSIGNATURE", msg} -> Saltpack.Sign.open_message(msg, plaintext)
{"MESSAGE", msg} -> msg
_ -> raise("No properly formatted message found.")
end
end
end