218 lines
7.1 KiB
JavaScript
218 lines
7.1 KiB
JavaScript
/*
|
|
* Copyright 2021 Netsyms Technologies.
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
var keymgr;
|
|
|
|
/**
|
|
* Load and unlock the private key in localstorage, prompting user as needed. If there is no key, generates, saves, and loads a new one.
|
|
* @param {function} callback Passed two arguments: message for user, and boolean true if OK false if error.
|
|
* @returns {undefined}
|
|
*/
|
|
function loadKeyFromLocalStorage(callback) {
|
|
if (typeof keymgr != "undefined") {
|
|
callback("Key already loaded.", true);
|
|
return;
|
|
}
|
|
if (!inStorage("signingkey") || getStorage("signingkey") == "undefined") {
|
|
var pass = prompt("Generating a new signing key (might take a while, be patient). Enter a password to protect it. You'll need to save this password somewhere safe; it cannot be recovered.");
|
|
generatePrivateKey(getStorage("notary_name") + " <null@null.com>", pass, function (key) {
|
|
if (typeof key == "undefined") {
|
|
callback("Could not generate key.", false);
|
|
return;
|
|
}
|
|
keymgr = key;
|
|
setStorage("signingkey", keymgr.armored_pgp_private);
|
|
callback("Signing key generated.", true);
|
|
});
|
|
} else {
|
|
var pass = prompt("Enter password to unlock signing key:");
|
|
loadPrivateKey(getStorage("signingkey"), pass, function (key) {
|
|
if (typeof key == "undefined") {
|
|
callback("Could not unlock key. Password is probably incorrect.", false);
|
|
return;
|
|
}
|
|
keymgr = key;
|
|
callback("Signing key unlocked.", true);
|
|
});
|
|
}
|
|
}
|
|
|
|
function loadKeyFromLocalStorageWithUserFeedback() {
|
|
loadKeyFromLocalStorage(function (msg, ok) {
|
|
if (ok) {
|
|
alert(msg);
|
|
} else {
|
|
alert("Error: " + msg);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Load a private key.
|
|
* @param {string} armoredkey PGP private key
|
|
* @param {string} pass key password
|
|
* @param {function} callback Passed a new keymanager for the key.
|
|
* @returns {undefined}
|
|
*/
|
|
function loadPrivateKey(armoredkey, pass, callback) {
|
|
kbpgp.KeyManager.import_from_armored_pgp({
|
|
armored: armoredkey
|
|
}, function (err, key) {
|
|
if (!err) {
|
|
if (key.is_pgp_locked()) {
|
|
key.unlock_pgp({
|
|
passphrase: pass
|
|
}, function (err) {
|
|
if (!err) {
|
|
console.log("Loaded private key with passphrase");
|
|
callback(key);
|
|
} else {
|
|
console.error(err);
|
|
callback(undefined);
|
|
}
|
|
});
|
|
} else {
|
|
console.log("Loaded private key w/o passphrase");
|
|
callback(key);
|
|
}
|
|
} else {
|
|
console.error(err);
|
|
callback(undefined);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Sign a message with a key and return the signed message in the callback.
|
|
* @param {type} text
|
|
* @param {type} key
|
|
* @param {type} callback
|
|
* @returns {undefined}
|
|
*/
|
|
function signMessage(text, key, callback) {
|
|
var params = {
|
|
msg: text,
|
|
sign_with: key
|
|
};
|
|
kbpgp.box(params, function (err, result_string, result_buffer) {
|
|
//console.log(err, result_string, result_buffer);
|
|
callback(result_string);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Generate a new private key.
|
|
* @param {string} userid Something like "Test User <test@netsyms.com>"
|
|
* @param {string} passphrase protects the key
|
|
* @param {function} callback Passed the keymanager for the new key
|
|
* @returns {undefined}
|
|
*/
|
|
function generatePrivateKey(userid, passphrase, callback) {
|
|
var F = kbpgp["const"].openpgp;
|
|
|
|
var opts = {
|
|
userid: userid,
|
|
primary: {
|
|
nbits: 2048,
|
|
flags: F.certify_keys | F.sign_data | F.auth | F.encrypt_comm | F.encrypt_storage,
|
|
expire_in: 0 // never expire
|
|
},
|
|
subkeys: []
|
|
};
|
|
|
|
kbpgp.KeyManager.generate(opts, function (err, alice) {
|
|
if (!err) {
|
|
alice.sign({}, function (err) {
|
|
alice.export_pgp_private({
|
|
passphrase: passphrase
|
|
}, function (err, pgp_private) {
|
|
callback(alice);
|
|
});
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function exportPublicKey() {
|
|
loadKeyFromLocalStorage(function (message, ok) {
|
|
if (ok) {
|
|
openSaveFileDialog(function (path) {
|
|
keymgr.export_pgp_public({}, function (err, pgp_public) {
|
|
if (err) {
|
|
alert("Something went wrong.");
|
|
} else {
|
|
writeToFile(path, pgp_public);
|
|
}
|
|
});
|
|
}, "public-key.asc", ".asc");
|
|
} else {
|
|
alert("Error: " + message);
|
|
}
|
|
});
|
|
}
|
|
|
|
function exportPrivateKey() {
|
|
var pass = prompt("Enter password for private key:");
|
|
const savepriv = function (key) {
|
|
var pass2 = prompt("Enter a password to protect the key backup:");
|
|
openSaveFileDialog(function (path) {
|
|
key.export_pgp_private({
|
|
passphrase: pass2
|
|
}, function (err, pgp_private) {
|
|
if (err) {
|
|
alert("Something went wrong.");
|
|
} else {
|
|
writeToFile(path, pgp_private);
|
|
}
|
|
});
|
|
}, "private-key.asc", ".asc");
|
|
}
|
|
kbpgp.KeyManager.import_from_armored_pgp({
|
|
armored: getStorage("signingkey")
|
|
}, function (err, key) {
|
|
if (!err) {
|
|
if (key.is_pgp_locked()) {
|
|
key.unlock_pgp({
|
|
passphrase: pass
|
|
}, function (err) {
|
|
if (!err) {
|
|
savepriv(key);
|
|
} else {
|
|
alert("Could not unlock key. Password is probably incorrect.");
|
|
}
|
|
});
|
|
} else {
|
|
console.log("Loaded private key w/o passphrase");
|
|
savepriv(key);
|
|
}
|
|
} else {
|
|
alert("Could not unlock key: " + err);
|
|
}
|
|
});
|
|
}
|
|
|
|
function importPrivateKey() {
|
|
if (inStorage("signingkey") && getStorage("signingkey") != "undefined") {
|
|
if (!confirm("The restored key will replace the current key, which will be unrecoverable unless you made a backup. Continue?")) {
|
|
return;
|
|
}
|
|
}
|
|
keymgr = null;
|
|
openFileDialog(function (path) {
|
|
var keyfile = getFileAsString(path);
|
|
var pass = prompt("Enter password for imported key (password was set when exported):");
|
|
loadPrivateKey(keyfile, pass, function (key) {
|
|
if (typeof key == "undefined") {
|
|
alert("Could not import key. Password is probably incorrect.");
|
|
return;
|
|
}
|
|
keymgr = key;
|
|
setStorage("signingkey", keymgr.armored_pgp_private);
|
|
alert("Private key imported.");
|
|
});
|
|
}, ".asc");
|
|
} |