Updated sig check 2

This commit is contained in:
Bryan Ashby 2023-04-19 13:19:02 -06:00
parent 1c27891f15
commit faf8ccaaf8
No known key found for this signature in database
GPG Key ID: C2C1B501E4EFD994
1 changed files with 115 additions and 80 deletions

View File

@ -215,6 +215,31 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
}); });
} }
_getAssociatedActors(objectActorId, signatureActorId, cb) {
signatureActorId = async.waterfall(
[
callback => {
Actor.fromId(objectActorId, (err, objectActor) => {
return callback(err, objectActor);
});
},
(objectActor, callback) => {
// shortcut
if (objectActorId === signatureActorId) {
return callback(null, objectActor, objectActor);
}
Actor.fromId(signatureActorId, (err, signatureActor) => {
return callback(err, objectActor, signatureActor);
});
},
],
(err, objectActor, signatureActor) => {
return cb(err, objectActor, signatureActor);
}
);
}
_inboxPostHandler(req, resp, signature, inboxType) { _inboxPostHandler(req, resp, signature, inboxType) {
EnigAssert(signature, 'Called without signature!'); EnigAssert(signature, 'Called without signature!');
EnigAssert(signature.keyId, 'No keyId in signature!'); EnigAssert(signature.keyId, 'No keyId in signature!');
@ -239,89 +264,99 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
} }
// Fetch and validate the signature of the remote Actor // Fetch and validate the signature of the remote Actor
Actor.fromId(getActorId(activity), (err, remoteActor) => { this._getAssociatedActors(
// validate sig up front getActorId(activity),
const httpSigValidated = signature.keyId.split('#', 1)[0], // trim #main-key
remoteActor && this._validateActorSignature(remoteActor, signature); (err, remoteActor, signatureActor) => {
if (activity.type !== WellKnownActivity.Delete && !httpSigValidated) { //Actor.fromId(getActorId(activity), (err, remoteActor) => {
return this.webServer.accessDenied(resp); // validate sig up front
} const httpSigValidated =
remoteActor &&
this._validateActorSignature(signatureActor, signature);
if (activity.type !== WellKnownActivity.Delete && !httpSigValidated) {
return this.webServer.accessDenied(resp);
}
switch (activity.type) { switch (activity.type) {
case WellKnownActivity.Accept: case WellKnownActivity.Accept:
return this._inboxAcceptActivity(resp, activity); return this._inboxAcceptActivity(resp, activity);
case WellKnownActivity.Add: case WellKnownActivity.Add:
break; break;
case WellKnownActivity.Create: case WellKnownActivity.Create:
return this._inboxCreateActivity(resp, activity); return this._inboxCreateActivity(resp, activity);
case WellKnownActivity.Delete: case WellKnownActivity.Delete:
return this._inboxDeleteActivity( return this._inboxDeleteActivity(
inboxType, inboxType,
resp, resp,
activity, activity,
httpSigValidated httpSigValidated
); );
case WellKnownActivity.Update: case WellKnownActivity.Update:
{ {
// Only Notes currently supported // Only Notes currently supported
const type = _.get(activity, 'object.type'); const type = _.get(activity, 'object.type');
if ('Note' === type) { if ('Note' === type) {
// :TODO: get rid of this extra indirection // :TODO: get rid of this extra indirection
return this._inboxUpdateExistingObject( return this._inboxUpdateExistingObject(
inboxType, inboxType,
resp, resp,
activity, activity,
httpSigValidated httpSigValidated
); );
} else { } else {
this.log.warn( this.log.warn(
`Unsupported Inbox Update for type "${type}"` `Unsupported Inbox Update for type "${type}"`
); );
}
} }
} break;
break;
case WellKnownActivity.Follow: case WellKnownActivity.Follow:
// Follow requests are only allowed directly // Follow requests are only allowed directly
if (Collections.Inbox === inboxType) { if (Collections.Inbox === inboxType) {
return this._inboxFollowActivity(resp, remoteActor, activity); return this._inboxFollowActivity(
}
break;
case WellKnownActivity.Reject:
return this._inboxRejectActivity(resp, activity);
case WellKnownActivity.Undo:
// We only Undo from private inboxes
if (Collections.Inbox === inboxType) {
// Only Follow Undo's currently supported
const type = _.get(activity, 'object.type');
if (WellKnownActivity.Follow === type) {
return this._inboxUndoActivity(
resp, resp,
remoteActor, remoteActor,
activity activity
); );
} else {
this.log.warn(`Unsupported Undo for type "${type}"`);
} }
} break;
break;
default: case WellKnownActivity.Reject:
this.log.warn( return this._inboxRejectActivity(resp, activity);
{ type: activity.type, inboxType },
`Unsupported Activity type "${activity.type}"` case WellKnownActivity.Undo:
); // We only Undo from private inboxes
break; if (Collections.Inbox === inboxType) {
// Only Follow Undo's currently supported
const type = _.get(activity, 'object.type');
if (WellKnownActivity.Follow === type) {
return this._inboxUndoActivity(
resp,
remoteActor,
activity
);
} else {
this.log.warn(`Unsupported Undo for type "${type}"`);
}
}
break;
default:
this.log.warn(
{ type: activity.type, inboxType },
`Unsupported Activity type "${activity.type}"`
);
break;
}
return this.webServer.notImplemented(resp);
} }
);
return this.webServer.notImplemented(resp);
});
}); });
} }
@ -801,17 +836,17 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
return false; return false;
} }
// if (signature.keyId !== pubKey.id) { if (signature.keyId !== pubKey.id) {
// this.log.warn( this.log.warn(
// { {
// actorId: actor.id, actorId: actor.id,
// signatureKeyId: signature.keyId, signatureKeyId: signature.keyId,
// actorPubKeyId: pubKey.id, actorPubKeyId: pubKey.id,
// }, },
// 'Key ID mismatch' 'Key ID mismatch'
// ); );
// return false; return false;
// } }
if (!httpSignature.verifySignature(signature, pubKey.publicKeyPem)) { if (!httpSignature.verifySignature(signature, pubKey.publicKeyPem)) {
this.log.warn( this.log.warn(