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