File pgpharden.diff of Package python-rpm.27835

--- rpmio/rpmpgp.c.orig	2020-04-28 12:50:11.936400484 +0000
+++ rpmio/rpmpgp.c	2022-10-25 08:29:02.628962162 +0000
@@ -297,6 +297,7 @@ int pgpValTok(pgpValTbl vs, const char *
 /** \ingroup rpmpgp
  * Decode length from 1, 2, or 5 octet body length encoding, used in
  * new format packet headers and V4 signature subpackets.
+ * Partial body lengths are (intentionally) not supported.
  * @param s		pointer to length encoding buffer
  * @param slen		buffer size
  * @retval *lenp	decoded length
@@ -316,14 +317,17 @@ size_t pgpLen(const uint8_t *s, size_t s
     if (*s < 192) {
 	lenlen = 1;
 	dlen = *s;
-    } else if (*s < 255 && slen > 2) {
+    } else if (*s < 224 && slen > 2) {
 	lenlen = 2;
 	dlen = (((s[0]) - 192) << 8) + s[1] + 192;
-    } else if (slen > 5) {
+    } else if (*s == 255 && slen > 5) {
 	lenlen = 5;
 	dlen = pgpGrab(s+1, 4);
     }
 
+    if (slen - lenlen < dlen)
+	lenlen = 0;
+
     if (lenlen)
 	*lenp = dlen;
 
@@ -411,8 +415,10 @@ static int pgpPrtSubType(const uint8_t *
 {
     const uint8_t *p = h;
     size_t plen = 0, i;
+    int rc = 0;
 
-    while (hlen > 0) {
+    while (hlen > 0 && rc == 0) {
+	int impl = 0;
 	i = pgpLen(p, hlen, &plen);
 	if (i == 0 || plen < 1 || i + plen > hlen)
 	    break;
@@ -424,7 +430,7 @@ static int pgpPrtSubType(const uint8_t *
 	if (p[0] & PGPSUBTYPE_CRITICAL)
 	    if (_print)
 		fprintf(stderr, " *CRITICAL*");
-	switch (*p) {
+	switch (*p & ~PGPSUBTYPE_CRITICAL) {
 	case PGPSUBTYPE_PREFER_SYMKEY:	/* preferred symmetric algorithms */
 	    for (i = 1; i < plen; i++)
 		pgpPrtVal(" ", pgpSymkeyTbl, p[i]);
@@ -442,6 +448,7 @@ static int pgpPrtSubType(const uint8_t *
 		pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]);
 	    break;
 	case PGPSUBTYPE_SIG_CREATE_TIME:
+	    impl = *p;
 	    if (!(_digp->saved & PGPDIG_SAVED_TIME) &&
 		(sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
 	    {
@@ -456,6 +463,7 @@ static int pgpPrtSubType(const uint8_t *
 	    break;
 
 	case PGPSUBTYPE_ISSUER_KEYID:	/* issuer key ID */
+	    impl = *p;
 	    if (!(_digp->saved & PGPDIG_SAVED_ID) &&
 		(sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
 	    {
@@ -495,10 +503,18 @@ static int pgpPrtSubType(const uint8_t *
 	    break;
 	}
 	pgpPrtNL();
+
+	if (!impl && (p[0] & PGPSUBTYPE_CRITICAL))
+	    rc = 1;
+
 	p += plen;
 	hlen -= plen;
     }
-    return (hlen != 0); /* non-zero hlen is an error */
+
+    if (hlen != 0)
+	rc = 1;
+
+    return rc;
 }
 
 pgpDigAlg pgpDigAlgFree(pgpDigAlg alg)
@@ -520,9 +536,9 @@ static int pgpPrtSigParams(pgpTag tag, u
     int i;
     pgpDigAlg sigalg = pgpSignatureNew(pubkey_algo);
 
-    for (i = 0; i < sigalg->mpis && p + 2 <= pend; i++) {
+    for (i = 0; i < sigalg->mpis && pend - p >= 2; i++) {
 	int mpil = pgpMpiLen(p);
-	if (p + mpil > pend)
+	if (pend - p < mpil)
 	    break;
 	if (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT) {
 	    if (sigalg->setmpi(sigalg, i, p))
@@ -549,9 +565,13 @@ static int pgpGet(const uint8_t *s, size
 {
     int rc = -1;
 
-    if (s + nbytes <= send) {
-	*valp = pgpGrab(s, nbytes);
-	rc = 0;
+    *valp = 0;
+    if (nbytes <= 4 && send - s >= nbytes) {
+	unsigned int val = pgpGrab(s, nbytes);
+	if (send - s - nbytes >= val) {
+	    rc =0;
+	    *valp = val;
+	}
     }
 
     return rc;
@@ -561,7 +581,7 @@ static int pgpPrtSig(pgpTag tag, const u
 		     pgpDigParams _digp)
 {
     uint8_t version = 0;
-    uint8_t * p;
+    const uint8_t * p;
     unsigned int plen;
     int rc = 1;
 
@@ -604,6 +624,7 @@ static int pgpPrtSig(pgpTag tag, const u
     }	break;
     case 4:
     {   pgpPktSigV4 v = (pgpPktSigV4)h;
+	const uint8_t *const hend = h + hlen;
 
 	if (hlen <= sizeof(*v))
 	    return 1;
@@ -615,11 +636,11 @@ static int pgpPrtSig(pgpTag tag, const u
 	pgpPrtNL();
 
 	p = &v->hashlen[0];
-	if (pgpGet(v->hashlen, sizeof(v->hashlen), h + hlen, &plen))
+	if (pgpGet(v->hashlen, sizeof(v->hashlen), hend, &plen))
 	    return 1;
 	p += sizeof(v->hashlen);
 
-	if ((p + plen) > (h + hlen))
+	if ((p + plen) > hend)
 	    return 1;
 
 	if (_digp->pubkey_algo == 0) {
@@ -630,18 +651,18 @@ static int pgpPrtSig(pgpTag tag, const u
 	    return 1;
 	p += plen;
 
-	if (pgpGet(p, 2, h + hlen, &plen))
+	if (pgpGet(p, 2, hend, &plen))
 	    return 1;
 	p += 2;
 
-	if ((p + plen) > (h + hlen))
+	if ((p + plen) > hend)
 	    return 1;
 
 	if (pgpPrtSubType(p, plen, v->sigtype, _digp))
 	    return 1;
 	p += plen;
 
-	if (pgpGet(p, 2, h + hlen, &plen))
+	if (h + hlen - p < 2)
 	    return 1;
 	pgpPrtHex(" signhash16", p, 2);
 	pgpPrtNL();
@@ -655,7 +676,7 @@ static int pgpPrtSig(pgpTag tag, const u
 	}
 
 	p += 2;
-	if (p > (h + hlen))
+	if (p > hend)
 	    return 1;
 
 	rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen, _digp);
@@ -1025,6 +1046,8 @@ int pgpPrtParams(const uint8_t * pkts, s
 	    break;
 
 	p += (pkt.body - pkt.head) + pkt.blen;
+	if (pkttype == PGPTAG_SIGNATURE)
+	    break;
     }
 
     rc = (digp && (p == pend)) ? 0 : -1;
openSUSE Build Service is sponsored by