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