From 1816cd3cf1ff7607cd7ee152cc74c06f473541ad Mon Sep 17 00:00:00 2001 From: Sam Hadow Date: Sun, 16 Feb 2025 23:59:05 +0100 Subject: [PATCH] fix authentication + public key linked to socket.io --- src/app.js | 29 ++++++++++++++++----------- src/authentication.js | 1 - src/controllers/account.js | 16 ++++++++++----- src/controllers/main.js | 1 + src/socket.js | 3 ++- src/views/index.pug | 4 ++++ tests/authentication.test.js | 38 +++++++++++++++++++++++++++++++++++- 7 files changed, 73 insertions(+), 19 deletions(-) diff --git a/src/app.js b/src/app.js index da5b8d3..ac249b3 100644 --- a/src/app.js +++ b/src/app.js @@ -16,6 +16,13 @@ const routes = require(__dirname + '/routes'); // session (used for login challenge) const session = require('express-session'); const SQLiteStore = require('connect-sqlite3')(session); +const sessionMiddleware = session({ + store: new SQLiteStore, + secret: process.env.COOKIE_SECRET || "toto", + resave: false, + saveUninitialized: true, + cookie: { maxAge: 7 * 24 * 60 * 60 * 1000 } // 1 week +}); // configure app app.set("port", port); @@ -23,24 +30,24 @@ app.set('view engine', 'pug'); app.set('views', __dirname + '/views'); app.use(cookieParser()); app.use(express.json()); -app.use(session({ - store: new SQLiteStore, - secret: process.env.COOKIE_SECRET || "toto", - resave: false, - saveUninitialized: true, - cookie: { maxAge: 7 * 24 * 60 * 60 * 1000 } // 1 week -})); +app.use(sessionMiddleware); app.use("/", routes); // bootstrap app.use('/css', express.static(__dirname + '/node_modules/bootstrap/dist/css')); // socket.io +io.engine.use(sessionMiddleware); io.on('connection', (socket) => { - console.log('A user connected'); - socket.on('disconnect', () => { - console.log('User disconnected'); - }); + const session = socket.request.session; + console.log('A user connected'); + socket.on('disconnect', () => { + console.log('User disconnected'); + }); + socket.on('chat message', (msg) => { + console.log('message: ' + msg + ', sender: ' + session.id); + console.log(session.publicKey); + }); }); diff --git a/src/authentication.js b/src/authentication.js index 0461144..1cacf87 100644 --- a/src/authentication.js +++ b/src/authentication.js @@ -18,7 +18,6 @@ const authentication = { msg ); if (verified) { - console.log('Signature verified successfully with public key:', pemPubKey); return pemPubKey; } } catch (err) { diff --git a/src/controllers/account.js b/src/controllers/account.js index 125501d..60776e6 100644 --- a/src/controllers/account.js +++ b/src/controllers/account.js @@ -36,13 +36,19 @@ const accountController = { const { signature } = req.body; const publicKeys = await database.getPublicKeys(); const msg = new TextEncoder().encode(req.session.randomNumber); - const sig = new TextEncoder().encode(signature); - let validKey = authentication.verifySignature(msg, sig, publicKeys); + const sig = Buffer.from(signature, 'base64'); + let validKey = await authentication.verifySignature(msg, sig, publicKeys); if (validKey !== null) { req.session.publicKey = validKey; - socket.auth = { validKey }; - socket.connect(); - return res.status(200).json({ message: "Challenge solved successfully" }); + req.session.save((err) => { + if (err) { + console.error("Error saving session:", err); + return res.status(500).json({ error: "Session save error" }); + } + socket.auth = { validKey }; + socket.connect(); + return res.status(200).json({ message: "Challenge solved successfully" }); + }); } else { return res.status(400).json({ error: "Challenge failed" }); } diff --git a/src/controllers/main.js b/src/controllers/main.js index 942d46f..2137e33 100644 --- a/src/controllers/main.js +++ b/src/controllers/main.js @@ -3,6 +3,7 @@ const path = require('path'); const mainController = { root: (req, res) => { let pubKey = req.session.publicKey; + console.log(pubKey); let isLoggedIn = typeof pubKey !== 'undefined'; res.render('index', {isLoggedIn, pubKey}); }, diff --git a/src/socket.js b/src/socket.js index 0dcdf2f..3a08f59 100644 --- a/src/socket.js +++ b/src/socket.js @@ -3,7 +3,8 @@ import { io } from "socket.io-client"; const URL = "http://localhost:3333"; const socket = io(URL, { autoConnect: false, - transports: ['websocket', 'polling'] + transports: ['websocket', 'polling'], + withCredentials: true }); // log during dev diff --git a/src/views/index.pug b/src/views/index.pug index 87f5880..8d4fe14 100644 --- a/src/views/index.pug +++ b/src/views/index.pug @@ -45,6 +45,9 @@ html(lang="en-US") .btn-group.mr-2(role="group", aria-label="logout") a#logout.btn.btn-secondary(href="./account/logout") logout + + p#pubkey #{pubKey} + ul#messages form#form(action="") @@ -52,3 +55,4 @@ html(lang="en-US") button Send + diff --git a/tests/authentication.test.js b/tests/authentication.test.js index 1cf1cd7..892a8fc 100644 --- a/tests/authentication.test.js +++ b/tests/authentication.test.js @@ -29,9 +29,45 @@ describe('authentication module', () => { const result = await authentication.verifySignature(encodedData, signature, publicKeys); expect(result).toBe(pemKey); - let fakeKey = `-----BEGIN PUBLIC KEY-----MCowBQYDK2VwAyEAmrBLT6lyiFh/eUticsIFNY6AkjXuQPqj0Qvb99pCJJk=-----END PUBLIC KEY-----` + let fakeKey = `-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAmrBLT6lyiFh/eUticsIFNY6AkjXuQPqj0Qvb99pCJJk=\n-----END PUBLIC KEY-----` const result2 = await authentication.verifySignature(encodedData, signature, [fakeKey,]); expect(result2).toBe(null); }); + + it('encoding and decoding test', async () => { + const testkey = '-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEILXfcMirlUiI/o/r+8rK7ZIP0fyAMynxYzJXCI6BJHPk\n-----END PRIVATE KEY-----'; + const base64 = testkey.replace(`-----BEGIN PRIVATE KEY-----`, '').replace(`-----END PRIVATE KEY-----`, '').trim(); + + const derBuffer = Buffer.from(base64, 'base64'); + + let privkey = await crypto.subtle.importKey( + "pkcs8", + derBuffer, + { + name: "Ed25519", + }, + true, + ["sign"], + ); + const msg2 = '12f4b99e3784ac2e8b95427533a3dbc4'; + const encoder2 = new TextEncoder(); + const encodedData2 = encoder2.encode(msg2); + const signature2 = await crypto.subtle.sign( + { + name: "Ed25519", + }, + privkey, + encodedData2, + ); + const signatureBase64 = Buffer.from(signature2).toString('base64'); + + const sig = Buffer.from(signatureBase64, 'base64'); + + let pemKey2 = '-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEALrj4A3Vftz5TgWXEHi5KG+HD+uQLGB3bGc4TprDi9kE=\n-----END PUBLIC KEY-----' + const publicKeys2 = [pemKey2,]; + const result3 = await authentication.verifySignature(encodedData2, sig, publicKeys2); + expect(result3).toBe(pemKey2); + + }); }); });