summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDemi Marie Obenour <demi@invisiblethingslab.com>2022-03-27 12:07:34 -0400
committerPanu Matilainen <pmatilai@redhat.com>2022-03-31 09:52:50 +0300
commit598a771d8b4f4f480d4990ccf59b978d537201dd (patch)
treec9c2a6d8f8f4a87a0a85979eb7ba092be230eb61
parent55849d2d6e16096dbd30fd3a5c751f13bb03484b (diff)
downloadrpm-598a771d8b4f4f480d4990ccf59b978d537201dd.tar.gz
Parse key usage flags
RPM needs to know if a subkey can be used for signing. Signatures made by a subkey that cannot be used for signing are invalid. Add a key_flags member to pgpDigParams_s to store this information, and a PGPDIG_SIG_HAS_KEY_FLAGS flag to indicate that it is valid. The key usage flags are reset for every signature. Key usage flags in the unhashed section are ignored. If there is more than one key usage flags subpacket in the hashed section, the signature is rejected.
-rw-r--r--rpmio/digest.h2
-rw-r--r--rpmio/rpmpgp.c13
2 files changed, 14 insertions, 1 deletions
diff --git a/rpmio/digest.h b/rpmio/digest.h
index ec7f3392f..6a326d20e 100644
--- a/rpmio/digest.h
+++ b/rpmio/digest.h
@@ -27,6 +27,7 @@ struct pgpDigParams_s {
uint8_t * hash;
uint8_t tag;
+ uint8_t key_flags; /*!< key usage flags */
uint8_t version; /*!< version number. */
uint32_t time; /*!< key/signature creation time. */
uint8_t pubkey_algo; /*!< public key algorithm. */
@@ -41,6 +42,7 @@ struct pgpDigParams_s {
#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)
pgpDigAlg alg;
};
diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c
index 9b8503e27..66837b18f 100644
--- a/rpmio/rpmpgp.c
+++ b/rpmio/rpmpgp.c
@@ -500,6 +500,17 @@ static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype,
_digp->saved |= PGPDIG_SAVED_ID;
memcpy(_digp->signid, p+1, sizeof(_digp->signid));
}
+ case PGPSUBTYPE_KEY_FLAGS: /* Key usage flags */
+ /* Subpackets in the unhashed section cannot be trusted */
+ if (!hashed)
+ break;
+ /* Reject duplicate key usage flags */
+ if (_digp->saved & PGPDIG_SIG_HAS_KEY_FLAGS)
+ return 1;
+ impl = *p;
+ _digp->saved |= PGPDIG_SIG_HAS_KEY_FLAGS;
+ _digp->key_flags = plen >= 2 ? p[1] : 0;
+ break;
case PGPSUBTYPE_EXPORTABLE_CERT:
case PGPSUBTYPE_TRUST_SIG:
case PGPSUBTYPE_REGEX:
@@ -510,7 +521,6 @@ static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype,
case PGPSUBTYPE_PREFER_KEYSERVER:
case PGPSUBTYPE_PRIMARY_USERID:
case PGPSUBTYPE_POLICY_URL:
- case PGPSUBTYPE_KEY_FLAGS:
case PGPSUBTYPE_SIGNER_USERID:
case PGPSUBTYPE_REVOKE_REASON:
case PGPSUBTYPE_FEATURES:
@@ -602,6 +612,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
/* Reset the saved flags */
_digp->saved &= PGPDIG_SAVED_TIME | PGPDIG_SAVED_ID;
+ _digp->key_flags = 0;
if (pgpVersion(h, hlen, &version))
return rc;