Revert commit 4654384fe7a4dcee113dacf27c398b13dea5d0be.
[gnupg.git] / g10 / packet.h
index d06c4c7..9eb16cf 100644 (file)
@@ -1,6 +1,7 @@
 /* packet.h - OpenPGP packet definitions
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
  *               2007 Free Software Foundation, Inc.
+ * Copyright (C) 2015 g10 Code GmbH
  *
  * This file is part of GnuPG.
  *
@@ -24,7 +25,7 @@
 #include "types.h"
 #include "../common/iobuf.h"
 #include "../common/strlist.h"
-#include "cipher.h"
+#include "dek.h"
 #include "filter.h"
 #include "../common/openpgpdefs.h"
 #include "../common/userids.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
+
+/* Usage flags */
+#define PUBKEY_USAGE_SIG     GCRY_PK_USAGE_SIGN  /* Good for signatures. */
+#define PUBKEY_USAGE_ENC     GCRY_PK_USAGE_ENCR  /* Good for encryption. */
+#define PUBKEY_USAGE_CERT    GCRY_PK_USAGE_CERT  /* Also good to certify keys.*/
+#define PUBKEY_USAGE_AUTH    GCRY_PK_USAGE_AUTH  /* Good for authentication. */
+#define PUBKEY_USAGE_UNKNOWN GCRY_PK_USAGE_UNKN  /* Unknown usage flag. */
+#define PUBKEY_USAGE_NONE    256                 /* No usage given. */
+#if  (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR | GCRY_PK_USAGE_CERT \
+      | GCRY_PK_USAGE_AUTH | GCRY_PK_USAGE_UNKN) >= 256
+# error Please choose another value for PUBKEY_USAGE_NONE
+#endif
+
+/* Helper macros.  */
+#define is_RSA(a)     ((a)==PUBKEY_ALGO_RSA || (a)==PUBKEY_ALGO_RSA_E \
+                      || (a)==PUBKEY_ALGO_RSA_S )
+#define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL_E)
+#define is_DSA(a)     ((a)==PUBKEY_ALGO_DSA)
+
+/* A pointer to the packet object.  */
 typedef struct packet_struct PACKET;
 
 /* PKT_GPG_CONTROL types */
@@ -49,11 +75,11 @@ typedef enum {
 } preftype_t;
 
 typedef struct {
-    byte type; 
+    byte type;
     byte value;
 } prefitem_t;
 
-typedef struct 
+typedef struct
 {
   int  mode;      /* Must be an integer due to the GNU modes 1001 et al.  */
   byte hash_algo;
@@ -114,9 +140,9 @@ typedef struct
 
 
 /* Object to keep information pertaining to a signature. */
-typedef struct 
+typedef struct
 {
-  struct 
+  struct
   {
     unsigned checked:1;         /* Signature has been checked. */
     unsigned valid:1;           /* Signature is good (if checked is set). */
@@ -141,7 +167,7 @@ typedef struct
   byte    trust_depth;
   byte    trust_value;
   const byte *trust_regexp;
-  struct revocation_key **revkey;
+  struct revocation_key *revkey;
   int numrevkeys;
   pka_info_t *pka_info;      /* Malloced PKA data or NULL if not
                                 available.  See also flags.pka_tried. */
@@ -149,6 +175,11 @@ typedef struct
   subpktarea_t *unhashed;    /* Ditto for unhashed data. */
   byte digest_start[2];      /* First 2 bytes of the digest. */
   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
+     the digest's value has not been saved here.  */
+  byte digest[512 / 8];
+  int digest_len;
 } PKT_signature;
 
 #define ATTRIB_IMAGE 1
@@ -213,7 +244,7 @@ struct seckey_info
                        /* be decrypted before use, the protected */
                        /* MPIs are simply (void*) pointers to memory */
                        /* and should never be passed to a mpi_xxx() */
-  int sha1chk:1;        /* SHA1 is used instead of a 16 bit checksum */ 
+  int sha1chk:1;        /* SHA1 is used instead of a 16 bit checksum */
   u16 csum;            /* Checksum for old protection modes.  */
   byte algo;            /* Cipher used to protect the secret information. */
   STRING2KEY s2k;       /* S2K parameter.  */
@@ -247,8 +278,7 @@ typedef struct
   byte    pubkey_algo;    /* algorithm used for public key scheme */
   byte    pubkey_usage;   /* for now only used to pass it to getkey() */
   byte    req_usage;      /* hack to pass a request to getkey() */
-  byte    req_algo;       /* Ditto */
-  u32     has_expired;    /* set to the expiration date if expired */ 
+  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() */
   prefitem_t *prefs;      /* list of preferences (may be NULL) */
@@ -257,7 +287,7 @@ typedef struct
     unsigned int mdc:1;           /* MDC 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.  */ 
+    unsigned int primary:1;       /* This is a primary key.  */
     unsigned int revoked:2;       /* Key has been revoked.
                                      1 = revoked by the owner
                                      2 = revoked by designated revoker.  */
@@ -278,7 +308,7 @@ typedef struct
   const byte *trust_regexp;
   char    *serialno;      /* Malloced hex string or NULL if it is
                              likely not on a card.  See also
-                             flags.serialno_valid.  */  
+                             flags.serialno_valid.  */
   struct seckey_info *seckey_info;  /* If not NULL this malloced
                                        structure describes a secret
                                        key.  */
@@ -348,7 +378,7 @@ struct packet_struct {
        PKT_pubkey_enc  *pubkey_enc;    /* PKT_PUBKEY_ENC */
        PKT_onepass_sig *onepass_sig;   /* PKT_ONEPASS_SIG */
        PKT_signature   *signature;     /* PKT_SIGNATURE */
-       PKT_public_key  *public_key;    /* PKT_PUBLIC_[SUB)KEY */
+       PKT_public_key  *public_key;    /* PKT_PUBLIC_[SUB]KEY */
        PKT_public_key  *secret_key;    /* PKT_SECRET_[SUB]KEY */
        PKT_comment     *comment;       /* PKT_COMMENT */
        PKT_user_id     *user_id;       /* PKT_USER_ID */
@@ -392,9 +422,19 @@ int proc_encryption_packets (ctrl_t ctrl, void *ctx, iobuf_t a);
 int list_packets( iobuf_t a );
 
 /*-- parse-packet.c --*/
+
+/* 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:
+
+     int saved_mode = set_packet_list_mode (0);
+     ...
+     set_packet_list_mode (saved_mode);
+*/
 int set_packet_list_mode( int mode );
 
 #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,
                        const char* file, int lineno  );
 int dbg_parse_packet( iobuf_t inp, PACKET *ret_pkt,
@@ -416,35 +456,155 @@ int dbg_skip_some_packets( iobuf_t inp, unsigned n,
 #define skip_some_packets( a,b ) \
              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);
+
+/* 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 );
-int parse_packet( iobuf_t inp, PACKET *ret_pkt);
+
+/* 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_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 );
+
+/* 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 );
 #endif
 
+/* Parse a signature packet and store it in *SIG.
+
+   The signature packet is read from INP.  The OpenPGP header (the tag
+   and the packet's length) have already been read; the next byte read
+   from INP should be the first byte of the packet's contents.  The
+   packet's type (as extract from the tag) must be passed as PKTTYPE
+   and the packet's length must be passed as PKTLEN.  This is used as
+   the upper bound on the amount of data read from INP.  If the packet
+   is shorter than PKTLEN, the data at the end will be silently
+   skipped.  If an error occurs, an error code will be returned.  -1
+   means the EOF was encountered.  0 means parsing was successful.  */
 int parse_signature( iobuf_t inp, int pkttype, unsigned long pktlen,
                     PKT_signature *sig );
+
+/* Given a subpacket area (typically either PKT_signature.hashed or
+   PKT_signature.unhashed), either:
+
+     - test whether there are any subpackets with the critical bit set
+       that we don't understand,
+
+     - list the subpackets, or,
+
+     - find a subpacket with a specific type.
+
+   REQTYPE indicates the type of operation.
+
+   If REQTYPE is SIGSUBPKT_TEST_CRITICAL, then this function checks
+   whether there are any subpackets that have the critical bit and
+   which GnuPG cannot handle.  If GnuPG understands all subpackets
+   whose critical bit is set, then this function returns simply
+   returns SUBPKTS.  If there is a subpacket whose critical bit is set
+   and which GnuPG does not understand, then this function returns
+   NULL and, if START is not NULL, sets *START to the 1-based index of
+   the subpacket that violates the constraint.
+
+   If REQTYPE is SIGSUBPKT_LIST_HASHED or SIGSUBPKT_LIST_UNHASHED, the
+   packets are dumped.  Note: if REQTYPE is SIGSUBPKT_LIST_HASHED,
+   this function does not check whether the hash is correct; this is
+   merely an indication of the section that the subpackets came from.
+
+   If REQTYPE is anything else, then this function interprets the
+   values as a subpacket type and looks for the first subpacket with
+   that type.  If such a packet is found, *CRITICAL (if not NULL) is
+   set if the critical bit was set, *RET_N is set to the offset of the
+   subpacket's content within the SUBPKTS buffer, *START is set to the
+   1-based index of the subpacket within the buffer, and returns
+   &SUBPKTS[*RET_N].
+
+   *START is the number of initial subpackets to not consider.  Thus,
+   if *START is 2, then the first 2 subpackets are ignored.  */
 const byte *enum_sig_subpkt ( const subpktarea_t *subpkts,
                               sigsubpkttype_t reqtype,
                               size_t *ret_n, int *start, int *critical );
+
+/* Shorthand for:
+
+     enum_sig_subpkt (buffer, reqtype, ret_n, NULL, NULL); */
 const byte *parse_sig_subpkt ( const subpktarea_t *buffer,
                                sigsubpkttype_t reqtype,
                                size_t *ret_n );
+
+/* This calls parse_sig_subpkt first on the hashed signature area in
+   SIG and then, if that returns NULL, calls parse_sig_subpkt on the
+   unhashed subpacket area in SIG.  */
 const byte *parse_sig_subpkt2 ( PKT_signature *sig,
-                                sigsubpkttype_t reqtype,
-                                size_t *ret_n );
+                                sigsubpkttype_t reqtype);
+
+/* Returns whether the N byte large buffer BUFFER is sufficient to
+   hold a subpacket of type TYPE.  Note: the buffer refers to the
+   contents of the subpacket (not the header) and it must already be
+   initialized: for some subpackets, it checks some internal
+   constraints.
+
+   Returns 0 if the size is acceptable.  Returns -2 if the buffer is
+   definitely too short.  To check for an error, check whether the
+   return value is less than 0.  */
 int parse_one_sig_subpkt( const byte *buffer, size_t n, int type );
+
+/* Looks for revocation key subpackets (see RFC 4880 5.2.3.15) in the
+   hashed area of the signature packet.  Any that are found are added
+   to SIG->REVKEY and SIG->NUMREVKEYS is updated appropriately.  */
 void parse_revkeys(PKT_signature *sig);
+
+/* Extract the attributes from the buffer at UID->ATTRIB_DATA and
+   update UID->ATTRIBS and UID->NUMATTRIBS accordingly.  */
 int parse_attribute_subpkts(PKT_user_id *uid);
+
+/* Set the UID->NAME field according to the attributes.  MAX_NAMELEN
+   must be at least 71.  */
 void make_attribute_uidname(PKT_user_id *uid, size_t max_namelen);
+
+/* Allocate and initialize a new GPG control packet.  DATA is the data
+   to save in the packet.  */
 PACKET *create_gpg_control ( ctrlpkttype_t type,
                              const byte *data,
                              size_t datalen );
 
 /*-- build-packet.c --*/
 int build_packet( iobuf_t inp, PACKET *pkt );
-gpg_error_t write_size_body_mpi (iobuf_t out, gcry_mpi_t a);
+gpg_error_t gpg_mpi_write (iobuf_t out, gcry_mpi_t a);
+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 );
@@ -461,7 +621,6 @@ void free_notation(struct notation *notation);
 void free_symkey_enc( PKT_symkey_enc *enc );
 void free_pubkey_enc( PKT_pubkey_enc *enc );
 void free_seckey_enc( PKT_signature *enc );
-int  digest_algo_from_sig( PKT_signature *sig );
 void release_public_key_parts( PKT_public_key *pk );
 void free_public_key( PKT_public_key *key );
 void free_attributes(PKT_user_id *uid);
@@ -478,13 +637,22 @@ int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );
 
 
 /*-- sig-check.c --*/
-int signature_check( PKT_signature *sig, gcry_md_hd_t digest );
-int signature_check2( PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate,
-                     int *r_expired, int *r_revoked, PKT_public_key *ret_pk );
+/* 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);
+
+/* 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);
 
 
 /*-- pubkey-enc.c --*/
-gpg_error_t get_session_key (PKT_pubkey_enc *k, DEK *dek);
+gpg_error_t get_session_key (ctrl_t ctrl, PKT_pubkey_enc *k, DEK *dek);
 gpg_error_t get_override_session_key (DEK *dek, const char *string);
 
 /*-- compress.c --*/
@@ -495,6 +663,8 @@ int handle_compressed (ctrl_t ctrl, void *ctx, PKT_compressed *cd,
 int decrypt_data (ctrl_t ctrl, void *ctx, PKT_encrypted *ed, DEK *dek );
 
 /*-- plaintext.c --*/
+gpg_error_t get_output_file (const byte *embedded_name, int embedded_namelen,
+                             iobuf_t data, char **fnamep, estream_t *fpp);
 int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
                                        int nooutput, int clearsig );
 int ask_for_detached_datafile( gcry_md_hd_t md, gcry_md_hd_t md2,
@@ -504,11 +674,11 @@ int ask_for_detached_datafile( gcry_md_hd_t md, gcry_md_hd_t md2,
 int make_keysig_packet( 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,
-                       int sigversion, u32 timestamp, u32 duration,
+                       u32 timestamp, u32 duration,
                        int (*mksubpkt)(PKT_signature *, void *),
                        void *opaque,
                         const char *cache_nonce);
-int update_keysig_packet( PKT_signature **ret_sig,
+gpg_error_t update_keysig_packet (PKT_signature **ret_sig,
                       PKT_signature *orig_sig,
                       PKT_public_key *pk,
                       PKT_user_id *uid,
@@ -518,6 +688,6 @@ int update_keysig_packet( PKT_signature **ret_sig,
                       void *opaque   );
 
 /*-- keygen.c --*/
-PKT_user_id *generate_user_id (KBNODE keyblock);
+PKT_user_id *generate_user_id (kbnode_t keyblock, const char *uidstr);
 
 #endif /*G10_PACKET_H*/