|
|
|
@ -193,7 +193,9 @@ pgp_key_find_uid_cond(
|
|
|
|
|
unsigned(*uidcond) ( uint8_t *, void *),
|
|
|
|
|
void *uidcondarg,
|
|
|
|
|
unsigned(*sigcond) ( const pgp_sig_info_t *),
|
|
|
|
|
time_t *youngest)
|
|
|
|
|
time_t *youngest,
|
|
|
|
|
unsigned checkrevoke,
|
|
|
|
|
unsigned checkexpiry)
|
|
|
|
|
{
|
|
|
|
|
unsigned uididx = 0;
|
|
|
|
|
unsigned uidsigidx = 0;
|
|
|
|
@ -201,6 +203,11 @@ pgp_key_find_uid_cond(
|
|
|
|
|
int32_t lastgood;
|
|
|
|
|
uint8_t **uidp;
|
|
|
|
|
pgp_uidsig_t *uidsigp;
|
|
|
|
|
time_t yngst = 0;
|
|
|
|
|
|
|
|
|
|
/* If not maximum age given, take default */
|
|
|
|
|
if(!youngest)
|
|
|
|
|
youngest = &yngst;
|
|
|
|
|
|
|
|
|
|
/* Loop over key's user ids*/
|
|
|
|
|
uidp = key->uids;
|
|
|
|
@ -221,7 +228,7 @@ pgp_key_find_uid_cond(
|
|
|
|
|
if(uidsigp->siginfo.type == PGP_SIG_REV_CERT)
|
|
|
|
|
{
|
|
|
|
|
/* ignore revocation if secret */
|
|
|
|
|
if(pgp_is_key_secret(key))
|
|
|
|
|
if(!checkrevoke)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* revert to last good candidate */
|
|
|
|
@ -230,8 +237,7 @@ pgp_key_find_uid_cond(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* in sig validity time frame */
|
|
|
|
|
if(pgp_is_key_secret(key) || /* ignore if secret */
|
|
|
|
|
siginfo_in_time(&uidsigp->siginfo))
|
|
|
|
|
if(!checkexpiry || siginfo_in_time(&uidsigp->siginfo))
|
|
|
|
|
{
|
|
|
|
|
/* sig cond is ok ? */
|
|
|
|
|
if(!sigcond || sigcond(&uidsigp->siginfo))
|
|
|
|
@ -261,7 +267,9 @@ pgp_key_find_key_conds(
|
|
|
|
|
const pgp_key_t *key,
|
|
|
|
|
unsigned(*keycond) ( const pgp_pubkey_t *, const uint8_t *, void*),
|
|
|
|
|
void *keycondarg,
|
|
|
|
|
unsigned(*sigcond) ( const pgp_sig_info_t *))
|
|
|
|
|
unsigned(*sigcond) ( const pgp_sig_info_t *),
|
|
|
|
|
unsigned checkrevoke,
|
|
|
|
|
unsigned checkexpiry)
|
|
|
|
|
{
|
|
|
|
|
unsigned subkeyidx = 0;
|
|
|
|
|
unsigned subkeysigidx = 0;
|
|
|
|
@ -291,15 +299,14 @@ pgp_key_find_key_conds(
|
|
|
|
|
if(directsigp->siginfo.type == PGP_SIG_REV_SUBKEY)
|
|
|
|
|
{
|
|
|
|
|
/* ignore revocation if secret */
|
|
|
|
|
if(pgp_is_key_secret(key))
|
|
|
|
|
if(!checkrevoke)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
return -2; /* Key is globally revoked, no result */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* in sig validity time frame */
|
|
|
|
|
if(pgp_is_key_secret(key) || /* ignore if secret */
|
|
|
|
|
siginfo_in_time(&directsigp->siginfo))
|
|
|
|
|
if(!checkexpiry || siginfo_in_time(&directsigp->siginfo))
|
|
|
|
|
{
|
|
|
|
|
/* condition on sig is ok */
|
|
|
|
|
if(sigcond(&directsigp->siginfo))
|
|
|
|
@ -314,9 +321,13 @@ pgp_key_find_key_conds(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uidres = pgp_key_find_uid_cond(key, NULL, NULL, sigcond, &youngest);
|
|
|
|
|
if(uidres != -1){
|
|
|
|
|
res = uidres;
|
|
|
|
|
uidres = pgp_key_find_uid_cond(
|
|
|
|
|
key, NULL, NULL, sigcond, &youngest,
|
|
|
|
|
checkrevoke, checkexpiry);
|
|
|
|
|
|
|
|
|
|
/* if matching uid sig, then primary is machin key */
|
|
|
|
|
if(uidres != -1){
|
|
|
|
|
res = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -343,7 +354,7 @@ pgp_key_find_key_conds(
|
|
|
|
|
if(subkeysigp->siginfo.type == PGP_SIG_REV_SUBKEY)
|
|
|
|
|
{
|
|
|
|
|
/* ignore revocation if secret */
|
|
|
|
|
if(pgp_is_key_secret(key))
|
|
|
|
|
if(!checkrevoke)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* revert to last good candidate */
|
|
|
|
@ -352,11 +363,10 @@ pgp_key_find_key_conds(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* in sig validity time frame */
|
|
|
|
|
if(pgp_is_key_secret(key) ||
|
|
|
|
|
siginfo_in_time(&subkeysigp->siginfo))
|
|
|
|
|
if(!checkexpiry || siginfo_in_time(&subkeysigp->siginfo))
|
|
|
|
|
{
|
|
|
|
|
/* subkey is primary */
|
|
|
|
|
if(sigcond(&subkeysigp->siginfo))
|
|
|
|
|
/* subkey sig condition is ok */
|
|
|
|
|
if(!sigcond || sigcond(&subkeysigp->siginfo))
|
|
|
|
|
{
|
|
|
|
|
/* youngest signature is deciding */
|
|
|
|
|
if(subkeysigp->siginfo.birthtime > youngest)
|
|
|
|
@ -453,19 +463,21 @@ static unsigned is_signing_role(const pgp_sig_info_t *siginfo)
|
|
|
|
|
return siginfo->key_flags & PGP_KEYFLAG_SIGN_DATA;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get a pub key to check signature */
|
|
|
|
|
const pgp_pubkey_t *
|
|
|
|
|
pgp_key_get_sigkey(const pgp_key_t *key)
|
|
|
|
|
{
|
|
|
|
|
int32_t subkeyidx =
|
|
|
|
|
pgp_key_find_key_conds(key, NULL, NULL, &is_signing_role);
|
|
|
|
|
pgp_key_find_key_conds(key, NULL, NULL, &is_signing_role, 0, 0);
|
|
|
|
|
return key_get_pubkey_from_subidx(key, NULL, subkeyidx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get a sec key to write a signature */
|
|
|
|
|
const pgp_seckey_t *
|
|
|
|
|
pgp_key_get_certkey(const pgp_key_t *key)
|
|
|
|
|
{
|
|
|
|
|
int32_t subkeyidx =
|
|
|
|
|
pgp_key_find_key_conds(key, NULL, NULL, &is_signing_role);
|
|
|
|
|
pgp_key_find_key_conds(key, NULL, NULL, &is_signing_role, 1, 0);
|
|
|
|
|
return key_get_seckey_from_subidx(key, NULL, subkeyidx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -478,7 +490,7 @@ const pgp_pubkey_t *
|
|
|
|
|
pgp_key_get_enckey(const pgp_key_t *key, const uint8_t **id)
|
|
|
|
|
{
|
|
|
|
|
int32_t subkeyidx =
|
|
|
|
|
pgp_key_find_key_conds(key, NULL, NULL, &is_encryption_role);
|
|
|
|
|
pgp_key_find_key_conds(key, NULL, NULL, &is_encryption_role, 1, 0);
|
|
|
|
|
|
|
|
|
|
return key_get_pubkey_from_subidx(key, id, subkeyidx);
|
|
|
|
|
}
|
|
|
|
@ -487,7 +499,7 @@ const pgp_seckey_t *
|
|
|
|
|
pgp_key_get_deckey(const pgp_key_t *key, const uint8_t **id)
|
|
|
|
|
{
|
|
|
|
|
int32_t subkeyidx =
|
|
|
|
|
pgp_key_find_key_conds(key, NULL, NULL, &is_encryption_role);
|
|
|
|
|
pgp_key_find_key_conds(key, NULL, NULL, &is_encryption_role, 0, 0);
|
|
|
|
|
|
|
|
|
|
return key_get_seckey_from_subidx(key, id, subkeyidx);
|
|
|
|
|
}
|
|
|
|
@ -499,14 +511,12 @@ static unsigned primary_uid_sigcond(const pgp_sig_info_t *siginfo)
|
|
|
|
|
|
|
|
|
|
const int32_t pgp_key_get_uid0(const pgp_key_t *key)
|
|
|
|
|
{
|
|
|
|
|
time_t youngest = 0;
|
|
|
|
|
int32_t res =
|
|
|
|
|
pgp_key_find_uid_cond(key, NULL, NULL, &primary_uid_sigcond, &youngest);
|
|
|
|
|
pgp_key_find_uid_cond(key, NULL, NULL, &primary_uid_sigcond, NULL, 1, 1);
|
|
|
|
|
|
|
|
|
|
youngest = 0;
|
|
|
|
|
/* arbitrarily use youngest uid if no primary is found */
|
|
|
|
|
return res == -1 ?
|
|
|
|
|
pgp_key_find_uid_cond(key, NULL, NULL, NULL, 0):
|
|
|
|
|
pgp_key_find_uid_cond(key, NULL, NULL, NULL, NULL, 1, 1):
|
|
|
|
|
res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -948,7 +958,11 @@ unsigned key_id_match(const pgp_pubkey_t *key, const uint8_t *keyid, void *refid
|
|
|
|
|
*/
|
|
|
|
|
const pgp_key_t *
|
|
|
|
|
pgp_getkeybyid(pgp_io_t *io, const pgp_keyring_t *keyring,
|
|
|
|
|
const uint8_t *keyid, unsigned *from, const pgp_pubkey_t **pubkey)
|
|
|
|
|
const uint8_t *keyid, unsigned *from,
|
|
|
|
|
const pgp_pubkey_t **pubkey,
|
|
|
|
|
const pgp_seckey_t **seckey,
|
|
|
|
|
unsigned checkrevoke,
|
|
|
|
|
unsigned checkexpiry)
|
|
|
|
|
{
|
|
|
|
|
uint8_t nullid[PGP_KEY_ID_SIZE];
|
|
|
|
|
|
|
|
|
@ -962,12 +976,16 @@ pgp_getkeybyid(pgp_io_t *io, const pgp_keyring_t *keyring,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
subkeyidx = pgp_key_find_key_conds(key, &key_id_match,
|
|
|
|
|
(void*)keyid, NULL);
|
|
|
|
|
(void*)keyid, NULL,
|
|
|
|
|
checkrevoke, checkexpiry);
|
|
|
|
|
|
|
|
|
|
if (subkeyidx != -2) {
|
|
|
|
|
if (pubkey) {
|
|
|
|
|
*pubkey = key_get_pubkey_from_subidx(key, NULL, subkeyidx);
|
|
|
|
|
}
|
|
|
|
|
if (seckey) {
|
|
|
|
|
*seckey = key_get_seckey_from_subidx(key, NULL, subkeyidx);
|
|
|
|
|
}
|
|
|
|
|
return key;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -982,7 +1000,7 @@ pgp_deletekeybyid(pgp_io_t *io, pgp_keyring_t *keyring,
|
|
|
|
|
pgp_key_t *key;
|
|
|
|
|
|
|
|
|
|
if ((key = (pgp_key_t *)pgp_getkeybyid(io, keyring, keyid,
|
|
|
|
|
&from, NULL)) == NULL) {
|
|
|
|
|
&from, NULL, NULL, 0, 0)) == NULL) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
/* 'from' is now index of key to delete */
|
|
|
|
@ -1120,7 +1138,8 @@ getkeybyname(pgp_io_t *io,
|
|
|
|
|
hexdump(io->outs, "keyid", keyid, 4);
|
|
|
|
|
}
|
|
|
|
|
savedstart = *from;
|
|
|
|
|
if ((kp = pgp_getkeybyid(io, keyring, keyid, from, NULL)) != NULL) {
|
|
|
|
|
if ((kp = pgp_getkeybyid(io, keyring, keyid, from,
|
|
|
|
|
NULL, NULL, 0, 0)) != NULL) {
|
|
|
|
|
return kp;
|
|
|
|
|
}
|
|
|
|
|
*from = savedstart;
|
|
|
|
@ -1307,7 +1326,7 @@ pgp_key_t *pgp_ensure_pubkey(
|
|
|
|
|
/* fill in what we already know */
|
|
|
|
|
key->type = PGP_PTAG_CT_PUBLIC_KEY;
|
|
|
|
|
pgp_pubkey_dup(&key->key.pubkey, pubkey);
|
|
|
|
|
(void) memcpy(&key->pubkeyid, pubkeyid, sizeof(PGP_KEY_ID_SIZE));
|
|
|
|
|
(void) memcpy(&key->pubkeyid, pubkeyid, PGP_KEY_ID_SIZE);
|
|
|
|
|
pgp_fingerprint(&key->pubkeyfpr, pubkey, keyring->hashtype);
|
|
|
|
|
|
|
|
|
|
return key;
|
|
|
|
@ -1337,7 +1356,7 @@ pgp_key_t *pgp_ensure_seckey(
|
|
|
|
|
/* fill in what we already know */
|
|
|
|
|
key->type = PGP_PTAG_CT_SECRET_KEY;
|
|
|
|
|
pgp_seckey_dup(&key->key.seckey, seckey);
|
|
|
|
|
(void) memcpy(&key->pubkeyid, pubkeyid, sizeof(PGP_KEY_ID_SIZE));
|
|
|
|
|
(void) memcpy(&key->pubkeyid, pubkeyid, PGP_KEY_ID_SIZE);
|
|
|
|
|
pgp_fingerprint(&key->pubkeyfpr, &seckey->pubkey, keyring->hashtype);
|
|
|
|
|
|
|
|
|
|
return key;
|
|
|
|
|