* RNP
** API
*** conflates certs and key
    This leads to man functions that are only applicable to either
    one, e.g. what should rnp_key_get_uid_count do when invoked with a
    subkey?  Or, rnp_key_remove seemingly allows one to remove a
    primary key but keep the subkeys.
*** key store model breaks down in corner cases
    As soon as a (sub)key belongs to two certificates, what happens is
    implementation defined.  For example, the results of
    rnp_key_is_primary and rnp_key_is_sub is unpredictable and depends
    on the order the keys are in the keyrings.
*** has many knobs, unclear defaults
    RNP allows many parameters to be tweaked, but the documentation
    doesn't state what the defaults are, or if they are sane.  This
    may lead to downstream users making an explicit choice (better
    safe than sorry), but making an explicit choice requires domain
    knowledge, and the choice may become outdated.
    E.g. rnp_op_generate_set_hash.
*** key unlock/lock mechanism
    RNP has the concept of unlocking keys.  When a key is unlocked via
    rnp_key_unlock, it's encrypted secret part is decrypted and
    persisted in memory until it is locked again using rnp_key_lock.
    During this period, the key may be exfiltrated from the process'
    address space.
*** unclear documentation
    "Generally ... not useful" pattern appears a lot, e.g. "Generally
    lock/unlock are not useful for unencrypted (not protected) keys."
*** strings as identifiers
    The API uses strings as identifiers where an enum would have been
    the better choice: public key algorithms, symmetric algorithms,
    hash algorithms, curves, armor labels, identifier types.  Possible
    values are documented with every function, but some lists are
    incomplete.  Also, the documentation suggests a case-insensitive
    match in some cases (e.g. rnp_op_generate_create) but not in
    others (e.g. rnp_op_generate_set_hash).
*** consistent use of rnp_result_t
    Every exported function returns a result, checks pointer arguments
    for NULL, and catches C++ exceptions turning them into error
    codes.  The consistency is nice, trying hard not to crash is nice,
    but makes getters unergonomic and cannot handle all cases of
    course, e.g. bad but non-NULL pointers.
*** rnp_export_public has odd flag
    RNP_KEY_EXPORT_PUBLIC.  How can you ever not export the public
    key?
*** rnp_key_have_public is odd
    How can you ever not have the public key?
*** rnp conflates keys and certs
    RNP has a certring and a keyring.  When doing rnp_locate_key, RNP
    searches both rings, and the returned rnp_key_handle_t can thus
    refer to two certificates, potentially different versions of the
    same, or even different certificates(!!!) if looked up by userid.
    It is not clear what to do, because the interface seems so broken.
*** revocation status is binary
    This is in stark contrast to the fact that RNP seems to support
    creating third party revocations using rnp_key_export_revocation:

    > @param key primary key to be revoked. Must have secret key,
    >            otherwise keyrings will be searched for the
    >            authorized to issue revocation signature secret key.
*** there is no way to automatically dearmor inputs
    There is rnp_input_dearmor_if_needed but it is not public.
*** rnp_key_valid_till

rnp_key_valid_till returns a 32-bit timestamp, but the expiration time
is a 33-bit quantity (the expiration time is a 32-bit offset relative
to the key's 32-bit creation time).

https://github.com/rnpgp/rnp/issues/1480

** implementation
*** very little documentation in the code
*** C-style runtime polymorphism with explicit vtables in C++ code
    E.g. struct pgp_dest_t
*** poorly supported by ADTs
    E.g. the key iterator uses a json_object_object_add to deduplicate
    items.
* TB's use of RNP
** unlocked keys may be exfiltrated
   RNP has the concept of unlocking keys.  When a key is unlocked via
   rnp_key_unlock, it's encrypted secret part is decrypted and
   persisted in memory until it is locked again using rnp_key_lock.
   During this period, the key may be exfiltrated from TB's address
   space.

   Sequoia improves this, because Sequoia encrypts unencrypted secrets
   in memory.

   In some places, the key is only temporarily unlocked for some
   operation (e.g. attaching a subkey) and then locked again.  This is
   fragile, because care must be take to run the locking on all exits
   (i.e. using try .. finally).

   In other places, the key is not locked again.
** Tests

   for example right now there is one xpcshell test, only, which you
   could request with
   mail/extensions/openpgp/test/unit/rnp/test_encryptAndOrSign.js -
   and there are many mochitests which you could request with
   directory mail/test/browser/openpgp as the parameter

   ./mach test mail/test/browser/openpgp/ mail/extensions/openpgp/test
