Compare commits

..

No commits in common. "7e6b8a0eba82c68e33d2c4a3f2d3dcbf7b213b51" and "d271b59da4c53ed104c8b4f923064c185929b79f" have entirely different histories.

2 changed files with 30 additions and 129 deletions

View File

@ -55,25 +55,11 @@ let encIV = encForm.createMediumTextBox({
label: "IV",
dataType: "b64",
advanced: true,
enabledFunc: function() {return encManualIV.value},
visibleFunc: function() {return ["AES-GCM", "AES-CBC"].includes(encMode.value)}
enabledFunc: function() {return encManualIV.value}
});
let encManualIV = encForm.createCheckBox({
label: "Use fixed IV instead of random",
advanced: true,
visibleFunc: function() {return ["AES-GCM", "AES-CBC"].includes(encMode.value)}
});
let encCounter = encForm.createMediumTextBox({
label: "Counter",
dataType: "b64",
advanced: true,
enabledFunc: function() {return encManualCounter.value},
visibleFunc: function() {return encMode.value === "AES-CTR"}
});
let encManualCounter = encForm.createCheckBox({
label: "Use fixed counter instead of random",
advanced: true,
visibleFunc: function() {return encMode.value === "AES-CTR"}
advanced: true
});
let encMode = encForm.createDropDown({
label: "AES mode",
@ -87,10 +73,6 @@ let encMode = encForm.createDropDown({
name: "AES-CBC (Cipher Block Chaining)",
value: "AES-CBC"
},
{
name: "AES-CTR (Counter)",
value: "AES-CTR"
},
]
});
let encButton = encForm.createButton({label: "Encrypt"});
@ -177,17 +159,6 @@ async function aesCbcEnc(key, iv, msgEncoded) {
msgEncoded
);
}
async function aesCtrEnc(key, counter, msgEncoded) {
return window.crypto.subtle.encrypt(
{
"name": "AES-CTR",
"counter": counter,
"length": 64
},
key,
msgEncoded
);
}
encButton.handle.addEventListener("click", async function() {
let keyMaterial = await getKeyMaterial(encPass.value);
@ -221,23 +192,11 @@ encButton.handle.addEventListener("click", async function() {
}
let iv;
if (["AES-GCM", "AES-CBC"].includes(encMode.value)) {
if (encManualIV.value) {
iv = encIV.value;
} else {
iv = window.crypto.getRandomValues(new Uint8Array(16));
encIV.value = iv;
}
}
let counter;
if (encMode.value === "AES-CTR") {
if (encManualCounter.value) {
counter = encCounter.value;
} else {
counter = window.crypto.getRandomValues(new Uint8Array(16));
encCounter.value = counter;
}
if (encManualIV.value) {
iv = encIV.value;
} else {
iv = window.crypto.getRandomValues(new Uint8Array(16));
encIV.value = iv;
}
let enc = new TextEncoder();
@ -251,9 +210,6 @@ encButton.handle.addEventListener("click", async function() {
case "AES-CBC":
ciphertext = await aesCbcEnc(key, iv, msgEncoded);
break;
case "AES-CTR":
ciphertext = await aesCtrEnc(key, counter, msgEncoded);
break;
default:
let e = Error(`Mode '${encMode.value}' is not implemented.`);
encMode.handleError(e);
@ -266,7 +222,6 @@ encButton.handle.addEventListener("click", async function() {
"ciphertext": bufToB64(ciphertext),
"salt": bufToB64(salt),
"iv": bufToB64(iv),
"counter": bufToB64(counter),
"encMode": encMode.value,
"pbkdf2Iters": pbkdf2Iters,
}
@ -292,26 +247,14 @@ async function aesCbcDec(key, iv, ciphertext) {
ciphertext
);
}
async function aesCtrDec(key, counter, ciphertext) {
return window.crypto.subtle.decrypt(
{
"name": "AES-CTR",
"counter": counter,
"length": 64
},
key,
ciphertext
);
}
decButton.handle.addEventListener("click", async function() {
let msgEncoded = decMsg.value;
let ciphertext, iv, counter, salt, encMode, pbkdf2Iters;
let ciphertext, iv, salt, encMode, pbkdf2Iters;
try {
ciphertext = new b64ToBuf(msgEncoded.ciphertext);
iv = new Uint8Array(b64ToBuf(msgEncoded.iv));
counter = new Uint8Array(b64ToBuf(msgEncoded.counter));
salt = new Uint8Array(b64ToBuf(msgEncoded.salt));
encMode = msgEncoded.encMode;
pbkdf2Iters = msgEncoded.pbkdf2Iters;
@ -360,9 +303,6 @@ decButton.handle.addEventListener("click", async function() {
case "AES-CBC":
plaintext = await aesCbcDec(key, iv, ciphertext);
break;
case "AES-CTR":
plaintext = await aesCtrDec(key, counter, ciphertext);
break;
default:
throw Error(`Mode '${encMode.value}' is not implemented.`);
}

View File

@ -15,7 +15,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
class InterfaceElement {
rootNodes = [];
constructor({fragment, enabledFunc, visibleFunc}) {
constructor({fragment, enabledFunc}) {
if (fragment === undefined) {
this.fragment = new DocumentFragment();
} else {
@ -27,16 +27,6 @@ class InterfaceElement {
} else {
this.enabledFunc = enabledFunc;
}
if (visibleFunc === undefined) {
this.visibleFunc = function(){ return true; };
} else {
this.visibleFunc = visibleFunc;
}
}
update() {
this.enabled = this.enabledFunc();
this.hidden = !this.visibleFunc();
}
scanNodes() {
@ -138,7 +128,11 @@ class Form extends InterfaceElement {
this.#advanced = x;
for (const element of this.elements) {
if (element.advanced === true) {
element.update();
if (this.advanced === true) {
element.hidden = false;
} else {
element.hidden = true;
}
}
}
}
@ -149,9 +143,7 @@ class Form extends InterfaceElement {
}
}
createElem(params) {
params.form = this;
let elem = new FormElement(params);
appendElement(elem) {
elem.mount(this.handle);
this.elements.push(elem);
this.rootNodes.push(...elem.rootNodes);
@ -168,27 +160,27 @@ class Form extends InterfaceElement {
let labelTag = document.createTextNode(params.label);
params.tag.appendChild(labelTag);
params.label = undefined;
return this.createElem(params);
return this.appendElement(new FormElement(params));
}
createTextBox(params) {
params.tag = document.createElement("input");
dataTypeSupports(params, ["plaintext", "b64", "json-b64"]);
return this.createElem(params);
return this.appendElement(new FormElement(params));
}
createMediumTextBox(params) {
params.tag = document.createElement("textarea");
params.tag.classList.add("mediumbox")
dataTypeSupports(params, ["plaintext", "b64", "json-b64"]);
return this.createElem(params);
return this.appendElement(new FormElement(params));
}
createPasswordInput(params) {
params.tag = document.createElement("input");
params.tag.setAttribute("type", "password");
dataTypeSupports(params, ["plaintext"]);
return this.createElem(params);
return this.appendElement(new FormElement(params));
}
createNumberInput(params) {
@ -199,7 +191,7 @@ class Form extends InterfaceElement {
if (params.minValue !== undefined) params.tag.min = params.minValue;
if (params.step !== undefined) params.tag.step = params.step;
if (params.required !== undefined) params.tag.required = params.required;
return this.createElem(params);
return this.appendElement(new FormElement(params));
}
createDropDown(params) {
@ -229,18 +221,13 @@ class Form extends InterfaceElement {
optTag.appendChild(document.createTextNode(option.name));
params.tag.appendChild(optTag);
}
params.tag.addEventListener("change", function() {
for (const elem of this.elements) {
elem.update();
}
}.bind(this));
return this.createElem(params);
return this.appendElement(new FormElement(params));
}
createTextArea(params) {
params.tag = document.createElement("textarea");
dataTypeSupports(params, ["plaintext", "b64", "json-b64"]);
return this.createElem(params);
return this.appendElement(new FormElement(params));
}
createButton(params) {
@ -250,7 +237,7 @@ class Form extends InterfaceElement {
params.tag.appendChild(params.labelTag);
params.fragment.appendChild(params.tag);
dataTypeSupports(params, ["none"]);
return this.createElem(params);
return this.appendElement(new FormElement(params));
}
createCheckBox(params) {
@ -267,17 +254,17 @@ class Form extends InterfaceElement {
dataTypeSupports(params, ["bool"]);
params.tag.addEventListener("change", function() {
for (const elem of this.elements) {
elem.update();
elem.enabled = elem.enabledFunc();
}
}.bind(this));
return this.createElem(params);
return this.appendElement(new FormElement(params));
}
createOutput(params) {
params.tag = document.createElement("textarea");
params.tag.setAttribute("readonly", true);
dataTypeSupports(params, ["plaintext", "b64", "json-b64"]);
return this.createElem(params);
return this.appendElement(new FormElement(params));
}
}
@ -301,36 +288,8 @@ function bufToB64 (buf) {
}
class FormElement extends InterfaceElement {
constructor({tag, fragment, advanced=false, form,
value, dataType,
labelTag, label="",
enabled=true, enabledFunc,
visibleFunc
}) {
let oriVisibleFunc = visibleFunc;
super({
fragment,
enabledFunc,
visibleFunc: function() {
let res;
if (oriVisibleFunc) {
res = oriVisibleFunc()
} else {
res = true;
}
if (form !== undefined) {
if (advanced) {
if (form.advanced) return res;
else return false;
}
}
return res;
}
});
this.form = form;
constructor({tag, labelTag, label="", value, fragment, dataType, advanced=false, enabled=true, enabledFunc}) {
super({fragment, enabled, enabledFunc});
this.labelText = label;
if (labelTag === undefined) {
@ -348,6 +307,8 @@ class FormElement extends InterfaceElement {
this.dataType = dataType;
this.advanced = advanced;
if (this.advanced === true) this.hidden = true;
if (value !== undefined) this.value = value;
}