aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Klöcker <[email protected]>2024-09-04 12:31:12 +0000
committerIngo Klöcker <[email protected]>2024-09-04 12:31:12 +0000
commit2264b64b85e6d522fdc5e06d5260f5b7b5414417 (patch)
tree0daa28652e6a95041a388a4ec079d94662f9885c
parentbuild,python: Fix build with setuptools 72.2.0+ (diff)
downloadgpgme-2264b64b85e6d522fdc5e06d5260f5b7b5414417.tar.gz
gpgme-2264b64b85e6d522fdc5e06d5260f5b7b5414417.zip
core: Treat email-only user IDs with upper case letters as email address
* src/key.c (_gpgme_key_append_name): Support email-only user IDs with upper case letters. * tests/gpg/t-keylist.c (struct key_info_s): Add algo, length, sec_algo, sec_length. (keys): Add expected algo and length for primary and secondary subkeys. (main): Factor out code for checking a key and the code for the keylist test. Call the factored out test function and a new test function. (check_key, test_keylist, key_with_email_only_user_id, key_info_email_only_user_id, test_email_only_user_id_with_upper_case_letters): New. -- Email-only user IDs with upper case letters are now also parsed as a user ID with empty name and the complete user ID as email. GnuPG-bug-id: 7280
-rw-r--r--src/key.c22
-rw-r--r--tests/gpg/t-keylist.c955
2 files changed, 557 insertions, 420 deletions
diff --git a/src/key.c b/src/key.c
index fec9eb16..77651d31 100644
--- a/src/key.c
+++ b/src/key.c
@@ -237,12 +237,24 @@ _gpgme_key_append_name (gpgme_key_t key, const char *src, int convert)
uid->address = _gpgme_mailbox_from_userid (uid->uid);
if ((!uid->email || !*uid->email) && uid->address && uid->name
- && !strcmp (uid->name, uid->address))
+ && !strcasecmp (uid->name, uid->address))
{
- /* Name and address are the same. This is a mailbox only key.
- Use address as email and remove name. */
- *uid->name = '\0';
- uid->email = uid->address;
+ /* Name and address are the same except that some letters may have
+ different case. This is a mailbox only key. */
+ if (!strcmp (uid->name, uid->address))
+ {
+ /* Name and address are the identical. Use address as email
+ and remove name. */
+ *uid->name = '\0';
+ uid->email = uid->address;
+ }
+ else
+ {
+ /* Name and address are the same except for different case of
+ some letters. Use name as email and point name to EOS. */
+ uid->email = uid->name;
+ uid->name = (dst - 1);
+ }
}
if (!key->uids)
diff --git a/tests/gpg/t-keylist.c b/tests/gpg/t-keylist.c
index fc9fc1b7..c1e8ff1c 100644
--- a/tests/gpg/t-keylist.c
+++ b/tests/gpg/t-keylist.c
@@ -38,6 +38,10 @@ struct key_info_s
{
const char *fpr;
const char *sec_keyid;
+ gpgme_pubkey_algo_t algo;
+ unsigned int length;
+ gpgme_pubkey_algo_t sec_algo;
+ unsigned int sec_length;
struct
{
const char *name;
@@ -58,6 +62,7 @@ static void check_whisky (struct key_info_s *keyinfo, gpgme_key_t key);
struct key_info_s keys[] =
{
{ "A0FF4590BB6122EDEF6E3C542D727CC768697734", "6AE6D7EE46A871F8",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Alfa Test", "demo key", "[email protected]",
GPGME_VALIDITY_ULTIMATE },
{ "Alpha Test", "demo key", "[email protected]",
@@ -65,82 +70,520 @@ struct key_info_s keys[] =
{ "Alice", "demo key", NULL, GPGME_VALIDITY_ULTIMATE } }, 1,
GPGME_VALIDITY_ULTIMATE },
{ "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2", "5381EA4EE29BA37F",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Bob", "demo key", NULL },
{ "Bravo Test", "demo key", "[email protected]" } }, 1 },
{ "61EE841A2A27EB983B3B3C26413F4AF31AFDAB6C", "E71E72ACBC43DA60",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Charlie Test", "demo key", "[email protected]" } }, 1 },
{ "6560C59C43D031C54D7C588EEBA9F240EB9DC9E6", "06F22880B0C45424",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Delta Test", "demo key", "[email protected]" } }, 1 },
{ "3531152DE293E26A07F504BC318C1FAEFAEF6D1B", "B5C79E1A7272144D",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Echelon", "demo key", NULL },
{ "Echo Test", "demo key", "[email protected]" },
{ "Eve", "demo key", NULL } }, 1 },
{ "56D33268F7FE693FBB594762D4BF57F37372E243", "0A32EE79EE45198E",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Foxtrot Test", "demo key", "[email protected]" } }, 1 },
{ "C9C07DCC6621B9FB8D071B1D168410A48FC282E6", "247491CC9DCAD354",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Golf Test", "demo key", "[email protected]" } }, 1 },
{ "9E91CBB11E4D4135583EF90513DB965534C6E3F1", "76E26537D622AD0A",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Hotel Test", "demo key", "[email protected]" } }, 1 },
{ "CD538D6CC9FB3D745ECDA5201FE8FC6F04259677", "C1C8EFDE61F76C73",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "India Test", "demo key", "[email protected]" } }, 1 },
{ "F8F1EDC73995AB739AD54B380C820C71D2699313", "BD0B108735F8F136",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Juliet Test", "demo key", "[email protected]" } }, 1 },
{ "3FD11083779196C2ECDD9594AD1B0FAD43C2D0C7", "86CBB34A9AF64D02",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Kilo Test", "demo key", "[email protected]" } }, 1 },
{ "1DDD28CEF714F5B03B8C246937CAB51FB79103F8", "0363B449FE56350C",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Lima Test", "demo key", "[email protected]" } }, 1 },
{ "2686AA191A278013992C72EBBE794852BE5CF886", "5F600A834F31EAE8",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Mallory", "demo key", NULL },
{ "Mike Test", "demo key", "[email protected]" } }, 1 },
{ "5AB9D6D7BAA1C95B3BAA3D9425B00FD430CEC684", "4C1D63308B70E472",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "November Test", "demo key", "[email protected]" } }, 1 },
{ "43929E89F8F79381678CAE515F6356BA6D9732AC", "FF0785712681619F",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Oscar Test", "demo key", "[email protected]" } }, 1 },
{ "6FAA9C201E5E26DCBAEC39FD5D15E01D3FF13206", "2764E18263330D9C",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Papa test", "demo key", "[email protected]" } }, 1 },
{ "A7969DA1C3297AA96D49843F1C67EC133C661C84", "6CDCFC44A029ACF4",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Quebec Test", "demo key", "[email protected]" } }, 1 },
{ "38FBE1E4BF6A5E1242C8F6A13BDBEDB1777FBED3", "9FAB805A11D102EA",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Romeo Test", "demo key", "[email protected]" } }, 1 },
{ "045B2334ADD69FC221076841A5E67F7FA3AE3EA1", "93B88B0F0F1B50B4",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Sierra Test", "demo key", "[email protected]" } }, 1 },
{ "ECAC774F4EEEB0620767044A58CB9A4C85A81F38", "97B60E01101C0402",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Tango Test", "demo key", "[email protected]" } }, 1 },
{ "0DBCAD3F08843B9557C6C4D4A94C0F75653244D6", "93079B915522BDB9",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Uniform Test", "demo key", "[email protected]" } }, 1 },
{ "E8143C489C8D41124DC40D0B47AF4B6961F04784", "04071FB807287134",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Victor Test", "demo key", "[email protected]" } }, 1 },
{ "E8D6C90B683B0982BD557A99DEF0F7B8EC67DBDE", "D7FBB421FD6E27F6",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Whisky Test", "demo key", "[email protected]" } }, 3,
GPGME_VALIDITY_UNKNOWN, check_whisky },
{ "04C1DF62EFA0EBB00519B06A8979A6C5567FB34A", "5CC6F87F41E408BE",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "XRay Test", "demo key", "[email protected]" } }, 1 },
{ "ED9B316F78644A58D042655A9EEF34CD4B11B25F", "5ADFD255F7B080AD",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Yankee Test", "demo key", "[email protected]" } }, 1 },
{ "23FD347A419429BACCD5E72D6BC4778054ACD246", "EF9DC276A172C881",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Zulu Test", "demo key", "[email protected]" } }, 1 },
{ "ADAB7FCC1F4DE2616ECFA402AF82244F9CD9FD55", "087DD7E0381701C4",
+ GPGME_PK_DSA, 1024, GPGME_PK_ELG_E, 1024,
{ { "Joe Random Hacker", "test key with passphrase \"abc\"",
"[email protected]" } }, 1 },
{ NULL }
};
-int
-main (int argc, char **argv)
+static void
+check_key (gpgme_key_t key, struct key_info_s* key_info)
+{
+ int n;
+ gpgme_subkey_t subkey;
+
+ if (!key)
+ {
+ fprintf (stderr, "Key unexpectedly NULL\n");
+ exit (1);
+ }
+
+ if (!key_info->fpr)
+ {
+ fprintf (stderr, "More keys returned than expected\n");
+ exit (1);
+ }
+
+ /* Global key flags. */
+ if (key->revoked)
+ {
+ fprintf (stderr, "Key unexpectedly revoked\n");
+ exit (1);
+ }
+ if (key->expired)
+ {
+ fprintf (stderr, "Key unexpectedly expired\n");
+ exit (1);
+ }
+ if (key->disabled)
+ {
+ fprintf (stderr, "Key unexpectedly disabled\n");
+ exit (1);
+ }
+ if (key->invalid)
+ {
+ fprintf (stderr, "Key unexpectedly invalid\n");
+ exit (1);
+ }
+#if 0
+ /* GnuPG 2.1+ have a different subkey for encryption. */
+ if (!key->can_encrypt)
+ {
+ fprintf (stderr, "Key unexpectedly unusable for encryption\n");
+ exit (1);
+ }
+#endif
+ if (!key->can_sign)
+ {
+ fprintf (stderr, "Key unexpectedly unusable for signing\n");
+ exit (1);
+ }
+ if (!key->can_certify)
+ {
+ fprintf (stderr, "Key unexpectedly unusable for certifications\n");
+ exit (1);
+ }
+ if (key->secret)
+ {
+ fprintf (stderr, "Key unexpectedly secret\n");
+ exit (1);
+ }
+ if (key->protocol != GPGME_PROTOCOL_OpenPGP)
+ {
+ fprintf (stderr, "Key has unexpected protocol: %s\n",
+ gpgme_get_protocol_name (key->protocol));
+ exit (1);
+ }
+ if (key->issuer_serial)
+ {
+ fprintf (stderr, "Key unexpectedly carries issuer serial: %s\n",
+ key->issuer_serial);
+ exit (1);
+ }
+ if (key->issuer_name)
+ {
+ fprintf (stderr, "Key unexpectedly carries issuer name: %s\n",
+ key->issuer_name);
+ exit (1);
+ }
+ if (key->chain_id)
+ {
+ fprintf (stderr, "Key unexpectedly carries chain ID: %s\n",
+ key->chain_id);
+ exit (1);
+ }
+ if (key->owner_trust != key_info->owner_trust)
+ {
+ fprintf (stderr, "Key `%s' has unexpected owner trust: %i\n",
+ key_info->uid[0].name, key->owner_trust);
+ exit (1);
+ }
+
+ for (n=0, subkey = key->subkeys; subkey; subkey = subkey->next)
+ n++;
+ if (!n || n-1 != key_info->n_subkeys)
+ {
+ fprintf (stderr, "Key `%s' has unexpected number of subkeys\n",
+ key_info->uid[0].name);
+ exit (1);
+ }
+
+ /* Primary key. */
+ if (key->subkeys->revoked)
+ {
+ fprintf (stderr, "Primary key unexpectedly revoked\n");
+ exit (1);
+ }
+ if (key->subkeys->expired)
+ {
+ fprintf (stderr, "Primary key unexpectedly expired\n");
+ exit (1);
+ }
+ if (key->subkeys->disabled)
+ {
+ fprintf (stderr, "Primary key unexpectedly disabled\n");
+ exit (1);
+ }
+ if (key->subkeys->invalid)
+ {
+ fprintf (stderr, "Primary key unexpectedly invalid\n");
+ exit (1);
+ }
+ if (key->subkeys->can_encrypt)
+ {
+ fprintf (stderr, "Primary key unexpectedly usable for encryption\n");
+ exit (1);
+ }
+ if (!key->subkeys->can_sign)
+ {
+ fprintf (stderr, "Primary key unexpectedly unusable for signing\n");
+ exit (1);
+ }
+ if (!key->subkeys->can_certify)
+ {
+ fprintf (stderr, "Primary key unexpectedly unusable for certifications\n");
+ exit (1);
+ }
+ if (key->subkeys->secret)
+ {
+ fprintf (stderr, "Primary key unexpectedly secret\n");
+ exit (1);
+ }
+ if (key->subkeys->is_cardkey)
+ {
+ fprintf (stderr, "Public key marked as card key\n");
+ exit (1);
+ }
+ if (key->subkeys->card_number)
+ {
+ fprintf (stderr, "Public key with card number set\n");
+ exit (1);
+ }
+ if (key->subkeys->pubkey_algo != key_info->algo)
+ {
+ fprintf (stderr, "Primary key has unexpected public key algo: %s\n",
+ gpgme_pubkey_algo_name (key->subkeys->pubkey_algo));
+ exit (1);
+ }
+ if (key->subkeys->length != key_info->length)
+ {
+ fprintf (stderr, "Primary key has unexpected length: %i\n",
+ key->subkeys->length);
+ exit (1);
+ }
+ if (strcmp (key->subkeys->keyid, &key_info->fpr[40 - 16]))
+ {
+ fprintf (stderr, "Primary key `%s' has unexpected key ID: %s\n",
+ key_info->uid[0].name, key->subkeys->keyid);
+ exit (1);
+ }
+ if (strcmp (key->subkeys->fpr, key_info->fpr))
+ {
+ fprintf (stderr, "Primary key has unexpected fingerprint: %s\n",
+ key->subkeys->fpr);
+ exit (1);
+ }
+ if (key->subkeys->expires)
+ {
+ fprintf (stderr, "Primary key `%s' unexpectedly expires: %lu\n",
+ key_info->uid[0].name, key->subkeys->expires);
+ exit (1);
+ }
+
+ /* Secondary key. */
+ if (key->subkeys->next->revoked)
+ {
+ fprintf (stderr, "Secondary key unexpectedly revoked\n");
+ exit (1);
+ }
+ if (key->subkeys->next->expired)
+ {
+ fprintf (stderr, "Secondary key unexpectedly expired\n");
+ exit (1);
+ }
+ if (key->subkeys->next->disabled)
+ {
+ fprintf (stderr, "Secondary key unexpectedly disabled\n");
+ exit (1);
+ }
+ if (key->subkeys->next->invalid)
+ {
+ fprintf (stderr, "Secondary key unexpectedly invalid\n");
+ exit (1);
+ }
+ if (!key->subkeys->next->can_encrypt)
+ {
+ fprintf (stderr, "Secondary key unexpectedly unusable for encryption\n");
+ exit (1);
+ }
+ if (key->subkeys->next->can_sign)
+ {
+ fprintf (stderr, "Secondary key unexpectedly usable for signing\n");
+ exit (1);
+ }
+ if (key->subkeys->next->can_certify)
+ {
+ fprintf (stderr, "Secondary key unexpectedly usable for certifications\n");
+ exit (1);
+ }
+ if (key->subkeys->next->secret)
+ {
+ fprintf (stderr, "Secondary key unexpectedly secret\n");
+ exit (1);
+ }
+ if (key->subkeys->next->is_cardkey)
+ {
+ fprintf (stderr, "Secondary public key marked as card key\n");
+ exit (1);
+ }
+ if (key->subkeys->next->card_number)
+ {
+ fprintf (stderr, "Secondary public key with card number set\n");
+ exit (1);
+ }
+ if (key->subkeys->next->pubkey_algo != key_info->sec_algo)
+ {
+ fprintf (stderr, "Secondary key has unexpected public key algo: %s\n",
+ gpgme_pubkey_algo_name (key->subkeys->next->pubkey_algo));
+ exit (1);
+ }
+ if (key->subkeys->next->length != key_info->sec_length)
+ {
+ fprintf (stderr, "Secondary key has unexpected length: %i\n",
+ key->subkeys->next->length);
+ exit (1);
+ }
+ if (strcmp (key->subkeys->next->keyid, key_info->sec_keyid))
+ {
+ fprintf (stderr, "Secondary key `%s' has unexpected key ID: %s/%s\n",
+ key_info->uid[0].name,
+ key->subkeys->next->keyid, key_info->sec_keyid );
+ exit (1);
+ }
+ if (!key->subkeys->next->fpr)
+ {
+ fprintf (stderr, "Secondary key has unexpectedly no fingerprint\n");
+ exit (1);
+ }
+ if (key->subkeys->next->expires)
+ {
+ fprintf (stderr, "Secondary key unexpectedly expires: %lu\n",
+ key->subkeys->next->expires);
+ exit (1);
+ }
+
+ /* FIXME: The below test will crash if we want to check for a
+ name, comment or email that doesn't exist in the key's user
+ IDs. */
+ if (!((!key_info->uid[0].name && !key->uids)
+ || (key_info->uid[0].name && !key_info->uid[1].name
+ && key->uids && !key->uids->next)
+ || (key_info->uid[0].name && key_info->uid[1].name
+ && !key_info->uid[2].name
+ && key->uids && key->uids->next && !key->uids->next->next)
+ || (key_info->uid[0].name && key_info->uid[1].name
+ && key_info->uid[2].name
+ && key->uids && key->uids->next && key->uids->next->next
+ && !key->uids->next->next->next)))
+ {
+ fprintf (stderr, "Key has unexpected number of user IDs\n");
+ exit (1);
+ }
+ if (key->uids && key->uids->revoked)
+ {
+ fprintf (stderr, "First user ID unexpectedly revoked\n");
+ exit (1);
+ }
+ if (key->uids && key->uids->invalid)
+ {
+ fprintf (stderr, "First user ID unexpectedly invalid\n");
+ exit (1);
+ }
+ if (key->uids && key->uids->validity != key_info->uid[0].validity)
+ {
+ fprintf (stderr, "First user ID `%s' has unexpectedly validity: %i\n",
+ key->uids->name, key->uids->validity);
+ exit (1);
+ }
+ if (key->uids && key->uids->signatures)
+ {
+ fprintf (stderr, "First user ID unexpectedly signed\n");
+ exit (1);
+ }
+ if (key_info->uid[0].name
+ && strcmp (key_info->uid[0].name, key->uids->name))
+ {
+ fprintf (stderr, "Unexpected name in first user ID: %s\n",
+ key->uids->name);
+ exit (1);
+ }
+ if (key_info->uid[0].comment
+ && strcmp (key_info->uid[0].comment, key->uids->comment))
+ {
+ fprintf (stderr, "Unexpected comment in first user ID: %s\n",
+ key->uids->comment);
+ exit (1);
+ }
+ if (key_info->uid[0].email
+ && strcmp (key_info->uid[0].email, key->uids->email))
+ {
+ fprintf (stderr, "Unexpected email in first user ID: %s\n",
+ key->uids->email);
+ exit (1);
+ }
+ if (key->uids && key->uids->next && key->uids->next->revoked)
+ {
+ fprintf (stderr, "Second user ID unexpectedly revoked\n");
+ exit (1);
+ }
+ if (key->uids && key->uids->next && key->uids->next->invalid)
+ {
+ fprintf (stderr, "Second user ID unexpectedly invalid\n");
+ exit (1);
+ }
+ if (key->uids && key->uids->next
+ && key->uids->next->validity != key_info->uid[1].validity)
+ {
+ fprintf (stderr, "Second user ID has unexpectedly validity: %i\n",
+ key->uids->next->validity);
+ exit (1);
+ }
+ if (key->uids && key->uids->next && key->uids->next->signatures)
+ {
+ fprintf (stderr, "Second user ID unexpectedly signed\n");
+ exit (1);
+ }
+ if (key_info->uid[1].name
+ && strcmp (key_info->uid[1].name, key->uids->next->name))
+ {
+ fprintf (stderr, "Unexpected name in second user ID: %s\n",
+ key->uids->next->name);
+ exit (1);
+ }
+ if (key_info->uid[1].comment
+ && strcmp (key_info->uid[1].comment, key->uids->next->comment))
+ {
+ fprintf (stderr, "Unexpected comment in second user ID: %s\n",
+ key->uids->next->comment);
+ exit (1);
+ }
+ if (key_info->uid[1].email
+ && strcmp (key_info->uid[1].email, key->uids->next->email))
+ {
+ fprintf (stderr, "Unexpected email in second user ID: %s\n",
+ key->uids->next->email);
+ exit (1);
+ }
+ if (key->uids && key->uids->next && key->uids->next->next
+ && key->uids->next->next->revoked)
+ {
+ fprintf (stderr, "Third user ID unexpectedly revoked\n");
+ exit (1);
+ }
+ if (key->uids && key->uids->next && key->uids->next->next
+ && key->uids->next->next->invalid)
+ {
+ fprintf (stderr, "Third user ID unexpectedly invalid\n");
+ exit (1);
+ }
+ if (key->uids && key->uids->next && key->uids->next->next
+ && key->uids->next->next->validity != key_info->uid[2].validity)
+ {
+ fprintf (stderr, "Third user ID has unexpectedly validity: %i\n",
+ key->uids->next->next->validity);
+ exit (1);
+ }
+ if (key->uids && key->uids->next && key->uids->next->next
+ && key->uids->next->next->signatures)
+ {
+ fprintf (stderr, "Third user ID unexpectedly signed\n");
+ exit (1);
+ }
+ if (key_info->uid[2].name
+ && strcmp (key_info->uid[2].name, key->uids->next->next->name))
+ {
+ fprintf (stderr, "Unexpected name in third user ID: %s\n",
+ key->uids->next->next->name);
+ exit (1);
+ }
+ if (key_info->uid[2].comment
+ && strcmp (key_info->uid[2].comment, key->uids->next->next->comment))
+ {
+ fprintf (stderr, "Unexpected comment in third user ID: %s\n",
+ key->uids->next->next->comment);
+ exit (1);
+ }
+ if (key_info->uid[2].email
+ && strcmp (key_info->uid[2].email, key->uids->next->next->email))
+ {
+ fprintf (stderr, "Unexpected email in third user ID: %s\n",
+ key->uids->next->next->email);
+ exit (1);
+ }
+
+ if (key_info->misc_check)
+ key_info->misc_check (key_info, key);
+}
+
+static void
+test_keylist (void)
{
gpgme_error_t err;
gpgme_ctx_t ctx;
gpgme_key_t key;
gpgme_keylist_result_t result;
int i = 0;
- int n;
- gpgme_subkey_t subkey;
-
- (void)argc;
- (void)argv;
-
- init_gpgme (GPGME_PROTOCOL_OpenPGP);
err = gpgme_new (&ctx);
fail_if_err (err);
@@ -150,412 +593,7 @@ main (int argc, char **argv)
while (!(err = gpgme_op_keylist_next (ctx, &key)))
{
- if (!keys[i].fpr)
- {
- fprintf (stderr, "More keys returned than expected\n");
- exit (1);
- }
-
- /* Global key flags. */
- if (key->revoked)
- {
- fprintf (stderr, "Key unexpectedly revoked\n");
- exit (1);
- }
- if (key->expired)
- {
- fprintf (stderr, "Key unexpectedly expired\n");
- exit (1);
- }
- if (key->disabled)
- {
- fprintf (stderr, "Key unexpectedly disabled\n");
- exit (1);
- }
- if (key->invalid)
- {
- fprintf (stderr, "Key unexpectedly invalid\n");
- exit (1);
- }
-#if 0
- /* GnuPG 2.1+ have a different subkey for encryption. */
- if (!key->can_encrypt)
- {
- fprintf (stderr, "Key unexpectedly unusable for encryption\n");
- exit (1);
- }
-#endif
- if (!key->can_sign)
- {
- fprintf (stderr, "Key unexpectedly unusable for signing\n");
- exit (1);
- }
- if (!key->can_certify)
- {
- fprintf (stderr, "Key unexpectedly unusable for certifications\n");
- exit (1);
- }
- if (key->secret)
- {
- fprintf (stderr, "Key unexpectedly secret\n");
- exit (1);
- }
- if (key->protocol != GPGME_PROTOCOL_OpenPGP)
- {
- fprintf (stderr, "Key has unexpected protocol: %s\n",
- gpgme_get_protocol_name (key->protocol));
- exit (1);
- }
- if (key->issuer_serial)
- {
- fprintf (stderr, "Key unexpectedly carries issuer serial: %s\n",
- key->issuer_serial);
- exit (1);
- }
- if (key->issuer_name)
- {
- fprintf (stderr, "Key unexpectedly carries issuer name: %s\n",
- key->issuer_name);
- exit (1);
- }
- if (key->chain_id)
- {
- fprintf (stderr, "Key unexpectedly carries chain ID: %s\n",
- key->chain_id);
- exit (1);
- }
- if (key->owner_trust != keys[i].owner_trust)
- {
- fprintf (stderr, "Key `%s' has unexpected owner trust: %i\n",
- keys[i].uid[0].name, key->owner_trust);
- exit (1);
- }
-
- for (n=0, subkey = key->subkeys; subkey; subkey = subkey->next)
- n++;
- if (!n || n-1 != keys[i].n_subkeys)
- {
- fprintf (stderr, "Key `%s' has unexpected number of subkeys\n",
- keys[i].uid[0].name);
- exit (1);
- }
-
- /* Primary key. */
- if (key->subkeys->revoked)
- {
- fprintf (stderr, "Primary key unexpectedly revoked\n");
- exit (1);
- }
- if (key->subkeys->expired)
- {
- fprintf (stderr, "Primary key unexpectedly expired\n");
- exit (1);
- }
- if (key->subkeys->disabled)
- {
- fprintf (stderr, "Primary key unexpectedly disabled\n");
- exit (1);
- }
- if (key->subkeys->invalid)
- {
- fprintf (stderr, "Primary key unexpectedly invalid\n");
- exit (1);
- }
- if (key->subkeys->can_encrypt)
- {
- fprintf (stderr, "Primary key unexpectedly usable for encryption\n");
- exit (1);
- }
- if (!key->subkeys->can_sign)
- {
- fprintf (stderr, "Primary key unexpectedly unusable for signing\n");
- exit (1);
- }
- if (!key->subkeys->can_certify)
- {
- fprintf (stderr, "Primary key unexpectedly unusable for certifications\n");
- exit (1);
- }
- if (key->subkeys->secret)
- {
- fprintf (stderr, "Primary key unexpectedly secret\n");
- exit (1);
- }
- if (key->subkeys->is_cardkey)
- {
- fprintf (stderr, "Public key marked as card key\n");
- exit (1);
- }
- if (key->subkeys->card_number)
- {
- fprintf (stderr, "Public key with card number set\n");
- exit (1);
- }
- if (key->subkeys->pubkey_algo != GPGME_PK_DSA)
- {
- fprintf (stderr, "Primary key has unexpected public key algo: %s\n",
- gpgme_pubkey_algo_name (key->subkeys->pubkey_algo));
- exit (1);
- }
- if (key->subkeys->length != 1024)
- {
- fprintf (stderr, "Primary key has unexpected length: %i\n",
- key->subkeys->length);
- exit (1);
- }
- if (strcmp (key->subkeys->keyid, &keys[i].fpr[40 - 16]))
- {
- fprintf (stderr, "Primary key `%s' has unexpected key ID: %s\n",
- keys[i].uid[0].name, key->subkeys->keyid);
- exit (1);
- }
- if (strcmp (key->subkeys->fpr, keys[i].fpr))
- {
- fprintf (stderr, "Primary key has unexpected fingerprint: %s\n",
- key->subkeys->fpr);
- exit (1);
- }
- if (key->subkeys->expires)
- {
- fprintf (stderr, "Primary key `%s' unexpectedly expires: %lu\n",
- keys[i].uid[0].name, key->subkeys->expires);
- exit (1);
- }
-
- /* Secondary key. */
- if (key->subkeys->next->revoked)
- {
- fprintf (stderr, "Secondary key unexpectedly revoked\n");
- exit (1);
- }
- if (key->subkeys->next->expired)
- {
- fprintf (stderr, "Secondary key unexpectedly expired\n");
- exit (1);
- }
- if (key->subkeys->next->disabled)
- {
- fprintf (stderr, "Secondary key unexpectedly disabled\n");
- exit (1);
- }
- if (key->subkeys->next->invalid)
- {
- fprintf (stderr, "Secondary key unexpectedly invalid\n");
- exit (1);
- }
- if (!key->subkeys->next->can_encrypt)
- {
- fprintf (stderr, "Secondary key unexpectedly unusable for encryption\n");
- exit (1);
- }
- if (key->subkeys->next->can_sign)
- {
- fprintf (stderr, "Secondary key unexpectedly usable for signing\n");
- exit (1);
- }
- if (key->subkeys->next->can_certify)
- {
- fprintf (stderr, "Secondary key unexpectedly usable for certifications\n");
- exit (1);
- }
- if (key->subkeys->next->secret)
- {
- fprintf (stderr, "Secondary key unexpectedly secret\n");
- exit (1);
- }
- if (key->subkeys->next->is_cardkey)
- {
- fprintf (stderr, "Secondary public key marked as card key\n");
- exit (1);
- }
- if (key->subkeys->next->card_number)
- {
- fprintf (stderr, "Secondary public key with card number set\n");
- exit (1);
- }
- if (key->subkeys->next->pubkey_algo != GPGME_PK_ELG_E)
- {
- fprintf (stderr, "Secondary key has unexpected public key algo: %s\n",
- gpgme_pubkey_algo_name (key->subkeys->next->pubkey_algo));
- exit (1);
- }
- if (key->subkeys->next->length != 1024)
- {
- fprintf (stderr, "Secondary key has unexpected length: %i\n",
- key->subkeys->next->length);
- exit (1);
- }
- if (strcmp (key->subkeys->next->keyid, keys[i].sec_keyid))
- {
- fprintf (stderr, "Secondary key `%s' has unexpected key ID: %s/%s\n",
- keys[i].uid[0].name,
- key->subkeys->next->keyid, keys[i].sec_keyid );
- exit (1);
- }
- if (!key->subkeys->next->fpr)
- {
- fprintf (stderr, "Secondary key has unexpectedly no fingerprint\n");
- exit (1);
- }
- if (key->subkeys->next->expires)
- {
- fprintf (stderr, "Secondary key unexpectedly expires: %lu\n",
- key->subkeys->next->expires);
- exit (1);
- }
-
- /* FIXME: The below test will crash if we want to check for a
- name, comment or email that doesn't exist in the key's user
- IDs. */
- if (!((!keys[i].uid[0].name && !key->uids)
- || (keys[i].uid[0].name && !keys[i].uid[1].name
- && key->uids && !key->uids->next)
- || (keys[i].uid[0].name && keys[i].uid[1].name
- && !keys[i].uid[2].name
- && key->uids && key->uids->next && !key->uids->next->next)
- || (keys[i].uid[0].name && keys[i].uid[1].name
- && keys[i].uid[2].name
- && key->uids && key->uids->next && key->uids->next->next
- && !key->uids->next->next->next)))
- {
- fprintf (stderr, "Key has unexpected number of user IDs\n");
- exit (1);
- }
- if (key->uids && key->uids->revoked)
- {
- fprintf (stderr, "First user ID unexpectedly revoked\n");
- exit (1);
- }
- if (key->uids && key->uids->invalid)
- {
- fprintf (stderr, "First user ID unexpectedly invalid\n");
- exit (1);
- }
- if (key->uids && key->uids->validity != keys[i].uid[0].validity)
- {
- fprintf (stderr, "First user ID `%s' has unexpectedly validity: %i\n",
- key->uids->name, key->uids->validity);
- exit (1);
- }
- if (key->uids && key->uids->signatures)
- {
- fprintf (stderr, "First user ID unexpectedly signed\n");
- exit (1);
- }
- if (keys[i].uid[0].name
- && strcmp (keys[i].uid[0].name, key->uids->name))
- {
- fprintf (stderr, "Unexpected name in first user ID: %s\n",
- key->uids->name);
- exit (1);
- }
- if (keys[i].uid[0].comment
- && strcmp (keys[i].uid[0].comment, key->uids->comment))
- {
- fprintf (stderr, "Unexpected comment in first user ID: %s\n",
- key->uids->comment);
- exit (1);
- }
- if (keys[i].uid[0].email
- && strcmp (keys[i].uid[0].email, key->uids->email))
- {
- fprintf (stderr, "Unexpected email in first user ID: %s\n",
- key->uids->email);
- exit (1);
- }
- if (key->uids && key->uids->next && key->uids->next->revoked)
- {
- fprintf (stderr, "Second user ID unexpectedly revoked\n");
- exit (1);
- }
- if (key->uids && key->uids->next && key->uids->next->invalid)
- {
- fprintf (stderr, "Second user ID unexpectedly invalid\n");
- exit (1);
- }
- if (key->uids && key->uids->next
- && key->uids->next->validity != keys[i].uid[1].validity)
- {
- fprintf (stderr, "Second user ID has unexpectedly validity: %i\n",
- key->uids->next->validity);
- exit (1);
- }
- if (key->uids && key->uids->next && key->uids->next->signatures)
- {
- fprintf (stderr, "Second user ID unexpectedly signed\n");
- exit (1);
- }
- if (keys[i].uid[1].name
- && strcmp (keys[i].uid[1].name, key->uids->next->name))
- {
- fprintf (stderr, "Unexpected name in second user ID: %s\n",
- key->uids->next->name);
- exit (1);
- }
- if (keys[i].uid[1].comment
- && strcmp (keys[i].uid[1].comment, key->uids->next->comment))
- {
- fprintf (stderr, "Unexpected comment in second user ID: %s\n",
- key->uids->next->comment);
- exit (1);
- }
- if (keys[i].uid[1].email
- && strcmp (keys[i].uid[1].email, key->uids->next->email))
- {
- fprintf (stderr, "Unexpected email in second user ID: %s\n",
- key->uids->next->email);
- exit (1);
- }
- if (key->uids && key->uids->next && key->uids->next->next
- && key->uids->next->next->revoked)
- {
- fprintf (stderr, "Third user ID unexpectedly revoked\n");
- exit (1);
- }
- if (key->uids && key->uids->next && key->uids->next->next
- && key->uids->next->next->invalid)
- {
- fprintf (stderr, "Third user ID unexpectedly invalid\n");
- exit (1);
- }
- if (key->uids && key->uids->next && key->uids->next->next
- && key->uids->next->next->validity != keys[i].uid[2].validity)
- {
- fprintf (stderr, "Third user ID has unexpectedly validity: %i\n",
- key->uids->next->next->validity);
- exit (1);
- }
- if (key->uids && key->uids->next && key->uids->next->next
- && key->uids->next->next->signatures)
- {
- fprintf (stderr, "Third user ID unexpectedly signed\n");
- exit (1);
- }
- if (keys[i].uid[2].name
- && strcmp (keys[i].uid[2].name, key->uids->next->next->name))
- {
- fprintf (stderr, "Unexpected name in third user ID: %s\n",
- key->uids->next->next->name);
- exit (1);
- }
- if (keys[i].uid[2].comment
- && strcmp (keys[i].uid[2].comment, key->uids->next->next->comment))
- {
- fprintf (stderr, "Unexpected comment in third user ID: %s\n",
- key->uids->next->next->comment);
- exit (1);
- }
- if (keys[i].uid[2].email
- && strcmp (keys[i].uid[2].email, key->uids->next->next->email))
- {
- fprintf (stderr, "Unexpected email in third user ID: %s\n",
- key->uids->next->next->email);
- exit (1);
- }
-
- if (keys[i].misc_check)
- keys[i].misc_check (keys+i, key);
-
+ check_key (key, keys + i);
gpgme_key_unref (key);
i++;
}
@@ -579,6 +617,93 @@ main (int argc, char **argv)
}
gpgme_release (ctx);
+}
+
+
+/* Test key with email-only user ID with some upper case letters:
+ pub ed25519 2024-09-04 [SC]
+ EEB4 9D86 957D 1A3B B65E 537A 44FF 03E9 2247 2260
+ uid [ultimate] [email protected]
+ sub cv25519 2024-09-04 [E]
+ 6389 70DC 1200 DBDD 52E1 94E4 2D71 8055 9B65 DC2A
+*/
+static const char *key_with_email_only_user_id =
+"-----BEGIN PGP PUBLIC KEY BLOCK-----\n"
+"\n"
+"mDMEZtgpCBYJKwYBBAHaRw8BAQdA7c2eHhElPpqS3wT9vAbOcluwYZ7OgYifqF/G\n"
+"T8oMZia0JmVtYWlsLW9ubHktd2l0aC1VcHBlci1DYXNlQGV4YW1wbGUubmV0iJME\n"
+"ExYKADsWIQTutJ2GlX0aO7ZeU3pE/wPpIkciYAUCZtgpCAIbAwULCQgHAgIiAgYV\n"
+"CgkICwIEFgIDAQIeBwIXgAAKCRBE/wPpIkciYH/NAP9ZMFl9/CzEd51b0WQqpT+g\n"
+"ofDuGgqLqns1bhan0Yg2WgD/QokAx3mkYwBKSFgQsY72ork93UObHmTzaNbveRMS\n"
+"TwK4OARm2CkIEgorBgEEAZdVAQUBAQdAorjpQQEUbFCfBBsV2sPpP+lZPNnZ+Hzb\n"
+"ZEMcKLTB3mwDAQgHiHgEGBYKACAWIQTutJ2GlX0aO7ZeU3pE/wPpIkciYAUCZtgp\n"
+"CAIbDAAKCRBE/wPpIkciYGTwAP9z5cD5RVj0bi4YC+yUHUhwg9m85LwmB0XbPb23\n"
+"4H8zDAEAzPjY00LJOP2G6TxG9KI1v18Su1quMacV3ibxLtHHLAA=\n"
+"=i4fy\n"
+"-----END PGP PUBLIC KEY BLOCK-----\n";
+
+struct key_info_s key_info_email_only_user_id[] =
+ {
+ { "EEB49D86957D1A3BB65E537A44FF03E922472260", "2D7180559B65DC2A",
+ GPGME_PK_EDDSA, 255, GPGME_PK_ECDH, 255,
+ { { "", "", "[email protected]" } }, 1 },
+ { NULL }
+ };
+
+
+static void
+test_email_only_user_id_with_upper_case_letters (void)
+{
+ gpgme_error_t err;
+ gpgme_ctx_t ctx;
+ gpgme_key_t key;
+ int i = 0;
+ gpgme_data_t data = NULL;
+
+ init_gpgme (GPGME_PROTOCOL_OpenPGP);
+
+ err = gpgme_new (&ctx);
+ fail_if_err (err);
+
+ err = gpgme_data_new_from_mem (&data, key_with_email_only_user_id,
+ strlen(key_with_email_only_user_id), 0);
+ fail_if_err (err);
+
+ err = gpgme_op_keylist_from_data_start (ctx, data, 0);
+
+ while (!(err = gpgme_op_keylist_next (ctx, &key)))
+ {
+ check_key (key, key_info_email_only_user_id + i);
+ gpgme_key_unref (key);
+ i++;
+ }
+ if (gpgme_err_code (err) != GPG_ERR_EOF)
+ fail_if_err (err);
+ err = gpgme_op_keylist_end (ctx);
+ fail_if_err (err);
+
+ if (key_info_email_only_user_id[i].fpr)
+ {
+ fprintf (stderr, "Less keys (%d) returned than expected (%d)\n",
+ i, (int)(DIM (keys) - 1));
+ exit (1);
+ }
+
+ gpgme_release (ctx);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ (void)argc;
+ (void)argv;
+
+ init_gpgme (GPGME_PROTOCOL_OpenPGP);
+
+ test_keylist ();
+ test_email_only_user_id_with_upper_case_letters ();
+
return 0;
}