Skip to content

Commit

Permalink
Mark signatures by revoked keys as untrusted
Browse files Browse the repository at this point in the history
RPMRC_NOKEY means that RPM does not have the key at all.  In the case of
a signature by a revoked subkey, RPM *does* have the key; it is just
refusing to trust it.  Therefore, RPMRC_NOTTRUSTED is the correct return
code.  The same is true if a subkey is incapable of signing: RPM has the
key, but is refusing to trust signatures made by it.
  • Loading branch information
DemiMarie committed Apr 22, 2022
1 parent 6f161d7 commit 47faf0c
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 15 deletions.
30 changes: 17 additions & 13 deletions rpmio/rpmpgp_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ struct pgpDigParams_s {
uint8_t signhash16[2];
pgpKeyID_t signid;
uint8_t saved; /*!< Various flags. `PGPDIG_SAVED_*` are never reset.
* `PGPDIG_SIG_HAS_*` are reset for each signature. */
* Others are reset for each signature. */
#define PGPDIG_SAVED_TIME (1 << 0)
#define PGPDIG_SAVED_ID (1 << 1)
#define PGPDIG_SIG_HAS_CREATION_TIME (1 << 2)
#define PGPDIG_SIG_HAS_KEY_FLAGS (1 << 3)
#define PGPDIG_UNTRUSTED (1 << 4)

pgpDigAlg alg;
};
Expand Down Expand Up @@ -947,7 +948,7 @@ static int parseSubkeySig(const struct pgpPkt *pkt, uint8_t tag,
{
/* It isn't safe to ignore this, because it could be a
* revocation of a binding signature or something else that
* should cause the subkey to be ignored. Return an error
* should cause the subkey to be distrusted. Return an error
* here, but log a warning so that users know what is going on. */
rpmlog(RPMLOG_WARNING, _("Unsupported subkey signature type %u\n"),
(unsigned int)params->sigtype);
Expand Down Expand Up @@ -1093,7 +1094,7 @@ int pgpPrtParamsSubkeys(const uint8_t *pkts, size_t pktlen,
continue;
}

int ignore = 0;
int untrusted = 0;
do {
pgpDigParams subkey_sig = NULL;
if (decodePkt(p, pend - p, &pkt) ||
Expand All @@ -1103,26 +1104,25 @@ int pgpPrtParamsSubkeys(const uint8_t *pkts, size_t pktlen,
goto end;
}

/* if this is wrong this will be freed anyway */
digps[count]->saved |= PGPDIG_SIG_HAS_KEY_FLAGS;
digps[count]->key_flags = subkey_sig->key_flags;
if (subkey_sig->saved & PGPDIG_SIG_HAS_KEY_FLAGS) {
digps[count]->saved |= PGPDIG_SIG_HAS_KEY_FLAGS;
digps[count]->key_flags = subkey_sig->key_flags;
}

/* Is the subkey revoked or incapable of signing? */
if (subkey_sig->sigtype != PGPSIGTYPE_SUBKEY_BINDING ||
!((subkey_sig->saved & PGPDIG_SIG_HAS_KEY_FLAGS) &&
(subkey_sig->key_flags & 0x02))) {
ignore = 1;
untrusted = 1;
}
p += (pkt.body - pkt.head) + pkt.blen;
pgpDigParamsFree(subkey_sig);
if (p >= pend || decodePkt(p, pend - p, &pkt))
break; /* next iteration will catch any error */
} while (pkt.tag != PGPTAG_PUBLIC_SUBKEY);
if (ignore) {
pgpDigParamsFree(digps[count]);
} else {
count++;
}
if (untrusted)
digps[count]->saved |= PGPDIG_UNTRUSTED;
count++;
}
}
end:
Expand Down Expand Up @@ -1180,7 +1180,11 @@ rpmRC pgpVerifySignature(pgpDigParams key, pgpDigParams sig, DIGEST_CTX hashctx)
pgpDigAlg ka = key->alg;
if (sa && sa->verify) {
if (sa->verify(ka, sa, hash, hashlen, sig->hash_algo) == 0) {
res = RPMRC_OK;
if ((key->saved & PGPDIG_UNTRUSTED) ||
(sig->saved & PGPDIG_UNTRUSTED))
res = RPMRC_NOTTRUSTED;
else
res = RPMRC_OK;
}
}
} else {
Expand Down
1 change: 1 addition & 0 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ EXTRA_DIST += data/RPMS/hello-1.0-1.ppc64.rpm
EXTRA_DIST += data/RPMS/hello-2.0-1.i686.rpm
EXTRA_DIST += data/RPMS/hello-2.0-1.x86_64.rpm
EXTRA_DIST += data/RPMS/hello-2.0-1.x86_64-signed.rpm
EXTRA_DIST += data/RPMS/hello-2.0-1.x86_64-signed-revoked.rpm
EXTRA_DIST += data/RPMS/hlinktest-1.0-1.noarch.rpm
EXTRA_DIST += data/RPMS/imatest-1.0-1.fc34.noarch.rpm
EXTRA_DIST += data/RPMS/hello-2.0-1.x86_64-corrupted.rpm
Expand Down
Binary file not shown.
66 changes: 64 additions & 2 deletions tests/rpmsigdig.at
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ runroot rpm -qi gpg-pubkey-1964c5fc-58e63918|grep -v Date|grep -v Version:
runroot rpm -q --provides gpg-pubkey-1964c5fc-58e63918
],
[0],
[Name : gpg-pubkey
[[Name : gpg-pubkey
Version : 1964c5fc
Release : 58e63918
Architecture: (none)
Expand Down Expand Up @@ -247,7 +247,9 @@ UNW2iqnN3BA7guhOv6OMiROF1+I7Q5nWT63mQC7IgQ==
gpg(rpm.org RSA testkey <[email protected]>) = 4:4344591e1964c5fc-58e63918
gpg(1964c5fc) = 4:4344591e1964c5fc-58e63918
gpg(4344591e1964c5fc) = 4:4344591e1964c5fc-58e63918
],
gpg(f00650f8) = 4:185e6146f00650f8-58e63918
gpg(185e6146f00650f8) = 4:185e6146f00650f8-58e63918
]],
[])
AT_CLEANUP

Expand Down Expand Up @@ -372,6 +374,10 @@ gpg(a0e0c1c7) = 4:9dd6f039a0e0c1c7-623f5e80
gpg(9dd6f039a0e0c1c7) = 4:9dd6f039a0e0c1c7-623f5e80
gpg(f5757247) = 4:a9ecf25cf5757247-623f5e9e
gpg(a9ecf25cf5757247) = 4:a9ecf25cf5757247-623f5e9e
gpg(7bab107a) = 4:dbf8808f7bab107a-623f5eb6
gpg(dbf8808f7bab107a) = 4:dbf8808f7bab107a-623f5eb6
gpg(63e4b138) = 4:511ed0d463e4b138-623f5f69
gpg(511ed0d463e4b138) = 4:511ed0d463e4b138-623f5f69
]],
[])
AT_CLEANUP
Expand Down Expand Up @@ -450,6 +456,10 @@ gpg(a0e0c1c7) = 4:9dd6f039a0e0c1c7-623f5e80
gpg(9dd6f039a0e0c1c7) = 4:9dd6f039a0e0c1c7-623f5e80
gpg(f5757247) = 4:a9ecf25cf5757247-623f5e9e
gpg(a9ecf25cf5757247) = 4:a9ecf25cf5757247-623f5e9e
gpg(7bab107a) = 4:dbf8808f7bab107a-623f5eb6
gpg(dbf8808f7bab107a) = 4:dbf8808f7bab107a-623f5eb6
gpg(63e4b138) = 4:511ed0d463e4b138-623f5f69
gpg(511ed0d463e4b138) = 4:511ed0d463e4b138-623f5f69
]],
[])
AT_CLEANUP
Expand Down Expand Up @@ -509,6 +519,8 @@ chEM
gpg(Another complex test key <[email protected]>) = 4:d115be9bebddd264-623f8f42
gpg(ebddd264) = 4:d115be9bebddd264-623f8f42
gpg(d115be9bebddd264) = 4:d115be9bebddd264-623f8f42
gpg(6c8ea995) = 4:026746b46c8ea995-623f8f5b
gpg(026746b46c8ea995) = 4:026746b46c8ea995-623f8f5b
gpg(ac1fbf3d) = 4:cb2e24c7ac1fbf3d-623f8fab
gpg(cb2e24c7ac1fbf3d) = 4:cb2e24c7ac1fbf3d-623f8fab
]],)
Expand Down Expand Up @@ -666,6 +678,56 @@ runroot rpmkeys -Kv --nosignature /data/RPMS/hello-2.0-1.x86_64-signed.rpm; echo
[])
AT_CLEANUP

# ------------------------------
# Test pre-built package verification (revoked subkey)
AT_SETUP([rpmkeys -Kv <signed with revoked subkey> 1])
AT_KEYWORDS([rpmkeys digest signature])
AT_CHECK([
RPMDB_INIT

runroot rpmkeys --define '_pkgverify_level all' -Kv /data/RPMS/hello-2.0-1.x86_64-signed-revoked.rpm; echo $?
runroot rpmkeys --import /data/keys/rpm.org-ed25519-subkey-2-test.pub; echo $?
runroot rpmkeys --define '_pkgverify_level all' -Kv /data/RPMS/hello-2.0-1.x86_64-signed-revoked.rpm; echo $?
runroot rpmkeys --define '_pkgverify_level all' -Kv --nodigest /data/RPMS/hello-2.0-1.x86_64-signed-revoked.rpm; echo $?
runroot rpmkeys --define '_pkgverify_level all' -Kv --nosignature /data/RPMS/hello-2.0-1.x86_64-signed-revoked.rpm; echo $?
],
[0],
[[/data/RPMS/hello-2.0-1.x86_64-signed-revoked.rpm:
Header V4 EdDSA/SHA512 Signature, key ID 7bab107a: NOKEY
Header RSA signature: NOTFOUND
Header SHA256 digest: OK
Header SHA1 digest: OK
Payload SHA256 digest: OK
RSA signature: NOTFOUND
DSA signature: NOTFOUND
MD5 digest: OK
1
0
/data/RPMS/hello-2.0-1.x86_64-signed-revoked.rpm:
Header V4 EdDSA/SHA512 Signature, key ID 7bab107a: NOTTRUSTED
Header RSA signature: NOTFOUND
Header SHA256 digest: OK
Header SHA1 digest: OK
Payload SHA256 digest: OK
RSA signature: NOTFOUND
DSA signature: NOTFOUND
MD5 digest: OK
1
/data/RPMS/hello-2.0-1.x86_64-signed-revoked.rpm:
Header V4 EdDSA/SHA512 Signature, key ID 7bab107a: NOTTRUSTED
Header RSA signature: NOTFOUND
RSA signature: NOTFOUND
DSA signature: NOTFOUND
1
/data/RPMS/hello-2.0-1.x86_64-signed-revoked.rpm:
Header SHA256 digest: OK
Header SHA1 digest: OK
Payload SHA256 digest: OK
MD5 digest: OK
0
]],
[])
AT_CLEANUP
# ------------------------------
# Test pre-built corrupted package verification (corrupted signature)
AT_SETUP([rpmkeys -Kv <corrupted signed> 1])
Expand Down

0 comments on commit 47faf0c

Please sign in to comment.