gpg: New card function agent_scd_keypairinfo.
[gnupg.git] / g10 / packet.h
index 9eb16cf..41dd1a9 100644 (file)
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 #ifndef G10_PACKET_H
 #define G10_PACKET_H
 
-#include "types.h"
+#include "../common/types.h"
 #include "../common/iobuf.h"
 #include "../common/strlist.h"
 #include "dek.h"
 #include "filter.h"
 #include "../common/openpgpdefs.h"
 #include "../common/userids.h"
+#include "../common/util.h"
 
 #define DEBUG_PARSE_PACKET 1
 
 
-/* Constants to allocate static MPI arrays. */
-#define PUBKEY_MAX_NPKEY  5
-#define PUBKEY_MAX_NSKEY  7
-#define PUBKEY_MAX_NSIG   2
-#define PUBKEY_MAX_NENC   2
+/* Constants to allocate static MPI arrays.  */
+#define PUBKEY_MAX_NPKEY  OPENPGP_MAX_NPKEY
+#define PUBKEY_MAX_NSKEY  OPENPGP_MAX_NSKEY
+#define PUBKEY_MAX_NSIG   OPENPGP_MAX_NSIG
+#define PUBKEY_MAX_NENC   OPENPGP_MAX_NENC
 
 /* Usage flags */
 #define PUBKEY_USAGE_SIG     GCRY_PK_USAGE_SIGN  /* Good for signatures. */
@@ -71,7 +72,8 @@ typedef enum {
     PREFTYPE_NONE = 0,
     PREFTYPE_SYM = 1,
     PREFTYPE_HASH = 2,
-    PREFTYPE_ZIP = 3
+    PREFTYPE_ZIP = 3,
+    PREFTYPE_AEAD = 4
 } preftype_t;
 
 typedef struct {
@@ -79,49 +81,109 @@ typedef struct {
     byte value;
 } prefitem_t;
 
+/* A string-to-key specifier as defined in RFC 4880, Section 3.7.  */
 typedef struct
 {
   int  mode;      /* Must be an integer due to the GNU modes 1001 et al.  */
   byte hash_algo;
   byte salt[8];
+  /* The *coded* (i.e., the serialized version) iteration count.  */
   u32  count;
 } STRING2KEY;
 
+/* A symmetric-key encrypted session key packet as defined in RFC
+   4880, Section 5.3.  All fields are serialized.  */
 typedef struct {
-    byte version;
-    byte cipher_algo;   /* cipher algorithm used */
-    STRING2KEY s2k;
-    byte seskeylen;   /* keylength in byte or 0 for no seskey */
-    byte seskey[1];
+  /* We support version 4 (rfc4880) and 5 (rfc4880bis).  */
+  byte version;
+  /* The cipher algorithm used to encrypt the session key.  Note that
+   * this may be different from the algorithm that is used to encrypt
+   * bulk data.  */
+  byte cipher_algo;
+  /* The AEAD algorithm or 0 for CFB encryption.  */
+  byte aead_algo;
+  /* The string-to-key specifier.  */
+  STRING2KEY s2k;
+  /* The length of SESKEY in bytes or 0 if this packet does not
+     encrypt a session key.  (In the latter case, the results of the
+     S2K function on the password is the session key. See RFC 4880,
+     Section 5.3.)  */
+  byte seskeylen;
+  /* The session key as encrypted by the S2K specifier.  For AEAD this
+   * includes the nonce and the authentication tag.  */
+  byte seskey[1];
 } PKT_symkey_enc;
 
+/* A public-key encrypted session key packet as defined in RFC 4880,
+   Section 5.1.  All fields are serialized.  */
 typedef struct {
-    u32     keyid[2];      /* 64 bit keyid */
-    byte    version;
-    byte    pubkey_algo;    /* algorithm used for public key scheme */
-    byte    throw_keyid;
-    gcry_mpi_t     data[PUBKEY_MAX_NENC];
+  /* The 64-bit keyid.  */
+  u32     keyid[2];
+  /* The packet's version.  Currently, only version 3 is defined.  */
+  byte    version;
+  /* The algorithm used for the public key encryption scheme.  */
+  byte    pubkey_algo;
+  /* Whether to hide the key id.  This value is not directly
+     serialized.  */
+  byte    throw_keyid;
+  /* The session key.  */
+  gcry_mpi_t     data[PUBKEY_MAX_NENC];
 } PKT_pubkey_enc;
 
 
+/* An object to build a list of public-key encrypted session key.  */
+struct pubkey_enc_list
+{
+  struct pubkey_enc_list *next;
+  u32 keyid[2];
+  int pubkey_algo;
+  int result;
+  gcry_mpi_t data[PUBKEY_MAX_NENC];
+};
+
+
+/* A one-pass signature packet as defined in RFC 4880, Section
+   5.4.  All fields are serialized.  */
 typedef struct {
-    u32     keyid[2];      /* 64 bit keyid */
-    byte    sig_class;     /* sig classification */
+    u32     keyid[2];      /* The 64-bit keyid */
+    /* The signature's classification (RFC 4880, Section 5.2.1).  */
+    byte    sig_class;
     byte    digest_algo;    /* algorithm used for digest */
     byte    pubkey_algo;    /* algorithm used for public key scheme */
-    byte    last;          /* a stupid flag */
+    /* A message can be signed by multiple keys.  In this case, there
+       are n one-pass signature packets before the message to sign and
+       n signatures packets after the message.  It is conceivable that
+       someone wants to not only sign the message, but all of the
+       signatures.  Now we need to distinguish between signing the
+       message and signing the message plus the surrounding
+       signatures.  This is the point of this flag.  If set, it means:
+       I sign all of the data starting at the next packet.  */
+    byte    last;
 } PKT_onepass_sig;
 
 
+/* A v4 OpenPGP signature has a hashed and unhashed area containing
+   co-called signature subpackets (RFC 4880, Section 5.2.3).  These
+   areas are described by this data structure.  Use enum_sig_subpkt to
+   parse this area.  */
 typedef struct {
     size_t size;  /* allocated */
-    size_t len;   /* used */
-    byte data[1];
+    size_t len;   /* used (serialized) */
+    byte data[1]; /* the serialized subpackes (serialized) */
 } subpktarea_t;
 
+/* The in-memory representation of a designated revoker signature
+   subpacket (RFC 4880, Section 5.2.3.15).  */
 struct revocation_key {
+  /* A bit field.  0x80 must be set.  0x40 means this information is
+     sensitive (and should not be uploaded to a keyserver by
+     default).  */
   byte class;
+  /* The public-key algorithm ID.  */
   byte algid;
+  /* The length of the fingerprint.  */
+  byte fprlen;
+  /* The fingerprint of the authorized key.  */
   byte fpr[MAX_FINGERPRINT_LEN];
 };
 
@@ -139,7 +201,11 @@ typedef struct
 } pka_info_t;
 
 
-/* Object to keep information pertaining to a signature. */
+/* A signature packet (RFC 4880, Section 5.2).  Only a subset of these
+   fields are directly serialized (these are marked as such); the rest
+   are read from the subpackets, which are not synthesized when
+   serializing this data structure (i.e., when using build_packet()).
+   Instead, the subpackets must be created by hand.  */
 typedef struct
 {
   struct
@@ -156,24 +222,43 @@ typedef struct
     unsigned expired:1;
     unsigned pka_tried:1;   /* Set if we tried to retrieve the PKA record. */
   } flags;
-  u32     keyid[2];      /* 64 bit keyid */
-  u32     timestamp;     /* Signature made (seconds since Epoch). */
+  /* The key that allegedly generated this signature.  (Directly
+     serialized in v3 sigs; for v4 sigs, this must be explicitly added
+     as an issuer subpacket (5.2.3.5.)  */
+  u32     keyid[2];
+  /* When the signature was made (seconds since the Epoch).  (Directly
+     serialized in v3 sigs; for v4 sigs, this must be explicitly added
+     as a signature creation time subpacket (5.2.3.4).)  */
+  u32     timestamp;
   u32     expiredate;     /* Expires at this date or 0 if not at all. */
+  /* The serialization format used / to use.  If 0, then defaults to
+     version 3.  (Serialized.)  */
   byte    version;
-  byte    sig_class;     /* Sig classification, append for MD calculation. */
-  byte    pubkey_algo;    /* Algorithm used for public key scheme */
-                          /* (PUBKEY_ALGO_xxx) */
-  byte    digest_algo;    /* Algorithm used for digest (DIGEST_ALGO_xxxx). */
+  /* The signature type. (See RFC 4880, Section 5.2.1.)  */
+  byte    sig_class;
+  /* Algorithm used for public key scheme (e.g., PUBKEY_ALGO_RSA).
+     (Serialized.)  */
+  byte    pubkey_algo;
+  /* Algorithm used for digest (e.g., DIGEST_ALGO_SHA1).
+     (Serialized.)  */
+  byte    digest_algo;
   byte    trust_depth;
   byte    trust_value;
   const byte *trust_regexp;
   struct revocation_key *revkey;
   int numrevkeys;
+  int help_counter;          /* Used internally bu some functions.  */
   pka_info_t *pka_info;      /* Malloced PKA data or NULL if not
                                 available.  See also flags.pka_tried. */
+  char *signers_uid;         /* Malloced value of the SIGNERS_UID
+                              * subpacket or NULL.  This string has
+                              * already been sanitized.  */
   subpktarea_t *hashed;      /* All subpackets with hashed data (v4 only). */
   subpktarea_t *unhashed;    /* Ditto for unhashed data. */
-  byte digest_start[2];      /* First 2 bytes of the digest. */
+  /* First 2 bytes of the digest.  (Serialized.  Note: this is not
+     automatically filled in when serializing a signature!)  */
+  byte digest_start[2];
+  /* The signature.  (Serialized.)  */
   gcry_mpi_t  data[PUBKEY_MAX_NSIG];
   /* The message digest and its length (in bytes).  Note the maximum
      digest length is 512 bits (64 bytes).  If DIGEST_LEN is 0, then
@@ -192,37 +277,52 @@ struct user_attribute {
 };
 
 
-/* (See also keybox-search-desc.h) */
-struct gpg_pkt_user_id_s
+/* A user id (RFC 4880, Section 5.11) or a user attribute packet (RFC
+   4880, Section 5.12).  Only a subset of these fields are directly
+   serialized (these are marked as such); the rest are read from the
+   self-signatures in merge_keys_and_selfsig()).  */
+typedef struct
 {
   int ref;              /* reference counter */
-  int len;             /* length of the name */
+  /* The length of NAME.  */
+  int len;
   struct user_attribute *attribs;
   int numattribs;
-  byte *attrib_data;    /* if this is not NULL, the packet is an attribute */
+  /* If this is not NULL, the packet is a user attribute rather than a
+     user id (See RFC 4880 5.12).  (Serialized.)  */
+  byte *attrib_data;
+  /* The length of ATTRIB_DATA.  */
   unsigned long attrib_len;
   byte *namehash;
   int help_key_usage;
   u32 help_key_expire;
   int help_full_count;
   int help_marginal_count;
-  int is_primary;       /* 2 if set via the primary flag, 1 if calculated */
-  int is_revoked;
-  int is_expired;
   u32 expiredate;       /* expires at this date or 0 if not at all */
   prefitem_t *prefs;    /* list of preferences (may be NULL)*/
   u32 created;          /* according to the self-signature */
+  u32 keyupdate;        /* From the ring trust packet.  */
+  char *updateurl;      /* NULL or the URL of the last update origin.  */
+  byte keyorg;          /* From the ring trust packet.  */
   byte selfsigversion;
   struct
   {
-    /* TODO: Move more flags here */
     unsigned int mdc:1;
+    unsigned int aead:1;
     unsigned int ks_modify:1;
     unsigned int compacted:1;
+    unsigned int primary:2; /* 2 if set via the primary flag, 1 if calculated */
+    unsigned int revoked:1;
+    unsigned int expired:1;
   } flags;
+
+  char *mbox;   /* NULL or the result of mailbox_from_userid.  */
+
+  /* The text contained in the user id packet, which is normally the
+   * name and email address of the key holder (See RFC 4880 5.11).
+   * (Serialized.). For convenience an extra Nul is always appended.  */
   char name[1];
-};
-typedef struct gpg_pkt_user_id_s PKT_user_id;
+} PKT_user_id;
 
 
 
@@ -254,6 +354,14 @@ struct seckey_info
 
 
 /****************
+ * The in-memory representation of a public key (RFC 4880, Section
+ * 5.5).  Note: this structure contains significantly more information
+ * than is contained in an OpenPGP public key packet.  This
+ * information is derived from the self-signed signatures (by
+ * merge_keys_and_selfsig()) and is ignored when serializing the
+ * packet.  The fields that are actually written out when serializing
+ * this packet are marked as accordingly.
+ *
  * We assume that secret keys have the same number of parameters as
  * the public key and that the public parameters are the first items
  * in the PKEY array.  Thus NPKEY is always less than NSKEY and it is
@@ -268,23 +376,36 @@ struct seckey_info
  */
 typedef struct
 {
-  u32     timestamp;       /* key made */
+  /* When the key was created.  (Serialized.)  */
+  u32     timestamp;
   u32     expiredate;     /* expires at this date or 0 if not at all */
   u32     max_expiredate; /* must not expire past this date */
   struct revoke_info revoked;
-  byte    hdrbytes;        /* number of header bytes */
+  /* An OpenPGP packet consists of a header and a body.  This is the
+     size of the header.  If this is 0, an appropriate size is
+     automatically chosen based on the size of the body.
+     (Serialized.)  */
+  byte    hdrbytes;
+  /* The serialization format.  If 0, the default version (4) is used
+     when serializing.  (Serialized.)  */
   byte    version;
   byte    selfsigversion; /* highest version of all of the self-sigs */
-  byte    pubkey_algo;    /* algorithm used for public key scheme */
+  /* The public key algorithm.  (Serialized.)  */
+  byte    pubkey_algo;
   byte    pubkey_usage;   /* for now only used to pass it to getkey() */
   byte    req_usage;      /* hack to pass a request to getkey() */
   u32     has_expired;    /* set to the expiration date if expired */
-  u32     main_keyid[2];  /* keyid of the primary key */
-  u32     keyid[2];        /* calculated by keyid_from_pk() */
+  /* keyid of the primary key.  Never access this value directly.
+     Instead, use pk_main_keyid().  */
+  u32     main_keyid[2];
+  /* keyid of this key.  Never access this value directly!  Instead,
+     use pk_keyid().  */
+  u32     keyid[2];
   prefitem_t *prefs;      /* list of preferences (may be NULL) */
   struct
   {
     unsigned int mdc:1;           /* MDC feature set.  */
+    unsigned int aead:1;          /* AEAD feature set.  */
     unsigned int disabled_valid:1;/* The next flag is valid.  */
     unsigned int disabled:1;      /* The key has been disabled.  */
     unsigned int primary:1;       /* This is a primary key.  */
@@ -298,6 +419,7 @@ typedef struct
     unsigned int dont_cache:1;    /* Do not cache this key.  */
     unsigned int backsig:2;       /* 0=none, 1=bad, 2=good.  */
     unsigned int serialno_valid:1;/* SERIALNO below is valid.  */
+    unsigned int exact:1;         /* Found via exact (!) search.  */
   } flags;
   PKT_user_id *user_id;   /* If != NULL: found by that uid. */
   struct revocation_key *revkey;
@@ -305,13 +427,20 @@ typedef struct
   u32     trust_timestamp;
   byte    trust_depth;
   byte    trust_value;
+  byte    keyorg;         /* From the ring trust packet.  */
+  u32     keyupdate;      /* From the ring trust packet.  */
+  char    *updateurl;     /* NULL or the URL of the last update origin.  */
   const byte *trust_regexp;
   char    *serialno;      /* Malloced hex string or NULL if it is
                              likely not on a card.  See also
                              flags.serialno_valid.  */
-  struct seckey_info *seckey_info;  /* If not NULL this malloced
-                                       structure describes a secret
-                                       key.  */
+  /* If not NULL this malloced structure describes a secret key.
+     (Serialized.)  */
+  struct seckey_info *seckey_info;
+  /* The public key.  Contains pubkey_get_npkey (pubkey_algo) +
+     pubkey_get_nskey (pubkey_algo) MPIs.  (If pubkey_get_npkey
+     returns 0, then the algorithm is not understood and the PKEY
+     contains a single opaque MPI.)  (Serialized.)  */
   gcry_mpi_t  pkey[PUBKEY_MAX_NSKEY]; /* Right, NSKEY elements.  */
 } PKT_public_key;
 
@@ -319,7 +448,7 @@ typedef struct
    there is no disable value cached, fill one in. */
 #define pk_is_disabled(a)                                       \
   (((a)->flags.disabled_valid)?                                 \
-   ((a)->flags.disabled):(cache_disabled_value((a))))
+   ((a)->flags.disabled):(cache_disabled_value(ctrl,(a))))
 
 
 typedef struct {
@@ -327,40 +456,100 @@ typedef struct {
     char data[1];
 } PKT_comment;
 
+/* A compression packet (RFC 4880, Section 5.6).  */
 typedef struct {
-    u32  len;            /* reserved */
-    byte  new_ctb;
-    byte  algorithm;
-    iobuf_t buf;         /* IOBUF reference */
+  /* Not used.  */
+  u32 len;
+  /* Whether the serialized version of the packet used / should use
+     the new format.  */
+  byte  new_ctb;
+  /* The compression algorithm.  */
+  byte  algorithm;
+  /* An iobuf holding the data to be decompressed.  (This is not used
+     for compression!)  */
+  iobuf_t buf;
 } PKT_compressed;
 
+/* A symmetrically encrypted data packet (RFC 4880, Section 5.7) or a
+   symmetrically encrypted integrity protected data packet (Section
+   5.13) */
 typedef struct {
-    u32  len;            /* Remaining length of encrypted data. */
-    int  extralen;        /* This is (blocksize+2).  Used by build_packet. */
-    byte new_ctb;        /* uses a new CTB */
-    byte is_partial;      /* partial length encoded */
-    byte mdc_method;     /* > 0: integrity protected encrypted data packet */
-    iobuf_t buf;         /* IOBUF reference */
+  /* Remaining length of encrypted data. */
+  u32  len;
+  /* When encrypting in CFB mode, the first block size bytes of data
+   * are random data and the following 2 bytes are copies of the last
+   * two bytes of the random data (RFC 4880, Section 5.7).  This
+   * provides a simple check that the key is correct.  EXTRALEN is the
+   * size of this extra data or, in AEAD mode, the length of the
+   * headers and the tags.  This is used by build_packet when writing
+   * out the packet's header. */
+  int  extralen;
+  /* Whether the serialized version of the packet used / should use
+     the new format.  */
+  byte new_ctb;
+  /* Whether the packet has an indeterminate length (old format) or
+     was encoded using partial body length headers (new format).
+     Note: this is ignored when encrypting.  */
+  byte is_partial;
+  /* If 0, MDC is disabled.  Otherwise, the MDC method that was used
+     (only DIGEST_ALGO_SHA1 has ever been defined).  */
+  byte mdc_method;
+  /* If 0, AEAD is not used.  Otherwise, the used AEAD algorithm.
+   * MDC_METHOD (above) shall be zero if AEAD is used.  */
+  byte aead_algo;
+  /* The cipher algo for/from the AEAD packet.  0 for other encryption
+   * packets. */
+  byte cipher_algo;
+  /* The chunk byte from the AEAD packet.  */
+  byte chunkbyte;
+
+  /* An iobuf holding the data to be decrypted.  (This is not used for
+     encryption!)  */
+  iobuf_t buf;
 } PKT_encrypted;
 
 typedef struct {
     byte hash[20];
 } PKT_mdc;
 
+
+/* Subtypes for the ring trust packet.  */
+#define RING_TRUST_SIG 0  /* The classical signature cache.  */
+#define RING_TRUST_KEY 1  /* A KEYORG on a primary key.      */
+#define RING_TRUST_UID 2  /* A KEYORG on a user id.          */
+
+/* The local only ring trust packet which OpenPGP declares as
+ * implementation defined.  GnuPG uses this to cache signature
+ * verification status and since 2.1.18 also to convey information
+ * about the origin of a key.  Note that this packet is not part
+ * struct packet_struct because we use it only local in the packet
+ * parser and builder. */
 typedef struct {
-    unsigned int trustval;
-    unsigned int sigcache;
+  unsigned int trustval;
+  unsigned int sigcache;
+  unsigned char subtype; /* The subtype of this ring trust packet.   */
+  unsigned char keyorg;  /* The origin of the key (KEYORG_*).        */
+  u32 keyupdate;         /* The wall time the key was last updated.  */
+  char *url;             /* NULL or the URL of the source.           */
 } PKT_ring_trust;
 
+
+/* A plaintext packet (see RFC 4880, 5.9).  */
 typedef struct {
-    u32  len;            /* length of encrypted data */
-    iobuf_t buf;         /* IOBUF reference */
-    byte new_ctb;
-    byte is_partial;      /* partial length encoded */
-    int mode;
-    u32 timestamp;
-    int  namelen;
-    char name[1];
+  /* The length of data in BUF or 0 if unknown.  */
+  u32  len;
+  /* A buffer containing the data stored in the packet's body.  */
+  iobuf_t buf;
+  byte new_ctb;
+  byte is_partial;      /* partial length encoded */
+  /* The data's formatting.  This is either 'b', 't', 'u', 'l' or '1'
+     (however, the last two are deprecated).  */
+  int mode;
+  u32 timestamp;
+  /* The name of the file.  This can be at most 255 characters long,
+     since namelen is just a byte in the serialized format.  */
+  int  namelen;
+  char name[1];
 } PKT_plaintext;
 
 typedef struct {
@@ -385,7 +574,6 @@ struct packet_struct {
        PKT_compressed  *compressed;    /* PKT_COMPRESSED */
        PKT_encrypted   *encrypted;     /* PKT_ENCRYPTED[_MDC] */
        PKT_mdc         *mdc;           /* PKT_MDC */
-       PKT_ring_trust  *ring_trust;    /* PKT_RING_TRUST */
        PKT_plaintext   *plaintext;     /* PKT_PLAINTEXT */
         PKT_gpg_control *gpg_control;   /* PKT_GPG_CONTROL */
     } pkt;
@@ -396,20 +584,45 @@ struct packet_struct {
                       } while(0)
 
 
+/* A notation.  See RFC 4880, Section 5.2.3.16.  */
 struct notation
 {
+  /* The notation's name.  */
   char *name;
+  /* If the notation is human readable, then the value is stored here
+     as a NUL-terminated string.  If it is not human readable a human
+     readable approximation of the binary value _may_ be stored
+     here.  */
   char *value;
+  /* Sometimes we want to %-expand the value.  In these cases, we save
+     that transformed value here.  */
   char *altvalue;
+  /* If the notation is not human readable, then the value is stored
+     here.  */
   unsigned char *bdat;
+  /* The amount of data stored in BDAT.
+
+     Note: if this is 0 and BDAT is NULL, this does not necessarily
+     mean that the value is human readable.  It could be that we have
+     a 0-length value.  To determine whether the notation is human
+     readable, always check if VALUE is not NULL.  This works, because
+     if a human-readable value has a length of 0, we will still
+     allocate space for the NUL byte.  */
   size_t blen;
   struct
   {
+    /* The notation is critical.  */
     unsigned int critical:1;
+    /* The notation is human readable.  */
+    unsigned int human:1;
+    /* The notation should be deleted.  */
     unsigned int ignore:1;
   } flags;
+
+  /* A field to facilitate creating a list of notations.  */
   struct notation *next;
 };
+typedef struct notation *notation_t;
 
 /*-- mainproc.c --*/
 void reset_literals_seen(void);
@@ -421,8 +634,14 @@ int proc_signature_packets_by_fd (ctrl_t ctrl,
 int proc_encryption_packets (ctrl_t ctrl, void *ctx, iobuf_t a);
 int list_packets( iobuf_t a );
 
+const byte *issuer_fpr_raw (PKT_signature *sig, size_t *r_len);
+char *issuer_fpr_string (PKT_signature *sig);
+
 /*-- parse-packet.c --*/
 
+
+void register_known_notation (const char *string);
+
 /* Sets the packet list mode to MODE (i.e., whether we are dumping a
    packet or not).  Returns the current mode.  This allows for
    temporarily suspending dumping by doing the following:
@@ -433,12 +652,40 @@ int list_packets( iobuf_t a );
 */
 int set_packet_list_mode( int mode );
 
+
+/* A context used with parse_packet.  */
+struct parse_packet_ctx_s
+{
+  iobuf_t inp;       /* The input stream with the packets.  */
+  struct packet_struct last_pkt; /* The last parsed packet.  */
+  int free_last_pkt; /* Indicates that LAST_PKT must be freed.  */
+  int skip_meta;     /* Skip ring trust packets.  */
+  unsigned int n_parsed_packets;       /* Number of parsed packets.  */
+};
+typedef struct parse_packet_ctx_s *parse_packet_ctx_t;
+
+#define init_parse_packet(a,i) do { \
+    (a)->inp = (i);                 \
+    (a)->last_pkt.pkttype = 0;      \
+    (a)->last_pkt.pkt.generic= NULL;\
+    (a)->free_last_pkt = 0;         \
+    (a)->skip_meta = 0;             \
+    (a)->n_parsed_packets = 0;      \
+  } while (0)
+
+#define deinit_parse_packet(a) do { \
+    if ((a)->free_last_pkt)         \
+      free_packet (NULL, (a));      \
+  } while (0)
+
+
 #if DEBUG_PARSE_PACKET
 /* There are debug functions and should not be used directly.  */
-int dbg_search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid,
+int dbg_search_packet (parse_packet_ctx_t ctx, PACKET *pkt,
+                       off_t *retpos, int with_uid,
                        const char* file, int lineno  );
-int dbg_parse_packet( iobuf_t inp, PACKET *ret_pkt,
-                      const char* file, int lineno );
+int dbg_parse_packet (parse_packet_ctx_t ctx, PACKET *ret_pkt,
+                      const char *file, int lineno);
 int dbg_copy_all_packets( iobuf_t inp, iobuf_t out,
                           const char* file, int lineno  );
 int dbg_copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff,
@@ -457,51 +704,53 @@ int dbg_skip_some_packets( iobuf_t inp, unsigned n,
              dbg_skip_some_packets((a),(b), __FILE__, __LINE__ )
 #else
 /* Return the next valid OpenPGP packet in *PKT.  (This function will
-   skip any packets whose type is 0.)
-
-   Returns 0 on success, -1 if EOF is reached, and an error code
-   otherwise.  In the case of an error, the packet in *PKT may be
-   partially constructed.  As such, even if there is an error, it is
-   necessary to free *PKT to avoid a resource leak.  To detect what
-   has been allocated, clear *PKT before calling this function.  */
-int parse_packet( iobuf_t inp, PACKET *pkt);
+ * skip any packets whose type is 0.)  CTX must have been setup prior to
+ * calling this function.
+ *
+ * Returns 0 on success, -1 if EOF is reached, and an error code
+ * otherwise.  In the case of an error, the packet in *PKT may be
+ * partially constructed.  As such, even if there is an error, it is
+ * necessary to free *PKT to avoid a resource leak.  To detect what
+ * has been allocated, clear *PKT before calling this function.  */
+int parse_packet (parse_packet_ctx_t ctx, PACKET *pkt);
 
 /* Return the first OpenPGP packet in *PKT that contains a key (either
-   a public subkey, a public key, a secret subkey or a secret key) or,
-   if WITH_UID is set, a user id.
-
-   Saves the position in the pipeline of the start of the returned
-   packet (according to iobuf_tell) in RETPOS, if it is not NULL.
-
-   The return semantics are the same as parse_packet.  */
-int search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid );
+ * a public subkey, a public key, a secret subkey or a secret key) or,
+ * if WITH_UID is set, a user id.
+ *
+ * Saves the position in the pipeline of the start of the returned
+ * packet (according to iobuf_tell) in RETPOS, if it is not NULL.
+ *
+ * The return semantics are the same as parse_packet.  */
+int search_packet (parse_packet_ctx_t ctx, PACKET *pkt,
+                   off_t *retpos, int with_uid);
 
 /* Copy all packets (except invalid packets, i.e., those with a type
  of 0) from INP to OUT until either an error occurs or EOF is
  reached.
-
  Returns -1 when end of file is reached or an error code, if an
  error occurred.  (Note: this function never returns 0, because it
  effectively keeps going until it gets an EOF.)  */
-int copy_all_packetsiobuf_t inp, iobuf_t out );
* of 0) from INP to OUT until either an error occurs or EOF is
* reached.
+ *
* Returns -1 when end of file is reached or an error code, if an
* error occurred.  (Note: this function never returns 0, because it
* effectively keeps going until it gets an EOF.)  */
+int copy_all_packets (iobuf_t inp, iobuf_t out );
 
 /* Like copy_all_packets, but stops at the first packet that starts at
  or after STOPOFF (as indicated by iobuf_tell).
-
-   Example: if STOPOFF is 100, the first packet in INP goes from 0 to
  110 and the next packet starts at offset 111, then the packet
  starting at offset 0 will be completely processed (even though it
  extends beyond STOPOFF) and the packet starting at offset 111 will
  not be processed at all.  */
-int copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff );
* or after STOPOFF (as indicated by iobuf_tell).
+ *
+ * Example: if STOPOFF is 100, the first packet in INP goes from
* 0 to 110 and the next packet starts at offset 111, then the packet
* starting at offset 0 will be completely processed (even though it
* extends beyond STOPOFF) and the packet starting at offset 111 will
* not be processed at all.  */
+int copy_some_packets (iobuf_t inp, iobuf_t out, off_t stopoff);
 
 /* Skips the next N packets from INP.
-
  If parsing a packet returns an error code, then the function stops
  immediately and returns the error code.  Note: in the case of an
  error, this function does not indicate how many packets were
  successfully processed.  */
-int skip_some_packets( iobuf_t inp, unsigned n );
+ *
* If parsing a packet returns an error code, then the function stops
* immediately and returns the error code.  Note: in the case of an
* error, this function does not indicate how many packets were
* successfully processed.  */
+int skip_some_packets (iobuf_t inp, unsigned int n);
 #endif
 
 /* Parse a signature packet and store it in *SIG.
@@ -602,18 +851,21 @@ PACKET *create_gpg_control ( ctrlpkttype_t type,
                              size_t datalen );
 
 /*-- build-packet.c --*/
-int build_packet( iobuf_t inp, PACKET *pkt );
-gpg_error_t gpg_mpi_write (iobuf_t out, gcry_mpi_t a);
+int build_packet (iobuf_t out, PACKET *pkt);
+gpg_error_t build_packet_and_meta (iobuf_t out, PACKET *pkt);
+gpg_error_t gpg_mpi_write (iobuf_t out, gcry_mpi_t a, unsigned int *t_nwritten);
 gpg_error_t gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a);
 u32 calc_packet_length( PACKET *pkt );
 void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
                        const byte *buffer, size_t buflen );
-void build_sig_subpkt_from_sig( PKT_signature *sig );
+void build_sig_subpkt_from_sig (PKT_signature *sig, PKT_public_key *pksk);
 int  delete_sig_subpkt(subpktarea_t *buffer, sigsubpkttype_t type );
 void build_attribute_subpkt(PKT_user_id *uid,byte type,
                            const void *buf,u32 buflen,
                            const void *header,u32 headerlen);
 struct notation *string_to_notation(const char *string,int is_utf8);
+struct notation *blob_to_notation(const char *name,
+                                  const char *data, size_t len);
 struct notation *sig_to_notation(PKT_signature *sig);
 void free_notation(struct notation *notation);
 
@@ -626,7 +878,7 @@ void free_public_key( PKT_public_key *key );
 void free_attributes(PKT_user_id *uid);
 void free_user_id( PKT_user_id *uid );
 void free_comment( PKT_comment *rem );
-void free_packet( PACKET *pkt );
+void free_packet (PACKET *pkt, parse_packet_ctx_t parsectx);
 prefitem_t *copy_prefs (const prefitem_t *prefs);
 PKT_public_key *copy_public_key( PKT_public_key *d, PKT_public_key *s );
 PKT_signature *copy_signature( PKT_signature *d, PKT_signature *s );
@@ -639,20 +891,22 @@ int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );
 /*-- sig-check.c --*/
 /* Check a signature.  This is shorthand for check_signature2 with
    the unnamed arguments passed as NULL.  */
-int check_signature (PKT_signature *sig, gcry_md_hd_t digest);
+int check_signature (ctrl_t ctrl, PKT_signature *sig, gcry_md_hd_t digest);
 
 /* Check a signature.  Looks up the public key from the key db.  (If
-   RET_PK is not NULL, it is returned in *RET_PK.)  DIGEST contains a
-   valid hash context that already includes the signed data.  This
-   function adds the relevant meta-data to the hash before finalizing
-   it and verifying the signature.  */
-int check_signature2 (PKT_signature *sig, gcry_md_hd_t digest,
-                     u32 *r_expiredate, int *r_expired, int *r_revoked,
-                     PKT_public_key *ret_pk);
+ * R_PK is not NULL, it is stored at RET_PK.)  DIGEST contains a
+ * valid hash context that already includes the signed data.  This
+ * function adds the relevant meta-data to the hash before finalizing
+ * it and verifying the signature.  */
+gpg_error_t check_signature2 (ctrl_t ctrl,
+                              PKT_signature *sig, gcry_md_hd_t digest,
+                              const void *extrahash, size_t extrahashlen,
+                              u32 *r_expiredate, int *r_expired, int *r_revoked,
+                              PKT_public_key **r_pk);
 
 
 /*-- pubkey-enc.c --*/
-gpg_error_t get_session_key (ctrl_t ctrl, PKT_pubkey_enc *k, DEK *dek);
+gpg_error_t get_session_key (ctrl_t ctrl, struct pubkey_enc_list *k, DEK *dek);
 gpg_error_t get_override_session_key (DEK *dek, const char *string);
 
 /*-- compress.c --*/
@@ -671,14 +925,16 @@ int ask_for_detached_datafile( gcry_md_hd_t md, gcry_md_hd_t md2,
                               const char *inname, int textmode );
 
 /*-- sign.c --*/
-int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
+int make_keysig_packet (ctrl_t ctrl,
+                        PKT_signature **ret_sig, PKT_public_key *pk,
                        PKT_user_id *uid, PKT_public_key *subpk,
                        PKT_public_key *pksk, int sigclass, int digest_algo,
                        u32 timestamp, u32 duration,
                        int (*mksubpkt)(PKT_signature *, void *),
                        void *opaque,
                         const char *cache_nonce);
-gpg_error_t update_keysig_packet (PKT_signature **ret_sig,
+gpg_error_t update_keysig_packet (ctrl_t ctrl,
+                      PKT_signature **ret_sig,
                       PKT_signature *orig_sig,
                       PKT_public_key *pk,
                       PKT_user_id *uid,