Update pgp_sequoia.c to latest sequoia version. sync
authorNeal H. Walfield <neal@pep.foundation>
Sun, 24 Nov 2019 12:48:26 +0100
branchsync
changeset 4217738d4cbc5af5
parent 4216 de70d8f412cf
child 4220 fa9a1793f6e0
Update pgp_sequoia.c to latest sequoia version.

- Use the 'pep-engine' branch.
src/pgp_sequoia.c
     1.1 --- a/src/pgp_sequoia.c	Sat Nov 23 19:47:08 2019 +0100
     1.2 +++ b/src/pgp_sequoia.c	Sun Nov 24 12:48:26 2019 +0100
     1.3 @@ -173,17 +173,15 @@
     1.4      pgp_packet_t a_userid = pgp_user_id_from_raw (a, a_len);
     1.5      pgp_packet_t b_userid = pgp_user_id_from_raw (b, b_len);
     1.6  
     1.7 -    T("(%.*s, %.*s)", a_len, (const char *) a, b_len, (const char *) b);
     1.8 -
     1.9 -    char *a_address = NULL;
    1.10 -    pgp_user_id_address_normalized(NULL, a_userid, &a_address);
    1.11 -    if (!a_address)
    1.12 -        pgp_user_id_other(NULL, a_userid, &a_address);
    1.13 -
    1.14 -    char *b_address = NULL;
    1.15 -    pgp_user_id_address_normalized(NULL, b_userid, &b_address);
    1.16 -    if (!b_address)
    1.17 -        pgp_user_id_other(NULL, b_userid, &b_address);
    1.18 +    char *a_email = NULL;
    1.19 +    pgp_user_id_email_normalized(NULL, a_userid, &a_email);
    1.20 +    if (!a_email)
    1.21 +        pgp_user_id_uri(NULL, a_userid, &a_email);
    1.22 +
    1.23 +    char *b_email = NULL;
    1.24 +    pgp_user_id_email_normalized(NULL, b_userid, &b_email);
    1.25 +    if (!b_email)
    1.26 +        pgp_user_id_uri(NULL, b_userid, &b_email);
    1.27  
    1.28      pgp_packet_free(a_userid);
    1.29      pgp_packet_free(b_userid);
    1.30 @@ -192,24 +190,24 @@
    1.31      // first string is less than, equal to, or greater than the
    1.32      // second, respectively.
    1.33      int result;
    1.34 -    if (!a_address && !b_address)
    1.35 +    if (!a_email && !b_email)
    1.36          result = 0;
    1.37 -    else if (!a_address)
    1.38 +    else if (!a_email)
    1.39          result = -1;
    1.40 -    else if (!b_address)
    1.41 +    else if (!b_email)
    1.42          result = 1;
    1.43      else
    1.44 -        result = strcmp(a_address, b_address);
    1.45 +        result = strcmp(a_email, b_email);
    1.46  
    1.47      if (true) {
    1.48          T("'%s' %s '%s'",
    1.49 -          a_address,
    1.50 +          a_email,
    1.51            result == 0 ? "==" : result < 0 ? "<" : ">",
    1.52 -          b_address);
    1.53 +          b_email);
    1.54      }
    1.55  
    1.56 -    free(a_address);
    1.57 -    free(b_address);
    1.58 +    free(a_email);
    1.59 +    free(b_email);
    1.60  
    1.61      return result;
    1.62  }
    1.63 @@ -792,7 +790,7 @@
    1.64      pgp_tsk_t tsk = pgp_tpk_as_tsk(tpk);
    1.65      pgp_status = pgp_tsk_serialize(&err, tsk, writer);
    1.66      pgp_tsk_free(tsk);
    1.67 -    //pgp_writer_free(writer);
    1.68 +    pgp_writer_free(writer);
    1.69      if (pgp_status != 0)
    1.70          ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Serializing TPK");
    1.71  
    1.72 @@ -858,7 +856,12 @@
    1.73  
    1.74          pgp_packet_t userid = pgp_user_id_new (user_id_value);
    1.75          pgp_user_id_name(NULL, userid, &name);
    1.76 -        pgp_user_id_address_or_other(NULL, userid, &email);
    1.77 +        // Try to get the normalized address.
    1.78 +        pgp_user_id_email_normalized(NULL, userid, &email);
    1.79 +        if (! email)
    1.80 +            // Ok, it's not a proper RFC 2822 name-addr.  Perhaps it
    1.81 +            // is a URI.
    1.82 +            pgp_user_id_uri(NULL, userid, &email);
    1.83          pgp_packet_free(userid);
    1.84          free(user_id_value);
    1.85  
    1.86 @@ -1240,7 +1243,7 @@
    1.87                          // Make sure the TPK is not revoked, it's
    1.88                          // creation time is <= now, and it hasn't
    1.89                          // expired.
    1.90 -                        pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
    1.91 +                        pgp_revocation_status_t rs = pgp_tpk_revoked(tpk, 0);
    1.92                          bool revoked = (pgp_revocation_status_variant(rs)
    1.93                                          == PGP_REVOCATION_STATUS_REVOKED);
    1.94                          pgp_revocation_status_free(rs);
    1.95 @@ -1248,7 +1251,7 @@
    1.96                              T("TPK %s is revoked.", primary_fpr_str);
    1.97                              good = false;
    1.98                              cookie->good_but_revoked ++;
    1.99 -                        } else if (! pgp_tpk_alive(tpk)) {
   1.100 +                        } else if (! pgp_tpk_alive(tpk, 0)) {
   1.101                              T("TPK %s is not alive.", primary_fpr_str);
   1.102                              good = false;
   1.103                              cookie->good_but_expired ++;
   1.104 @@ -1273,7 +1276,7 @@
   1.105                                            primary_fpr_str, keyid_str);
   1.106                                          good = false;
   1.107                                          cookie->good_but_revoked ++;
   1.108 -                                    } else if (! pgp_signature_key_alive(sig, key)) {
   1.109 +                                    } else if (! pgp_signature_key_alive(sig, key, 0)) {
   1.110                                          T("TPK %s's signing key %s is expired.",
   1.111                                            primary_fpr_str, keyid_str);
   1.112                                          good = false;
   1.113 @@ -1671,6 +1674,8 @@
   1.114      ws = pgp_signer_new_detached(&err, ws, &signer, 1, 0);
   1.115      if (!ws)
   1.116          ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up signer");
   1.117 +    // pgp_signer_new_detached consumes signer.
   1.118 +    signer = NULL;
   1.119  
   1.120      pgp_status_t write_status =
   1.121          pgp_writer_stack_write_all (&err, ws,
   1.122 @@ -1692,7 +1697,11 @@
   1.123  
   1.124   out:
   1.125      pgp_signer_free (signer);
   1.126 -    pgp_key_pair_free (signing_keypair);
   1.127 +    // XXX: pgp_key_pair_as_signer is only supposed to reference
   1.128 +    // signing_keypair, but it consumes it.  If this is fixed, this
   1.129 +    // will become a leak.
   1.130 +    //
   1.131 +    //pgp_key_pair_free (signing_keypair);
   1.132      pgp_tpk_key_iter_free (iter);
   1.133      pgp_tpk_free(signer_tpk);
   1.134  
   1.135 @@ -1706,8 +1715,16 @@
   1.136  {
   1.137      PEP_STATUS status = PEP_STATUS_OK;
   1.138      pgp_error_t err = NULL;
   1.139 -    int keys_count = 0;
   1.140 -    pgp_tpk_t *keys = NULL;
   1.141 +
   1.142 +    int recipient_tpk_count = 0;
   1.143 +    pgp_tpk_t *recipient_tpks = NULL;
   1.144 +
   1.145 +    int recipient_count = 0;
   1.146 +    int recipient_alloc = 0;
   1.147 +    pgp_recipient_t *recipients = NULL;
   1.148 +    int recipient_keys_count = 0;
   1.149 +    pgp_key_t *recipient_keys = NULL;
   1.150 +
   1.151      pgp_tpk_t signer_tpk = NULL;
   1.152      pgp_writer_stack_t ws = NULL;
   1.153      pgp_tpk_key_iter_t iter = NULL;
   1.154 @@ -1724,18 +1741,82 @@
   1.155      *ctext = NULL;
   1.156      *csize = 0;
   1.157  
   1.158 -    keys = calloc(stringlist_length(keylist), sizeof(*keys));
   1.159 -    if (keys == NULL)
   1.160 +    int keylist_len = stringlist_length(keylist);
   1.161 +
   1.162 +    // We don't need to worry about extending recipient_tpks, because
   1.163 +    // there will be at most KEYLIST_LEN tpks, which we allocate up
   1.164 +    // front.
   1.165 +    recipient_tpks = calloc(keylist_len, sizeof(*recipient_tpks));
   1.166 +    if (recipient_tpks == NULL)
   1.167          ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   1.168  
   1.169 +    // Because there may be multiple encryption keys per TPK, we may
   1.170 +    // need to extend recipient_keys and recipients.
   1.171 +    recipient_alloc = keylist_len;
   1.172 +    recipient_keys = calloc(recipient_alloc, sizeof(*recipient_keys));
   1.173 +    if (recipient_keys == NULL)
   1.174 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   1.175 +
   1.176 +    recipients = calloc(recipient_alloc, sizeof(*recipients));
   1.177 +    if (recipients == NULL)
   1.178 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   1.179 +
   1.180 +
   1.181      // Get the keys for the recipients.
   1.182      const stringlist_t *_keylist;
   1.183      for (_keylist = keylist; _keylist != NULL; _keylist = _keylist->next) {
   1.184          assert(_keylist->value);
   1.185 -        pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(_keylist->value);
   1.186 -        status = tpk_find_by_fpr(session, pgp_fpr, false, &keys[keys_count ++], NULL);
   1.187 -        pgp_fingerprint_free(pgp_fpr);
   1.188 -        ERROR_OUT(NULL, status, "Looking up key for recipient '%s'", _keylist->value);
   1.189 +
   1.190 +        pgp_tpk_t tpk;
   1.191 +        status = tpk_find_by_fpr_hex(session, _keylist->value,
   1.192 +                                     false, &tpk, NULL);
   1.193 +        // We couldn't find a key for this recipient.
   1.194 +        ERROR_OUT(NULL, status,
   1.195 +                  "Looking up key for recipient '%s'", _keylist->value);
   1.196 +
   1.197 +        recipient_tpks[recipient_tpk_count ++] = tpk;
   1.198 +
   1.199 +        // Collect all of the keys that have the encryption for
   1.200 +        // transport capability.
   1.201 +        pgp_tpk_key_iter_t iter = pgp_tpk_key_iter_valid(tpk);
   1.202 +        if (! iter)
   1.203 +            ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   1.204 +        pgp_tpk_key_iter_encrypting_capable_for_transport(iter);
   1.205 +
   1.206 +        pgp_key_t key;
   1.207 +        while ((key = pgp_tpk_key_iter_next (iter, NULL, NULL))) {
   1.208 +            assert(recipient_count == recipient_keys_count);
   1.209 +            if (recipient_count == recipient_alloc) {
   1.210 +                assert(recipient_alloc > 0);
   1.211 +                recipient_alloc *= 2;
   1.212 +
   1.213 +                void *t = reallocarray(recipient_keys, recipient_alloc,
   1.214 +                                       sizeof(*recipient_keys));
   1.215 +                if (! t)
   1.216 +                    ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   1.217 +                recipient_keys = t;
   1.218 +
   1.219 +                t = reallocarray(recipients, recipient_alloc,
   1.220 +                                 sizeof(*recipients));
   1.221 +                if (! t)
   1.222 +                    ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   1.223 +                recipients = t;
   1.224 +            }
   1.225 +
   1.226 +            // pgp_recipient_new consumes the passed key id, but it
   1.227 +            // only references key (i.e., we still have to free key).
   1.228 +            pgp_keyid_t keyid = pgp_key_keyid(key);
   1.229 +            if (! key)
   1.230 +                ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   1.231 +
   1.232 +            key = pgp_key_clone(key);
   1.233 +            if (! key)
   1.234 +                ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   1.235 +            recipient_keys[recipient_keys_count++] = key;
   1.236 +
   1.237 +            recipients[recipient_count++] = pgp_recipient_new(keyid, key);
   1.238 +        }
   1.239 +        pgp_tpk_key_iter_free(iter);
   1.240      }
   1.241  
   1.242      if (sign) {
   1.243 @@ -1752,11 +1833,14 @@
   1.244  
   1.245      ws = pgp_writer_stack_message(writer);
   1.246      ws = pgp_encryptor_new (&err, ws,
   1.247 -                            NULL, 0, keys, keys_count,
   1.248 -                            PGP_ENCRYPTION_MODE_FOR_TRANSPORT, 0);
   1.249 +                            NULL, 0, recipients, recipient_count,
   1.250 +                            0, 0);
   1.251      if (!ws)
   1.252          ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up encryptor");
   1.253  
   1.254 +    // pgp_encrypt_new consumes the recipients (but not the keys).
   1.255 +    recipient_count = 0;
   1.256 +
   1.257      if (sign) {
   1.258          iter = pgp_tpk_key_iter_valid(signer_tpk);
   1.259          pgp_tpk_key_iter_signing_capable (iter);
   1.260 @@ -1780,6 +1864,8 @@
   1.261          ws = pgp_signer_new(&err, ws, &signer, 1, 0);
   1.262          if (!ws)
   1.263              ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up signer");
   1.264 +        // pgp_signer_new consumes signer.
   1.265 +        signer = NULL;
   1.266      }
   1.267  
   1.268      ws = pgp_literal_writer_new (&err, ws);
   1.269 @@ -1811,13 +1897,23 @@
   1.270  
   1.271   out:
   1.272      pgp_signer_free (signer);
   1.273 -    pgp_key_pair_free (signing_keypair);
   1.274 +    // XXX: pgp_key_pair_as_signer is only supposed to reference
   1.275 +    // signing_keypair, but it consumes it.  If this is fixed, this
   1.276 +    // will become a leak.
   1.277 +    //
   1.278 +    // pgp_key_pair_free (signing_keypair);
   1.279      pgp_tpk_key_iter_free (iter);
   1.280      pgp_tpk_free(signer_tpk);
   1.281  
   1.282 -    for (int i = 0; i < keys_count; i ++)
   1.283 -        pgp_tpk_free(keys[i]);
   1.284 -    free(keys);
   1.285 +    for (int i = 0; i < recipient_count; i ++)
   1.286 +        pgp_recipient_free(recipients[i]);
   1.287 +    free(recipients);
   1.288 +    for (int i = 0; i < recipient_keys_count; i ++)
   1.289 +        pgp_key_free(recipient_keys[i]);
   1.290 +    free(recipient_keys);
   1.291 +    for (int i = 0; i < recipient_tpk_count; i ++)
   1.292 +        pgp_tpk_free(recipient_tpks[i]);
   1.293 +    free(recipient_tpks);
   1.294  
   1.295      T("-> %s", pEp_status_to_string(status));
   1.296      return status;
   1.297 @@ -2269,7 +2365,7 @@
   1.298      bool revoked = false;
   1.299      // Don't add revoked keys to the keyinfo_list.
   1.300      if (keyinfo_list) {
   1.301 -        pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
   1.302 +        pgp_revocation_status_t rs = pgp_tpk_revoked(tpk, 0);
   1.303          pgp_revocation_status_variant_t rsv = pgp_revocation_status_variant(rs);
   1.304          pgp_revocation_status_free(rs);
   1.305          if (rsv == PGP_REVOCATION_STATUS_REVOKED)
   1.306 @@ -2471,7 +2567,7 @@
   1.307      status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
   1.308      ERROR_OUT(NULL, status, "Looking up '%s'", fpr);
   1.309  
   1.310 -    uint32_t creation_time = pgp_key_creation_time(pgp_tpk_primary(tpk));
   1.311 +    uint32_t creation_time = pgp_key_creation_time(pgp_tpk_primary_key(tpk));
   1.312      if (creation_time > t)
   1.313          // The creation time is after the expiration time!
   1.314          ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   1.315 @@ -2509,6 +2605,10 @@
   1.316  
   1.317   out:
   1.318      pgp_signer_free (signer);
   1.319 +    // XXX: pgp_key_pair_as_signer is only supposed to reference
   1.320 +    // signing_keypair, but it consumes it.  If this is fixed, this
   1.321 +    // will become a leak.
   1.322 +    //
   1.323      pgp_key_pair_free (keypair);
   1.324      pgp_tpk_key_iter_free (iter);
   1.325      pgp_tpk_free(tpk);
   1.326 @@ -2557,7 +2657,7 @@
   1.327      if (! tpk)
   1.328          ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
   1.329  
   1.330 -    assert(pgp_revocation_status_variant(pgp_tpk_revocation_status(tpk))
   1.331 +    assert(pgp_revocation_status_variant(pgp_tpk_revoked(tpk, 0))
   1.332             == PGP_REVOCATION_STATUS_REVOKED);
   1.333  
   1.334      status = tpk_save(session, tpk, NULL);
   1.335 @@ -2577,7 +2677,7 @@
   1.336  static void _pgp_key_expired(pgp_tpk_t tpk, const time_t when, bool* expired)
   1.337  {
   1.338      // Is the TPK live?
   1.339 -    *expired = !pgp_tpk_alive_at(tpk, when);
   1.340 +    *expired = !pgp_tpk_alive(tpk, when);
   1.341  
   1.342  #ifdef TRACING
   1.343      {
   1.344 @@ -2635,7 +2735,7 @@
   1.345        
   1.346  out:
   1.347      // Er, this might be problematic in terms of internal vs. external in log. FIXME?
   1.348 -    T("(%s) -> %s (expired: %d)", fpr, pEp_status_to_string(status), *expired);
   1.349 +    T(" -> expired: %d", *expired);
   1.350      return;
   1.351  }
   1.352                              
   1.353 @@ -2682,7 +2782,7 @@
   1.354      pgp_fingerprint_free(pgp_fpr);
   1.355      ERROR_OUT(NULL, status, "Looking up %s", fpr);
   1.356  
   1.357 -    pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
   1.358 +    pgp_revocation_status_t rs = pgp_tpk_revoked(tpk, 0);
   1.359      *revoked = pgp_revocation_status_variant(rs) == PGP_REVOCATION_STATUS_REVOKED;
   1.360      pgp_revocation_status_free (rs);
   1.361      pgp_tpk_free(tpk);
   1.362 @@ -2726,7 +2826,7 @@
   1.363      //     goto out;
   1.364      // }
   1.365  
   1.366 -    pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
   1.367 +    pgp_revocation_status_t rs = pgp_tpk_revoked(tpk, 0);
   1.368      pgp_revocation_status_variant_t rsv = pgp_revocation_status_variant(rs);
   1.369      pgp_revocation_status_free(rs);
   1.370      if (rsv == PGP_REVOCATION_STATUS_REVOKED) {
   1.371 @@ -2800,7 +2900,7 @@
   1.372      pgp_fingerprint_free(pgp_fpr);
   1.373      ERROR_OUT(NULL, status, "Looking up %s", fpr);
   1.374  
   1.375 -    pgp_key_t k = pgp_tpk_primary(tpk);
   1.376 +    pgp_key_t k = pgp_tpk_primary_key(tpk);
   1.377      *created = pgp_key_creation_time(k);
   1.378      pgp_tpk_free(tpk);
   1.379