]> the.earth.li Git - onak.git/commitdiff
Expose more of calculating the packet signature hash
authorJonathan McDowell <noodles@earth.li>
Mon, 5 Aug 2019 18:27:06 +0000 (19:27 +0100)
committerJonathan McDowell <noodles@earth.li>
Mon, 5 Aug 2019 18:27:06 +0000 (19:27 +0100)
As preparation for full signature verification move to calculating the
signature hash and exposing it, and then doing the verification in the
cleaning routine.

cleankey.c
sigcheck.c
sigcheck.h

index c7a69be28e78d2f124acb6a880573ccdcc429e32..52d482a486dac01eed5adab5b84f150f7a0ca222 100644 (file)
@@ -137,10 +137,28 @@ int clean_sighashes(struct openpgp_publickey *key,
                struct openpgp_packet_list **sigs)
 {
        struct openpgp_packet_list *tmpsig;
+       onak_status_t ret;
+       uint8_t hashtype;
+       uint8_t hash[64];
+       uint8_t *sighash;
        int removed = 0;
+       uint64_t keyid;
 
        while (*sigs != NULL) {
-               if (check_packet_sighash(key, sigdata, (*sigs)->packet) == 0) {
+               ret = calculate_packet_sighash(key, sigdata, (*sigs)->packet,
+                               &hashtype, hash, &sighash);
+
+               if (ret == ONAK_E_UNSUPPORTED_FEATURE) {
+                       get_keyid(key, &keyid);
+                       logthing(LOGTHING_ERROR,
+                               "Unsupported signature hash type %d on 0x%016"
+                               PRIX64,
+                               hashtype,
+                               keyid);
+                       sigs = &(*sigs)->next;
+               } else if (ret != ONAK_E_OK ||
+                               !(hash[0] == sighash[0] &&
+                                       hash[1] == sighash[1])) {
                        tmpsig = *sigs;
                        *sigs = (*sigs)->next;
                        tmpsig->next = NULL;
index 04f26760b1c3e3dd6fa0a50bd65364fbf1ff4fd1..0f93a31009c123e77fa0660eba76167bc7b72be7 100644 (file)
 #endif
 #include "sha1x.h"
 
-int check_packet_sighash(struct openpgp_publickey *key,
+onak_status_t calculate_packet_sighash(struct openpgp_publickey *key,
                        struct openpgp_packet *packet,
-                       struct openpgp_packet *sig)
+                       struct openpgp_packet *sig,
+                       uint8_t *hashtype,
+                       uint8_t *hash,
+                       uint8_t **sighash)
 {
-       uint8_t hashtype;
-       uint8_t *sighash;
        size_t siglen, unhashedlen;
        struct sha1_ctx sha1_context;
        struct sha1x_ctx sha1x_context;
@@ -56,7 +57,6 @@ int check_packet_sighash(struct openpgp_publickey *key,
        uint8_t keyheader[5];
        uint8_t packetheader[5];
        uint8_t trailer[10];
-       uint8_t hash[64];
        uint8_t *hashdata[8];
        size_t hashlen[8];
        int chunks, i;
@@ -75,7 +75,7 @@ int check_packet_sighash(struct openpgp_publickey *key,
                hashlen[1] = key->publickey->length;
                chunks = 2;
 
-               hashtype = sig->data[16];
+               *hashtype = sig->data[16];
 
                if (packet != NULL) {
                        if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
@@ -96,7 +96,7 @@ int check_packet_sighash(struct openpgp_publickey *key,
                hashdata[chunks] = &sig->data[2];
                hashlen[chunks] = 5;
                chunks++;
-               sighash = &sig->data[17];
+               *sighash = &sig->data[17];
                break;
        case 4:
                keyheader[0] = 0x99;
@@ -108,7 +108,7 @@ int check_packet_sighash(struct openpgp_publickey *key,
                hashlen[1] = key->publickey->length;
                chunks = 2;
 
-               hashtype = sig->data[3];
+               *hashtype = sig->data[3];
 
                /* Check to see if this is an X509 based signature */
                if (sig->data[2] == 0 || sig->data[2] == 100) {
@@ -119,8 +119,7 @@ int check_packet_sighash(struct openpgp_publickey *key,
                                                sig->length - 4, &len,
                                                &keyid, NULL);
                        if (res != ONAK_E_OK) {
-                               /* If it parses badly, reject it */
-                               return 0;
+                               return res;
                        }
                        if (keyid == 0 &&
                                        /* No unhashed data */
@@ -133,12 +132,7 @@ int check_packet_sighash(struct openpgp_publickey *key,
                                        sig->data[8 + len] == 0 &&
                                        sig->data[9 + len] == 1 &&
                                        sig->data[10 + len] == 1) {
-                               get_keyid(key, &keyid);
-                               logthing(LOGTHING_DEBUG,
-                                       "Skipping X509 signature on 0x%016"
-                                       PRIX64,
-                                       keyid);
-                               return -1;
+                               return ONAK_E_UNSUPPORTED_FEATURE;
                        }
                }
 
@@ -172,7 +166,7 @@ int check_packet_sighash(struct openpgp_publickey *key,
                        sig->data[5] + 6;;
                if (siglen > sig->length) {
                        /* Signature data exceed packet length, bogus */
-                       return 0;
+                       return ONAK_E_INVALID_PKT;
                }
                chunks++;
 
@@ -188,7 +182,7 @@ int check_packet_sighash(struct openpgp_publickey *key,
 
                unhashedlen = (sig->data[siglen] << 8) +
                        sig->data[siglen + 1];
-               sighash = &sig->data[siglen + unhashedlen + 2];
+               *sighash = &sig->data[siglen + unhashedlen + 2];
                break;
        case 5:
                keyheader[0] = 0x9A;
@@ -202,7 +196,7 @@ int check_packet_sighash(struct openpgp_publickey *key,
                hashlen[1] = key->publickey->length;
                chunks = 2;
 
-               hashtype = sig->data[3];
+               *hashtype = sig->data[3];
 
                if (packet != NULL) {
                        if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
@@ -236,7 +230,7 @@ int check_packet_sighash(struct openpgp_publickey *key,
                        sig->data[5] + 6;;
                if (siglen > sig->length) {
                        /* Signature data exceed packet length, bogus */
-                       return 0;
+                       return ONAK_E_INVALID_PKT;
                }
                chunks++;
 
@@ -256,17 +250,13 @@ int check_packet_sighash(struct openpgp_publickey *key,
 
                unhashedlen = (sig->data[siglen] << 8) +
                        sig->data[siglen + 1];
-               sighash = &sig->data[siglen + unhashedlen + 2];
+               *sighash = &sig->data[siglen + unhashedlen + 2];
                break;
        default:
-               get_keyid(key, &keyid);
-               logthing(LOGTHING_ERROR,
-                       "Unknown signature version %d on 0x%016" PRIX64,
-                       sig->data[0], keyid);
-               return -1;
+               return ONAK_E_UNSUPPORTED_FEATURE;
        }
 
-       switch (hashtype) {
+       switch (*hashtype) {
        case OPENPGP_HASH_MD5:
                md5_init(&md5_context);
                for (i = 0; i < chunks; i++) {
@@ -332,18 +322,8 @@ int check_packet_sighash(struct openpgp_publickey *key,
                break;
 #endif
        default:
-               get_keyid(key, &keyid);
-               logthing(LOGTHING_ERROR,
-                       "Unsupported signature hash type %d on 0x%016" PRIX64,
-                       hashtype,
-                       keyid);
-               return -1;
+               return ONAK_E_UNSUPPORTED_FEATURE;
        }
 
-       logthing(LOGTHING_DEBUG, "Hash type: %d, %d chunks, "
-               "calculated: %02X%02X / actual: %02X%02X",
-               hashtype, chunks,
-               hash[0], hash[1], sighash[0], sighash[1]);
-
-       return (hash[0] == sighash[0] && hash[1] == sighash[1]);
+       return ONAK_E_OK;
 }
index 394dd65f56b0a44ebe4cefd7d71601dc7a5f7421..756987e2b72745410769be0694f824e26cfd5c55 100644 (file)
@@ -2,8 +2,11 @@
 #define __SIGCHECK_H__
 #include "keystructs.h"
 
-int check_packet_sighash(struct openpgp_publickey *key,
+onak_status_t calculate_packet_sighash(struct openpgp_publickey *key,
                        struct openpgp_packet *packet,
-                       struct openpgp_packet *sig);
+                       struct openpgp_packet *sig,
+                       uint8_t *hashtype,
+                       uint8_t *hash,
+                       uint8_t **sighash);
 
 #endif /* __SIGCHECK_H__ */