]> the.earth.li Git - onak.git/blobdiff - sigcheck.c
Remove unused worddb_cmp() from DB4 backend
[onak.git] / sigcheck.c
index 3ee8d3959e0e2db27e1c8c264d4b631cdec22896..0fe87b55ac891b60b86cbee6a22cd880495fbed8 100644 (file)
  * more details.
  *
  * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
 #include <stdint.h>
 
-#include "config.h"
+#include "build-config.h"
 #include "decodekey.h"
 #include "keyid.h"
 #include "keystructs.h"
@@ -47,42 +46,35 @@ int check_packet_sighash(struct openpgp_publickey *key,
        struct sha1_ctx sha1_context;
        struct sha1x_ctx sha1x_context;
        struct md5_ctx md5_context;
-#ifdef NETTLE_WITH_RIPEMD160
+#ifdef HAVE_NETTLE
        struct ripemd160_ctx ripemd160_context;
-#endif
-#ifdef NETTLE_WITH_SHA224
        struct sha224_ctx sha224_context;
-#endif
-#ifdef NETTLE_WITH_SHA256
        struct sha256_ctx sha256_context;
-#endif
-#ifdef NETTLE_WITH_SHA384
        struct sha384_ctx sha384_context;
-#endif
-#ifdef NETTLE_WITH_SHA512
        struct sha512_ctx sha512_context;
 #endif
        uint8_t keyheader[3];
        uint8_t packetheader[5];
-       uint8_t v4trailer[6];
+       uint8_t trailer[10];
        uint8_t hash[64];
        uint8_t *hashdata[8];
        size_t hashlen[8];
        int chunks, i;
        uint64_t keyid;
-
-       keyheader[0] = 0x99;
-       keyheader[1] = key->publickey->length >> 8;
-       keyheader[2] = key->publickey->length & 0xFF;
-       hashdata[0] = keyheader;
-       hashlen[0] = 3;
-       hashdata[1] = key->publickey->data;
-       hashlen[1] = key->publickey->length;
-       chunks = 2;
+       onak_status_t res;
 
        switch (sig->data[0]) {
        case 2:
        case 3:
+               keyheader[0] = 0x99;
+               keyheader[1] = key->publickey->length >> 8;
+               keyheader[2] = key->publickey->length & 0xFF;
+               hashdata[0] = keyheader;
+               hashlen[0] = 3;
+               hashdata[1] = key->publickey->data;
+               hashlen[1] = key->publickey->length;
+               chunks = 2;
+
                hashtype = sig->data[16];
 
                if (packet != NULL) {
@@ -107,6 +99,15 @@ int check_packet_sighash(struct openpgp_publickey *key,
                sighash = &sig->data[17];
                break;
        case 4:
+               keyheader[0] = 0x99;
+               keyheader[1] = key->publickey->length >> 8;
+               keyheader[2] = key->publickey->length & 0xFF;
+               hashdata[0] = keyheader;
+               hashlen[0] = 3;
+               hashdata[1] = key->publickey->data;
+               hashlen[1] = key->publickey->length;
+               chunks = 2;
+
                hashtype = sig->data[3];
 
                /* Check to see if this is an X509 based signature */
@@ -114,7 +115,13 @@ int check_packet_sighash(struct openpgp_publickey *key,
                        size_t len;
 
                        keyid = 0;
-                       len = parse_subpackets(&sig->data[4], &keyid, NULL);
+                       res = parse_subpackets(&sig->data[4],
+                                               sig->length - 4, &len,
+                                               &keyid, NULL);
+                       if (res != ONAK_E_OK) {
+                               /* If it parses badly, reject it */
+                               return 0;
+                       }
                        if (keyid == 0 &&
                                        /* No unhashed data */
                                        sig->data[4 + len] == 0 &&
@@ -163,18 +170,90 @@ int check_packet_sighash(struct openpgp_publickey *key,
                hashdata[chunks] = sig->data;
                hashlen[chunks] = siglen = (sig->data[4] << 8) +
                        sig->data[5] + 6;;
+               if (siglen > sig->length) {
+                       /* Signature data exceed packet length, bogus */
+                       return 0;
+               }
                chunks++;
 
-               v4trailer[0] = 4;
-               v4trailer[1] = 0xFF;
-               v4trailer[2] = siglen >> 24;
-               v4trailer[3] = (siglen >> 16) & 0xFF;
-               v4trailer[4] = (siglen >> 8) & 0xFF;
-               v4trailer[5] = siglen & 0xFF;
-               hashdata[chunks] = v4trailer;
+               trailer[0] = 4;
+               trailer[1] = 0xFF;
+               trailer[2] = siglen >> 24;
+               trailer[3] = (siglen >> 16) & 0xFF;
+               trailer[4] = (siglen >> 8) & 0xFF;
+               trailer[5] = siglen & 0xFF;
+               hashdata[chunks] = trailer;
                hashlen[chunks] = 6;
                chunks++;
 
+               unhashedlen = (sig->data[siglen] << 8) +
+                       sig->data[siglen + 1];
+               sighash = &sig->data[siglen + unhashedlen + 2];
+               break;
+       case 5:
+               keyheader[0] = 0x9A;
+               keyheader[1] = 0;
+               keyheader[2] = 0;
+               keyheader[3] = key->publickey->length >> 8;
+               keyheader[4] = key->publickey->length & 0xFF;
+               hashdata[0] = keyheader;
+               hashlen[0] = 5;
+               hashdata[1] = key->publickey->data;
+               hashlen[1] = key->publickey->length;
+               chunks = 2;
+
+               hashtype = sig->data[3];
+
+               if (packet != NULL) {
+                       if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
+                               packetheader[0] = 0x9A;
+                               packetheader[1] = 0;
+                               packetheader[2] = 0;
+                               packetheader[3] = packet->length >> 8;
+                               packetheader[4] = packet->length & 0xFF;
+                               hashdata[chunks] = packetheader;
+                               hashlen[chunks] = 5;
+                               chunks++;
+                       } else if (packet->tag == OPENPGP_PACKET_UID ||
+                                       packet->tag == OPENPGP_PACKET_UAT) {
+                               packetheader[0] = (packet->tag ==
+                                       OPENPGP_PACKET_UID) ?  0xB4 : 0xD1;
+                               packetheader[1] = packet->length >> 24;
+                               packetheader[2] = (packet->length >> 16) & 0xFF;
+                               packetheader[3] = (packet->length >> 8) & 0xFF;
+                               packetheader[4] = packet->length & 0xFF;
+                               hashdata[chunks] = packetheader;
+                               hashlen[chunks] = 5;
+                               chunks++;
+                       }
+                       hashdata[chunks] = packet->data;
+                       hashlen[chunks] = packet->length;
+                       chunks++;
+               }
+
+               hashdata[chunks] = sig->data;
+               hashlen[chunks] = siglen = (sig->data[4] << 8) +
+                       sig->data[5] + 6;;
+               if (siglen > sig->length) {
+                       /* Signature data exceed packet length, bogus */
+                       return 0;
+               }
+               chunks++;
+
+               trailer[0] = 5;
+               trailer[1] = 0xFF;
+               trailer[2] = 0;
+               trailer[3] = 0;
+               trailer[4] = 0;
+               trailer[5] = 0;
+               trailer[6] = siglen >> 24;
+               trailer[7] = (siglen >> 16) & 0xFF;
+               trailer[8] = (siglen >> 8) & 0xFF;
+               trailer[9] = siglen & 0xFF;
+               hashdata[chunks] = trailer;
+               hashlen[chunks] = 10;
+               chunks++;
+
                unhashedlen = (sig->data[siglen] << 8) +
                        sig->data[siglen + 1];
                sighash = &sig->data[siglen + unhashedlen + 2];
@@ -202,8 +281,15 @@ int check_packet_sighash(struct openpgp_publickey *key,
                }
                sha1_digest(&sha1_context, 20, hash);
                break;
+       case OPENPGP_HASH_SHA1X:
+               sha1x_init(&sha1x_context);
+               for (i = 0; i < chunks; i++) {
+                       sha1x_update(&sha1x_context, hashlen[i], hashdata[i]);
+               }
+               sha1x_digest(&sha1x_context, 20, hash);
+               break;
+#ifdef HAVE_NETTLE
        case OPENPGP_HASH_RIPEMD160:
-#ifdef NETTLE_WITH_RIPEMD160
                ripemd160_init(&ripemd160_context);
                for (i = 0; i < chunks; i++) {
                        ripemd160_update(&ripemd160_context, hashlen[i],
@@ -212,19 +298,7 @@ int check_packet_sighash(struct openpgp_publickey *key,
                ripemd160_digest(&ripemd160_context, RIPEMD160_DIGEST_SIZE,
                        hash);
                break;
-#else
-               logthing(LOGTHING_INFO, "RIPEMD160 support not available.");
-               return -1;
-#endif
-       case OPENPGP_HASH_SHA1X:
-               sha1x_init(&sha1x_context);
-               for (i = 0; i < chunks; i++) {
-                       sha1x_update(&sha1x_context, hashlen[i], hashdata[i]);
-               }
-               sha1x_digest(&sha1x_context, 20, hash);
-               break;
        case OPENPGP_HASH_SHA224:
-#ifdef NETTLE_WITH_SHA224
                sha224_init(&sha224_context);
                for (i = 0; i < chunks; i++) {
                        sha224_update(&sha224_context, hashlen[i],
@@ -232,12 +306,7 @@ int check_packet_sighash(struct openpgp_publickey *key,
                }
                sha224_digest(&sha224_context, SHA224_DIGEST_SIZE, hash);
                break;
-#else
-               logthing(LOGTHING_INFO, "SHA224 support not available.");
-               return -1;
-#endif
        case OPENPGP_HASH_SHA256:
-#ifdef NETTLE_WITH_SHA256
                sha256_init(&sha256_context);
                for (i = 0; i < chunks; i++) {
                        sha256_update(&sha256_context, hashlen[i],
@@ -245,12 +314,7 @@ int check_packet_sighash(struct openpgp_publickey *key,
                }
                sha256_digest(&sha256_context, SHA256_DIGEST_SIZE, hash);
                break;
-#else
-               logthing(LOGTHING_INFO, "SHA256 support not available.");
-               return -1;
-#endif
        case OPENPGP_HASH_SHA384:
-#ifdef NETTLE_WITH_SHA384
                sha384_init(&sha384_context);
                for (i = 0; i < chunks; i++) {
                        sha384_update(&sha384_context, hashlen[i],
@@ -258,12 +322,7 @@ int check_packet_sighash(struct openpgp_publickey *key,
                }
                sha384_digest(&sha384_context, SHA384_DIGEST_SIZE, hash);
                break;
-#else
-               logthing(LOGTHING_INFO, "SHA384 support not available.");
-               return -1;
-#endif
        case OPENPGP_HASH_SHA512:
-#ifdef NETTLE_WITH_SHA512
                sha512_init(&sha512_context);
                for (i = 0; i < chunks; i++) {
                        sha512_update(&sha512_context, hashlen[i],
@@ -271,9 +330,6 @@ int check_packet_sighash(struct openpgp_publickey *key,
                }
                sha512_digest(&sha512_context, SHA512_DIGEST_SIZE, hash);
                break;
-#else
-               logthing(LOGTHING_INFO, "SHA512 support not available.");
-               return -1;
 #endif
        default:
                get_keyid(key, &keyid);