Browse Source

Update pgp_sequoia.c to latest sequoia version.

- Use the 'pep-engine' branch.
add_key_notification
Neal Walfield 3 years ago
parent
commit
6146a73daa
1 changed files with 146 additions and 46 deletions
  1. +146
    -46
      src/pgp_sequoia.c

+ 146
- 46
src/pgp_sequoia.c View File

@ -173,17 +173,15 @@ int email_cmp(void *cookie, int a_len, const void *a, int b_len, const void *b)
pgp_packet_t a_userid = pgp_user_id_from_raw (a, a_len);
pgp_packet_t b_userid = pgp_user_id_from_raw (b, b_len);
T("(%.*s, %.*s)", a_len, (const char *) a, b_len, (const char *) b);
char *a_email = NULL;
pgp_user_id_email_normalized(NULL, a_userid, &a_email);
if (!a_email)
pgp_user_id_uri(NULL, a_userid, &a_email);
char *a_address = NULL;
pgp_user_id_address_normalized(NULL, a_userid, &a_address);
if (!a_address)
pgp_user_id_other(NULL, a_userid, &a_address);
char *b_address = NULL;
pgp_user_id_address_normalized(NULL, b_userid, &b_address);
if (!b_address)
pgp_user_id_other(NULL, b_userid, &b_address);
char *b_email = NULL;
pgp_user_id_email_normalized(NULL, b_userid, &b_email);
if (!b_email)
pgp_user_id_uri(NULL, b_userid, &b_email);
pgp_packet_free(a_userid);
pgp_packet_free(b_userid);
@ -192,24 +190,24 @@ int email_cmp(void *cookie, int a_len, const void *a, int b_len, const void *b)
// first string is less than, equal to, or greater than the
// second, respectively.
int result;
if (!a_address && !b_address)
if (!a_email && !b_email)
result = 0;
else if (!a_address)
else if (!a_email)
result = -1;
else if (!b_address)
else if (!b_email)
result = 1;
else
result = strcmp(a_address, b_address);
result = strcmp(a_email, b_email);
if (true) {
T("'%s' %s '%s'",
a_address,
a_email,
result == 0 ? "==" : result < 0 ? "<" : ">",
b_address);
b_email);
}
free(a_address);
free(b_address);
free(a_email);
free(b_email);
return result;
}
@ -792,7 +790,7 @@ static PEP_STATUS tpk_save(PEP_SESSION session, pgp_tpk_t tpk,
pgp_tsk_t tsk = pgp_tpk_as_tsk(tpk);
pgp_status = pgp_tsk_serialize(&err, tsk, writer);
pgp_tsk_free(tsk);
//pgp_writer_free(writer);
pgp_writer_free(writer);
if (pgp_status != 0)
ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Serializing TPK");
@ -858,7 +856,12 @@ static PEP_STATUS tpk_save(PEP_SESSION session, pgp_tpk_t tpk,
pgp_packet_t userid = pgp_user_id_new (user_id_value);
pgp_user_id_name(NULL, userid, &name);
pgp_user_id_address_or_other(NULL, userid, &email);
// Try to get the normalized address.
pgp_user_id_email_normalized(NULL, userid, &email);
if (! email)
// Ok, it's not a proper RFC 2822 name-addr. Perhaps it
// is a URI.
pgp_user_id_uri(NULL, userid, &email);
pgp_packet_free(userid);
free(user_id_value);
@ -1240,7 +1243,7 @@ check_signatures_cb(void *cookie_opaque, pgp_message_structure_t structure)
// Make sure the TPK is not revoked, it's
// creation time is <= now, and it hasn't
// expired.
pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
pgp_revocation_status_t rs = pgp_tpk_revoked(tpk, 0);
bool revoked = (pgp_revocation_status_variant(rs)
== PGP_REVOCATION_STATUS_REVOKED);
pgp_revocation_status_free(rs);
@ -1248,7 +1251,7 @@ check_signatures_cb(void *cookie_opaque, pgp_message_structure_t structure)
T("TPK %s is revoked.", primary_fpr_str);
good = false;
cookie->good_but_revoked ++;
} else if (! pgp_tpk_alive(tpk)) {
} else if (! pgp_tpk_alive(tpk, 0)) {
T("TPK %s is not alive.", primary_fpr_str);
good = false;
cookie->good_but_expired ++;
@ -1273,7 +1276,7 @@ check_signatures_cb(void *cookie_opaque, pgp_message_structure_t structure)
primary_fpr_str, keyid_str);
good = false;
cookie->good_but_revoked ++;
} else if (! pgp_signature_key_alive(sig, key)) {
} else if (! pgp_signature_key_alive(sig, key, 0)) {
T("TPK %s's signing key %s is expired.",
primary_fpr_str, keyid_str);
good = false;
@ -1671,6 +1674,8 @@ PEP_STATUS pgp_sign_only(
ws = pgp_signer_new_detached(&err, ws, &signer, 1, 0);
if (!ws)
ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up signer");
// pgp_signer_new_detached consumes signer.
signer = NULL;
pgp_status_t write_status =
pgp_writer_stack_write_all (&err, ws,
@ -1692,7 +1697,11 @@ PEP_STATUS pgp_sign_only(
out:
pgp_signer_free (signer);
pgp_key_pair_free (signing_keypair);
// XXX: pgp_key_pair_as_signer is only supposed to reference
// signing_keypair, but it consumes it. If this is fixed, this
// will become a leak.
//
//pgp_key_pair_free (signing_keypair);
pgp_tpk_key_iter_free (iter);
pgp_tpk_free(signer_tpk);
@ -1706,8 +1715,16 @@ static PEP_STATUS pgp_encrypt_sign_optional(
{
PEP_STATUS status = PEP_STATUS_OK;
pgp_error_t err = NULL;
int keys_count = 0;
pgp_tpk_t *keys = NULL;
int recipient_tpk_count = 0;
pgp_tpk_t *recipient_tpks = NULL;
int recipient_count = 0;
int recipient_alloc = 0;
pgp_recipient_t *recipients = NULL;
int recipient_keys_count = 0;
pgp_key_t *recipient_keys = NULL;
pgp_tpk_t signer_tpk = NULL;
pgp_writer_stack_t ws = NULL;
pgp_tpk_key_iter_t iter = NULL;
@ -1724,18 +1741,82 @@ static PEP_STATUS pgp_encrypt_sign_optional(
*ctext = NULL;
*csize = 0;
keys = calloc(stringlist_length(keylist), sizeof(*keys));
if (keys == NULL)
int keylist_len = stringlist_length(keylist);
// We don't need to worry about extending recipient_tpks, because
// there will be at most KEYLIST_LEN tpks, which we allocate up
// front.
recipient_tpks = calloc(keylist_len, sizeof(*recipient_tpks));
if (recipient_tpks == NULL)
ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
// Because there may be multiple encryption keys per TPK, we may
// need to extend recipient_keys and recipients.
recipient_alloc = keylist_len;
recipient_keys = calloc(recipient_alloc, sizeof(*recipient_keys));
if (recipient_keys == NULL)
ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
recipients = calloc(recipient_alloc, sizeof(*recipients));
if (recipients == NULL)
ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
// Get the keys for the recipients.
const stringlist_t *_keylist;
for (_keylist = keylist; _keylist != NULL; _keylist = _keylist->next) {
assert(_keylist->value);
pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(_keylist->value);
status = tpk_find_by_fpr(session, pgp_fpr, false, &keys[keys_count ++], NULL);
pgp_fingerprint_free(pgp_fpr);
ERROR_OUT(NULL, status, "Looking up key for recipient '%s'", _keylist->value);
pgp_tpk_t tpk;
status = tpk_find_by_fpr_hex(session, _keylist->value,
false, &tpk, NULL);
// We couldn't find a key for this recipient.
ERROR_OUT(NULL, status,
"Looking up key for recipient '%s'", _keylist->value);
recipient_tpks[recipient_tpk_count ++] = tpk;
// Collect all of the keys that have the encryption for
// transport capability.
pgp_tpk_key_iter_t iter = pgp_tpk_key_iter_valid(tpk);
if (! iter)
ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
pgp_tpk_key_iter_encrypting_capable_for_transport(iter);
pgp_key_t key;
while ((key = pgp_tpk_key_iter_next (iter, NULL, NULL))) {
assert(recipient_count == recipient_keys_count);
if (recipient_count == recipient_alloc) {
assert(recipient_alloc > 0);
recipient_alloc *= 2;
void *t = reallocarray(recipient_keys, recipient_alloc,
sizeof(*recipient_keys));
if (! t)
ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
recipient_keys = t;
t = reallocarray(recipients, recipient_alloc,
sizeof(*recipients));
if (! t)
ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
recipients = t;
}
// pgp_recipient_new consumes the passed key id, but it
// only references key (i.e., we still have to free key).
pgp_keyid_t keyid = pgp_key_keyid(key);
if (! key)
ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
key = pgp_key_clone(key);
if (! key)
ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
recipient_keys[recipient_keys_count++] = key;
recipients[recipient_count++] = pgp_recipient_new(keyid, key);
}
pgp_tpk_key_iter_free(iter);
}
if (sign) {
@ -1752,11 +1833,14 @@ static PEP_STATUS pgp_encrypt_sign_optional(
ws = pgp_writer_stack_message(writer);
ws = pgp_encryptor_new (&err, ws,
NULL, 0, keys, keys_count,
PGP_ENCRYPTION_MODE_FOR_TRANSPORT, 0);
NULL, 0, recipients, recipient_count,
0, 0);
if (!ws)
ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up encryptor");
// pgp_encrypt_new consumes the recipients (but not the keys).
recipient_count = 0;
if (sign) {
iter = pgp_tpk_key_iter_valid(signer_tpk);
pgp_tpk_key_iter_signing_capable (iter);
@ -1780,6 +1864,8 @@ static PEP_STATUS pgp_encrypt_sign_optional(
ws = pgp_signer_new(&err, ws, &signer, 1, 0);
if (!ws)
ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up signer");
// pgp_signer_new consumes signer.
signer = NULL;
}
ws = pgp_literal_writer_new (&err, ws);
@ -1811,13 +1897,23 @@ static PEP_STATUS pgp_encrypt_sign_optional(
out:
pgp_signer_free (signer);
pgp_key_pair_free (signing_keypair);
// XXX: pgp_key_pair_as_signer is only supposed to reference
// signing_keypair, but it consumes it. If this is fixed, this
// will become a leak.
//
// pgp_key_pair_free (signing_keypair);
pgp_tpk_key_iter_free (iter);
pgp_tpk_free(signer_tpk);
for (int i = 0; i < keys_count; i ++)
pgp_tpk_free(keys[i]);
free(keys);
for (int i = 0; i < recipient_count; i ++)
pgp_recipient_free(recipients[i]);
free(recipients);
for (int i = 0; i < recipient_keys_count; i ++)
pgp_key_free(recipient_keys[i]);
free(recipient_keys);
for (int i = 0; i < recipient_tpk_count; i ++)
pgp_tpk_free(recipient_tpks[i]);
free(recipient_tpks);
T("-> %s", pEp_status_to_string(status));
return status;
@ -2269,7 +2365,7 @@ static stringpair_list_t *add_key(PEP_SESSION session,
bool revoked = false;
// Don't add revoked keys to the keyinfo_list.
if (keyinfo_list) {
pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
pgp_revocation_status_t rs = pgp_tpk_revoked(tpk, 0);
pgp_revocation_status_variant_t rsv = pgp_revocation_status_variant(rs);
pgp_revocation_status_free(rs);
if (rsv == PGP_REVOCATION_STATUS_REVOKED)
@ -2471,7 +2567,7 @@ PEP_STATUS pgp_renew_key(
status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
ERROR_OUT(NULL, status, "Looking up '%s'", fpr);
uint32_t creation_time = pgp_key_creation_time(pgp_tpk_primary(tpk));
uint32_t creation_time = pgp_key_creation_time(pgp_tpk_primary_key(tpk));
if (creation_time > t)
// The creation time is after the expiration time!
ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
@ -2509,6 +2605,10 @@ PEP_STATUS pgp_renew_key(
out:
pgp_signer_free (signer);
// XXX: pgp_key_pair_as_signer is only supposed to reference
// signing_keypair, but it consumes it. If this is fixed, this
// will become a leak.
//
pgp_key_pair_free (keypair);
pgp_tpk_key_iter_free (iter);
pgp_tpk_free(tpk);
@ -2557,7 +2657,7 @@ PEP_STATUS pgp_revoke_key(
if (! tpk)
ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
assert(pgp_revocation_status_variant(pgp_tpk_revocation_status(tpk))
assert(pgp_revocation_status_variant(pgp_tpk_revoked(tpk, 0))
== PGP_REVOCATION_STATUS_REVOKED);
status = tpk_save(session, tpk, NULL);
@ -2577,7 +2677,7 @@ PEP_STATUS pgp_revoke_key(
static void _pgp_key_expired(pgp_tpk_t tpk, const time_t when, bool* expired)
{
// Is the TPK live?
*expired = !pgp_tpk_alive_at(tpk, when);
*expired = !pgp_tpk_alive(tpk, when);
#ifdef TRACING
{
@ -2635,7 +2735,7 @@ static void _pgp_key_expired(pgp_tpk_t tpk, const time_t when, bool* expired)
out:
// Er, this might be problematic in terms of internal vs. external in log. FIXME?
T("(%s) -> %s (expired: %d)", fpr, pEp_status_to_string(status), *expired);
T(" -> expired: %d", *expired);
return;
}
@ -2682,7 +2782,7 @@ PEP_STATUS pgp_key_revoked(PEP_SESSION session, const char *fpr, bool *revoked)
pgp_fingerprint_free(pgp_fpr);
ERROR_OUT(NULL, status, "Looking up %s", fpr);
pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
pgp_revocation_status_t rs = pgp_tpk_revoked(tpk, 0);
*revoked = pgp_revocation_status_variant(rs) == PGP_REVOCATION_STATUS_REVOKED;
pgp_revocation_status_free (rs);
pgp_tpk_free(tpk);
@ -2726,7 +2826,7 @@ PEP_STATUS pgp_get_key_rating(
// goto out;
// }
pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
pgp_revocation_status_t rs = pgp_tpk_revoked(tpk, 0);
pgp_revocation_status_variant_t rsv = pgp_revocation_status_variant(rs);
pgp_revocation_status_free(rs);
if (rsv == PGP_REVOCATION_STATUS_REVOKED) {
@ -2800,7 +2900,7 @@ PEP_STATUS pgp_key_created(PEP_SESSION session, const char *fpr, time_t *created
pgp_fingerprint_free(pgp_fpr);
ERROR_OUT(NULL, status, "Looking up %s", fpr);
pgp_key_t k = pgp_tpk_primary(tpk);
pgp_key_t k = pgp_tpk_primary_key(tpk);
*created = pgp_key_creation_time(k);
pgp_tpk_free(tpk);


Loading…
Cancel
Save