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
423 lines (370 loc) • 16.5 kB
HTML
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>TSP request 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 #tsp-req-attributes{
margin:0;
padding:0;
float:left;
list-style:none;
}
.border-block .two-col #tsp-req-attributes li p{
margin:0;
}
.border-block .two-col #tsp-req-attributes li p span{
width:40px;
display:inline-block;
margin:0 0 5px;
}
.border-block .two-col #tsp-req-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 tspReqBuffer = new ArrayBuffer(0); // ArrayBuffer with loaded or created TSP request
var issuerCertificate = null;
var issuerPublicKey = null;
//*********************************************************************************
// #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;
temp_reader.onload =
function(event)
{
tspReqBuffer = event.target.result;
parse_TSP_req();
};
temp_reader.readAsArrayBuffer(current_files[0]);
}
//*********************************************************************************
function handleIssuerCert(evt)
{
var temp_reader = new FileReader();
var current_files = evt.target.files;
temp_reader.onload =
function(event)
{
try
{
issuerPublicKey = null;
var asn1 = org.pkijs.fromBER(event.target.result);
issuerCertificate = new org.pkijs.simpl.CERT({ schema: asn1.result });
}
catch(ex) { }
};
temp_reader.readAsArrayBuffer(current_files[0]);
}
//*********************************************************************************
// #endregion
//*********************************************************************************
// #region Create TSP request
//*********************************************************************************
function create_TSP_req(buffer)
{
// #region Initial variables
var sequence = Promise.resolve();
var tsp_req_simpl = new org.pkijs.simpl.TSP_REQUEST();
// #endregion
// #region Put static variables
var fictionBuffer = new ArrayBuffer(4);
var fictionView = new Uint8Array(fictionBuffer);
fictionView[0] = 0x7F;
fictionView[1] = 0x01;
fictionView[2] = 0x02;
fictionView[3] = 0x03;
tsp_req_simpl.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: fictionBuffer })
});
tsp_req_simpl.reqPolicy = "1.1.1";
tsp_req_simpl.certReq = new org.pkijs.asn1.BOOLEAN({ value: true });
tsp_req_simpl.nonce = new org.pkijs.asn1.INTEGER({ value_hex: fictionBuffer });
// #endregion
// #region Encode TSP request and put on the Web page
// #region Convert ArrayBuffer to String
var signed_data_string = "";
var tsp_req_schema = tsp_req_simpl.toSchema();
tspReqBuffer = tsp_req_schema.toBER(false);
var view = new Uint8Array(tspReqBuffer);
for(var i = 0; i < view.length; i++)
signed_data_string = signed_data_string + String.fromCharCode(view[i]);
// #endregion
var result_string = "";
result_string = result_string + "\r\n-----BEGIN TSP REQUEST-----\r\n";
result_string = result_string + formatPEM(window.btoa(signed_data_string));
result_string = result_string + "\r\n-----END TSP REQUEST-----\r\n\r\n";
document.getElementById("new_signed_data").innerHTML = result_string;
parse_TSP_req();
alert("TSP request has created successfully!");
// #endregion
}
//*********************************************************************************
// #endregion
//*********************************************************************************
// #region Parse existing TSP request
//*********************************************************************************
function parse_TSP_req()
{
// #region Initial check
if(tspReqBuffer.byteLength === 0)
{
alert("Nothing to parse!");
return;
}
// #endregion
// #region Initial activities
document.getElementById("tsp-req-extn-div").style.display = "none";
var imprintTable = document.getElementById("tsp-req-imprint");
while(imprintTable.rows.length > 1)
{
imprintTable.deleteRow(imprintTable.rows.length - 1);
}
var extensionTable = document.getElementById("tsp-req-extn-table");
while(extensionTable.rows.length > 1)
{
extensionTable.deleteRow(extensionTable.rows.length - 1);
}
// #endregion
// #region Decode existing TSP request
var asn1 = org.pkijs.fromBER(tspReqBuffer);
var tsp_req_simpl = new org.pkijs.simpl.TSP_REQUEST({ schema: asn1.result });
// #endregion
// #region Put information about 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[tsp_req_simpl.messageImprint.hashAlgorithm.algorithm_id];
if(typeof hashAlgorithm === "undefined")
hashAlgorithm = tsp_req_simpl.messageImprint.hashAlgorithm.algorithm_id;
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(tsp_req_simpl.messageImprint.hashedMessage.value_block.value_hex);
// #endregion
// #region Put information about policy
if("reqPolicy" in tsp_req_simpl)
{
document.getElementById("tsp-req-policy").innerHTML = tsp_req_simpl.reqPolicy;
document.getElementById("tsp-req-pol").style.display = "block";
}
// #endregion
// #region Put information about nonce
if("nonce" in tsp_req_simpl)
{
document.getElementById("tsp-req-nonce").innerHTML = org.pkijs.bufferToHexCodes(tsp_req_simpl.nonce.value_block.value_hex);
document.getElementById("tsp-req-non").style.display = "block";
}
// #endregion
// #region Put information about existence of "certReq" flag
if("certReq" in tsp_req_simpl)
{
document.getElementById("tsp-req-cert-req").innerHTML = tsp_req_simpl.certReq;
document.getElementById("tsp-req-cert").style.display = "block";
}
// #endregion
// #region Put information about TST info extensions
if("extensions" in tsp_req_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("tsp-req-extn-div").style.display = "block";
}
// #endregion
}
//*********************************************************************************
// #endregion
//*********************************************************************************
</script>
</head>
<body>
<div class="wrapper">
<p class="header-block">Create new TSP request</p>
<div id="output_div" class="border-block">
<label for="new_signed_data" style="font-weight:bold;float:left;">BASE-64 encoded new TSP request:</label>
<textarea id="new_signed_data">< New encoded TSP request will be stored here ></textarea>
<a onclick="create_TSP_req();">Create</a>
</div>
<p class="header-block">Parse loaded/created TSP request</p>
<div id="tsp-req-data-block" class="border-block">
<p>
<label for="tsp-req-file">Select TSP request file (binary):</label>
<input type="file" id="tsp-req-file" title="TSP request" />
</p>
<div id="tsp-req-imprint-div" class="two-col">
<p class="subject">Message imprint:</p>
<table id="tsp-req-imprint"><tr><th>Algorithm</th><th>Message</th></tr></table>
</div>
<p id="tsp-req-pol" style="display:none;"><span class="type">Policy:</span> <span id="tsp-req-policy"></span></p>
<p id="tsp-req-non" style="display:none;"><span class="type">Nonce:</span> <span id="tsp-req-nonce"></span></p>
<p id="tsp-req-cert" style="display:none;"><span class="type">Cert. req. exists:</span> <span id="tsp-req-cert-req"></span></p>
<div id="tsp-req-extn-div" class="two-col" style="display:none;">
<p class="subject">Extensions:</p>
<table id="tsp-req-extn-table"><tr><th>OID</th></tr></table>
</div>
</div>
</div>
<script>
document.getElementById('tsp-req-file').addEventListener('change', handleFileBrowse, false);
</script>
</body>
</html>