diff options
Diffstat (limited to 'openpgp-ffi/include/sequoia/openpgp.h')
-rw-r--r-- | openpgp-ffi/include/sequoia/openpgp.h | 1663 |
1 files changed, 1663 insertions, 0 deletions
diff --git a/openpgp-ffi/include/sequoia/openpgp.h b/openpgp-ffi/include/sequoia/openpgp.h new file mode 100644 index 00000000..ddc6ed5a --- /dev/null +++ b/openpgp-ffi/include/sequoia/openpgp.h @@ -0,0 +1,1663 @@ +#ifndef SEQUOIA_OPENPGP_H +#define SEQUOIA_OPENPGP_H + +#include <stddef.h> +#include <stdint.h> +#include <limits.h> +#include <unistd.h> +#include <time.h> + +#include <sequoia/io.h> +#include <sequoia/openpgp/error.h> +#include <sequoia/openpgp/crypto.h> + +/*/ +/// A low-level OpenPGP message parser. +/// +/// A `PacketParser` provides a low-level, iterator-like interface to +/// parse OpenPGP messages. +/// +/// For each iteration, the user is presented with a [`Packet`] +/// corresponding to the last packet, a `PacketParser` for the next +/// packet, and their positions within the message. +/// +/// Using the `PacketParser`, the user is able to configure how the +/// new packet will be parsed. For instance, it is possible to stream +/// the packet's contents (a `PacketParser` implements the +/// `std::io::Read` and the `BufferedReader` traits), buffer them +/// within the [`Packet`], or drop them. The user can also decide to +/// recurse into the packet, if it is a container, instead of getting +/// the following packet. +/*/ +typedef struct sq_packet_parser *sq_packet_parser_t; + +/*/ +/// Like an `Option<PacketParser>`, but the `None` variant +/// (`PacketParserEOF`) contains some summary information. +/*/ +typedef struct sq_packet_parser_result *sq_packet_parser_result_t; + +/*/ +/// The `None` variant of a `PacketParserResult`. +/*/ +typedef struct sq_packet_parser_eof *sq_packet_parser_eof_t; + +/* sequoia::openpgp::KeyID. */ + +/*/ +/// Holds a KeyID. +/*/ +typedef struct sq_keyid *sq_keyid_t; + +/*/ +/// Reads a binary key ID. +/*/ +sq_keyid_t sq_keyid_from_bytes (const uint8_t *id); + +/*/ +/// Reads a hex-encoded Key ID. +/*/ +sq_keyid_t sq_keyid_from_hex (const char *id); + +/*/ +/// Frees a sq_keyid_t. +/*/ +void sq_keyid_free (sq_keyid_t keyid); + +/*/ +/// Clones the KeyID. +/*/ +sq_keyid_t sq_keyid_clone (sq_keyid_t keyid); + +/*/ +/// Hashes the KeyID. +/*/ +uint64_t sq_keyid_hash (sq_keyid_t keyid); + +/*/ +/// Converts the KeyID to its standard representation. +/*/ +char *sq_keyid_to_string (const sq_keyid_t fp); + +/*/ +/// Converts the KeyID to a hexadecimal number. +/*/ +char *sq_keyid_to_hex (const sq_keyid_t keyid); + +/*/ +/// Compares KeyIDs. +/*/ +int sq_keyid_equal (const sq_keyid_t a, const sq_keyid_t b); + + +/* sequoia::openpgp::Fingerprint. */ + +/*/ +/// Holds a fingerprint. +/*/ +typedef struct sq_fingerprint *sq_fingerprint_t; + +/*/ +/// Reads a binary fingerprint. +/*/ +sq_fingerprint_t sq_fingerprint_from_bytes (const uint8_t *buf, size_t len); + +/*/ +/// Reads a hexadecimal fingerprint. +/*/ +sq_fingerprint_t sq_fingerprint_from_hex (const char *hex); + +/*/ +/// Frees a sq_fingerprint_t. +/*/ +void sq_fingerprint_free (sq_fingerprint_t fp); + +/*/ +/// Clones the Fingerprint. +/*/ +sq_fingerprint_t sq_fingerprint_clone (sq_fingerprint_t fingerprint); + +/*/ +/// Hashes the Fingerprint. +/*/ +uint64_t sq_fingerprint_hash (sq_fingerprint_t fingerprint); + +/*/ +/// Returns a reference to the raw Fingerprint. +/// +/// This returns a reference to the internal buffer that is valid as +/// long as the fingerprint is. +/*/ +uint8_t *sq_fingerprint_as_bytes (const sq_fingerprint_t fp, size_t *fp_len); + +/*/ +/// Converts the fingerprint to its standard representation. +/*/ +char *sq_fingerprint_to_string (const sq_fingerprint_t fp); + +/*/ +/// Converts the fingerprint to a hexadecimal number. +/*/ +char *sq_fingerprint_to_hex (const sq_fingerprint_t fp); + +/*/ +/// Converts the fingerprint to a key ID. +/*/ +sq_keyid_t sq_fingerprint_to_keyid (const sq_fingerprint_t fp); + +/*/ +/// Compares Fingerprints. +/*/ +int sq_fingerprint_equal (const sq_fingerprint_t a, const sq_fingerprint_t b); + +/* sequoia::openpgp::RevocationStatus. */ + +/*/ +/// Holds a revocation status. +/*/ +typedef struct sq_revocation_status *sq_revocation_status_t; + +typedef enum sq_revocation_status_variant { + /*/ + /// The key is definitely revoked. + /// + /// All self-revocations are returned, the most recent revocation + /// first. + /*/ + SQ_REVOCATION_STATUS_REVOKED, + + /*/ + /// We have a third-party revocation certificate that is allegedly + /// from a designated revoker, but we don't have the designated + /// revoker's key to check its validity. + /// + /// All such certificates are returned. The caller must check + /// them manually. + /*/ + SQ_REVOCATION_STATUS_COULD_BE, + + /*/ + /// The key does not appear to be revoked, but perhaps an attacker + /// has performed a DoS, which prevents us from seeing the + /// revocation certificate. + /*/ + SQ_REVOCATION_STATUS_NOT_AS_FAR_AS_WE_KNOW, + + /* Dummy value to make sure the enumeration has a defined size. Do + not use this value. */ + SQ_REVOCATION_STATUS_FORCE_WIDTH = INT_MAX, +} sq_revocation_status_variant_t; + +/*/ +/// Returns the revocation status's variant. +/*/ +sq_revocation_status_variant_t sq_revocation_status_variant ( + sq_revocation_status_t rs); + +/*/ +/// Frees the revocation status. +/*/ +void sq_revocation_status_free (sq_revocation_status_t rs); + + +/* openpgp::armor. */ + +/*/ +/// Specifies the type of data (see [RFC 4880, section 6.2]). +/// +/// [RFC 4880, section 6.2]: https://tools.ietf.org/html/rfc4880#section-6.2 +/*/ +typedef enum sq_armor_kind { + /*/ + /// When reading an Armored file, accept any type. + /*/ + SQ_ARMOR_KIND_ANY, + + /*/ + /// A generic OpenPGP message. + /*/ + SQ_ARMOR_KIND_MESSAGE, + + /*/ + /// A transferable public key. + /*/ + SQ_ARMOR_KIND_PUBLICKEY, + + /*/ + /// A transferable secret key. + /*/ + SQ_ARMOR_KIND_SECRETKEY, + + /*/ + /// A detached signature. + /*/ + SQ_ARMOR_KIND_SIGNATURE, + + /*/ + /// A generic file. This is a GnuPG extension. + /*/ + SQ_ARMOR_KIND_FILE, + + /* Dummy value to make sure the enumeration has a defined size. Do + not use this value. */ + SQ_ARMOR_KIND_FORCE_WIDTH = INT_MAX, +} sq_armor_kind_t; + +/*/ +/// Represents a (key, value) pair in an armor header. +/*/ +typedef struct sq_armor_header { + char *key; + char *value; +} sq_armor_header_t; + + +/*/ +/// Constructs a new filter for the given type of data. +/// +/// A filter that strips ASCII Armor from a stream of data. +/*/ +sq_reader_t sq_armor_reader_new (sq_reader_t inner, sq_armor_kind_t kind); + +/*/ +/// Creates a `Reader` from a file. +/*/ +sq_reader_t sq_armor_reader_from_file (sq_error_t *errp, + const char *filename, + sq_armor_kind_t kind); + +/*/ +/// Creates a `Reader` from a buffer. +/*/ +sq_reader_t sq_armor_reader_from_bytes (const uint8_t *b, size_t len, + sq_armor_kind_t kind); + + +/*/ +/// Returns the kind of data this reader is for. +/// +/// Useful if the kind of data is not known in advance. If the header +/// has not been encountered yet (try reading some data first!), this +/// function returns SQ_ARMOR_KIND_ANY. +/*/ +sq_armor_kind_t sq_armor_reader_kind (sq_reader_t reader); + +/*/ +/// Returns the armored headers. +/// +/// The tuples contain a key and a value. +/// +/// Note: if a key occurs multiple times, then there are multiple +/// entries in the vector with the same key; values with the same +/// key are *not* combined. +/// +/// The returned array and the strings in the headers have been +/// allocated with `malloc`, and the caller is responsible for freeing +/// both the array and the strings. +/*/ +sq_armor_header_t *sq_armor_reader_headers (sq_error_t *errp, + sq_reader_t reader, + size_t *len); + + +/*/ +/// Constructs a new filter for the given type of data. +/// +/// A filter that applies ASCII Armor to the data written to it. +/*/ +sq_writer_t sq_armor_writer_new (sq_error_t *errp, sq_writer_t inner, + sq_armor_kind_t kind, + sq_armor_header_t *header, size_t header_len); + + + +/*/ +/// The OpenPGP packet tags as defined in [Section 4.3 of RFC 4880]. +/// +/// [Section 4.3 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-4.3 +/// +/// The values correspond to the serialized format. The packet types +/// named `UnassignedXX` are not in use as of RFC 4880. +/// +/// Use [`Tag::from_numeric`] to translate a numeric value to a symbolic +/// one. +/// +/// [`Tag::from_numeric`]: enum.Tag.html#method.from_numeric +/*/ +typedef enum sq_tag { + SQ_TAG_RESERVED0 = 0, + /* Public-Key Encrypted Session Key Packet. */ + SQ_TAG_PKESK = 1, + SQ_TAG_SIGNATURE = 2, + /* Symmetric-Key Encrypted Session Key Packet. */ + SQ_TAG_SKESK = 3, + /* One-Pass Signature Packet. */ + SQ_TAG_ONE_PASS_SIG = 4, + SQ_TAG_SECRET_KEY = 5, + SQ_TAG_PUBLIC_KEY = 6, + SQ_TAG_SECRET_SUBKEY = 7, + SQ_TAG_COMPRESSED_DATA = 8, + /* Symmetrically Encrypted Data Packet. */ + SQ_TAG_SED = 9, + SQ_TAG_MARKER = 10, + SQ_TAG_LITERAL = 11, + SQ_TAG_TRUST = 12, + SQ_TAG_USER_ID = 13, + SQ_TAG_PUBLIC_SUBKEY = 14, + + SQ_TAG_UNASSIGNED15 = 15, + SQ_TAG_UNASSIGNED16 = 16, + + SQ_TAG_USER_ATTRIBUTE = 17, + /* Sym. Encrypted and Integrity Protected Data Packet. */ + SQ_TAG_SEIP = 18, + /* Modification Detection Code Packet. */ + SQ_TAG_MDC = 19, + + /* Unassigned packets (as of RFC4880). */ + SQ_TAG_UNASSIGNED20 = 20, + SQ_TAG_UNASSIGNED21 = 21, + SQ_TAG_UNASSIGNED22 = 22, + SQ_TAG_UNASSIGNED23 = 23, + SQ_TAG_UNASSIGNED24 = 24, + SQ_TAG_UNASSIGNED25 = 25, + SQ_TAG_UNASSIGNED26 = 26, + SQ_TAG_UNASSIGNED27 = 27, + SQ_TAG_UNASSIGNED28 = 28, + SQ_TAG_UNASSIGNED29 = 29, + + SQ_TAG_UNASSIGNED30 = 30, + SQ_TAG_UNASSIGNED31 = 31, + SQ_TAG_UNASSIGNED32 = 32, + SQ_TAG_UNASSIGNED33 = 33, + SQ_TAG_UNASSIGNED34 = 34, + SQ_TAG_UNASSIGNED35 = 35, + SQ_TAG_UNASSIGNED36 = 36, + SQ_TAG_UNASSIGNED37 = 37, + SQ_TAG_UNASSIGNED38 = 38, + SQ_TAG_UNASSIGNED39 = 39, + + SQ_TAG_UNASSIGNED40 = 40, + SQ_TAG_UNASSIGNED41 = 41, + SQ_TAG_UNASSIGNED42 = 42, + SQ_TAG_UNASSIGNED43 = 43, + SQ_TAG_UNASSIGNED44 = 44, + SQ_TAG_UNASSIGNED45 = 45, + SQ_TAG_UNASSIGNED46 = 46, + SQ_TAG_UNASSIGNED47 = 47, + SQ_TAG_UNASSIGNED48 = 48, + SQ_TAG_UNASSIGNED49 = 49, + + SQ_TAG_UNASSIGNED50 = 50, + SQ_TAG_UNASSIGNED51 = 51, + SQ_TAG_UNASSIGNED52 = 52, + SQ_TAG_UNASSIGNED53 = 53, + SQ_TAG_UNASSIGNED54 = 54, + SQ_TAG_UNASSIGNED55 = 55, + SQ_TAG_UNASSIGNED56 = 56, + SQ_TAG_UNASSIGNED57 = 57, + SQ_TAG_UNASSIGNED58 = 58, + SQ_TAG_UNASSIGNED59 = 59, + + /* Experimental packets. */ + SQ_TAG_PRIVATE0 = 60, + SQ_TAG_PRIVATE1 = 61, + SQ_TAG_PRIVATE2 = 62, + SQ_TAG_PRIVATE3 = 63, +} sq_tag_t; + +/*/ +/// Returns a human-readable tag name. +/*/ +const char *sq_tag_to_string (sq_tag_t tag); + +/*/ +/// Opaque types for all the Packets that Sequoia understands. +/*/ +typedef struct sq_unknown *sq_unknown_t; +typedef struct sq_signature *sq_signature_t; +typedef struct sq_one_pass_sig *sq_one_pass_sig_t; +typedef struct sq_p_key *sq_p_key_t; +typedef struct sq_user_id *sq_user_id_t; +typedef struct sq_user_attribute *sq_user_attribute_t; +typedef struct sq_literal *sq_literal_t; +typedef struct sq_compressed_data *sq_compressed_data_t; +typedef struct sq_pkesk *sq_pkesk_t; +typedef struct sq_skesk *sq_skesk_t; +typedef struct sq_seip *sq_seip_t; +typedef struct sq_mdc *sq_mdc_t; + +/*/ +/// The OpenPGP packets that Sequoia understands. +/// +/// The different OpenPGP packets are detailed in [Section 5 of RFC 4880]. +/// +/// The `Unknown` packet allows Sequoia to deal with packets that it +/// doesn't understand. The `Unknown` packet is basically a binary +/// blob that includes the packet's tag. +/// +/// The unknown packet is also used for packets that are understood, +/// but use unsupported options. For instance, when the packet parser +/// encounters a compressed data packet with an unknown compression +/// algorithm, it returns the packet in an `Unknown` packet rather +/// than a `CompressedData` packet. +/// +/// [Section 5 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5 +/*/ +typedef union sq_packet { + sq_unknown_t unknown; + sq_signature_t signature; + sq_one_pass_sig_t one_pass_sig; + sq_p_key_t key; + sq_user_id_t user_id; + sq_user_attribute_t user_attribute; + sq_literal_t literal; + sq_compressed_data_t compressed_data; + sq_pkesk_t pkesk; + sq_skesk_t skesk; + sq_seip_t seip; + sq_mdc_t mdc; +} sq_packet_t; + +/*/ +/// Frees the Packet. +/*/ +void sq_packet_free (sq_packet_t p); + +/*/ +/// Returns the `Packet's` corresponding OpenPGP tag. +/// +/// Tags are explained in [Section 4.3 of RFC 4880]. +/// +/// [Section 4.3 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-4.3 +/*/ +sq_tag_t sq_packet_tag (sq_packet_t p); + +/*/ +/// Returns the parsed `Packet's` corresponding OpenPGP tag. +/// +/// Returns the packets tag, but only if it was successfully +/// parsed into the corresponding packet type. If e.g. a +/// Signature Packet uses some unsupported methods, it is parsed +/// into an `Packet::Unknown`. `tag()` returns `SQ_TAG_SIGNATURE`, +/// whereas `kind()` returns `0`. +/*/ +sq_tag_t sq_packet_kind (sq_packet_t p); + +/* openpgp::PacketPile. */ + +/*/ +/// A `PacketPile` holds a deserialized OpenPGP message. +/*/ +typedef struct sq_packet_pile *sq_packet_pile_t; + +/*/ +/// Deserializes the OpenPGP message stored in a `std::io::Read` +/// object. +/// +/// Although this method is easier to use to parse an OpenPGP +/// packet pile than a `PacketParser` or a `PacketPileParser`, this +/// interface buffers the whole packet pile in memory. Thus, the +/// caller must be certain that the *deserialized* packet pile is not +/// too large. +/// +/// Note: this interface *does* buffer the contents of packets. +/*/ +sq_packet_pile_t sq_packet_pile_from_reader (sq_error_t *errp, + sq_reader_t reader); + +/*/ +/// Deserializes the OpenPGP packet pile stored in the file named by +/// `filename`. +/// +/// See `sq_packet_pile_from_reader` for more details and caveats. +/*/ +sq_packet_pile_t sq_packet_pile_from_file (sq_error_t *errp, + const char *filename); + +/*/ +/// Deserializes the OpenPGP packet pile stored in the provided buffer. +/// +/// See `sq_packet_pile_from_reader` for more details and caveats. +/*/ +sq_packet_pile_t sq_packet_pile_from_bytes (sq_error_t *errp, + const uint8_t *b, size_t len); + +/*/ +/// Frees the packet pile. +/*/ +void sq_packet_pile_free (sq_packet_pile_t message); + +/*/ +/// Clones the packet pile. +/*/ +sq_packet_pile_t sq_packet_pile_clone (sq_packet_pile_t message); + +/*/ +/// Serializes the packet pile. +/*/ +sq_status_t sq_packet_pile_serialize (sq_error_t *errp, + const sq_packet_pile_t message, + sq_writer_t writer); + +/*/ +/// Frees the signature. +/*/ +void sq_signature_free (sq_signature_t signature); + +/*/ +/// Converts the signature to a packet. +/*/ +sq_packet_t sq_signature_to_packet (sq_signature_t signature); + +/*/ +/// Returns the value of the `Signature` packet's Issuer subpacket. +/// +/// If there is no Issuer subpacket, this returns NULL. Note: if +/// there is no Issuer subpacket, but there is an IssuerFingerprint +/// subpacket, this still returns NULL. +/*/ +sq_keyid_t sq_signature_issuer(sq_signature_t sig); + +/*/ +/// Returns the value of the `Signature` packet's IssuerFingerprint subpacket. +/// +/// If there is no IssuerFingerprint subpacket, this returns NULL. +/// Note: if there is no IssuerFingerprint subpacket, but there is an +/// Issuer subpacket, this still returns NULL. +/*/ +sq_fingerprint_t sq_signature_issuer_fingerprint(sq_signature_t sig); + +/*/ +/// Returns whether the KeyFlags indicates that the key can be used to +/// make certifications. +/*/ +int sq_signature_can_certify(sq_signature_t signature); + +/*/ +/// Returns whether the KeyFlags indicates that the key can be used to +/// make signatures. +/*/ +int sq_signature_can_sign(sq_signature_t signature); + +/*/ +/// Returns whether the KeyFlags indicates that the key can be used to +/// encrypt data for transport. +/*/ +int sq_signature_can_encrypt_for_transport(sq_signature_t signature); + +/*/ +/// Returns whether the KeyFlags indicates that the key can be used to +/// encrypt data at rest. +/*/ +int sq_signature_can_encrypt_at_rest(sq_signature_t signature); + +/*/ +/// Returns whether the KeyFlags indicates that the key can be used +/// for authentication. +/*/ +int sq_signature_can_authenticate(sq_signature_t signature); + +/*/ +/// Returns whether the KeyFlags indicates that the key is a split +/// key. +/*/ +int sq_signature_is_split_key(sq_signature_t signature); + +/*/ +/// Returns whether the KeyFlags indicates that the key is a group +/// key. +/*/ +int sq_signature_is_group_key(sq_signature_t signature); + +/*/ +/// Returns whether the signature is alive. +/// +/// A signature is alive if the creation date is in the past, and the +/// signature has not expired. +/*/ +int sq_signature_alive(sq_signature_t signature); + +/*/ +/// Returns whether the signature is alive at the specified time. +/// +/// A signature is alive if the creation date is in the past, and the +/// signature has not expired at the specified time. +/*/ +int sq_signature_alive_at(sq_signature_t signature, time_t when); + +/*/ +/// Returns whether the signature is expired. +/*/ +int sq_signature_expired(sq_signature_t signature); + +/*/ +/// Returns whether the signature is expired at the specified time. +/*/ +int sq_signature_expired_at(sq_signature_t signature, time_t when); + +/*/ +/// Returns the PKESK's recipient. +/// +/// The return value is a reference ot a `KeyID`. The caller must not +/// modify or free it. +/*/ +sq_keyid_t sq_pkesk_recipient(sq_pkesk_t pkesk); + +/*/ +/// Returns the session key. +/// +/// `key` of size `key_len` must be a buffer large enough to hold the +/// session key. If `key` is NULL, or not large enough, then the key +/// is not written to it. Either way, `key_len` is set to the size of +/// the session key. +/*/ +sq_status_t sq_pkesk_decrypt (sq_error_t *errp, sq_pkesk_t pkesk, + sq_p_key_t secret_key, + uint8_t *algo, /* XXX */ + uint8_t *key, size_t *key_len); + +typedef enum sq_reason_for_revocation { + /*/ + /// No reason specified (key revocations or cert revocations) + /*/ + SQ_REASON_FOR_REVOCATION_UNSPECIFIED, + + /*/ + /// Key is superseded (key revocations) + /*/ + SQ_REASON_FOR_REVOCATION_KEY_SUPERSEDED, + + /*/ + /// Key material has been compromised (key revocations) + /*/ + SQ_REASON_FOR_REVOCATION_KEY_COMPROMISED, + + /*/ + /// Key is retired and no longer used (key revocations) + /*/ + SQ_REASON_FOR_REVOCATION_KEY_RETIRED, + + /*/ + /// User ID information is no longer valid (cert revocations) + /*/ + SQ_REASON_FOR_REVOCATION_UID_RETIRED, + + /* Dummy value to make sure the enumeration has a defined size. Do + not use this value. */ + SQ_REASON_FOR_REVOCATION_FORCE_WIDTH = INT_MAX, +} sq_reason_for_revocation_t; + +/* openpgp::tpk::UserIDBinding. */ + +/*/ +/// A `UserIDBinding`. +/*/ +typedef struct sq_user_id_binding *sq_user_id_binding_t; + +/*/ +/// Returns the user id. +/// +/// This function may fail and return NULL if the user id contains an +/// interior NUL byte. We do this rather than complicate the API, as +/// there is no valid use for such user ids; they must be malicious. +/// +/// The caller must free the returned value. +/*/ +char *sq_user_id_binding_user_id (sq_user_id_binding_t binding); + +/*/ +/// Returns a reference to the self-signature, if any. +/*/ +sq_signature_t sq_user_id_binding_selfsig(sq_user_id_binding_t binding); + +/* openpgp::tpk::UserIDBindingIter. */ + +/*/ +/// An iterator over `UserIDBinding`s. +/*/ +typedef struct sq_user_id_binding_iter *sq_user_id_binding_iter_t; + +/*/ +/// Returns the next element in the iterator. +/*/ +sq_user_id_binding_t sq_user_id_binding_iter_next (sq_user_id_binding_iter_t iter); + +/// Frees an sq_user_id_binding_iter_t. +void sq_user_id_binding_iter_free (sq_user_id_binding_iter_t iter); + +/* openpgp::tpk::KeyIter. */ + +/*/ +/// An iterator over keys in a TPK. +/*/ +typedef struct sq_tpk_key_iter *sq_tpk_key_iter_t; + +/*/ +/// Returns the next key. Returns NULL if there are no more elements. +/// +/// If sigo is not NULL, stores the current self-signature (if any) in +/// *sigo. (Note: subkeys always have signatures, but a primary key +/// may not have a direct signature, and there might not be any user +/// ids.) +/// +/// If rso is not NULL, this stores the key's revocation status in +/// *rso. +/*/ +sq_p_key_t sq_tpk_key_iter_next (sq_tpk_key_iter_t iter, + sq_signature_t *signature, + sq_revocation_status_t *rev); + +/// Frees an sq_tpk_key_iter_t. +void sq_tpk_key_iter_free (sq_tpk_key_iter_t iter); + +/* openpgp::tpk. */ + +/*/ +/// A transferable public key (TPK). +/// +/// A TPK (see [RFC 4880, section 11.1]) can be used to verify +/// signatures and encrypt data. It can be stored in a keystore and +/// uploaded to keyservers. +/// +/// [RFC 4880, section 11.1]: https://tools.ietf.org/html/rfc4880#section-11.1 +/*/ +typedef struct sq_tpk *sq_tpk_t; + + +/*/ +/// A transferable secret key (TSK). +/// +/// A TSK (see [RFC 4880, section 11.2]) can be used to create +/// signatures and decrypt data. +/// +/// [RFC 4880, section 11.2]: https://tools.ietf.org/html/rfc4880#section-11.2 +/*/ +typedef struct sq_tsk *sq_tsk_t; + + +/*/ +/// Returns the first TPK encountered in the reader. +/*/ +sq_tpk_t sq_tpk_from_reader (sq_error_t *errp, + sq_reader_t reader); + +/*/ +/// Returns the first TPK encountered in the file. +/*/ +sq_tpk_t sq_tpk_from_file (sq_error_t *errp, + const char *filename); + +/*/ +/// Returns the first TPK found in `m`. +/// +/// Consumes `m`. +/*/ +sq_tpk_t sq_tpk_from_packet_pile (sq_error_t *errp, + sq_packet_pile_t m); + +/*/ +/// Returns the first TPK found in `buf`. +/// +/// `buf` must be an OpenPGP-encoded TPK. +/*/ +sq_tpk_t sq_tpk_from_bytes (sq_error_t *errp, + const uint8_t *b, size_t len); + +/*/ +/// Returns the first TPK found in the packet parser. +/// +/// Consumes the packet parser result. +/*/ +sq_tpk_t sq_tpk_from_packet_parser (sq_error_t *errp, + sq_packet_parser_result_t ppr); + +/*/ +/// Frees the TPK. +/*/ +void sq_tpk_free (sq_tpk_t tpk); + +/*/ +/// Clones the TPK. +/*/ +sq_tpk_t sq_tpk_clone (sq_tpk_t tpk); + +/*/ +/// Compares TPKs. +/*/ +int sq_tpk_equal (const sq_tpk_t a, const sq_tpk_t b); + +/*/ +/// Serializes the TPK. +/*/ +sq_status_t sq_tpk_serialize (sq_error_t *errp, + const sq_tpk_t tpk, + sq_writer_t writer); + +/*/ +/// Merges `other` into `tpk`. +/// +/// If `other` is a different key, then nothing is merged into +/// `tpk`, but `tpk` is still canonicalized. +/// +/// Consumes `tpk` and `other`. +/*/ +sq_tpk_t sq_tpk_merge (sq_error_t *errp, + sq_tpk_t tpk, + sq_tpk_t other); + +/*/ +/// Adds packets to the TPK. +/// +/// This recanonicalizes the TPK. If the packets are invalid, they +/// are dropped. +/// +/// Consumes `tpk` and the packets in `packets`. The buffer, however, +/// must be freed by the caller. +/*/ +sq_tpk_t sq_tpk_merge_packets (sq_error_t *errp, + sq_tpk_t tpk, + sq_packet_t *packets, + size_t packets_len); +/*/ +/// Dumps the TPK. +/*/ +void sq_tpk_dump (const sq_tpk_t tpk); + +/*/ +/// Returns the fingerprint. +/*/ +sq_fingerprint_t sq_tpk_fingerprint (const sq_tpk_t tpk); + + +/*/ +/// Cast the public key into a secret key that allows using the secret +/// parts of the containing keys. +/*/ +sq_tsk_t sq_tpk_into_tsk (sq_tpk_t tpk); + +/*/ +/// Returns a reference to the TPK's primary key. +/// +/// The tpk still owns the key. The caller should neither modify nor +/// free the key. +/*/ +sq_p_key_t sq_tpk_primary (sq_tpk_t tpk); + +/*/ +/// Returns the TPK's revocation status. +/// +/// Note: this only returns whether the TPK has been revoked, and does +/// not reflect whether an individual user id, user attribute or +/// subkey has been revoked. +/*/ +sq_revocation_status_t sq_tpk_revocation_status (sq_tpk_t tpk); + +/*/ +/// Writes a revocation certificate to the writer. +/// +/// This function consumes the writer. It does *not* consume tpk. +/*/ +sq_signature_t sq_tpk_revoke (sq_error_t *errp, + sq_tpk_t tpk, + sq_signer_t primary_signer, + sq_reason_for_revocation_t code, + const char *reason); + +/*/ +/// Adds a revocation certificate to the tpk. +/// +/// This function consumes the tpk. +/*/ +sq_tpk_t sq_tpk_revoke_in_place (sq_error_t *errp, + sq_tpk_t tpk, + sq_signer_t primary_signer, + sq_reason_for_revocation_t code, + const char *reason); + +/*/ +/// Returns whether the TPK has expired. +/*/ +int sq_tpk_expired(sq_tpk_t tpk); + +/*/ +/// Returns whether the TPK has expired at the specified time. +/*/ +int sq_tpk_expired_at(sq_tpk_t tpk, time_t at); + +/*/ +/// Returns whether the TPK is alive. +/*/ +int sq_tpk_alive(sq_tpk_t tpk); + +/*/ +/// Returns whether the TPK is alive at the specified time. +/*/ +int sq_tpk_alive_at(sq_tpk_t tpk, time_t at); + +/*/ +/// Changes the TPK's expiration. +/// +/// Expiry is when the key should expire in seconds relative to the +/// key's creation (not the current time). +/// +/// This function consumes `tpk` and returns a new `TPK`. +/*/ +sq_tpk_t sq_tpk_set_expiry(sq_error_t *errp, + sq_tpk_t tpk, + uint32_t expiry); + +/*/ +/// Returns whether the TPK includes any secret key material. +/*/ +int sq_tpk_is_tsk(sq_tpk_t tpk); + +/*/ +/// Returns an iterator over the `UserIDBinding`s. +/*/ +sq_user_id_binding_iter_t sq_tpk_user_id_binding_iter (sq_tpk_t tpk); + +/*/ |