1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-04-13 22:21:09 +02:00

gpg: Re-indent sig-check.c and use signature class macros.

* g10/keydb.h (IS_BACK_SIG): New.
* g10/sig-check.c: Re-indent and use macros.
--

This makes the code easier to understand.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2018-04-06 10:18:53 +02:00
parent 80b775bdbb
commit 5ba74a134d
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
2 changed files with 375 additions and 390 deletions

View File

@ -33,6 +33,7 @@
#define IS_KEY_SIG(s) ((s)->sig_class == 0x1f) #define IS_KEY_SIG(s) ((s)->sig_class == 0x1f)
#define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10) #define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10)
#define IS_SUBKEY_SIG(s) ((s)->sig_class == 0x18) #define IS_SUBKEY_SIG(s) ((s)->sig_class == 0x18)
#define IS_BACK_SIG(s) ((s)->sig_class == 0x19)
#define IS_KEY_REV(s) ((s)->sig_class == 0x20) #define IS_KEY_REV(s) ((s)->sig_class == 0x20)
#define IS_UID_REV(s) ((s)->sig_class == 0x30) #define IS_UID_REV(s) ((s)->sig_class == 0x30)
#define IS_SUBKEY_REV(s) ((s)->sig_class == 0x28) #define IS_SUBKEY_REV(s) ((s)->sig_class == 0x28)

View File

@ -132,7 +132,9 @@ check_signature2 (ctrl_t ctrl,
return gpg_error_from_syserror (); return gpg_error_from_syserror ();
if ((rc=openpgp_md_test_algo(sig->digest_algo))) if ((rc=openpgp_md_test_algo(sig->digest_algo)))
; /* We don't have this digest. */ {
/* We don't have this digest. */
}
else if (!gnupg_digest_is_allowed (opt.compliance, 0, sig->digest_algo)) else if (!gnupg_digest_is_allowed (opt.compliance, 0, sig->digest_algo))
{ {
/* Compliance failure. */ /* Compliance failure. */
@ -142,14 +144,15 @@ check_signature2 (ctrl_t ctrl,
rc = gpg_error (GPG_ERR_DIGEST_ALGO); rc = gpg_error (GPG_ERR_DIGEST_ALGO);
} }
else if ((rc=openpgp_pk_test_algo(sig->pubkey_algo))) else if ((rc=openpgp_pk_test_algo(sig->pubkey_algo)))
; /* We don't have this pubkey algo. */ {
/* We don't have this pubkey algo. */
}
else if (!gcry_md_is_enabled (digest,sig->digest_algo)) else if (!gcry_md_is_enabled (digest,sig->digest_algo))
{ {
/* Sanity check that the md has a context for the hash that the /* Sanity check that the md has a context for the hash that the
sig is expecting. This can happen if a onepass sig header does * sig is expecting. This can happen if a onepass sig header
not match the actual sig, and also if the clearsign "Hash:" * does not match the actual sig, and also if the clearsign
header is missing or does not match the actual sig. */ * "Hash:" header is missing or does not match the actual sig. */
log_info(_("WARNING: signature digest conflict in message\n")); log_info(_("WARNING: signature digest conflict in message\n"));
rc = gpg_error (GPG_ERR_GENERAL); rc = gpg_error (GPG_ERR_GENERAL);
} }
@ -178,12 +181,12 @@ check_signature2 (ctrl_t ctrl,
rc = check_signature_end (pk, sig, digest, r_expired, r_revoked, NULL); rc = check_signature_end (pk, sig, digest, r_expired, r_revoked, NULL);
/* Check the backsig. This is a 0x19 signature from the /* Check the backsig. This is a back signature (0x19) from
subkey on the primary key. The idea here is that it should * the subkey on the primary key. The idea here is that it
not be possible for someone to "steal" subkeys and claim * should not be possible for someone to "steal" subkeys and
them as their own. The attacker couldn't actually use the * claim them as their own. The attacker couldn't actually
subkey, but they could try and claim ownership of any * use the subkey, but they could try and claim ownership of
signatures issued by it. */ * any signatures issued by it. */
if (!rc && !pk->flags.primary && pk->flags.backsig < 2) if (!rc && !pk->flags.primary && pk->flags.backsig < 2)
{ {
if (!pk->flags.backsig) if (!pk->flags.backsig)
@ -192,9 +195,8 @@ check_signature2 (ctrl_t ctrl,
" cross-certified\n"),keystr_from_pk(pk)); " cross-certified\n"),keystr_from_pk(pk));
log_info (_("please see %s for more information\n"), log_info (_("please see %s for more information\n"),
"https://gnupg.org/faq/subkey-cross-certify.html"); "https://gnupg.org/faq/subkey-cross-certify.html");
/* --require-cross-certification makes this warning an /* The default option --require-cross-certification
error. TODO: change the default to require this * makes this warning an error. */
after more keys have backsigs. */
if (opt.flags.require_cross_cert) if (opt.flags.require_cross_cert)
rc = gpg_error (GPG_ERR_GENERAL); rc = gpg_error (GPG_ERR_GENERAL);
} }
@ -208,7 +210,8 @@ check_signature2 (ctrl_t ctrl,
} }
if( !rc && sig->sig_class < 2 && is_status_enabled() ) { if (!rc && sig->sig_class < 2 && is_status_enabled ())
{
/* This signature id works best with DLP algorithms because /* This signature id works best with DLP algorithms because
* they use a random parameter for every signature. Instead of * they use a random parameter for every signature. Instead of
* this sig-id we could have also used the hash of the document * this sig-id we could have also used the hash of the document
@ -319,8 +322,7 @@ check_signature_metadata_validity (PKT_public_key *pk, PKT_signature *sig,
ulong d = pk->timestamp - sig->timestamp; ulong d = pk->timestamp - sig->timestamp;
if ( d < 86400 ) if ( d < 86400 )
{ {
log_info log_info (ngettext
(ngettext
("public key %s is %lu second newer than the signature\n", ("public key %s is %lu second newer than the signature\n",
"public key %s is %lu seconds newer than the signature\n", "public key %s is %lu seconds newer than the signature\n",
d), keystr_from_pk (pk), d); d), keystr_from_pk (pk), d);
@ -328,8 +330,7 @@ check_signature_metadata_validity (PKT_public_key *pk, PKT_signature *sig,
else else
{ {
d /= 86400; d /= 86400;
log_info log_info (ngettext
(ngettext
("public key %s is %lu day newer than the signature\n", ("public key %s is %lu day newer than the signature\n",
"public key %s is %lu days newer than the signature\n", "public key %s is %lu days newer than the signature\n",
d), keystr_from_pk (pk), d); d), keystr_from_pk (pk), d);
@ -364,15 +365,16 @@ check_signature_metadata_validity (PKT_public_key *pk, PKT_signature *sig,
} }
/* Check whether the key has expired. We check the has_expired /* Check whether the key has expired. We check the has_expired
flag which is set after a full evaluation of the key (getkey.c) * flag which is set after a full evaluation of the key (getkey.c)
as well as a simple compare to the current time in case the * as well as a simple compare to the current time in case the
merge has for whatever reasons not been done. */ * merge has for whatever reasons not been done. */
if( pk->has_expired || (pk->expiredate && pk->expiredate < cur_time)) { if (pk->has_expired || (pk->expiredate && pk->expiredate < cur_time))
{
char buf[11]; char buf[11];
if (opt.verbose) if (opt.verbose)
log_info (_("Note: signature key %s expired %s\n"), log_info (_("Note: signature key %s expired %s\n"),
keystr_from_pk(pk), asctimestamp( pk->expiredate ) ); keystr_from_pk(pk), asctimestamp( pk->expiredate ) );
sprintf(buf,"%lu",(ulong)pk->expiredate); snprintf (buf, sizeof buf, "%lu",(ulong)pk->expiredate);
write_status_text (STATUS_KEYEXPIRED, buf); write_status_text (STATUS_KEYEXPIRED, buf);
if (r_expired) if (r_expired)
*r_expired = 1; *r_expired = 1;
@ -440,9 +442,10 @@ check_signature_end (PKT_public_key *pk, PKT_signature *sig,
return rc; return rc;
} }
/* This function is similar to check_signature_end, but it only checks /* This function is similar to check_signature_end, but it only checks
whether the signature was generated by PK. It does not check * whether the signature was generated by PK. It does not check
expiration, revocation, etc. */ * expiration, revocation, etc. */
static int static int
check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig, check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig,
gcry_md_hd_t digest) gcry_md_hd_t digest)
@ -452,48 +455,55 @@ check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig,
const struct weakhash *weak; const struct weakhash *weak;
if (!opt.flags.allow_weak_digest_algos) if (!opt.flags.allow_weak_digest_algos)
{
for (weak = opt.weak_digests; weak; weak = weak->next) for (weak = opt.weak_digests; weak; weak = weak->next)
if (sig->digest_algo == weak->algo) if (sig->digest_algo == weak->algo)
{ {
print_digest_rejected_note(sig->digest_algo); print_digest_rejected_note(sig->digest_algo);
return GPG_ERR_DIGEST_ALGO; return GPG_ERR_DIGEST_ALGO;
} }
}
/* Make sure the digest algo is enabled (in case of a detached /* Make sure the digest algo is enabled (in case of a detached
signature). */ * signature). */
gcry_md_enable (digest, sig->digest_algo); gcry_md_enable (digest, sig->digest_algo);
/* Complete the digest. */ /* Complete the digest. */
if (sig->version >= 4) if (sig->version >= 4)
gcry_md_putc (digest, sig->version); gcry_md_putc (digest, sig->version);
gcry_md_putc( digest, sig->sig_class ); gcry_md_putc( digest, sig->sig_class );
if( sig->version < 4 ) { if (sig->version < 4)
{
u32 a = sig->timestamp; u32 a = sig->timestamp;
gcry_md_putc( digest, (a >> 24) & 0xff ); gcry_md_putc (digest, ((a >> 24) & 0xff));
gcry_md_putc( digest, (a >> 16) & 0xff ); gcry_md_putc (digest, ((a >> 16) & 0xff));
gcry_md_putc( digest, (a >> 8) & 0xff ); gcry_md_putc (digest, ((a >> 8) & 0xff));
gcry_md_putc( digest, a & 0xff ); gcry_md_putc (digest, ( a & 0xff));
} }
else { else
{
byte buf[6]; byte buf[6];
size_t n; size_t n;
gcry_md_putc (digest, sig->pubkey_algo); gcry_md_putc (digest, sig->pubkey_algo);
gcry_md_putc (digest, sig->digest_algo); gcry_md_putc (digest, sig->digest_algo);
if( sig->hashed ) { if (sig->hashed)
{
n = sig->hashed->len; n = sig->hashed->len;
gcry_md_putc (digest, (n >> 8) ); gcry_md_putc (digest, (n >> 8) );
gcry_md_putc (digest, n ); gcry_md_putc (digest, n );
gcry_md_write (digest, sig->hashed->data, n); gcry_md_write (digest, sig->hashed->data, n);
n += 6; n += 6;
} }
else { else
{
/* Two octets for the (empty) length of the hashed /* Two octets for the (empty) length of the hashed
section. */ * section. */
gcry_md_putc (digest, 0); gcry_md_putc (digest, 0);
gcry_md_putc (digest, 0); gcry_md_putc (digest, 0);
n = 6; n = 6;
} }
/* add some magic per Section 5.2.4 of RFC 4880. */ /* Add some magic per Section 5.2.4 of RFC 4880. */
buf[0] = sig->version; buf[0] = sig->version;
buf[1] = 0xff; buf[1] = 0xff;
buf[2] = n >> 24; buf[2] = n >> 24;
@ -525,12 +535,14 @@ check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig,
/* Add a uid node to a hash context. See section 5.2.4, paragraph 4 /* Add a uid node to a hash context. See section 5.2.4, paragraph 4
of RFC 4880. */ * of RFC 4880. */
static void static void
hash_uid_packet (PKT_user_id *uid, gcry_md_hd_t md, PKT_signature *sig ) hash_uid_packet (PKT_user_id *uid, gcry_md_hd_t md, PKT_signature *sig )
{ {
if( uid->attrib_data ) { if (uid->attrib_data)
if( sig->version >=4 ) { {
if (sig->version >=4)
{
byte buf[5]; byte buf[5];
buf[0] = 0xd1; /* packet of type 17 */ buf[0] = 0xd1; /* packet of type 17 */
buf[1] = uid->attrib_len >> 24; /* always use 4 length bytes */ buf[1] = uid->attrib_len >> 24; /* always use 4 length bytes */
@ -541,8 +553,10 @@ hash_uid_packet (PKT_user_id *uid, gcry_md_hd_t md, PKT_signature *sig )
} }
gcry_md_write( md, uid->attrib_data, uid->attrib_len ); gcry_md_write( md, uid->attrib_data, uid->attrib_len );
} }
else { else
if( sig->version >=4 ) { {
if (sig->version >=4)
{
byte buf[5]; byte buf[5];
buf[0] = 0xb4; /* indicates a userid packet */ buf[0] = 0xb4; /* indicates a userid packet */
buf[1] = uid->len >> 24; /* always use 4 length bytes */ buf[1] = uid->len >> 24; /* always use 4 length bytes */
@ -558,15 +572,18 @@ hash_uid_packet (PKT_user_id *uid, gcry_md_hd_t md, PKT_signature *sig )
static void static void
cache_sig_result ( PKT_signature *sig, int result ) cache_sig_result ( PKT_signature *sig, int result )
{ {
if ( !result ) { if (!result)
{
sig->flags.checked = 1; sig->flags.checked = 1;
sig->flags.valid = 1; sig->flags.valid = 1;
} }
else if ( gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE ) { else if (gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE)
{
sig->flags.checked = 1; sig->flags.checked = 1;
sig->flags.valid = 0; sig->flags.valid = 0;
} }
else { else
{
sig->flags.checked = 0; sig->flags.checked = 0;
sig->flags.valid = 0; sig->flags.valid = 0;
} }
@ -686,14 +703,14 @@ check_revocation_keys (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig)
} }
/* Check that the backsig BACKSIG from the subkey SUB_PK to its /* Check that the backsig BACKSIG from the subkey SUB_PK to its
primary key MAIN_PK is valid. * primary key MAIN_PK is valid.
*
Backsigs (0x19) have the same format as binding sigs (0x18), but * Backsigs (0x19) have the same format as binding sigs (0x18), but
this function is simpler than check_key_signature in a few ways. * this function is simpler than check_key_signature in a few ways.
For example, there is no support for expiring backsigs since it is * For example, there is no support for expiring backsigs since it is
questionable what such a thing actually means. Note also that the * questionable what such a thing actually means. Note also that the
sig cache check here, unlike other sig caches in GnuPG, is not * sig cache check here, unlike other sig caches in GnuPG, is not
persistent. */ * persistent. */
int int
check_backsig (PKT_public_key *main_pk,PKT_public_key *sub_pk, check_backsig (PKT_public_key *main_pk,PKT_public_key *sub_pk,
PKT_signature *backsig) PKT_signature *backsig)
@ -789,32 +806,18 @@ check_signature_over_key_or_uid (ctrl_t ctrl, PKT_public_key *signer,
/* A signature's class indicates the type of packet that it /* A signature's class indicates the type of packet that it
signs. */ signs. */
if (/* Primary key binding (made by a subkey). */ if (IS_BACK_SIG (sig) || IS_KEY_SIG (sig) || IS_KEY_REV (sig))
sig->sig_class == 0x19
/* Direct key signature. */
|| sig->sig_class == 0x1f
/* Primary key revocation. */
|| sig->sig_class == 0x20)
{ {
/* Key revocations can only be over primary keys. */ /* Key revocations can only be over primary keys. */
if (packet->pkttype != PKT_PUBLIC_KEY) if (packet->pkttype != PKT_PUBLIC_KEY)
return gpg_error (GPG_ERR_SIG_CLASS); return gpg_error (GPG_ERR_SIG_CLASS);
} }
else if (/* Subkey binding. */ else if (IS_SUBKEY_SIG (sig) || IS_SUBKEY_REV (sig))
sig->sig_class == 0x18
/* Subkey revocation. */
|| sig->sig_class == 0x28)
{ {
if (packet->pkttype != PKT_PUBLIC_SUBKEY) if (packet->pkttype != PKT_PUBLIC_SUBKEY)
return gpg_error (GPG_ERR_SIG_CLASS); return gpg_error (GPG_ERR_SIG_CLASS);
} }
else if (/* Certification. */ else if (IS_UID_SIG (sig) || IS_UID_REV (sig))
sig->sig_class == 0x10
|| sig->sig_class == 0x11
|| sig->sig_class == 0x12
|| sig->sig_class == 0x13
/* Certification revocation. */
|| sig->sig_class == 0x30)
{ {
if (packet->pkttype != PKT_USER_ID) if (packet->pkttype != PKT_USER_ID)
return gpg_error (GPG_ERR_SIG_CLASS); return gpg_error (GPG_ERR_SIG_CLASS);
@ -849,7 +852,7 @@ check_signature_over_key_or_uid (ctrl_t ctrl, PKT_public_key *signer,
else else
{ {
/* See if one of the subkeys was the signer (although this /* See if one of the subkeys was the signer (although this
is extremely unlikely). */ * is extremely unlikely). */
kbnode_t ctx = NULL; kbnode_t ctx = NULL;
kbnode_t n; kbnode_t n;
@ -909,40 +912,27 @@ check_signature_over_key_or_uid (ctrl_t ctrl, PKT_public_key *signer,
/* Hash the relevant data. */ /* Hash the relevant data. */
if (/* Direct key signature. */ if (IS_KEY_SIG (sig) || IS_KEY_REV (sig))
sig->sig_class == 0x1f
/* Primary key revocation. */
|| sig->sig_class == 0x20)
{ {
log_assert (packet->pkttype == PKT_PUBLIC_KEY); log_assert (packet->pkttype == PKT_PUBLIC_KEY);
hash_public_key (md, packet->pkt.public_key); hash_public_key (md, packet->pkt.public_key);
rc = check_signature_end_simple (signer, sig, md); rc = check_signature_end_simple (signer, sig, md);
} }
else if (/* Primary key binding (made by a subkey). */ else if (IS_BACK_SIG (sig))
sig->sig_class == 0x19)
{ {
log_assert (packet->pkttype == PKT_PUBLIC_KEY); log_assert (packet->pkttype == PKT_PUBLIC_KEY);
hash_public_key (md, packet->pkt.public_key); hash_public_key (md, packet->pkt.public_key);
hash_public_key (md, signer); hash_public_key (md, signer);
rc = check_signature_end_simple (signer, sig, md); rc = check_signature_end_simple (signer, sig, md);
} }
else if (/* Subkey binding. */ else if (IS_SUBKEY_SIG (sig) || IS_SUBKEY_REV (sig))
sig->sig_class == 0x18
/* Subkey revocation. */
|| sig->sig_class == 0x28)
{ {
log_assert (packet->pkttype == PKT_PUBLIC_SUBKEY); log_assert (packet->pkttype == PKT_PUBLIC_SUBKEY);
hash_public_key (md, pripk); hash_public_key (md, pripk);
hash_public_key (md, packet->pkt.public_key); hash_public_key (md, packet->pkt.public_key);
rc = check_signature_end_simple (signer, sig, md); rc = check_signature_end_simple (signer, sig, md);
} }
else if (/* Certification. */ else if (IS_UID_SIG (sig) || IS_UID_REV (sig))
sig->sig_class == 0x10
|| sig->sig_class == 0x11
|| sig->sig_class == 0x12
|| sig->sig_class == 0x13
/* Certification revocation. */
|| sig->sig_class == 0x30)
{ {
log_assert (packet->pkttype == PKT_USER_ID); log_assert (packet->pkttype == PKT_USER_ID);
hash_public_key (md, pripk); hash_public_key (md, pripk);
@ -1073,7 +1063,7 @@ check_key_signature2 (ctrl_t ctrl,
if (rc) if (rc)
return rc; return rc;
if (sig->sig_class == 0x20) /* key revocation */ if (IS_KEY_REV (sig))
{ {
u32 keyid[2]; u32 keyid[2];
keyid_from_pk( pk, keyid ); keyid_from_pk( pk, keyid );
@ -1091,8 +1081,7 @@ check_key_signature2 (ctrl_t ctrl,
is_selfsig, ret_pk); is_selfsig, ret_pk);
} }
} }
else if (sig->sig_class == 0x28 /* subkey revocation */ else if (IS_SUBKEY_REV (sig) || IS_SUBKEY_SIG (sig))
|| sig->sig_class == 0x18) /* key binding */
{ {
kbnode_t snode = find_prev_kbnode (root, node, PKT_PUBLIC_SUBKEY); kbnode_t snode = find_prev_kbnode (root, node, PKT_PUBLIC_SUBKEY);
@ -1102,9 +1091,10 @@ check_key_signature2 (ctrl_t ctrl,
r_expired, NULL); r_expired, NULL);
if (! rc) if (! rc)
{ {
/* 0x28 must be a self-sig, but 0x18 needn't be. */ /* A subkey revocation (0x28) must be a self-sig, but a
* subkey signature (0x18) needn't be. */
rc = check_signature_over_key_or_uid (ctrl, rc = check_signature_over_key_or_uid (ctrl,
sig->sig_class == 0x18 IS_SUBKEY_SIG (sig)
? NULL : pk, ? NULL : pk,
sig, root, snode->pkt, sig, root, snode->pkt,
is_selfsig, ret_pk); is_selfsig, ret_pk);
@ -1114,7 +1104,7 @@ check_key_signature2 (ctrl_t ctrl,
{ {
if (opt.verbose) if (opt.verbose)
{ {
if (sig->sig_class == 0x28) if (IS_SUBKEY_REV (sig))
log_info (_("key %s: no subkey for subkey" log_info (_("key %s: no subkey for subkey"
" revocation signature\n"), keystr_from_pk(pk)); " revocation signature\n"), keystr_from_pk(pk));
else if (sig->sig_class == 0x18) else if (sig->sig_class == 0x18)
@ -1124,7 +1114,7 @@ check_key_signature2 (ctrl_t ctrl,
rc = GPG_ERR_SIG_CLASS; rc = GPG_ERR_SIG_CLASS;
} }
} }
else if (sig->sig_class == 0x1f) /* direct key signature */ else if (IS_KEY_SIG (sig)) /* direct key signature */
{ {
rc = check_signature_metadata_validity (pk, sig, rc = check_signature_metadata_validity (pk, sig,
r_expired, NULL); r_expired, NULL);
@ -1132,13 +1122,7 @@ check_key_signature2 (ctrl_t ctrl,
rc = check_signature_over_key_or_uid (ctrl, pk, sig, root, root->pkt, rc = check_signature_over_key_or_uid (ctrl, pk, sig, root, root->pkt,
is_selfsig, ret_pk); is_selfsig, ret_pk);
} }
else if (/* Certification. */ else if (IS_UID_SIG (sig) || IS_UID_REV (sig))
sig->sig_class == 0x10
|| sig->sig_class == 0x11
|| sig->sig_class == 0x12
|| sig->sig_class == 0x13
/* Certification revocation. */
|| sig->sig_class == 0x30)
{ {
kbnode_t unode = find_prev_kbnode (root, node, PKT_USER_ID); kbnode_t unode = find_prev_kbnode (root, node, PKT_USER_ID);