From e2077a89cf743416755ef970ccce73a7dc306b10 Mon Sep 17 00:00:00 2001 From: pehmo1 Date: Mon, 16 Aug 2021 19:20:29 +0300 Subject: [PATCH] Make util.js functions generic Also moved crypto to window.cryptoEngine for easy access in util.js --- static/js/certidude.js | 35 +++++++++----------- static/js/util.js | 73 +++++++++++++++++++++--------------------- 2 files changed, 51 insertions(+), 57 deletions(-) diff --git a/static/js/certidude.js b/static/js/certidude.js index bbd224e..5c76ba5 100644 --- a/static/js/certidude.js +++ b/static/js/certidude.js @@ -12,20 +12,18 @@ import { } from "../node_modules/pkijs/src/common.js"; import CertificationRequest from "../node_modules/pkijs/src/CertificationRequest.js"; import AttributeTypeAndValue from "../node_modules/pkijs/src/AttributeTypeAndValue.js"; -import { formatPEM } from "./formatPEM.js"; import { pkcs12chain } from "./pkcs12chain.js"; -import { - privKeyToBase64, - privKeyToPem, - certReqToPem +import { + pkijsToPem, + pkijsToBase64, } from "./util.js" const DEVICE_KEYWORDS = ["Android", "iPhone", "iPad", "Windows", "Ubuntu", "Fedora", "Mac", "Linux"]; jQuery.timeago.settings.allowFuture = true; -const crypto = getCrypto(); -if (typeof crypto === "undefined") +window.cryptoEngine = getCrypto(); +if (typeof window.cryptoEngine === "undefined") console.error("No WebCrypto extension found"); function onLaunchShell(common_name) { @@ -113,7 +111,7 @@ function onKeyGen() { if ("hash" in algorithm.algorithm) algorithm.algorithm.hash.name = window.authority.hash_alg; - const keyPair = await crypto.generateKey( + const keyPair = await window.cryptoEngine.generateKey( algorithm.algorithm, true, algorithm.usages); window.keys = keyPair; const publicKey = keyPair.publicKey; @@ -157,7 +155,10 @@ function onKeyGen() { function blobToUuid(blob) { return new Promise((resolve, reject) => { - crypto.digest({ name: "SHA-1" }, stringToArrayBuffer(blob)).then((res) => { + window.cryptoEngine.digest( + { name: "SHA-1" }, + stringToArrayBuffer(blob)) + .then((res) => { res = bufferToHexCodes(res).toLowerCase(); res = res.substring(0, 8) + @@ -195,7 +196,7 @@ function onEnroll(encoding) { /(-----(BEGIN|END) CERTIFICATE-----|\n)/g, ""); // Private key to base64 (for pkcs12chain) - let privKeyBase64 = await privKeyToBase64(keys.privateKey, crypto); + let privKeyBase64 = await pkijsToBase64(keys.privateKey); switch(encoding) { case 'p12': @@ -231,7 +232,7 @@ function onEnroll(encoding) { a.download = query.title + ".sswan"; break case 'ovpn': - let privKeyPem = await privKeyToPem(keys.privateKey, crypto); + let privKeyPem = await pkijsToPem(keys.privateKey); var buf = nunjucks.render('snippets/openvpn-client.conf', { authority: authority, @@ -281,9 +282,7 @@ function onEnroll(encoding) { } } }; - let resultString = await certReqToPem(window.csr); - - xhr2.send(resultString); + xhr2.send(await pkijsToPem(window.csr)); } } xhr.send(); @@ -769,7 +768,7 @@ function loadAuthority(query) { $("#enroll").click(async function() { - var keys = await crypto.generateKey( + var keys = await window.cryptoEngine.generateKey( { name: "RSASSA-PKCS1-v1_5", modulusLength: 1024, @@ -795,11 +794,7 @@ function loadAuthority(query) { - var pkcs8 = await crypto.exportKey("pkcs8", keys.privateKey); - var pem = formatPEM( - toBase64(String.fromCharCode.apply(null, new Uint8Array(pkcs8))) - ); - privateKeyBuffer = `-----BEGIN RSA PRIVATE KEY-----\r\n${pem}\r\n-----END RSA PRIVATE KEY-----\r\n`; + var privateKeyBuffer = pkijsToPem(keys.privateKey); }); /** diff --git a/static/js/util.js b/static/js/util.js index 87c0b9f..cf6afb8 100644 --- a/static/js/util.js +++ b/static/js/util.js @@ -1,51 +1,50 @@ -import * as asn1js from "asn1js"; import { arrayBufferToString, - stringToArrayBuffer, toBase64, - fromBase64, - bufferToHexCodes } from "pvutils"; -import { - getCrypto, - getAlgorithmParameters, -} from "../node_modules/pkijs/src/common.js"; -import CertificationRequest from "../node_modules/pkijs/src/CertificationRequest.js"; -import AttributeTypeAndValue from "../node_modules/pkijs/src/AttributeTypeAndValue.js"; -import Certificate from "../node_modules/pkijs/src/Certificate.js"; import { formatPEM } from "./formatPEM.js"; -export async function privKeyToBase64(privKey, crypto) { +export function pkijsToBase64(pkijsObj) { return new Promise(async (resolve, reject) => { - let arrayBuf = new ArrayBuffer(0); - arrayBuf = await crypto.exportKey("pkcs8", privKey); - - resolve(formatPEM(toBase64(arrayBufferToString(arrayBuf)))); + switch(pkijsObj.__proto__.constructor.name) { + case "CryptoKey": + let arrayBuf = new ArrayBuffer(0); + + if (pkijsObj.type == "private") + arrayBuf = await window.cryptoEngine.exportKey("pkcs8", pkijsObj); + else + arrayBuf = await window.cryptoEngine.exportKey("spki", pkijsObj); + + resolve(toBase64(arrayBufferToString(arrayBuf))); + break; + + case "CertificationRequest": + resolve(toBase64(arrayBufferToString(pkijsObj.toSchema().toBER(false)))); + break; + } }); } -export async function privKeyToPem(privKey, crypto) { +export function pkijsToPem(pkijsObj) { return new Promise(async (resolve, reject) => { - let privKeyExported = await crypto.exportKey("pkcs8", privKey); - let privKeyBody = formatPEM( - toBase64( - String.fromCharCode.apply(null, new Uint8Array(privKeyExported)) - ) - ); - let privKeyPem = `-----BEGIN RSA PRIVATE KEY-----\r\n${privKeyBody}\r\n-----END RSA PRIVATE KEY-----\r\n`; + switch(pkijsObj.__proto__.constructor.name) { + case "CryptoKey": + let privKeyExported = await window.cryptoEngine.exportKey("pkcs8", pkijsObj); + let privKeyBody = formatPEM( + toBase64( + String.fromCharCode.apply(null, new Uint8Array(privKeyExported)) + ) + ); + resolve(`-----BEGIN RSA PRIVATE KEY-----\r\n${privKeyBody}\r\n-----END RSA PRIVATE KEY-----\r\n`); + break; - resolve(privKeyPem); - }); -} - -export async function certReqToPem(csr) { - return new Promise(async (resolve, reject) => { - let resPem = "-----BEGIN CERTIFICATE REQUEST-----\r\n"; - resPem = `${resPem}${formatPEM( - toBase64(arrayBufferToString(csr.toSchema().toBER(false))) - )}`; - resPem = `${resPem}\r\n-----END CERTIFICATE REQUEST-----\r\n`; - - resolve(resPem); + case "CertificationRequest": + let resPem = "-----BEGIN CERTIFICATE REQUEST-----\r\n"; + resPem = `${resPem}${formatPEM( + toBase64(arrayBufferToString(pkijsObj.toSchema().toBER(false))) + )}`; + resolve(`${resPem}\r\n-----END CERTIFICATE REQUEST-----\r\n`); + break; + } }); } \ No newline at end of file