identity/identity-api/src/m2m.ts

106 lines
3.1 KiB
TypeScript
Raw Normal View History

2024-06-29 17:12:12 +00:00
// Identity. Store your memories and mental belongings
// Copyright (C) 2024 Sofía Aritz
2024-06-29 18:11:53 +00:00
//
2024-06-29 17:12:12 +00:00
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
2024-06-29 18:11:53 +00:00
//
2024-06-29 17:12:12 +00:00
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
2024-06-29 18:11:53 +00:00
//
2024-06-29 17:12:12 +00:00
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
2024-06-25 22:29:26 +00:00
import { createVerify } from "node:crypto";
2024-06-29 18:11:53 +00:00
import assert from "node:assert";
2024-06-25 22:29:26 +00:00
import app from "./app.js";
import { ASSET_API_ENDPOINT, ASSET_API_M2M_REFRESH_INTERVAL } from "./consts.js";
2024-06-30 16:52:10 +00:00
let assetPubKey;
try {
assetPubKey = await fetchAssetPubkey();
} catch (e) {
console.error("Couldn't retrieve the pubkey from the asset-api. Is the asset-api server running?")
process.exit(1);
}
let assetAlgorithm;
try {
assetAlgorithm = await fetchAssetAlgorithm();
} catch (e) {
console.error("Couldn't retrieve the algorithm from the asset-api. Is the asset-api server running?")
process.exit(1);
}
2024-06-25 22:29:26 +00:00
setInterval(async () => {
try {
let pubkey = await fetchAssetPubkey();
let algo = await fetchAssetAlgorithm();
if (pubkey != null && algo != null) {
if (assetPubKey !== pubkey) {
2024-06-29 18:11:53 +00:00
app.log.warn("The M2M public key has changed!");
2024-06-25 22:29:26 +00:00
}
if (assetAlgorithm !== algo) {
app.log.warn("The M2M algorith has changed!");
}
assetPubKey = pubkey;
assetAlgorithm = algo;
app.log.debug("Successfully updated the M2M credentials");
} else {
app.log.warn("Failed to retrieve the M2M credentials");
}
} catch (e) {
app.log.warn("Failed to update the M2M credentials");
app.log.warn(e);
}
2024-06-29 18:11:53 +00:00
}, ASSET_API_M2M_REFRESH_INTERVAL);
2024-06-25 22:29:26 +00:00
async function fetchAssetPubkey() {
let url = new URL(ASSET_API_ENDPOINT);
url.pathname = "/crypto/cert";
let res = await fetch(url);
return await res.text();
}
async function fetchAssetAlgorithm() {
let url = new URL(ASSET_API_ENDPOINT);
url.pathname = "/crypto/algo";
let res = await fetch(url);
return await res.text();
}
function partsFromSigned(content) {
let parts = content
.replace("-----BEGIN SIGNED MESSAGE-----\n\n", "")
.replace("\n-----END SIGNATURE-----", "")
.split("\n\n-----BEGIN SIGNATURE-----\n\n");
assert(parts.length === 2);
2024-06-29 18:11:53 +00:00
return parts;
2024-06-25 22:29:26 +00:00
}
export function verifySignature(content) {
2024-06-29 18:11:53 +00:00
let parts = partsFromSigned(content);
2024-06-25 22:29:26 +00:00
let verify = createVerify(assetAlgorithm);
verify.update(parts[0]);
let pubkey = Buffer.from(assetPubKey, "ascii");
let digest = Buffer.from(parts[1], "base64");
return verify.verify(pubkey, digest);
}
export function contentFromSigned(content) {
return partsFromSigned(content)[0];
2024-06-29 18:11:53 +00:00
}