sequoia: Track Sequoia API changes sync
authorNeal H. Walfield <neal@pep.foundation>
Fri, 10 May 2019 11:35:31 +0200
branchsync
changeset 3659bd1c82a4f0ff
parent 3658 733edb269d7d
child 3660 5baccf081566
sequoia: Track Sequoia API changes
src/pgp_sequoia.c
     1.1 --- a/src/pgp_sequoia.c	Fri May 10 09:12:39 2019 +0200
     1.2 +++ b/src/pgp_sequoia.c	Fri May 10 11:35:31 2019 +0200
     1.3 @@ -1036,85 +1036,145 @@
     1.4  }
     1.5  
     1.6  static pgp_status_t
     1.7 -check_signatures_cb(void *cookie_opaque,
     1.8 -                   pgp_verification_results_t results, size_t levels)
     1.9 +check_signatures_cb(void *cookie_opaque, pgp_message_structure_t structure)
    1.10  {
    1.11      struct decrypt_cookie *cookie = cookie_opaque;
    1.12      PEP_SESSION session = cookie->session;
    1.13  
    1.14 -    int level;
    1.15 -    for (level = 0; level < levels; level ++) {
    1.16 -        pgp_verification_result_t *vrs;
    1.17 -        size_t vr_count;
    1.18 -        pgp_verification_results_at_level(results, level, &vrs, &vr_count);
    1.19 +    pgp_message_structure_iter_t iter
    1.20 +        = pgp_message_structure_iter (structure);
    1.21 +    for (pgp_message_layer_t layer = pgp_message_structure_iter_next (iter);
    1.22 +         layer;
    1.23 +         layer = pgp_message_structure_iter_next (iter)) {
    1.24 +        pgp_verification_result_iter_t results;
    1.25  
    1.26 -        int i;
    1.27 -        for (i = 0; i < vr_count; i ++) {
    1.28 -            pgp_tpk_t tpk = NULL;
    1.29 -            pgp_verification_result_code_t code
    1.30 -                = pgp_verification_result_code(vrs[i]);
    1.31 +        switch (pgp_message_layer_variant (layer)) {
    1.32 +        case PGP_MESSAGE_LAYER_COMPRESSION:
    1.33 +        case PGP_MESSAGE_LAYER_ENCRYPTION:
    1.34 +            break;
    1.35  
    1.36 -            if (code == PGP_VERIFICATION_RESULT_CODE_BAD_CHECKSUM) {
    1.37 -                cookie->bad_checksums ++;
    1.38 -                continue;
    1.39 +        case PGP_MESSAGE_LAYER_SIGNATURE_GROUP:
    1.40 +            pgp_message_layer_signature_group(layer, &results);
    1.41 +            pgp_verification_result_t result;
    1.42 +            while ((result = pgp_verification_result_iter_next (results))) {
    1.43 +                pgp_signature_t sig;
    1.44 +                pgp_keyid_t keyid = NULL;
    1.45 +                char *keyid_str = NULL;
    1.46 +
    1.47 +                switch (pgp_verification_result_variant (result)) {
    1.48 +                case PGP_VERIFICATION_RESULT_GOOD_CHECKSUM:
    1.49 +                    // We need to add the fingerprint of the primary
    1.50 +                    // key to cookie->signer_keylist.
    1.51 +
    1.52 +                    pgp_verification_result_good_checksum (result, &sig, NULL,
    1.53 +                                                           NULL, NULL, NULL);
    1.54 +
    1.55 +                    // First try looking up by the TPK using the
    1.56 +                    // IssuerFingerprint subpacket.
    1.57 +                    pgp_fingerprint_t fpr
    1.58 +                        = pgp_signature_issuer_fingerprint(sig);
    1.59 +                    if (fpr) {
    1.60 +                        // Even though we have a fingerprint, we have
    1.61 +                        // to look the key up by keyid, because we
    1.62 +                        // want to match on subkeys and we only store
    1.63 +                        // keyids for subkeys.
    1.64 +                        keyid = pgp_fingerprint_to_keyid(fpr);
    1.65 +                        pgp_fingerprint_free(fpr);
    1.66 +                    } else {
    1.67 +                        // That is not available, try using the Issuer
    1.68 +                        // subpacket.
    1.69 +                        keyid = pgp_signature_issuer(sig);
    1.70 +                    }
    1.71 +
    1.72 +                    if (! keyid) {
    1.73 +                        T("signature with no Issuer or Issuer Fingerprint subpacket!");
    1.74 +                        goto eol;
    1.75 +                    }
    1.76 +
    1.77 +                    pgp_tpk_t tpk;
    1.78 +                    if (tpk_find_by_keyid(session, keyid, false,
    1.79 +                                          &tpk, NULL) != PEP_STATUS_OK)
    1.80 +                        ; // Soft error.  Ignore.
    1.81 +
    1.82 +                    if (tpk) {
    1.83 +                        // Ok, we have a TPK.
    1.84 +
    1.85 +                        // We need the primary key's fingerprint (not
    1.86 +                        // the issuer fingerprint).
    1.87 +                        pgp_fingerprint_t primary_fpr
    1.88 +                            = pgp_tpk_fingerprint(tpk);
    1.89 +                        char *primary_fpr_str
    1.90 +                            = pgp_fingerprint_to_hex(primary_fpr);
    1.91 +                        stringlist_add_unique(cookie->signer_keylist,
    1.92 +                                              primary_fpr_str);
    1.93 +
    1.94 +                        T("Good signature from %s", primary_fpr_str);
    1.95 +
    1.96 +                        // XXX: Check that the TPK and the key used to make
    1.97 +                        // the signature and the signature itself are alive
    1.98 +                        // and not revoked.  Revoked =>
    1.99 +                        // PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH; Expired key
   1.100 +                        // or sig => PEP_DECRYPTED.
   1.101 +                        cookie->good_checksums ++;
   1.102 +
   1.103 +                        free(primary_fpr_str);
   1.104 +                        pgp_fingerprint_free(primary_fpr);
   1.105 +                        pgp_tpk_free(tpk);
   1.106 +                    } else {
   1.107 +                        // If we get
   1.108 +                        // PGP_VERIFICATION_RESULT_CODE_GOOD_CHECKSUM, then the
   1.109 +                        // TPK should be available.  But, another process
   1.110 +                        // could have deleted the key from the store in the
   1.111 +                        // mean time, so be tolerant.
   1.112 +                        T("Key to check signature from %s disappeared",
   1.113 +                          keyid_str);
   1.114 +                        cookie->missing_keys ++;
   1.115 +                    }
   1.116 +                    break;
   1.117 +
   1.118 +                case PGP_VERIFICATION_RESULT_MISSING_KEY:
   1.119 +                    pgp_verification_result_missing_key (result, &sig);
   1.120 +                    keyid = pgp_signature_issuer (sig);
   1.121 +                    keyid_str = pgp_keyid_to_string (keyid);
   1.122 +                    T("No key to check signature from %s", keyid_str);
   1.123 +
   1.124 +                    cookie->missing_keys ++;
   1.125 +                    break;
   1.126 +
   1.127 +                case PGP_VERIFICATION_RESULT_BAD_CHECKSUM:
   1.128 +                    pgp_verification_result_bad_checksum (result, &sig);
   1.129 +                    keyid = pgp_signature_issuer (sig);
   1.130 +                    if (keyid) {
   1.131 +                        keyid_str = pgp_keyid_to_string (keyid);
   1.132 +                        T("Bad signature from %s", keyid_str);
   1.133 +                    } else {
   1.134 +                        T("Bad signature without issuer information");
   1.135 +                    }
   1.136 +
   1.137 +                    cookie->bad_checksums ++;
   1.138 +                    break;
   1.139 +
   1.140 +                default:
   1.141 +                    assert (! "reachable");
   1.142 +                }
   1.143 +
   1.144 +            eol:
   1.145 +                free (keyid_str);
   1.146 +                pgp_signature_free (sig);
   1.147 +                pgp_verification_result_free (result);
   1.148              }
   1.149 -            if (code == PGP_VERIFICATION_RESULT_CODE_MISSING_KEY) {
   1.150 -                // No key, nothing we can do.
   1.151 -                cookie->missing_keys ++;
   1.152 -                continue;
   1.153 -            }
   1.154 +            pgp_verification_result_iter_free (results);
   1.155 +            break;
   1.156  
   1.157 -            // We need to add the fingerprint of the primary key to
   1.158 -            // cookie->signer_keylist.
   1.159 -            pgp_signature_t sig = pgp_verification_result_signature(vrs[i]);
   1.160 +        default:
   1.161 +            assert (! "reachable");
   1.162 +        }
   1.163  
   1.164 -            // First try looking up by the TPK using the
   1.165 -            // IssuerFingerprint subpacket.
   1.166 -            pgp_fingerprint_t issuer_fp = pgp_signature_issuer_fingerprint(sig);
   1.167 -            if (issuer_fp) {
   1.168 -                pgp_keyid_t issuer = pgp_fingerprint_to_keyid(issuer_fp);
   1.169 -                if (tpk_find_by_keyid(session, issuer, false, &tpk, NULL) != PEP_STATUS_OK)
   1.170 -                    ; // Soft error.  Ignore.
   1.171 -                pgp_keyid_free(issuer);
   1.172 -                pgp_fingerprint_free(issuer_fp);
   1.173 -            }
   1.174 +        pgp_message_layer_free (layer);
   1.175 +    }
   1.176  
   1.177 -            // If that is not available, try using the Issuer subpacket.
   1.178 -            if (!tpk) {
   1.179 -                pgp_keyid_t issuer = pgp_signature_issuer(sig);
   1.180 -                if (issuer) {
   1.181 -                    if (tpk_find_by_keyid(session, issuer, false, &tpk, NULL) != PEP_STATUS_OK)
   1.182 -                        ; // Soft error.  Ignore.
   1.183 -                }
   1.184 -                pgp_keyid_free(issuer);
   1.185 -            }
   1.186 -
   1.187 -            if (tpk) {
   1.188 -                // Ok, we have a TPK.
   1.189 -                pgp_fingerprint_t fp = pgp_tpk_fingerprint(tpk);
   1.190 -                char *fp_str = pgp_fingerprint_to_hex(fp);
   1.191 -                stringlist_add_unique(cookie->signer_keylist, fp_str);
   1.192 -
   1.193 -                // XXX: Check that the TPK and the key used to make
   1.194 -                // the signature and the signature itself are alive
   1.195 -                // and not revoked.  Revoked =>
   1.196 -                // PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH; Expired key
   1.197 -                // or sig => PEP_DECRYPTED.
   1.198 -                cookie->good_checksums ++;
   1.199 -
   1.200 -                free(fp_str);
   1.201 -                pgp_fingerprint_free(fp);
   1.202 -                pgp_tpk_free(tpk);
   1.203 -            } else {
   1.204 -                // If we get
   1.205 -                // PGP_VERIFICATION_RESULT_CODE_GOOD_CHECKSUM, then the
   1.206 -                // TPK should be available.  But, another process
   1.207 -                // could have deleted the key from the store in the
   1.208 -                // mean time, so be tolerant.
   1.209 -                cookie->missing_keys ++;
   1.210 -            }
   1.211 -        }
   1.212 -    }
   1.213 +    pgp_message_structure_iter_free (iter);
   1.214 +    pgp_message_structure_free (structure);
   1.215  
   1.216      return PGP_STATUS_SUCCESS;
   1.217  }