interface Header { name: string; offset: number; length: number; derived?: boolean } export const Constants = { crypto: { RAW_KEY_LENGTH: 32, SIGN_PRIVATE_KEY_HEADER: Buffer.from("302e020100300506032b657004220420", "hex"), ENCRYPT_PRIVATE_KEY_HEADER: Buffer.from("302e020100300506032b656e04220420", "hex"), PRIVATE_KEY_LENGTH: 48, SIGN_PUBLIC_KEY_HEADER: Buffer.from("302a300506032b6570032100", "hex"), ENCRYPT_PUBLIC_KEY_HEADER: Buffer.from("302a300506032b656e032100", "hex"), PUBLIC_KEY_LENGTH: 44, SIGNATURE_LENGTH: 64 }, fields: { PAYLOAD_LENGTH_OFFSET: -1, // filled in below TOTAL_HEADERS_LENGTH: -1, PAYLOAD_MAX_LENGTH: -1, // 64KB - headers headers: [ { name: "MAGIC", offset: 0, length: 2 }, { name: "PROTOCOL_VERSION", offset: 2, length: 1 }, { name: "SIGNATURE_VERSION", offset: 3, length: 1 }, { name: "TIMESTAMP", offset: 4, length: 4, "derived": true }, { name: "MESSAGE_ID", offset: 8, length: 4 }, { name: "PAYLOAD_TYPE", offset: 12, length: 1 }, { name: "RESERVED", offset: 13, length: 1 }, { name: "PAYLOAD_SIZE", offset: 14, length: 2, "derived": true } ], PAYLOAD_OFFSET: 16 } }; Constants.fields.PAYLOAD_LENGTH_OFFSET = Constants.fields.headers.find(header => header.name === "PAYLOAD_SIZE")?.offset; Constants.fields.TOTAL_HEADERS_LENGTH = Constants.fields.headers.reduce((prev: number, curr: Header) => prev + curr.length, 0); Constants.fields.PAYLOAD_MAX_LENGTH = (1024 * 64) - Constants.fields.TOTAL_HEADERS_LENGTH; /** * Convert DER key Buffer to PEM string. FIXME: break out the validity checks. * @param DERKey key in DER-form * @returns key in PEM form */ export const DERToPEM = (DERKey: Buffer) => { const wrap = (buf: Buffer, type: "PUBLIC" | "PRIVATE") => Buffer.from(`-----BEGIN ${type} KEY----- ${buf.toString("base64")} -----END ${type} KEY----- `); if (DERKey.byteLength == Constants.crypto.PRIVATE_KEY_LENGTH) { const header = DERKey.subarray(0, Constants.crypto.PRIVATE_KEY_LENGTH - Constants.crypto.RAW_KEY_LENGTH); if (header.equals(Constants.crypto.ENCRYPT_PRIVATE_KEY_HEADER) || header.equals(Constants.crypto.SIGN_PRIVATE_KEY_HEADER)) { return wrap(DERKey, "PRIVATE"); } } else if (DERKey.byteLength == Constants.crypto.PUBLIC_KEY_LENGTH) { const header = DERKey.subarray(0, Constants.crypto.PUBLIC_KEY_LENGTH - Constants.crypto.RAW_KEY_LENGTH); if (header.equals(Constants.crypto.ENCRYPT_PUBLIC_KEY_HEADER) || header.equals(Constants.crypto.SIGN_PUBLIC_KEY_HEADER)) { return wrap(DERKey, "PUBLIC"); } } throw new Error("Unrecognized key type"); };