Switch from node-forge to pkijs
This commit is contained in:
parent
a6787dae6c
commit
1ea20850e9
@ -1,14 +1,17 @@
|
|||||||
FROM alpine
|
FROM alpine
|
||||||
MAINTAINER Pinecrypt Labs <info@pinecrypt.com>
|
MAINTAINER Pinecrypt Labs <info@pinecrypt.com>
|
||||||
RUN apk add --update npm nginx rsync bash
|
RUN apk add --update npm nginx rsync bash
|
||||||
RUN npm install --prefix /usr/local --silent --no-optional -g nunjucks@2.5.2 nunjucks-date@1.2.0 node-forge bootstrap@4.0.0-alpha.6 jquery timeago tether font-awesome qrcode-svg xterm
|
RUN npm install --prefix /usr/local --silent --no-optional -g nunjucks@2.5.2 nunjucks-date@1.2.0 node-forge bootstrap@4.0.0-alpha.6 jquery timeago tether font-awesome qrcode-svg xterm rollup
|
||||||
RUN test -e /usr/local/lib/node_modules/jquery/dist/jquery.min.js
|
RUN test -e /usr/local/lib/node_modules/jquery/dist/jquery.min.js
|
||||||
COPY nginx.conf /etc/nginx/nginx.conf
|
COPY nginx.conf /etc/nginx/nginx.conf
|
||||||
EXPOSE 80 443 8443
|
EXPOSE 80 443 8443
|
||||||
WORKDIR /var/lib/nginx/html/
|
WORKDIR /var/lib/nginx/html/
|
||||||
|
RUN npm init -y && npm i pkijs rollup-plugin-node-resolve
|
||||||
RUN rsync -avq /usr/local/lib/node_modules/font-awesome/fonts/ fonts/
|
RUN rsync -avq /usr/local/lib/node_modules/font-awesome/fonts/ fonts/
|
||||||
COPY static ./
|
COPY static ./
|
||||||
COPY templates templates
|
COPY templates templates
|
||||||
|
COPY rollup.config.js .
|
||||||
|
RUN rollup -c
|
||||||
RUN nunjucks-precompile --include snippets --include views templates >> js/bundle.js
|
RUN nunjucks-precompile --include snippets --include views templates >> js/bundle.js
|
||||||
RUN bash -c 'cat /usr/local/lib/node_modules/{jquery/dist/jquery.min.js,tether/dist/js/tether.min.js,bootstrap/dist/js/bootstrap.min.js,node-forge/dist/forge.all.min.js,qrcode-svg/dist/qrcode.min.js,timeago/jquery.timeago.js,nunjucks/browser/nunjucks-slim.min.js,xterm/lib/xterm.js} >> js/bundle.js'
|
RUN bash -c 'cat /usr/local/lib/node_modules/{jquery/dist/jquery.min.js,tether/dist/js/tether.min.js,bootstrap/dist/js/bootstrap.min.js,node-forge/dist/forge.all.min.js,qrcode-svg/dist/qrcode.min.js,timeago/jquery.timeago.js,nunjucks/browser/nunjucks-slim.min.js,xterm/lib/xterm.js} >> js/bundle.js'
|
||||||
RUN bash -c 'cat /usr/local/lib/node_modules/{tether/dist/css/tether.min.css,bootstrap/dist/css/bootstrap.min.css,font-awesome/css/font-awesome.min.css,xterm/css/xterm.css} >> css/bundle.css'
|
RUN bash -c 'cat /usr/local/lib/node_modules/{tether/dist/css/tether.min.css,bootstrap/dist/css/bootstrap.min.css,font-awesome/css/font-awesome.min.css,xterm/css/xterm.css} >> css/bundle.css'
|
||||||
|
14
rollup.config.js
Normal file
14
rollup.config.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import rollupNodeResolve from "rollup-plugin-node-resolve";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
input: "js/certidude.js",
|
||||||
|
plugins: [
|
||||||
|
rollupNodeResolve({ jsnext: true, main: true })
|
||||||
|
],
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
file: "js/certidude_bundle.js",
|
||||||
|
format: "iife"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
@ -6,7 +6,7 @@
|
|||||||
<link href="/css/bundle.css" rel="stylesheet" type="text/css"/>
|
<link href="/css/bundle.css" rel="stylesheet" type="text/css"/>
|
||||||
<link href="/css/style.css" rel="stylesheet" type="text/css"/>
|
<link href="/css/style.css" rel="stylesheet" type="text/css"/>
|
||||||
<script type="text/javascript" src="/js/bundle.js"></script>
|
<script type="text/javascript" src="/js/bundle.js"></script>
|
||||||
<script type="text/javascript" src="/js/certidude.js"></script>
|
<script type="text/javascript" src="/js/certidude_bundle.js"></script>
|
||||||
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
|
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
|
||||||
</head>
|
</head>
|
||||||
|
@ -1,11 +1,32 @@
|
|||||||
|
"use strict";
|
||||||
|
import * as asn1js from "asn1js";
|
||||||
|
import {
|
||||||
|
arrayBufferToString,
|
||||||
|
stringToArrayBuffer,
|
||||||
|
toBase64,
|
||||||
|
fromBase64,
|
||||||
|
bufferToHexCodes
|
||||||
|
} from "pvutils";
|
||||||
|
import {
|
||||||
|
getCrypto,
|
||||||
|
getAlgorithmParameters,
|
||||||
|
} from "../node_modules/pkijs/src/common.js";
|
||||||
|
import { formatPEM } from "./formatPEM.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";
|
||||||
|
|
||||||
'use strict';
|
let hashAlg = "SHA-384";
|
||||||
|
let signAlg = "RSASSA-PKCS1-V1_5";
|
||||||
const KEY_SIZE = 2048;
|
const KEY_SIZE = 2048;
|
||||||
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();
|
||||||
|
if (typeof crypto === "undefined")
|
||||||
|
console.error("No WebCrypto extension found");
|
||||||
|
|
||||||
function onLaunchShell(common_name) {
|
function onLaunchShell(common_name) {
|
||||||
$.post({
|
$.post({
|
||||||
url: "/api/signed/" + common_name + "/shell/",
|
url: "/api/signed/" + common_name + "/shell/",
|
||||||
@ -60,61 +81,114 @@ function onShowAll() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onKeyGen() {
|
function onKeyGen() {
|
||||||
if (window.navigator.userAgent.indexOf(" Edge/") >= 0) {
|
return new Promise((resolve, reject) => {
|
||||||
$("#enroll .loader-container").hide();
|
if (window.navigator.userAgent.indexOf(" Edge/") >= 0) {
|
||||||
$("#enroll .edge-broken").show();
|
$("#enroll .loader-container").hide();
|
||||||
return;
|
$("#enroll .edge-broken").show();
|
||||||
}
|
|
||||||
|
|
||||||
window.keys = forge.pki.rsa.generateKeyPair(KEY_SIZE);
|
|
||||||
console.info('Key-pair created.');
|
|
||||||
|
|
||||||
window.csr = forge.pki.createCertificationRequest();
|
|
||||||
csr.publicKey = keys.publicKey;
|
|
||||||
csr.setSubject([{
|
|
||||||
name: 'commonName', value: common_name
|
|
||||||
}]);
|
|
||||||
|
|
||||||
csr.sign(keys.privateKey, forge.md.sha384.create());
|
|
||||||
console.info('Certification request created');
|
|
||||||
|
|
||||||
|
|
||||||
$("#enroll .loader-container").hide();
|
|
||||||
|
|
||||||
var prefix = null;
|
|
||||||
for (i in DEVICE_KEYWORDS) {
|
|
||||||
var keyword = DEVICE_KEYWORDS[i];
|
|
||||||
if (window.navigator.userAgent.indexOf(keyword) >= 0) {
|
|
||||||
prefix = keyword.toLowerCase();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prefix == null) {
|
|
||||||
$(".option").show();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var protocols = query.protocols.split(",");
|
let sequence = Promise.resolve();
|
||||||
console.info("Showing snippets for:", protocols);
|
const pkcs10 = new CertificationRequest();
|
||||||
for (var j = 0; j < protocols.length; j++) {
|
let publicKey, privateKey;
|
||||||
var options = document.querySelectorAll(".option." + protocols[j] + "." + prefix);
|
|
||||||
for (i = 0; i < options.length; i++) {
|
// Commonname
|
||||||
options[i].style.display = "block";
|
pkcs10.subject.typesAndValues.push(
|
||||||
|
new AttributeTypeAndValue({
|
||||||
|
type: "2.5.4.3",
|
||||||
|
value: new asn1js.Utf8String({ value: common_name }),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
pkcs10.attributes = [];
|
||||||
|
|
||||||
|
sequence = sequence.then(() => {
|
||||||
|
const algorithm = getAlgorithmParameters(signAlg, "generatekey");
|
||||||
|
if ("hash" in algorithm.algorithm)
|
||||||
|
algorithm.algorithm.hash.name = hashAlg;
|
||||||
|
|
||||||
|
return crypto.generateKey(algorithm.algorithm, true, algorithm.usages);
|
||||||
|
});
|
||||||
|
|
||||||
|
sequence = sequence.then(
|
||||||
|
(keyPair) => {
|
||||||
|
window.keys = keyPair;
|
||||||
|
publicKey = keyPair.publicKey;
|
||||||
|
privateKey = keyPair.privateKey;
|
||||||
|
},
|
||||||
|
(error) => Promise.reject(`Error during key generation: ${error}`)
|
||||||
|
);
|
||||||
|
|
||||||
|
sequence = sequence.then(() =>
|
||||||
|
pkcs10.subjectPublicKeyInfo.importKey(publicKey)
|
||||||
|
);
|
||||||
|
|
||||||
|
sequence = sequence.then(
|
||||||
|
async () => {
|
||||||
|
pkcs10.sign(privateKey, hashAlg);
|
||||||
|
window.csr = pkcs10;
|
||||||
|
console.info("Certification request created");
|
||||||
|
var pkcs8 = await crypto.exportKey("pkcs8", keys.privateKey);
|
||||||
|
var pem = formatPEM(
|
||||||
|
toBase64(String.fromCharCode.apply(null, new Uint8Array(pkcs8)))
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
`-----BEGIN RSA PRIVATE KEY-----\r\n${pem}\r\n-----END RSA PRIVATE KEY-----\r\n`
|
||||||
|
);
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
(error) => Promise.reject(`Error during exporting public key: ${error}`)
|
||||||
|
);
|
||||||
|
|
||||||
|
sequence = sequence.then(() => {
|
||||||
|
$("#enroll .loader-container").hide();
|
||||||
|
var prefix = null;
|
||||||
|
for (i in DEVICE_KEYWORDS) {
|
||||||
|
var keyword = DEVICE_KEYWORDS[i];
|
||||||
|
if (window.navigator.userAgent.indexOf(keyword) >= 0) {
|
||||||
|
prefix = keyword.toLowerCase();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
$(".option.any").show();
|
if (prefix == null) {
|
||||||
|
$(".option").show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var protocols = query.protocols.split(",");
|
||||||
|
console.info("Showing snippets for:", protocols);
|
||||||
|
for (var j = 0; j < protocols.length; j++) {
|
||||||
|
var options = document.querySelectorAll(
|
||||||
|
".option." + protocols[j] + "." + prefix
|
||||||
|
);
|
||||||
|
for (i = 0; i < options.length; i++) {
|
||||||
|
options[i].style.display = "block";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$(".option.any").show();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function blobToUuid(blob) {
|
function blobToUuid(blob) {
|
||||||
var md = forge.md.md5.create();
|
return new Promise((resolve, reject) => {
|
||||||
md.update(blob);
|
crypto.digest({ name: "SHA-1" }, stringToArrayBuffer(blob)).then((res) => {
|
||||||
var digest = md.digest().toHex();
|
res = bufferToHexCodes(res).toLowerCase();
|
||||||
return digest.substring(0, 8) + "-" +
|
res =
|
||||||
digest.substring(8, 12) + "-" +
|
res.substring(0, 8) +
|
||||||
digest.substring(12, 16) + "-" +
|
"-" +
|
||||||
digest.substring(16,20) + "-" +
|
res.substring(8, 12) +
|
||||||
digest.substring(20);
|
"-" +
|
||||||
|
res.substring(12, 16) +
|
||||||
|
"-" +
|
||||||
|
res.substring(16, 20) +
|
||||||
|
"-" +
|
||||||
|
res.substring(20);
|
||||||
|
|
||||||
|
resolve(res);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onEnroll(encoding) {
|
function onEnroll(encoding) {
|
||||||
@ -125,17 +199,42 @@ function onEnroll(encoding) {
|
|||||||
xhr.open('GET', "/api/certificate/");
|
xhr.open('GET', "/api/certificate/");
|
||||||
xhr.onload = function() {
|
xhr.onload = function() {
|
||||||
if (xhr.status === 200) {
|
if (xhr.status === 200) {
|
||||||
|
// const xhrPEM = xhr.responseText.replace(
|
||||||
|
// /(-----(BEGIN|END) CERTIFICATE-----|\n)/g,
|
||||||
|
// ""
|
||||||
|
// );
|
||||||
|
// const xhrAsn1 = asn1js.fromBER(stringToArrayBuffer(fromBase64(xhrPEM)));
|
||||||
|
// var ca = new Certificate({ schema: xhrAsn1.result });
|
||||||
var ca = forge.pki.certificateFromPem(xhr.responseText);
|
var ca = forge.pki.certificateFromPem(xhr.responseText);
|
||||||
console.info("Got CA certificate:");
|
console.info("Got CA certificate:");
|
||||||
var xhr2 = new XMLHttpRequest();
|
var xhr2 = new XMLHttpRequest();
|
||||||
xhr2.open("PUT", "/api/token/?token=" + query.token );
|
xhr2.open("PUT", "/api/token/?token=" + query.token );
|
||||||
xhr2.onload = function() {
|
xhr2.onload = async function() {
|
||||||
if (xhr2.status === 200) {
|
if (xhr2.status === 200) {
|
||||||
var a = document.createElement("a");
|
var a = document.createElement("a");
|
||||||
|
|
||||||
|
// const xhr2PEM = xhr.responseText.replace(
|
||||||
|
// /(-----(BEGIN|END) CERTIFICATE-----|\n)/g,
|
||||||
|
// ""
|
||||||
|
// );
|
||||||
|
// const xhr2asn1 = asn1js.fromBER(
|
||||||
|
// stringToArrayBuffer(fromBase64(xhr2PEM))
|
||||||
|
// );
|
||||||
|
// var cert = await new Certificate({ schema: xhr2asn1.result });
|
||||||
|
|
||||||
var cert = forge.pki.certificateFromPem(xhr2.responseText);
|
var cert = forge.pki.certificateFromPem(xhr2.responseText);
|
||||||
console.info("Got signed certificate:", xhr2.responseText);
|
console.info("Got signed certificate:", xhr2.responseText);
|
||||||
|
|
||||||
|
// Convert PKIJS key to forge key through PEM
|
||||||
|
let privateKeyArrayBuffer = new ArrayBuffer(0);
|
||||||
|
privateKeyArrayBuffer = await crypto.exportKey("pkcs8", keys.privateKey);
|
||||||
|
let tempPrivPem = `\r\n-----BEGIN PRIVATE KEY-----\r\n`;
|
||||||
|
tempPrivPem = `${tempPrivPem}${formatPEM(toBase64(arrayBufferToString(privateKeyArrayBuffer)))}`;
|
||||||
|
tempPrivPem = `${tempPrivPem}\r\n-----END PRIVATE KEY-----\r\n`;
|
||||||
|
let forgePrivKey = forge.pki.privateKeyFromPem(tempPrivPem);
|
||||||
|
|
||||||
var p12 = forge.asn1.toDer(forge.pkcs12.toPkcs12Asn1(
|
var p12 = forge.asn1.toDer(forge.pkcs12.toPkcs12Asn1(
|
||||||
keys.privateKey, [cert, ca], "", {algorithm: '3des'})).getBytes();
|
forgePrivKey, [cert, ca], "", {algorithm: '3des'})).getBytes();
|
||||||
|
|
||||||
switch(encoding) {
|
switch(encoding) {
|
||||||
case 'p12':
|
case 'p12':
|
||||||
@ -158,7 +257,7 @@ function onEnroll(encoding) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
local: {
|
local: {
|
||||||
p12: forge.util.encode64(p12)
|
p12: toBase64(p12),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.info("Buf is:", buf);
|
console.info("Buf is:", buf);
|
||||||
@ -166,9 +265,17 @@ function onEnroll(encoding) {
|
|||||||
a.download = query.title + ".sswan";
|
a.download = query.title + ".sswan";
|
||||||
break
|
break
|
||||||
case 'ovpn':
|
case 'ovpn':
|
||||||
|
let privKey = await crypto.exportKey("pkcs8", keys.privateKey);
|
||||||
|
let privKeyBody = formatPEM(
|
||||||
|
toBase64(
|
||||||
|
String.fromCharCode.apply(null, new Uint8Array(privKey))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
let privKeyPem = `-----BEGIN RSA PRIVATE KEY-----\r\n${privKeyBody}\r\n-----END RSA PRIVATE KEY-----\r\n`;
|
||||||
|
|
||||||
var buf = nunjucks.render('snippets/openvpn-client.conf', {
|
var buf = nunjucks.render('snippets/openvpn-client.conf', {
|
||||||
authority: authority,
|
authority: authority,
|
||||||
key: forge.pki.privateKeyToPem(keys.privateKey),
|
key: privKeyPem,
|
||||||
cert: xhr2.responseText,
|
cert: xhr2.responseText,
|
||||||
ca: xhr.responseText
|
ca: xhr.responseText
|
||||||
});
|
});
|
||||||
@ -186,15 +293,19 @@ function onEnroll(encoding) {
|
|||||||
common_name: common_name,
|
common_name: common_name,
|
||||||
gateway: authority.namespace,
|
gateway: authority.namespace,
|
||||||
p12_uuid: blobToUuid(p12),
|
p12_uuid: blobToUuid(p12),
|
||||||
p12: forge.util.encode64(p12),
|
p12: toBase64(p12),
|
||||||
ca_uuid: blobToUuid(forge.asn1.toDer(forge.pki.certificateToAsn1(ca)).getBytes()),
|
ca_uuid: blobToUuid(
|
||||||
ca: forge.util.encode64(forge.asn1.toDer(forge.pki.certificateToAsn1(ca)).getBytes())
|
forge.asn1.toDer(forge.pki.certificateToAsn1(ca)).getBytes()
|
||||||
|
),
|
||||||
|
ca: toBase64(
|
||||||
|
forge.asn1.toDer(forge.pki.certificateToAsn1(ca)).getBytes()
|
||||||
|
),
|
||||||
});
|
});
|
||||||
var mimetype = "application/x-apple-aspen-config";
|
var mimetype = "application/x-apple-aspen-config";
|
||||||
a.download = query.title + ".mobileconfig";
|
a.download = query.title + ".mobileconfig";
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
a.href = "data:" + mimetype + ";base64," + forge.util.encode64(buf);
|
a.href = "data:" + mimetype + ";base64," + toBase64(buf);
|
||||||
console.info("Offering bundle for download");
|
console.info("Offering bundle for download");
|
||||||
document.body.appendChild(a); // Firefox needs this!
|
document.body.appendChild(a); // Firefox needs this!
|
||||||
a.click();
|
a.click();
|
||||||
@ -210,7 +321,13 @@ function onEnroll(encoding) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhr2.send(forge.pki.certificationRequestToPem(csr));
|
let resultString = "-----BEGIN CERTIFICATE REQUEST-----\r\n";
|
||||||
|
resultString = `${resultString}${formatPEM(
|
||||||
|
toBase64(arrayBufferToString(csr.toSchema().toBER(false)))
|
||||||
|
)}`;
|
||||||
|
resultString = `${resultString}\r\n-----END CERTIFICATE REQUEST-----\r\n`;
|
||||||
|
|
||||||
|
xhr2.send(resultString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xhr.send();
|
xhr.send();
|
||||||
@ -238,13 +355,9 @@ function onHashChanged() {
|
|||||||
}
|
}
|
||||||
$("#view-dashboard").html(env.render('views/error.html', { message: msg }));
|
$("#view-dashboard").html(env.render('views/error.html', { message: msg }));
|
||||||
},
|
},
|
||||||
success: function(authority) {
|
success: async function(authority) {
|
||||||
window.authority = authority
|
window.authority = authority
|
||||||
|
|
||||||
// Device identifier
|
|
||||||
var dig = forge.md.sha384.create();
|
|
||||||
dig.update(window.navigator.userAgent);
|
|
||||||
|
|
||||||
var prefix = "unknown";
|
var prefix = "unknown";
|
||||||
for (i in DEVICE_KEYWORDS) {
|
for (i in DEVICE_KEYWORDS) {
|
||||||
var keyword = DEVICE_KEYWORDS[i];
|
var keyword = DEVICE_KEYWORDS[i];
|
||||||
@ -254,7 +367,9 @@ function onHashChanged() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.common_name = prefix + "-" + dig.digest().toHex().substring(0, 5);
|
// Device identifier
|
||||||
|
var dig = await blobToUuid(window.navigator.userAgent);
|
||||||
|
window.common_name = prefix + "-" + dig.substring(0, 5);
|
||||||
console.info("Device identifier:", common_name);
|
console.info("Device identifier:", common_name);
|
||||||
|
|
||||||
if (window.location.protocol != "https:") {
|
if (window.location.protocol != "https:") {
|
||||||
@ -694,8 +809,16 @@ function loadAuthority(query) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
$("#enroll").click(function() {
|
$("#enroll").click(async function() {
|
||||||
var keys = forge.pki.rsa.generateKeyPair(1024);
|
var keys = await crypto.generateKey(
|
||||||
|
{
|
||||||
|
name: "RSASSA-PKCS1-v1_5",
|
||||||
|
modulusLength: 1024,
|
||||||
|
publicExponent: new Uint8Array([1, 0, 1]),
|
||||||
|
hash: "SHA-256",
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
["encrypt", "decrypt"]);
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@ -713,7 +836,11 @@ function loadAuthority(query) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
var privateKeyBuffer = forge.pki.privateKeyToPem(keys.privateKey);
|
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`;
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -838,3 +965,28 @@ $(document).ready(function() {
|
|||||||
env.addFilter("serial", serialFilter);
|
env.addFilter("serial", serialFilter);
|
||||||
onHashChanged();
|
onHashChanged();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.onLaunchShell = onLaunchShell;
|
||||||
|
window.onRejectRequest = onRejectRequest;
|
||||||
|
window.onSignRequest = onSignRequest;
|
||||||
|
window.onShowAll = onShowAll;
|
||||||
|
window.onKeyGen = onKeyGen;
|
||||||
|
window.onEnroll = onEnroll;
|
||||||
|
window.onHashChanged = onHashChanged;
|
||||||
|
window.onToggleAccessButtonClicked = onToggleAccessButtonClicked;
|
||||||
|
window.onTagClicked = onTagClicked;
|
||||||
|
window.onNewTagClicked = onNewTagClicked;
|
||||||
|
window.onTagFilterChanged = onTagFilterChanged;
|
||||||
|
window.onLogEntry = onLogEntry;
|
||||||
|
window.onRequestSubmitted = onRequestSubmitted;
|
||||||
|
window.onRequestDeleted = onRequestDeleted;
|
||||||
|
window.onLeaseUpdate = onLeaseUpdate;
|
||||||
|
window.onRequestSigned = onRequestSigned;
|
||||||
|
window.onCertificateRevoked = onCertificateRevoked;
|
||||||
|
window.onTagUpdated = onTagUpdated;
|
||||||
|
window.onAttributeUpdated = onAttributeUpdated;
|
||||||
|
window.onSubmitRequest = onSubmitRequest;
|
||||||
|
window.onServerStarted = onServerStarted;
|
||||||
|
window.onServerStopped = onServerStopped;
|
||||||
|
window.onIssueToken = onIssueToken;
|
||||||
|
window.onInstanceAvailabilityUpdated = onInstanceAvailabilityUpdated;
|
32
static/js/formatPEM.js
Normal file
32
static/js/formatPEM.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//**************************************************************************************
|
||||||
|
//region Auxilliary functions
|
||||||
|
//**************************************************************************************
|
||||||
|
/**
|
||||||
|
* Format string in order to have each line with length equal to 64
|
||||||
|
* @param {string} pemString String to format
|
||||||
|
* @returns {string} Formatted string
|
||||||
|
*/
|
||||||
|
export function formatPEM(pemString)
|
||||||
|
{
|
||||||
|
const PEM_STRING_LENGTH = pemString.length, LINE_LENGTH = 64;
|
||||||
|
const wrapNeeded = PEM_STRING_LENGTH > LINE_LENGTH;
|
||||||
|
|
||||||
|
if(wrapNeeded)
|
||||||
|
{
|
||||||
|
let formattedString = "", wrapIndex = 0;
|
||||||
|
|
||||||
|
for(let i = LINE_LENGTH; i < PEM_STRING_LENGTH; i += LINE_LENGTH)
|
||||||
|
{
|
||||||
|
formattedString += pemString.substring(wrapIndex, i) + "\r\n";
|
||||||
|
wrapIndex = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
formattedString += pemString.substring(wrapIndex, PEM_STRING_LENGTH);
|
||||||
|
return formattedString;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return pemString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//**************************************************************************************
|
Loading…
Reference in New Issue
Block a user