Skip to content

Commit

Permalink
WIP: check whether PGP key is revoked or expired
Browse files Browse the repository at this point in the history
  • Loading branch information
dmantipov committed Mar 30, 2021
1 parent 134998a commit 972c960
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 8 deletions.
39 changes: 34 additions & 5 deletions lib/rpmts.c
Expand Up @@ -283,12 +283,19 @@ static int loadKeyringFromFiles(rpmts ts)
for (char **f = files; *f; f++) {
int subkeysCount, i;
rpmPubkey *subkeys;
int keyVerifyFlags;
rpmPubkey key = rpmPubkeyRead(*f);

if (!key) {
rpmlog(RPMLOG_ERR, _("%s: reading of public key failed.\n"), *f);
continue;
}
keyVerifyFlags = rpmPubkeyVerify(key, 0);
if (keyVerifyFlags & RPM_PUBKEY_EXPIRED)
rpmlog(RPMLOG_DEBUG, "mark key %s as expired\n", *f);
if (keyVerifyFlags & RPM_PUBKEY_REVOKED)
rpmlog(RPMLOG_DEBUG, "mark key %s as revoked\n", *f);

if (rpmKeyringAddKey(ts->keyring, key) == 0) {
nkeys++;
rpmlog(RPMLOG_DEBUG, "added key %s to keyring\n", *f);
Expand All @@ -298,6 +305,15 @@ static int loadKeyringFromFiles(rpmts ts)

for (i = 0; i < subkeysCount; i++) {
rpmPubkey subkey = subkeys[i];
int subkeyVerifyFlags;

subkeyVerifyFlags = rpmPubkeyVerify(subkey, keyVerifyFlags);
if (subkeyVerifyFlags & RPM_PUBKEY_EXPIRED)
rpmlog(RPMLOG_DEBUG, "mark subkey %d of "
"main key %s as expired\n", i, *f);
if (subkeyVerifyFlags & RPM_PUBKEY_REVOKED)
rpmlog(RPMLOG_DEBUG, "mark subkey %d of "
"main key %s as revoked\n", i, *f);

if (rpmKeyringAddKey(ts->keyring, subkey) == 0) {
rpmlog(RPMLOG_DEBUG,
Expand Down Expand Up @@ -338,32 +354,45 @@ static int loadKeyringFromDB(rpmts ts)
if (rpmBase64Decode(key, (void **) &pkt, &pktlen) == 0) {
rpmPubkey key = rpmPubkeyNew(pkt, pktlen);
int subkeysCount, i;
int keyVerifyFlags;
rpmPubkey *subkeys = rpmGetSubkeys(key, &subkeysCount);
char *nvr = headerGetAsString(h, RPMTAG_NVR);

keyVerifyFlags = rpmPubkeyVerify(key, 0);
if (keyVerifyFlags & RPM_PUBKEY_EXPIRED)
rpmlog(RPMLOG_DEBUG, "mark key %s as expired\n", nvr);
if (keyVerifyFlags & RPM_PUBKEY_REVOKED)
rpmlog(RPMLOG_DEBUG, "mark key %s as revoked\n", nvr);

if (rpmKeyringAddKey(ts->keyring, key) == 0) {
char *nvr = headerGetAsString(h, RPMTAG_NVR);
rpmlog(RPMLOG_DEBUG, "added key %s to keyring\n", nvr);
free(nvr);
nkeys++;
}
rpmPubkeyFree(key);

for (i = 0; i < subkeysCount; i++) {
rpmPubkey subkey = subkeys[i];
int subkeyVerifyFlags;

subkeyVerifyFlags = rpmPubkeyVerify(subkey, keyVerifyFlags);
if (subkeyVerifyFlags & RPM_PUBKEY_EXPIRED)
rpmlog(RPMLOG_DEBUG, "mark subkey %d of "
"main key %s as expired\n", i, nvr);
if (subkeyVerifyFlags & RPM_PUBKEY_REVOKED)
rpmlog(RPMLOG_DEBUG, "mark subkey %d of "
"main key %s as revoked\n", i, nvr);

if (rpmKeyringAddKey(ts->keyring, subkey) == 0) {
char *nvr = headerGetAsString(h, RPMTAG_NVR);
rpmlog(RPMLOG_DEBUG,
"added subkey %d of main key %s to keyring\n",
i, nvr);

free(nvr);
nkeys++;
}
rpmPubkeyFree(subkey);
}
free(subkeys);
free(pkt);
free(nvr);
}
}
rpmtdFreeData(&pubkeys);
Expand Down
4 changes: 3 additions & 1 deletion rpmio/digest.h
Expand Up @@ -29,6 +29,7 @@ struct pgpDigParams_s {

uint8_t version; /*!< version number. */
uint32_t time; /*!< key/signature creation time. */
uint32_t etime; /*!< key/signature expiration time. */
uint8_t pubkey_algo; /*!< public key algorithm. */

uint8_t hash_algo;
Expand All @@ -39,7 +40,8 @@ struct pgpDigParams_s {
uint8_t saved;
#define PGPDIG_SAVED_TIME (1 << 0)
#define PGPDIG_SAVED_ID (1 << 1)

#define PGPDIG_SAVED_ETIME (1 << 2)
#define PGPDIG_SAVED_REVOKED (1 << 3)
pgpDigAlg alg;
};

Expand Down
36 changes: 36 additions & 0 deletions rpmio/rpmkeyring.c
Expand Up @@ -21,6 +21,7 @@ struct rpmPubkey_s {
pgpKeyID_t keyid;
pgpDigParams pgpkey;
int nrefs;
int flags;
pthread_rwlock_t lock;
};

Expand Down Expand Up @@ -81,6 +82,41 @@ static rpmPubkey rpmKeyringFindKeyid(rpmKeyring keyring, rpmPubkey key)
return found ? *found : NULL;
}

int rpmPubkeyVerify(rpmPubkey key, int keyVerifyFlags)
{
uint32_t now = time(NULL);

/* All subkeys of an expired key are expired,
all subkeys of the revoked key are revoked. */
if (keyVerifyFlags)
key->flags = keyVerifyFlags;

if (key->pgpkey->time && key->pgpkey->time > now)
/* Key created in the future, or system clock is skewed.
Treat this suspicious case as an expired key anyway. */
key->flags |= RPM_PUBKEY_EXPIRED;

if (key->pgpkey->etime && key->pgpkey->etime < now)
/* Key is really expired. */
key->flags |= RPM_PUBKEY_EXPIRED;

/* Digging says this key was revoked. */
if (key->pgpkey->saved & PGPDIG_SAVED_REVOKED)
key->flags |= RPM_PUBKEY_REVOKED;

if (key->flags & RPM_PUBKEY_EXPIRED)
rpmlog(RPMLOG_DEBUG, "mark key %x%x%x%x%x%x%x%x as expired\n",
key->keyid[0], key->keyid[1], key->keyid[2], key->keyid[3],
key->keyid[4], key->keyid[5], key->keyid[6], key->keyid[7]);

if (key->flags & RPM_PUBKEY_REVOKED)
rpmlog(RPMLOG_DEBUG, "mark key %x%x%x%x%x%x%x%x as revoked\n",
key->keyid[0], key->keyid[1], key->keyid[2], key->keyid[3],
key->keyid[4], key->keyid[5], key->keyid[6], key->keyid[7]);

return key->flags;
}

int rpmKeyringAddKey(rpmKeyring keyring, rpmPubkey key)
{
int rc = 1; /* assume already seen key */
Expand Down
5 changes: 5 additions & 0 deletions rpmio/rpmkeyring.h
Expand Up @@ -116,6 +116,11 @@ char * rpmPubkeyBase64(rpmPubkey key);
*/
pgpDigParams rpmPubkeyPgpDigParams(rpmPubkey key);

#define RPM_PUBKEY_EXPIRED (1 << 0)
#define RPM_PUBKEY_REVOKED (1 << 1)

int rpmPubkeyVerify(rpmPubkey key, int keyVerifyFlags);

#ifdef __cplusplus
}
#endif
Expand Down
23 changes: 21 additions & 2 deletions rpmio/rpmpgp.c
Expand Up @@ -454,9 +454,29 @@ static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype,
_digp->saved |= PGPDIG_SAVED_TIME;
_digp->time = pgpGrab(p+1, sizeof(_digp->time));
}
break;
case PGPSUBTYPE_SIG_EXPIRE_TIME:
case PGPSUBTYPE_KEY_EXPIRE_TIME:
pgpPrtTime(" ", p+1, plen-1);
if (!(_digp->saved & PGPDIG_SAVED_ETIME) &&
(sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
{
uint32_t etime;
if (plen-1 != sizeof(_digp->etime))
break;
etime = pgpGrab(p+1, sizeof(_digp->etime));
/* Expiration time is relative to creation time. */
if ((_digp->saved & PGPDIG_SAVED_TIME) && etime > 0) {
_digp->saved |= PGPDIG_SAVED_ETIME;
_digp->etime = _digp->time + etime;
}
}
break;

case PGPSUBTYPE_REVOKE_REASON:
rpmlog(RPMLOG_DEBUG, "digging says %x%x%x%x%x%x%x%x is revoked\n",
_digp->signid[0], _digp->signid[1], _digp->signid[2], _digp->signid[3],
_digp->signid[4], _digp->signid[5], _digp->signid[6], _digp->signid[7]);
_digp->saved |= PGPDIG_SAVED_REVOKED;
break;

case PGPSUBTYPE_ISSUER_KEYID: /* issuer key ID */
Expand All @@ -480,7 +500,6 @@ static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype,
case PGPSUBTYPE_POLICY_URL:
case PGPSUBTYPE_KEY_FLAGS:
case PGPSUBTYPE_SIGNER_USERID:
case PGPSUBTYPE_REVOKE_REASON:
case PGPSUBTYPE_FEATURES:
case PGPSUBTYPE_EMBEDDED_SIG:
case PGPSUBTYPE_INTERNAL_100:
Expand Down

0 comments on commit 972c960

Please sign in to comment.