diff --git a/static/js/pkcs12chain.js b/static/js/pkcs12chain.js new file mode 100644 index 0000000..65d0741 --- /dev/null +++ b/static/js/pkcs12chain.js @@ -0,0 +1,120 @@ +import * as asn1js from "asn1js"; +import { + stringToArrayBuffer, + fromBase64, +} from "pvutils"; +import { + getRandomValues +} from "../node_modules/pkijs/src/common.js"; +import Certificate from "../node_modules/pkijs/src/Certificate.js"; +import PrivateKeyInfo from "../node_modules/pkijs/src/PrivateKeyInfo"; +import Attribute from "../node_modules/pkijs/src/Attribute"; +import SafeBag from "../node_modules/pkijs/src/SafeBag"; +import PKCS8ShroudedKeyBag from "../node_modules/pkijs/src/PKCS8ShroudedKeyBag"; +import PFX from "../node_modules/pkijs/src/PFX"; +import AuthenticatedSafe from "../node_modules/pkijs/src/AuthenticatedSafe"; +import SafeContents from "../node_modules/pkijs/src/SafeContents"; +import CertBag from "../node_modules/pkijs/src/CertBag"; + +export async function pkcs12chain(priv, certs, password, hash_alg) { + const asn1 = asn1js.fromBER(stringToArrayBuffer(fromBase64(priv))); + const pkcs8Simpl = new PrivateKeyInfo({schema: asn1.result}); + + const keyLocalIDBuffer = new ArrayBuffer(4); + const keyLocalIDView = new Uint8Array(keyLocalIDBuffer); + getRandomValues(keyLocalIDView); + + const bitArray = new ArrayBuffer(1); + const bitView = new Uint8Array(bitArray); + + bitView[0] = bitView[0] | 0x80; + + const keyUsage = new asn1js.BitString({ + valueHex: bitArray, + unusedBits: 7 + }); + + pkcs8Simpl.attributes = [ + new Attribute({ + type: "2.5.29.15", + values: [ + keyUsage + ] + }) + ]; + + const safeBags = [ + new SafeBag({ + bagId: "1.2.840.113549.1.12.10.1.2", + bagValue: new PKCS8ShroudedKeyBag({ + parsedValue: pkcs8Simpl + }), + bagAttributes: [ + new Attribute({ + type: "1.2.840.113549.1.9.21", // localKeyID + values: [ + new asn1js.OctetString({valueHex: keyLocalIDBuffer}) + ] + }) + ] + }) + ]; + + const numCerts = certs.length; + for (let i=0;i { + let arrayBuf = new ArrayBuffer(0); + arrayBuf = await crypto.exportKey("pkcs8", privKey); + + resolve(formatPEM(toBase64(arrayBufferToString(arrayBuf)))); + }); +} + +export async function privKeyToPem(privKey, crypto) { + 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`; + + 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); + }); +} \ No newline at end of file