alexk / rpms / rpm

Forked from rpms/rpm 2 years ago
Clone
a9e8d8
From 82c53e4b7f720012a391d8f6e5da9ee3c4f22bed Mon Sep 17 00:00:00 2001
c7b760
From: Demi Marie Obenour <demi@invisiblethingslab.com>
c7b760
Date: Thu, 6 May 2021 18:34:45 -0400
c7b760
Subject: [PATCH] Validate and require subkey binding signatures on PGP public
c7b760
 keys
c7b760
c7b760
All subkeys must be followed by a binding signature by the primary key
c7b760
as per the OpenPGP RFC, enforce the presence and validity in the parser.
c7b760
c7b760
The implementation is as kludgey as they come to work around our
c7b760
simple-minded parser structure without touching API, to maximise
c7b760
backportability. Store all the raw packets internally as we decode them
c7b760
to be able to access previous elements at will, needed to validate ordering
c7b760
and access the actual data. Add testcases for manipulated keys whose
c7b760
import previously would succeed.
c7b760
c7b760
Combined with:
c7b760
5ff86764b17f31535cb247543a90dd739076ec38
c7b760
b5e8bc74b2b05aa557f663fe227b94d2bc64fbd8
c7b760
9f03f42e2614a68f589f9db8fe76287146522c0c
a9e8d8
b6dffb6dc5ffa2ddc389743f0507876cab341315 (mem-leak fix)
a9e8d8
ae3d2d234ae47ff85229d3fce97a266fa1aa5a61 (use-after-free fix)
c7b760
c7b760
Fixes CVE-2021-3521.
c7b760
---
a9e8d8
 rpmio/rpmpgp.c                                | 122 +++++++++++++++---
a9e8d8
 sign/rpmgensig.c                              |   2 +-
c7b760
 tests/Makefile.am                             |   3 +
c7b760
 tests/data/keys/CVE-2021-3521-badbind.asc     |  25 ++++
c7b760
 .../data/keys/CVE-2021-3521-nosubsig-last.asc |  25 ++++
c7b760
 tests/data/keys/CVE-2021-3521-nosubsig.asc    |  37 ++++++
c7b760
 tests/rpmsigdig.at                            |  28 ++++
a9e8d8
 7 files changed, 224 insertions(+), 18 deletions(-)
c7b760
 create mode 100644 tests/data/keys/CVE-2021-3521-badbind.asc
c7b760
 create mode 100644 tests/data/keys/CVE-2021-3521-nosubsig-last.asc
c7b760
 create mode 100644 tests/data/keys/CVE-2021-3521-nosubsig.asc
c7b760
c7b760
diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c
a9e8d8
index 46cd0f31a..bd4992ec7 100644
c7b760
--- a/rpmio/rpmpgp.c
c7b760
+++ b/rpmio/rpmpgp.c
c7b760
@@ -511,7 +511,7 @@ pgpDigAlg pgpDigAlgFree(pgpDigAlg alg)
c7b760
     return NULL;
c7b760
 }
c7b760
 
c7b760
-static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo, uint8_t sigtype,
c7b760
+static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo,
c7b760
 		const uint8_t *p, const uint8_t *h, size_t hlen,
c7b760
 		pgpDigParams sigp)
c7b760
 {
c7b760
@@ -524,10 +524,8 @@ static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo, uint8_t sigtype,
c7b760
 	int mpil = pgpMpiLen(p);
c7b760
 	if (p + mpil > pend)
c7b760
 	    break;
c7b760
-	if (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT) {
c7b760
-	    if (sigalg->setmpi(sigalg, i, p))
c7b760
-		break;
c7b760
-	}
c7b760
+	if (sigalg->setmpi(sigalg, i, p))
c7b760
+	    break;
c7b760
 	p += mpil;
c7b760
     }
c7b760
 
c7b760
@@ -600,7 +598,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
c7b760
 	}
c7b760
 
c7b760
 	p = ((uint8_t *)v) + sizeof(*v);
c7b760
-	rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen, _digp);
c7b760
+	rc = pgpPrtSigParams(tag, v->pubkey_algo, p, h, hlen, _digp);
c7b760
     }	break;
c7b760
     case 4:
c7b760
     {   pgpPktSigV4 v = (pgpPktSigV4)h;
c7b760
@@ -658,7 +656,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
c7b760
 	if (p > (h + hlen))
c7b760
 	    return 1;
c7b760
 
c7b760
-	rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen, _digp);
c7b760
+	rc = pgpPrtSigParams(tag, v->pubkey_algo, p, h, hlen, _digp);
c7b760
     }	break;
c7b760
     default:
c7b760
 	rpmlog(RPMLOG_WARNING, _("Unsupported version of key: V%d\n"), version);
a9e8d8
@@ -999,36 +997,127 @@ unsigned int pgpDigParamsAlgo(pgpDigParams digp, unsigned int algotype)
c7b760
     return algo;
c7b760
 }
c7b760
 
c7b760
+static pgpDigParams pgpDigParamsNew(uint8_t tag)
c7b760
+{
c7b760
+    pgpDigParams digp = xcalloc(1, sizeof(*digp));
c7b760
+    digp->tag = tag;
c7b760
+    return digp;
c7b760
+}
c7b760
+
c7b760
+static int hashKey(DIGEST_CTX hash, const struct pgpPkt *pkt, int exptag)
c7b760
+{
c7b760
+    int rc = -1;
c7b760
+    if (pkt->tag == exptag) {
c7b760
+	uint8_t head[] = {
c7b760
+	    0x99,
c7b760
+	    (pkt->blen >> 8),
c7b760
+	    (pkt->blen     ),
c7b760
+	};
c7b760
+
c7b760
+	rpmDigestUpdate(hash, head, 3);
c7b760
+	rpmDigestUpdate(hash, pkt->body, pkt->blen);
c7b760
+	rc = 0;
c7b760
+    }
c7b760
+    return rc;
c7b760
+}
c7b760
+
c7b760
+static int pgpVerifySelf(pgpDigParams key, pgpDigParams selfsig,
c7b760
+			const struct pgpPkt *all, int i)
c7b760
+{
c7b760
+    int rc = -1;
c7b760
+    DIGEST_CTX hash = NULL;
c7b760
+
c7b760
+    switch (selfsig->sigtype) {
c7b760
+    case PGPSIGTYPE_SUBKEY_BINDING:
c7b760
+	hash = rpmDigestInit(selfsig->hash_algo, 0);
c7b760
+	if (hash) {
c7b760
+	    rc = hashKey(hash, &all[0], PGPTAG_PUBLIC_KEY);
c7b760
+	    if (!rc)
c7b760
+		rc = hashKey(hash, &all[i-1], PGPTAG_PUBLIC_SUBKEY);
c7b760
+	}
c7b760
+	break;
c7b760
+    default:
c7b760
+	/* ignore types we can't handle */
c7b760
+	rc = 0;
c7b760
+	break;
c7b760
+    }
c7b760
+
c7b760
+    if (hash && rc == 0)
c7b760
+	rc = pgpVerifySignature(key, selfsig, hash);
c7b760
+
c7b760
+    rpmDigestFinal(hash, NULL, NULL, 0);
c7b760
+
c7b760
+    return rc;
c7b760
+}
c7b760
+
c7b760
 int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype,
c7b760
 		 pgpDigParams * ret)
c7b760
 {
c7b760
     const uint8_t *p = pkts;
c7b760
     const uint8_t *pend = pkts + pktlen;
c7b760
     pgpDigParams digp = NULL;
c7b760
-    struct pgpPkt pkt;
c7b760
+    pgpDigParams selfsig = NULL;
c7b760
+    int i = 0;
c7b760
+    int alloced = 16; /* plenty for normal cases */
c7b760
+    struct pgpPkt *all = xmalloc(alloced * sizeof(*all));
c7b760
     int rc = -1; /* assume failure */
c7b760
+    int expect = 0;
c7b760
+    int prevtag = 0;
c7b760
 
c7b760
     while (p < pend) {
c7b760
-	if (decodePkt(p, (pend - p), &pkt))
c7b760
+	struct pgpPkt *pkt = &all[i];
c7b760
+	if (decodePkt(p, (pend - p), pkt))
c7b760
 	    break;
c7b760
 
c7b760
 	if (digp == NULL) {
c7b760
-	    if (pkttype && pkt.tag != pkttype) {
c7b760
+	    if (pkttype && pkt->tag != pkttype) {
c7b760
 		break;
c7b760
 	    } else {
c7b760
-		digp = xcalloc(1, sizeof(*digp));
c7b760
-		digp->tag = pkt.tag;
c7b760
+		digp = pgpDigParamsNew(pkt->tag);
c7b760
 	    }
c7b760
 	}
c7b760
 
c7b760
-	if (pgpPrtPkt(&pkt, digp))
c7b760
+	if (expect) {
c7b760
+	    if (pkt->tag != expect)
c7b760
+		break;
c7b760
+	    selfsig = pgpDigParamsNew(pkt->tag);
c7b760
+	}
c7b760
+
c7b760
+	if (pgpPrtPkt(pkt, selfsig ? selfsig : digp))
c7b760
 	    break;
c7b760
 
c7b760
-	p += (pkt.body - pkt.head) + pkt.blen;
c7b760
+	if (selfsig) {
c7b760
+	    /* subkeys must be followed by binding signature */
a9e8d8
+	    int xx = 1; /* assume failure */
c7b760
+
a9e8d8
+	    if (!(prevtag == PGPTAG_PUBLIC_SUBKEY &&
a9e8d8
+		  selfsig->sigtype != PGPSIGTYPE_SUBKEY_BINDING))
a9e8d8
+		xx = pgpVerifySelf(digp, selfsig, all, i);
c7b760
+
c7b760
+	    selfsig = pgpDigParamsFree(selfsig);
c7b760
+	    if (xx)
c7b760
+		break;
c7b760
+	    expect = 0;
c7b760
+	}
c7b760
+
c7b760
+	if (pkt->tag == PGPTAG_PUBLIC_SUBKEY)
c7b760
+	    expect = PGPTAG_SIGNATURE;
c7b760
+	prevtag = pkt->tag;
c7b760
+
c7b760
+	i++;
c7b760
+	p += (pkt->body - pkt->head) + pkt->blen;
c7b760
+	if (pkttype == PGPTAG_SIGNATURE)
c7b760
+	    break;
c7b760
+
c7b760
+	if (alloced <= i) {
c7b760
+	    alloced *= 2;
c7b760
+	    all = xrealloc(all, alloced * sizeof(*all));
c7b760
+	}
c7b760
     }
c7b760
 
c7b760
-    rc = (digp && (p == pend)) ? 0 : -1;
c7b760
+    rc = (digp && (p == pend) && expect == 0) ? 0 : -1;
c7b760
 
c7b760
+    free(all);
c7b760
     if (ret && rc == 0) {
c7b760
 	*ret = digp;
c7b760
     } else {
a9e8d8
@@ -1063,8 +1152,7 @@ int pgpPrtParamsSubkeys(const uint8_t *pkts, size_t pktlen,
c7b760
 		digps = xrealloc(digps, alloced * sizeof(*digps));
c7b760
 	    }
c7b760
 
c7b760
-	    digps[count] = xcalloc(1, sizeof(**digps));
c7b760
-	    digps[count]->tag = PGPTAG_PUBLIC_SUBKEY;
c7b760
+	    digps[count] = pgpDigParamsNew(PGPTAG_PUBLIC_SUBKEY);
c7b760
 	    /* Copy UID from main key to subkey */
c7b760
 	    digps[count]->userid = xstrdup(mainkey->userid);
c7b760
 
a9e8d8
diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c
a9e8d8
index 771d01098..b33fe996c 100644
a9e8d8
--- a/sign/rpmgensig.c
a9e8d8
+++ b/sign/rpmgensig.c
a9e8d8
@@ -409,7 +409,7 @@ static int haveSignature(rpmtd sigtd, Header h)
a9e8d8
 	pgpPrtParams(oldtd.data, oldtd.count, PGPTAG_SIGNATURE, &sig2;;
a9e8d8
 	if (pgpDigParamsCmp(sig1, sig2) == 0)
a9e8d8
 	    rc = 1;
a9e8d8
-	pgpDigParamsFree(sig2);
a9e8d8
+	sig2 = pgpDigParamsFree(sig2);
a9e8d8
     }
a9e8d8
     pgpDigParamsFree(sig1);
a9e8d8
     rpmtdFreeData(&oldtd);
c7b760
diff --git a/tests/Makefile.am b/tests/Makefile.am
c7b760
index 5f5207e56..309347262 100644
c7b760
--- a/tests/Makefile.am
c7b760
+++ b/tests/Makefile.am
c7b760
@@ -87,6 +87,9 @@ EXTRA_DIST += data/SPECS/hello-config-buildid.spec
c7b760
 EXTRA_DIST += data/SPECS/hello-cd.spec
c7b760
 EXTRA_DIST += data/keys/rpm.org-rsa-2048-test.pub
c7b760
 EXTRA_DIST += data/keys/rpm.org-rsa-2048-test.secret
c7b760
+EXTRA_DIST += data/keys/CVE-2021-3521-badbind.asc
c7b760
+EXTRA_DIST += data/keys/CVE-2021-3521-nosubsig.asc
c7b760
+EXTRA_DIST += data/keys/CVE-2021-3521-nosubsig-last.asc
c7b760
 EXTRA_DIST += data/macros.testfile
c7b760
 
c7b760
 # testsuite voodoo
c7b760
diff --git a/tests/data/keys/CVE-2021-3521-badbind.asc b/tests/data/keys/CVE-2021-3521-badbind.asc
c7b760
new file mode 100644
c7b760
index 000000000..aea00f9d7
c7b760
--- /dev/null
c7b760
+++ b/tests/data/keys/CVE-2021-3521-badbind.asc
c7b760
@@ -0,0 +1,25 @@
c7b760
+-----BEGIN PGP PUBLIC KEY BLOCK-----
c7b760
+Version: rpm-4.17.90 (NSS-3)
c7b760
+
c7b760
+mQENBFjmORgBCAC7TMEk6wnjSs8Dr4yqSScWdU2pjcqrkTxuzdWvowcIUPZI0w/g
c7b760
+HkRqGd4apjvY2V15kjL10gk3QhFP3pZ/9p7zh8o8NHX7aGdSGDK7NOq1eFaErPRY
c7b760
+91LW9RiZ0lbOjXEzIL0KHxUiTQEmdXJT43DJMFPyW9fkCWg0OltiX618FUdWWfI8
c7b760
+eySdLur1utnqBvdEbCUvWK2RX3vQZQdvEBODnNk2pxqTyV0w6VPQ96W++lF/5Aas
c7b760
+7rUv3HIyIXxIggc8FRrnH+y9XvvHDonhTIlGnYZN4ubm9i4y3gOkrZlGTrEw7elQ
c7b760
+1QeMyG2QQEbze8YjpTm4iLABCBrRfPRaQpwrABEBAAG0IXJwbS5vcmcgUlNBIHRl
c7b760
+c3RrZXkgPHJzYUBycG0ub3JnPokBNwQTAQgAIQUCWOY5GAIbAwULCQgHAgYVCAkK
c7b760
+CwIEFgIDAQIeAQIXgAAKCRBDRFkeGWTF/MxxCACnjqFL+MmPh9W9JQKT2DcLbBzf
c7b760
+Cqo6wcEBoCOcwgRSk8dSikhARoteoa55JRJhuMyeKhhEAogE9HRmCPFdjezFTwgB
c7b760
+BDVBpO2dZ023mLXDVCYX3S8pShOgCP6Tn4wqCnYeAdLcGg106N4xcmgtcssJE+Pr
c7b760
+XzTZksbZsrTVEmL/Ym+R5w5jBfFnGk7Yw7ndwfQsfNXQb5AZynClFxnX546lcyZX
c7b760
+fEx3/e6ezw57WNOUK6WT+8b+EGovPkbetK/rGxNXuWaP6X4A/QUm8O98nCuHYFQq
c7b760
++mvNdsCBqGf7mhaRGtpHk/JgCn5rFvArMDqLVrR9hX0LdCSsH7EGE+bR3r7wuQEN
c7b760
+BFjmORgBCACk+vDZrIXQuFXEYToZVwb2attzbbJJCqD71vmZTLsW0QxuPKRgbcYY
c7b760
+zp4K4lVBnHhFrF8MOUOxJ7kQWIJZMZFt+BDcptCYurbD2H4W2xvnWViiC+LzCMzz
c7b760
+iMJT6165uefL4JHTDPxC2fFiM9yrc72LmylJNkM/vepT128J5Qv0gRUaQbHiQuS6
c7b760
+Dm/+WRnUfx3i89SV4mnBxb/Ta93GVqoOciWwzWSnwEnWYAvOb95JL4U7c5J5f/+c
c7b760
+KnQDHsW7sIiIdscsWzvgf6qs2Ra1Zrt7Fdk4+ZS2f/adagLhDO1C24sXf5XfMk5m
c7b760
+L0OGwZSr9m5s17VXxfspgU5ugc8kBJfzABEBAAE=
c7b760
+=WCfs
c7b760
+-----END PGP PUBLIC KEY BLOCK-----
c7b760
+
c7b760
diff --git a/tests/data/keys/CVE-2021-3521-nosubsig-last.asc b/tests/data/keys/CVE-2021-3521-nosubsig-last.asc
c7b760
new file mode 100644
c7b760
index 000000000..aea00f9d7
c7b760
--- /dev/null
c7b760
+++ b/tests/data/keys/CVE-2021-3521-nosubsig-last.asc
c7b760
@@ -0,0 +1,25 @@
c7b760
+-----BEGIN PGP PUBLIC KEY BLOCK-----
c7b760
+Version: rpm-4.17.90 (NSS-3)
c7b760
+
c7b760
+mQENBFjmORgBCAC7TMEk6wnjSs8Dr4yqSScWdU2pjcqrkTxuzdWvowcIUPZI0w/g
c7b760
+HkRqGd4apjvY2V15kjL10gk3QhFP3pZ/9p7zh8o8NHX7aGdSGDK7NOq1eFaErPRY
c7b760
+91LW9RiZ0lbOjXEzIL0KHxUiTQEmdXJT43DJMFPyW9fkCWg0OltiX618FUdWWfI8
c7b760
+eySdLur1utnqBvdEbCUvWK2RX3vQZQdvEBODnNk2pxqTyV0w6VPQ96W++lF/5Aas
c7b760
+7rUv3HIyIXxIggc8FRrnH+y9XvvHDonhTIlGnYZN4ubm9i4y3gOkrZlGTrEw7elQ
c7b760
+1QeMyG2QQEbze8YjpTm4iLABCBrRfPRaQpwrABEBAAG0IXJwbS5vcmcgUlNBIHRl
c7b760
+c3RrZXkgPHJzYUBycG0ub3JnPokBNwQTAQgAIQUCWOY5GAIbAwULCQgHAgYVCAkK
c7b760
+CwIEFgIDAQIeAQIXgAAKCRBDRFkeGWTF/MxxCACnjqFL+MmPh9W9JQKT2DcLbBzf
c7b760
+Cqo6wcEBoCOcwgRSk8dSikhARoteoa55JRJhuMyeKhhEAogE9HRmCPFdjezFTwgB
c7b760
+BDVBpO2dZ023mLXDVCYX3S8pShOgCP6Tn4wqCnYeAdLcGg106N4xcmgtcssJE+Pr
c7b760
+XzTZksbZsrTVEmL/Ym+R5w5jBfFnGk7Yw7ndwfQsfNXQb5AZynClFxnX546lcyZX
c7b760
+fEx3/e6ezw57WNOUK6WT+8b+EGovPkbetK/rGxNXuWaP6X4A/QUm8O98nCuHYFQq
c7b760
++mvNdsCBqGf7mhaRGtpHk/JgCn5rFvArMDqLVrR9hX0LdCSsH7EGE+bR3r7wuQEN
c7b760
+BFjmORgBCACk+vDZrIXQuFXEYToZVwb2attzbbJJCqD71vmZTLsW0QxuPKRgbcYY
c7b760
+zp4K4lVBnHhFrF8MOUOxJ7kQWIJZMZFt+BDcptCYurbD2H4W2xvnWViiC+LzCMzz
c7b760
+iMJT6165uefL4JHTDPxC2fFiM9yrc72LmylJNkM/vepT128J5Qv0gRUaQbHiQuS6
c7b760
+Dm/+WRnUfx3i89SV4mnBxb/Ta93GVqoOciWwzWSnwEnWYAvOb95JL4U7c5J5f/+c
c7b760
+KnQDHsW7sIiIdscsWzvgf6qs2Ra1Zrt7Fdk4+ZS2f/adagLhDO1C24sXf5XfMk5m
c7b760
+L0OGwZSr9m5s17VXxfspgU5ugc8kBJfzABEBAAE=
c7b760
+=WCfs
c7b760
+-----END PGP PUBLIC KEY BLOCK-----
c7b760
+
c7b760
diff --git a/tests/data/keys/CVE-2021-3521-nosubsig.asc b/tests/data/keys/CVE-2021-3521-nosubsig.asc
c7b760
new file mode 100644
c7b760
index 000000000..3a2e7417f
c7b760
--- /dev/null
c7b760
+++ b/tests/data/keys/CVE-2021-3521-nosubsig.asc
c7b760
@@ -0,0 +1,37 @@
c7b760
+-----BEGIN PGP PUBLIC KEY BLOCK-----
c7b760
+Version: rpm-4.17.90 (NSS-3)
c7b760
+
c7b760
+mQENBFjmORgBCAC7TMEk6wnjSs8Dr4yqSScWdU2pjcqrkTxuzdWvowcIUPZI0w/g
c7b760
+HkRqGd4apjvY2V15kjL10gk3QhFP3pZ/9p7zh8o8NHX7aGdSGDK7NOq1eFaErPRY
c7b760
+91LW9RiZ0lbOjXEzIL0KHxUiTQEmdXJT43DJMFPyW9fkCWg0OltiX618FUdWWfI8
c7b760
+eySdLur1utnqBvdEbCUvWK2RX3vQZQdvEBODnNk2pxqTyV0w6VPQ96W++lF/5Aas
c7b760
+7rUv3HIyIXxIggc8FRrnH+y9XvvHDonhTIlGnYZN4ubm9i4y3gOkrZlGTrEw7elQ
c7b760
+1QeMyG2QQEbze8YjpTm4iLABCBrRfPRaQpwrABEBAAG0IXJwbS5vcmcgUlNBIHRl
c7b760
+c3RrZXkgPHJzYUBycG0ub3JnPokBNwQTAQgAIQUCWOY5GAIbAwULCQgHAgYVCAkK
c7b760
+CwIEFgIDAQIeAQIXgAAKCRBDRFkeGWTF/MxxCACnjqFL+MmPh9W9JQKT2DcLbBzf
c7b760
+Cqo6wcEBoCOcwgRSk8dSikhARoteoa55JRJhuMyeKhhEAogE9HRmCPFdjezFTwgB
c7b760
+BDVBpO2dZ023mLXDVCYX3S8pShOgCP6Tn4wqCnYeAdLcGg106N4xcmgtcssJE+Pr
c7b760
+XzTZksbZsrTVEmL/Ym+R5w5jBfFnGk7Yw7ndwfQsfNXQb5AZynClFxnX546lcyZX
c7b760
+fEx3/e6ezw57WNOUK6WT+8b+EGovPkbetK/rGxNXuWaP6X4A/QUm8O98nCuHYFQq
c7b760
++mvNdsCBqGf7mhaRGtpHk/JgCn5rFvArMDqLVrR9hX0LdCSsH7EGE+bR3r7wuQEN
c7b760
+BFjmORgBCACk+vDZrIXQuFXEYToZVwb2attzbbJJCqD71vmZTLsW0QxuPKRgbcYY
c7b760
+zp4K4lVBnHhFrF8MOUOxJ7kQWIJZMZFt+BDcptCYurbD2H4W2xvnWViiC+LzCMzz
c7b760
+iMJT6165uefL4JHTDPxC2fFiM9yrc72LmylJNkM/vepT128J5Qv0gRUaQbHiQuS6
c7b760
+Dm/+WRnUfx3i89SV4mnBxb/Ta93GVqoOciWwzWSnwEnWYAvOb95JL4U7c5J5f/+c
c7b760
+KnQDHsW7sIiIdscsWzvgf6qs2Ra1Zrt7Fdk4+ZS2f/adagLhDO1C24sXf5XfMk5m
c7b760
+L0OGwZSr9m5s17VXxfspgU5ugc8kBJfzABEBAAG5AQ0EWOY5GAEIAKT68NmshdC4
c7b760
+VcRhOhlXBvZq23NtskkKoPvW+ZlMuxbRDG48pGBtxhjOngriVUGceEWsXww5Q7En
c7b760
+uRBYglkxkW34ENym0Ji6tsPYfhbbG+dZWKIL4vMIzPOIwlPrXrm558vgkdMM/ELZ
c7b760
+8WIz3KtzvYubKUk2Qz+96lPXbwnlC/SBFRpBseJC5LoOb/5ZGdR/HeLz1JXiacHF
c7b760
+v9Nr3cZWqg5yJbDNZKfASdZgC85v3kkvhTtzknl//5wqdAMexbuwiIh2xyxbO+B/
c7b760
+qqzZFrVmu3sV2Tj5lLZ/9p1qAuEM7ULbixd/ld8yTmYvQ4bBlKv2bmzXtVfF+ymB
c7b760
+Tm6BzyQEl/MAEQEAAYkBHwQYAQgACQUCWOY5GAIbDAAKCRBDRFkeGWTF/PANB/9j
c7b760
+mifmj6z/EPe0PJFhrpISt9PjiUQCt0IPtiL5zKAkWjHePIzyi+0kCTBF6DDLFxos
c7b760
+3vN4bWnVKT1kBhZAQlPqpJTg+m74JUYeDGCdNx9SK7oRllATqyu+5rncgxjWVPnQ
c7b760
+zu/HRPlWJwcVFYEVXYL8xzfantwQTqefjmcRmBRdA2XJITK+hGWwAmrqAWx+q5xX
c7b760
+Pa8wkNMxVzNS2rUKO9SoVuJ/wlUvfoShkJ/VJ5HDp3qzUqncADfdGN35TDzscngQ
c7b760
+gHvnMwVBfYfSCABV1hNByoZcc/kxkrWMmsd/EnIyLd1Q1baKqc3cEDuC6E6/o4yJ
c7b760
+E4XX4jtDmdZPreZALsiB
c7b760
+=rRop
c7b760
+-----END PGP PUBLIC KEY BLOCK-----
c7b760
+
c7b760
diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at
c7b760
index 09fcdd525..a74f400ae 100644
c7b760
--- a/tests/rpmsigdig.at
c7b760
+++ b/tests/rpmsigdig.at
c7b760
@@ -212,6 +212,34 @@ UNW2iqnN3BA7guhOv6OMiROF1+I7Q5nWT63mQC7IgQ==
c7b760
 [])
c7b760
 AT_CLEANUP
c7b760
 
c7b760
+AT_SETUP([rpmkeys --import invalid keys])
c7b760
+AT_KEYWORDS([rpmkeys import])
c7b760
+RPMDB_INIT
c7b760
+
c7b760
+AT_CHECK([
c7b760
+runroot rpmkeys --import /data/keys/CVE-2021-3521-badbind.asc
c7b760
+],
c7b760
+[1],
c7b760
+[],
c7b760
+[error: /data/keys/CVE-2021-3521-badbind.asc: key 1 import failed.]
c7b760
+)
c7b760
+AT_CHECK([
c7b760
+runroot rpmkeys --import /data/keys/CVE-2021-3521-nosubsig.asc
c7b760
+],
c7b760
+[1],
c7b760
+[],
c7b760
+[error: /data/keys/CVE-2021-3521-nosubsig.asc: key 1 import failed.]
c7b760
+)
c7b760
+
c7b760
+AT_CHECK([
c7b760
+runroot rpmkeys --import /data/keys/CVE-2021-3521-nosubsig-last.asc
c7b760
+],
c7b760
+[1],
c7b760
+[],
c7b760
+[error: /data/keys/CVE-2021-3521-nosubsig-last.asc: key 1 import failed.]
c7b760
+)
c7b760
+AT_CLEANUP
c7b760
+
c7b760
 # ------------------------------
c7b760
 # Test pre-built package verification
c7b760
 AT_SETUP([rpmkeys -K <signed> 1])
c7b760
-- 
a9e8d8
2.34.1
c7b760