diff options
author | Demi Marie Obenour <demi@invisiblethingslab.com> | 2022-02-06 15:52:48 -0500 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2022-03-18 13:00:29 +0200 |
commit | 7e7266c9af883ce49b3516a5bd099d218e8e3fac (patch) | |
tree | 89b242f466ec8116b8a393e880a7a571e14846cf | |
parent | 82b27f81bd884e5dc6fc7caa917ba4a0b4dc6e90 (diff) | |
download | rpm-7e7266c9af883ce49b3516a5bd099d218e8e3fac.tar.gz |
Require creation time to be unique and hashed
According to RFC 4880 §5.2.3.4 the signature creation time MUST be a
hashed subpacket. Enforce this requirement in RPM. Also set the saved
flags to PGPDIG_SAVED_TIME | PGPDIG_SAVED_ID |
PGPDIG_SAVED_CREATION_TIME for v3 signatures, and do not overwrite an
already saved key ID with one taken from a v3 signature.
-rw-r--r-- | rpmio/digest.h | 4 | ||||
-rw-r--r-- | rpmio/rpmpgp.c | 29 |
2 files changed, 22 insertions, 11 deletions
diff --git a/rpmio/digest.h b/rpmio/digest.h index 3b72a2870..ec7f3392f 100644 --- a/rpmio/digest.h +++ b/rpmio/digest.h @@ -36,9 +36,11 @@ struct pgpDigParams_s { uint32_t hashlen; uint8_t signhash16[2]; pgpKeyID_t signid; - uint8_t saved; + uint8_t saved; /*!< Various flags. `PGPDIG_SAVED_*` are never reset. + * `PGPDIG_SIG_HAS_*` 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) pgpDigAlg alg; }; diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c index f9e265827..02009000e 100644 --- a/rpmio/rpmpgp.c +++ b/rpmio/rpmpgp.c @@ -473,16 +473,16 @@ static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype, for (i = 1; i < plen; i++) pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]); break; - case PGPSUBTYPE_SIG_CREATE_TIME: + case PGPSUBTYPE_SIG_CREATE_TIME: /* signature creation time */ + if (plen-1 != sizeof(_digp->time)) + break; /* other lengths not understood */ + if (_digp->saved & PGPDIG_SIG_HAS_CREATION_TIME) + return 1; /* duplicate timestamps not allowed */ impl = *p; - if (!(_digp->saved & PGPDIG_SAVED_TIME) && - (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE)) - { - if (plen-1 != sizeof(_digp->time)) - break; - _digp->saved |= PGPDIG_SAVED_TIME; + if (!(_digp->saved & PGPDIG_SAVED_TIME)) _digp->time = pgpGrab(p+1, sizeof(_digp->time)); - } + _digp->saved |= PGPDIG_SAVED_TIME | PGPDIG_SIG_HAS_CREATION_TIME; + break; case PGPSUBTYPE_SIG_EXPIRE_TIME: case PGPSUBTYPE_KEY_EXPIRE_TIME: pgpPrtTime(" ", p+1, plen-1); @@ -598,6 +598,9 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen, size_t plen; int rc = 1; + /* Reset the saved flags */ + _digp->saved &= PGPDIG_SAVED_TIME | PGPDIG_SAVED_ID; + if (pgpVersion(h, hlen, &version)) return rc; @@ -625,8 +628,11 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen, _digp->hashlen = v->hashlen; _digp->sigtype = v->sigtype; _digp->hash = memcpy(xmalloc(v->hashlen), &v->sigtype, v->hashlen); - _digp->time = pgpGrab(v->time, sizeof(v->time)); - memcpy(_digp->signid, v->signid, sizeof(_digp->signid)); + if (!(_digp->saved & PGPDIG_SAVED_TIME)) + _digp->time = pgpGrab(v->time, sizeof(v->time)); + if (!(_digp->saved & PGPDIG_SAVED_ID)) + memcpy(_digp->signid, v->signid, sizeof(_digp->signid)); + _digp->saved = PGPDIG_SAVED_TIME | PGPDIG_SIG_HAS_CREATION_TIME | PGPDIG_SAVED_ID; _digp->pubkey_algo = v->pubkey_algo; _digp->hash_algo = v->hash_algo; memcpy(_digp->signhash16, v->signhash16, sizeof(_digp->signhash16)); @@ -664,6 +670,9 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen, return 1; p += plen; + if (!(_digp->saved & PGPDIG_SIG_HAS_CREATION_TIME)) + return 1; /* RFC 4880 §5.2.3.4 creation time MUST be hashed */ + if (pgpGet(p, 2, hend, &plen)) return 1; p += 2; |