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
387 lines (356 loc) • 16.8 kB
HTML
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>How to decode a X.509 CRL</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>
<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;
}
#add-crl-block label{
display:block;
font:bold 18px/22px Helvetica, Arial, sans-serif;
margin:0 0 8px;
}
#pem-text-block{
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;
}
#add-crl-block a{
display:inline-block;
padding:5px 15px;
background:#ACD0EC;
border:solid 1px #4C6181;
color:#000;
font:normal 14px/16px Helvetica, Arial, sans-serif;
}
#add-crl-block a:hover{
background:#DAEBF8;
cursor:pointer;
}
#crl-data-block{
display:none;
border:solid 2px #999;
border-radius:5px;
-webkit-border-radius:5px;
margin:50px 0 0;
padding:20px 30px;
background:#F0F4FF;
}
#crl-data-block h2{
margin:0 0 16px;
font:bold 22px/24px Helvetica, Arial, sans-serif;
}
#crl-data-block p{
margin:0 0 12px;
}
#crl-data-block p .type{
font-weight:bold;
display:inline-block;
width:176px;
}
#crl-data-block .two-col{
overflow:hidden;
margin:0 0 16px;
}
#crl-data-block .two-col .issuer{
width:180px;
font-weight:bold;
margin:0 0 12px;
float:left;
}
#crl-data-block .two-col #crl-issuer{
margin:0;
padding:0;
float:left;
list-style:none;
}
#crl-data-block .two-col #crl-issuer li p{
margin:0;
}
#crl-data-block .two-col #crl-issuer li p span{
width:40px;
display:inline-block;
margin:0 0 5px;
}
#crl-data-block .two-col #crl-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 type="text/javascript">
function getCRLData()
{
// function to convert string to ArrayBuffer
function str2ab(str)
{
var buf = new ArrayBuffer(str.length);
var bufView = new Uint8Array(buf);
for(var i = 0, strLen = str.length; i < strLen; i++)
bufView[i] = str.charCodeAt(i);
return buf;
};
// function to convert serial from buffer array if needed
function toHexCodes(input_buffer)
{
var result = "";
var int_buffer = new Uint8Array(input_buffer);
for(var i = 0; i < int_buffer.length; i++)
{
var str = int_buffer[i].toString(16).toUpperCase();
result = result + ((str.length === 1) ? " 0" : " ") + str;
}
return result;
};
// remove any things in our table so we start clean
document.getElementById("crl-data-block").style.display = "none";
document.getElementById("crl-revokedCertificates").getElementsByTagName("tbody")[0].innerHTML = "";
document.getElementById("crl-issuer").innerHTML = "";
document.getElementById("issued").innerHTML="";
document.getElementById("expire").innerHTML="";
document.getElementById("sig-algo").innerHTML="";
document.getElementById("crl-exten").innerHTML = "";
// strip certificate header/footer from PEM
var CRLPEM = document.getElementById("pem-text-block").value.replace(/(-----(BEGIN|END) X509 CRL-----|\n)/g, ''),
CertBuf = str2ab(window.atob(CRLPEM)), // convert stripped PEM to ArrayBuffer
algomap = {
"1.2.840.113549.2.1": "MD2",
"1.2.840.113549.1.1.2": "MD2 with RSA",
"1.2.840.113549.2.5": "MD5",
"1.2.840.113549.1.1.4": "MD5 with RSA",
"1.3.14.3.2.26": "SHA1",
"1.2.840.10040.4.3": "SHA1 with DSA",
"1.2.840.10045.4.1": "SHA1 with ECDSA",
"1.2.840.113549.1.1.5": "SHA1 with RSA",
"2.16.840.1.101.3.4.2.4": "SHA224",
"1.2.840.113549.1.1.14": "SHA224 with RSA",
"2.16.840.1.101.3.4.2.1": "SHA256",
"1.2.840.113549.1.1.11": "SHA256 with RSA",
"2.16.840.1.101.3.4.2.2": "SHA384",
"1.2.840.113549.1.1.12": "SHA384 with RSA",
"2.16.840.1.101.3.4.2.3": "SHA512",
"1.2.840.113549.1.1.13": "SHA512 with RSA"
}; // array mapping of common algorithm OIDs and corresponding types
// calls to convert ArrayBuffer with encoded CRL to an object in the variable 'crl_simpl'
var asn1 = org.pkijs.fromBER(CertBuf);
var crl_simpl = new org.pkijs.simpl.CRL({ schema: asn1.result });
// #region Get information about CRL issuer
document.getElementById("crl-issuer").innerHTML = "";
// loop to get the issuer key and values
for(var i = 0; i < crl_simpl.issuer.types_and_values.length; i++)
{
// OID map
var typemap = {
"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" : "Email",
"0.9.2342.19200300.100.1.25" : "DC"
},
typeval = typemap[crl_simpl.issuer.types_and_values[i].type],
issuerval = crl_simpl.issuer.types_and_values[i].value.value_block.value,
ulrow = "<li><p><span>" + typeval + "</span> " + issuerval + "</p></li>";
document.getElementById("crl-issuer").innerHTML = document.getElementById("crl-issuer").innerHTML + ulrow;
if (typeval == "CN")
document.getElementById("crl-issuer-cn").innerHTML = issuerval;
}
// #endregion
// #region Working with CRL extensions
if (("crlExtensions" in crl_simpl) === false)
document.getElementById("crl-exten").innerHTML = "<li><p>None</p></li>";
else
{
// loop to get extensions
for(var i = 0; i < crl_simpl.crlExtensions.length; i++)
{
// OID map
var extenmap = {
"2.5.29.1": "old Authority Key Identifier",
"2.5.29.2": "old Primary Key Attributes",
"2.5.29.9": "issuer Directory Attributes",
"2.5.29.14": "issuer Key Identifier",
"2.5.29.20": "CRL Number",
"2.5.29.21": "Reason code",
"2.5.29.23": "Hold Instruction Code",
"2.5.29.24": "Invalidity Date",
"2.5.29.27": "Delta CRL indicator",
"2.5.29.28": "Issuing Distribution Point",
"2.5.29.29": "Certificate Issuer",
"2.5.29.31": "CRL Distribution Points",
"2.5.29.35": "Authority Key Identifier",
"2.5.29.46": "FreshestCRL",
"1.3.6.1.4.1.311.21.1": "Microsoft CA Version",
"1.3.6.1.4.1.311.21.4": "CRL Next Publish Date"
},
extenval = extenmap[crl_simpl.crlExtensions[i].extnID],
extenrow = "<li><p>"+extenval+"</p></li>";
document.getElementById("crl-exten").innerHTML = document.getElementById("crl-exten").innerHTML + extenrow;
};
};
// #endregion
if (("revokedCertificates" in crl_simpl) === false)
document.getElementById("crl-revokedCertificates").innerHTML = "None";
else
{
// loop to get revoked certificates
var rev_table = document.getElementById("crl-revokedCertificates").getElementsByTagName("tbody")[0];
for(var i = 0; i < crl_simpl.revokedCertificates.length; i++)
{
// #region Initial variables
var revokedSerial;
var revokedReason = "Not specified";
// #endregion
// #region Get the serial number of the revoked certificate
if(crl_simpl.revokedCertificates[i].userCertificate.value_block.is_hex_only == true)
revokedSerial = toHexCodes(crl_simpl.revokedCertificates[i].userCertificate.value_block.value_hex);
else
revokedSerial = crl_simpl.revokedCertificates[i].userCertificate.value_block.value_dec;
// #endregion
// #region Find a reason why the specific certificate was revoked
for(var j = 0; j < crl_simpl.revokedCertificates[i].crlEntryExtensions.length; j++)
{
if(crl_simpl.revokedCertificates[i].crlEntryExtensions[j].extnID === "2.5.29.21")
{
switch(crl_simpl.revokedCertificates[i].crlEntryExtensions[j].parsedValue.value_block.value_dec)
{
case 0:
revokedReason = "unused";
break;
case 1:
revokedReason = "keyCompromise";
break;
case 2:
revokedReason = "cACompromise";
break;
case 3:
revokedReason = "affiliationChanged";
break;
case 4:
revokedReason = "superseded";
break;
case 5:
revokedReason = "cessationOfOperation";
break;
case 6:
revokedReason = "certificateHold";
break;
case 7:
revokedReason = "privilegeWithdrawn";
break;
case 8:
revokedReason = "aACompromise";
break;
default:
revokedReason = "Unknown reason";
}
break;
}
}
// #endregion
var revokedDate = crl_simpl.revokedCertificates[i].revocationDate.value.toUTCString();
var row = rev_table.insertRow(rev_table.rows.length);
var cell1 = row.insertCell(0);
cell1.innerHTML = revokedSerial;
var cell2 = row.insertCell(1);
cell2.innerHTML = revokedDate;
var cell3 = row.insertCell(2);
cell3.innerHTML = revokedReason
};
}
// get issuance date
document.getElementById("issued").innerHTML = crl_simpl.thisUpdate.value.toUTCString();
// get expiration date
if (("nextUpdate" in crl_simpl) === false)
document.getElementById("expire").innerHTML = "None";
else
document.getElementById("expire").innerHTML = crl_simpl.nextUpdate.value.toUTCString();
// get signature algorithm
document.getElementById("sig-algo").innerHTML = algomap[crl_simpl.signatureAlgorithm.algorithm_id];
document.getElementById("crl-data-block").style.display = "block";
}
</script>
</head>
<body>
<div class="wrapper">
<div id="add-crl-block">
<label for="pem-text-block" style="font-weight:bold">Paste in CRL in PEM:</label>
<textarea id="pem-text-block" onClick="select();">-----BEGIN X509 CRL-----
MIIBbzCB2QIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UE
ChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rp
bmcxFTATBgNVBAMTDFRydXN0IEFuY2hvchcNOTkwMTAxMTIwMTAwWhcNNDgwMTAx
MTIwMTAwWjAiMCACAScXDTk5MDEwMTEyMDAwMFowDDAKBgNVHRUEAwoBAaAjMCEw
CgYDVR0UBAMCAQEwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcNAQEFBQAD
gYEAC7lqZwejJRW7QvzH11/7cYcL3racgMxH3PSU/ufvyLk7ahR++RtHary/WeCv
RdyznLiIOA8ZBiguWtVPqsNysNn7WLofQIVa+/TD3T+lece4e1NwGQvj5Q+e2wRt
GXg+gCuTjTKUFfKRnWz7O7RyiJKKim0jtAF4RkCpLebNChY=
-----END X509 CRL-----</textarea>
<a onClick="getCRLData();">Decode</a>
</div>
<!-- <div id="crl-data-block" style="display:none;">-->
<div id="crl-data-block">
<h2 id="crl-issuer-cn"></h2>
<div class="two-col">
<p class="issuer">Issuer:</p>
<ul id="crl-issuer"></ul>
</div>
<p><span class="type">Issuance Date:</span> <span id="issued"></span></p>
<p><span class="type">Expiration Date:</span> <span id="expire"></span></p>
<p><span class="type">Signature Algorithm:</span> <span id="sig-algo"></span></p>
<div class="two-col">
<p class="issuer">Extensions:</p>
<ul id="crl-exten"></ul>
</div>
<div class="two-col">
<p class="issuer">Revoked Certificates:</p>
<table id="crl-revokedCertificates"><thead><tr><th>Serial Number</th><th>Revocation Date</th><th>Revocation Reason</th></thead><tbody></tbody></table>
</div>
</div>
</div>
</body>
</html>