UNPKG

@hazae41/kdbx

Version:

Rust-like KeePass (KDBX 4) file format for TypeScript

120 lines (119 loc) 3.8 kB
// deno-lint-ignore-file no-namespace export * from "./cipher/mod.js"; export * from "./markup/mod.js"; import { Vector } from "../../vector/mod.js"; import { Readable, Unknown, Writable } from "@hazae41/binary"; import { Cipher } from "./cipher/mod.js"; import { KeePassFile } from "./markup/mod.js"; export class HeadersAndContentWithBytes { headers; content; constructor(headers, content) { this.headers = headers; this.content = content; } sizeOrThrow() { return this.headers.sizeOrThrow() + this.content.sizeOrThrow(); } writeOrThrow(cursor) { this.headers.writeOrThrow(cursor); this.content.writeOrThrow(cursor); } } export class ContentWithBytes { bytes; value; constructor(bytes, value) { this.bytes = bytes; this.value = value; } static computeOrThrow(value) { return new ContentWithBytes(new Unknown(value.encodeOrThrow()), value); } sizeOrThrow() { return this.bytes.sizeOrThrow(); } writeOrThrow(cursor) { this.bytes.writeOrThrow(cursor); } } (function (ContentWithBytes) { function readOrThrow(cursor) { const bytes = new Unknown(cursor.readOrThrow(cursor.remaining)); const value = KeePassFile.decodeOrThrow(bytes.bytes); return new ContentWithBytes(bytes, value); } ContentWithBytes.readOrThrow = readOrThrow; })(ContentWithBytes || (ContentWithBytes = {})); (function (HeadersAndContentWithBytes) { function readOrThrow(cursor) { const headers = Headers.readOrThrow(cursor); const content = ContentWithBytes.readOrThrow(cursor); return new HeadersAndContentWithBytes(headers, content); } HeadersAndContentWithBytes.readOrThrow = readOrThrow; })(HeadersAndContentWithBytes || (HeadersAndContentWithBytes = {})); export class Headers { value; constructor(value) { this.value = value; } get cipher() { return this.value.value[1][0]; } get key() { return this.value.value[2][0]; } get binary() { return this.value.value[3]; } sizeOrThrow() { return this.value.sizeOrThrow(); } writeOrThrow(cursor) { this.value.writeOrThrow(cursor); } cloneOrThrow() { return Readable.readFromBytesOrThrow(Headers, Writable.writeToBytesOrThrow(this)); } rotateOrThrow() { const { cipher, binary } = this; const key = new Unknown(crypto.getRandomValues(new Uint8Array(32))); return Headers.initOrThrow({ cipher, key, binary }); } async getCipherOrThrow() { return await this.cipher.initOrThrow(this.key.bytes); } } (function (Headers) { function createOrThrow(cipher) { const binary = new Array(); const key = new Unknown(crypto.getRandomValues(new Uint8Array(32))); return Headers.initOrThrow({ cipher, key, binary }); } Headers.createOrThrow = createOrThrow; function initOrThrow(init) { const { cipher, key, binary } = init; const indexed = { 1: [cipher], 2: [key], 3: binary }; return new Headers(Vector.initOrThrow(indexed)); } Headers.initOrThrow = initOrThrow; function readOrThrow(cursor) { const vector = Vector.readOrThrow(cursor); if (vector.value[1].length !== 1) throw new Error(); if (vector.value[2].length !== 1) throw new Error(); const indexed = { 1: [vector.value[1][0].readIntoOrThrow(Cipher)], 2: [vector.value[2][0]], 3: vector.value[3] }; return new Headers(new Vector(vector.bytes, indexed)); } Headers.readOrThrow = readOrThrow; })(Headers || (Headers = {}));