|
|
@ -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) { |
|
|
|