gpg: Improve documentation and comments related to OpenPGP packets.

--
Signed-off-by: Neal H. Walfield <neal@g10code.com>
This commit is contained in:
Neal H. Walfield 2016-02-25 21:08:56 +01:00
parent c9636a1acc
commit b7b4a1bdd9
3 changed files with 362 additions and 66 deletions

View File

@ -310,6 +310,11 @@ write_fake_data (IOBUF out, gcry_mpi_t a)
}
/* Serialize the user id (RFC 4880, Section 5.11) or the user
attribute UID (Section 5.12) and write it to OUT.
CTB is the serialization's CTB. It specifies the header format and
the packet's type. The header length must not be set. */
static int
do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
{
@ -332,12 +337,31 @@ do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
}
/* Serialize the key (RFC 4880, Section 5.5) described by PK and write
it to OUT.
This function serializes both primary keys and subkeys with or
without a secret part.
CTB is the serialization's CTB. It specifies the header format and
the packet's type. The header length must not be set.
PK->VERSION specifies the serialization format. A value of 0 means
to use the default version. Currently, only version 4 packets are
supported.
*/
static int
do_key (iobuf_t out, int ctb, PKT_public_key *pk)
{
gpg_error_t err = 0;
/* The length of the body is stored in the packet's header, which
occurs before the body. Unfortunately, we don't know the length
of the packet's body until we've written all of the data! To
work around this, we first write the data into this temporary
buffer, then generate the header, and finally copy the contents
of this buffer to OUT. */
iobuf_t a = iobuf_temp();
int i, nskey, npkey;
iobuf_t a = iobuf_temp(); /* Build in a self-enlarging buffer. */
log_assert (pk->version == 0 || pk->version == 4);
log_assert (ctb_pkttype (ctb) == PKT_PUBLIC_KEY
@ -355,7 +379,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
iobuf_put (a, pk->pubkey_algo );
/* Get number of secret and public parameters. They are held in one
array first the public ones, then the secret ones. */
array: the public ones followed by the secret ones. */
nskey = pubkey_get_nskey (pk->pubkey_algo);
npkey = pubkey_get_npkey (pk->pubkey_algo);
@ -463,7 +487,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
writing all the other stuff, so that we know the length of
the packet */
write_header2 (out, ctb, iobuf_get_temp_length(a), pk->hdrbytes);
/* And finally write it out to the real stream. */
/* And finally write it out to the real stream. */
err = iobuf_write_temp (out, a);
}
@ -471,6 +495,11 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
return err;
}
/* Serialize the symmetric-key encrypted session key packet (RFC 4880,
5.3) described by ENC and write it to OUT.
CTB is the serialization's CTB. It specifies the header format and
the packet's type. The header length must not be set. */
static int
do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc )
{
@ -479,10 +508,23 @@ do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc )
log_assert (ctb_pkttype (ctb) == PKT_SYMKEY_ENC);
/* The only acceptable version. */
assert( enc->version == 4 );
switch( enc->s2k.mode ) {
case 0: case 1: case 3: break;
default: log_bug("do_symkey_enc: s2k=%d\n", enc->s2k.mode );
/* RFC 4880, Section 3.7. */
switch( enc->s2k.mode )
{
/* Simple S2K. */
case 0:
/* Salted S2K. */
case 1:
/* Iterated and salted S2K. */
case 3:
/* Reasonable values. */
break;
default:
log_bug("do_symkey_enc: s2k=%d\n", enc->s2k.mode );
}
iobuf_put( a, enc->version );
iobuf_put( a, enc->cipher_algo );
@ -504,6 +546,11 @@ do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc )
}
/* Serialize the public-key encrypted session key packet (RFC 4880,
5.1) described by ENC and write it to OUT.
CTB is the serialization's CTB. It specifies the header format and
the packet's type. The header length must not be set. */
static int
do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
{
@ -548,6 +595,8 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
}
/* Calculate the length of the serialized plaintext packet PT (RFC
4480, Section 5.9). */
static u32
calc_plaintext( PKT_plaintext *pt )
{
@ -561,6 +610,15 @@ calc_plaintext( PKT_plaintext *pt )
return pt->len? (1 + 1 + pt->namelen + 4 + pt->len) : 0;
}
/* Serialize the plaintext packet (RFC 4880, 5.9) described by PT and
write it to OUT.
The body of the message is stored in PT->BUF. The amount of data
to write is PT->LEN. (PT->BUF should be configured to return EOF
after this much data has been read.) If PT->LEN is 0 and CTB
indicates that this is a new format packet, then partial block mode
is assumed to have been enabled on OUT. On success, partial block
mode is disabled. */
static int
do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt )
{
@ -591,6 +649,13 @@ do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt )
/* Serialize the symmetrically encrypted data packet (RFC 4880,
Section 5.7) described by ED and write it to OUT.
Note: this only writes the packets header! The call must then
follow up and write the initial random data and the body to OUT.
(If you use the encryption iobuf filter (cipher_filter), then this
is done automatically.) */
static int
do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed )
{
@ -608,6 +673,14 @@ do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed )
return rc;
}
/* Serialize the symmetrically encrypted integrity protected data
packet (RFC 4880, Section 5.13) described by ED and write it to
OUT.
Note: this only writes the packet's header! The caller must then
follow up and write the initial random data, the body and the MDC
packet to OUT. (If you use the encryption iobuf filter
(cipher_filter), then this is done automatically.) */
static int
do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed )
{
@ -628,6 +701,11 @@ do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed )
}
/* Serialize the compressed packet (RFC 4880, Section 5.6) described
by CD and write it to OUT.
Note: this only writes the packet's header! The caller must then
follow up and write the body to OUT. */
static int
do_compressed( IOBUF out, int ctb, PKT_compressed *cd )
{
@ -983,6 +1061,15 @@ build_attribute_subpkt(PKT_user_id *uid,byte type,
uid->attrib_len+=idx+headerlen+buflen;
}
/* Turn the notation described by the string STRING into a notation.
STRING has the form:
- -name - Delete the notation.
- name@domain.name=value - Normal notation
- !name@domain.name=value - Notation with critical bit set.
The caller must free the result using free_notation(). */
struct notation *
string_to_notation(const char *string,int is_utf8)
{
@ -1073,6 +1160,8 @@ string_to_notation(const char *string,int is_utf8)
return NULL;
}
/* Return all of the notations stored in the signature SIG. The
caller must free them using free_notation(). */
struct notation *
sig_to_notation(PKT_signature *sig)
{
@ -1081,6 +1170,15 @@ sig_to_notation(PKT_signature *sig)
int seq=0,crit;
struct notation *list=NULL;
/* See RFC 4880, 5.2.3.16 for the format of notation data. In
short, a notation has:
- 4 bytes of flags
- 2 byte name length (n1)
- 2 byte value length (n2)
- n1 bytes of name data
- n2 bytes of value data
*/
while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,&len,&seq,&crit)))
{
int n1,n2;
@ -1092,7 +1190,9 @@ sig_to_notation(PKT_signature *sig)
continue;
}
/* name length. */
n1=(p[4]<<8)|p[5];
/* value length. */
n2=(p[6]<<8)|p[7];
if(8+n1+n2!=len)
@ -1108,12 +1208,14 @@ sig_to_notation(PKT_signature *sig)
n->name[n1]='\0';
if(p[0]&0x80)
/* The value is human-readable. */
{
n->value=xmalloc(n2+1);
memcpy(n->value,&p[8+n1],n2);
n->value[n2]='\0';
}
else
/* Binary data. */
{
n->bdat=xmalloc(n2);
n->blen=n2;
@ -1134,6 +1236,9 @@ sig_to_notation(PKT_signature *sig)
return list;
}
/* Release the resources associated with the *list* of notations. To
release a single notation, make sure that notation->next is
NULL. */
void
free_notation(struct notation *notation)
{
@ -1150,6 +1255,8 @@ free_notation(struct notation *notation)
}
}
/* Serialize the signature packet (RFC 4880, Section 5.2) described by
SIG and write it to OUT. */
static int
do_signature( IOBUF out, int ctb, PKT_signature *sig )
{
@ -1217,6 +1324,8 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig )
}
/* Serialize the one-pass signature packet (RFC 4880, Section 5.4)
described by OPS and write it to OUT. */
static int
do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops )
{
@ -1236,6 +1345,7 @@ do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops )
}
/* Write a 16-bit quantity to OUT in big endian order. */
static int
write_16(IOBUF out, u16 a)
{
@ -1245,6 +1355,7 @@ write_16(IOBUF out, u16 a)
return 0;
}
/* Write a 32-bit quantity to OUT in big endian order. */
static int
write_32(IOBUF out, u32 a)
{
@ -1308,11 +1419,26 @@ write_sign_packet_header (IOBUF out, int ctb, u32 len)
}
/****************
* If HDRLEN is > 0, try to build a header of this length. We need
* this so that we can hash packets without reading them again. If
* len is 0, write a partial or indeterminate length header, unless
* hdrlen is specified in which case write an actual zero length
* (using the specified hdrlen).
* Write a packet header to OUT.
*
* CTB is the ctb. It determines whether a new or old format packet
* header should be written. The length field is adjusted, but the
* CTB is otherwise written out as is.
*
* LEN is the length of the packet's body.
*
* If HDRLEN is set, then we don't necessarily use the most efficient
* encoding to store LEN, but the specified length. (If this is not
* possible, this is a bug.) In this case, LEN=0 means a 0 length
* packet. Note: setting HDRLEN is only supported for old format
* packets!
*
* If HDRLEN is not set, then the shortest encoding is used. In this
* case, LEN=0 means the body has an indeterminate length and a
* partial body length header (if a new format packet) or an
* indeterminate length header (if an old format packet) is written
* out. Further, if using partial body lengths, this enables partial
* body length mode on OUT.
*/
static int
write_header2( IOBUF out, int ctb, u32 len, int hdrlen )
@ -1320,26 +1446,39 @@ write_header2( IOBUF out, int ctb, u32 len, int hdrlen )
if( ctb & 0x40 )
return write_new_header( out, ctb, len, hdrlen );
/* An old format packet. Refer to RFC 4880, Section 4.2.1 to
understand how lengths are encoded in this case. */
log_assert (hdrlen == 0 || hdrlen == 2 || hdrlen == 3 || hdrlen == 5);
if( hdrlen )
if (hdrlen)
/* Header length is given. */
{
if( hdrlen == 2 && len < 256 )
/* 00 => 1 byte length. */
;
else if( hdrlen == 3 && len < 65536 )
/* 01 => 2 byte length. If len < 256, this is not the most
compact encoding, but it is a correct encoding. */
ctb |= 1;
else
/* 10 => 4 byte length. If len < 65536, this is not the most
compact encoding, but it is a correct encoding. */
ctb |= 2;
}
else
{
if( !len )
/* 11 => Indeterminate length. */
ctb |= 3;
else if( len < 256 )
/* 00 => 1 byte length. */
;
else if( len < 65536 )
/* 01 => 2 byte length. */
ctb |= 1;
else
/* 10 => 4 byte length. */
ctb |= 2;
}
@ -1368,6 +1507,20 @@ write_header2( IOBUF out, int ctb, u32 len, int hdrlen )
}
/* Write a new format header to OUT.
CTB is the ctb.
LEN is the length of the packet's body. If LEN is 0, then enables
partial body length mode (i.e., the body is of an indeterminant
length) on OUT. Note: this function cannot be used to generate a
header for a zero length packet.
HDRLEN is the length of the packet's header. If HDRLEN is 0, the
shortest encoding is chosen based on the length of the packet's
body. Currently, values other than 0 are not supported.
Returns 0 on success. */
static int
write_new_header( IOBUF out, int ctb, u32 len, int hdrlen )
{

View File

@ -79,49 +79,91 @@ 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];
/* RFC 4880: this must be 4. */
byte version;
/* The cipher algorithm used. */
byte cipher_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. */
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;
/* 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 fingerprint of the authorized key. */
byte fpr[MAX_FINGERPRINT_LEN];
};
@ -139,7 +181,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,14 +202,26 @@ 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;
@ -173,7 +231,10 @@ typedef struct
available. See also flags.pka_tried. */
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,14 +253,21 @@ 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. (Serialized.) */
byte *attrib_data;
/* The length of ATTRIB_DATA. */
unsigned long attrib_len;
byte *namehash;
int help_key_usage;
@ -220,9 +288,11 @@ struct gpg_pkt_user_id_s
unsigned int ks_modify:1;
unsigned int compacted:1;
} flags;
/* 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.) */
char name[1];
};
typedef struct gpg_pkt_user_id_s PKT_user_id;
} PKT_user_id;
@ -254,6 +324,14 @@ struct seckey_info
/****************
* The in-memory representation of a public key (RFC 4880, Section
* 5.5). Note: this structure contains significantly more information
* thatn 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,14 +346,22 @@ 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 */
@ -314,9 +400,13 @@ typedef struct
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;
@ -332,20 +422,46 @@ 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, 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. 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
(currently, only DIGEST_ALGO_SHA1 is supported). */
byte mdc_method;
/* An iobuf holding the data to be decrypted. (This is not used for
encryption!) */
iobuf_t buf;
} PKT_encrypted;
typedef struct {
@ -357,15 +473,22 @@ typedef struct {
unsigned int sigcache;
} 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 {
@ -401,18 +524,38 @@ 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. */
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 strored
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 should be deleted. */
unsigned int ignore:1;
} flags;
/* A field to facilitate creating a list of notations. */
struct notation *next;
};

View File

@ -1668,7 +1668,7 @@ enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype,
}
if (reqtype == SIGSUBPKT_TEST_CRITICAL)
/* Returning NULL means we found a subpacket with the critical bit
set that we dn't grok. We've iterated over all the subpackets
set that we don't grok. We've iterated over all the subpackets
and haven't found such a packet so we need to return a non-NULL
value. */
return buffer;