diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/third_party/rnp/include | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/third_party/rnp/include')
-rw-r--r-- | comm/third_party/rnp/include/rekey/rnp_key_store.h | 149 | ||||
-rw-r--r-- | comm/third_party/rnp/include/repgp/repgp_def.h | 505 | ||||
-rw-r--r-- | comm/third_party/rnp/include/rnp.h | 42 | ||||
-rw-r--r-- | comm/third_party/rnp/include/rnp/rnp.h | 3150 | ||||
-rw-r--r-- | comm/third_party/rnp/include/rnp/rnp_def.h | 35 | ||||
-rw-r--r-- | comm/third_party/rnp/include/rnp/rnp_err.h | 77 |
6 files changed, 3958 insertions, 0 deletions
diff --git a/comm/third_party/rnp/include/rekey/rnp_key_store.h b/comm/third_party/rnp/include/rekey/rnp_key_store.h new file mode 100644 index 0000000000..04faabf75f --- /dev/null +++ b/comm/third_party/rnp/include/rekey/rnp_key_store.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2017, [Ribose Inc](https://www.ribose.com). + * All rights reserved. + * + * This code is originally derived from software contributed to + * The NetBSD Foundation by Alistair Crooks (agc@netbsd.org), and + * carried further by Ribose Inc (https://www.ribose.com). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef KEY_STORE_H_ +#define KEY_STORE_H_ + +#include <stdint.h> +#include <stdbool.h> +#include "rnp.h" +#include "librepgp/stream-common.h" +#include "pgp-key.h" +#include <string> +#include <list> +#include <map> +#include <unordered_map> +#include <memory> +#include "librekey/kbx_blob.hpp" +#include "sec_profile.hpp" + +/* Key import status. Order of elements is important. */ +typedef enum pgp_key_import_status_t { + PGP_KEY_IMPORT_STATUS_UNKNOWN = 0, + PGP_KEY_IMPORT_STATUS_UNCHANGED, + PGP_KEY_IMPORT_STATUS_UPDATED, + PGP_KEY_IMPORT_STATUS_NEW, +} pgp_key_import_status_t; + +typedef enum pgp_sig_import_status_t { + PGP_SIG_IMPORT_STATUS_UNKNOWN = 0, + PGP_SIG_IMPORT_STATUS_UNKNOWN_KEY, + PGP_SIG_IMPORT_STATUS_UNCHANGED, + PGP_SIG_IMPORT_STATUS_NEW +} pgp_sig_import_status_t; + +typedef std::unordered_map<pgp_fingerprint_t, std::list<pgp_key_t>::iterator> pgp_key_fp_map_t; + +typedef struct rnp_key_store_t { + std::string path; + pgp_key_store_format_t format; + rnp::SecurityContext & secctx; + bool disable_validation = + false; /* do not automatically validate keys, added to this key store */ + + std::list<pgp_key_t> keys; + pgp_key_fp_map_t keybyfp; + std::vector<std::unique_ptr<kbx_blob_t>> blobs; + + ~rnp_key_store_t(); + rnp_key_store_t(rnp::SecurityContext &ctx) + : path(""), format(PGP_KEY_STORE_UNKNOWN), secctx(ctx){}; + rnp_key_store_t(pgp_key_store_format_t format, + const std::string & path, + rnp::SecurityContext & ctx); + /* make sure we use only empty constructor */ + rnp_key_store_t(rnp_key_store_t &&src) = delete; + rnp_key_store_t &operator=(rnp_key_store_t &&) = delete; + rnp_key_store_t(const rnp_key_store_t &src) = delete; + rnp_key_store_t &operator=(const rnp_key_store_t &) = delete; +} rnp_key_store_t; + +bool rnp_key_store_load_from_path(rnp_key_store_t *, const pgp_key_provider_t *key_provider); +bool rnp_key_store_load_from_src(rnp_key_store_t *, + pgp_source_t *, + const pgp_key_provider_t *key_provider); + +bool rnp_key_store_write_to_path(rnp_key_store_t *); +bool rnp_key_store_write_to_dst(rnp_key_store_t *, pgp_dest_t *); + +void rnp_key_store_clear(rnp_key_store_t *); + +size_t rnp_key_store_get_key_count(const rnp_key_store_t *); + +/** + * @brief Add key to the keystore, copying it. + * + * @param keyring allocated keyring, cannot be NULL. + * @param key key to be added, cannot be NULL. + * @return pointer to the added key or NULL if failed. + */ +pgp_key_t *rnp_key_store_add_key(rnp_key_store_t *keyring, pgp_key_t *key); + +pgp_key_t *rnp_key_store_import_key(rnp_key_store_t *, + pgp_key_t *, + bool, + pgp_key_import_status_t *); + +/** + * @brief Get signer's key from key store. + * + * @param store populated key store, cannot be NULL. + * @param sig signature, cannot be NULL. + * @return pointer to pgp_key_t structure if key was found or NULL otherwise. + */ +pgp_key_t *rnp_key_store_get_signer_key(rnp_key_store_t *store, const pgp_signature_t *sig); + +pgp_sig_import_status_t rnp_key_store_import_key_signature(rnp_key_store_t * keyring, + pgp_key_t * key, + const pgp_signature_t *sig); + +/** + * @brief Import revocation or direct-key signature to the keyring. + * + * @param keyring populated keyring, cannot be NULL. + * @param sig signature to import. + * @param status signature import status will be put here, if not NULL. + * @return pointer to the key to which this signature belongs (or NULL if key was not found) + */ +pgp_key_t *rnp_key_store_import_signature(rnp_key_store_t * keyring, + const pgp_signature_t * sig, + pgp_sig_import_status_t *status); + +bool rnp_key_store_remove_key(rnp_key_store_t *, const pgp_key_t *, bool); + +bool rnp_key_store_get_key_grip(const pgp_key_material_t *, pgp_key_grip_t &grip); + +const pgp_key_t *rnp_key_store_get_key_by_fpr(const rnp_key_store_t *, + const pgp_fingerprint_t &fpr); +pgp_key_t * rnp_key_store_get_key_by_fpr(rnp_key_store_t *, const pgp_fingerprint_t &fpr); +pgp_key_t * rnp_key_store_get_primary_key(rnp_key_store_t *, const pgp_key_t *); +pgp_key_t *rnp_key_store_search(rnp_key_store_t *, const pgp_key_search_t *, pgp_key_t *); + +#endif /* KEY_STORE_H_ */ diff --git a/comm/third_party/rnp/include/repgp/repgp_def.h b/comm/third_party/rnp/include/repgp/repgp_def.h new file mode 100644 index 0000000000..218736c377 --- /dev/null +++ b/comm/third_party/rnp/include/repgp/repgp_def.h @@ -0,0 +1,505 @@ +/* + * Copyright (c) 2017-2020, 2023 [Ribose Inc](https://www.ribose.com). + * All rights reserved. + * + * This code is originally derived from software contributed to + * The NetBSD Foundation by Alistair Crooks (agc@netbsd.org), and + * carried further by Ribose Inc (https://www.ribose.com). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef REPGP_DEF_H_ +#define REPGP_DEF_H_ + +#include <cstdint> + +/************************************/ +/* Packet Tags - RFC4880, 4.2 */ +/************************************/ + +/** Packet Tag - Bit 7 Mask (this bit is always set). + * The first byte of a packet is the "Packet Tag". It always + * has bit 7 set. This is the mask for it. + * + * \see RFC4880 4.2 + */ +#define PGP_PTAG_ALWAYS_SET 0x80 + +/** Packet Tag - New Format Flag. + * Bit 6 of the Packet Tag is the packet format indicator. + * If it is set, the new format is used, if cleared the + * old format is used. + * + * \see RFC4880 4.2 + */ +#define PGP_PTAG_NEW_FORMAT 0x40 + +/** Old Packet Format: Mask for content tag. + * In the old packet format bits 5 to 2 (including) + * are the content tag. This is the mask to apply + * to the packet tag. Note that you need to + * shift by #PGP_PTAG_OF_CONTENT_TAG_SHIFT bits. + * + * \see RFC4880 4.2 + */ +#define PGP_PTAG_OF_CONTENT_TAG_MASK 0x3c +/** Old Packet Format: Offset for the content tag. + * As described at #PGP_PTAG_OF_CONTENT_TAG_MASK the + * content tag needs to be shifted after being masked + * out from the Packet Tag. + * + * \see RFC4880 4.2 + */ +#define PGP_PTAG_OF_CONTENT_TAG_SHIFT 2 +/** Old Packet Format: Mask for length type. + * Bits 1 and 0 of the packet tag are the length type + * in the old packet format. + * + * See #pgp_ptag_of_lt_t for the meaning of the values. + * + * \see RFC4880 4.2 + */ +#define PGP_PTAG_OF_LENGTH_TYPE_MASK 0x03 + +/* Maximum block size for symmetric crypto */ +#define PGP_MAX_BLOCK_SIZE 16 + +/* Maximum key size for symmetric crypto */ +#define PGP_MAX_KEY_SIZE 32 + +/* Salt size for hashing */ +#define PGP_SALT_SIZE 8 + +/* Size of the keyid */ +#define PGP_KEY_ID_SIZE 8 + +/* Size of the fingerprint */ +#define PGP_FINGERPRINT_SIZE 20 +#define PGP_FINGERPRINT_HEX_SIZE (PGP_FINGERPRINT_SIZE * 2) + 1 + +/* Size of the key grip */ +#define PGP_KEY_GRIP_SIZE 20 + +/* PGP marker packet contents */ +#define PGP_MARKER_CONTENTS "PGP" +#define PGP_MARKER_LEN 3 + +/** Old Packet Format Lengths. + * Defines the meanings of the 2 bits for length type in the + * old packet format. + * + * \see RFC4880 4.2.1 + */ +typedef enum { + PGP_PTAG_OLD_LEN_1 = 0x00, /* Packet has a 1 byte length - + * header is 2 bytes long. */ + PGP_PTAG_OLD_LEN_2 = 0x01, /* Packet has a 2 byte length - + * header is 3 bytes long. */ + PGP_PTAG_OLD_LEN_4 = 0x02, /* Packet has a 4 byte + * length - header is 5 bytes + * long. */ + PGP_PTAG_OLD_LEN_INDETERMINATE = 0x03 /* Packet has a + * indeterminate length. */ +} pgp_ptag_of_lt_t; + +/** New Packet Format: Mask for content tag. + * In the new packet format the 6 rightmost bits + * are the content tag. This is the mask to apply + * to the packet tag. Note that you need to + * shift by #PGP_PTAG_NF_CONTENT_TAG_SHIFT bits. + * + * \see RFC4880 4.2 + */ +#define PGP_PTAG_NF_CONTENT_TAG_MASK 0x3f +/** New Packet Format: Offset for the content tag. + * As described at #PGP_PTAG_NF_CONTENT_TAG_MASK the + * content tag needs to be shifted after being masked + * out from the Packet Tag. + * + * \see RFC4880 4.2 + */ +#define PGP_PTAG_NF_CONTENT_TAG_SHIFT 0 + +#define MDC_PKT_TAG 0xd3 +#define MDC_V1_SIZE 22 + +typedef enum : uint8_t { + PGP_REVOCATION_NO_REASON = 0, + PGP_REVOCATION_SUPERSEDED = 1, + PGP_REVOCATION_COMPROMISED = 2, + PGP_REVOCATION_RETIRED = 3, + PGP_REVOCATION_NO_LONGER_VALID = 0x20 +} pgp_revocation_type_t; + +/** + * @brief OpenPGP packet tags. See section 4.3 of RFC4880 for the detailed description. + * + */ +typedef enum : uint8_t { + PGP_PKT_RESERVED = 0, /* Reserved - a packet tag must not have this value */ + PGP_PKT_PK_SESSION_KEY = 1, /* Public-Key Encrypted Session Key Packet */ + PGP_PKT_SIGNATURE = 2, /* Signature Packet */ + PGP_PKT_SK_SESSION_KEY = 3, /* Symmetric-Key Encrypted Session Key Packet */ + PGP_PKT_ONE_PASS_SIG = 4, /* One-Pass Signature Packet */ + PGP_PKT_SECRET_KEY = 5, /* Secret Key Packet */ + PGP_PKT_PUBLIC_KEY = 6, /* Public Key Packet */ + PGP_PKT_SECRET_SUBKEY = 7, /* Secret Subkey Packet */ + PGP_PKT_COMPRESSED = 8, /* Compressed Data Packet */ + PGP_PKT_SE_DATA = 9, /* Symmetrically Encrypted Data Packet */ + PGP_PKT_MARKER = 10, /* Marker Packet */ + PGP_PKT_LITDATA = 11, /* Literal Data Packet */ + PGP_PKT_TRUST = 12, /* Trust Packet */ + PGP_PKT_USER_ID = 13, /* User ID Packet */ + PGP_PKT_PUBLIC_SUBKEY = 14, /* Public Subkey Packet */ + PGP_PKT_RESERVED2 = 15, /* Reserved */ + PGP_PKT_RESERVED3 = 16, /* Reserved */ + PGP_PKT_USER_ATTR = 17, /* User Attribute Packet */ + PGP_PKT_SE_IP_DATA = 18, /* Sym. Encrypted and Integrity Protected Data Packet */ + PGP_PKT_MDC = 19, /* Modification Detection Code Packet */ + PGP_PKT_AEAD_ENCRYPTED = 20 /* AEAD Encrypted Data Packet, RFC 4880bis */ +} pgp_pkt_type_t; + +/** Public Key Algorithm Numbers. + * OpenPGP assigns a unique Algorithm Number to each algorithm that is part of OpenPGP. + * + * This lists algorithm numbers for public key algorithms. + * + * \see RFC4880 9.1 + */ +typedef enum : uint8_t { + PGP_PKA_NOTHING = 0, /* No PKA */ + PGP_PKA_RSA = 1, /* RSA (Encrypt or Sign) */ + PGP_PKA_RSA_ENCRYPT_ONLY = 2, /* RSA Encrypt-Only (deprecated - + * \see RFC4880 13.5) */ + PGP_PKA_RSA_SIGN_ONLY = 3, /* RSA Sign-Only (deprecated - + * \see RFC4880 13.5) */ + PGP_PKA_ELGAMAL = 16, /* Elgamal (Encrypt-Only) */ + PGP_PKA_DSA = 17, /* DSA (Digital Signature Algorithm) */ + PGP_PKA_ECDH = 18, /* ECDH public key algorithm */ + PGP_PKA_ECDSA = 19, /* ECDSA public key algorithm [FIPS186-3] */ + PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN = 20, /* Elgamal Encrypt or Sign. Implementation MUST not + generate such keys and elgamal signatures. */ + PGP_PKA_RESERVED_DH = 21, /* Reserved for Diffie-Hellman + * (X9.42, as defined for + * IETF-S/MIME) */ + PGP_PKA_EDDSA = 22, /* EdDSA from draft-ietf-openpgp-rfc4880bis */ + PGP_PKA_SM2 = 99, /* SM2 encryption/signature schemes */ + + PGP_PKA_PRIVATE00 = 100, /* Private/Experimental Algorithm */ + PGP_PKA_PRIVATE01 = 101, /* Private/Experimental Algorithm */ + PGP_PKA_PRIVATE02 = 102, /* Private/Experimental Algorithm */ + PGP_PKA_PRIVATE03 = 103, /* Private/Experimental Algorithm */ + PGP_PKA_PRIVATE04 = 104, /* Private/Experimental Algorithm */ + PGP_PKA_PRIVATE05 = 105, /* Private/Experimental Algorithm */ + PGP_PKA_PRIVATE06 = 106, /* Private/Experimental Algorithm */ + PGP_PKA_PRIVATE07 = 107, /* Private/Experimental Algorithm */ + PGP_PKA_PRIVATE08 = 108, /* Private/Experimental Algorithm */ + PGP_PKA_PRIVATE09 = 109, /* Private/Experimental Algorithm */ + PGP_PKA_PRIVATE10 = 110 /* Private/Experimental Algorithm */ +} pgp_pubkey_alg_t; + +/** + * Enumeration of elliptic curves used by PGP. + * + * \see RFC4880-bis01 9.2. ECC Curve OID + * + * Values in this enum correspond to order in ec_curve array (in ec.c) + */ +typedef enum { + PGP_CURVE_UNKNOWN = 0, + PGP_CURVE_NIST_P_256, + PGP_CURVE_NIST_P_384, + PGP_CURVE_NIST_P_521, + PGP_CURVE_ED25519, + PGP_CURVE_25519, + PGP_CURVE_BP256, + PGP_CURVE_BP384, + PGP_CURVE_BP512, + PGP_CURVE_P256K1, + + PGP_CURVE_SM2_P_256, + + // Keep always last one + PGP_CURVE_MAX +} pgp_curve_t; + +/** Symmetric Key Algorithm Numbers. + * OpenPGP assigns a unique Algorithm Number to each algorithm that is + * part of OpenPGP. + * + * This lists algorithm numbers for symmetric key algorithms. + * + * \see RFC4880 9.2 + */ +typedef enum { + PGP_SA_PLAINTEXT = 0, /* Plaintext or unencrypted data */ + PGP_SA_IDEA = 1, /* IDEA */ + PGP_SA_TRIPLEDES = 2, /* TripleDES */ + PGP_SA_CAST5 = 3, /* CAST5 */ + PGP_SA_BLOWFISH = 4, /* Blowfish */ + PGP_SA_AES_128 = 7, /* AES with 128-bit key (AES) */ + PGP_SA_AES_192 = 8, /* AES with 192-bit key */ + PGP_SA_AES_256 = 9, /* AES with 256-bit key */ + PGP_SA_TWOFISH = 10, /* Twofish with 256-bit key (TWOFISH) */ + PGP_SA_CAMELLIA_128 = 11, /* Camellia with 128-bit key (CAMELLIA) */ + PGP_SA_CAMELLIA_192 = 12, /* Camellia with 192-bit key */ + PGP_SA_CAMELLIA_256 = 13, /* Camellia with 256-bit key */ + + PGP_SA_SM4 = 105, /* RNP extension - SM4 */ + PGP_SA_UNKNOWN = 255 +} pgp_symm_alg_t; + +typedef enum { + PGP_CIPHER_MODE_NONE = 0, + PGP_CIPHER_MODE_CFB = 1, + PGP_CIPHER_MODE_CBC = 2, + PGP_CIPHER_MODE_OCB = 3, +} pgp_cipher_mode_t; + +typedef enum { + PGP_AEAD_NONE = 0, + PGP_AEAD_EAX = 1, + PGP_AEAD_OCB = 2, + PGP_AEAD_UNKNOWN = 255 +} pgp_aead_alg_t; + +/** s2k_usage_t + */ +typedef enum { + PGP_S2KU_NONE = 0, + PGP_S2KU_ENCRYPTED_AND_HASHED = 254, + PGP_S2KU_ENCRYPTED = 255 +} pgp_s2k_usage_t; + +/** s2k_specifier_t + */ +typedef enum : uint8_t { + PGP_S2KS_SIMPLE = 0, + PGP_S2KS_SALTED = 1, + PGP_S2KS_ITERATED_AND_SALTED = 3, + PGP_S2KS_EXPERIMENTAL = 101 +} pgp_s2k_specifier_t; + +typedef enum { + PGP_S2K_GPG_NONE = 0, + PGP_S2K_GPG_NO_SECRET = 1, + PGP_S2K_GPG_SMARTCARD = 2 +} pgp_s2k_gpg_extension_t; + +/** Signature Type. + * OpenPGP defines different signature types that allow giving + * different meanings to signatures. Signature types include 0x10 for + * generitc User ID certifications (used when Ben signs Weasel's key), + * Subkey binding signatures, document signatures, key revocations, + * etc. + * + * Different types are used in different places, and most make only + * sense in their intended location (for instance a subkey binding has + * no place on a UserID). + * + * \see RFC4880 5.2.1 + */ +typedef enum : uint8_t { + PGP_SIG_BINARY = 0x00, /* Signature of a binary document */ + PGP_SIG_TEXT = 0x01, /* Signature of a canonical text document */ + PGP_SIG_STANDALONE = 0x02, /* Standalone signature */ + + PGP_CERT_GENERIC = 0x10, /* Generic certification of a User ID and + * Public Key packet */ + PGP_CERT_PERSONA = 0x11, /* Persona certification of a User ID and + * Public Key packet */ + PGP_CERT_CASUAL = 0x12, /* Casual certification of a User ID and + * Public Key packet */ + PGP_CERT_POSITIVE = 0x13, /* Positive certification of a + * User ID and Public Key packet */ + + PGP_SIG_SUBKEY = 0x18, /* Subkey Binding Signature */ + PGP_SIG_PRIMARY = 0x19, /* Primary Key Binding Signature */ + PGP_SIG_DIRECT = 0x1f, /* Signature directly on a key */ + + PGP_SIG_REV_KEY = 0x20, /* Key revocation signature */ + PGP_SIG_REV_SUBKEY = 0x28, /* Subkey revocation signature */ + PGP_SIG_REV_CERT = 0x30, /* Certification revocation signature */ + + PGP_SIG_TIMESTAMP = 0x40, /* Timestamp signature */ + + PGP_SIG_3RD_PARTY = 0x50 /* Third-Party Confirmation signature */ +} pgp_sig_type_t; + +/** Signature Subpacket Type + * Signature subpackets contains additional information about the signature + * + * \see RFC4880 5.2.3.1-5.2.3.26 + */ + +typedef enum { + PGP_SIG_SUBPKT_UNKNOWN = 0, + PGP_SIG_SUBPKT_RESERVED_1 = 1, + PGP_SIG_SUBPKT_CREATION_TIME = 2, /* signature creation time */ + PGP_SIG_SUBPKT_EXPIRATION_TIME = 3, /* signature expiration time */ + PGP_SIG_SUBPKT_EXPORT_CERT = 4, /* exportable certification */ + PGP_SIG_SUBPKT_TRUST = 5, /* trust signature */ + PGP_SIG_SUBPKT_REGEXP = 6, /* regular expression */ + PGP_SIG_SUBPKT_REVOCABLE = 7, /* revocable */ + PGP_SIG_SUBPKT_RESERVED_8 = 8, + PGP_SIG_SUBPKT_KEY_EXPIRY = 9, /* key expiration time */ + PGP_SIG_SUBPKT_PLACEHOLDER = 10, /* placeholder for backward compatibility */ + PGP_SIG_SUBPKT_PREFERRED_SKA = 11, /* preferred symmetric algs */ + PGP_SIG_SUBPKT_REVOCATION_KEY = 12, /* revocation key */ + PGP_SIG_SUBPKT_RESERVED_13 = 13, + PGP_SIG_SUBPKT_RESERVED_14 = 14, + PGP_SIG_SUBPKT_RESERVED_15 = 15, + PGP_SIG_SUBPKT_ISSUER_KEY_ID = 16, /* issuer key ID */ + PGP_SIG_SUBPKT_RESERVED_17 = 17, + PGP_SIG_SUBPKT_RESERVED_18 = 18, + PGP_SIG_SUBPKT_RESERVED_19 = 19, + PGP_SIG_SUBPKT_NOTATION_DATA = 20, /* notation data */ + PGP_SIG_SUBPKT_PREFERRED_HASH = 21, /* preferred hash algs */ + PGP_SIG_SUBPKT_PREF_COMPRESS = 22, /* preferred compression algorithms */ + PGP_SIG_SUBPKT_KEYSERV_PREFS = 23, /* key server preferences */ + PGP_SIG_SUBPKT_PREF_KEYSERV = 24, /* preferred key Server */ + PGP_SIG_SUBPKT_PRIMARY_USER_ID = 25, /* primary user ID */ + PGP_SIG_SUBPKT_POLICY_URI = 26, /* policy URI */ + PGP_SIG_SUBPKT_KEY_FLAGS = 27, /* key flags */ + PGP_SIG_SUBPKT_SIGNERS_USER_ID = 28, /* signer's user ID */ + PGP_SIG_SUBPKT_REVOCATION_REASON = 29, /* reason for revocation */ + PGP_SIG_SUBPKT_FEATURES = 30, /* features */ + PGP_SIG_SUBPKT_SIGNATURE_TARGET = 31, /* signature target */ + PGP_SIG_SUBPKT_EMBEDDED_SIGNATURE = 32, /* embedded signature */ + PGP_SIG_SUBPKT_ISSUER_FPR = 33, /* issuer fingerprint */ + PGP_SIG_SUBPKT_PREFERRED_AEAD = 34, /* preferred AEAD algorithms */ + PGP_SIG_SUBPKT_PRIVATE_100 = 100, /* private/experimental subpackets */ + PGP_SIG_SUBPKT_PRIVATE_101 = 101, + PGP_SIG_SUBPKT_PRIVATE_102 = 102, + PGP_SIG_SUBPKT_PRIVATE_103 = 103, + PGP_SIG_SUBPKT_PRIVATE_104 = 104, + PGP_SIG_SUBPKT_PRIVATE_105 = 105, + PGP_SIG_SUBPKT_PRIVATE_106 = 106, + PGP_SIG_SUBPKT_PRIVATE_107 = 107, + PGP_SIG_SUBPKT_PRIVATE_108 = 108, + PGP_SIG_SUBPKT_PRIVATE_109 = 109, + PGP_SIG_SUBPKT_PRIVATE_110 = 110 +} pgp_sig_subpacket_type_t; + +/** Key Flags + * + * \see RFC4880 5.2.3.21 + */ +typedef enum { + PGP_KF_CERTIFY = 0x01, /* This key may be used to certify other keys. */ + PGP_KF_SIGN = 0x02, /* This key may be used to sign data. */ + PGP_KF_ENCRYPT_COMMS = 0x04, /* This key may be used to encrypt communications. */ + PGP_KF_ENCRYPT_STORAGE = 0x08, /* This key may be used to encrypt storage. */ + PGP_KF_SPLIT = 0x10, /* The private component of this key may have been split + by a secret-sharing mechanism. */ + PGP_KF_AUTH = 0x20, /* This key may be used for authentication. */ + PGP_KF_SHARED = 0x80, /* The private component of this key may be in the + possession of more than one person. */ + /* pseudo flags */ + PGP_KF_NONE = 0x00, + PGP_KF_ENCRYPT = PGP_KF_ENCRYPT_COMMS | PGP_KF_ENCRYPT_STORAGE, +} pgp_key_flags_t; + +typedef enum { + PGP_KEY_FEATURE_MDC = 0x01, + PGP_KEY_FEATURE_AEAD = 0x02, + PGP_KEY_FEATURE_V5 = 0x04 +} pgp_key_feature_t; + +/** Types of Compression */ +typedef enum { + PGP_C_NONE = 0, + PGP_C_ZIP = 1, + PGP_C_ZLIB = 2, + PGP_C_BZIP2 = 3, + PGP_C_UNKNOWN = 255 +} pgp_compression_type_t; + +enum { PGP_SE_IP_DATA_VERSION = 1, PGP_PKSK_V3 = 3, PGP_SKSK_V4 = 4, PGP_SKSK_V5 = 5 }; + +/** Version. + * OpenPGP has two different protocol versions: version 3 and version 4. + * + * \see RFC4880 5.2 + */ +typedef enum { + PGP_VUNKNOWN = 0, + PGP_V2 = 2, /* Version 2 (essentially the same as v3) */ + PGP_V3 = 3, /* Version 3 */ + PGP_V4 = 4 /* Version 4 */ +} pgp_version_t; + +typedef enum pgp_op_t { + PGP_OP_UNKNOWN = 0, + PGP_OP_ADD_SUBKEY = 1, /* adding a subkey, primary key password required */ + PGP_OP_SIGN = 2, /* signing file or data */ + PGP_OP_DECRYPT = 3, /* decrypting file or data */ + PGP_OP_UNLOCK = 4, /* unlocking a key with key->unlock() */ + PGP_OP_PROTECT = 5, /* adding protection to a key */ + PGP_OP_UNPROTECT = 6, /* removing protection from a (locked) key */ + PGP_OP_DECRYPT_SYM = 7, /* symmetric decryption */ + PGP_OP_ENCRYPT_SYM = 8, /* symmetric encryption */ + PGP_OP_VERIFY = 9, /* signature verification */ + PGP_OP_ADD_USERID = 10, /* adding a userid */ + PGP_OP_MERGE_INFO = 11, /* merging information from one key to another */ + PGP_OP_ENCRYPT = 12, /* public-key encryption */ + PGP_OP_CERTIFY = 13 /* key certification */ +} pgp_op_t; + +/** Hashing Algorithm Numbers. + * OpenPGP assigns a unique Algorithm Number to each algorithm that is + * part of OpenPGP. + * + * This lists algorithm numbers for hash algorithms. + * + * \see RFC4880 9.4 + */ +typedef enum : uint8_t { + PGP_HASH_UNKNOWN = 0, /* used to indicate errors */ + PGP_HASH_MD5 = 1, + PGP_HASH_SHA1 = 2, + PGP_HASH_RIPEMD = 3, + + PGP_HASH_SHA256 = 8, + PGP_HASH_SHA384 = 9, + PGP_HASH_SHA512 = 10, + PGP_HASH_SHA224 = 11, + PGP_HASH_SHA3_256 = 12, + PGP_HASH_SHA3_512 = 14, + + /* Private range */ + PGP_HASH_SM3 = 105, +} pgp_hash_alg_t; + +typedef enum pgp_key_store_format_t { + PGP_KEY_STORE_UNKNOWN = 0, + PGP_KEY_STORE_GPG, + PGP_KEY_STORE_KBX, + PGP_KEY_STORE_G10, +} pgp_key_store_format_t; + +namespace rnp { +enum class AuthType { None, MDC, AEADv1 }; +} + +#endif diff --git a/comm/third_party/rnp/include/rnp.h b/comm/third_party/rnp/include/rnp.h new file mode 100644 index 0000000000..0d666db7eb --- /dev/null +++ b/comm/third_party/rnp/include/rnp.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017, [Ribose Inc](https://www.ribose.com). + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is originally derived from software contributed to + * The NetBSD Foundation by Alistair Crooks (agc@netbsd.org), and + * carried further by Ribose Inc (https://www.ribose.com). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RNP_RNP_H +#define RNP_RNP_H + +#include "types.h" +#include "pass-provider.h" +#include "key-provider.h" +#include "crypto/rng.h" +#include <rnp/rnp_def.h> +#include "utils.h" + +#endif // RNP_RNP_H diff --git a/comm/third_party/rnp/include/rnp/rnp.h b/comm/third_party/rnp/include/rnp/rnp.h new file mode 100644 index 0000000000..66671698a2 --- /dev/null +++ b/comm/third_party/rnp/include/rnp/rnp.h @@ -0,0 +1,3150 @@ +/*- + * Copyright (c) 2017-2021 Ribose Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <rnp/rnp_export.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * Function return type. 0 == SUCCESS, all other values indicate an error. + */ +typedef uint32_t rnp_result_t; + +#define RNP_KEY_EXPORT_ARMORED (1U << 0) +#define RNP_KEY_EXPORT_PUBLIC (1U << 1) +#define RNP_KEY_EXPORT_SECRET (1U << 2) +#define RNP_KEY_EXPORT_SUBKEYS (1U << 3) + +/* Export base64-encoded autocrypt key instead of binary */ +#define RNP_KEY_EXPORT_BASE64 (1U << 9) + +#define RNP_KEY_REMOVE_PUBLIC (1U << 0) +#define RNP_KEY_REMOVE_SECRET (1U << 1) +#define RNP_KEY_REMOVE_SUBKEYS (1U << 2) + +#define RNP_KEY_UNLOAD_PUBLIC (1U << 0) +#define RNP_KEY_UNLOAD_SECRET (1U << 1) + +/** + * Flags for optional details to include in JSON. + */ +#define RNP_JSON_PUBLIC_MPIS (1U << 0) +#define RNP_JSON_SECRET_MPIS (1U << 1) +#define RNP_JSON_SIGNATURES (1U << 2) +#define RNP_JSON_SIGNATURE_MPIS (1U << 3) + +/** + * Flags to include additional data in packet dumping + */ +#define RNP_JSON_DUMP_MPI (1U << 0) +#define RNP_JSON_DUMP_RAW (1U << 1) +#define RNP_JSON_DUMP_GRIP (1U << 2) + +#define RNP_DUMP_MPI (1U << 0) +#define RNP_DUMP_RAW (1U << 1) +#define RNP_DUMP_GRIP (1U << 2) + +/** + * Flags for the key loading/saving functions. + */ +#define RNP_LOAD_SAVE_PUBLIC_KEYS (1U << 0) +#define RNP_LOAD_SAVE_SECRET_KEYS (1U << 1) +#define RNP_LOAD_SAVE_PERMISSIVE (1U << 8) +#define RNP_LOAD_SAVE_SINGLE (1U << 9) +#define RNP_LOAD_SAVE_BASE64 (1U << 10) + +/** + * Flags for the rnp_key_remove_signatures + */ + +#define RNP_KEY_SIGNATURE_INVALID (1U << 0) +#define RNP_KEY_SIGNATURE_UNKNOWN_KEY (1U << 1) +#define RNP_KEY_SIGNATURE_NON_SELF_SIG (1U << 2) + +#define RNP_KEY_SIGNATURE_KEEP (0U) +#define RNP_KEY_SIGNATURE_REMOVE (1U) + +/** + * Flags for output structure creation. + */ +#define RNP_OUTPUT_FILE_OVERWRITE (1U << 0) +#define RNP_OUTPUT_FILE_RANDOM (1U << 1) + +/** + * Flags for default key selection. + */ +#define RNP_KEY_SUBKEYS_ONLY (1U << 0) + +/** + * User id type + */ +#define RNP_USER_ID (1U) +#define RNP_USER_ATTR (2U) + +/** + * Predefined feature security levels + */ +#define RNP_SECURITY_PROHIBITED (0U) +#define RNP_SECURITY_INSECURE (1U) +#define RNP_SECURITY_DEFAULT (2U) + +/** + * Flags for feature security rules. + */ +#define RNP_SECURITY_OVERRIDE (1U << 0) +#define RNP_SECURITY_VERIFY_KEY (1U << 1) +#define RNP_SECURITY_VERIFY_DATA (1U << 2) +#define RNP_SECURITY_REMOVE_ALL (1U << 16) + +/** + * Encryption flags + */ +#define RNP_ENCRYPT_NOWRAP (1U << 0) + +/** + * Decryption/verification flags + */ +#define RNP_VERIFY_IGNORE_SIGS_ON_DECRYPT (1U << 0) +#define RNP_VERIFY_REQUIRE_ALL_SIGS (1U << 1) +#define RNP_VERIFY_ALLOW_HIDDEN_RECIPIENT (1U << 2) + +/** + * Return a constant string describing the result code + */ +RNP_API const char *rnp_result_to_string(rnp_result_t result); + +RNP_API const char *rnp_version_string(); +RNP_API const char *rnp_version_string_full(); + +/** return a value representing the version of librnp + * + * This function is only useful for releases. For non-releases, + * it will return 0. + * + * The value returned can be used in comparisons by utilizing + * rnp_version_for. + * + * @return a value representing the librnp version + **/ +RNP_API uint32_t rnp_version(); + +/** return a value representing a specific version of librnp + * + * This value can be used in comparisons. + * + * @return a value representing a librnp version + **/ +RNP_API uint32_t rnp_version_for(uint32_t major, uint32_t minor, uint32_t patch); + +/** return the librnp major version + * + * @return + **/ +RNP_API uint32_t rnp_version_major(uint32_t version); + +/** return the librnp minor version + * + * @return + **/ +RNP_API uint32_t rnp_version_minor(uint32_t version); + +/** return the librnp patch version + * + * @return + **/ +RNP_API uint32_t rnp_version_patch(uint32_t version); + +/** return a unix timestamp of the last commit, if available + * + * This function is only useful for non-releases. For releases, + * it will return 0. + * + * The intended usage is to provide a form of versioning for the main + * branch. + * + * @return the unix timestamp of the last commit, or 0 if unavailable + **/ +RNP_API uint64_t rnp_version_commit_timestamp(); + +#ifndef RNP_NO_DEPRECATED +/** @brief This function is deprecated and should not be used anymore. It would just silently + * return RNP_SUCCESS. + * + * @param file name of the sourcer file. Use 'all' to enable debug for all code. + * + */ +RNP_API RNP_DEPRECATED rnp_result_t rnp_enable_debug(const char *file); + +/** + * @brief This function is deprecated and should not be used anymore. It would just silently + * return RNP_SUCCESS. + * + */ +RNP_API RNP_DEPRECATED rnp_result_t rnp_disable_debug(); +#endif + +/* + * Opaque structures + */ +typedef struct rnp_ffi_st * rnp_ffi_t; +typedef struct rnp_key_handle_st * rnp_key_handle_t; +typedef struct rnp_input_st * rnp_input_t; +typedef struct rnp_output_st * rnp_output_t; +typedef struct rnp_op_generate_st * rnp_op_generate_t; +typedef struct rnp_op_sign_st * rnp_op_sign_t; +typedef struct rnp_op_sign_signature_st * rnp_op_sign_signature_t; +typedef struct rnp_op_verify_st * rnp_op_verify_t; +typedef struct rnp_op_verify_signature_st *rnp_op_verify_signature_t; +typedef struct rnp_op_encrypt_st * rnp_op_encrypt_t; +typedef struct rnp_identifier_iterator_st *rnp_identifier_iterator_t; +typedef struct rnp_uid_handle_st * rnp_uid_handle_t; +typedef struct rnp_signature_handle_st * rnp_signature_handle_t; +typedef struct rnp_recipient_handle_st * rnp_recipient_handle_t; +typedef struct rnp_symenc_handle_st * rnp_symenc_handle_t; + +/* Callbacks */ +/** + * @brief Callback, used to read data from the source. + * + * @param app_ctx custom parameter, passed back to the function. + * @param buf on successful call data should be put here. Cannot be NULL, + * and must be capable to store at least len bytes. + * @param len number of bytes to read. + * @param read on successful call number of read bytes must be put here. + * @return true on success (including EOF condition), or false on read error. + * EOF case is indicated by zero bytes read on non-zero read call. + */ +typedef bool rnp_input_reader_t(void *app_ctx, void *buf, size_t len, size_t *read); +/** + * @brief Callback, used to close input stream. + * + * @param app_ctx custom parameter, passed back to the function. + * @return void + */ +typedef void rnp_input_closer_t(void *app_ctx); +/** + * @brief Callback, used to write data to the output stream. + * + * @param app_ctx custom parameter, passed back to the function. + * @param buf buffer with data, cannot be NULL. + * @param len number of bytes to write. + * @return true if call was successful and all data is written, or false otherwise. + */ +typedef bool rnp_output_writer_t(void *app_ctx, const void *buf, size_t len); + +/** + * @brief Callback, used to close output stream. + * + * @param app_ctx custom parameter, passed back to the function. + * @param discard true if the already written data should be deleted. + * @return void + */ +typedef void rnp_output_closer_t(void *app_ctx, bool discard); + +/** + * Callback used for getting a password. + * + * @param ffi + * @param app_ctx provided by application + * @param key the key, if any, for which the password is being requested. + * Note: this key handle should not be held by the application, + * it is destroyed after the callback. It should only be used to + * retrieve information like the userids, grip, etc. + * @param pgp_context a descriptive string on why the password is being + * requested, may have one of the following values: + * - "add subkey": add subkey to the encrypted secret key + * - "add userid": add userid to the encrypted secret key + * - "sign": sign data + * - "decrypt": decrypt data using the encrypted secret key + * - "unlock": temporary unlock secret key (decrypting its fields), so it may be used + * later without need to decrypt + * - "protect": encrypt secret key fields + * - "unprotect": decrypt secret key fields, leaving those in a raw format + * - "decrypt (symmetric)": decrypt data, using the password + * - "encrypt (symmetric)": encrypt data, using the password + * @param buf to which the callback should write the returned password, NULL terminated. + * @param buf_len the size of buf + * @return true if a password was provided, false otherwise + */ +typedef bool (*rnp_password_cb)(rnp_ffi_t ffi, + void * app_ctx, + rnp_key_handle_t key, + const char * pgp_context, + char buf[], + size_t buf_len); + +/** callback used to signal the application that a key is needed + * + * The application should use the appropriate functions (rnp_load_public_keys, etc) + * to load the requested key. + * + * This may be called multiple times for the same key. For example, if attempting + * to verify a signature, the signer's keyid may be used first to request the key. + * If that is not successful, the signer's fingerprint (if available) may be used. + * + * Please note that there is a special case with 'hidden' recipient, with all-zero keyid. In + * this case implementation should load all available secret keys for the decryption attempt + * (or do nothing, in this case decryption to the hidden recipient would fail). + * + * Situations in which this callback would be used include: + * - When decrypting data that includes a public-key encrypted session key, + * and the key is not found in the keyrings. + * - When attempting to verify a signature, when the signer's key is not found in + * the keyrings. + * + * @param ffi + * @param app_ctx provided by application in rnp_keyring_open + * @param identifier_type the type of identifier ("userid", "keyid", "grip") + * @param identifier the identifier for locating the key + * @param secret true if a secret key is being requested + */ +typedef void (*rnp_get_key_cb)(rnp_ffi_t ffi, + void * app_ctx, + const char *identifier_type, + const char *identifier, + bool secret); + +/** + * @brief callback used to report back signatures from the function + * rnp_key_remove_signatures(). This may be used to implement custom signature filtering + * code or record information about the signatures which are removed. + * @param ffi + * @param app_ctx custom context, provided by application. + * @param sig signature handle to retrieve information about the signature. Callback must not + * call rnp_signature_handle_destroy() on it. + * @param action action which will be performed on the signature. Currently defined are + * RNP_KEY_SIGNATURE_KEEP an RNP_KEY_SIGNATURE_REMOVE. + * Callback may overwrite this value. + * + */ +typedef void (*rnp_key_signatures_cb)(rnp_ffi_t ffi, + void * app_ctx, + rnp_signature_handle_t sig, + uint32_t * action); + +/** create the top-level object used for interacting with the library + * + * @param ffi pointer that will be set to the created ffi object + * @param pub_format the format of the public keyring, RNP_KEYSTORE_GPG or other + * RNP_KEYSTORE_* constant + * @param sec_format the format of the secret keyring, RNP_KEYSTORE_GPG or other + * RNP_KEYSTORE_* constant + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_ffi_create(rnp_ffi_t * ffi, + const char *pub_format, + const char *sec_format); + +/** destroy the top-level object used for interacting with the library + * + * Note that this invalidates key handles, keyrings, and any other + * objects associated with this particular object. + * + * @param ffi the ffi object + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_ffi_destroy(rnp_ffi_t ffi); + +RNP_API rnp_result_t rnp_ffi_set_log_fd(rnp_ffi_t ffi, int fd); + +/** + * @brief Set key provider callback. This callback would be called in case when required public + * or secret key is not loaded to the keyrings. + * + * @param ffi initialized ffi object, cannot be NULL. + * @param getkeycb callback function. See rnp_get_key_cb documentation for details. + * @param getkeycb_ctx implementation-specific context, which would be passed to the getkeycb + * on invocation. + * @return RNP_SUCCESS on success, or any other value on error. + */ +RNP_API rnp_result_t rnp_ffi_set_key_provider(rnp_ffi_t ffi, + rnp_get_key_cb getkeycb, + void * getkeycb_ctx); +RNP_API rnp_result_t rnp_ffi_set_pass_provider(rnp_ffi_t ffi, + rnp_password_cb getpasscb, + void * getpasscb_ctx); + +/* Operations on key rings */ + +/** retrieve the default homedir (example: /home/user/.rnp) + * + * @param homedir pointer that will be set to the homedir path. + * The caller should free this with rnp_buffer_destroy. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_get_default_homedir(char **homedir); + +/** Try to detect the formats and paths of the homedir keyrings. + * @param homedir the path to the home directory (example: /home/user/.rnp) + * @param pub_format pointer that will be set to the format of the public keyring. + * The caller should free this with rnp_buffer_destroy. + * Note: this and below may be set to NULL in case of no known format is found. + * @param pub_path pointer that will be set to the path to the public keyring. + * The caller should free this with rnp_buffer_destroy. + * @param sec_format pointer that will be set to the format of the secret keyring. + * The caller should free this with rnp_buffer_destroy. + * @param sec_path pointer that will be set to the path to the secret keyring. + * The caller should free this with rnp_buffer_destroy. + * @return RNP_SUCCESS on success (even if no known format was found), or any other value on + * error. + */ +RNP_API rnp_result_t rnp_detect_homedir_info( + const char *homedir, char **pub_format, char **pub_path, char **sec_format, char **sec_path); + +/** try to detect the key format of the provided data + * + * @param buf the key data, must not be NULL + * @param buf_len the size of the buffer, must be > 0 + * @param format pointer that will be set to the format of the keyring. + * Must not be NULL. The caller should free this with rnp_buffer_destroy. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_detect_key_format(const uint8_t buf[], size_t buf_len, char **format); + +/** Get the number of s2k hash iterations, based on calculation time requested. + * Number of iterations is used to derive encryption key from password. + * + * @param hash hash algorithm to try + * @param msec number of milliseconds which will be needed to derive key from the password. + * Since it depends on CPU speed the calculated value will make sense only for the + * system it was calculated for. + * @param iterations approximate number of iterations to satisfy time complexity. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_calculate_iterations(const char *hash, + size_t msec, + size_t * iterations); + +/** Check whether rnp supports specific feature (algorithm, elliptic curve, whatever else). + * + * @param type string with the feature type. See RNP_FEATURE_* defines for the supported + * values. + * @param name value of the feature to check whether it is supported. + * @param supported will contain true or false depending whether feature is supported or not. + * @return RNP_SUCCESS on success or any other value on error. + */ +RNP_API rnp_result_t rnp_supports_feature(const char *type, const char *name, bool *supported); + +/** Get the JSON with array of supported rnp feature values (algorithms, curves, etc) by type. + * + * @param type type of the feature. See RNP_FEATURE_* defines for the supported values. + * @param result after successful execution will contain the JSON with supported feature + * values. You must destroy it using the rnp_buffer_destroy() function. + * @return RNP_SUCCESS on success or any other value on error. + */ +RNP_API rnp_result_t rnp_supported_features(const char *type, char **result); + +/** + * @brief Add new security rule to the FFI. Security rules allows to override default algorithm + * security settings by disabling them or marking as insecure. After creation of FFI + * object default rules are added, however caller may add more strict rules or + * completely overwrite rule table by calling rnp_remove_security_rule(). + * Note: key signature validation status is cached, so rules should be changed before + * keyrings are loaded or keyring should be reloaded after updating rules. + * + * @param ffi initialized FFI object. + * @param type type of the feature, cannot be NULL. Currently only RNP_FEATURE_HASH_ALG is + * supported. + * @param name name of the feature, i.e. SHA1, MD5. The same values are used in + * rnp_supports_feature()/rnp_supported_features(). + * @param flags additional flags. Following ones currently supported: + * - RNP_SECURITY_OVERRIDE : override all other rules for the specified feature. + * May be used to temporarily enable or disable some feature value (e.g., to + * enable verification of SHA1 or MD5 signature), and then revert changes via + * rnp_remove_security_rule(). + * - RNP_SECURITY_VERIFY_KEY : limit rule only to the key signature verification. + * - RNP_SECURITY_VERIFY_DATA : limit rule only to the data signature + * verification. + * Note: by default rule applies to all possible usages. + * + * @param from timestamp, from when the rule is active. Objects that have creation time (like + * signatures) are matched with the closest rules from the past, unless there is + * a rule with an override flag. For instance, given a single rule with algorithm + * 'MD5', level 'insecure' and timestamp '2012-01-01', all signatures made before + * 2012-01-01 using the MD5 hash algorithm are considered to be at the default + * security level (i.e., valid), whereas all signatures made after 2021-01-01 will + * be marked as 'insecure' (i.e., invalid). + * @param level security level of the rule. Currently the following ones are defined: + * - RNP_SECURITY_PROHIBITED : feature (for instance, MD5 algorithm) is completely + * disabled, so no processing can be done. In terms of signature check, that + * would mean the check will fail right after the hashing begins. + * Note: Currently it works in the same way as RNP_SECURITY_INSECURE. + * - RNP_SECURITY_INSECURE : feature (for instance, SHA1 algorithm) is marked as + * insecure. So even valid signatures, produced later than `from`, will be + * marked as invalid. + * - RNP_SECURITY_DEFAULT : feature is secure enough. Default value when there are + * no other rules for feature. + * + * @return RNP_SUCCESS or any other value on error. + */ +RNP_API rnp_result_t rnp_add_security_rule(rnp_ffi_t ffi, + const char *type, + const char *name, + uint32_t flags, + uint64_t from, + uint32_t level); + +/** + * @brief Get security rule applicable for the corresponding feature value and timestamp. + * Note: if there is no matching rule, it will fall back to the default security level + * with empty flags and `from`. + * + * @param ffi initialized FFI object. + * @param type feature type to search for. Only RNP_FEATURE_HASH_ALG is supported right now. + * @param name feature name, i.e. SHA1 or so on. + * @param time timestamp for which feature should be checked. + * @param flags if non-NULL then rule's flags will be put here. In this case *flags must be + * initialized to the desired usage limitation: + * - 0 to look up for any usage (this is also assumed if flags parameter is + * NULL). + * - RNP_SECURITY_VERIFY_KEY, RNP_SECURITY_VERIFY_DATA and so on to look up for + * the specific usage. Please note that constants cannot be ORed here, only + * single one must be present. + * @param from if non-NULL then rule's from time will be put here. + * @param level cannot be NULL. Security level will be stored here. + * @return RNP_SUCCESS or any other value on error. + */ +RNP_API rnp_result_t rnp_get_security_rule(rnp_ffi_t ffi, + const char *type, + const char *name, + uint64_t time, + uint32_t * flags, + uint64_t * from, + uint32_t * level); + +/** + * @brief Remove security rule(s), matching the parameters. + * Note: use this with caution, as this may also clear default security rules, so + * all affected features would be considered of the default security level. + * + * @param ffi populated FFI structure, cannot be NULL. + * @param type type of the feature. If NULL, then all of the rules will be cleared. + * @param name name of the feature. If NULL, then all rules of the type will be cleared. + * @param level security level of the rule. + * @param flags additional flags, following are defined at the moment: + * - RNP_SECURITY_OVERRIDE : rule should match this flag + * - RNP_SECURITY_VERIFY_KEY, RNP_SECURITY_VERIFY_DATA : rule should match these flags + * (can be ORed together) + * - RNP_SECURITY_REMOVE_ALL : remove all rules for type and name. + * @param from timestamp, for when the rule should be removed. Ignored if + * RNP_SECURITY_REMOVE_ALL_FROM is specified. + * @param removed if non-NULL then number of removed rules will be stored here. + * @return RNP_SUCCESS on success or any other value on error. Please note that if no rules are + * matched, execution will be marked as successful. Use the `removed` parameter to + * check for this case. + */ +RNP_API rnp_result_t rnp_remove_security_rule(rnp_ffi_t ffi, + const char *type, + const char *name, + uint32_t level, + uint32_t flags, + uint64_t from, + size_t * removed); + +/** + * @brief Request password via configured FFI's callback + * + * @param ffi initialized FFI structure + * @param key key handle for which password is requested. May be NULL. + * @param context string describing the purpose of password request. See description of + * rnp_password_cb for the list of possible values. Also you may use any + * custom one as far as your password callback handles it. + * @param password password will be put here on success. Must be destroyed via + * rnp_buffer_destroy(), also it is good idea to securely clear it via + * rnp_buffer_clear(). + * @return RNP_SUCCESS or other value on error. + */ +RNP_API rnp_result_t rnp_request_password(rnp_ffi_t ffi, + rnp_key_handle_t key, + const char * context, + char ** password); + +/** + * @brief Set timestamp, used in all operations instead of system's time. These operations + * include key/signature generation (this timestamp will be used as signature/key + * creation date), verification of the keys and signatures (this timestamp will be used + * as 'current' time). + * Please note, that exactly this timestamp will be used during the whole ffi lifetime. + * + * @param ffi initialized FFI structure + * @param time non-zero timestamp to be used. Zero value restores original behaviour and uses + * system's time. + * @return RNP_SUCCESS or other value on error. + */ +RNP_API rnp_result_t rnp_set_timestamp(rnp_ffi_t ffi, uint64_t time); + +/** load keys + * + * Note that for G10, the input must be a directory (which must already exist). + * + * @param ffi + * @param format the key format of the data (GPG, KBX, G10). Must not be NULL. + * @param input source to read from. + * @param flags the flags. See RNP_LOAD_SAVE_*. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_load_keys(rnp_ffi_t ffi, + const char *format, + rnp_input_t input, + uint32_t flags); + +/** unload public and/or secret keys + * Note: After unloading all key handles will become invalid and must be destroyed. + * @param ffi + * @param flags choose which keys should be unloaded (pubic, secret or both). + * See RNP_KEY_UNLOAD_PUBLIC/RNP_KEY_UNLOAD_SECRET. + * @return RNP_SUCCESS on success, or any other value on error. + */ +RNP_API rnp_result_t rnp_unload_keys(rnp_ffi_t ffi, uint32_t flags); + +/** import keys to the keyring and receive JSON list of the new/updated keys. + * Note: this will work only with keys in OpenPGP format, use rnp_load_keys for other formats. + * @param ffi + * @param input source to read from. Cannot be NULL. + * @param flags see RNP_LOAD_SAVE_* constants. If RNP_LOAD_SAVE_PERMISSIVE is specified + * then import process will skip unrecognized or bad keys/signatures instead of + * failing the whole operation. + * If flag RNP_LOAD_SAVE_SINGLE is set, then only first key will be loaded (subkey + * or primary key with its subkeys). In case RNP_LOAD_SAVE_PERMISSIVE and + * erroneous first key on the stream RNP_SUCCESS will be returned, but results + * will include an empty array. Also RNP_ERROR_EOF will be returned if the last + * key was read. + * RNP_LOAD_SAVE_BASE64 should set to allow import of base64-encoded keys (i.e. + * autocrypt ones). By default only binary and OpenPGP-armored keys are allowed. + * @param results if not NULL then after the successful execution will contain JSON with + * information about new and updated keys. You must free it using the + * rnp_buffer_destroy() function. + * @return RNP_SUCCESS on success + * RNP_ERROR_EOF if last key was read (if RNP_LOAD_SAVE_SINGLE was used) + * any other value on error. + */ +RNP_API rnp_result_t rnp_import_keys(rnp_ffi_t ffi, + rnp_input_t input, + uint32_t flags, + char ** results); + +/** import standalone signatures to the keyring and receive JSON list of the updated keys. + * + * @param ffi + * @param input source to read from. Cannot be NULL. + * @param flags additional import flags, currently must be 0. + * @param results if not NULL then after the successful execution will contain JSON with + * information about the updated keys. You must free it using the + * rnp_buffer_destroy() function. + * @return RNP_SUCCESS on success, or any other value on error. + */ +RNP_API rnp_result_t rnp_import_signatures(rnp_ffi_t ffi, + rnp_input_t input, + uint32_t flags, + char ** results); + +/** save keys + * + * Note that for G10, the output must be a directory (which must already exist). + * + * @param ffi + * @param format the key format of the data (GPG, KBX, G10). Must not be NULL. + * @param output the output destination to write to. + * @param flags the flags. See RNP_LOAD_SAVE_*. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_save_keys(rnp_ffi_t ffi, + const char * format, + rnp_output_t output, + uint32_t flags); + +RNP_API rnp_result_t rnp_get_public_key_count(rnp_ffi_t ffi, size_t *count); +RNP_API rnp_result_t rnp_get_secret_key_count(rnp_ffi_t ffi, size_t *count); + +/** Search for the key + * Note: only valid userids are checked while searching by userid. + * + * @param ffi + * @param identifier_type string with type of the identifier: userid, keyid, fingerprint, grip + * @param identifier for userid is the userid string, for other search types - hex string + * representation of the value + * @param key if key was found then the resulting key handle will be stored here, otherwise it + * will contain NULL value. You must free handle after use with rnp_key_handle_destroy. + * @return RNP_SUCCESS on success (including case where key is not found), or any other value + * on error + */ +RNP_API rnp_result_t rnp_locate_key(rnp_ffi_t ffi, + const char * identifier_type, + const char * identifier, + rnp_key_handle_t *key); + +RNP_API rnp_result_t rnp_key_handle_destroy(rnp_key_handle_t key); + +/** generate a key or pair of keys using a JSON description + * + * Notes: + * - When generating a subkey, the pass provider may be required. + * + * @param ffi + * @param json the json data that describes the key generation. + * Must not be NULL. + * @param results pointer that will be set to the JSON results. + * Must not be NULL. The caller should free this with rnp_buffer_destroy. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_generate_key_json(rnp_ffi_t ffi, const char *json, char **results); + +/* Key operations */ + +/** Shortcut function for rsa key-subkey pair generation. See rnp_generate_key_ex() for the + * detailed parameters description. + */ +RNP_API rnp_result_t rnp_generate_key_rsa(rnp_ffi_t ffi, + uint32_t bits, + uint32_t subbits, + const char * userid, + const char * password, + rnp_key_handle_t *key); + +/** Shortcut function for DSA/ElGamal key-subkey pair generation. See rnp_generate_key_ex() for + * the detailed parameters description. + */ +RNP_API rnp_result_t rnp_generate_key_dsa_eg(rnp_ffi_t ffi, + uint32_t bits, + uint32_t subbits, + const char * userid, + const char * password, + rnp_key_handle_t *key); + +/** Shortcut function for ECDSA/ECDH key-subkey pair generation. See rnp_generate_key_ex() for + * the detailed parameters description. + */ +RNP_API rnp_result_t rnp_generate_key_ec(rnp_ffi_t ffi, + const char * curve, + const char * userid, + const char * password, + rnp_key_handle_t *key); + +/** Shortcut function for EdDSA/x25519 key-subkey pair generation. See rnp_generate_key_ex() + * for the detailed parameters description. + */ +RNP_API rnp_result_t rnp_generate_key_25519(rnp_ffi_t ffi, + const char * userid, + const char * password, + rnp_key_handle_t *key); + +/** Shortcut function for SM2/SM2 key-subkey pair generation. See rnp_generate_key_ex() for + * for the detailed parameters description. + */ +RNP_API rnp_result_t rnp_generate_key_sm2(rnp_ffi_t ffi, + const char * userid, + const char * password, + rnp_key_handle_t *key); + +/** + * @brief Shortcut for quick key generation. It is used in other shortcut functions for + * key generation (rnp_generate_key_*). + * + * @param ffi + * @param key_alg string with primary key algorithm. Cannot be NULL. + * @param sub_alg string with subkey algorithm. If NULL then subkey will not be generated. + * @param key_bits size of key in bits. If zero then default value will be used. + * Must be zero for EC-based primary key algorithm (use curve instead). + * @param sub_bits size of subkey in bits. If zero then default value will be used. + * Must be zero for EC-based subkey algorithm (use scurve instead). + * @param key_curve Curve name. Must be non-NULL only with EC-based primary key algorithm, + * otherwise error will be returned. + * @param sub_curve Subkey curve name. Must be non-NULL only with EC-based subkey algorithm, + * otherwise error will be returned. + * @param userid String with userid. Cannot be NULL. + * @param password String with password which would be used to protect the key and subkey. + * If NULL then key will be stored in cleartext (unencrypted). + * @param key if non-NULL, then handle of the primary key will be stored here on success. + * Caller must destroy it with rnp_key_handle_destroy() call. + * @return RNP_SUCCESS or error code instead. + */ +RNP_API rnp_result_t rnp_generate_key_ex(rnp_ffi_t ffi, + const char * key_alg, + const char * sub_alg, + uint32_t key_bits, + uint32_t sub_bits, + const char * key_curve, + const char * sub_curve, + const char * userid, + const char * password, + rnp_key_handle_t *key); + +/** Create key generation context for the primary key. + * To generate a subkey use function rnp_op_generate_subkey_create() instead. + * Note: pass provider is required if generated key needs protection. + * + * @param op pointer to opaque key generation context. + * @param ffi + * @param alg key algorithm as string. Must be able to sign. Currently the following algorithms + * are supported (case-insensetive) : 'rsa', 'dsa', 'ecdsa', 'eddsa', 'sm2'. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_create(rnp_op_generate_t *op, + rnp_ffi_t ffi, + const char * alg); + +/** Create key generation context for the subkey. + * Note: you need to have primary key before calling this function. It can be loaded from + * keyring or generated via the function rnp_op_generate_create(). Also pass provider is needed + * if primary key is encrypted (protected and locked). + * + * @param op pointer to opaque key generation context. + * @param ffi + * @param primary primary key handle, must have secret part. + * @param alg key algorithm as string. Currently the following algorithms are supported + * (case-insensetive) : 'rsa', 'dsa', 'elgamal', 'ecdsa', 'eddsa', 'ecdh', 'sm2'. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_subkey_create(rnp_op_generate_t *op, + rnp_ffi_t ffi, + rnp_key_handle_t primary, + const char * alg); + +/** Set bits of the generated key or subkey. + * Note: this is applicable only to rsa, dsa and el-gamal keys. + * + * @param op pointer to opaque key generation context. + * @param bits number of bits + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_set_bits(rnp_op_generate_t op, uint32_t bits); + +/** Set hash algorithm used in self signature or subkey binding signature. + * + * @param op pointer to opaque key generation context. + * @param hash string with hash algorithm name. Following hash algorithms are supported: + * "MD5", "SHA1", "RIPEMD160", "SHA256", "SHA384", "SHA512", "SHA224", "SM3" + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_set_hash(rnp_op_generate_t op, const char *hash); + +/** Set size of q parameter for DSA key. + * Note: appropriate default value will be set, depending on key bits. However you may + * override it if needed. + * @param op pointer to opaque key generation context. + * @param qbits number of bits + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_set_dsa_qbits(rnp_op_generate_t op, uint32_t qbits); + +/** Set the curve used for ECC key + * Note: this is only applicable for ECDSA, ECDH and SM2 keys. + * @param op pointer to opaque key generation context. + * @param curve string with curve name. Following curve names may be used: + * "NIST P-256", "NIST P-384", "NIST P-521", "Curve25519" (ECDH only), + * "brainpoolP256r1", "brainpoolP384r1", "brainpoolP512r1", "secp256k1", + * "SM2 P-256" (SM2 only) + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_set_curve(rnp_op_generate_t op, const char *curve); + +/** Set password, used to encrypt secret key data. If this method is not called then + * key will be generated without protection (unencrypted). + * + * @param op pointer to opaque key generation context. + * @param password string with password, could not be NULL. Will be copied internally so may + * be safely freed after the call. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_set_protection_password(rnp_op_generate_t op, + const char * password); + +/** + * @brief Enable or disable password requesting via ffi's password provider. This password + * then will be used for key encryption. + * Note: this will be ignored if password was set via + * rnp_op_generate_set_protection_password(). + * + * @param op pointer to opaque key generation context. + * @param request true to enable password requesting or false otherwise. Default value is false + * (i.e. key will be generated unencrypted). + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_set_request_password(rnp_op_generate_t op, bool request); + +/** Set cipher used to encrypt secret key data. If not called then default one will be used. + * + * @param op pointer to opaque key generation context. + * @param cipher string with cipher name. Following ciphers are supported: + * "Idea", "Tripledes", "Cast5", "Blowfish", "AES128", "AES192", "AES256", + * "Twofish", "Camellia128", "Camellia192", "Camellia256", "SM4". + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_set_protection_cipher(rnp_op_generate_t op, + const char * cipher); + +/** Set hash algorithm, used to derive key from password for secret key data encryption. + * If not called then default one will be used. + * + * @param op pointer to opaque key generation context. + * @param hash string with hash algorithm, see rnp_op_generate_set_hash() for the whole list. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_set_protection_hash(rnp_op_generate_t op, + const char * hash); + +/** Set encryption mode, used for secret key data encryption. + * Note: currently this makes sense only for G10 key format + * + * @param op pointer to opaque key generation context. + * @param mode string with mode name: "CFB", "CBC", "OCB" + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_set_protection_mode(rnp_op_generate_t op, + const char * mode); + +/** Set number of iterations used to derive key from password for secret key encryption. + * If not called then default one will be used. + * + * @param op pointer to opaque key generation context. + * @param iterations number of iterations + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_set_protection_iterations(rnp_op_generate_t op, + uint32_t iterations); + +/** Add key usage flag to the key or subkey. + * Note: use it only if you need to override defaults, which depend on primary key or subkey, + * and public key algorithm. + * + * @param op pointer to opaque key generation context. + * @param usage string, representing key usage. Following values are supported: "sign", + * "certify", "encrypt", "authenticate". + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_add_usage(rnp_op_generate_t op, const char *usage); + +/** Reset key usage flags, so default ones will be used during key/subkey generation + * + * @param op pointer to opaque key generation context. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_clear_usage(rnp_op_generate_t op); + +/** Set the userid which will represent the generate key. + * Note: Makes sense only for primary key generation. + * + * @param op pointer to opaque key generation context. + * @param userid NULL-terminated string with userid. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_set_userid(rnp_op_generate_t op, const char *userid); + +/** Set the key or subkey expiration time. + * + * @param op pointer to opaque key generation context. + * @param expiration expiration time in seconds. 0 value means that key doesn't expire. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_set_expiration(rnp_op_generate_t op, uint32_t expiration); + +/** Add preferred hash to user preferences. + * Note: the first added hash algorithm has the highest priority, then the second and so on. + * Applicable only for the primary key generation. + * + * @param op pointer to opaque key generation context. + * @param hash string, representing the hash algorithm. See the rnp_op_generate_set_hash() + * function description for the list of possible values. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_add_pref_hash(rnp_op_generate_t op, const char *hash); + +/** Clear the preferred hash algorithms list, so default ones will be used. + * + * @param op pointer to opaque key generation context. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_clear_pref_hashes(rnp_op_generate_t op); + +/** Add preferred compression algorithm to user preferences. + * Note: the first added algorithm has the highest priority, then the second and so on. + * Applicable only for the primary key generation. + * + * @param op pointer to opaque key generation context. + * @param compression string, representing the compression algorithm. Possible values are: + * "zip", "zlib", "bzip2" + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_add_pref_compression(rnp_op_generate_t op, + const char * compression); + +/** Clear the preferred compression algorithms list, so default ones will be used. + * + * @param op pointer to opaque key generation context. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_clear_pref_compression(rnp_op_generate_t op); + +/** Add preferred encryption algorithm to user preferences. + * Note: the first added algorithm has the highest priority, then the second and so on. + * Applicable only for the primary key generation. + * + * @param op pointer to opaque key generation context. + * @param cipher string, representing the encryption algorithm. + * See the rnp_op_generate_set_protection_cipher() function description for + * the list of possible values. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_add_pref_cipher(rnp_op_generate_t op, const char *cipher); + +/** Clear the preferred encryption algorithms list, so default ones will be used. + * + * @param op pointer to opaque key generation context. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_clear_pref_ciphers(rnp_op_generate_t op); + +/** Set the preferred key server. Applicable only for the primary key. + * + * @param op pointer to opaque key generation context. + * @param keyserver NULL-terminated string with key server's URL, or NULL to delete it from + * user preferences. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_set_pref_keyserver(rnp_op_generate_t op, + const char * keyserver); + +/** Execute the prepared key or subkey generation operation. + * Note: if you set protection algorithm, then you need to specify ffi password provider to + * be able to request password for key encryption. + * + * @param op pointer to opaque key generation context. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_execute(rnp_op_generate_t op); + +/** Get the generated key's handle. Should be called only after successful execution of + * rnp_op_generate_execute(). + * + * @param op pointer to opaque key generation context. + * @param handle pointer to key handle will be stored here. + * You must free handle after use with rnp_key_handle_destroy. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_get_key(rnp_op_generate_t op, rnp_key_handle_t *handle); + +/** Free resources associated with key generation operation. + * + * @param op opaque key generation context. Must be successfully initialized with one of the + * rnp_op_generate_*_create functions. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_generate_destroy(rnp_op_generate_t op); + +/** export a key + * + * @param key the key to export + * @param output the stream to write to + * @param flags see RNP_KEY_EXPORT_*. + * @return RNP_SUCCESS on success, or any other value on error + **/ +RNP_API rnp_result_t rnp_key_export(rnp_key_handle_t key, rnp_output_t output, uint32_t flags); + +/** + * @brief Export minimal key for autocrypt feature (just 5 packets: key, uid, signature, + * encryption subkey, signature) + * + * @param key primary key handle, cannot be NULL. + * @param subkey subkey to export. May be NULL to pick the first suitable. + * @param uid userid to export. May be NULL if key has only one uid. + * @param output the stream to write to + * @param flags additional flags. Currently only RNP_KEY_EXPORT_BASE64 is supported. Enabling + * it would export key base64-encoded instead of binary. + * @return RNP_SUCCESS on success, or any other value if failed. + */ +RNP_API rnp_result_t rnp_key_export_autocrypt(rnp_key_handle_t key, + rnp_key_handle_t subkey, + const char * uid, + rnp_output_t output, + uint32_t flags); + +/** + * @brief Generate and export primary key revocation signature. + * Note: to revoke a key you'll need to import this signature into the keystore or use + * rnp_key_revoke() function. + * @param key primary key to be revoked. Must have secret key, otherwise keyrings will be + * searched for the authorized to issue revocation signature secret key. If secret + * key is locked then password will be asked via password provider. + * @param output signature contents will be saved here. + * @param flags must be RNP_KEY_EXPORT_ARMORED or 0. + * @param hash hash algorithm used to calculate signature. Pass NULL for default algorithm + * selection. + * @param code reason for revocation code. Possible values: 'no', 'superseded', 'compromised', + * 'retired'. May be NULL - then 'no' value will be used. + * @param reason textual representation of the reason for revocation. May be NULL or empty + * string. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_key_export_revocation(rnp_key_handle_t key, + rnp_output_t output, + uint32_t flags, + const char * hash, + const char * code, + const char * reason); + +/** + * @brief revoke a key or subkey by generating and adding revocation signature. + * @param key key or subkey to be revoked. For primary key must have secret key, otherwise + * keyrings will be searched for the authorized to issue revocation signatures + * secret key. For subkey keyrings must have primary secret key. + * If secret key is locked then password will be asked via password provider. + * @param flags currently must be 0. + * @param hash hash algorithm used to calculate signature. Pass NULL for default algorithm + * selection. + * @param code reason for revocation code. Possible values: 'no', 'superseded', 'compromised', + * 'retired'. May be NULL - then 'no' value will be used. + * @param reason textual representation of the reason for revocation. May be NULL or empty + * string. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_key_revoke(rnp_key_handle_t key, + uint32_t flags, + const char * hash, + const char * code, + const char * reason); + +/** + * @brief Check whether Curve25519 secret key's bits are correctly set, i.e. 3 least + * significant bits are zero and key is exactly 255 bits in size. See RFC 7748, section + * 5 for the details. RNP interpreted RFC requirements in the way that Curve25519 secret + * key is random 32-byte string, which bits are correctly tweaked afterwards within + * secret key operation. However, for compatibility reasons, it would be more correct to + * store/transfer secret key with bits already tweaked. + * + * Note: this operation requires unlocked secret key, so make sure to call + * rnp_key_lock() afterwards. + * + * @param key key handle, cannot be NULL. Must be ECDH Curve25519 unlocked secret key. + * @param result true will be stored here if secret key's low/high bits are not correctly set. + * In this case you may need to call `rnp_key_25519_bits_tweak()` on it to set + * bits to correct values so exported secret key will be compatible with + * implementations which do not tweak these bits automatically. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_25519_bits_tweaked(rnp_key_handle_t key, bool *result); + +/** + * @brief Make sure Curve25519 secret key's least significant and most significant bits are + * correctly set, see rnp_key_25519_bits_tweaked() documentation for the details. + * Note: this operation requires unprotected secret key since it would modify secret + * key's data, so make sure to call rnp_key_protect() afterwards. + * + * @param key key handle, cannot be NULL. Must be ECDH Curve25519 unprotected secret key. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_25519_bits_tweak(rnp_key_handle_t key); + +/** remove a key from keyring(s) + * Note: you need to call rnp_save_keys() to write updated keyring(s) out. + * Other handles of the same key should not be used after this call. + * @param key pointer to the key handle. + * @param flags see RNP_KEY_REMOVE_* constants. Flag RNP_KEY_REMOVE_SUBKEYS will work only for + * primary key, and remove all of its subkeys as well. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_remove(rnp_key_handle_t key, uint32_t flags); + +/** + * @brief Remove unneeded signatures from the key, it's userids and subkeys if any. + * May be called on subkey handle as well. + * Note: you'll need to call rnp_save_keys() to write updated keyring(s) out. + * Any signature handles related to this key, it's uids or subkeys should not be used + * after this call. + * + * @param key key handle, cannot be NULL. + * @param flags flags, controlling which signatures to remove. Signature will be removed if it + * matches at least one of these flags. + * Currently following signature matching flags are defined: + * - RNP_KEY_SIGNATURE_INVALID : signature is invalid and was never valid. Note, + * that this will not remove invalid signature if there is no signer's public + * key in the keyring. + * - RNP_KEY_SIGNATURE_UNKNOWN_KEY : signature is made by the key which is not + * known/available. + * - RNP_KEY_SIGNATURE_NON_SELF_SIG : signature is not a self-signature (i.e. made + * by the key itself or corresponding primary key). + * + * Note: if RNP_KEY_SIGNATURE_NON_SELF_SIG is not specified then function will + * attempt to validate all the signatures, and look up for the signer's public key + * via keyring/key provider. + * + * @param sigcb callback, used to record information about the removed signatures, or further + * filter out the signatures. May be NULL. + * @param app_ctx context information, passed to sigcb. May be NULL. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_remove_signatures(rnp_key_handle_t key, + uint32_t flags, + rnp_key_signatures_cb sigcb, + void * app_ctx); + +/** + * @brief Guess contents of the OpenPGP data stream. + * Note: This call just peeks data from the stream, so stream is still usable for + * the further processing. + * @param input stream with data. Must be opened and cannot be NULL. + * @param contents string with guessed data format will be stored here. + * Possible values: 'message', 'public key', 'secret key', 'signature', + * 'unknown'. May be used as type in rnp_enarmor() function. Must be + * deallocated with rnp_buffer_destroy() call. + * @return RNP_SUCCESS on success, or any other value on error. + */ +RNP_API rnp_result_t rnp_guess_contents(rnp_input_t input, char **contents); + +/** Add ASCII Armor + * + * @param input stream to read data from + * @param output stream to write armored data to + * @param type the type of armor to add ("message", "public key", + * "secret key", "signature", "cleartext"). Use NULL to try + * to guess the type. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_enarmor(rnp_input_t input, rnp_output_t output, const char *type); + +/** Remove ASCII Armor + * + * @param input stream to read armored data from + * @param output stream to write dearmored data to + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_dearmor(rnp_input_t input, rnp_output_t output); + +/** Get key's primary user id. + * Note: userid considered as primary if it has marked as primary in self-certification, and + * is valid (i.e. both certification and key are valid, not expired and not revoked). If + * there is no userid marked as primary then the first valid userid handle will be + * returned. + * @param key key handle. + * @param uid pointer to the string with primary user id will be stored here. + * You must free it using the rnp_buffer_destroy(). + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_get_primary_uid(rnp_key_handle_t key, char **uid); + +/** Get number of the key's user ids. + * + * @param key key handle. + * @param count number of user ids will be stored here. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_get_uid_count(rnp_key_handle_t key, size_t *count); + +/** Get key's user id by its index. + * + * @param key key handle. + * @param idx zero-based index of the userid. + * @param uid pointer to the string with user id will be stored here. + * You must free it using the rnp_buffer_destroy(). + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_get_uid_at(rnp_key_handle_t key, size_t idx, char **uid); + +/** Get key's user id handle by its index. + * Note: user id handle may become invalid once corresponding user id or key is removed. + * + * @param key key handle + * @param idx zero-based index of the userid. + * @param uid user id handle will be stored here on success. You must destroy it + * using the rnp_uid_handle_destroy(). + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_get_uid_handle_at(rnp_key_handle_t key, + size_t idx, + rnp_uid_handle_t *uid); + +/** Get userid's type. Currently two possible values are defined: + * - RNP_USER_ID - string representation of user's name and email. + * - RNP_USER_ATTR - binary photo of the user + + * @param uid uid handle, cannot be NULL. + * @param type on success userid type will be stored here. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_uid_get_type(rnp_uid_handle_t uid, uint32_t *type); + +/** Get userid's data. Representation of data depends on userid type (see rnp_uid_get_type() + * function) + * + * @param uid uid handle, cannot be NULL. + * @param data cannot be NULL. On success pointer to the allocated buffer with data will be + * stored here. Must be deallocated by caller via rnp_buffer_destroy(). + * @param size cannot be NULL. On success size of the data will be stored here. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_uid_get_data(rnp_uid_handle_t uid, void **data, size_t *size); + +/** Check whether uid is marked as primary. + * + * @param uid uid handle, cannot be NULL + * @param primary cannot be NULL. On success true or false will be stored here. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_uid_is_primary(rnp_uid_handle_t uid, bool *primary); + +/** Get userid validity status. Userid is considered as valid if key itself is valid, and + * userid has at least one valid, non-expired self-certification. + * Note: - userid still may be valid even if a primary key is invalid - expired, revoked, etc. + * - up to the RNP version 0.15.1 uid was not considered as valid if it's latest + * self-signature has key expiration in the past. + * + * @param uid user id handle. + * @param valid validity status will be stored here on success. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_uid_is_valid(rnp_uid_handle_t uid, bool *valid); + +/** Get number of key's signatures. + * Note: this will not count user id certifications and subkey(s) signatures if any. + * I.e. it will return only number of direct-key and key revocation signatures for the + * primary key, and number of subkey bindings/revocation signatures for the subkey. + * Use rnp_uid_get_signature_count() or call this function on subkey's handle. + * + * @param key key handle + * @param count number of key's signatures will be stored here. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_get_signature_count(rnp_key_handle_t key, size_t *count); + +/** Get key's signature, based on its index. + * Note: see the rnp_key_get_signature_count() description for the details. + * + * @param key key handle + * @param idx zero-based signature index. + * @param sig signature handle will be stored here on success. You must free it after use with + * the rnp_signature_handle_destroy() function. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_get_signature_at(rnp_key_handle_t key, + size_t idx, + rnp_signature_handle_t *sig); + +/** + * @brief Get key's revocation signature handle, if any. + * + * @param key key handle + * @param sig signature handle or NULL will be stored here on success. NULL will be stored in + * case when there is no valid revocation signature. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_get_revocation_signature(rnp_key_handle_t key, + rnp_signature_handle_t *sig); + +/** Get the number of user id's signatures. + * + * @param uid user id handle. + * @param count number of uid's signatures will be stored here. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_uid_get_signature_count(rnp_uid_handle_t uid, size_t *count); + +/** Get user id's signature, based on its index. + * + * @param uid uid handle. + * @param idx zero-based signature index. + * @param sig signature handle will be stored here on success. You must free it after use with + * the rnp_signature_handle_destroy() function. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_uid_get_signature_at(rnp_uid_handle_t uid, + size_t idx, + rnp_signature_handle_t *sig); + +/** + * @brief Get signature's type. + * + * @param sig signature handle. + * @param type on success string with signature type will be saved here. Cannot be NULL. + * You must free it using the rnp_buffer_destroy(). + * Currently defined values are: + * - 'binary' : signature of a binary document + * - 'text' : signature of a canonical text document + * - 'standalone' : standalone signature + * - 'certification (generic)` : generic certification of a user id + * - 'certification (persona)' : persona certification of a user id + * - 'certification (casual)' : casual certification of a user id + * - 'certification (positive)' : positive certification of a user id + * - 'subkey binding' : subkey binding signature + * - 'primary key binding' : primary key binding signature + * - 'direct' : direct-key signature + * - 'key revocation' : primary key revocation signature + * - 'subkey revocation' : subkey revocation signature + * - 'certification revocation' : certification revocation signature + * - 'timestamp' : timestamp signature + * - 'third-party' : third party confirmation signature + * - 'uknown: 0..255' : unknown signature with its type specified as number + * + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_signature_get_type(rnp_signature_handle_t sig, char **type); + +/** Get signature's algorithm. + * + * @param sig signature handle. + * @param alg on success string with algorithm name will be saved here. Cannot be NULL. +* You must free it using the rnp_buffer_destroy(). + + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_signature_get_alg(rnp_signature_handle_t sig, char **alg); + +/** Get signature's hash algorithm. + * + * @param sig signature handle. + * @param alg on success string with algorithm name will be saved here. Cannot be NULL. + * You must free it using the rnp_buffer_destroy(). + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_signature_get_hash_alg(rnp_signature_handle_t sig, char **alg); + +/** Get the signature creation time as number of seconds since Jan, 1 1970 UTC + * + * @param sig signature handle. + * @param create on success result will be stored here. Cannot be NULL. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_signature_get_creation(rnp_signature_handle_t sig, uint32_t *create); + +/** Get the signature expiration time as number of seconds after creation time + * + * @param sig signature handle. + * @param expires on success result will be stored here. Cannot be NULL. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_signature_get_expiration(rnp_signature_handle_t sig, + uint32_t * expires); + +/** Get signer's key id from the signature. + * Note: if key id is not available from the signature then NULL value will + * be stored to result. + * @param sig signature handle + * @param result hex-encoded key id will be stored here. Cannot be NULL. You must free it + * later on using the rnp_buffer_destroy() function. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_signature_get_keyid(rnp_signature_handle_t sig, char **result); + +/** Get signer's key fingerprint from the signature. + * Note: if key fingerprint is not available from the signature then NULL value will + * be stored to result. + * @param sig signature handle + * @param result hex-encoded key fp will be stored here. Cannot be NULL. You must free it + * later on using the rnp_buffer_destroy() function. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_signature_get_key_fprint(rnp_signature_handle_t sig, char **result); + +/** Get signing key handle, if available. + * Note: if signing key is not available then NULL will be stored in key. + * @param sig signature handle + * @param key on success and key availability will contain signing key's handle. You must + * destroy it using the rnp_key_handle_destroy() function. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_signature_get_signer(rnp_signature_handle_t sig, + rnp_key_handle_t * key); + +/** + * @brief Get signature validity, revalidating it if didn't before. + * + * @param sig key/userid signature handle + * @param flags validation flags, currently must be zero. + * @return Following error codes represents the validation status: + * RNP_SUCCESS : operation succeeds and signature is valid + * RNP_ERROR_KEY_NOT_FOUND : signer's key not found + * RNP_ERROR_VERIFICATION_FAILED: verification failed, so validity cannot be checked + * RNP_ERROR_SIGNATURE_EXPIRED: signature is valid but expired + * RNP_ERROR_SIGNATURE_INVALID: signature is invalid (corrupted, malformed, was issued + * by invalid key, whatever else.) + * + * Please also note that other error codes may be returned because of wrong + * function call (included, but not limited to): + * RNP_ERROR_NULL_POINTER: sig as well as some of its fields are NULL + * RNP_ERROR_BAD_PARAMETERS: invalid parameter value (unsupported flag, etc). + */ +RNP_API rnp_result_t rnp_signature_is_valid(rnp_signature_handle_t sig, uint32_t flags); + +/** Dump signature packet to JSON, obtaining the whole information about it. + * + * @param sig sigmature handle, cannot be NULL + * @param flags include additional fields in JSON (see RNP_JSON_DUMP_MPI and other + * RNP_JSON_DUMP_* flags) + * @param result resulting JSON string will be stored here. You must free it using the + * rnp_buffer_destroy() function. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_signature_packet_to_json(rnp_signature_handle_t sig, + uint32_t flags, + char ** json); + +/** + * @brief Remove a signature. + * + * @param key key handle, cannot be NULL. + * @param sig signature handle, cannot be NULL. Must be obtained via the key handle or one of + * its userids. You still need to call rnp_signature_handle_destroy afterwards to + * destroy handle itself. All other handles of the same signature, if any, should + * not be used after the call is made. + * @return RNP_SUCCESS if signature was successfully deleted, or any other value on error. + */ +RNP_API rnp_result_t rnp_signature_remove(rnp_key_handle_t key, rnp_signature_handle_t sig); + +/** + * @brief Export a signature. + * + * @param sig signature handle, cannot be NULL. + * @param output destination of the data stream. + * @param flags must be RNP_KEY_EXPORT_ARMORED or 0. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_signature_export(rnp_signature_handle_t sig, + rnp_output_t output, + uint32_t flags); + +/** Free signature handle. + * + * @param sig signature handle. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_signature_handle_destroy(rnp_signature_handle_t sig); + +/** Check whether user id is revoked. + * + * @param uid user id handle, should not be NULL. + * @param result boolean result will be stored here on success. Cannot be NULL. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_uid_is_revoked(rnp_uid_handle_t uid, bool *result); + +/** Retrieve uid revocation signature, if any. + * + * @param uid user id handle, should not be NULL. + * @param sig on success signature handle or NULL will be stored here. NULL will be stored in + * case when uid is not revoked. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_uid_get_revocation_signature(rnp_uid_handle_t uid, + rnp_signature_handle_t *sig); + +/** + * @brief Remove userid with all of its signatures from the key + * + * @param key key handle, cannot be NULL and must own the uid. + * @param uid uid handle, cannot be NULL. Still must be destroyed afterwards via the + * rnp_uid_handle_destroy(). All other handles pointing to the same uid will + * become invalid and should not be used. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_uid_remove(rnp_key_handle_t key, rnp_uid_handle_t uid); + +/** Destroy previously allocated user id handle. + * + * @param uid user id handle. + * @return RNP_SUCCESS or error code + */ +RNP_API rnp_result_t rnp_uid_handle_destroy(rnp_uid_handle_t uid); + +/** Get number of the key's subkeys. + * + * @param key key handle. + * @param count number of subkeys will be stored here. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_get_subkey_count(rnp_key_handle_t key, size_t *count); + +/** Get the handle of one of the key's subkeys, using its index in the list. + * + * @param key handle of the primary key. + * @param idx zero-based index of the subkey. + * @param subkey on success handle for the subkey will be stored here. You must free it + * using the rnp_key_handle_destroy() function. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_get_subkey_at(rnp_key_handle_t key, + size_t idx, + rnp_key_handle_t *subkey); + +/** Get default key for specified usage. Accepts primary key + * and returns one of its subkeys suitable for desired usage. + * May return the same primary key if it is suitable for requested + * usage and flag RNP_KEY_SUBKEYS_ONLY is not set. + * + * @param primary_key handle of the primary key. + * @param usage desired key usage i.e. "sign", "certify", etc, + * see rnp_op_generate_add_usage() function description for all possible values. + * @param flags possible values: RNP_KEY_SUBKEYS_ONLY - select only subkeys, + * otherwise if flags is 0, primary key can be returned if + * it is suitable for specified usage. + * @param default_key on success resulting key handle will be stored here, otherwise it + * will contain NULL value. You must free this handle after use with + * rnp_key_handle_destroy(). + * @return RNP_SUCCESS on success, RNP_ERROR_KEY_NOT_FOUND if no key with desired usage + * was found or any other error code. + */ +RNP_API rnp_result_t rnp_key_get_default_key(rnp_key_handle_t primary_key, + const char * usage, + uint32_t flags, + rnp_key_handle_t *default_key); + +/** Get the key's algorithm. + * + * @param key key handle + * @param alg string with algorithm name will be stored here. You must free it using the + * rnp_buffer_destroy() function. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_get_alg(rnp_key_handle_t key, char **alg); + +/** Get number of bits in the key. For EC-based keys it will return size of the curve. + * + * @param key key handle + * @param bits number of bits will be stored here. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_get_bits(rnp_key_handle_t key, uint32_t *bits); + +/** Get the number of bits in q parameter of the DSA key. Makes sense only for DSA keys. + * + * @param key key handle + * @param qbits number of bits will be stored here. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_get_dsa_qbits(rnp_key_handle_t key, uint32_t *qbits); + +/** Get the curve of EC-based key. + * + * @param key key handle + * @param curve string with name of the curve will be stored here. You must free it using the + * rnp_buffer_destroy() function. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_get_curve(rnp_key_handle_t key, char **curve); + +/** Add a new user identifier to a key + * + * @param ffi + * @param key the key to add - must be a secret key + * @param uid the UID to add + * @param hash name of the hash function to use for the uid binding + * signature (eg "SHA256"). If NULL, default hash algorithm + * will be used. + * @param expiration time when this user id expires + * @param key_flags usage flags, see section 5.2.3.21 of RFC 4880 + * or just provide zero to indicate no special handling. + * @param primary indicates if this is the primary UID + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_add_uid(rnp_key_handle_t key, + const char * uid, + const char * hash, + uint32_t expiration, + uint8_t key_flags, + bool primary); + +/* The following output hex encoded strings */ + +/** + * @brief Get key's fingerprint as hex-encoded string. + * + * @param key key handle, should not be NULL + * @param fprint pointer to the NULL-terminated string with hex-encoded fingerprint will be + * stored here. You must free it later using rnp_buffer_destroy function. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_get_fprint(rnp_key_handle_t key, char **fprint); + +/** + * @brief Get key's id as hex-encoded string + * + * @param key key handle, should not be NULL + * @param keyid pointer to the NULL-terminated string with hex-encoded key id will be + * stored here. You must free it later using rnp_buffer_destroy function. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_get_keyid(rnp_key_handle_t key, char **keyid); + +/** + * @brief Get key's grip as hex-encoded string + * + * @param key key handle, should not be NULL + * @param grip pointer to the NULL-terminated string with hex-encoded key grip will be + * stored here. You must free it later using rnp_buffer_destroy function. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_get_grip(rnp_key_handle_t key, char **grip); + +/** + * @brief Get primary's key grip for the subkey, if available. + * + * @param key key handle, should not be NULL + * @param grip pointer to the NULL-terminated string with hex-encoded key grip or NULL will be + * stored here, depending whether primary key is available or not. + * You must free it later using rnp_buffer_destroy function. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_get_primary_grip(rnp_key_handle_t key, char **grip); + +/** + * @brief Get primary's key fingerprint for the subkey, if available. + * + * @param key subkey handle, should not be NULL + * @param grip pointer to the NULL-terminated string with hex-encoded key fingerprint or NULL + * will be stored here, depending whether primary key is available or not. You must + * free it later using rnp_buffer_destroy function. + * @return RNP_SUCCESS on success, RNP_BAD_PARAMETERS if not a subkey, or other error code + * on failure. + */ +RNP_API rnp_result_t rnp_key_get_primary_fprint(rnp_key_handle_t key, char **fprint); + +/** + * @brief Check whether certain usage type is allowed for the key. + * + * @param key key handle, should not be NULL + * @param usage string describing the key usage. For the list of allowed values see the + * rnp_op_generate_add_usage() function description. + * @param result function result will be stored here. Could not be NULL. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_allows_usage(rnp_key_handle_t key, + const char * usage, + bool * result); + +/** + * @brief Get the key's creation time. + * + * @param key key handle, should not be NULL. + * @param result creation time will be stored here. Cannot be NULL. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_get_creation(rnp_key_handle_t key, uint32_t *result); + +/** + * @brief Get the key's expiration time in seconds. + * Note: 0 means that the key doesn't expire. + * + * @param key key handle, should not be NULL + * @param result expiration time will be stored here. Could not be NULL. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_get_expiration(rnp_key_handle_t key, uint32_t *result); + +/** + * @brief Set the key's expiration time in seconds. + * Note: this will require re-signing, which requires availability of the secret key (or + * secret primary key for the subkey). If the secret key is locked then may ask for + * key's password via FFI callback. + * + * @param key key's handle. + * @param expiry expiration time in seconds (or 0 if key doesn't expire). Please note that it + * is calculated from the key creation time, not from the current time. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_set_expiration(rnp_key_handle_t key, uint32_t expiry); + +/** + * @brief Check whether public key is valid. This includes checks of the self-signatures, + * expiration times, revocations and so on. + * Note: it doesn't take in account secret key, if it is available. + * + * @param key key's handle. + * @param result on success true or false will be stored here. Cannot be NULL. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_is_valid(rnp_key_handle_t key, bool *result); + +/** + * @brief Get the timestamp till which key can be considered as valid. + * Note: this will take into account not only key's expiration, but revocations as well. + * For the subkey primary key's validity time will be also checked. + * While in OpenPGP key creation and expiration times are 32-bit, their sum may overflow + * 32 bits, so rnp_key_valid_till64 function should be used. + * In case of 32 bit overflow result will be set to the UINT32_MAX - 1. + * @param key key's handle. + * @param result on success timestamp will be stored here. If key doesn't expire then maximum + * value (UINT32_MAX or UINT64_MAX) will be stored here. If key was never valid + * then zero value will be stored here. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_valid_till(rnp_key_handle_t key, uint32_t *result); +RNP_API rnp_result_t rnp_key_valid_till64(rnp_key_handle_t key, uint64_t *result); + +/** + * @brief Check whether key is revoked. + * + * @param key key handle, should not be NULL + * @param result on success result will be stored here. Could not be NULL. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_is_revoked(rnp_key_handle_t key, bool *result); + +/** + * @brief Get textual description of the key's revocation reason (if any) + * + * @param key key handle, should not be NULL + * @param result on success pointer to the NULL-terminated string will be stored here. + * You must free it later using rnp_buffer_destroy() function. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_get_revocation_reason(rnp_key_handle_t key, char **result); + +/** + * @brief Check whether revoked key was superseded by other key. + * + * @param key key handle, should not be NULL + * @param result on success result will be stored here. Could not be NULL. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_is_superseded(rnp_key_handle_t key, bool *result); + +/** + * @brief Check whether revoked key's material was compromised. + * + * @param key key handle, should not be NULL + * @param result on success result will be stored here. Could not be NULL. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_is_compromised(rnp_key_handle_t key, bool *result); + +/** + * @brief Check whether revoked key was retired. + * + * @param key key handle, should not be NULL + * @param result on success result will be stored here. Could not be NULL. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_is_retired(rnp_key_handle_t key, bool *result); + +/** + * @brief Check whether key is expired. + * Note: while expired key cannot be used to generate new signatures or encrypt to, it + * still could be used to check older signatures/decrypt previously encrypted data. + * + * @param key key handle, should not be NULL. + * @param result on success result will be stored here. True means that key is expired and is + * not usable and false otherwise. + * @return RNP_SUCCESS or error code on failure. + */ +RNP_API rnp_result_t rnp_key_is_expired(rnp_key_handle_t key, bool *result); + +/** check if a key is currently locked + * + * @param key + * @param result pointer to hold the result. This will be set to true if + * the key is currently locked, or false otherwise. Must not be NULL. + * @return RNP_SUCCESS on success, or any other value on error + **/ +RNP_API rnp_result_t rnp_key_is_locked(rnp_key_handle_t key, bool *result); + +/** + * @brief Get type of protection, used for secret key data. + * + * @param key key handle, cannot be NULL and should have secret part (see function + * rnp_key_have_secret()). + * @param type on success protection type will be stored here. Cannot be NULL. + * Must be freed by caller via rnp_buffer_destroy() call. + * Currently defined values are: + * - "None" : secret key data is stored in plaintext. + * - "Encrypted" : secret key data is encrypted, using just CRC as integrity + * protection. + * - "Encrypted-Hashed" : secret key data is encrypted, using the SHA1 hash as + * an integrity protection. + * - "GPG-None" : secret key data is not available at all (this would happen if + * secret key is exported from GnuPG via --export-secret-subkeys) + * - "GPG-Smartcard" : secret key data is stored on smartcard by GnuPG, so is not + * available + * - "Unknown" : key protection type is unknown, so secret key data is not + * available + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_key_get_protection_type(rnp_key_handle_t key, char **type); + +/** + * @brief Get mode in which secret key data is encrypted. + * + * @param key key handle, cannot be NULL and should have secret part (see function + * rnp_key_have_secret()). + * @param mode on success secret key protection mode name will be stored here. Cannot be NULL. + * Must be freed by caller via rnp_buffer_destroy() call. + * Currently defined values are: + * - "None" : secret key data is not encrypted at all + * - "Unknown" : it is not known how secret key data is encrypted, so there is no + * way to unlock/unprotect the key. + * - "CFB" : secret key data is encrypted in CFB mode, using the password + * - "CBC" : secret key data is encrypted in CBC mode, using the password + * (only for G10 keys) + * - "OCB" : secert key data is encrypted in OCB mode, using the password + * (only for G10 keys) + * @return RNP_SUCCESS on success, or any other value on error. + */ +RNP_API rnp_result_t rnp_key_get_protection_mode(rnp_key_handle_t key, char **mode); + +/** + * @brief Get cipher, used to encrypt secret key data. + * Note: this call will return an error if secret key data is not available or secret + * key is not encrypted. + * + * @param key key handle, cannot be NULL and should have secret part. + * @param cipher on success cipher name will be stored here. See + * rnp_op_generate_set_protection_cipher for possible values. Cannot be NULL. + * Must be freed by caller via rnp_buffer_destroy() call. + * @return RNP_SUCCESS on success, or any other value on error. + */ +RNP_API rnp_result_t rnp_key_get_protection_cipher(rnp_key_handle_t key, char **cipher); + +/** + * @brief Get hash, used to derive secret key data encrypting key from the password. + * Note: this call will return an error if secret key data is not available or secret + * key is not encrypted. + * @param key key handle, cannot be NULL and should have secret part. + * @param hash on success hash name will be stored here. See rnp_op_generate_set_hash() for the + * whole list of possible values. Cannot be NULL. + * Must be freed by caller via rnp_buffer_destroy() call. + * @return RNP_SUCCESS on success, or any other value on error. + */ +RNP_API rnp_result_t rnp_key_get_protection_hash(rnp_key_handle_t key, char **hash); + +/** + * @brief Get number of iterations used to derive encrypting key from password, using the hash + * function. + * Note: this call will return an error if secret key data is not available or secret + * key is not encrypted. + * + * @param key key handle, cannot be NULL and should have secret part. + * @param iterations on success number of iterations will be stored here. Cannot be NULL. + * @return RNP_SUCCESS on success, or any other value on error. + */ +RNP_API rnp_result_t rnp_key_get_protection_iterations(rnp_key_handle_t key, + size_t * iterations); + +/** lock the key + * + * A locked key does not have the secret key material immediately + * available for use. A locked and protected (aka encrypted) key + * is safely encrypted in memory and requires a password for + * performing any operations involving the secret key material. + * + * Generally lock/unlock are not useful for unencrypted (not protected) keys. + * + * @param key + * @return RNP_SUCCESS on success, or any other value on error + **/ +RNP_API rnp_result_t rnp_key_lock(rnp_key_handle_t key); + +/** unlock the key + * + * An unlocked key has unencrypted secret key material available for use + * without a password. + * + * Generally lock/unlock are not useful for unencrypted (not protected) keys. + * + * @param key + * @param password the password to unlock the key. If NULL, the password + * provider will be used. + * @return RNP_SUCCESS on success, or any other value on error + **/ +RNP_API rnp_result_t rnp_key_unlock(rnp_key_handle_t key, const char *password); + +/** check if a key is currently protected + * + * A protected key is one that is encrypted and can be safely held in memory + * and locked/unlocked as needed. + * + * @param key + * @param result pointer to hold the result. This will be set to true if + * the key is currently protected, or false otherwise. Must not be NULL. + * @return RNP_SUCCESS on success, or any other value on error + **/ +RNP_API rnp_result_t rnp_key_is_protected(rnp_key_handle_t key, bool *result); + +/** protect the key + * + * This can be used to set a new password on a key or to protect an unprotected + * key. + * + * Note that the only required parameter is "password". + * + * @param key + * @param password the new password to encrypt/re-encrypt the key with. + * Must not be NULL. + * @param cipher the cipher (AES256, etc) used to encrypt the key. May be NULL, + * in which case a default will be used. + * @param cipher_mode the cipher mode (CFB, CBC, OCB). This parameter is not + * well supported currently and is mostly relevant for G10. + * May be NULL. + * @param hash the hash algorithm (SHA512, etc) used for the String-to-Key key + * derivation. May be NULL, in which case a default will be used. + * @param iterations the number of iterations used for the String-to-Key key + * derivation. Use 0 to select a reasonable default. + * @return RNP_SUCCESS on success, or any other value on error + **/ +RNP_API rnp_result_t rnp_key_protect(rnp_key_handle_t handle, + const char * password, + const char * cipher, + const char * cipher_mode, + const char * hash, + size_t iterations); + +/** unprotect the key + * + * This removes the encryption from the key. + * + * @param key + * @param password the password to unlock the key. If NULL, the password + * provider will be used. + * @return RNP_SUCCESS on success, or any other value on error + **/ +RNP_API rnp_result_t rnp_key_unprotect(rnp_key_handle_t key, const char *password); + +/** + * @brief Check whether key is primary key. + * + * @param key key handle, cannot be NULL. + * @param result true or false will be stored here on success. + * @return RNP_SUCCESS on success, or any other value on error. + */ +RNP_API rnp_result_t rnp_key_is_primary(rnp_key_handle_t key, bool *result); + +/** + * @brief Check whether key is subkey. + * + * @param key key handle, cannot be NULL. + * @param result true or false will be stored here on success. + * @return RNP_SUCCESS on success, or any other value on error. + */ +RNP_API rnp_result_t rnp_key_is_sub(rnp_key_handle_t key, bool *result); + +/** + * @brief Check whether key has secret part. + * + * @param key key handle, cannot be NULL. + * @param result true will be stored here on success, or false otherwise. + * @return RNP_SUCCESS on success, or any other value on error. + */ +RNP_API rnp_result_t rnp_key_have_secret(rnp_key_handle_t key, bool *result); + +/** + * @brief Check whether key has public part. Generally all keys would have public part. + * + * @param key key handle, cannot be NULL. + * @param result true will be stored here on success, or false otherwise. + * @return RNP_SUCCESS on success, or any other value on error. + */ +RNP_API rnp_result_t rnp_key_have_public(rnp_key_handle_t key, bool *result); + +/** Get the information about key packets in JSON string. + * Note: this will not work for G10 keys. + * + * @param key key's handle, cannot be NULL + * @param secret dump secret key instead of public + * @param flags include additional fields in JSON (see RNP_JSON_DUMP_MPI and other + * RNP_JSON_DUMP_* flags) + * @param result resulting JSON string will be stored here. You must free it using the + * rnp_buffer_destroy() function. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_key_packets_to_json(rnp_key_handle_t key, + bool secret, + uint32_t flags, + char ** result); + +/** Dump OpenPGP packets stream information to the JSON string. + * @param input source with OpenPGP data + * @param flags include additional fields in JSON (see RNP_JSON_DUMP_MPI and other + * RNP_JSON_DUMP_* flags) + * @result resulting JSON string will be stored here. You must free it using the + * rnp_buffer_destroy() function. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_dump_packets_to_json(rnp_input_t input, + uint32_t flags, + char ** result); + +/** Dump OpenPGP packets stream information to output in humand-readable format. + * @param input source with OpenPGP data + * @param output text, describing packet sequence, will be written here + * @param flags see RNP_DUMP_MPI and other RNP_DUMP_* constants. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_dump_packets_to_output(rnp_input_t input, + rnp_output_t output, + uint32_t flags); + +/* Signing operations */ + +/** @brief Create signing operation context. This method should be used for embedded + * signatures of binary data. For detached and cleartext signing corresponding + * function should be used. + * @param op pointer to opaque signing context + * @param ffi + * @param input stream with data to be signed. Could not be NULL. + * @param output stream to write results to. Could not be NULL. + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_sign_create(rnp_op_sign_t *op, + rnp_ffi_t ffi, + rnp_input_t input, + rnp_output_t output); + +/** @brief Create cleartext signing operation context. Input should be text data. Output will + * contain source data with additional headers and armored signature. + * @param op pointer to opaque signing context + * @param ffi + * @param input stream with data to be signed. Could not be NULL. + * @param output stream to write results to. Could not be NULL. + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_sign_cleartext_create(rnp_op_sign_t *op, + rnp_ffi_t ffi, + rnp_input_t input, + rnp_output_t output); + +/** @brief Create detached signing operation context. Output will contain only signature of the + * source data. + * @param op pointer to opaque signing context + * @param ffi + * @param input stream with data to be signed. Could not be NULL. + * @param signature stream to write results to. Could not be NULL. + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_sign_detached_create(rnp_op_sign_t *op, + rnp_ffi_t ffi, + rnp_input_t input, + rnp_output_t signature); + +/** @brief Add information about the signature so it could be calculated later in execute + * function call. Multiple signatures could be added. + * @param op opaque signing context. Must be successfully initialized with one of the + * rnp_op_sign_*_create functions. + * @param key handle of the private key. Private key should be capable for signing. + * @param sig pointer to opaque structure holding the signature information. May be NULL. + * You should not free it as it will be destroyed together with signing context. + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_sign_add_signature(rnp_op_sign_t op, + rnp_key_handle_t key, + rnp_op_sign_signature_t *sig); + +/** @brief Set hash algorithm used during signature calculation instead of default one, or one + * set by rnp_op_encrypt_set_hash/rnp_op_sign_set_hash + * @param sig opaque signature context, returned via rnp_op_sign_add_signature + * @param hash hash algorithm to be used + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_sign_signature_set_hash(rnp_op_sign_signature_t sig, + const char * hash); + +/** @brief Set signature creation time. By default current time is used or value set by + * rnp_op_encrypt_set_creation_time/rnp_op_sign_set_creation_time + * @param sig opaque signature context, returned via rnp_op_sign_add_signature + * @param create creation time in seconds since Jan, 1 1970 UTC + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_sign_signature_set_creation_time(rnp_op_sign_signature_t sig, + uint32_t create); + +/** @brief Set signature expiration time. By default is set to never expire or to value set by + * rnp_op_encrypt_set_expiration_time/rnp_op_sign_set_expiration_time + * @param sig opaque signature context, returned via rnp_op_sign_add_signature + * @param expire expiration time in seconds since the creation time. 0 value is used to mark + * signature as non-expiring (default value) + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_sign_signature_set_expiration_time(rnp_op_sign_signature_t sig, + uint32_t expires); + +/** @brief Set data compression parameters. Makes sense only for embedded signatures. + * @param op opaque signing context. Must be initialized with rnp_op_sign_create function + * @param compression compression algorithm (zlib, zip, bzip2) + * @param level compression level, 0-9. 0 disables compression. + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_sign_set_compression(rnp_op_sign_t op, + const char * compression, + int level); + +/** @brief Enabled or disable armored (textual) output. Doesn't make sense for cleartext sign. + * @param op opaque signing context. Must be initialized with rnp_op_sign_create or + * rnp_op_sign_detached_create function. + * @param armored true if armoring should be used (it is disabled by default) + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_sign_set_armor(rnp_op_sign_t op, bool armored); + +/** @brief Set hash algorithm used during signature calculation. This will set hash function + * for all signature. To change it for a single signature use + * rnp_op_sign_signature_set_hash function. + * @param op opaque signing context. Must be successfully initialized with one of the + * rnp_op_sign_*_create functions. + * @param hash hash algorithm to be used + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_sign_set_hash(rnp_op_sign_t op, const char *hash); + +/** @brief Set signature creation time. By default current time is used. + * @param op opaque signing context. Must be successfully initialized with one of the + * rnp_op_sign_*_create functions. + * @param create creation time in seconds since Jan, 1 1970 UTC. 32 bit unsigned integer + * datatype is used here instead of 64 bit (like modern timestamps do) because + * in OpenPGP messages times are stored as 32-bit unsigned integers. + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_sign_set_creation_time(rnp_op_sign_t op, uint32_t create); + +/** @brief Set signature expiration time. + * @param op opaque signing context. Must be successfully initialized with one of the + * rnp_op_sign_*_create functions. + * @param expire expiration time in seconds since the creation time. 0 value is used to mark + * signature as non-expiring (default value) + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_sign_set_expiration_time(rnp_op_sign_t op, uint32_t expire); + +/** @brief Set input's file name. Makes sense only for embedded signature. + * @param op opaque signing context. Must be initialized with rnp_op_sign_create function + * @param filename source data file name. Special value _CONSOLE may be used to mark message + * as 'for your eyes only', i.e. it should not be stored anywhere but only displayed + * to the receiver. Default is the empty string. + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_sign_set_file_name(rnp_op_sign_t op, const char *filename); + +/** @brief Set input's file modification date. Makes sense only for embedded signature. + * @param op opaque signing context. Must be initialized with rnp_op_sign_create function + * @param mtime modification time in seconds since Jan, 1 1970 UTC. 32 bit unsigned integer + * datatype is used here instead of 64 bit (like modern timestamps do) because + * in OpenPGP messages times are stored as 32-bit unsigned integers. + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_sign_set_file_mtime(rnp_op_sign_t op, uint32_t mtime); + +/** @brief Execute previously initialized signing operation. + * @param op opaque signing context. Must be successfully initialized with one of the + * rnp_op_sign_*_create functions. At least one signing key should be added. + * @return RNP_SUCCESS or error code if failed. On success output stream, passed in the create + * function call, will be populated with signed data + */ +RNP_API rnp_result_t rnp_op_sign_execute(rnp_op_sign_t op); + +/** @brief Free resources associated with signing operation. + * @param op opaque signing context. Must be successfully initialized with one of the + * rnp_op_sign_*_create functions. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_sign_destroy(rnp_op_sign_t op); + +/* Verification */ + +/** @brief Create verification operation context. This method should be used for embedded + * signatures, cleartext signed data and encrypted (and possibly signed) data. + * For the detached signature verification the function rnp_op_verify_detached_create() + * should be used. + * @param op pointer to opaque verification context + * @param ffi + * @param input stream with signed data. Could not be NULL. + * @param output stream to write results to. Could not be NULL, but may be null output stream + * if verified data should be discarded. + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_verify_create(rnp_op_verify_t *op, + rnp_ffi_t ffi, + rnp_input_t input, + rnp_output_t output); + +/** @brief Create verification operation context for detached signature. + * @param op pointer to opaque verification context + * @param ffi + * @param input stream with raw data. Could not be NULL. + * @param signature stream with detached signature data + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_verify_detached_create(rnp_op_verify_t *op, + rnp_ffi_t ffi, + rnp_input_t input, + rnp_input_t signature); + +/** + * @brief Set additional flags which control data verification/decryption process. + * + * @param op pointer to opaque verification context. + * @param flags verification flags. OR-ed combination of RNP_VERIFY_* values. + * Following flags are supported: + * RNP_VERIFY_IGNORE_SIGS_ON_DECRYPT - ignore invalid signatures for the encrypted + * and signed data. If this flag is set then rnp_op_verify_execute() call will + * succeed and output data even if all signatures are invalid or issued by the + * unknown key(s). + * RNP_VERIFY_REQUIRE_ALL_SIGS - require that all signatures (if any) must be + * valid for successful run of rnp_op_verify_execute(). + * RNP_VERIFY_ALLOW_HIDDEN_RECIPIENT - allow hidden recipient during the + * decryption. + * + * Note: all flags are set at once, if some flag is not present in the subsequent + * call then it will be unset. + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_verify_set_flags(rnp_op_verify_t op, uint32_t flags); + +/** @brief Execute previously initialized verification operation. + * @param op opaque verification context. Must be successfully initialized. + * @return RNP_SUCCESS if data was processed successfully and output may be used. By default + * this means at least one valid signature for the signed data, or successfully + * decrypted data if no signatures are present. + * This behaviour may be overriden via rnp_op_verify_set_flags() call. + * + * To check number of signatures and their verification status use functions + * rnp_op_verify_get_signature_count() and rnp_op_verify_get_signature_at(). + * To check data encryption status use function rnp_op_verify_get_protection_info(). + */ +RNP_API rnp_result_t rnp_op_verify_execute(rnp_op_verify_t op); + +/** @brief Get number of the signatures for verified data. + * @param op opaque verification context. Must be initialized and have execute() called on it. + * @param count result will be stored here on success. + * @return RNP_SUCCESS if call succeeded. + */ +RNP_API rnp_result_t rnp_op_verify_get_signature_count(rnp_op_verify_t op, size_t *count); + +/** @brief Get single signature information based on its index. + * @param op opaque verification context. Must be initialized and have execute() called on it. + * @param sig opaque signature context data will be stored here on success. + * @return RNP_SUCCESS if call succeeded. + */ +RNP_API rnp_result_t rnp_op_verify_get_signature_at(rnp_op_verify_t op, + size_t idx, + rnp_op_verify_signature_t *sig); + +/** @brief Get embedded in OpenPGP data file name and modification time. Makes sense only for + * embedded signature verification. + * @param op opaque verification context. Must be initialized and have execute() called on it. + * @param filename pointer to the filename. On success caller is responsible for freeing it + * via the rnp_buffer_destroy function call. May be NULL if this information + * is not needed. + * @param mtime file modification time will be stored here on success. May be NULL. + * @return RNP_SUCCESS if call succeeded. + */ +RNP_API rnp_result_t rnp_op_verify_get_file_info(rnp_op_verify_t op, + char ** filename, + uint32_t * mtime); + +/** + * @brief Get data protection (encryption) mode, used in processed message. + * + * @param op opaque verification context. Must be initialized and have execute() called on it. + * @param mode on success string with mode will be stored here. Caller is responsible for + * freeing it using the rnp_buffer_destroy() call. May be NULL if information is + * not needed. Currently defined values are as following: + * - none : message was not protected/encrypted + * - cfb : message was encrypted in CFB mode without the MDC + * - cfb-mdc : message was encrypted in CFB mode and protected with MDC + * - aead-ocb : message was encrypted in AEAD-OCB mode + * - aead-eax : message was encrypted in AEAD-EAX mode + * @param cipher symmetric cipher, used for data encryption. May be NULL if information is not + * needed. Must be freed by rnp_buffer_destroy() call. + * @param valid true if message integrity protection was used (i.e. MDC or AEAD), and it was + * validated successfully. Otherwise (even for raw cfb mode) will be false. May be + * NULL if information is not needed. + * @return RNP_SUCCESS if call succeeded, or error code otherwise. + */ +RNP_API rnp_result_t rnp_op_verify_get_protection_info(rnp_op_verify_t op, + char ** mode, + char ** cipher, + bool * valid); + +/** + * @brief Get number of public keys (recipients) to whom message was encrypted to. + * + * @param op opaque verification context. Must be initialized and have execute() called on it. + * @param count on success number of keys will be stored here. Cannot be NULL. + * @return RNP_SUCCESS if call succeeded, or error code otherwise. + */ +RNP_API rnp_result_t rnp_op_verify_get_recipient_count(rnp_op_verify_t op, size_t *count); + +/** + * @brief Get the recipient's handle, used to decrypt message. + * + * @param op opaque verification context. Must be initialized and have execute() called on it. + * @param recipient pointer to the opaque handle context. Cannot be NULL. If recipient's key + * was used to decrypt a message then handle will be stored here, otherwise + * it will be set to NULL. + * @return RNP_SUCCESS if call succeeded, or error code otherwise. + */ +RNP_API rnp_result_t rnp_op_verify_get_used_recipient(rnp_op_verify_t op, + rnp_recipient_handle_t *recipient); + +/** + * @brief Get the recipient's handle by index. + * + * @param op opaque verification context. Must be initialized and have execute() called on it. + * @param idx zero-based index in array. + * @param recipient pointer to the opaque handle context. Cannot be NULL. On success handle + * will be stored here. + * @return RNP_SUCCESS if call succeeded, or error code otherwise. + */ +RNP_API rnp_result_t rnp_op_verify_get_recipient_at(rnp_op_verify_t op, + size_t idx, + rnp_recipient_handle_t *recipient); + +/** + * @brief Get recipient's keyid. + * + * @param recipient recipient's handle, obtained via rnp_op_verify_get_used_recipient() or + * rnp_op_verify_get_recipient_at() function call. Cannot be NULL. + * @param keyid on success pointer to NULL-terminated string with hex-encoded keyid will be + * stored here. Cannot be NULL. Must be freed using the rnp_buffer_destroy(). + * @return RNP_SUCCESS if call succeeded, or error code otherwise. + */ +RNP_API rnp_result_t rnp_recipient_get_keyid(rnp_recipient_handle_t recipient, char **keyid); + +/** + * @brief Get recipient's key algorithm. + * + * @param recipient recipient's handle, obtained via rnp_op_verify_get_used_recipient() or + * rnp_op_verify_get_recipient_at() function call. Cannot be NULL. + * @param alg on success pointer to NULL-terminated string with algorithm will be stored here. + * Cannot be NULL. Must be freed using the rnp_buffer_destroy(). + * @return RNP_SUCCESS if call succeeded, or error code otherwise. + */ +RNP_API rnp_result_t rnp_recipient_get_alg(rnp_recipient_handle_t recipient, char **alg); + +/** + * @brief Get number of symenc entries (i.e. passwords), to which message was encrypted. + * + * @param op opaque verification context. Must be initialized and have execute() called on it. + * @param count on success number of keys will be stored here. Cannot be NULL. + * @return RNP_SUCCESS if call succeeded, or error code otherwise. + */ +RNP_API rnp_result_t rnp_op_verify_get_symenc_count(rnp_op_verify_t op, size_t *count); + +/** + * @brief Get the symenc handle, used to decrypt a message. + * + * @param op opaque verification context. Must be initialized and have execute() called on it. + * @param symenc pointer to the opaque symenc context. Cannot be NULL. If password was used to + * decrypt a message then handle will be stored here, otherwise it will be set to + * NULL. + * @return RNP_SUCCESS if call succeeded, or error code otherwise. + */ +RNP_API rnp_result_t rnp_op_verify_get_used_symenc(rnp_op_verify_t op, + rnp_symenc_handle_t *symenc); + +/** + * @brief Get the symenc handle by index. + * + * @param op opaque verification context. Must be initialized and have execute() called on it. + * @param idx zero-based index in array. + * @param symenc pointer to the opaque handle context. Cannot be NULL. On success handle + * will be stored here. + * @return RNP_SUCCESS if call succeeded, or error code otherwise. + */ +RNP_API rnp_result_t rnp_op_verify_get_symenc_at(rnp_op_verify_t op, + size_t idx, + rnp_symenc_handle_t *symenc); + +/** + * @brief Get the symmetric cipher, used to encrypt data encryption key. + * Note: if message is encrypted with only one passphrase and without public keys, then + * key, derived from password, may be used to encrypt the whole message. + * @param symenc opaque handle, cannot be NULL. + * @param cipher NULL-terminated string with cipher's name will be stored here. Cannot be NULL. + * Must be freed using the rnp_buffer_destroy(). + * @return RNP_SUCCESS if call succeeded, or error code otherwise. + */ +RNP_API rnp_result_t rnp_symenc_get_cipher(rnp_symenc_handle_t symenc, char **cipher); + +/** + * @brief Get AEAD algorithm if it was used to encrypt data encryption key. + * + * @param symenc opaque handle, cannot be NULL. + * @param alg NULL-terminated string with AEAD algorithm name will be stored here. If AEAD was + * not used then it will contain string 'None'. Must be freed using the + * rnp_buffer_destroy(). + * @return RNP_SUCCESS if call succeeded, or error code otherwise. + */ +RNP_API rnp_result_t rnp_symenc_get_aead_alg(rnp_symenc_handle_t symenc, char **alg); + +/** + * @brief Get hash algorithm, used to derive key from the passphrase. + * + * @param symenc opaque handle, cannot be NULL. + * @param alg NULL-terminated string with hash algorithm name will be stored here. Cannot be + * NULL. Must be freed using the rnp_buffer_destroy(). + * @return RNP_SUCCESS if call succeeded, or error code otherwise. + */ +RNP_API rnp_result_t rnp_symenc_get_hash_alg(rnp_symenc_handle_t symenc, char **alg); + +/** + * @brief Get string-to-key type, used to derive password. + * + * @param symenc opaque handle, cannot be NULL. + * @param type NULL-terminated string with s2k type will be stored here. Currently following + * types are available: 'Simple', 'Salted', 'Iterated and salted'. Please note that + * first two are considered weak and should not be used. Must be freed using the + * rnp_buffer_destroy(). + * @return RNP_SUCCESS if call succeeded, or error code otherwise. + */ +RNP_API rnp_result_t rnp_symenc_get_s2k_type(rnp_symenc_handle_t symenc, char **type); + +/** + * @brief Get number of iterations in iterated-and-salted S2K, if it was used. + * + * @param symenc opaque handle, cannot be NULL. + * @param iterations on success number of iterations will be stored here. Cannot be NULL. + * If non-iterated s2k was used then will be set to 0. + * @return RNP_SUCCESS if call succeeded, or error code otherwise. + */ +RNP_API rnp_result_t rnp_symenc_get_s2k_iterations(rnp_symenc_handle_t symenc, + uint32_t * iterations); + +/** @brief Free resources allocated in verification context. + * @param op opaque verification context. Must be initialized. + * @return RNP_SUCCESS if call succeeded. + */ +RNP_API rnp_result_t rnp_op_verify_destroy(rnp_op_verify_t op); + +/** @brief Get signature verification status. + * @param sig opaque signature context obtained via rnp_op_verify_get_signature_at call. + * @return signature verification status: + * RNP_SUCCESS : signature is valid + * RNP_ERROR_SIGNATURE_EXPIRED : signature is valid but expired + * RNP_ERROR_KEY_NOT_FOUND : public key to verify signature was not available + * RNP_ERROR_SIGNATURE_INVALID : data or signature was modified + * RNP_ERROR_SIGNATURE_UNKNOWN : signature has unknown format + */ +RNP_API rnp_result_t rnp_op_verify_signature_get_status(rnp_op_verify_signature_t sig); + +/** Get the signature handle from the verified signature. This would allow to query extended + * information on the signature. + * + * @param sig verified signature context, cannot be NULL. + * @param handle signature handle will be stored here on success. You must free it after use + * with the rnp_signature_handle_destroy() function. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_verify_signature_get_handle(rnp_op_verify_signature_t sig, + rnp_signature_handle_t * handle); + +/** @brief Get hash function used to calculate signature + * @param sig opaque signature context obtained via rnp_op_verify_get_signature_at call. + * @param hash pointer to string with hash algorithm name will be put here on success. + * Caller is responsible for freeing it with rnp_buffer_destroy + * @return RNP_SUCCESS or error code otherwise + */ +RNP_API rnp_result_t rnp_op_verify_signature_get_hash(rnp_op_verify_signature_t sig, + char ** hash); + +/** @brief Get key used for signing + * @param sig opaque signature context obtained via rnp_op_verify_get_signature_at call. + * @param key pointer to opaque key handle structure. + * @return RNP_SUCCESS or error code otherwise + */ +RNP_API rnp_result_t rnp_op_verify_signature_get_key(rnp_op_verify_signature_t sig, + rnp_key_handle_t * key); + +/** @brief Get signature creation and expiration times + * @param sig opaque signature context obtained via rnp_op_verify_get_signature_at call. + * @param create signature creation time will be put here. It is number of seconds since + * Jan, 1 1970 UTC. May be NULL if called doesn't need this data. + * @param expires signature expiration time will be stored here. It is number of seconds since + * the creation time or 0 if signature never expires. May be NULL. + * @return RNP_SUCCESS or error code otherwise + */ +RNP_API rnp_result_t rnp_op_verify_signature_get_times(rnp_op_verify_signature_t sig, + uint32_t * create, + uint32_t * expires); + +/** + * @brief Free buffer allocated by a function in this header. + * + * @param ptr previously allocated buffer. May be NULL, then nothing is done. + */ +RNP_API void rnp_buffer_destroy(void *ptr); + +/** + * @brief Securely clear buffer contents. + * + * @param ptr pointer to the buffer contents, may be NULL. + * @param size number of bytes in buffer. + */ +RNP_API void rnp_buffer_clear(void *ptr, size_t size); + +/** + * @brief Initialize input struct to read from a path + * + * @param input pointer to the input opaque structure + * @param path path of the file to read from + * @return RNP_SUCCESS if operation succeeded and input struct is ready to read, or error code + * otherwise + */ +RNP_API rnp_result_t rnp_input_from_path(rnp_input_t *input, const char *path); + +/** + * @brief Initialize input struct to read from the stdin + * + * @param input pointer to the input opaque structure + * @return RNP_SUCCESS if operation succeeded and input struct is ready to read, or error code + * otherwise + */ +RNP_API rnp_result_t rnp_input_from_stdin(rnp_input_t *input); + +/** + * @brief Initialize input struct to read from memory + * + * @param input pointer to the input opaque structure + * @param buf memory buffer. Could not be NULL. + * @param buf_len number of bytes available to read from buf + * @param do_copy if true then the buffer will be copied internally. If + * false then the application should ensure that the buffer + * is valid and not modified during the lifetime of this object. + * @return RNP_SUCCESS if operation succeeded or error code otherwise + */ +RNP_API rnp_result_t rnp_input_from_memory(rnp_input_t * input, + const uint8_t buf[], + size_t buf_len, + bool do_copy); + +/** + * @brief Initialize input struct to read via callbacks + * + * @param input pointer to the input opaque structure + * @param reader callback used for reading + * @param closer callback used to close the stream + * @param app_ctx context to pass as parameter to reader and closer + * @return RNP_SUCCESS if operation succeeded or error code otherwise + */ +RNP_API rnp_result_t rnp_input_from_callback(rnp_input_t * input, + rnp_input_reader_t *reader, + rnp_input_closer_t *closer, + void * app_ctx); + +/** + * @brief Close previously opened input and free all corresponding resources + * + * @param input previously opened input structure + * @return RNP_SUCCESS if operation succeeded or error code otherwise + */ +RNP_API rnp_result_t rnp_input_destroy(rnp_input_t input); + +/** + * @brief Initialize output structure to write to a path. If path is a file + * that already exists then it will be overwritten. + * + * @param output pointer to the opaque output structure. + * @param path path to the file. + * @return RNP_SUCCESS if file was opened successfully and ready for writing or error code + * otherwise. + */ +RNP_API rnp_result_t rnp_output_to_path(rnp_output_t *output, const char *path); + +/** + * @brief Initialize structure to write to a file. + * Note: it doesn't allow output to directory like rnp_output_to_path does, but + * allows additional options to be specified. + * When RNP_OUTPUT_FILE_RANDOM flag is included then you may want to call + * rnp_output_finish() to make sure that final rename succeeded. + * @param output pointer to the opaque output structure. After use you must free it using the + * rnp_output_destroy() function. + * @param path path to the file. + * @param flags additional flags, see RNP_OUTPUT_* flags. + * @return RNP_SUCCESS if file was opened successfully and ready for writing or error code + * otherwise. + */ +RNP_API rnp_result_t rnp_output_to_file(rnp_output_t *output, + const char * path, + uint32_t flags); + +/** + * @brief Initialize structure to write to the stdout. + * + * @param output pointer to the opaque output structure. After use you must free it using the + * rnp_output_destroy() function. + * @return RNP_SUCCESS if output was initialized successfully or error code otherwise. + */ +RNP_API rnp_result_t rnp_output_to_stdout(rnp_output_t *output); + +/** + * @brief Initialize output structure to write to the memory. + * + * @param output pointer to the opaque output structure. + * @param max_alloc maximum amount of memory to allocate. 0 value means unlimited. + * @return RNP_SUCCESS if operation succeeded or error code otherwise. + */ +RNP_API rnp_result_t rnp_output_to_memory(rnp_output_t *output, size_t max_alloc); + +/** + * @brief Output data to armored stream (and then output to other destination), allowing + * streamed output. + * + * @param base initialized output structure, where armored data will be written to. + * @param output pointer to the opaque output structure. You must free it later using the + * rnp_output_destroy() function. + * @param type type of the armored stream. See rnp_enarmor() for possible values. + * @return RNP_SUCCESS if operation succeeded or error code otherwise. + */ +RNP_API rnp_result_t rnp_output_to_armor(rnp_output_t base, + rnp_output_t *output, + const char * type); + +/** + * @brief Get the pointer to the buffer of output, initialized by rnp_output_to_memory + * + * @param output output structure, initialized by rnp_output_to_memory and populated with data + * @param buf pointer to the buffer will be stored here, could not be NULL + * @param len number of bytes in buffer will be stored here, could not be NULL + * @param do_copy if true then a newly-allocated buffer will be returned and the application + * will be responsible for freeing it with rnp_buffer_destroy. If false + * then the internal buffer is returned and the application must not modify the + * buffer or access it after this object is destroyed. + * @return RNP_SUCCESS if operation succeeded or error code otherwise. + */ +RNP_API rnp_result_t rnp_output_memory_get_buf(rnp_output_t output, + uint8_t ** buf, + size_t * len, + bool do_copy); + +/** + * @brief Initialize output structure to write to callbacks. + * + * @param output pointer to the opaque output structure. + * @param writer write callback. + * @param closer close callback. + * @param app_ctx context parameter which will be passed to writer and closer. + * @return RNP_SUCCESS if operation succeeded or error code otherwise. + */ +RNP_API rnp_result_t rnp_output_to_callback(rnp_output_t * output, + rnp_output_writer_t *writer, + rnp_output_closer_t *closer, + void * app_ctx); + +/** + * @brief Initialize output structure which will discard all data + * + * @param output pointer to the opaque output structure. + * @return RNP_SUCCESS if operation succeeded or error code otherwise. + */ +RNP_API rnp_result_t rnp_output_to_null(rnp_output_t *output); + +/** + * @brief write some data to the output structure. + * + * @param output pointer to the initialized opaque output structure. + * @param data pointer to data which should be written. + * @param size number of bytes to write. + * @param written on success will contain the number of bytes written. May be NULL. + * @return rnp_result_t RNP_SUCCESS if operation succeeded or error code otherwise. + */ +RNP_API rnp_result_t rnp_output_write(rnp_output_t output, + const void * data, + size_t size, + size_t * written); + +/** + * @brief Finish writing to the output. + * Note: on most output types you'll need just to call rnp_output_destroy(). + * However, for file output with RNP_OUTPUT_FILE_RANDOM flag, you need to call this + * to make sure that rename from random to required name succeeded. + * + * @param output pointer to the opaque output structure. + * @return RNP_SUCCESS if operation succeeded or error code otherwise. + */ +RNP_API rnp_result_t rnp_output_finish(rnp_output_t output); + +/** + * @brief Close previously opened output and free all associated data. + * + * @param output previously opened output structure. + * @return RNP_SUCCESS if operation succeeds or error code otherwise. + */ +RNP_API rnp_result_t rnp_output_destroy(rnp_output_t output); + +/* encrypt */ +RNP_API rnp_result_t rnp_op_encrypt_create(rnp_op_encrypt_t *op, + rnp_ffi_t ffi, + rnp_input_t input, + rnp_output_t output); + +/** + * @brief Add recipient's public key to encrypting context. + * + * @param op opaque encrypting context. Must be allocated and initialized. + * @param key public key, used for encryption. Key is not checked for + * validity or expiration. + * @return RNP_SUCCESS if operation succeeds or error code otherwise. + */ +RNP_API rnp_result_t rnp_op_encrypt_add_recipient(rnp_op_encrypt_t op, rnp_key_handle_t key); + +/** + * @brief Add signature to encrypting context, so data will be encrypted and signed. + * + * @param op opaque encrypting context. Must be allocated and initialized. + * @param key private key, used for signing. + * @param sig pointer to the newly added signature will be stored here. May be NULL. + * @return RNP_SUCCESS if signature was added or error code otherwise. + */ +RNP_API rnp_result_t rnp_op_encrypt_add_signature(rnp_op_encrypt_t op, + rnp_key_handle_t key, + rnp_op_sign_signature_t *sig); + +/** + * @brief Set hash function used for signature calculation. Makes sense if encrypt-and-sign is + * used. To set hash function for each signature separately use rnp_op_sign_signature_set_hash. + * + * @param op opaque encrypting context. Must be allocated and initialized. + * @param hash hash algorithm to be used as NULL-terminated string. Following values are + * supported: "MD5", "SHA1", "RIPEMD160", "SHA256", "SHA384", "SHA512", "SHA224", "SM3". + * However, some signature types may require specific hash function or hash function + * output length. + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_encrypt_set_hash(rnp_op_encrypt_t op, const char *hash); + +/** + * @brief Set signature creation time. By default current time is used. + * + * @param op opaque encrypting context. Must be allocated and initialized. + * @param create creation time in seconds since Jan, 1 1970 UTC + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_encrypt_set_creation_time(rnp_op_encrypt_t op, uint32_t create); + +/** + * @brief Set signature expiration time. By default signatures do not expire. + * + * @param op opaque encrypting context. Must be allocated and initialized. + * @param expire expiration time in seconds since the creation time. 0 value is used to mark + * signature as non-expiring + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_encrypt_set_expiration_time(rnp_op_encrypt_t op, uint32_t expire); + +/** + * @brief Add password which is used to encrypt data. Multiple passwords can be added. + * + * @param op opaque encrypting context. Must be allocated and initialized. + * @param password NULL-terminated password string, or NULL if password should be requested + * via password provider. + * @param s2k_hash hash algorithm, used in key-from-password derivation. Pass NULL for default + * value. See rnp_op_encrypt_set_hash for possible values. + * @param iterations number of iterations, used in key derivation function. + * According to RFC 4880, chapter 3.7.1.3, only 256 distinct values within the range + * [1024..0x3e00000] can be encoded. Thus, the number will be increased to the closest + * encodable value. In case it exceeds the maximum encodable value, it will be decreased + * to the maximum encodable value. + * If 0 is passed, an optimal number (greater or equal to 1024) will be calculated based + * on performance measurement. + * @param s2k_cipher symmetric cipher, used for key encryption. Pass NULL for default value. + * See rnp_op_encrypt_set_cipher for possible values. + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_encrypt_add_password(rnp_op_encrypt_t op, + const char * password, + const char * s2k_hash, + size_t iterations, + const char * s2k_cipher); + +/** + * @brief Set whether output should be ASCII-armored, or binary. + * + * @param op opaque encrypting context. Must be allocated and initialized. + * @param armored true for armored, false for binary + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_encrypt_set_armor(rnp_op_encrypt_t op, bool armored); + +/** + * @brief set the encryption algorithm + * + * @param op opaque encrypting context. Must be allocated and initialized. + * @param cipher NULL-terminated string with cipher's name. One of the "IDEA", "TRIPLEDES", + * "CAST5", "BLOWFISH", "AES128", "AES192", "AES256", "TWOFISH", "CAMELLIA128", + * "CAMELLIA192", "CAMELLIA256", "SM4". + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_encrypt_set_cipher(rnp_op_encrypt_t op, const char *cipher); + +/** + * @brief set AEAD mode algorithm or disable AEAD usage. By default it is disabled. + * + * @param op opaque encrypting context. Must be allocated and initialized. + * @param alg NULL-terminated AEAD algorithm name. Use "None" to disable AEAD, or "EAX", "OCB" + * to use the corresponding algorithm. + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_encrypt_set_aead(rnp_op_encrypt_t op, const char *alg); + +/** + * @brief set chunk length for AEAD mode via number of chunk size bits (refer to the OpenPGP + * specification for the details). + * + * @param op opaque encrypting context. Must be allocated and initialized. + * @param bits number of bits, currently it must be from 0 to 16. + * @return RNP_SUCCESS or error code if failed + */ +RNP_API rnp_result_t rnp_op_encrypt_set_aead_bits(rnp_op_encrypt_t op, int bits); + +/** + * @brief set the compression algorithm and level for the inner raw data + * + * @param op opaque encrypted context. Must be allocated and initialized + * @param compression compression algorithm name. Can be one of the "Uncompressed", "ZIP", + * "ZLIB", "BZip2". Please note that ZIP is not PkWare's ZIP file format but just a + * DEFLATE compressed data (RFC 1951). + * @param level 0 - 9, where 0 is no compression and 9 is maximum compression level. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_op_encrypt_set_compression(rnp_op_encrypt_t op, + const char * compression, + int level); + +/** + * @brief Set additional encryption flags. + * + * @param op opaque encrypting context. Must be allocated and initialized. + * @param flags encryption flags. ORed combination of RNP_ENCRYPT_* values. + * Following flags are supported: + * RNP_ENCRYPT_NOWRAP - do not wrap the data in a literal data packet. This + * would allow to encrypt already signed data. + * + * @return RNP_SUCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_op_encrypt_set_flags(rnp_op_encrypt_t op, uint32_t flags); + +/** + * @brief set the internally stored file name for the data being encrypted + * + * @param op opaque encrypted context. Must be allocated and initialized + * @param filename file name as NULL-terminated string. May be empty string. Value "_CONSOLE" + * may have specific processing (see RFC 4880 for the details), depending on implementation. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_op_encrypt_set_file_name(rnp_op_encrypt_t op, const char *filename); + +/** + * @brief set the internally stored file modification date for the data being encrypted + * + * @param op opaque encrypted context. Must be allocated and initialized + * @param mtime time in seconds since Jan, 1 1970. 32 bit unsigned integer datatype is used + * here instead of 64 bit (like modern timestamps do) because in OpenPGP messages + * times are stored as 32-bit unsigned integers. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_op_encrypt_set_file_mtime(rnp_op_encrypt_t op, uint32_t mtime); + +RNP_API rnp_result_t rnp_op_encrypt_execute(rnp_op_encrypt_t op); +RNP_API rnp_result_t rnp_op_encrypt_destroy(rnp_op_encrypt_t op); + +/** + * @brief Decrypt encrypted data in input and write it to the output on success. + * If data is additionally signed then signatures are ignored. + * For more control over the decryption process see functions rnp_op_verify_create() and + * rnp_op_verify_execute(), which allows to verify signatures as well as decrypt data + * and retrieve encryption-related information. + * + * @param ffi initialized FFI object. Cannot be NULL. + * @param input source with encrypted data. Cannot be NULL. + * @param output on success decrypted data will be written here. Cannot be NULL. + * @return RNP_SUCCESS if data was successfully decrypted and written to the output, or any + * other value on error. + */ +RNP_API rnp_result_t rnp_decrypt(rnp_ffi_t ffi, rnp_input_t input, rnp_output_t output); + +/** retrieve the raw data for a public key + * + * This will always be PGP packets and will never include ASCII armor. + * + * @param handle the key handle + * @param buf + * @param buf_len + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_get_public_key_data(rnp_key_handle_t handle, + uint8_t ** buf, + size_t * buf_len); + +/** retrieve the raw data for a secret key + * + * If this is a G10 key, this will be the s-expr data. Otherwise, it will + * be PGP packets. + * + * Note that this result will never include ASCII armor. + * + * @param handle the key handle + * @param buf + * @param buf_len + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_get_secret_key_data(rnp_key_handle_t handle, + uint8_t ** buf, + size_t * buf_len); + +/** output key information to JSON structure and serialize it to the string + * + * @param handle the key handle, could not be NULL + * @param flags controls which key data is printed, see RNP_JSON_* constants. + * @param result pointer to the resulting string will be stored here on success. You must + * release it afterwards via rnp_buffer_destroy() function call. + * @return RNP_SUCCESS or error code if failed. + */ +RNP_API rnp_result_t rnp_key_to_json(rnp_key_handle_t handle, uint32_t flags, char **result); + +/** create an identifier iterator + * + * @param ffi + * @param it pointer that will be set to the created iterator + * @param identifier_type the type of identifier ("userid", "keyid", "grip", "fingerprint") + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_identifier_iterator_create(rnp_ffi_t ffi, + rnp_identifier_iterator_t *it, + const char *identifier_type); + +/** retrieve the next item from an iterator + * + * @param it the iterator + * @param identifier pointer that will be set to the identifier value. + * Must not be NULL. This buffer should not be freed by the application. + * It will be modified by subsequent calls to this function, and its + * life is tied to the iterator. + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_identifier_iterator_next(rnp_identifier_iterator_t it, + const char ** identifier); + +/** destroy an identifier iterator + * + * @param it the iterator object + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_identifier_iterator_destroy(rnp_identifier_iterator_t it); + +/** Read from input and write to output + * + * @param input stream to read data from + * @param output stream to write data to + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_output_pipe(rnp_input_t input, rnp_output_t output); + +/** Set line length for armored output + * + * @param output stream to configure + * @param llen line length in characters [16..76] + * @return RNP_SUCCESS on success, or any other value on error + */ +RNP_API rnp_result_t rnp_output_armor_set_line_length(rnp_output_t output, size_t llen); + +/** + * @brief Return cryptographic backend library name. + * + * @return Backend name string. Currently supported + * backends are "Botan" and "OpenSSL". + */ +RNP_API const char *rnp_backend_string(); + +/** + * @brief Return cryptographic backend library version. + * + * @return Version string. + */ +RNP_API const char *rnp_backend_version(); + +#if defined(__cplusplus) +} + +#endif + +/** + * Feature strings. + */ +#ifndef RNP_FEATURE_SYMM_ALG + +#define RNP_FEATURE_SYMM_ALG "symmetric algorithm" +#define RNP_FEATURE_AEAD_ALG "aead algorithm" +#define RNP_FEATURE_PROT_MODE "protection mode" +#define RNP_FEATURE_PK_ALG "public key algorithm" +#define RNP_FEATURE_HASH_ALG "hash algorithm" +#define RNP_FEATURE_COMP_ALG "compression algorithm" +#define RNP_FEATURE_CURVE "elliptic curve" + +#endif + +/** Algorithm Strings + */ +#ifndef RNP_ALGNAME_PLAINTEXT + +#define RNP_ALGNAME_PLAINTEXT "PLAINTEXT" +#define RNP_ALGNAME_RSA "RSA" +#define RNP_ALGNAME_ELGAMAL "ELGAMAL" +#define RNP_ALGNAME_DSA "DSA" +#define RNP_ALGNAME_ECDH "ECDH" +#define RNP_ALGNAME_ECDSA "ECDSA" +#define RNP_ALGNAME_EDDSA "EDDSA" +#define RNP_ALGNAME_IDEA "IDEA" +#define RNP_ALGNAME_TRIPLEDES "TRIPLEDES" +#define RNP_ALGNAME_CAST5 "CAST5" +#define RNP_ALGNAME_BLOWFISH "BLOWFISH" +#define RNP_ALGNAME_TWOFISH "TWOFISH" +#define RNP_ALGNAME_AES_128 "AES128" +#define RNP_ALGNAME_AES_192 "AES192" +#define RNP_ALGNAME_AES_256 "AES256" +#define RNP_ALGNAME_CAMELLIA_128 "CAMELLIA128" +#define RNP_ALGNAME_CAMELLIA_192 "CAMELLIA192" +#define RNP_ALGNAME_CAMELLIA_256 "CAMELLIA256" +#define RNP_ALGNAME_SM2 "SM2" +#define RNP_ALGNAME_SM3 "SM3" +#define RNP_ALGNAME_SM4 "SM4" +#define RNP_ALGNAME_MD5 "MD5" +#define RNP_ALGNAME_SHA1 "SHA1" +#define RNP_ALGNAME_SHA256 "SHA256" +#define RNP_ALGNAME_SHA384 "SHA384" +#define RNP_ALGNAME_SHA512 "SHA512" +#define RNP_ALGNAME_SHA224 "SHA224" +#define RNP_ALGNAME_SHA3_256 "SHA3-256" +#define RNP_ALGNAME_SHA3_512 "SHA3-512" +#define RNP_ALGNAME_RIPEMD160 "RIPEMD160" +#define RNP_ALGNAME_CRC24 "CRC24" + +/* SHA1 is not considered secured anymore and SHOULD NOT be used to create messages (as per + * Appendix C of RFC 4880-bis-02). SHA2 MUST be implemented. + * Let's preempt this by specifying SHA256 - gpg interoperates just fine with SHA256 - agc, + * 20090522 + */ +#define DEFAULT_HASH_ALG RNP_ALGNAME_SHA256 + +/* Default symmetric algorithm */ +#define DEFAULT_SYMM_ALG RNP_ALGNAME_AES_256 + +/* Keystore format: GPG, KBX (pub), G10 (sec), GPG21 ( KBX for pub, G10 for sec) */ +#define RNP_KEYSTORE_GPG ("GPG") +#define RNP_KEYSTORE_KBX ("KBX") +#define RNP_KEYSTORE_G10 ("G10") +#define RNP_KEYSTORE_GPG21 ("GPG21") + +#endif diff --git a/comm/third_party/rnp/include/rnp/rnp_def.h b/comm/third_party/rnp/include/rnp/rnp_def.h new file mode 100644 index 0000000000..5b099d98dd --- /dev/null +++ b/comm/third_party/rnp/include/rnp/rnp_def.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017, [Ribose Inc](https://www.ribose.com). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef RNP_DEF_H_ +#define RNP_DEF_H_ + +#include <stdint.h> +#include "rnp_err.h" + +/* rnp_result_t is the type used for return codes from the APIs. */ +typedef uint32_t rnp_result_t; + +#endif diff --git a/comm/third_party/rnp/include/rnp/rnp_err.h b/comm/third_party/rnp/include/rnp/rnp_err.h new file mode 100644 index 0000000000..f4ff179e5f --- /dev/null +++ b/comm/third_party/rnp/include/rnp/rnp_err.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2017-2019, [Ribose Inc](https://www.ribose.com). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef RNP_ERR_H_ +#define RNP_ERR_H_ + +/* + * Error code definitions + */ +enum { + + RNP_SUCCESS = 0x00000000, + + /* Common error codes */ + RNP_ERROR_GENERIC = 0x10000000, + RNP_ERROR_BAD_FORMAT, + RNP_ERROR_BAD_PARAMETERS, + RNP_ERROR_NOT_IMPLEMENTED, + RNP_ERROR_NOT_SUPPORTED, + RNP_ERROR_OUT_OF_MEMORY, + RNP_ERROR_SHORT_BUFFER, + RNP_ERROR_NULL_POINTER, + + /* Storage */ + RNP_ERROR_ACCESS = 0x11000000, + RNP_ERROR_READ, + RNP_ERROR_WRITE, + + /* Crypto */ + RNP_ERROR_BAD_STATE = 0x12000000, + RNP_ERROR_MAC_INVALID, + RNP_ERROR_SIGNATURE_INVALID, + RNP_ERROR_KEY_GENERATION, + RNP_ERROR_BAD_PASSWORD, + RNP_ERROR_KEY_NOT_FOUND, + RNP_ERROR_NO_SUITABLE_KEY, + RNP_ERROR_DECRYPT_FAILED, + RNP_ERROR_RNG, + RNP_ERROR_SIGNING_FAILED, + RNP_ERROR_NO_SIGNATURES_FOUND, + + RNP_ERROR_SIGNATURE_EXPIRED, + RNP_ERROR_VERIFICATION_FAILED, + RNP_ERROR_SIGNATURE_UNKNOWN, + + /* Parsing */ + RNP_ERROR_NOT_ENOUGH_DATA = 0x13000000, + RNP_ERROR_UNKNOWN_TAG, + RNP_ERROR_PACKET_NOT_CONSUMED, + RNP_ERROR_NO_USERID, + RNP_ERROR_EOF + +}; + +#endif |