Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
phoqe committed Jun 6, 2021
2 parents 0d127fd + 37c07c1 commit d49f535
Show file tree
Hide file tree
Showing 14 changed files with 370 additions and 318 deletions.
2 changes: 1 addition & 1 deletion browsers/brave.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ exports.keychain = {
account: "Brave",
};

exports.getUserDataDirectoryPath = () => {
exports.userDataDirectoryPath = () => {
let userDataDirectoryPath;

if (process.platform === "win32") {
Expand Down
2 changes: 1 addition & 1 deletion browsers/chrome-beta.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ exports.keychain = {
account: "Chrome",
};

exports.getUserDataDirectoryPath = () => {
exports.userDataDirectoryPath = () => {
let userDataDirectoryPath;

if (process.platform === "linux") {
Expand Down
2 changes: 1 addition & 1 deletion browsers/chrome-canary.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ exports.keychain = {
account: "Chrome",
};

exports.getUserDataDirectoryPath = () => {
exports.userDataDirectoryPath = () => {
let userDataDirectoryPath;

if (process.platform === "win32") {
Expand Down
2 changes: 1 addition & 1 deletion browsers/chrome-dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ exports.keychain = {
account: "Chrome",
};

exports.getUserDataDirectoryPath = () => {
exports.userDataDirectoryPath = () => {
let userDataDirectoryPath;

if (process.platform === "linux") {
Expand Down
2 changes: 1 addition & 1 deletion browsers/chrome.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ exports.keychain = {
account: "Chrome",
};

exports.getUserDataDirectoryPath = () => {
exports.userDataDirectoryPath = () => {
let userDataDirectoryPath;

if (process.platform === "win32") {
Expand Down
2 changes: 1 addition & 1 deletion browsers/chromium.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ exports.keychain = {
account: "Chromium",
};

exports.getUserDataDirectoryPath = () => {
exports.userDataDirectoryPath = () => {
let userDataDirectoryPath;

if (process.platform === "win32") {
Expand Down
109 changes: 101 additions & 8 deletions cli/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const writeToFile = (fileName, data) => {
* Supply `type` to use typical data points.
*
* @param {string} type Type of data, e.g., `logins` or `urls`.
* @param {Array} data Data to structure in a table. Must be an `Array`.
* @param {object[]} data Data to structure in a table.
*/
const tabular = (type, data) => {
switch (type) {
Expand All @@ -88,23 +88,116 @@ const tabular = (type, data) => {
}
};

/**
* Return the encrypted field for a type of data, e.g., for `logins` it's `password_value`.
*
* @param {string} type
* @returns {string}
*/
const encryptedFieldForType = (type) => {
switch (type) {
case "logins":
return "password_value";
case "cookies":
return "encrypted_value";
default:
return null;
}
};

/**
* Decrypt specified `rows` and return them in the same format but with the decrypted value.
*
* @param {object[]} rows Rows to decrypt. Must adhere to correct fields.
* @param {object} browser Browser to decrypt from.
* @param {string} type Type of data to decrypt.
* @returns {Promise<object[]>}
*/
const decrypt = (rows, browser, type) => {
return new Promise((resolve, reject) => {
if (!rows) {
reject(new TypeError("No rows."));

return;
}

const decs = [];

rows.forEach((row) => {
const encField = encryptedFieldForType(type);

decs.push(
havelock.crypto.decrypt(browser, row[encField]).then((plaintext) => {
return {
...row,
[encField]: plaintext,
};
})
);
});

Promise.all(decs)
.then((decRows) => {
resolve(decRows);
})
.catch((reason) => {
reject(reason);
});
});
};

/**
* Print `data` in multiple formats.
* Format is deduced from `opts`.
*
* @param {string} type Type of data to print. Used to determine interesting data points.
* @param {Array} data Data to print. Must be an `Array`.
* @param {commander.OptionValues} opts Program options used to determine format type.
* @param {object} browser
* @returns
*/
const printData = (type, data, opts) => {
const printData = (type, data, opts, browser) => {
return new Promise((resolve, reject) => {
if (!data.length) {
reject();

return;
}

if (opts.decrypt) {
decrypt(data, browser, type)
.then((rows) => {
if (opts.tabular) {
tabular(type, rows);

resolve();

return;
}

if (opts.file) {
writeToFile(type, rows)
.then((filePath) => {
resolve(filePath);
})
.catch((reason) => {
reject(reason);
});

return;
}

console.info(rows);

resolve();
})
.catch((reason) => {
reject(reason);
});

return;
}

if (opts.tabular) {
tabular(type, data);

Expand Down Expand Up @@ -145,9 +238,9 @@ exports.logins = (browser, profile = "Default") => {
}

explorer
.getLoginsFromLoginDataFile(browser, profile)
.loginsFromLoginDataFile(browser, profile)
.then((logins) => {
printData("logins", logins, opts)
printData("logins", logins, opts, browser)
.then((filePath) => {
if (filePath) {
success(filePath);
Expand Down Expand Up @@ -186,9 +279,9 @@ exports.cookies = (browser, profile = "Default") => {
}

explorer
.getCookiesFromCookiesFile(browser, profile)
.cookiesFromCookiesFile(browser, profile)
.then((cookies) => {
printData("cookies", cookies, opts)
printData("cookies", cookies, opts, browser)
.then((filePath) => {
if (filePath) {
success(filePath);
Expand Down Expand Up @@ -227,9 +320,9 @@ exports.urls = (browser, profile = "Default") => {
}

explorer
.getUrlsFromHistoryFile(browser, profile)
.urlsFromHistoryFile(browser, profile)
.then((urls) => {
printData("urls", urls, opts)
printData("urls", urls, opts, browser)
.then((filePath) => {
if (filePath) {
success(filePath);
Expand Down
1 change: 1 addition & 0 deletions cli/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ program.description(package.description);

program.option("-t, --tabular", "present data of interest in a table", false);
program.option("-f, --file", "write requested data to file", false);
program.option("-d, --decrypt", "decrypt fields known to be encrypted", false);

/**
* Actions
Expand Down
74 changes: 74 additions & 0 deletions crypto/win32.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Core modules
const crypto = require("crypto");

// Third-party modules
const hkdf = require("futoin-hkdf");

// Password Versions
const PASSWORD_V10 = "v10";

// Encryption Key
const KEY_SECRET = "peanuts";
const KEY_LEN = 256 / 8; // 32 bytes
const KEY_SALT = "salt";
const KEY_INFO = "info";
const KEY_HASH = "sha-256";

const NONCE_LEN = 96 / 8; // 12 bytes
const DEC_ALGO = "aes-256-gcm";

/**
*
* @returns {Buffer}
*/
const createEncryptionKey = () => {
return hkdf(KEY_SECRET, KEY_LEN, {
salt: KEY_SALT,
info: KEY_INFO,
hash: KEY_HASH,
});
};

/**
*
* @param {string} ciphertext
* @returns {string}
*/
const decryptWithDpApi = (ciphertext) => {};

/**
*
* @param {object} browser
* @param {Buffer} data
* @returns {Promise<string>}
*/
exports.decrypt = (browser, data) => {
return new Promise((resolve, reject) => {
if (!browser) {
reject(new TypeError("No browser."));

return;
}

if (!data) {
reject(new TypeError("No data."));

return;
}

const ciphertext = data.toString();

if (ciphertext.startsWith(PASSWORD_V10)) {
// TODO: Unprotect data.

return;
}

const key = createEncryptionKey();
const nonce = ciphertext.substring(PASSWORD_V10.length - 1, NONCE_LEN);
const rawCiphertext = ciphertext.substring(
NONCE_LEN + PASSWORD_V10.length - 1
);
const decipher = crypto.createDecipheriv(DEC_ALGO, key, iv);
});
};
Loading

0 comments on commit d49f535

Please sign in to comment.