change representation of public key in db to hex string + create room
This commit is contained in:
parent
da4f74b60c
commit
4d68e7a9f7
@ -1,4 +1,5 @@
|
|||||||
const { subtle } = require('node:crypto').webcrypto;
|
const { subtle } = require('node:crypto').webcrypto;
|
||||||
|
const stringutils = require("./stringutils");
|
||||||
|
|
||||||
const sharedSecret = process.env.SHARED_SECRET;
|
const sharedSecret = process.env.SHARED_SECRET;
|
||||||
|
|
||||||
@ -8,9 +9,9 @@ const authentication = {
|
|||||||
},
|
},
|
||||||
verifySignature : async (msg, sig, publicKeys) => {
|
verifySignature : async (msg, sig, publicKeys) => {
|
||||||
try {
|
try {
|
||||||
for (const pemPubKey of publicKeys) {
|
for (const hexKey of publicKeys) {
|
||||||
try {
|
try {
|
||||||
const pubKey = await authentication.pemToKey(pemPubKey);
|
const pubKey = await stringutils.hexToKey(hexKey);
|
||||||
const verified = await subtle.verify(
|
const verified = await subtle.verify(
|
||||||
'Ed25519',
|
'Ed25519',
|
||||||
pubKey,
|
pubKey,
|
||||||
@ -18,31 +19,16 @@ const authentication = {
|
|||||||
msg
|
msg
|
||||||
);
|
);
|
||||||
if (verified) {
|
if (verified) {
|
||||||
return pemPubKey;
|
return hexKey;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('Failed to verify signature with public key:', pemPubKey, err);
|
console.log('Failed to verify signature with public key:', hexKey, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error verifying signature:', err);
|
console.error('Error verifying signature:', err);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
pemToKey: async (pemKey) => {
|
|
||||||
const base64 = pemKey.replace(`-----BEGIN PUBLIC KEY-----`, '').replace(`-----END PUBLIC KEY-----`, '').trim();
|
|
||||||
const buffer = Buffer.from(base64, 'base64');
|
|
||||||
const uint8Array = new Uint8Array(buffer);
|
|
||||||
const publicKey = await subtle.importKey(
|
|
||||||
"spki",
|
|
||||||
uint8Array,
|
|
||||||
{
|
|
||||||
name: "Ed25519",
|
|
||||||
},
|
|
||||||
true,
|
|
||||||
["verify"],
|
|
||||||
);
|
|
||||||
return publicKey;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const database = require("../db");
|
const database = require("../db");
|
||||||
|
const stringutils = require("../stringutils");
|
||||||
const authentication = require("../authentication");
|
const authentication = require("../authentication");
|
||||||
const socket = require('../socket').default;
|
const socket = require('../socket').default;
|
||||||
|
|
||||||
@ -10,9 +11,9 @@ const accountController = {
|
|||||||
if (!sharedSecret || !publicKey) {
|
if (!sharedSecret || !publicKey) {
|
||||||
return res.status(400).json({ error: "Missing sharedSecret or publicKey" });
|
return res.status(400).json({ error: "Missing sharedSecret or publicKey" });
|
||||||
}
|
}
|
||||||
console.log('Received data:', { sharedSecret, publicKey });
|
|
||||||
if (authentication.checkSharedSecret(sharedSecret)) {
|
if (authentication.checkSharedSecret(sharedSecret)) {
|
||||||
database.addUser(publicKey);
|
let pubkey = stringutils.pemToHex(publicKey)
|
||||||
|
database.addUser(pubkey);
|
||||||
} else {
|
} else {
|
||||||
return res.status(400).json({ error: "Wrong sharedSecret" });
|
return res.status(400).json({ error: "Wrong sharedSecret" });
|
||||||
}
|
}
|
||||||
|
@ -1 +1,20 @@
|
|||||||
|
const database = require("../db");
|
||||||
|
const stringutils = require("../stringutils");
|
||||||
|
|
||||||
|
const chatController = {
|
||||||
|
add: async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { pubkey } = req.body;
|
||||||
|
if (!pubkey) {
|
||||||
|
return res.status(400).json({ error: "Missing publicKey" });
|
||||||
|
}
|
||||||
|
await database.createRoom(req.session.publicKey, stringutils.pemToHex(pubkey));
|
||||||
|
return res.status(201).json({ message: "Room created successfully." });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error creating the room:", error);
|
||||||
|
return res.status(500).json({ error: "Failed to create the room" });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = chatController;
|
||||||
|
@ -1,39 +1,13 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const stringutils = require("../stringutils");
|
||||||
|
|
||||||
const mainController = {
|
const mainController = {
|
||||||
root: (req, res) => {
|
root: (req, res) => {
|
||||||
let pubKey = req.session.publicKey;
|
let pubKeyHex = req.session.publicKey;
|
||||||
console.log(pubKey);
|
let isLoggedIn = typeof pubKeyHex !== 'undefined';
|
||||||
let isLoggedIn = typeof pubKey !== 'undefined';
|
let pubKey = isLoggedIn ? stringutils.hexToPem(pubKeyHex).replaceAll('\n','') : null;
|
||||||
res.render('index', {isLoggedIn, pubKey});
|
res.render('index', {isLoggedIn, pubKey});
|
||||||
},
|
}
|
||||||
// style: (req, res) => {
|
|
||||||
// res.sendFile(path.resolve(__dirname + '/../public/style.css'));
|
|
||||||
// },
|
|
||||||
// script: (req, res) => {
|
|
||||||
// res.sendFile(path.resolve(__dirname + '/../public/script.js'));
|
|
||||||
// },
|
|
||||||
// ecc: (req, res) => {
|
|
||||||
// res.sendFile(path.resolve(__dirname + '/../public/ecc.js'));
|
|
||||||
// },
|
|
||||||
// ecdh: (req, res) => {
|
|
||||||
// res.sendFile(path.resolve(__dirname + '/../public/ecdh.js'));
|
|
||||||
// },
|
|
||||||
// popups: (req, res) => {
|
|
||||||
// res.sendFile(path.resolve(__dirname + '/../public/popups.js'));
|
|
||||||
// },
|
|
||||||
// chat : (req, res) => {
|
|
||||||
// res.sendFile(path.resolve(__dirname + '/../public/chat.js'));
|
|
||||||
// },
|
|
||||||
// register : (req, res) => {
|
|
||||||
// res.sendFile(path.resolve(__dirname + '/../public/register.js'));
|
|
||||||
// },
|
|
||||||
// pubkey : (req, res) => {
|
|
||||||
// res.sendFile(path.resolve(__dirname + '/../public/pubkey.js'));
|
|
||||||
// },
|
|
||||||
// registertext : (req, res) => {
|
|
||||||
// res.sendFile(path.resolve(__dirname + '/../public/registertext.js'));
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = mainController;
|
module.exports = mainController;
|
||||||
|
74
src/db.js
74
src/db.js
@ -35,40 +35,43 @@ const database = {
|
|||||||
createTables: () => {
|
createTables: () => {
|
||||||
pool.query(`
|
pool.query(`
|
||||||
CREATE TABLE IF NOT EXISTS "users" (
|
CREATE TABLE IF NOT EXISTS "users" (
|
||||||
uuid integer PRIMARY KEY,
|
uuid SERIAL PRIMARY KEY,
|
||||||
pubkey text
|
pubkey text
|
||||||
);
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS "room" (
|
||||||
|
uuid SERIAL PRIMARY KEY
|
||||||
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS "room_members" (
|
||||||
|
room_uuid INTEGER REFERENCES "room"(uuid),
|
||||||
|
user_uuid INTEGER REFERENCES "users"(uuid),
|
||||||
|
PRIMARY KEY (room_uuid, user_uuid)
|
||||||
|
);
|
||||||
`, (err, _) => {
|
`, (err, _) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('Error creating users table', err);
|
console.error('Error creating tables', err);
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
pool.query(`
|
console.log("tables created successfully.");
|
||||||
CREATE SEQUENCE IF NOT EXISTS uuid_sequence
|
|
||||||
INCREMENT BY 1
|
|
||||||
START WITH 1;
|
|
||||||
`, (err, _) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('Error creating sequence', err);
|
|
||||||
} else {
|
|
||||||
console.log("users table and sequence created successfully.");
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
checkSchema: () => {
|
checkSchema: () => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
pool.query(`
|
pool.query(`
|
||||||
SELECT EXISTS (
|
SELECT
|
||||||
SELECT 1 FROM pg_tables WHERE tablename = 'users'
|
(EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'users'))
|
||||||
) AS table_exists;
|
AND
|
||||||
|
(EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'room'))
|
||||||
|
AND
|
||||||
|
(EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'room_members'))
|
||||||
|
AS all_tables_exist;
|
||||||
`, (err, res) => {
|
`, (err, res) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('Error executing query', err);
|
console.error('Error executing query', err);
|
||||||
reject(err);
|
reject(err);
|
||||||
} else {
|
} else {
|
||||||
const tableExists = res.rows[0].table_exists;
|
const all_tables_exist = res.rows[0].all_tables_exist;
|
||||||
resolve(tableExists);
|
resolve(all_tables_exist);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -90,17 +93,44 @@ const database = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const result = await pool.query('SELECT NEXTVAL(\'uuid_sequence\') AS next_uuid');
|
|
||||||
const nextUuid = result.rows[0].next_uuid;
|
|
||||||
await pool.query(
|
await pool.query(
|
||||||
'INSERT INTO "users" (uuid, pubkey) VALUES ($1, $2)',
|
'INSERT INTO "users" (uuid, pubkey) VALUES (DEFAULT, $1)',
|
||||||
[nextUuid, pubkey]
|
[pubkey,]
|
||||||
);
|
);
|
||||||
console.log(`Added user with the public key ${pubkey} .`);
|
console.log(`Added user with the public key ${pubkey} .`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error adding user:', err);
|
console.error('Error adding user:', err);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
createRoom: async (pubkey1, pubkey2) => {
|
||||||
|
try {
|
||||||
|
const userQuery = 'SELECT uuid FROM users WHERE pubkey = $1';
|
||||||
|
const uuidRes1 = await pool.query(userQuery, [pubkey1]);
|
||||||
|
const uuidRes2 = await pool.query(userQuery, [pubkey2]);
|
||||||
|
|
||||||
|
if (!uuidRes1.rows[0] || !uuidRes2.rows[0]) {
|
||||||
|
throw new Error('One or both users not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const uuid1 = uuidRes1.rows[0].uuid;
|
||||||
|
const uuid2 = uuidRes2.rows[0].uuid;
|
||||||
|
|
||||||
|
const roomRes = await pool.query(
|
||||||
|
'INSERT INTO room (uuid) VALUES (DEFAULT) RETURNING uuid'
|
||||||
|
);
|
||||||
|
const roomid = roomRes.rows[0].uuid;
|
||||||
|
|
||||||
|
await pool.query(
|
||||||
|
`INSERT INTO room_members (room_uuid, user_uuid)
|
||||||
|
VALUES ($1, $2), ($1, $3)`,
|
||||||
|
[roomid, uuid1, uuid2]
|
||||||
|
);
|
||||||
|
return roomid;
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error creating the room:', err);
|
||||||
|
throw err; // Re-throw to handle in calling code
|
||||||
|
}
|
||||||
|
},
|
||||||
getPublicKeys: async () => {
|
getPublicKeys: async () => {
|
||||||
try {
|
try {
|
||||||
const result = await pool.query('SELECT pubkey FROM users');
|
const result = await pool.query('SELECT pubkey FROM users');
|
||||||
|
51
src/public/popups-logged.js
Normal file
51
src/public/popups-logged.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
const currentUrl = window.location.href;
|
||||||
|
|
||||||
|
// handle key presses (close/confirm)
|
||||||
|
document.addEventListener("keydown", async function(event) {
|
||||||
|
if (event.isComposing || event.key === 'Escape') {
|
||||||
|
Array.from(document.getElementsByClassName("popup")).forEach(function(x) {
|
||||||
|
x.style.display = 'none';
|
||||||
|
});
|
||||||
|
document.getElementById("publickeyadd").innerText = "";
|
||||||
|
} else if (event.key === 'Enter') {
|
||||||
|
if (addPopup.style.display == 'flex') {
|
||||||
|
await addConfirm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// add popup
|
||||||
|
document.getElementById("add").addEventListener("click", function () {
|
||||||
|
addPopup.style.display = 'flex';
|
||||||
|
});
|
||||||
|
// cancel
|
||||||
|
document.getElementById("addcancel").addEventListener("click", function () {
|
||||||
|
addPopup.style.display = 'none';
|
||||||
|
document.getElementById("publickeyadd").innerText = "";
|
||||||
|
});
|
||||||
|
//confirm
|
||||||
|
document.getElementById("addconfirm").addEventListener("click", async () => {
|
||||||
|
await addConfirm();
|
||||||
|
});
|
||||||
|
|
||||||
|
export async function addConfirm() {
|
||||||
|
const apiUrl = `${currentUrl}chat/add`;
|
||||||
|
const inputFieldPublicKey = document.getElementById("publickeyadd");
|
||||||
|
|
||||||
|
const response = await fetch(apiUrl, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
pubkey: inputFieldPublicKey.value
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to add');
|
||||||
|
} else {
|
||||||
|
inputFieldPublicKey.value = '';
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,9 @@
|
|||||||
// const express = require("express");
|
const express = require("express");
|
||||||
// const chatController = require("../controllers/chat");
|
const chatController = require("../controllers/chat");
|
||||||
// const router = express.Router();
|
const router = express.Router();
|
||||||
//
|
|
||||||
// module.exports = router;
|
router
|
||||||
|
.route("/add")
|
||||||
|
.post(chatController.add);
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
const express = require("express");
|
const express = require("express");
|
||||||
const rootRoutes = require('./root');
|
const rootRoutes = require('./root');
|
||||||
const accountRoutes = require('./account.js');
|
const accountRoutes = require('./account.js');
|
||||||
// const chatRoutes = require('./chat.js');
|
const chatRoutes = require('./chat.js');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
router.use("/", rootRoutes);
|
router.use("/", rootRoutes);
|
||||||
router.use("/account", accountRoutes);
|
router.use("/account", accountRoutes);
|
||||||
// router.use("/chat", chatRoutes);
|
router.use("/chat", chatRoutes);
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
@ -1,9 +1,52 @@
|
|||||||
|
const { subtle } = require('node:crypto').webcrypto;
|
||||||
|
|
||||||
const stringutils = {
|
const stringutils = {
|
||||||
hexToArray: (hexString) => {
|
hexToArray: (hexString) => {
|
||||||
return Uint8Array.from(Buffer.from(hexString, 'hex'));
|
return Uint8Array.from(Buffer.from(hexString, 'hex'));
|
||||||
},
|
},
|
||||||
arrayToHex: (hex) => {
|
arrayToHex: (hex) => {
|
||||||
return Buffer.from(hex).toString('hex');
|
return Buffer.from(hex).toString('hex');
|
||||||
|
},
|
||||||
|
pemToHex: (pemKey) => {
|
||||||
|
const base64 = pemKey.replace(`-----BEGIN PUBLIC KEY-----`, '').replace(`-----END PUBLIC KEY-----`, '').trim().replaceAll('\n','');
|
||||||
|
const buffer = Buffer.from(base64, 'base64');
|
||||||
|
const hex = buffer.toString('hex');
|
||||||
|
return hex
|
||||||
|
},
|
||||||
|
hexToPem: (hexString) => {
|
||||||
|
const buffer = Buffer.from(hexString, 'hex');
|
||||||
|
const base64 = buffer.toString('base64');
|
||||||
|
// split into 64 character long chunks for PEM format
|
||||||
|
const base64Chunks = base64.match(/.{1,64}/g) || [];
|
||||||
|
return `-----BEGIN PUBLIC KEY-----\n${base64Chunks.join('\n')}\n-----END PUBLIC KEY-----`;
|
||||||
|
},
|
||||||
|
hexToKey: async (hexString) => {
|
||||||
|
const uint8Array = stringutils.hexToArray(hexString);
|
||||||
|
const publicKey = await subtle.importKey(
|
||||||
|
"spki",
|
||||||
|
uint8Array,
|
||||||
|
{
|
||||||
|
name: "Ed25519",
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
["verify"],
|
||||||
|
);
|
||||||
|
return publicKey;
|
||||||
|
},
|
||||||
|
pemToKey: async (pemKey) => {
|
||||||
|
const base64 = pemKey.replace(`-----BEGIN PUBLIC KEY-----`, '').replace(`-----END PUBLIC KEY-----`, '').trim();
|
||||||
|
const buffer = Buffer.from(base64, 'base64');
|
||||||
|
const uint8Array = new Uint8Array(buffer);
|
||||||
|
const publicKey = await subtle.importKey(
|
||||||
|
"spki",
|
||||||
|
uint8Array,
|
||||||
|
{
|
||||||
|
name: "Ed25519",
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
["verify"],
|
||||||
|
);
|
||||||
|
return publicKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = stringutils;
|
module.exports = stringutils;
|
||||||
|
@ -13,6 +13,7 @@ html(lang="en-US")
|
|||||||
script(src="/pubkey.js", defer)
|
script(src="/pubkey.js", defer)
|
||||||
script(src="/noble-curves.js", defer)
|
script(src="/noble-curves.js", defer)
|
||||||
script(type="module", src="/ecdh.js", defer)
|
script(type="module", src="/ecdh.js", defer)
|
||||||
|
script(type="module", src="/popups-logged.js", defer)
|
||||||
else
|
else
|
||||||
script(type="module", src="/popups.js", defer)
|
script(type="module", src="/popups.js", defer)
|
||||||
script(type="module", src="/register.js", defer)
|
script(type="module", src="/register.js", defer)
|
||||||
@ -47,7 +48,8 @@ html(lang="en-US")
|
|||||||
else
|
else
|
||||||
.btn-toolbar.btn-group-sm(role="toolbar", aria-label="Toolbar")
|
.btn-toolbar.btn-group-sm(role="toolbar", aria-label="Toolbar")
|
||||||
.btn-group.mr-2(role="group", aria-label="logout")
|
.btn-group.mr-2(role="group", aria-label="logout")
|
||||||
a#logout.btn.btn-secondary(href="./account/logout") logout
|
a#logout.btn.btn-secondary(href="/account/logout") logout
|
||||||
|
button#add.btn.btn-secondary(type="button") add
|
||||||
|
|
||||||
|
|
||||||
.d-flex.mb-3
|
.d-flex.mb-3
|
||||||
@ -60,5 +62,12 @@ html(lang="en-US")
|
|||||||
input#input(autocomplete="off")
|
input#input(autocomplete="off")
|
||||||
button Send
|
button Send
|
||||||
|
|
||||||
|
#addPopup.popup
|
||||||
|
.popup-content
|
||||||
|
.btn-group.mr-2.w-100(role="group", aria-label="Add group")
|
||||||
|
input#publickeyadd.form-control.input-sm.w-50(type="text", placeholder="public key", required)
|
||||||
|
button#addconfirm.btn.btn-secondary(type="button") confirm
|
||||||
|
button#addcancel.btn.btn-secondary(type="button") cancel
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,36 @@
|
|||||||
const { subtle } = require('node:crypto').webcrypto;
|
const { subtle } = require('node:crypto').webcrypto;
|
||||||
const authentication = require('../src/authentication');
|
const authentication = require('../src/authentication');
|
||||||
|
const stringutils = require("../src/stringutils");
|
||||||
|
|
||||||
describe('authentication module', () => {
|
describe('authentication module', () => {
|
||||||
|
it('conversion between pem and hex', async () => {
|
||||||
|
let pemKey = '-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEALrj4A3Vftz5TgWXEHi5KG+HD+uQLGB3bGc4TprDi9kE=\n-----END PUBLIC KEY-----';
|
||||||
|
let hexKey = stringutils.pemToHex(pemKey);
|
||||||
|
let pemKeyFromHex = stringutils.hexToPem(hexKey);
|
||||||
|
expect(pemKeyFromHex).toBe(pemKey);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should convert a pemkey to hex', async () => {
|
||||||
|
const { publicKey, privateKey } = await crypto.subtle.generateKey(
|
||||||
|
{
|
||||||
|
name: "Ed25519",
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
["sign", "verify"],
|
||||||
|
);
|
||||||
|
const exportedPubkey = await crypto.subtle.exportKey("spki", publicKey);
|
||||||
|
const exportedBuffer = Buffer.from(exportedPubkey);
|
||||||
|
const exportedAsBase64 = exportedBuffer.toString('base64');
|
||||||
|
let pemKey = `-----BEGIN PUBLIC KEY-----\n${exportedAsBase64}\n-----END PUBLIC KEY-----`;
|
||||||
|
let hexKey = stringutils.pemToHex(pemKey);
|
||||||
|
let importedKey = await stringutils.hexToKey(hexKey);
|
||||||
|
const exportedPubkeyAgain = await crypto.subtle.exportKey("spki", importedKey);
|
||||||
|
const exportedBufferAgain = Buffer.from(exportedPubkeyAgain);
|
||||||
|
const exportedAsBase64Again = exportedBufferAgain.toString('base64');
|
||||||
|
let pemKeyAgain = `-----BEGIN PUBLIC KEY-----\n${exportedAsBase64Again}\n-----END PUBLIC KEY-----`;
|
||||||
|
expect(pemKeyAgain).toBe(pemKey);
|
||||||
|
});
|
||||||
|
|
||||||
it('should return the public key if the signature is verified successfully', async () => {
|
it('should return the public key if the signature is verified successfully', async () => {
|
||||||
const { publicKey, privateKey } = await crypto.subtle.generateKey(
|
const { publicKey, privateKey } = await crypto.subtle.generateKey(
|
||||||
{
|
{
|
||||||
@ -11,10 +40,11 @@ describe('authentication module', () => {
|
|||||||
["sign", "verify"],
|
["sign", "verify"],
|
||||||
);
|
);
|
||||||
const exportedPubkey = await crypto.subtle.exportKey("spki", publicKey);
|
const exportedPubkey = await crypto.subtle.exportKey("spki", publicKey);
|
||||||
let exportedAsString = String.fromCharCode.apply(null, new Uint8Array(exportedPubkey));
|
const exportedBuffer = Buffer.from(exportedPubkey);
|
||||||
let exportedAsBase64 = Buffer.from(exportedAsString, 'binary').toString('base64');
|
const exportedAsBase64 = exportedBuffer.toString('base64');
|
||||||
let pemKey = `-----BEGIN PUBLIC KEY-----\n${exportedAsBase64}\n-----END PUBLIC KEY-----`;
|
let pemKey = `-----BEGIN PUBLIC KEY-----\n${exportedAsBase64}\n-----END PUBLIC KEY-----`;
|
||||||
const publicKeys = [pemKey,];
|
let hexKey = stringutils.pemToHex(pemKey);
|
||||||
|
const publicKeys = [hexKey,];
|
||||||
const msg = 'test message';
|
const msg = 'test message';
|
||||||
const encoder = new TextEncoder();
|
const encoder = new TextEncoder();
|
||||||
const encodedData = encoder.encode(msg);
|
const encodedData = encoder.encode(msg);
|
||||||
@ -26,10 +56,11 @@ describe('authentication module', () => {
|
|||||||
encodedData,
|
encodedData,
|
||||||
);
|
);
|
||||||
const result = await authentication.verifySignature(encodedData, signature, publicKeys);
|
const result = await authentication.verifySignature(encodedData, signature, publicKeys);
|
||||||
expect(result).toBe(pemKey);
|
expect(result).toBe(hexKey);
|
||||||
|
|
||||||
let fakeKey = `-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAmrBLT6lyiFh/eUticsIFNY6AkjXuQPqj0Qvb99pCJJk=\n-----END PUBLIC KEY-----`
|
let fakeKey = `-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAmrBLT6lyiFh/eUticsIFNY6AkjXuQPqj0Qvb99pCJJk=\n-----END PUBLIC KEY-----`
|
||||||
const result2 = await authentication.verifySignature(encodedData, signature, [fakeKey,]);
|
let fakeKeyHex = stringutils.pemToHex(fakeKey);
|
||||||
|
const result2 = await authentication.verifySignature(encodedData, signature, [fakeKeyHex,]);
|
||||||
expect(result2).toBe(null);
|
expect(result2).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -62,10 +93,11 @@ describe('authentication module', () => {
|
|||||||
|
|
||||||
const sig = Buffer.from(signatureBase64, 'base64');
|
const sig = Buffer.from(signatureBase64, 'base64');
|
||||||
|
|
||||||
let pemKey2 = '-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEALrj4A3Vftz5TgWXEHi5KG+HD+uQLGB3bGc4TprDi9kE=\n-----END PUBLIC KEY-----'
|
let pemKey2 = '-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEALrj4A3Vftz5TgWXEHi5KG+HD+uQLGB3bGc4TprDi9kE=\n-----END PUBLIC KEY-----';
|
||||||
const publicKeys2 = [pemKey2,];
|
let hexKey2 = stringutils.pemToHex(pemKey2);
|
||||||
|
const publicKeys2 = [hexKey2,];
|
||||||
const result3 = await authentication.verifySignature(encodedData2, sig, publicKeys2);
|
const result3 = await authentication.verifySignature(encodedData2, sig, publicKeys2);
|
||||||
expect(result3).toBe(pemKey2);
|
expect(result3).toBe(hexKey2);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user