Browse Source

Key Filter now deals with uids and subkeys.

Started extending pgp_key_t, changes need to be propagated.
master
Edouard Tisserant 7 years ago
parent
commit
5fcaf4b5c9
4 changed files with 217 additions and 75 deletions
  1. +18
    -5
      dist/src/lib/keyring.c
  2. +1
    -1
      dist/src/lib/keyring.h
  3. +46
    -8
      dist/src/lib/packet.h
  4. +152
    -61
      dist/src/lib/validate.c

+ 18
- 5
dist/src/lib/keyring.c View File

@ -134,7 +134,13 @@ pgp_key_free(pgp_key_t *keydata)
FREE_ARRAY(keydata, packet);
/* XXX uidsigs revokes ? */
for (n = 0; n < keydata->uidsigc; ++n) {
/* TODO
pgp_uidsig_free(&keydata->uidsigs[n]);
*/
}
FREE_ARRAY(keydata, uidsig);
if (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) {
pgp_pubkey_free(&keydata->key.pubkey);
@ -142,6 +148,13 @@ pgp_key_free(pgp_key_t *keydata)
pgp_seckey_free(&keydata->key.seckey);
}
/* TODO enckey sigkey seckey subkeys attributes directsig uidrevokes*/
if(keydata->revocation.reason){
free(keydata->revocation.reason);
keydata->revocation.reason = NULL;
}
}
/**
@ -473,8 +486,8 @@ pgp_is_key_supported(const pgp_key_t *key)
\param src Source User ID
\note If dst already has a userid, it will be freed.
*/
static uint8_t *
copy_userid(uint8_t **dst, const uint8_t *src)
uint8_t *
pgp_copy_userid(uint8_t **dst, const uint8_t *src)
{
size_t len;
@ -483,7 +496,7 @@ copy_userid(uint8_t **dst, const uint8_t *src)
free(*dst);
}
if ((*dst = calloc(1, len + 1)) == NULL) {
(void) fprintf(stderr, "copy_userid: bad alloc\n");
(void) fprintf(stderr, "pgp_copy_userid: bad alloc\n");
} else {
(void) memcpy(*dst, src, len);
}
@ -530,7 +543,7 @@ pgp_add_userid(pgp_key_t *key, const uint8_t *userid)
uidp = &key->uids[key->uidc++];
*uidp = NULL;
/* now copy it */
return copy_userid(uidp, userid);
return pgp_copy_userid(uidp, userid);
}
void print_packet_hex(const pgp_subpacket_t *pkt);


+ 1
- 1
dist/src/lib/keyring.h View File

@ -173,5 +173,5 @@ int pgp_add_to_secring(pgp_keyring_t *, const pgp_seckey_t *);
int pgp_append_keyring(pgp_keyring_t *, pgp_keyring_t *);
pgp_subpacket_t * pgp_copy_packet(pgp_subpacket_t *, const pgp_subpacket_t *);
uint8_t * pgp_copy_userid(uint8_t **dst, const uint8_t *src);
#endif /* KEYRING_H_ */

+ 46
- 8
dist/src/lib/packet.h View File

@ -953,34 +953,72 @@ typedef struct pgp_revoke_t {
uint32_t uid; /* index in uid array */
uint8_t code; /* revocation code */
char *reason; /* c'mon, spill the beans */
pgp_subpacket_t *packet;
} pgp_revoke_t;
/** signature subpackets */
/** userid signature subpackets */
typedef struct pgp_uidsig_t {
uint32_t uid; /* index in userid array in key */
pgp_sig_info_t siginfo; /* trust signature */
pgp_sig_info_t siginfo;
uint8_t trustlevel; /* level of trust */
uint8_t trustamount; /* amount of trust */
pgp_subpacket_t *packet;
uint8_t revoked; /* sigs revokes uid */
pgp_subpacket_t packet;
} pgp_uidsig_t;
/** subkey signature subpackets */
typedef struct pgp_subkeysig_t {
uint32_t subkey; /* index of subkey in array */
pgp_sig_info_t siginfo;
uint8_t revoked; /* sigs revokes subkey */
pgp_subpacket_t packet;
} pgp_subkeysig_t;
typedef struct pgp_subkey_t {
pgp_keydata_key_t key; /* pubkey/seckey data */
uint8_t id[PGP_KEY_ID_SIZE];
} pgp_subkey_t;
typedef struct pgp_directsig_t {
pgp_sig_info_t siginfo;
pgp_subpacket_t packet;
} pgp_directsig_t;
/* describes a user's key */
struct pgp_key_t {
DYNARRAY(uint8_t *, uid); /* array of user ids */
pgp_content_enum type; /* type of key */
pgp_keydata_key_t key; /* pubkey/seckey data */
/* TODO remove */
DYNARRAY(pgp_subpacket_t, packet); /* array of raw subpackets */
DYNARRAY(pgp_uidsig_t, uidsig); /* array of signature subkeys */
DYNARRAY(uint8_t *, uid); /* array of user ids */
DYNARRAY(pgp_uidsig_t, uidsig); /* array of signature for user ids */
/* TODO remove */
uint32_t uid0; /* primary uid index in uids array */
/* TODO user attributes */
/* TODO remove */
DYNARRAY(pgp_revoke_t, revoke); /* array of signature revocations */
pgp_content_enum type; /* type of key */
pgp_keydata_key_t key; /* pubkey/seckey data */
DYNARRAY(pgp_subkey_t, subkey); /* array of subkeys */
DYNARRAY(pgp_subkeysig_t, subkeysig); /* array of sigs for subkeys */
pgp_pubkey_t sigkey; /* signature key */
uint8_t sigid[PGP_KEY_ID_SIZE];
pgp_fingerprint_t sigfingerprint; /* pgp signature fingerprint */
pgp_pubkey_t enckey; /* encryption key */
uint8_t encid[PGP_KEY_ID_SIZE];
pgp_fingerprint_t encfingerprint; /* pgp encryption id fingerprint */
uint32_t uid0; /* primary uid index in uids array */
DYNARRAY(pgp_directsig_t, directsig); /* direct signatures */
uint8_t revoked; /* key has been revoked */
pgp_sig_info_t revokeinfo; /* trust signature */
pgp_subpacket_t revokepacket;
/* TODO remove */
pgp_revoke_t revocation; /* revocation reason */
};


+ 152
- 61
dist/src/lib/validate.c View File

@ -376,6 +376,7 @@ pgp_validate_key_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
}
break;
case PGP_SIG_REV_SUBKEY:
case PGP_SIG_SUBKEY:
/*
* we ensure that the signing key is the
@ -392,6 +393,7 @@ pgp_validate_key_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
}
break;
case PGP_SIG_REV_KEY:
case PGP_SIG_DIRECT:
if(vdata->last_seen == PRIMARYKEY){
valid = pgp_check_direct_sig(&vdata->pubkey,
@ -400,12 +402,17 @@ pgp_validate_key_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
}
break;
if(vdata->last_seen == PRIMARYKEY){
/* XXX TODO
valid = pgp_check_keyrev_sig(&vdata->pubkey,
&content->sig,
sigkey);
*/
}
break;
case PGP_SIG_STANDALONE:
case PGP_SIG_PRIMARY:
case PGP_SIG_REV_KEY:
/* TODO */
case PGP_SIG_REV_SUBKEY:
/* TODO */
case PGP_SIG_TIMESTAMP:
case PGP_SIG_3RD_PARTY:
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED,
@ -485,6 +492,18 @@ pgp_validate_key_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
return PGP_RELEASE_MEMORY;
}
static void validate_key_cb_free (validate_key_cb_t *vdata){
pgp_pubkey_free(&vdata->pubkey);
if (vdata->subkey.version) {
pgp_pubkey_free(&vdata->subkey);
}
pgp_userid_free(&vdata->userid);
pgp_data_free(&vdata->userattr);
pgp_subpacket_free(&vdata->last_pkt);
pgp_free_sig_info(&vdata->valid_sig_info);
}
pgp_cb_ret_t
validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
{
@ -753,14 +772,14 @@ static pgp_cb_ret_t key_filter_cb (
validate_key_cb_t *vdata,
const pgp_subpacket_t *sigpkt)
{
pgp_key_t *key;
key_filter_cb_t *filter = vdata->on_valid_args;
if(vdata->not_commited){
printf("New key ************************************** \n");
/*hexdump(stdout, "signer ID", vdata->valid_sig_info.signer_id,
sizeof(vdata->valid_sig_info.signer_id));*/
hexdump(stdout, "pubkey ID", vdata->pubkeyid,
sizeof(vdata->pubkeyid));
/* TODO also ensure secret keys */
if((filter->key = pgp_ensure_pubkey(filter->destring,
&vdata->pubkey,
vdata->pubkeyid))==NULL){
@ -768,45 +787,132 @@ static pgp_cb_ret_t key_filter_cb (
}
}
key = filter->key;
if(key == NULL)
return PGP_FINISHED;
switch(vdata->last_seen){
case ATTRIBUTE:
printf("ATTRIBUTE\n");
break;
case ID:
printf("ID %s\n", vdata->userid);
/* XXX TODO add/update userid
* - id expiration
* - revocation
* - is primary
* */
break;
case SUBKEY:
printf("SUBKEY\n");
{
uint8_t subkeyid[PGP_KEY_ID_SIZE];
pgp_keyid(subkeyid, PGP_KEY_ID_SIZE,
&vdata->subkey, PGP_HASH_SHA1);
hexdump(stdout, "subkey ID", subkeyid,
sizeof(subkeyid));
/* XXX TODO add/update subkey
* with expiration and flags from sig info
if (memcmp(key->encid, "\0\0\0\0\0\0\0\0", 8) == 0) {
pgp_pubkey_dup(&key->enckey, pubkey);
(void) memcpy(&key->encid, pubkeyid, sizeof(PGP_KEY_ID_SIZE));
(void) memcpy(&key->encfingerprint, &key->sigfingerprint,
sizeof(key->encfingerprint));
* */
}
break;
case PRIMARYKEY:
printf("PRIMARYKEY\n");
/* XXX TODO direct key signature pgp_update_key
* with expiration and flags from sig info */
break;
default:
printf("no_last_seen\n");
break;
case PRIMARYKEY:
/* If this is a primary key revocation */
if(vdata->valid_sig_info.type == PGP_SIG_REV_KEY){
printf("PRIMARYKEY REVOKE\n");
/* Mark key. This cannot be reset, revocation isn't undoable */
key->revoked = 1;
/* Store revocation details */
/* TODO store only if new revocation made later than current
* or systematically fail, since only one revocation
* should be allowed according rfc4880 */
copy_sig_info(&key->revokeinfo,
&vdata->valid_sig_info);
pgp_copy_packet(&key->revokepacket, sigpkt);
/* Direct key signature. Stack them unconditionally */
}else{
printf("PRIMARYKEY DIRECT KEY\n");
pgp_directsig_t *directsigp;
EXPAND_ARRAY(key, directsig);
directsigp = &key->directsigs[key->directsigc++];
copy_sig_info(&directsigp->siginfo,
&vdata->valid_sig_info);
pgp_copy_packet(&directsigp->packet, sigpkt);
}
break;
case ID: {
unsigned idx = 0;
uint8_t **uidp;
pgp_uidsig_t *uidsig;
printf("ID %s\n", vdata->userid);
/* Try to find identical userID */
uidp = key->uids;
for (idx = 0 ; idx < key->uidc; idx++, uidp++) {
if (strcmp((char *)*uidp, (char *)vdata->userid) == 0) {
break;
}
}
/* Add a new one if none found */
if(idx==key->uidc){
EXPAND_ARRAY(key, uid);
uidp = &key->uids[key->uidc++];
*uidp = NULL;
pgp_copy_userid(uidp, vdata->userid);
}
/* Add uid sig info, pointing to that uid */
EXPAND_ARRAY(key, uidsig);
uidsig = &key->uidsigs[key->uidsigc++];
uidsig->uid = idx;
/* if sig packet is revocation mark uidsig */
if(vdata->valid_sig_info.type == PGP_SIG_REV_CERT){
uidsig->revoked = 1;
printf("ID %s REVOKED\n", vdata->userid);
}
/* store sig info and packet */
copy_sig_info(&uidsig->siginfo,
&vdata->valid_sig_info);
pgp_copy_packet(&uidsig->packet, sigpkt);
break;
}
case ATTRIBUTE:
printf("ATTRIBUTE -- IGNORED\n");
/* TODO */
break;
case SUBKEY:{
unsigned idx = 0;
pgp_subkey_t *subkeyp;
pgp_subkeysig_t *subkeysig;
uint8_t subkeyid[PGP_KEY_ID_SIZE];
pgp_keyid(subkeyid, PGP_KEY_ID_SIZE,
&vdata->subkey, PGP_HASH_SHA1);
printf("SUBKEY\n");
hexdump(stdout, "subkey ID", subkeyid,
sizeof(subkeyid));
/* Try to find identical ID */
subkeyp = key->subkeys;
for (idx = 0 ; idx < key->subkeyc; idx++, subkeyp++) {
if(memcmp(subkeyid, subkeyp->id,
PGP_KEY_ID_SIZE) == 0 ){
break;
}
}
/* Add a new one if none found */
if(idx==key->subkeyc){
EXPAND_ARRAY(key, subkey);
subkeyp = &key->subkeys[key->subkeyc++];
/* copy subkey material */
/* TODO also accept secret subkeys */
pgp_pubkey_dup(&subkeyp->key.pubkey, &vdata->subkey);
/* copy subkeyID */
memcpy(subkeyp->id, subkeyid, PGP_KEY_ID_SIZE);
}
/* Add subkey sig info, pointing to that subkey */
EXPAND_ARRAY(key, subkeysig);
subkeysig = &key->subkeysigs[key->subkeysigc++];
subkeysig->subkey = idx;
if(vdata->valid_sig_info.type == PGP_SIG_REV_CERT){
subkeysig->revoked = 1;
}
/* store sig info and packet */
copy_sig_info(&subkeysig->siginfo,
&vdata->valid_sig_info);
pgp_copy_packet(&subkeysig->packet, sigpkt);
break;
}
default:
printf("no_last_seen\n");
break;
}
printtime(vdata->valid_sig_info.birthtime);
return PGP_RELEASE_MEMORY;
@ -850,14 +956,7 @@ pgp_filter_keys_from_mem(pgp_io_t *io,
res = pgp_parse(stream, !printerrors);
pgp_pubkey_free(&vdata.pubkey);
if (vdata.subkey.version) {
pgp_pubkey_free(&vdata.subkey);
}
pgp_userid_free(&vdata.userid);
pgp_data_free(&vdata.userattr);
pgp_subpacket_free(&vdata.last_pkt);
pgp_free_sig_info(&vdata.valid_sig_info);
validate_key_cb_free(&vdata);
if (armour) {
pgp_reader_pop_dearmour(stream);
@ -909,15 +1008,7 @@ pgp_validate_key_sigs(pgp_validation_t *result,
pgp_parse(stream, !printerrors);
pgp_pubkey_free(&vdata.pubkey);
if (vdata.subkey.version) {
pgp_pubkey_free(&vdata.subkey);
}
pgp_userid_free(&vdata.userid);
pgp_data_free(&vdata.userattr);
pgp_subpacket_free(&vdata.last_pkt);
pgp_free_sig_info(&vdata.valid_sig_info);
validate_key_cb_free(&vdata);
pgp_stream_delete(stream);


Loading…
Cancel
Save