Add support for EC keys #3

Merged
lauri merged 6 commits from ec-key-support into master 2021-08-19 16:59:21 +00:00
2 changed files with 51 additions and 57 deletions
Showing only changes of commit e2077a89cf - Show all commits

View File

@ -12,20 +12,18 @@ import {
} from "../node_modules/pkijs/src/common.js"; } from "../node_modules/pkijs/src/common.js";
import CertificationRequest from "../node_modules/pkijs/src/CertificationRequest.js"; import CertificationRequest from "../node_modules/pkijs/src/CertificationRequest.js";
import AttributeTypeAndValue from "../node_modules/pkijs/src/AttributeTypeAndValue.js"; import AttributeTypeAndValue from "../node_modules/pkijs/src/AttributeTypeAndValue.js";
import { formatPEM } from "./formatPEM.js";
import { pkcs12chain } from "./pkcs12chain.js"; import { pkcs12chain } from "./pkcs12chain.js";
import { import {
privKeyToBase64, pkijsToPem,
privKeyToPem, pkijsToBase64,
certReqToPem
} from "./util.js" } from "./util.js"
const DEVICE_KEYWORDS = ["Android", "iPhone", "iPad", "Windows", "Ubuntu", "Fedora", "Mac", "Linux"]; const DEVICE_KEYWORDS = ["Android", "iPhone", "iPad", "Windows", "Ubuntu", "Fedora", "Mac", "Linux"];
jQuery.timeago.settings.allowFuture = true; jQuery.timeago.settings.allowFuture = true;
const crypto = getCrypto(); window.cryptoEngine = getCrypto();
if (typeof crypto === "undefined") if (typeof window.cryptoEngine === "undefined")
console.error("No WebCrypto extension found"); console.error("No WebCrypto extension found");
function onLaunchShell(common_name) { function onLaunchShell(common_name) {
@ -113,7 +111,7 @@ function onKeyGen() {
if ("hash" in algorithm.algorithm) if ("hash" in algorithm.algorithm)
algorithm.algorithm.hash.name = window.authority.hash_alg; algorithm.algorithm.hash.name = window.authority.hash_alg;
const keyPair = await crypto.generateKey( const keyPair = await window.cryptoEngine.generateKey(
algorithm.algorithm, true, algorithm.usages); algorithm.algorithm, true, algorithm.usages);
window.keys = keyPair; window.keys = keyPair;
const publicKey = keyPair.publicKey; const publicKey = keyPair.publicKey;
@ -157,7 +155,10 @@ function onKeyGen() {
function blobToUuid(blob) { function blobToUuid(blob) {
return new Promise((resolve, reject) => { 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 = bufferToHexCodes(res).toLowerCase();
res = res =
res.substring(0, 8) + res.substring(0, 8) +
@ -195,7 +196,7 @@ function onEnroll(encoding) {
/(-----(BEGIN|END) CERTIFICATE-----|\n)/g, ""); /(-----(BEGIN|END) CERTIFICATE-----|\n)/g, "");
// Private key to base64 (for pkcs12chain) // Private key to base64 (for pkcs12chain)
let privKeyBase64 = await privKeyToBase64(keys.privateKey, crypto); let privKeyBase64 = await pkijsToBase64(keys.privateKey);
switch(encoding) { switch(encoding) {
case 'p12': case 'p12':
@ -231,7 +232,7 @@ function onEnroll(encoding) {
a.download = query.title + ".sswan"; a.download = query.title + ".sswan";
break break
case 'ovpn': case 'ovpn':
let privKeyPem = await privKeyToPem(keys.privateKey, crypto); let privKeyPem = await pkijsToPem(keys.privateKey);
var buf = nunjucks.render('snippets/openvpn-client.conf', { var buf = nunjucks.render('snippets/openvpn-client.conf', {
authority: authority, authority: authority,
@ -281,9 +282,7 @@ function onEnroll(encoding) {
} }
} }
}; };
let resultString = await certReqToPem(window.csr); xhr2.send(await pkijsToPem(window.csr));
xhr2.send(resultString);
} }
} }
xhr.send(); xhr.send();
@ -769,7 +768,7 @@ function loadAuthority(query) {
$("#enroll").click(async function() { $("#enroll").click(async function() {
var keys = await crypto.generateKey( var keys = await window.cryptoEngine.generateKey(
{ {
name: "RSASSA-PKCS1-v1_5", name: "RSASSA-PKCS1-v1_5",
modulusLength: 1024, modulusLength: 1024,
@ -795,11 +794,7 @@ function loadAuthority(query) {
var pkcs8 = await crypto.exportKey("pkcs8", keys.privateKey); var privateKeyBuffer = pkijsToPem(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`;
}); });
/** /**

View File

@ -1,51 +1,50 @@
import * as asn1js from "asn1js";
import { import {
arrayBufferToString, arrayBufferToString,
stringToArrayBuffer,
toBase64, toBase64,
fromBase64,
bufferToHexCodes
} from "pvutils"; } 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"; import { formatPEM } from "./formatPEM.js";
export async function privKeyToBase64(privKey, crypto) { export function pkijsToBase64(pkijsObj) {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
let arrayBuf = new ArrayBuffer(0); switch(pkijsObj.__proto__.constructor.name) {
arrayBuf = await crypto.exportKey("pkcs8", privKey); case "CryptoKey":
let arrayBuf = new ArrayBuffer(0);
resolve(formatPEM(toBase64(arrayBufferToString(arrayBuf)))); 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) => { return new Promise(async (resolve, reject) => {
let privKeyExported = await crypto.exportKey("pkcs8", privKey); switch(pkijsObj.__proto__.constructor.name) {
let privKeyBody = formatPEM( case "CryptoKey":
toBase64( let privKeyExported = await window.cryptoEngine.exportKey("pkcs8", pkijsObj);
String.fromCharCode.apply(null, new Uint8Array(privKeyExported)) 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`; )
);
resolve(`-----BEGIN RSA PRIVATE KEY-----\r\n${privKeyBody}\r\n-----END RSA PRIVATE KEY-----\r\n`);
break;
resolve(privKeyPem); case "CertificationRequest":
}); let resPem = "-----BEGIN CERTIFICATE REQUEST-----\r\n";
} resPem = `${resPem}${formatPEM(
toBase64(arrayBufferToString(pkijsObj.toSchema().toBER(false)))
export async function certReqToPem(csr) { )}`;
return new Promise(async (resolve, reject) => { resolve(`${resPem}\r\n-----END CERTIFICATE REQUEST-----\r\n`);
let resPem = "-----BEGIN CERTIFICATE REQUEST-----\r\n"; break;
resPem = `${resPem}${formatPEM( }
toBase64(arrayBufferToString(csr.toSchema().toBER(false)))
)}`;
resPem = `${resPem}\r\n-----END CERTIFICATE REQUEST-----\r\n`;
resolve(resPem);
}); });
} }