UNPKG

pkijs

Version:

Public Key Infrastructure (PKI) is the basis of how identity and key management is performed on the web today. PKIjs is a pure JavaScript library implementing the formats that are used in PKI applications. It is built on WebCrypto and aspires to make it p

1,015 lines (900 loc) 43.7 kB
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title>TSP response complex example</title> <script type="text/javascript" src="org/pkijs/common.js"></script> <script type="text/javascript" src="org/pkijs/asn1.js"></script> <script type="text/javascript" src="org/pkijs/x509_schema.js"></script> <script type="text/javascript" src="org/pkijs/x509_simpl.js"></script> <script type="text/javascript" src="org/pkijs/cms_schema.js"></script> <script type="text/javascript" src="org/pkijs/cms_simpl.js"></script> <script type="text/javascript" src="org/pkijs/ocsp_tsp_schema.js"></script> <script type="text/javascript" src="org/pkijs/ocsp_tsp_simpl.js"></script> <style type="text/css"> body{background:#EFEFEF;font:normal 14px/16px Helvetica, Arial, sans-serif;} .wrapper{ width:600px; margin:50px auto; padding:50px; border:solid 2px #CCC; border-radius:10px; -webkit-border-radius:10px; box-shadow:0 0 12px 3px #CDCDCD; -webkit-box-shadow:0 0 12px 3px #CDCDCD; background:#FFF; } label{ font:bold 16px/20px Helvetica, Arial, sans-serif; margin:0 0 8px; } textarea{ width:500px; border:solid 1px #999; border-radius:5px; -webkit-border-radius:5px; height:340px; font:normal 12px/15px monospace; display:block; margin:0 0 12px; box-shadow:0 0 5px 5px #EFEFEF inset; -webkit-box-shadow:0 0 5px 5px #EFEFEF inset; padding:20px; resize: none; } a{ display:inline-block; padding:5px 15px; background:#ACD0EC; border:solid 1px #4C6181; color:#000; font:normal 14px/16px Helvetica, Arial, sans-serif; } a:hover{ background:#DAEBF8; cursor:pointer; } .header-block { margin-top:30px; font:bold 16px/20px Helvetica, Arial, sans-serif; } .border-block{ border:solid 2px #999; border-radius:5px; -webkit-border-radius:5px; margin:10px 0 0; padding:20px 30px; background:#F0F4FF; } .border-block h2{ margin:0 0 16px; font:bold 22px/24px Helvetica, Arial, sans-serif; } .border-block p{ margin:0 0 12px; } .border-block p .type{ font-weight:bold; display:inline-block; width:176px; } .border-block .two-col{ overflow:hidden; margin:0 0 16px; } .border-block .two-col .subject{ width:180px; font-weight:bold; margin:0 0 12px; float:left; } .border-block .two-col #cms-signed-attributes{ margin:0; padding:0; float:left; list-style:none; } .border-block .two-col #cms-signed-attributes li p{ margin:0; } .border-block .two-col #cms-signed-attributes li p span{ width:40px; display:inline-block; margin:0 0 5px; } .border-block .two-col #cms-signed-exten{ overflow:hidden; padding:0 0 0 17px; margin:0; list-style-type:square; } table { border:solid; border-collapse:collapse; border-color:black; } th { text-align:center; background: #ccc; padding: 5px; border: 1px solid black; } td { padding: 5px; border: 1px solid black; } </style> <script> //********************************************************************************* var tspResponseBuffer = new ArrayBuffer(0); // ArrayBuffer with loaded or created TSP response var trustedCertificates = new Array(); // Array of root certificates from "CA Bundle" //********************************************************************************* // #region Auxiliary functions //********************************************************************************* function formatPEM(pem_string) { /// <summary>Format string in order to have each line with length equal to 63</summary> /// <param name="pem_string" type="String">String to format</param> var string_length = pem_string.length; var result_string = ""; for(var i = 0, count = 0; i < string_length; i++, count++) { if(count > 63) { result_string = result_string + "\r\n"; count = 0; } result_string = result_string + pem_string[i]; } return result_string; } //********************************************************************************* function arrayBufferToString(buffer) { /// <summary>Create a string from ArrayBuffer</summary> /// <param name="buffer" type="ArrayBuffer">ArrayBuffer to create a string from</param> var result_string = ""; var view = new Uint8Array(buffer); for(var i = 0; i < view.length; i++) result_string = result_string + String.fromCharCode(view[i]); return result_string; } //********************************************************************************* function stringToArrayBuffer(str) { /// <summary>Create an ArrayBuffer from string</summary> /// <param name="str" type="String">String to create ArrayBuffer from</param> var stringLength = str.length; var resultBuffer = new ArrayBuffer(stringLength); var resultView = new Uint8Array(resultBuffer); for(var i = 0; i < stringLength; i++) resultView[i] = str.charCodeAt(i); return resultBuffer; } //********************************************************************************* function handleFileBrowse(evt) { var temp_reader = new FileReader(); var current_files = evt.target.files; var current_index = 0; temp_reader.onload = function(event) { tspResponseBuffer = event.target.result; parse_TSP_resp(); }; temp_reader.readAsArrayBuffer(current_files[0]); } //********************************************************************************* function handleCABundle(evt) { var temp_reader = new FileReader(); var current_files = evt.target.files; temp_reader.onload = function(event) { parseCAbundle(event.target.result); }; temp_reader.readAsArrayBuffer(current_files[0]); } //********************************************************************************* // #endregion //********************************************************************************* // #region Create TSP response //********************************************************************************* function create_TSP_resp() { // #region Initial variables var sequence = Promise.resolve(); var cert_simpl = new org.pkijs.simpl.CERT(); var cms_signed_simpl; var publicKey; var privateKey; var hash_algorithm = "sha-1"; var hash_algorithm_oid = "1.3.14.3.2.26"; var signature_algorithm = "1.2.840.113549.1.1.5"; var hash_option = document.getElementById("hash_alg").value; switch(hash_option) { case "alg_SHA1": hash_algorithm = "sha-1"; hash_algorithm_oid = "1.3.14.3.2.26"; signature_algorithm = "1.2.840.113549.1.1.5"; break; case "alg_SHA256": hash_algorithm = "sha-256"; hash_algorithm_oid = "2.16.840.1.101.3.4.2.1"; signature_algorithm = "1.2.840.113549.1.1.11"; break; case "alg_SHA384": hash_algorithm = "sha-384"; hash_algorithm_oid = "2.16.840.1.101.3.4.2.2"; signature_algorithm = "1.2.840.113549.1.1.12"; break; case "alg_SHA512": hash_algorithm = "sha-512"; hash_algorithm_oid = "2.16.840.1.101.3.4.2.3"; signature_algorithm = "1.2.840.113549.1.1.13"; break; default:; } // #endregion // #region Get a "crypto" extension var crypto = org.pkijs.getCrypto(); if(typeof crypto == "undefined") { alert("No WebCrypto extension found"); return; } // #endregion // #region Put a static values cert_simpl.version = 2; cert_simpl.serialNumber = new org.pkijs.asn1.INTEGER({ value: 1 }); cert_simpl.issuer.types_and_values.push(new org.pkijs.simpl.ATTR_TYPE_AND_VALUE({ type: "2.5.4.6", // Country name value: new org.pkijs.asn1.PRINTABLESTRING({ value: "RU" }) })); cert_simpl.issuer.types_and_values.push(new org.pkijs.simpl.ATTR_TYPE_AND_VALUE({ type: "2.5.4.3", // Common name value: new org.pkijs.asn1.BMPSTRING({ value: "Test" }) })); cert_simpl.subject.types_and_values.push(new org.pkijs.simpl.ATTR_TYPE_AND_VALUE({ type: "2.5.4.6", // Country name value: new org.pkijs.asn1.PRINTABLESTRING({ value: "RU" }) })); cert_simpl.subject.types_and_values.push(new org.pkijs.simpl.ATTR_TYPE_AND_VALUE({ type: "2.5.4.3", // Common name value: new org.pkijs.asn1.BMPSTRING({ value: "Test" }) })); cert_simpl.notBefore.value = new Date(2013, 01, 01); cert_simpl.notAfter.value = new Date(2016, 01, 01); cert_simpl.extensions = new Array(); // Extensions are not a part of certificate by default, it's an optional array // #region "BasicConstraints" extension //var basic_constr = new org.pkijs.simpl.x509.BasicConstraints({ // cA: true, // pathLenConstraint: 3 //}); //cert_simpl.extensions.push(new org.pkijs.simpl.EXTENSION({ // extnID: "2.5.29.19", // critical: false, // extnValue: basic_constr.toSchema().toBER(false), // parsedValue: basic_constr // Parsed value for well-known extensions //})); // #endregion // #region "KeyUsage" extension var bit_array = new ArrayBuffer(1); var bit_view = new Uint8Array(bit_array); bit_view[0] = bit_view[0] | 0x02; // Key usage "cRLSign" flag //bit_view[0] = bit_view[0] | 0x04; // Key usage "keyCertSign" flag var key_usage = new org.pkijs.asn1.BITSTRING({ value_hex: bit_array }); cert_simpl.extensions.push(new org.pkijs.simpl.EXTENSION({ extnID: "2.5.29.15", critical: false, extnValue: key_usage.toBER(false), parsedValue: key_usage // Parsed value for well-known extensions })); // #endregion cert_simpl.signatureAlgorithm.algorithm_id = signature_algorithm; cert_simpl.signature.algorithm_id = cert_simpl.signatureAlgorithm.algorithm_id; // Must be the same value // #endregion // #region Create a new key pair sequence = sequence.then( function() { return crypto.generateKey({ name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([0x01, 0x00, 0x01]), hash: { name: hash_algorithm } }, true, ["sign", "verify"]); } ); // #endregion // #region Store new key in an interim variables sequence = sequence.then( function(keyPair) { publicKey = keyPair.publicKey; privateKey = keyPair.privateKey; }, function(error) { alert("Error during key generation: " + error); } ); // #endregion // #region Exporting public key into "subjectPublicKeyInfo" value of certificate sequence = sequence.then( function() { return cert_simpl.subjectPublicKeyInfo.importKey(publicKey); } ); // #endregion // #region Signing final certificate sequence = sequence.then( function() { return cert_simpl.sign(privateKey); }, function(error) { alert("Error during exporting public key: " + error); } ); // #endregion // #region Encode and store certificate sequence = sequence.then( function() { var cert_simpl_encoded = cert_simpl.toSchema(true).toBER(false); var cert_simpl_string = String.fromCharCode.apply(null, new Uint8Array(cert_simpl_encoded)); var result_string = "-----BEGIN CERTIFICATE-----\r\n"; result_string = result_string + formatPEM(window.btoa(cert_simpl_string)); result_string = result_string + "\r\n-----END CERTIFICATE-----\r\n"; document.getElementById("new_signed_data").innerHTML = result_string; alert("Certificate created successfully!"); }, function(error) { alert("Error during signing: " + error); } ); // #endregion // #region Exporting private key sequence = sequence.then( function() { return crypto.exportKey("pkcs8", privateKey); } ); // #endregion // #region Store exported key on Web page sequence = sequence.then( function(result) { var private_key_string = String.fromCharCode.apply(null, new Uint8Array(result)); var result_string = document.getElementById("new_signed_data").innerHTML; result_string = result_string + "\r\n-----BEGIN PRIVATE KEY-----\r\n"; result_string = result_string + formatPEM(window.btoa(private_key_string)); result_string = result_string + "\r\n-----END PRIVATE KEY-----\r\n"; document.getElementById("new_signed_data").innerHTML = result_string; alert("Private key exported successfully!"); }, function(error) { alert("Error during exporting of private key: " + error); } ); // #endregion // #region Create specific TST info structure to sign sequence = sequence.then( function() { var hashedBuffer = new ArrayBuffer(4); var hashedView = new Uint8Array(hashedBuffer); hashedView[0] = 0x7F; hashedView[1] = 0x02; hashedView[2] = 0x03; hashedView[3] = 0x04; var tst_info_simpl = new org.pkijs.simpl.TST_INFO({ version: 1, policy: "1.1.1", messageImprint: new org.pkijs.simpl.tsp.MessageImprint({ hashAlgorithm: new org.pkijs.simpl.ALGORITHM_IDENTIFIER({ algorithm_id: "1.3.14.3.2.26" }), hashedMessage: new org.pkijs.asn1.OCTETSTRING({ value_hex: hashedBuffer }) }), serialNumber: new org.pkijs.asn1.INTEGER({ value_hex: hashedBuffer }), genTime: new Date(), ordering: true, accuracy: new org.pkijs.simpl.tsp.Accuracy({ seconds: 1, millis: 1, micros: 10 }), nonce: new org.pkijs.asn1.INTEGER({ value_hex: hashedBuffer }) }); return tst_info_simpl.toSchema().toBER(false); } ); // #endregion // #region Initialize CMS Signed Data structures and sign it sequence = sequence.then( function(result) { var encapContent = new org.pkijs.simpl.cms.EncapsulatedContentInfo(); encapContent.eContentType = "1.2.840.113549.1.9.16.1.4"; // "tSTInfo" content type encapContent.eContent = new org.pkijs.asn1.OCTETSTRING({ value_hex: result }); cms_signed_simpl = new org.pkijs.simpl.CMS_SIGNED_DATA({ version: 3, digestAlgorithms: [ new org.pkijs.simpl.ALGORITHM_IDENTIFIER({ algorithm_id: hash_algorithm_oid, algorithm_params: new org.pkijs.asn1.NULL() }) // SHA-1 ], encapContentInfo: encapContent, signerInfos: [ new org.pkijs.simpl.CMS_SIGNER_INFO({ version: 1, sid: new org.pkijs.simpl.cms.IssuerAndSerialNumber({ issuer: cert_simpl.issuer, serialNumber: cert_simpl.serialNumber }), digestAlgorithm: new org.pkijs.simpl.ALGORITHM_IDENTIFIER({ algorithm_id: hash_algorithm_oid, algorithm_params: new org.pkijs.asn1.NULL() }), // SHA-1 signatureAlgorithm: new org.pkijs.simpl.ALGORITHM_IDENTIFIER({ algorithm_id: "1.2.840.113549.1.1.1", algorithm_params: new org.pkijs.asn1.NULL() }), // RSA (PKCS #1 v1.5) key transport algorithm }) ], certificates: [cert_simpl] }); return cms_signed_simpl.sign(privateKey, 0); } ); // #endregion // #region Create internal CMS Signed Data sequence = sequence.then( function(result) { var cms_signed_schema = cms_signed_simpl.toSchema(true); var cms_content_simp = new org.pkijs.simpl.CMS_CONTENT_INFO({ contentType: "1.2.840.113549.1.7.2", content: cms_signed_schema }); return cms_content_simp.toSchema(true); }, function(error) { alert("Erorr during signing of CMS Signed Data: " + error); } ); // #endregion // #region Finally create completed TSP response structure sequence.then( function(result) { var tsp_resp_simpl = new org.pkijs.simpl.TSP_RESPONSE({ status: new org.pkijs.simpl.tsp.PKIStatusInfo({ status: 0 }), timeStampToken: new org.pkijs.simpl.CMS_CONTENT_INFO({ schema: result }) }); // #region Convert ArrayBuffer to String var signed_data_string = ""; var tsp_schema = tsp_resp_simpl.toSchema(); tspResponseBuffer = tsp_schema.toBER(false); var view = new Uint8Array(tspResponseBuffer); for(var i = 0; i < view.length; i++) signed_data_string = signed_data_string + String.fromCharCode(view[i]); // #endregion var result_string = document.getElementById("new_signed_data").innerHTML; result_string = result_string + "\r\n-----BEGIN TSP RESPONSE-----\r\n"; result_string = result_string + formatPEM(window.btoa(signed_data_string)); result_string = result_string + "\r\n-----END TSP RESPONSE-----\r\n\r\n"; document.getElementById("new_signed_data").innerHTML = result_string; parse_TSP_resp(); alert("TSP response has created successfully!"); } ); // #endregion } //********************************************************************************* // #endregion //********************************************************************************* // #region Parse existing TSP response //********************************************************************************* function parse_TSP_resp() { // #region Initial activities document.getElementById("resp-accur").style.display = "none"; document.getElementById("resp-ord").style.display = "none"; document.getElementById("resp-non").style.display = "none"; document.getElementById("resp-ts-rdn").style.display = "none"; document.getElementById("resp-ts-simpl").style.display = "none"; document.getElementById("resp-ext").style.display = "none"; var imprTable = document.getElementById("resp-imprint"); while(imprTable.rows.length > 1) { imprTable.deleteRow(imprTable.rows.length - 1); } var accurTable = document.getElementById("resp-accuracy"); while(accurTable.rows.length > 1) { accurTable.deleteRow(accurTable.rows.length - 1); } var tsTable = document.getElementById("resp-tsa"); while(tsTable.rows.length > 1) { tsTable.deleteRow(tsTable.rows.length - 1); } var extTable = document.getElementById("resp-extensions"); while(extTable.rows.length > 1) { extTable.deleteRow(extTable.rows.length - 1); } // #endregion // #region Decode existing TSP response var asn1 = org.pkijs.fromBER(tspResponseBuffer); var tsp_resp_simpl = new org.pkijs.simpl.TSP_RESPONSE({ schema: asn1.result }); // #endregion // #region Put information about TSP response status var status = ""; switch(tsp_resp_simpl.status.status) { case 0: status = "granted"; break; case 1: status = "grantedWithMods"; break; case 2: status = "rejection"; break; case 3: status = "waiting"; break; case 4: status = "revocationWarning"; break; case 5: status = "revocationNotification"; break; default:; } document.getElementById("resp-status").innerHTML = status // #endregion // #region Parse internal CMS Signed Data if(("timeStampToken" in tsp_resp_simpl) === false) { alert("No additional info but PKIStatusInfo"); return; } var signed_simpl = new org.pkijs.simpl.CMS_SIGNED_DATA({ schema: tsp_resp_simpl.timeStampToken.content }); var asn1_tst = org.pkijs.fromBER(signed_simpl.encapContentInfo.eContent.value_block.value_hex); var tst_info_simpl = new org.pkijs.simpl.TST_INFO({ schema: asn1_tst.result }); // #endregion // #region Put information about policy document.getElementById("resp-policy").innerHTML = tst_info_simpl.policy; // #endregion // #region Put information about TST info message imprint var dgstmap = { "1.3.14.3.2.26": "SHA-1", "2.16.840.1.101.3.4.2.1": "SHA-256", "2.16.840.1.101.3.4.2.2": "SHA-384", "2.16.840.1.101.3.4.2.3": "SHA-512" }; var hashAlgorithm = dgstmap[tst_info_simpl.messageImprint.hashAlgorithm.algorithm_id]; if(typeof hashAlgorithm === "undefined") hashAlgorithm = tst_info_simpl.messageImprint.hashAlgorithm.algorithm_id; var imprintTable = document.getElementById("resp-imprint"); var row = imprintTable.insertRow(imprintTable.rows.length); var cell0 = row.insertCell(0); cell0.innerHTML = hashAlgorithm; var cell1 = row.insertCell(1); cell1.innerHTML = org.pkijs.bufferToHexCodes(tst_info_simpl.messageImprint.hashedMessage.value_block.value_hex); // #endregion // #region Put information about TST info serial number document.getElementById("resp-serial").innerHTML = org.pkijs.bufferToHexCodes(tst_info_simpl.serialNumber.value_block.value_hex); // #endregion // #region Put information about the time when TST info was generated document.getElementById("resp-time").innerHTML = tst_info_simpl.genTime.toString(); // #endregion // #region Put information about TST info accuracy if("accuracy" in tst_info_simpl) { var accuracyTable = document.getElementById("resp-accuracy"); var row = accuracyTable.insertRow(accuracyTable.rows.length); var cell0 = row.insertCell(0); cell0.innerHTML = ("seconds" in tst_info_simpl.accuracy) ? tst_info_simpl.accuracy.seconds : 0; var cell1 = row.insertCell(1); cell1.innerHTML = ("millis" in tst_info_simpl.accuracy) ? tst_info_simpl.accuracy.millis : 0; var cell2 = row.insertCell(2); cell2.innerHTML = ("micros" in tst_info_simpl.accuracy) ? tst_info_simpl.accuracy.micros : 0; document.getElementById("resp-accur").style.display = "block"; } // #endregion // #region Put information about TST info ordering if("ordering" in tst_info_simpl) { document.getElementById("resp-ordering").innerHTML = tst_info_simpl.ordering.toString(); document.getElementById("resp-ord").style.display = "block"; } // #endregion // #region Put information about TST info nonce value if("nonce" in tst_info_simpl) { document.getElementById("resp-nonce").innerHTML = org.pkijs.bufferToHexCodes(tst_info_simpl.nonce.value_block.value_hex); document.getElementById("resp-non").style.display = "block"; } // #endregion // #region Put information about TST info TSA if("tsa" in tst_info_simpl) { switch(tst_info_simpl.tsa.NameType) { case 1: // rfc822Name case 2: // dNSName case 6: // uniformResourceIdentifier document.getElementById("resp-tsa-simpl").innerHTML = tst_info_simpl.tsa.Name.value_block.value; document.getElementById("resp-ts-simpl").style.display = "block"; break; case 7: // iPAddress { var view = new Uint8Array(tst_info_simpl.tsa.Name.value_block.value_hex); document.getElementById("resp-tsa-simpl").innerHTML = view[0].toString() + "." + view[1].toString() + "." + view[2].toString() + "." + view[3].toString(); document.getElementById("resp-ts-simpl").style.display = "block"; } break; case 3: // x400Address case 5: // ediPartyName document.getElementById("resp-tsa-simpl").innerHTML = (tst_info_simpl.tsa.NameType === 3) ? "<type \"x400Address\">" : "<type \"ediPartyName\">"; document.getElementById("resp-ts-simpl").style.display = "block"; break; case 4: // directoryName { var rdnmap = { "2.5.4.6": "C", "2.5.4.10": "OU", "2.5.4.11": "O", "2.5.4.3": "CN", "2.5.4.7": "L", "2.5.4.8": "S", "2.5.4.12": "T", "2.5.4.42": "GN", "2.5.4.43": "I", "2.5.4.4": "SN", "1.2.840.113549.1.9.1": "E-mail" }; var rdnTable = document.getElementById("resp-tsa"); for(var i = 0; i < tst_info_simpl.tsa.Name.types_and_values.length; i++) { var typeval = rdnmap[tst_info_simpl.tsa.Name.types_and_values[i].type]; if(typeof typeval === "undefined") typeval = tst_info_simpl.tsa.Name.types_and_values[i].type; var subjval = tst_info_simpl.tsa.Name.types_and_values[i].value.value_block.value; var row = rdnTable.insertRow(rdnTable.rows.length); var cell0 = row.insertCell(0); cell0.innerHTML = typeval; var cell1 = row.insertCell(1); cell1.innerHTML = subjval; } document.getElementById("resp-ts-rdn").style.display = "block"; } break; } } // #endregion // #region Put information about TST info extensions if("extensions" in tst_info_simpl) { var extensionTable = document.getElementById("resp-extensions"); for(var i = 0; i < tst_info_simpl.extensions.length; i++) { var row = extensionTable.insertRow(extensionTable.rows.length); var cell0 = row.insertCell(0); cell0.innerHTML = tst_info_simpl.extensions[i].extnID; } document.getElementById("resp-ext").style.display = "block"; } // #endregion } //********************************************************************************* // #endregion //********************************************************************************* // #region Verify existing TSP response //********************************************************************************* function verify_TSP_resp() { // #region Decode existing TSP response var asn1 = org.pkijs.fromBER(tspResponseBuffer); var tsp_resp_simpl = new org.pkijs.simpl.TSP_RESPONSE({ schema: asn1.result }); // #endregion // #region Verify TSP response tsp_resp_simpl.verify({ trusted_certs: trustedCertificates }). then( function(result) { alert("Verification result: " + result); }, function(error) { alert("Error during verification: " + error); } ); // #endregion } //********************************************************************************* // #endregion //********************************************************************************* // #region Parse "CA Bundle" file //********************************************************************************* function parseCAbundle(buffer) { // #region Initial variables var base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var startChars = "-----BEGIN CERTIFICATE-----"; var endChars = "-----END CERTIFICATE-----"; var endLineChars = "\r\n"; var view = new Uint8Array(buffer); var waitForStart = false; var middleStage = true; var waitForEnd = false; var waitForEndLine = false; var started = false; var certBodyEncoded = ""; // #endregion for(var i = 0; i < view.length; i++) { if(started === true) { if(base64Chars.indexOf(String.fromCharCode(view[i])) !== (-1)) certBodyEncoded = certBodyEncoded + String.fromCharCode(view[i]); else { if(String.fromCharCode(view[i]) === '-') { // #region Decoded trustedCertificates var asn1 = org.pkijs.fromBER(stringToArrayBuffer(window.atob(certBodyEncoded))); try { trustedCertificates.push(new org.pkijs.simpl.CERT({ schema: asn1.result })); } catch(ex) { alert("Wrong certificate format"); return; } // #endregion // #region Set all "flag variables" certBodyEncoded = ""; started = false; waitForEnd = true; // #endregion } } } else { if(waitForEndLine === true) { if(endLineChars.indexOf(String.fromCharCode(view[i])) === (-1)) { waitForEndLine = false; if(waitForEnd === true) { waitForEnd = false; middleStage = true; } else { if(waitForStart === true) { waitForStart = false; started = true; certBodyEncoded = certBodyEncoded + String.fromCharCode(view[i]); } else middleStage = true; } } } else { if(middleStage === true) { if(String.fromCharCode(view[i]) === "-") { if((i === 0) || ((String.fromCharCode(view[i - 1]) === "\r") || (String.fromCharCode(view[i - 1]) === "\n"))) { middleStage = false; waitForStart = true; } } } else { if(waitForStart === true) { if(startChars.indexOf(String.fromCharCode(view[i])) === (-1)) waitForEndLine = true; } else { if(waitForEnd === true) { if(endChars.indexOf(String.fromCharCode(view[i])) === (-1)) waitForEndLine = true; } } } } } } } //********************************************************************************* // #endregion //********************************************************************************* </script> </head> <body> <div class="wrapper"> <p class="header-block">Create new TSP response</p> <div id="add-tsp-resp-block" class="border-block"> <p> <label for="hash_alg" style="font-weight:bold">Hashing algorithm:</label> <select id="hash_alg"> <option value="alg_SHA1">SHA-1</option> <option value="alg_SHA256">SHA-256</option> <option value="alg_SHA384">SHA-384</option> <option value="alg_SHA512">SHA-512</option> </select> </p> <label for="new_signed_data" style="font-weight:bold;float:left;">TSP resp data + BASE-64 encoded new certificate + PKCS#8 private key:</label> <textarea id="new_signed_data">&lt; New TSP response data + new encoded certificate + PKCS#8 exported private key will be stored here &gt;</textarea> <a onclick="create_TSP_resp();">Create</a> </div> <p class="header-block">Parse loaded/created TSP response</p> <div id="tsp-resp-data-block" class="border-block"> <p> <label for="temp_file">Select TSP response file:</label> <input type="file" id="temp_file" title="TSP response" /> </p> <p><span class="type">Response status:</span> <span id="resp-status"></span></p> <p><span class="type">TST info policy:</span> <span id="resp-policy"></span></p> <div id="resp-impr" class="two-col"> <p class="subject">TST info imprint:</p> <table id="resp-imprint"><tr><th>Hash algorithm</th><th>Hash value</th></tr></table> </div> <p><span class="type">TST info serial:</span> <span id="resp-serial"></span></p> <p><span class="type">TST info gen. time:</span> <span id="resp-time"></span></p> <div id="resp-accur" class="two-col" style="display:none;"> <p class="subject">TST info accuracy:</p> <table id="resp-accuracy"><tr><th>Seconds</th><th>Milliseconds</th><th>Microseconds</th></tr></table> </div> <p id="resp-ord" style="display:none;"><span class="type">TST info has ordering:</span> <span id="resp-ordering"></span></p> <p id="resp-non" style="display:none;"><span class="type">TST info nonce value:</span> <span id="resp-nonce"></span></p> <div id="resp-ts-rdn" class="two-col" style="display:none;"> <p class="subject">TST info TSA:</p> <table id="resp-tsa"><tr><th>RDN OID</th><th>RDN value</th></tr></table> </div> <p id="resp-ts-simpl" style="display:none;"><span class="type">TST info TSA:</span> <span id="resp-tsa-simpl"></span></p> <div id="resp-ext" class="two-col" style="display:none;"> <p class="subject">TST info extensions:</p> <table id="resp-extensions"><tr><th>Extension OID</th></tr></table> </div> </div> <p class="header-block">Verify loaded/created TSP response</p> <div class="border-block"> <p> <label for="ca_bundle">Load "CA bundle":</label> <input type="file" id="ca_bundle" title="Input file" /> </p> <a onclick="verify_TSP_resp();">Verify</a> </div> </div> <script> document.getElementById('temp_file').addEventListener('change', handleFileBrowse, false); document.getElementById('ca_bundle').addEventListener('change', handleCABundle, false); </script> </body> </html>