/*- * Copyright (c) 2009 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Alistair Crooks (agc@NetBSD.org) * * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. */ /* * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) * All rights reserved. * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted * their moral rights under the UK Copyright Design and Patents Act 1988 to * be recorded as the authors of this copyright work. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. * * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * limitations under the License. */ /** \file * packet related headers. */ #ifndef PACKET_H_ #define PACKET_H_ #include #ifdef HAVE_OPENSSL_BN_H #include #endif #include "types.h" #include "errors.h" /* structure to keep track of printing state variables */ typedef struct pgp_printstate_t { unsigned unarmoured; unsigned skipping; int indent; } pgp_printstate_t; /** General-use structure for variable-length data */ typedef struct { size_t len; uint8_t *contents; uint8_t mmapped; /* contents need an munmap(2) */ } pgp_data_t; /************************************/ /* 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 /** 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 /* PTag Content Tags */ /***************************/ /** Package Tags (aka Content Tags) and signature subpacket types. * This enumerates all rfc-defined packet tag values and the * signature subpacket type values that we understand. * * \see RFC4880 4.3 * \see RFC4880 5.2.3.1 */ typedef enum { PGP_PTAG_CT_RESERVED = 0, /* Reserved - a packet tag must * not have this value */ PGP_PTAG_CT_PK_SESSION_KEY = 1, /* Public-Key Encrypted Session * Key Packet */ PGP_PTAG_CT_SIGNATURE = 2, /* Signature Packet */ PGP_PTAG_CT_SK_SESSION_KEY = 3, /* Symmetric-Key Encrypted Session * Key Packet */ PGP_PTAG_CT_1_PASS_SIG = 4, /* One-Pass Signature * Packet */ PGP_PTAG_CT_SECRET_KEY = 5, /* Secret Key Packet */ PGP_PTAG_CT_PUBLIC_KEY = 6, /* Public Key Packet */ PGP_PTAG_CT_SECRET_SUBKEY = 7, /* Secret Subkey Packet */ PGP_PTAG_CT_COMPRESSED = 8, /* Compressed Data Packet */ PGP_PTAG_CT_SE_DATA = 9,/* Symmetrically Encrypted Data Packet */ PGP_PTAG_CT_MARKER = 10,/* Marker Packet */ PGP_PTAG_CT_LITDATA = 11, /* Literal Data Packet */ PGP_PTAG_CT_TRUST = 12, /* Trust Packet */ PGP_PTAG_CT_USER_ID = 13, /* User ID Packet */ PGP_PTAG_CT_PUBLIC_SUBKEY = 14, /* Public Subkey Packet */ PGP_PTAG_CT_RESERVED2 = 15, /* reserved */ PGP_PTAG_CT_RESERVED3 = 16, /* reserved */ PGP_PTAG_CT_USER_ATTR = 17, /* User Attribute Packet */ PGP_PTAG_CT_SE_IP_DATA = 18, /* Sym. Encrypted and Integrity * Protected Data Packet */ PGP_PTAG_CT_MDC = 19, /* Modification Detection Code Packet */ PGP_PARSER_PTAG = 0x100,/* Internal Use: The packet is the "Packet * Tag" itself - used when callback sends * back the PTag. */ PGP_PTAG_RAW_SS = 0x101,/* Internal Use: content is raw sig subtag */ PGP_PTAG_SS_ALL = 0x102,/* Internal Use: select all subtags */ PGP_PARSER_PACKET_END = 0x103, /* signature subpackets (0x200-2ff) (type+0x200) */ /* only those we can parse are listed here */ PGP_PTAG_SIG_SUBPKT_BASE = 0x200, /* Base for signature * subpacket types - All * signature type values * are relative to this * value. */ PGP_PTAG_SS_CREATION_TIME = 0x200 + 2, /* signature creation time */ PGP_PTAG_SS_EXPIRATION_TIME = 0x200 + 3, /* signature * expiration time */ PGP_PTAG_SS_EXPORT_CERT = 0x200 + 4, /* exportable certification */ PGP_PTAG_SS_TRUST = 0x200 + 5, /* trust signature */ PGP_PTAG_SS_REGEXP = 0x200 + 6, /* regular expression */ PGP_PTAG_SS_REVOCABLE = 0x200 + 7, /* revocable */ PGP_PTAG_SS_KEY_EXPIRY = 0x200 + 9, /* key expiration * time */ PGP_PTAG_SS_RESERVED = 0x200 + 10, /* reserved */ PGP_PTAG_SS_PREFERRED_SKA = 0x200 + 11, /* preferred symmetric * algs */ PGP_PTAG_SS_REVOCATION_KEY = 0x200 + 12, /* revocation key */ PGP_PTAG_SS_ISSUER_KEY_ID = 0x200 + 16, /* issuer key ID */ PGP_PTAG_SS_NOTATION_DATA = 0x200 + 20, /* notation data */ PGP_PTAG_SS_PREFERRED_HASH = 0x200 + 21, /* preferred hash * algs */ PGP_PTAG_SS_PREF_COMPRESS = 0x200 + 22, /* preferred * compression * algorithms */ PGP_PTAG_SS_KEYSERV_PREFS = 0x200 + 23, /* key server * preferences */ PGP_PTAG_SS_PREF_KEYSERV = 0x200 + 24, /* Preferred Key * Server */ PGP_PTAG_SS_PRIMARY_USER_ID = 0x200 + 25, /* primary User ID */ PGP_PTAG_SS_POLICY_URI = 0x200 + 26, /* Policy URI */ PGP_PTAG_SS_KEY_FLAGS = 0x200 + 27, /* key flags */ PGP_PTAG_SS_SIGNERS_USER_ID = 0x200 + 28, /* Signer's User ID */ PGP_PTAG_SS_REVOCATION_REASON = 0x200 + 29, /* reason for * revocation */ PGP_PTAG_SS_FEATURES = 0x200 + 30, /* features */ PGP_PTAG_SS_SIGNATURE_TARGET = 0x200 + 31, /* signature target */ PGP_PTAG_SS_EMBEDDED_SIGNATURE = 0x200 + 32, /* embedded signature */ PGP_PTAG_SS_USERDEFINED00 = 0x200 + 100, /* internal or * user-defined */ PGP_PTAG_SS_USERDEFINED01 = 0x200 + 101, PGP_PTAG_SS_USERDEFINED02 = 0x200 + 102, PGP_PTAG_SS_USERDEFINED03 = 0x200 + 103, PGP_PTAG_SS_USERDEFINED04 = 0x200 + 104, PGP_PTAG_SS_USERDEFINED05 = 0x200 + 105, PGP_PTAG_SS_USERDEFINED06 = 0x200 + 106, PGP_PTAG_SS_USERDEFINED07 = 0x200 + 107, PGP_PTAG_SS_USERDEFINED08 = 0x200 + 108, PGP_PTAG_SS_USERDEFINED09 = 0x200 + 109, PGP_PTAG_SS_USERDEFINED10 = 0x200 + 110, /* pseudo content types */ PGP_PTAG_CT_LITDATA_HEADER = 0x300, PGP_PTAG_CT_LITDATA_BODY = 0x300 + 1, PGP_PTAG_CT_SIGNATURE_HEADER = 0x300 + 2, PGP_PTAG_CT_SIGNATURE_FOOTER = 0x300 + 3, PGP_PTAG_CT_ARMOUR_HEADER = 0x300 + 4, PGP_PTAG_CT_ARMOUR_TRAILER = 0x300 + 5, PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER = 0x300 + 6, PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY = 0x300 + 7, PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER = 0x300 + 8, PGP_PTAG_CT_UNARMOURED_TEXT = 0x300 + 9, PGP_PTAG_CT_ENCRYPTED_SECRET_KEY = 0x300 + 10, /* In this case the * algorithm specific * fields will not be * initialised */ PGP_PTAG_CT_SE_DATA_HEADER = 0x300 + 11, PGP_PTAG_CT_SE_DATA_BODY = 0x300 + 12, PGP_PTAG_CT_SE_IP_DATA_HEADER = 0x300 + 13, PGP_PTAG_CT_SE_IP_DATA_BODY = 0x300 + 14, PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY = 0x300 + 15, /* commands to the callback */ PGP_GET_PASSPHRASE = 0x400, PGP_GET_SECKEY = 0x400 + 1, /* Errors */ PGP_PARSER_ERROR = 0x500, /* Internal Use: Parser Error */ PGP_PARSER_ERRCODE = 0x500 + 1 /* Internal Use: Parser Error * with errcode returned */ } pgp_content_enum; enum { PGP_REVOCATION_NO_REASON = 0, PGP_REVOCATION_SUPERSEDED = 1, PGP_REVOCATION_COMPROMISED = 2, PGP_REVOCATION_RETIRED = 3, PGP_REVOCATION_NO_LONGER_VALID = 0x20 }; /** Structure to hold one error code */ typedef struct { pgp_errcode_t errcode; } pgp_parser_errcode_t; /** Structure to hold one packet tag. * \see RFC4880 4.2 */ typedef struct { unsigned new_format; /* Whether this packet tag is new * (1) or old format (0) */ unsigned type; /* content_tag value - See * #pgp_content_enum for meanings */ pgp_ptag_of_lt_t length_type; /* Length type (#pgp_ptag_of_lt_t) * - only if this packet tag is old * format. Set to 0 if new format. */ unsigned length; /* The length of the packet. This value * is set when we read and compute the length * information, not at the same moment we * create the packet tag structure. Only * defined if #readc is set. *//* XXX: Ben, is this correct? */ unsigned position; /* The position (within the * current reader) of the packet */ unsigned size; /* number of bits */ } pgp_ptag_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 { 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_RESERVED_ELLIPTIC_CURVE = 18, /* Reserved for Elliptic * Curve */ PGP_PKA_RESERVED_ECDSA = 19, /* Reserved for ECDSA */ PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN = 20, /* Deprecated. */ PGP_PKA_RESERVED_DH = 21, /* Reserved for Diffie-Hellman * (X9.42, as defined for * IETF-S/MIME) */ 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; /** Structure to hold one DSA public key params. * * \see RFC4880 5.5.2 */ typedef struct { BIGNUM *p; /* DSA prime p */ BIGNUM *q; /* DSA group order q */ BIGNUM *g; /* DSA group generator g */ BIGNUM *y; /* DSA public key value y (= g^x mod p * with x being the secret) */ } pgp_dsa_pubkey_t; /** Structure to hold an RSA public key. * * \see RFC4880 5.5.2 */ typedef struct { BIGNUM *n; /* RSA public modulus n */ BIGNUM *e; /* RSA public encryption exponent e */ } pgp_rsa_pubkey_t; /** Structure to hold an ElGamal public key params. * * \see RFC4880 5.5.2 */ typedef struct { BIGNUM *p; /* ElGamal prime p */ BIGNUM *g; /* ElGamal group generator g */ BIGNUM *y; /* ElGamal public key value y (= g^x mod p * with x being the secret) */ } pgp_elgamal_pubkey_t; /** Version. * OpenPGP has two different protocol versions: version 3 and version 4. * * \see RFC4880 5.2 */ typedef enum { PGP_V2 = 2, /* Version 2 (essentially the same as v3) */ PGP_V3 = 3, /* Version 3 */ PGP_V4 = 4 /* Version 4 */ } pgp_version_t; /** Structure to hold a pgp public key */ typedef struct { pgp_version_t version;/* version of the key (v3, v4...) */ time_t birthtime; time_t duration; /* validity period of the key in days since * creation. A value of 0 has a special meaning * indicating this key does not expire. Only used with * v3 keys. */ unsigned days_valid; /* v4 duration */ pgp_pubkey_alg_t alg; /* Public Key Algorithm type */ union { pgp_dsa_pubkey_t dsa; /* A DSA public key */ pgp_rsa_pubkey_t rsa; /* An RSA public key */ pgp_elgamal_pubkey_t elgamal; /* An ElGamal public key */ } key; /* Public Key Parameters */ } pgp_pubkey_t; /** Structure to hold data for one RSA secret key */ typedef struct { BIGNUM *d; BIGNUM *p; BIGNUM *q; BIGNUM *u; } pgp_rsa_seckey_t; /** pgp_dsa_seckey_t */ typedef struct { BIGNUM *x; } pgp_dsa_seckey_t; /** pgp_elgamal_seckey_t */ typedef struct { BIGNUM *x; } pgp_elgamal_seckey_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 { PGP_S2KS_SIMPLE = 0, PGP_S2KS_SALTED = 1, PGP_S2KS_ITERATED_AND_SALTED = 3 } pgp_s2k_specifier_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 = 100, /* Camellia with 128-bit key (CAMELLIA) */ PGP_SA_CAMELLIA_192 = 101, /* Camellia with 192-bit key */ PGP_SA_CAMELLIA_256 = 102 /* Camellia with 256-bit key */ } pgp_symm_alg_t; #define PGP_SA_DEFAULT_CIPHER PGP_SA_CAST5 /** 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 { PGP_HASH_UNKNOWN = -1, /* used to indicate errors */ PGP_HASH_MD5 = 1, /* MD5 */ PGP_HASH_SHA1 = 2, /* SHA-1 */ PGP_HASH_RIPEMD = 3, /* RIPEMD160 */ PGP_HASH_SHA256 = 8, /* SHA256 */ PGP_HASH_SHA384 = 9, /* SHA384 */ PGP_HASH_SHA512 = 10, /* SHA512 */ PGP_HASH_SHA224 = 11 /* SHA224 */ } pgp_hash_alg_t; #define PGP_DEFAULT_HASH_ALGORITHM PGP_HASH_SHA256 void pgp_calc_mdc_hash(const uint8_t *, const size_t, const uint8_t *, const unsigned, uint8_t *); unsigned pgp_is_hash_alg_supported(const pgp_hash_alg_t *); /* 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 /* Max hash size */ #define PGP_MAX_HASH_SIZE 64 /** pgp_seckey_t */ typedef struct pgp_seckey_t { pgp_pubkey_t pubkey; /* public key */ pgp_s2k_usage_t s2k_usage; pgp_s2k_specifier_t s2k_specifier; pgp_symm_alg_t alg; /* symmetric alg */ pgp_hash_alg_t hash_alg; /* hash algorithm */ uint8_t salt[PGP_SALT_SIZE]; unsigned octetc; uint8_t iv[PGP_MAX_BLOCK_SIZE]; union { pgp_rsa_seckey_t rsa; pgp_dsa_seckey_t dsa; pgp_elgamal_seckey_t elgamal; } key; unsigned checksum; uint8_t *checkhash; } pgp_seckey_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 { 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; /** Struct to hold params of an RSA signature */ typedef struct pgp_rsa_sig_t { BIGNUM *sig; /* the signature value (m^d % n) */ } pgp_rsa_sig_t; /** Struct to hold params of a DSA signature */ typedef struct pgp_dsa_sig_t { BIGNUM *r; /* DSA value r */ BIGNUM *s; /* DSA value s */ } pgp_dsa_sig_t; /** pgp_elgamal_signature_t */ typedef struct pgp_elgamal_sig_t { BIGNUM *r; BIGNUM *s; } pgp_elgamal_sig_t; #define PGP_KEY_ID_SIZE 8 #define PGP_FINGERPRINT_SIZE 20 /** Struct to hold a signature packet. * * \see RFC4880 5.2.2 * \see RFC4880 5.2.3 */ typedef struct pgp_sig_info_t { pgp_version_t version;/* signature version number */ pgp_sig_type_t type; /* signature type value */ time_t birthtime; /* creation time of the signature */ time_t duration; /* number of seconds it's valid for */ uint8_t signer_id[PGP_KEY_ID_SIZE]; /* Eight-octet key ID * of signer */ pgp_pubkey_alg_t key_alg; /* public key algorithm number */ pgp_hash_alg_t hash_alg; /* hashing algorithm number */ union { pgp_rsa_sig_t rsa; /* An RSA Signature */ pgp_dsa_sig_t dsa; /* A DSA Signature */ pgp_elgamal_sig_t elgamal; /* deprecated */ pgp_data_t unknown; /* private or experimental */ } sig; /* signature params */ size_t v4_hashlen; uint8_t *v4_hashed; unsigned birthtime_set:1; unsigned signer_id_set:1; unsigned duration_set:1; } pgp_sig_info_t; /** Struct used when parsing a signature */ typedef struct pgp_sig_t { pgp_sig_info_t info; /* The signature information */ /* The following fields are only used while parsing the signature */ uint8_t hash2[2]; /* high 2 bytes of hashed value */ size_t v4_hashstart; /* only valid if accumulate is set */ pgp_hash_t *hash; /* the hash filled in for the data so far */ } pgp_sig_t; /** The raw bytes of a signature subpacket */ typedef struct pgp_ss_raw_t { pgp_content_enum tag; size_t length; uint8_t *raw; } pgp_ss_raw_t; /** Signature Subpacket : Trust Level */ typedef struct pgp_ss_trust_t { uint8_t level; /* Trust Level */ uint8_t amount; /* Amount */ } pgp_ss_trust_t; /** Signature Subpacket : Notation Data */ typedef struct pgp_ss_notation_t { pgp_data_t flags; pgp_data_t name; pgp_data_t value; } pgp_ss_notation_t; /** Signature Subpacket : Signature Target */ typedef struct pgp_ss_sig_target_t { pgp_pubkey_alg_t pka_alg; pgp_hash_alg_t hash_alg; pgp_data_t hash; } pgp_ss_sig_target_t; /** pgp_subpacket_t */ typedef struct pgp_subpacket_t { pgp_content_enum tag; size_t length; uint8_t *raw; } pgp_subpacket_t; /** Types of Compression */ typedef enum { PGP_C_NONE = 0, PGP_C_ZIP = 1, PGP_C_ZLIB = 2, PGP_C_BZIP2 = 3 } pgp_compression_type_t; /** pgp_one_pass_sig_t */ typedef struct { uint8_t version; pgp_sig_type_t sig_type; pgp_hash_alg_t hash_alg; pgp_pubkey_alg_t key_alg; uint8_t keyid[PGP_KEY_ID_SIZE]; unsigned nested; } pgp_one_pass_sig_t; /** Signature Subpacket : Revocation Key */ typedef struct { uint8_t class; uint8_t algid; uint8_t fingerprint[PGP_FINGERPRINT_SIZE]; } pgp_ss_revocation_key_t; /** Signature Subpacket : Revocation Reason */ typedef struct { uint8_t code; char *reason; } pgp_ss_revocation_t; /** litdata_type_t */ typedef enum { PGP_LDT_BINARY = 'b', PGP_LDT_TEXT = 't', PGP_LDT_UTF8 = 'u', PGP_LDT_LOCAL = 'l', PGP_LDT_LOCAL2 = '1' } pgp_litdata_enum; /** pgp_litdata_header_t */ typedef struct { pgp_litdata_enum format; char filename[256]; time_t mtime; } pgp_litdata_header_t; /** pgp_litdata_body_t */ typedef struct { unsigned length; uint8_t *data; void *mem; /* pgp_memory_t pointer */ } pgp_litdata_body_t; /** pgp_header_var_t */ typedef struct { char *key; char *value; } pgp_header_var_t; /** pgp_headers_t */ typedef struct { pgp_header_var_t *headers; unsigned headerc; } pgp_headers_t; /** pgp_armour_header_t */ typedef struct { const char *type; pgp_headers_t headers; } pgp_armour_header_t; /** pgp_fixed_body_t */ typedef struct pgp_fixed_body_t { unsigned length; uint8_t data[8192]; /* \todo fix hard-coded value? */ } pgp_fixed_body_t; /** pgp_dyn_body_t */ typedef struct pgp_dyn_body_t { unsigned length; uint8_t *data; } pgp_dyn_body_t; enum { PGP_SE_IP_DATA_VERSION = 1, PGP_PKSK_V3 = 3 }; /** pgp_pk_sesskey_params_rsa_t */ typedef struct { BIGNUM *encrypted_m; BIGNUM *m; } pgp_pk_sesskey_params_rsa_t; /** pgp_pk_sesskey_params_elgamal_t */ typedef struct { BIGNUM *g_to_k; BIGNUM *encrypted_m; } pgp_pk_sesskey_params_elgamal_t; /** pgp_pk_sesskey_params_t */ typedef union { pgp_pk_sesskey_params_rsa_t rsa; pgp_pk_sesskey_params_elgamal_t elgamal; } pgp_pk_sesskey_params_t; /** pgp_pk_sesskey_t */ typedef struct { unsigned version; uint8_t key_id[PGP_KEY_ID_SIZE]; pgp_pubkey_alg_t alg; pgp_pk_sesskey_params_t params; pgp_symm_alg_t symm_alg; uint8_t key[PGP_MAX_KEY_SIZE]; uint16_t checksum; } pgp_pk_sesskey_t; /** pgp_seckey_passphrase_t */ typedef struct { const pgp_seckey_t *seckey; char **passphrase; /* point somewhere that gets filled * in to work around constness of * content */ } pgp_seckey_passphrase_t; /** pgp_get_seckey_t */ typedef struct { const pgp_seckey_t **seckey; const pgp_pk_sesskey_t *pk_sesskey; } pgp_get_seckey_t; /** pgp_parser_union_content_t */ typedef union { const char *error; pgp_parser_errcode_t errcode; pgp_ptag_t ptag; pgp_pubkey_t pubkey; pgp_data_t trust; uint8_t *userid; pgp_data_t userattr; pgp_sig_t sig; pgp_ss_raw_t ss_raw; pgp_ss_trust_t ss_trust; unsigned ss_revocable; time_t ss_time; uint8_t ss_issuer[PGP_KEY_ID_SIZE]; pgp_ss_notation_t ss_notation; pgp_subpacket_t packet; pgp_compression_type_t compressed; pgp_one_pass_sig_t one_pass_sig; pgp_data_t ss_skapref; pgp_data_t ss_hashpref; pgp_data_t ss_zpref; pgp_data_t ss_key_flags; pgp_data_t ss_key_server_prefs; unsigned ss_primary_userid; char *ss_regexp; char *ss_policy; char *ss_keyserv; pgp_ss_revocation_key_t ss_revocation_key; pgp_data_t ss_userdef; pgp_data_t ss_unknown; pgp_litdata_header_t litdata_header; pgp_litdata_body_t litdata_body; pgp_dyn_body_t mdc; pgp_data_t ss_features; pgp_ss_sig_target_t ss_sig_target; pgp_data_t ss_embedded_sig; pgp_ss_revocation_t ss_revocation; pgp_seckey_t seckey; uint8_t *ss_signer; pgp_armour_header_t armour_header; const char *armour_trailer; pgp_headers_t cleartext_head; pgp_fixed_body_t cleartext_body; struct pgp_hash_t *cleartext_trailer; pgp_dyn_body_t unarmoured_text; pgp_pk_sesskey_t pk_sesskey; pgp_seckey_passphrase_t skey_passphrase; unsigned se_ip_data_header; pgp_dyn_body_t se_ip_data_body; pgp_fixed_body_t se_data_body; pgp_get_seckey_t get_seckey; } pgp_contents_t; /** pgp_packet_t */ struct pgp_packet_t { pgp_content_enum tag; /* type of contents */ uint8_t critical; /* for sig subpackets */ pgp_contents_t u; /* union for contents */ }; /** pgp_fingerprint_t */ typedef struct { uint8_t fingerprint[PGP_FINGERPRINT_SIZE]; unsigned length; pgp_hash_alg_t hashtype; } pgp_fingerprint_t; int pgp_keyid(uint8_t *, const size_t, const pgp_pubkey_t *, pgp_hash_alg_t); int pgp_fingerprint(pgp_fingerprint_t *, const pgp_pubkey_t *, pgp_hash_alg_t); void pgp_finish(void); void pgp_pubkey_free(pgp_pubkey_t *); void pgp_userid_free(uint8_t **); void pgp_data_free(pgp_data_t *); void pgp_sig_free(pgp_sig_t *); void pgp_ss_notation_free(pgp_ss_notation_t *); void pgp_ss_revocation_free(pgp_ss_revocation_t *); void pgp_ss_sig_target_free(pgp_ss_sig_target_t *); void pgp_subpacket_free(pgp_subpacket_t *); void pgp_parser_content_free(pgp_packet_t *); void pgp_seckey_free(pgp_seckey_t *); void pgp_pk_sesskey_free(pgp_pk_sesskey_t *); int pgp_print_packet(pgp_printstate_t *, const pgp_packet_t *); #define DYNARRAY(type, arr) \ unsigned arr##c; unsigned arr##vsize; type *arr##s #define EXPAND_ARRAY(str, arr) do { \ if (str->arr##c == str->arr##vsize) { \ void *__newarr; \ char *__newarrc; \ unsigned __newsize; \ __newsize = (str->arr##vsize * 2) + 10; \ if ((__newarrc = __newarr = realloc(str->arr##s, \ __newsize * sizeof(*str->arr##s))) == NULL) { \ (void) fprintf(stderr, "EXPAND_ARRAY - bad realloc\n"); \ } else { \ (void) memset(&__newarrc[str->arr##vsize * sizeof(*str->arr##s)], \ 0x0, (__newsize - str->arr##vsize) * sizeof(*str->arr##s)); \ str->arr##s = __newarr; \ str->arr##vsize = __newsize; \ } \ } \ } while(/*CONSTCOND*/0) /** pgp_keydata_key_t */ typedef union { pgp_pubkey_t pubkey; pgp_seckey_t seckey; } pgp_keydata_key_t; /* sigpacket_t */ typedef struct { uint8_t **userid; pgp_subpacket_t *packet; } sigpacket_t; /* user revocation info */ typedef struct pgp_revoke_t { uint32_t uid; /* index in uid array */ uint8_t code; /* revocation code */ char *reason; /* c'mon, spill the beans */ } pgp_revoke_t; /** signature subpackets */ typedef struct pgp_subsig_t { uint32_t uid; /* index in userid array in key */ pgp_sig_t sig; /* trust signature */ uint8_t trustlevel; /* level of trust */ uint8_t trustamount; /* amount of trust */ } pgp_subsig_t; /* describes a user's key */ struct pgp_key_t { DYNARRAY(uint8_t *, uid); /* array of user ids */ DYNARRAY(pgp_subpacket_t, packet); /* array of raw subpackets */ DYNARRAY(pgp_subsig_t, subsig); /* array of signature subkeys */ DYNARRAY(pgp_revoke_t, revoke); /* array of signature revocations */ pgp_content_enum type; /* type of key */ pgp_keydata_key_t key; /* pubkey/seckey data */ pgp_pubkey_t sigkey; /* signature key */ uint8_t sigid[PGP_KEY_ID_SIZE]; pgp_fingerprint_t sigfingerprint; /* pgp signature fingerprint */ pgp_pubkey_t enckey; /* encryption key */ uint8_t encid[PGP_KEY_ID_SIZE]; pgp_fingerprint_t encfingerprint; /* pgp encryption id fingerprint */ uint32_t uid0; /* primary uid index in uids array */ uint8_t revoked; /* key has been revoked */ pgp_revoke_t revocation; /* revocation reason */ }; #define MDC_PKT_TAG 0xd3 #endif /* PACKET_H_ */