View Source OpenPGP (OpenPGP v0.6.2)

OpenPGP lib allows to inspect, decode and decrypt OpenPGP Message Format as per RFC4880

As of v0.5.x:

  1. Any valid OpenPGP message can be decoded via generic OpenPGP.Packet decoder. This abstraction layer provide Packet Tags and Body Chunks for packet envelope level evaluation.
  2. Some Packet Tag specific decoders implemented with limited feature support:
    1. OpenPGP.LiteralDataPacket
    2. OpenPGP.PublicKeyEncryptedSessionKeyPacket
    3. OpenPGP.PublicKeyPacket - support only V4 packets
    4. OpenPGP.SecretKeyPacket - support only V4 packets; Iterated and Salted String-to-Key (S2K) specifier (ID: 3); S2K usage convention octet of 254 only; S2K hashing algo SHA1; AES128 symmetric encryption of secret key material
    5. OpenPGP.CompressedDataPacket - support only ZLIB- and ZIP- style blocks
    6. OpenPGP.IntegrityProtectedDataPacket - support Session Key algo 9 (AES with 256-bit key) in CFB mode; Modification Detection Code system is not supported

At a high level OpenPGP.list_packets/1 and OpenPGP.cast_packets/1 serve as an entrypoint to OpenPGP Message decoding and extracting generic data. Packet specific decoders implement OpenPGP.Packet.Behaviour, which exposes .decode/1 interface (including genric OpenPGP.Packet). Additionaly some of the packet specific decoders may provide interface for further packet processing, such as OpenPGP.SecretKeyPacket.decrypt/2.

Examples:

Decode message packets and then cast

iex> message = <<160, 24, 2, 120, 156, 243, 72, 205, 201, 201, 215, 81, 8, 207, 47, 202, 73,
...>     81, 84, 84, 4, 0, 40, 213, 4, 172>>
...>
iex> packets = OpenPGP.list_packets(message)
[
  %OpenPGP.Packet{
    body: [
      %OpenPGP.Packet.BodyChunk{
        chunk_length: {:fixed, 24},
        data: <<2, 120, 156, 243, 72, 205, 201, 201, 215, 81, 8, 207, 47, 202, 73, 81, 84,
            84, 4, 0, 40, 213, 4, 172>>,
        header_length: 1
      }
    ],
    tag: %OpenPGP.Packet.PacketTag{
      format: :old,
      length_type: {0, "one-octet"},
      tag: {8, "Compressed Data Packet"}
    }
  }
]
iex> OpenPGP.cast_packets(packets)
[
  %OpenPGP.CompressedDataPacket{
    algo: {2, "ZLIB [RFC1950]"},
    data_deflated: <<120, 156, 243, 72, 205, 201, 201, 215, 81, 8, 207, 47, 202, 73, 81, 84,
        84, 4, 0, 40, 213, 4, 172>>,
    data_inflated: "Hello, World!!!"
  }
]

Summary

Functions

Cast a generic packet %Packet{} to a speicific struct with a packet specific data assigned.

Similar to .cast_packet/1, but operates on a list of generic packets.

Encode any packet (except for %Packet{}) that implements OpenPGP.Encode protocol.

Encrypt any packet that implements OpenPGP.Encrypt protocol.

Decode all packets in a message (input). Return a list of %Packet{} structs. Does not cast packets. To cast generic packets, use .cast_packets/1 after .list_packets/1, i.e. <<...>> |> OpenPGP.list_packets() |> OpenPGP.cast_packets()

Types

@type any_packet() ::
  %OpenPGP.Packet{body: term(), tag: term()}
  | %OpenPGP.PublicKeyEncryptedSessionKeyPacket{
      ciphertext: term(),
      public_key_algo: term(),
      public_key_id: term(),
      session_key_algo: term(),
      session_key_material: term(),
      version: term()
    }
  | %OpenPGP.SecretKeyPacket{
      ciphertext: term(),
      public_key: term(),
      s2k_specifier: term(),
      s2k_usage: term(),
      secret_key_material: term(),
      sym_key_algo: term(),
      sym_key_initial_vector: term(),
      sym_key_size: term()
    }
  | %OpenPGP.PublicKeyPacket{
      algo: term(),
      created_at: term(),
      expires: term(),
      fingerprint: term(),
      id: term(),
      material: term(),
      version: term()
    }
  | %OpenPGP.CompressedDataPacket{
      algo: term(),
      data_deflated: term(),
      data_inflated: term()
    }
  | %OpenPGP.IntegrityProtectedDataPacket{
      ciphertext: term(),
      plaintext: term(),
      version: term()
    }
  | %OpenPGP.LiteralDataPacket{
      created_at: term(),
      data: term(),
      file_name: term(),
      format: term()
    }
  | %OpenPGP.ModificationDetectionCodePacket{sha: term()}

Functions

@spec cast_packet(OpenPGP.Packet.t()) :: any_packet()

Cast a generic packet %Packet{} to a speicific struct with a packet specific data assigned.

NOTE: As of 0.5.x subset of RFC4880 Packet Tags can be casted. Other Packet tags remain as %Packet{} (not casted). Should not be considered as error.

@spec cast_packets([OpenPGP.Packet.t()]) :: [any_packet()]

Similar to .cast_packet/1, but operates on a list of generic packets.

NOTE: As of 0.5.x subset of RFC4880 Packet Tags can be casted. Other Packet tags remain as %Packet{} (not casted). Should not be considered as error.

@spec encode_packet(any_packet()) :: binary()

Encode any packet (except for %Packet{}) that implements OpenPGP.Encode protocol.

Link to this function

encrypt_packet(packet, opts \\ [])

View Source
@spec encrypt_packet(packet, opts :: Keyword.t()) :: packet when packet: any_packet()

Encrypt any packet that implements OpenPGP.Encrypt protocol.

@spec list_packets(binary()) :: [OpenPGP.Packet.t()]

Decode all packets in a message (input). Return a list of %Packet{} structs. Does not cast packets. To cast generic packets, use .cast_packets/1 after .list_packets/1, i.e. <<...>> |> OpenPGP.list_packets() |> OpenPGP.cast_packets()

This function extremely handy for inspection, when operating at PTag and BodyChunk level.