add pgp verification support

This commit is contained in:
Aidan 2024-11-13 14:54:53 -05:00
parent 9aea40e3d1
commit d1b76e830b
No known key found for this signature in database
GPG Key ID: B863233834530C44
2 changed files with 56 additions and 3 deletions

46
app.js
View File

@ -1,20 +1,64 @@
const express = require('express');
const openpgp = require('openpgp');
const path = require('path');
const fs = require('fs');
const app = express();
app.use(express.urlencoded({ extended: true }));
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.json());
const routes = ['/', '/about', '/contact', '/verify', '/status', '/design', '/projects', '/cloud'];
const PUBKEY = path.join(__dirname, 'src', 'pgp', 'publickey.asc');
const routes = ['/', '/about', '/contact', '/status', '/design', '/projects', '/cloud'];
routes.forEach(route => {
app.get(route, (req, res) => {
res.render(route === '/' ? 'index' : route.slice(1), { req });
});
});
app.get('/verify', (req, res) => {
res.render('verify', { req, verifyResult: null });
});
app.post('/verify', async (req, res) => {
const { pgpMessage } = req.body;
try {
const pubKeyArmored = fs.readFileSync(PUBKEY, 'utf8');
const pubKey = await openpgp.readKey({ armoredKey: pubKeyArmored });
const cleartextMessage = await openpgp.readCleartextMessage({ cleartextMessage: pgpMessage });
const verifyResult = await openpgp.verify({
message: cleartextMessage,
verificationKeys: pubKey,
});
const isValid = await verifyResult.signatures[0].verified;
let resultMessage;
if (isValid) {
resultMessage = '✅ Signature is valid!';
} else {
resultMessage = '❌ Signature is invalid or message has been tampered with.';
}
res.render('verify', { req, verifyResult: resultMessage });
} catch (error) {
if (error.message.includes("Could not find signing key")) {
console.error('Verification failed: Unknown/invalid signing key');
res.render('verify', { req, verifyResult: '❌ Signature is from unknown signer or invalid.' });
} else {
console.error('Verification failed:', error);
res.render('verify', { req, verifyResult: '❌ An error occurred during verification.' });
}
}
});
const PORT = process.env.PORT || 5566;
app.listen(PORT, () => {
const now = new Date();

View File

@ -22,9 +22,18 @@
<h3 class="text-2xl font-bold mb-4 text-white">Introduction</h3>
<p class="text-slate-300 mb-4">Did I send you a PGP signed message? Let's check it's actually from me! The form below will verify the message was signed by my key.</p>
<p class="text-slate-300 mb-4"><span class="font-bold">Remember</span>, if you have confirmed my key in person, you should always trust that key over this page.</p>
<p class="text-slate-300 mb-4">The key this is being checked against is stored on my server, which can be prone to being hacked. Thus, this is better than nothing, but not the #1 option for verifying a message.</p>
<p class="text-slate-300 mb-4">The key this is being checked against is stored on my server, which can be prone to being hacked. Thus, this is better than nothing, but not the #1 option for verifying a message. As of now, messages are checked by the server, not locally.</p>
<h3 class="text-2xl font-bold mb-4 text-white">Check Message</h3>
<p class="text-slate-300 font-bold">THIS FORM IS NOT CURRENTLY AVAILABLE</p>
<form action="/verify" method="POST" class="space-y-4">
<label for="pgpMessage" class="block text-slate-300">PGP Message:</label>
<textarea id="pgpMessage" name="pgpMessage" class="w-full p-2 bg-slate-800 text-slate-300 rounded-md" rows="10" placeholder="Paste a PGP-signed message here"></textarea>
<button type="submit" class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded">Verify</button>
</form>
<% if (verifyResult) { %>
<div class="mt-4 p-4 rounded bg-slate-800 text-white">
<p><%= verifyResult %></p>
</div>
<% } %>
</div>
<script src="js/main.js"></script>
<%- include('shards/footer.ejs') %>