|
|
|
@ -192,8 +192,9 @@ pgp_key_find_uid_cond(
|
|
|
|
|
const pgp_key_t *key,
|
|
|
|
|
unsigned(*uidcond) ( uint8_t *, void *),
|
|
|
|
|
void *uidcondarg,
|
|
|
|
|
unsigned(*sigcond) ( const pgp_sig_info_t *),
|
|
|
|
|
time_t *youngest,
|
|
|
|
|
unsigned(*sigcond) ( const pgp_sig_info_t *, void *),
|
|
|
|
|
void *sigcondarg,
|
|
|
|
|
time_t *youngest,
|
|
|
|
|
unsigned checkrevoke,
|
|
|
|
|
unsigned checkexpiry)
|
|
|
|
|
{
|
|
|
|
@ -240,7 +241,7 @@ pgp_key_find_uid_cond(
|
|
|
|
|
if(!checkexpiry || siginfo_in_time(&uidsigp->siginfo))
|
|
|
|
|
{
|
|
|
|
|
/* sig cond is ok ? */
|
|
|
|
|
if(!sigcond || sigcond(&uidsigp->siginfo))
|
|
|
|
|
if(!sigcond || sigcond(&uidsigp->siginfo, sigcondarg))
|
|
|
|
|
{
|
|
|
|
|
/* youngest signature is deciding */
|
|
|
|
|
if(uidsigp->siginfo.birthtime > *youngest)
|
|
|
|
@ -267,7 +268,8 @@ 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 *, void*),
|
|
|
|
|
void *sigcondarg,
|
|
|
|
|
unsigned checkrevoke,
|
|
|
|
|
unsigned checkexpiry)
|
|
|
|
|
{
|
|
|
|
@ -309,7 +311,7 @@ pgp_key_find_key_conds(
|
|
|
|
|
if(!checkexpiry || siginfo_in_time(&directsigp->siginfo))
|
|
|
|
|
{
|
|
|
|
|
/* condition on sig is ok */
|
|
|
|
|
if(sigcond(&directsigp->siginfo))
|
|
|
|
|
if(sigcond(&directsigp->siginfo, sigcondarg))
|
|
|
|
|
{
|
|
|
|
|
/* youngest signature is deciding */
|
|
|
|
|
if(directsigp->siginfo.birthtime > youngest)
|
|
|
|
@ -322,7 +324,7 @@ pgp_key_find_key_conds(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uidres = pgp_key_find_uid_cond(
|
|
|
|
|
key, NULL, NULL, sigcond, &youngest,
|
|
|
|
|
key, NULL, NULL, sigcond, sigcondarg, &youngest,
|
|
|
|
|
checkrevoke, checkexpiry);
|
|
|
|
|
|
|
|
|
|
/* if matching uid sig, then primary is matching key */
|
|
|
|
@ -366,7 +368,7 @@ pgp_key_find_key_conds(
|
|
|
|
|
if(!checkexpiry || siginfo_in_time(&subkeysigp->siginfo))
|
|
|
|
|
{
|
|
|
|
|
/* subkey sig condition is ok */
|
|
|
|
|
if(!sigcond || sigcond(&subkeysigp->siginfo))
|
|
|
|
|
if(!sigcond || sigcond(&subkeysigp->siginfo, sigcondarg))
|
|
|
|
|
{
|
|
|
|
|
/* youngest signature is deciding */
|
|
|
|
|
if(subkeysigp->siginfo.birthtime > youngest)
|
|
|
|
@ -458,7 +460,7 @@ key_get_seckey_from_subidx(
|
|
|
|
|
return pgp_get_seckey(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned is_signing_role(const pgp_sig_info_t *siginfo)
|
|
|
|
|
static unsigned is_signing_role(const pgp_sig_info_t *siginfo, void *arg)
|
|
|
|
|
{
|
|
|
|
|
return siginfo->key_flags & PGP_KEYFLAG_SIGN_DATA;
|
|
|
|
|
}
|
|
|
|
@ -468,7 +470,7 @@ 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, 0, 0);
|
|
|
|
|
pgp_key_find_key_conds(key, NULL, NULL, &is_signing_role, NULL, 0, 0);
|
|
|
|
|
return key_get_pubkey_from_subidx(key, NULL, subkeyidx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -477,11 +479,11 @@ 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, 1, 0);
|
|
|
|
|
pgp_key_find_key_conds(key, NULL, NULL, &is_signing_role, NULL, 1, 0);
|
|
|
|
|
return key_get_seckey_from_subidx(key, NULL, subkeyidx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned is_encryption_role(const pgp_sig_info_t *siginfo)
|
|
|
|
|
static unsigned is_encryption_role(const pgp_sig_info_t *siginfo, void *arg)
|
|
|
|
|
{
|
|
|
|
|
return siginfo->key_flags & PGP_KEYFLAG_ENC_COMM;
|
|
|
|
|
}
|
|
|
|
@ -490,7 +492,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, 1, 0);
|
|
|
|
|
pgp_key_find_key_conds(key, NULL, NULL, &is_encryption_role, NULL, 1, 0);
|
|
|
|
|
|
|
|
|
|
return key_get_pubkey_from_subidx(key, id, subkeyidx);
|
|
|
|
|
}
|
|
|
|
@ -499,12 +501,12 @@ 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, 0, 0);
|
|
|
|
|
pgp_key_find_key_conds(key, NULL, NULL, &is_encryption_role, NULL, 0, 0);
|
|
|
|
|
|
|
|
|
|
return key_get_seckey_from_subidx(key, id, subkeyidx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned primary_uid_sigcond(const pgp_sig_info_t *siginfo)
|
|
|
|
|
static unsigned primary_uid_sigcond(const pgp_sig_info_t *siginfo, void *arg)
|
|
|
|
|
{
|
|
|
|
|
return siginfo->primary_userid;
|
|
|
|
|
}
|
|
|
|
@ -512,14 +514,84 @@ static unsigned primary_uid_sigcond(const pgp_sig_info_t *siginfo)
|
|
|
|
|
const int32_t pgp_key_get_uid0(const pgp_key_t *key)
|
|
|
|
|
{
|
|
|
|
|
int32_t res =
|
|
|
|
|
pgp_key_find_uid_cond(key, NULL, NULL, &primary_uid_sigcond, NULL, 1, 1);
|
|
|
|
|
pgp_key_find_uid_cond(key, NULL, NULL, &primary_uid_sigcond, NULL, NULL, 1, 1);
|
|
|
|
|
|
|
|
|
|
/* arbitrarily use youngest uid if no primary is found */
|
|
|
|
|
return res == -1 ?
|
|
|
|
|
pgp_key_find_uid_cond(key, NULL, NULL, NULL, NULL, 1, 1):
|
|
|
|
|
pgp_key_find_uid_cond(key, NULL, NULL, NULL, NULL, NULL, 1, 1):
|
|
|
|
|
res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned key_bit_len(const pgp_pubkey_t *key)
|
|
|
|
|
{
|
|
|
|
|
switch (key->alg) {
|
|
|
|
|
case PGP_PKA_DSA:
|
|
|
|
|
return BN_num_bits(key->key.dsa.p);
|
|
|
|
|
|
|
|
|
|
case PGP_PKA_RSA:
|
|
|
|
|
return BN_num_bits(key->key.rsa.n);
|
|
|
|
|
|
|
|
|
|
case PGP_PKA_ELGAMAL:
|
|
|
|
|
return BN_num_bits(key->key.elgamal.p);
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned key_is_weak(
|
|
|
|
|
const pgp_pubkey_t *key,
|
|
|
|
|
const uint8_t *keyid,
|
|
|
|
|
void *arg)
|
|
|
|
|
{
|
|
|
|
|
unsigned kbl;
|
|
|
|
|
pgp_key_rating_t *res;
|
|
|
|
|
|
|
|
|
|
res = (pgp_key_rating_t*)arg;
|
|
|
|
|
kbl = key_bit_len(key);
|
|
|
|
|
|
|
|
|
|
if(kbl == 0)
|
|
|
|
|
{
|
|
|
|
|
*res = PGP_INVALID;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else if(kbl < 1024)
|
|
|
|
|
{
|
|
|
|
|
*res = PGP_TOOSHORT;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else if(kbl == 1024 && key->alg == PGP_PKA_RSA)
|
|
|
|
|
{
|
|
|
|
|
*res = PGP_WEAK;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const pgp_key_rating_t pgp_key_get_rating(const pgp_key_t *key)
|
|
|
|
|
{
|
|
|
|
|
/* keys exist in rings only if valid */
|
|
|
|
|
pgp_key_rating_t res = PGP_VALID;
|
|
|
|
|
|
|
|
|
|
pgp_key_find_key_conds(key, &key_is_weak, (void*)&res, NULL, NULL, 0, 0);
|
|
|
|
|
|
|
|
|
|
if(res == PGP_VALID)
|
|
|
|
|
{
|
|
|
|
|
if(pgp_key_find_key_conds(
|
|
|
|
|
key, NULL, NULL, NULL, NULL, 1, 0) == -2)
|
|
|
|
|
{
|
|
|
|
|
return PGP_REVOKED;
|
|
|
|
|
}
|
|
|
|
|
if(pgp_key_find_key_conds(
|
|
|
|
|
key, NULL, NULL, NULL, NULL, 0, 1) == -2)
|
|
|
|
|
{
|
|
|
|
|
return PGP_EXPIRED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
\ingroup HighLevel_KeyGeneral
|
|
|
|
|
|
|
|
|
@ -978,7 +1050,7 @@ 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, NULL,
|
|
|
|
|
checkrevoke, checkexpiry);
|
|
|
|
|
|
|
|
|
|
if (subkeyidx != -2) {
|
|
|
|
|