extract verifying a signed object from the device tracker
This commit is contained in:
parent
bd64aaf029
commit
0545c1f0c5
2 changed files with 28 additions and 22 deletions
|
@ -14,13 +14,11 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import anotherjson from "../../../lib/another-json/index.js";
|
import {verifyEd25519Signature, SIGNATURE_ALGORITHM} from "./common.js";
|
||||||
|
|
||||||
const TRACKING_STATUS_OUTDATED = 0;
|
const TRACKING_STATUS_OUTDATED = 0;
|
||||||
const TRACKING_STATUS_UPTODATE = 1;
|
const TRACKING_STATUS_UPTODATE = 1;
|
||||||
|
|
||||||
const DEVICE_KEYS_SIGNATURE_ALGORITHM = "ed25519";
|
|
||||||
|
|
||||||
// map 1 device from /keys/query response to DeviceIdentity
|
// map 1 device from /keys/query response to DeviceIdentity
|
||||||
function deviceKeysAsDeviceIdentity(deviceSection) {
|
function deviceKeysAsDeviceIdentity(deviceSection) {
|
||||||
const deviceId = deviceSection["device_id"];
|
const deviceId = deviceSection["device_id"];
|
||||||
|
@ -200,7 +198,7 @@ export class DeviceTracker {
|
||||||
if (deviceIdOnKeys !== deviceId) {
|
if (deviceIdOnKeys !== deviceId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this._verifyUserDeviceKeys(deviceKeys);
|
return this._hasValidSignature(deviceKeys);
|
||||||
});
|
});
|
||||||
const verifiedKeys = verifiedEntries.map(([, deviceKeys]) => deviceKeys);
|
const verifiedKeys = verifiedEntries.map(([, deviceKeys]) => deviceKeys);
|
||||||
return {userId, verifiedKeys};
|
return {userId, verifiedKeys};
|
||||||
|
@ -208,26 +206,11 @@ export class DeviceTracker {
|
||||||
return verifiedKeys;
|
return verifiedKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
_verifyUserDeviceKeys(deviceSection) {
|
_hasValidSignature(deviceSection) {
|
||||||
const deviceId = deviceSection["device_id"];
|
const deviceId = deviceSection["device_id"];
|
||||||
const userId = deviceSection["user_id"];
|
const userId = deviceSection["user_id"];
|
||||||
const clone = Object.assign({}, deviceSection);
|
const ed25519Key = deviceSection?.keys?.[`${SIGNATURE_ALGORITHM}:${deviceId}`];
|
||||||
delete clone.unsigned;
|
return verifyEd25519Signature(this._olmUtil, userId, deviceId, ed25519Key, deviceSection);
|
||||||
delete clone.signatures;
|
|
||||||
const canonicalJson = anotherjson.stringify(clone);
|
|
||||||
const key = deviceSection?.keys?.[`${DEVICE_KEYS_SIGNATURE_ALGORITHM}:${deviceId}`];
|
|
||||||
const signature = deviceSection?.signatures?.[userId]?.[`${DEVICE_KEYS_SIGNATURE_ALGORITHM}:${deviceId}`];
|
|
||||||
try {
|
|
||||||
if (!signature) {
|
|
||||||
throw new Error("no signature");
|
|
||||||
}
|
|
||||||
// throws when signature is invalid
|
|
||||||
this._olmUtil.ed25519_verify(key, canonicalJson, signature);
|
|
||||||
return true;
|
|
||||||
} catch (err) {
|
|
||||||
console.warn("Invalid device signature, ignoring device.", key, canonicalJson, signature, err);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import anotherjson from "../../../lib/another-json/index.js";
|
||||||
|
|
||||||
// use common prefix so it's easy to clear properties that are not e2ee related during session clear
|
// use common prefix so it's easy to clear properties that are not e2ee related during session clear
|
||||||
export const SESSION_KEY_PREFIX = "e2ee:";
|
export const SESSION_KEY_PREFIX = "e2ee:";
|
||||||
export const OLM_ALGORITHM = "m.olm.v1.curve25519-aes-sha2";
|
export const OLM_ALGORITHM = "m.olm.v1.curve25519-aes-sha2";
|
||||||
|
@ -27,3 +29,24 @@ export class DecryptionError extends Error {
|
||||||
this.details = detailsObj;
|
this.details = detailsObj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const SIGNATURE_ALGORITHM = "ed25519";
|
||||||
|
|
||||||
|
export function verifyEd25519Signature(olmUtil, userId, deviceOrKeyId, ed25519Key, value) {
|
||||||
|
const clone = Object.assign({}, value);
|
||||||
|
delete clone.unsigned;
|
||||||
|
delete clone.signatures;
|
||||||
|
const canonicalJson = anotherjson.stringify(clone);
|
||||||
|
const signature = value?.signatures?.[userId]?.[`${SIGNATURE_ALGORITHM}:${deviceOrKeyId}`];
|
||||||
|
try {
|
||||||
|
if (!signature) {
|
||||||
|
throw new Error("no signature");
|
||||||
|
}
|
||||||
|
// throws when signature is invalid
|
||||||
|
this._olmUtil.ed25519_verify(ed25519Key, canonicalJson, signature);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
console.warn("Invalid signature, ignoring.", ed25519Key, canonicalJson, signature, err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Reference in a new issue