UNPKG

ts-postgres

Version:
66 lines 2.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.sign = exports.hi = exports.sha256 = exports.hmacSha256 = exports.xorBuffers = void 0; const node_crypto_1 = require("node:crypto"); const node_buffer_1 = require("node:buffer"); function xorBuffers(a, b) { if (a.length !== b.length) { throw new Error('Buffer length mismatch'); } if (a.length === 0 || b.length === 0) { throw new Error('Buffers cannot be empty'); } return node_buffer_1.Buffer.from(a.map((_, i) => a[i] ^ b[i])); } exports.xorBuffers = xorBuffers; function hmacSha256(key, msg) { return (0, node_crypto_1.createHmac)('sha256', key).update(msg).digest(); } exports.hmacSha256 = hmacSha256; function sha256(key) { return (0, node_crypto_1.createHash)('sha256').update(key).digest(); } exports.sha256 = sha256; function hi(password, saltBytes, iterations) { let ui1 = hmacSha256(password, node_buffer_1.Buffer.concat([saltBytes, node_buffer_1.Buffer.from([0, 0, 0, 1])])); let ui = ui1; for (let i = 0; i < iterations - 1; i++) { ui1 = hmacSha256(password, ui1); ui = xorBuffers(ui, ui1); } return ui; } exports.hi = hi; function sign(data, password, clientNonce) { const m = Object.fromEntries(data.split(',').map((attr) => [attr[0], attr.substring(2)])); if (!(m.i && m.r && m.s)) throw new Error('SASL message parse error'); const nonce = m.r; if (!nonce.startsWith(clientNonce)) throw new Error('SASL nonce mismatch'); if (nonce.length === clientNonce.length) throw new Error('SASL nonce too short'); const iterations = parseInt(m.i, 10); const salt = node_buffer_1.Buffer.from(m.s, 'base64'); const saltedPassword = hi(password, salt, iterations); const clientKey = hmacSha256(saltedPassword, 'Client Key'); const storedKey = sha256(clientKey); const clientFinalMessageWithoutProof = 'c=biws,r=' + nonce; const clientFirstMessageBare = 'n=*,r=' + clientNonce; const serverFirstMessage = data; const authMessage = clientFirstMessageBare + ',' + serverFirstMessage + ',' + clientFinalMessageWithoutProof; const clientSignature = hmacSha256(storedKey, authMessage); const clientProofBytes = xorBuffers(clientKey, clientSignature); const clientProof = clientProofBytes.toString('base64'); const serverKey = hmacSha256(saltedPassword, 'Server Key'); const serverSignatureBytes = hmacSha256(serverKey, authMessage); const response = clientFinalMessageWithoutProof + ',p=' + clientProof; const serverSignature = serverSignatureBytes.toString('base64'); return [response, serverSignature]; } exports.sign = sign; //# sourceMappingURL=sasl.js.map