s-bit-agent
Version:
s.BitAgent is a simple Bitwarden CLI wrapper which provides a SSH2 Key Agent solution for Bitwarden.
72 lines • 3.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SshAgentcSignRequest = void 0;
const handler_1 = require("../../types/handler");
const node_ipc_1 = require("node-ipc");
const SshPK = require("sshpk");
class SshAgentcSignRequest {
constructor() {
this.messageType = handler_1.IcpMessageType.SSH_AGENTC_SIGN_REQUEST;
}
async handle(message, prefix, agentService, client) {
agentService.logService.info(prefix + 'Received', 'SSH_AGENTC_SIGN_REQUEST');
const keyBlobLength = message.readUInt32BE(5);
const keyBlob = message.subarray(9, 9 + keyBlobLength);
const dataLength = message.readUInt32BE(9 + keyBlobLength);
const dataBuffer = message.subarray(13 + keyBlobLength, 13 + keyBlobLength + dataLength);
const flags = message.readUInt32BE(13 + keyBlobLength + dataLength);
const token = await agentService.sessionService.getSession(null);
if (!token)
throw new Error('Session not approved');
const items = await agentService.cacheService.getCacheWithToken(token);
agentService.keyCacheService.setCache(items.map((item) => {
const raw = item.fields.find((field) => field.name === 'public-key');
if (!raw ||
!item.fields.find((field) => field.name === 'private-key')) {
agentService.logService.error('Item', item.name, '@', item.id, 'has no public and/or private key');
return null;
}
const pub = SshPK.parseKey(raw.value, 'auto');
return { item, pub };
})
.filter((x) => x !== null)
.map((x) => ({
key: x.pub.toString('ssh'),
comment: x.item.name,
})));
const item = items.find((item) => {
const raw = item.fields.find((field) => field.name === 'public-key');
if (!raw)
return false;
const pub = SshPK.parseKey(raw.value, 'auto');
return pub.toBuffer('rfc4253').equals(keyBlob);
});
if (!item)
throw new Error('Key not found');
const approval = await agentService.guiService.getInput(`SSH Agent: Sign request for "${item.name}", approve?`, 'confirm');
if (approval !== 'true')
throw new Error('Request denied');
const priv = item.fields.find((field) => field.name === 'private-key');
if (!priv)
throw new Error('Private key not found');
const key = SshPK.parsePrivateKey(priv.value, 'auto');
const signature = key
.createSign(flags === 4 ? 'sha512' : flags === 2 ? 'sha256' : 'sha1')
.update(dataBuffer)
.sign();
const signatureBuffer = signature.toBuffer([4, 2].includes(flags) ? 'ssh' : 'raw');
const signatureSize = Buffer.alloc(4);
signatureSize.writeUInt32BE(signatureBuffer.length, 0);
const size = Buffer.alloc(4);
size.writeUInt32BE(signatureBuffer.length + 5, 0);
agentService.logService.info(prefix + 'Sending', 'SSH_AGENT_SIGN_RESPONSE');
node_ipc_1.default.server.emit(client, Buffer.concat([
size,
Buffer.from([handler_1.IcpMessageType.SSH_AGENT_SIGN_RESPONSE]),
signatureSize,
signatureBuffer,
]));
}
}
exports.SshAgentcSignRequest = SshAgentcSignRequest;
//# sourceMappingURL=SshAgentcSignRequest.js.map