diff --git a/javascript/src/iframe/viamapi-iframe.js b/javascript/src/iframe/viamapi-iframe.js index 428d5ea7b0312c7ef7c918c3e3908e6cfebf01d3..7687af53e5d2b697a2c6cc2e6a51a5e72edd35e8 100644 --- a/javascript/src/iframe/viamapi-iframe.js +++ b/javascript/src/iframe/viamapi-iframe.js @@ -1194,8 +1194,12 @@ const connection = Penpal.connectToParent({ certificatePEM: certificateOneTime } = keys; + passportChain.reverse(); + passportChain.push(passportCertificate); + passportChain.reverse(); + const pdfContentType = "application/pdf"; if (documentContentType !== pdfContentType) { @@ -1271,6 +1275,84 @@ const connection = Penpal.connectToParent({ return encodeResponse("200", "", "Document signed"); }, + signDocumentJava: async (passportUUID, documentUUID, documentContentType) => { + const authenticationPublicKey = localStorage.getItem( + "authenticatedIdentity" + ); + + if ( + !authenticationPublicKey || + !window.loadedIdentities[authenticationPublicKey] || + !extendPinCodeTtl(authenticationPublicKey) + ) { + return encodeResponse("400", "", "Identity not authenticated"); + } + + const certResponse = await getCertificateForPassport(passportUUID, true); + + if (certResponse.code !== "200") { + return encodeResponse("400", "", certResponse.status); + } + + const { + x509Certificate: passportCertificate, + privateKey: passportPrivateKey, + chain: passportChain + } = certResponse.data; + + const keys = await createOneTimePassportCertificate( + makeid() + "-" + passportUUID, + null, + passportPrivateKey, + passportCertificate + ); + + const { + privateKeyPEM: privateKeyOneTime, + certificatePEM: certificateOneTime + } = keys; + + passportChain.reverse(); + + passportChain.push(passportCertificate); + passportChain.push(certificateOneTime); + + passportChain.reverse(); + + const pdfContentType = "application/pdf"; + + if (documentContentType !== pdfContentType) { + const convResponse = await executeRestfulFunction( + "private", + window.viamApi, + window.viamApi.documentConvertDocumentByUUID, + null, + documentUUID, + documentContentType, + pdfContentType + ); + if (convResponse.code !== "200") { + return encodeResponse("400", "", convResponse.status); + } + } + + const signResponse = await executeRestfulFunction( + "private", + window.viamApi, + window.viamApi.documentSignDocumentJavaService, + null, + privateKeyOneTime, + passportChain, + passportUUID, + documentUUID, + pdfContentType + ); + if (signResponse.code !== "200") { + return encodeResponse("400", "", signResponse.status); + } + + return encodeResponse("200", "", "Document signed"); + }, documentCreateDocument: async (passportUUID, path, contentType, title) => { const authenticationPublicKey = localStorage.getItem( "authenticatedIdentity" diff --git a/javascript/src/utilities/signingUtilities.js b/javascript/src/utilities/signingUtilities.js index db47ed62ed7c1c3fd455405cd95092a84a7129ff..2fa2064cb262f70771a965f419cfc7e51ede8c19 100644 --- a/javascript/src/utilities/signingUtilities.js +++ b/javascript/src/utilities/signingUtilities.js @@ -124,8 +124,28 @@ function generateKeys(algorithms) { return crypto.generateKey(algorithm.algorithm, true, algorithm.usages); } +function fixPkijsRDN() { + pkijs.RelativeDistinguishedNames.prototype.toSchema = function () { + //region Decode stored TBS value + if (this.valueBeforeDecode.byteLength === 0) // No stored encoded array, create "from scratch" + { + return (new asn1js.Sequence({ + value: Array.from(this.typesAndValues, element => new asn1js.Set({value: [element.toSchema()]})) + })); + } + + const asn1 = asn1js.fromBER(this.valueBeforeDecode); + //endregion + + //region Construct and return new ASN.1 schema for this object + return asn1.result; + //endregion + }; +} + //********************************************************************************* function createCertificate(certData, issuerData = null) { + if (typeof certData === "undefined") { return Promise.reject("No Certificate data provided"); } @@ -1252,3 +1272,6 @@ export const verifySMIME = (smimeString, rootCaPem) => { }, 50); }); }; + +//Initialization block +fixPkijsRDN();