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:
parent
80b775bdbb
commit
5ba74a134d
@ -33,6 +33,7 @@
|
||||
#define IS_KEY_SIG(s) ((s)->sig_class == 0x1f)
|
||||
#define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10)
|
||||
#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_UID_REV(s) ((s)->sig_class == 0x30)
|
||||
#define IS_SUBKEY_REV(s) ((s)->sig_class == 0x28)
|
||||
|
190
g10/sig-check.c
190
g10/sig-check.c
@ -132,7 +132,9 @@ check_signature2 (ctrl_t ctrl,
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
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))
|
||||
{
|
||||
/* Compliance failure. */
|
||||
@ -142,14 +144,15 @@ check_signature2 (ctrl_t ctrl,
|
||||
rc = gpg_error (GPG_ERR_DIGEST_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))
|
||||
{
|
||||
/* 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
|
||||
not match the actual sig, and also if the clearsign "Hash:"
|
||||
header is missing or does not match the actual sig. */
|
||||
|
||||
* sig is expecting. This can happen if a onepass sig header
|
||||
* does not match the actual sig, and also if the clearsign
|
||||
* "Hash:" header is missing or does not match the actual sig. */
|
||||
log_info(_("WARNING: signature digest conflict in message\n"));
|
||||
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);
|
||||
|
||||
/* Check the backsig. This is a 0x19 signature from the
|
||||
subkey on the primary key. The idea here is that it should
|
||||
not be possible for someone to "steal" subkeys and claim
|
||||
them as their own. The attacker couldn't actually use the
|
||||
subkey, but they could try and claim ownership of any
|
||||
signatures issued by it. */
|
||||
/* Check the backsig. This is a back signature (0x19) from
|
||||
* the subkey on the primary key. The idea here is that it
|
||||
* should not be possible for someone to "steal" subkeys and
|
||||
* claim them as their own. The attacker couldn't actually
|
||||
* use the subkey, but they could try and claim ownership of
|
||||
* any signatures issued by it. */
|
||||
if (!rc && !pk->flags.primary && pk->flags.backsig < 2)
|
||||
{
|
||||
if (!pk->flags.backsig)
|
||||
@ -192,9 +195,8 @@ check_signature2 (ctrl_t ctrl,
|
||||
" cross-certified\n"),keystr_from_pk(pk));
|
||||
log_info (_("please see %s for more information\n"),
|
||||
"https://gnupg.org/faq/subkey-cross-certify.html");
|
||||
/* --require-cross-certification makes this warning an
|
||||
error. TODO: change the default to require this
|
||||
after more keys have backsigs. */
|
||||
/* The default option --require-cross-certification
|
||||
* makes this warning an error. */
|
||||
if (opt.flags.require_cross_cert)
|
||||
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
|
||||
* they use a random parameter for every signature. Instead of
|
||||
* 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;
|
||||
if ( d < 86400 )
|
||||
{
|
||||
log_info
|
||||
(ngettext
|
||||
log_info (ngettext
|
||||
("public key %s is %lu second newer than the signature\n",
|
||||
"public key %s is %lu seconds newer than the signature\n",
|
||||
d), keystr_from_pk (pk), d);
|
||||
@ -328,8 +330,7 @@ check_signature_metadata_validity (PKT_public_key *pk, PKT_signature *sig,
|
||||
else
|
||||
{
|
||||
d /= 86400;
|
||||
log_info
|
||||
(ngettext
|
||||
log_info (ngettext
|
||||
("public key %s is %lu day newer than the signature\n",
|
||||
"public key %s is %lu days newer than the signature\n",
|
||||
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
|
||||
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
|
||||
merge has for whatever reasons not been done. */
|
||||
if( pk->has_expired || (pk->expiredate && pk->expiredate < cur_time)) {
|
||||
* 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
|
||||
* merge has for whatever reasons not been done. */
|
||||
if (pk->has_expired || (pk->expiredate && pk->expiredate < cur_time))
|
||||
{
|
||||
char buf[11];
|
||||
if (opt.verbose)
|
||||
log_info (_("Note: signature key %s expired %s\n"),
|
||||
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);
|
||||
if (r_expired)
|
||||
*r_expired = 1;
|
||||
@ -440,9 +442,10 @@ check_signature_end (PKT_public_key *pk, PKT_signature *sig,
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* This function is similar to check_signature_end, but it only checks
|
||||
whether the signature was generated by PK. It does not check
|
||||
expiration, revocation, etc. */
|
||||
* whether the signature was generated by PK. It does not check
|
||||
* expiration, revocation, etc. */
|
||||
static int
|
||||
check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig,
|
||||
gcry_md_hd_t digest)
|
||||
@ -452,48 +455,55 @@ check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig,
|
||||
const struct weakhash *weak;
|
||||
|
||||
if (!opt.flags.allow_weak_digest_algos)
|
||||
{
|
||||
for (weak = opt.weak_digests; weak; weak = weak->next)
|
||||
if (sig->digest_algo == weak->algo)
|
||||
{
|
||||
print_digest_rejected_note(sig->digest_algo);
|
||||
return GPG_ERR_DIGEST_ALGO;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure the digest algo is enabled (in case of a detached
|
||||
signature). */
|
||||
* signature). */
|
||||
gcry_md_enable (digest, sig->digest_algo);
|
||||
|
||||
/* Complete the digest. */
|
||||
if (sig->version >= 4)
|
||||
gcry_md_putc (digest, sig->version);
|
||||
|
||||
gcry_md_putc( digest, sig->sig_class );
|
||||
if( sig->version < 4 ) {
|
||||
if (sig->version < 4)
|
||||
{
|
||||
u32 a = sig->timestamp;
|
||||
gcry_md_putc( digest, (a >> 24) & 0xff );
|
||||
gcry_md_putc( digest, (a >> 16) & 0xff );
|
||||
gcry_md_putc( digest, (a >> 8) & 0xff );
|
||||
gcry_md_putc( digest, a & 0xff );
|
||||
gcry_md_putc (digest, ((a >> 24) & 0xff));
|
||||
gcry_md_putc (digest, ((a >> 16) & 0xff));
|
||||
gcry_md_putc (digest, ((a >> 8) & 0xff));
|
||||
gcry_md_putc (digest, ( a & 0xff));
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
byte buf[6];
|
||||
size_t n;
|
||||
gcry_md_putc (digest, sig->pubkey_algo);
|
||||
gcry_md_putc (digest, sig->digest_algo);
|
||||
if( sig->hashed ) {
|
||||
if (sig->hashed)
|
||||
{
|
||||
n = sig->hashed->len;
|
||||
gcry_md_putc (digest, (n >> 8) );
|
||||
gcry_md_putc (digest, n );
|
||||
gcry_md_write (digest, sig->hashed->data, n);
|
||||
n += 6;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
/* Two octets for the (empty) length of the hashed
|
||||
section. */
|
||||
* section. */
|
||||
gcry_md_putc (digest, 0);
|
||||
gcry_md_putc (digest, 0);
|
||||
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[1] = 0xff;
|
||||
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
|
||||
of RFC 4880. */
|
||||
* of RFC 4880. */
|
||||
static void
|
||||
hash_uid_packet (PKT_user_id *uid, gcry_md_hd_t md, PKT_signature *sig )
|
||||
{
|
||||
if( uid->attrib_data ) {
|
||||
if( sig->version >=4 ) {
|
||||
if (uid->attrib_data)
|
||||
{
|
||||
if (sig->version >=4)
|
||||
{
|
||||
byte buf[5];
|
||||
buf[0] = 0xd1; /* packet of type 17 */
|
||||
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 );
|
||||
}
|
||||
else {
|
||||
if( sig->version >=4 ) {
|
||||
else
|
||||
{
|
||||
if (sig->version >=4)
|
||||
{
|
||||
byte buf[5];
|
||||
buf[0] = 0xb4; /* indicates a userid packet */
|
||||
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
|
||||
cache_sig_result ( PKT_signature *sig, int result )
|
||||
{
|
||||
if ( !result ) {
|
||||
if (!result)
|
||||
{
|
||||
sig->flags.checked = 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.valid = 0;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
sig->flags.checked = 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
|
||||
primary key MAIN_PK is valid.
|
||||
|
||||
Backsigs (0x19) have the same format as binding sigs (0x18), but
|
||||
this function is simpler than check_key_signature in a few ways.
|
||||
For example, there is no support for expiring backsigs since it is
|
||||
questionable what such a thing actually means. Note also that the
|
||||
sig cache check here, unlike other sig caches in GnuPG, is not
|
||||
persistent. */
|
||||
* primary key MAIN_PK is valid.
|
||||
*
|
||||
* Backsigs (0x19) have the same format as binding sigs (0x18), but
|
||||
* this function is simpler than check_key_signature in a few ways.
|
||||
* For example, there is no support for expiring backsigs since it is
|
||||
* questionable what such a thing actually means. Note also that the
|
||||
* sig cache check here, unlike other sig caches in GnuPG, is not
|
||||
* persistent. */
|
||||
int
|
||||
check_backsig (PKT_public_key *main_pk,PKT_public_key *sub_pk,
|
||||
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
|
||||
signs. */
|
||||
if (/* Primary key binding (made by a subkey). */
|
||||
sig->sig_class == 0x19
|
||||
/* Direct key signature. */
|
||||
|| sig->sig_class == 0x1f
|
||||
/* Primary key revocation. */
|
||||
|| sig->sig_class == 0x20)
|
||||
if (IS_BACK_SIG (sig) || IS_KEY_SIG (sig) || IS_KEY_REV (sig))
|
||||
{
|
||||
/* Key revocations can only be over primary keys. */
|
||||
if (packet->pkttype != PKT_PUBLIC_KEY)
|
||||
return gpg_error (GPG_ERR_SIG_CLASS);
|
||||
}
|
||||
else if (/* Subkey binding. */
|
||||
sig->sig_class == 0x18
|
||||
/* Subkey revocation. */
|
||||
|| sig->sig_class == 0x28)
|
||||
else if (IS_SUBKEY_SIG (sig) || IS_SUBKEY_REV (sig))
|
||||
{
|
||||
if (packet->pkttype != PKT_PUBLIC_SUBKEY)
|
||||
return gpg_error (GPG_ERR_SIG_CLASS);
|
||||
}
|
||||
else if (/* Certification. */
|
||||
sig->sig_class == 0x10
|
||||
|| sig->sig_class == 0x11
|
||||
|| sig->sig_class == 0x12
|
||||
|| sig->sig_class == 0x13
|
||||
/* Certification revocation. */
|
||||
|| sig->sig_class == 0x30)
|
||||
else if (IS_UID_SIG (sig) || IS_UID_REV (sig))
|
||||
{
|
||||
if (packet->pkttype != PKT_USER_ID)
|
||||
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
|
||||
{
|
||||
/* See if one of the subkeys was the signer (although this
|
||||
is extremely unlikely). */
|
||||
* is extremely unlikely). */
|
||||
kbnode_t ctx = NULL;
|
||||
kbnode_t n;
|
||||
|
||||
@ -909,40 +912,27 @@ check_signature_over_key_or_uid (ctrl_t ctrl, PKT_public_key *signer,
|
||||
|
||||
/* Hash the relevant data. */
|
||||
|
||||
if (/* Direct key signature. */
|
||||
sig->sig_class == 0x1f
|
||||
/* Primary key revocation. */
|
||||
|| sig->sig_class == 0x20)
|
||||
if (IS_KEY_SIG (sig) || IS_KEY_REV (sig))
|
||||
{
|
||||
log_assert (packet->pkttype == PKT_PUBLIC_KEY);
|
||||
hash_public_key (md, packet->pkt.public_key);
|
||||
rc = check_signature_end_simple (signer, sig, md);
|
||||
}
|
||||
else if (/* Primary key binding (made by a subkey). */
|
||||
sig->sig_class == 0x19)
|
||||
else if (IS_BACK_SIG (sig))
|
||||
{
|
||||
log_assert (packet->pkttype == PKT_PUBLIC_KEY);
|
||||
hash_public_key (md, packet->pkt.public_key);
|
||||
hash_public_key (md, signer);
|
||||
rc = check_signature_end_simple (signer, sig, md);
|
||||
}
|
||||
else if (/* Subkey binding. */
|
||||
sig->sig_class == 0x18
|
||||
/* Subkey revocation. */
|
||||
|| sig->sig_class == 0x28)
|
||||
else if (IS_SUBKEY_SIG (sig) || IS_SUBKEY_REV (sig))
|
||||
{
|
||||
log_assert (packet->pkttype == PKT_PUBLIC_SUBKEY);
|
||||
hash_public_key (md, pripk);
|
||||
hash_public_key (md, packet->pkt.public_key);
|
||||
rc = check_signature_end_simple (signer, sig, md);
|
||||
}
|
||||
else if (/* Certification. */
|
||||
sig->sig_class == 0x10
|
||||
|| sig->sig_class == 0x11
|
||||
|| sig->sig_class == 0x12
|
||||
|| sig->sig_class == 0x13
|
||||
/* Certification revocation. */
|
||||
|| sig->sig_class == 0x30)
|
||||
else if (IS_UID_SIG (sig) || IS_UID_REV (sig))
|
||||
{
|
||||
log_assert (packet->pkttype == PKT_USER_ID);
|
||||
hash_public_key (md, pripk);
|
||||
@ -1073,7 +1063,7 @@ check_key_signature2 (ctrl_t ctrl,
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (sig->sig_class == 0x20) /* key revocation */
|
||||
if (IS_KEY_REV (sig))
|
||||
{
|
||||
u32 keyid[2];
|
||||
keyid_from_pk( pk, keyid );
|
||||
@ -1091,8 +1081,7 @@ check_key_signature2 (ctrl_t ctrl,
|
||||
is_selfsig, ret_pk);
|
||||
}
|
||||
}
|
||||
else if (sig->sig_class == 0x28 /* subkey revocation */
|
||||
|| sig->sig_class == 0x18) /* key binding */
|
||||
else if (IS_SUBKEY_REV (sig) || IS_SUBKEY_SIG (sig))
|
||||
{
|
||||
kbnode_t snode = find_prev_kbnode (root, node, PKT_PUBLIC_SUBKEY);
|
||||
|
||||
@ -1102,9 +1091,10 @@ check_key_signature2 (ctrl_t ctrl,
|
||||
r_expired, NULL);
|
||||
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,
|
||||
sig->sig_class == 0x18
|
||||
IS_SUBKEY_SIG (sig)
|
||||
? NULL : pk,
|
||||
sig, root, snode->pkt,
|
||||
is_selfsig, ret_pk);
|
||||
@ -1114,7 +1104,7 @@ check_key_signature2 (ctrl_t ctrl,
|
||||
{
|
||||
if (opt.verbose)
|
||||
{
|
||||
if (sig->sig_class == 0x28)
|
||||
if (IS_SUBKEY_REV (sig))
|
||||
log_info (_("key %s: no subkey for subkey"
|
||||
" revocation signature\n"), keystr_from_pk(pk));
|
||||
else if (sig->sig_class == 0x18)
|
||||
@ -1124,7 +1114,7 @@ check_key_signature2 (ctrl_t ctrl,
|
||||
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,
|
||||
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,
|
||||
is_selfsig, ret_pk);
|
||||
}
|
||||
else if (/* Certification. */
|
||||
sig->sig_class == 0x10
|
||||
|| sig->sig_class == 0x11
|
||||
|| sig->sig_class == 0x12
|
||||
|| sig->sig_class == 0x13
|
||||
/* Certification revocation. */
|
||||
|| sig->sig_class == 0x30)
|
||||
else if (IS_UID_SIG (sig) || IS_UID_REV (sig))
|
||||
{
|
||||
kbnode_t unode = find_prev_kbnode (root, node, PKT_USER_ID);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user