1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/manager/pki/resources/content/viewCertDetails.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,306 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +const nsIX509Cert = Components.interfaces.nsIX509Cert; 1.9 +const nsIX509Cert3 = Components.interfaces.nsIX509Cert3; 1.10 +const nsX509CertDB = "@mozilla.org/security/x509certdb;1"; 1.11 +const nsIX509CertDB = Components.interfaces.nsIX509CertDB; 1.12 +const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1"; 1.13 +const nsIPK11TokenDB = Components.interfaces.nsIPK11TokenDB; 1.14 +const nsIPKIParamBlock = Components.interfaces.nsIPKIParamBlock; 1.15 +const nsIASN1Object = Components.interfaces.nsIASN1Object; 1.16 +const nsIASN1Sequence = Components.interfaces.nsIASN1Sequence; 1.17 +const nsIASN1PrintableItem = Components.interfaces.nsIASN1PrintableItem; 1.18 +const nsIASN1Tree = Components.interfaces.nsIASN1Tree; 1.19 +const nsASN1Tree = "@mozilla.org/security/nsASN1Tree;1" 1.20 + 1.21 +var bundle; 1.22 + 1.23 +function doPrompt(msg) 1.24 +{ 1.25 + let prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]. 1.26 + getService(Components.interfaces.nsIPromptService); 1.27 + prompts.alert(window, null, msg); 1.28 +} 1.29 + 1.30 +function AddCertChain(node, chain, idPrefix) 1.31 +{ 1.32 + var idfier = idPrefix+"chain_"; 1.33 + var child = document.getElementById(node); 1.34 + var numCerts = chain.length; 1.35 + var currCert; 1.36 + var displayVal; 1.37 + var addTwistie; 1.38 + for (var i=numCerts-1; i>=0; i--) { 1.39 + currCert = chain.queryElementAt(i, nsIX509Cert); 1.40 + if (currCert.commonName) { 1.41 + displayVal = currCert.commonName; 1.42 + } else { 1.43 + displayVal = currCert.windowTitle; 1.44 + } 1.45 + if (0 == i) { 1.46 + addTwistie = false; 1.47 + } else { 1.48 + addTwistie = true; 1.49 + } 1.50 + child = addChildrenToTree(child, displayVal, currCert.dbKey,addTwistie); 1.51 + } 1.52 +} 1.53 + 1.54 +function AddUsage(usage,verifyInfoBox) 1.55 +{ 1.56 + var text = document.createElement("textbox"); 1.57 + text.setAttribute("value", usage); 1.58 + text.setAttribute("style", "margin: 2px 5px"); 1.59 + text.setAttribute("readonly", "true"); 1.60 + text.setAttribute("class", "scrollfield"); 1.61 + verifyInfoBox.appendChild(text); 1.62 +} 1.63 + 1.64 +function setWindowName() 1.65 +{ 1.66 + // Get the cert from the cert database 1.67 + var certdb = Components.classes[nsX509CertDB].getService(nsIX509CertDB); 1.68 + var myName = self.name; 1.69 + bundle = document.getElementById("pippki_bundle"); 1.70 + var cert; 1.71 + 1.72 + var certDetails = bundle.getString('certDetails'); 1.73 + if (myName != "") { 1.74 + document.title = certDetails + '"' + myName + '"'; // XXX l10n? 1.75 + // Get the token 1.76 + // XXX ignore this for now. NSS will find the cert on a token 1.77 + // by "tokenname:certname", which is what we have. 1.78 + //var tokenName = ""; 1.79 + //var pk11db = Components.classes[nsPK11TokenDB].getService(nsIPK11TokenDB); 1.80 + //var token = pk11db.findTokenByName(tokenName); 1.81 + 1.82 + //var cert = certdb.findCertByNickname(token, myName); 1.83 + cert = certdb.findCertByNickname(null, myName); 1.84 + } else { 1.85 + var pkiParams = window.arguments[0].QueryInterface(nsIPKIParamBlock); 1.86 + var isupport = pkiParams.getISupportAtIndex(1); 1.87 + cert = isupport.QueryInterface(nsIX509Cert); 1.88 + document.title = certDetails + '"' + cert.windowTitle + '"'; // XXX l10n? 1.89 + } 1.90 + 1.91 + // 1.92 + // Set the cert attributes for viewing 1.93 + // 1.94 + 1.95 + // The chain of trust 1.96 + var chain = cert.getChain(); 1.97 + AddCertChain("treesetDump", chain, "dump_"); 1.98 + DisplayGeneralDataFromCert(cert); 1.99 + BuildPrettyPrint(cert); 1.100 + 1.101 + if (cert instanceof nsIX509Cert3) 1.102 + { 1.103 + cert.requestUsagesArrayAsync(new listener()); 1.104 + } 1.105 +} 1.106 + 1.107 + 1.108 +function addChildrenToTree(parentTree,label,value,addTwistie) 1.109 +{ 1.110 + var treeChild1 = document.createElement("treechildren"); 1.111 + var treeElement = addTreeItemToTreeChild(treeChild1,label,value,addTwistie); 1.112 + parentTree.appendChild(treeChild1); 1.113 + return treeElement; 1.114 +} 1.115 + 1.116 +function addTreeItemToTreeChild(treeChild,label,value,addTwistie) 1.117 +{ 1.118 + var treeElem1 = document.createElement("treeitem"); 1.119 + if (addTwistie) { 1.120 + treeElem1.setAttribute("container","true"); 1.121 + treeElem1.setAttribute("open","true"); 1.122 + } 1.123 + var treeRow = document.createElement("treerow"); 1.124 + var treeCell = document.createElement("treecell"); 1.125 + treeCell.setAttribute("label",label); 1.126 + if (value) 1.127 + treeCell.setAttribute("display",value); 1.128 + treeRow.appendChild(treeCell); 1.129 + treeElem1.appendChild(treeRow); 1.130 + treeChild.appendChild(treeElem1); 1.131 + return treeElem1; 1.132 +} 1.133 + 1.134 +function displaySelected() { 1.135 + var asn1Tree = document.getElementById('prettyDumpTree'). 1.136 + treeBoxObject.view.QueryInterface(nsIASN1Tree); 1.137 + var items = asn1Tree.selection; 1.138 + var certDumpVal = document.getElementById('certDumpVal'); 1.139 + if (items.currentIndex != -1) { 1.140 + var value = asn1Tree.getDisplayData(items.currentIndex); 1.141 + certDumpVal.value = value; 1.142 + } else { 1.143 + certDumpVal.value =""; 1.144 + } 1.145 +} 1.146 + 1.147 +function BuildPrettyPrint(cert) 1.148 +{ 1.149 + var certDumpTree = Components.classes[nsASN1Tree]. 1.150 + createInstance(nsIASN1Tree); 1.151 + certDumpTree.loadASN1Structure(cert.ASN1Structure); 1.152 + document.getElementById('prettyDumpTree'). 1.153 + treeBoxObject.view = certDumpTree; 1.154 +} 1.155 + 1.156 +function addAttributeFromCert(nodeName, value) 1.157 +{ 1.158 + var node = document.getElementById(nodeName); 1.159 + if (!value) { 1.160 + value = bundle.getString('notPresent'); 1.161 + } 1.162 + node.setAttribute('value', value); 1.163 +} 1.164 + 1.165 + 1.166 + 1.167 +function listener() { 1.168 +} 1.169 + 1.170 +listener.prototype.QueryInterface = 1.171 + function(iid) { 1.172 + if (iid.equals(Components.interfaces.nsISupports) || 1.173 + iid.equals(Components.interfaces.nsICertVerificationListener)) 1.174 + return this; 1.175 + 1.176 + throw Components.results.NS_ERROR_NO_INTERFACE; 1.177 + } 1.178 + 1.179 +listener.prototype.notify = 1.180 + function(cert, result) { 1.181 + DisplayVerificationData(cert, result); 1.182 + } 1.183 + 1.184 +function DisplayVerificationData(cert, result) 1.185 +{ 1.186 + document.getElementById("verify_pending").setAttribute("hidden", "true"); 1.187 + 1.188 + if (!result || !cert) 1.189 + return; // no results could be produced 1.190 + 1.191 + if (!(cert instanceof Components.interfaces.nsIX509Cert)) 1.192 + return; 1.193 + 1.194 + // Verification and usage 1.195 + var verifystr = ""; 1.196 + var o1 = {}; 1.197 + var o2 = {}; 1.198 + var o3 = {}; 1.199 + 1.200 + if (!(result instanceof Components.interfaces.nsICertVerificationResult)) 1.201 + return; 1.202 + 1.203 + result.getUsagesArrayResult(o1, o2, o3); 1.204 + 1.205 + var verifystate = o1.value; 1.206 + var count = o2.value; 1.207 + var usageList = o3.value; 1.208 + if (verifystate == cert.VERIFIED_OK) { 1.209 + verifystr = bundle.getString('certVerified'); 1.210 + } else if (verifystate == cert.CERT_REVOKED) { 1.211 + verifystr = bundle.getString('certNotVerified_CertRevoked'); 1.212 + } else if (verifystate == cert.CERT_EXPIRED) { 1.213 + verifystr = bundle.getString('certNotVerified_CertExpired'); 1.214 + } else if (verifystate == cert.CERT_NOT_TRUSTED) { 1.215 + verifystr = bundle.getString('certNotVerified_CertNotTrusted'); 1.216 + } else if (verifystate == cert.ISSUER_NOT_TRUSTED) { 1.217 + verifystr = bundle.getString('certNotVerified_IssuerNotTrusted'); 1.218 + } else if (verifystate == cert.ISSUER_UNKNOWN) { 1.219 + verifystr = bundle.getString('certNotVerified_IssuerUnknown'); 1.220 + } else if (verifystate == cert.INVALID_CA) { 1.221 + verifystr = bundle.getString('certNotVerified_CAInvalid'); 1.222 + } else if (verifystate == cert.SIGNATURE_ALGORITHM_DISABLED) { 1.223 + verifystr = bundle.getString('certNotVerified_AlgorithmDisabled'); 1.224 + } else { /* if (verifystate == cert.NOT_VERIFIED_UNKNOWN || == USAGE_NOT_ALLOWED) */ 1.225 + verifystr = bundle.getString('certNotVerified_Unknown'); 1.226 + } 1.227 + var verified=document.getElementById('verified'); 1.228 + verified.textContent = verifystr; 1.229 + if (count > 0) { 1.230 + var verifyInfoBox = document.getElementById('verify_info_box'); 1.231 + for (var i=0; i<count; i++) { 1.232 + AddUsage(usageList[i],verifyInfoBox); 1.233 + } 1.234 + } 1.235 +} 1.236 + 1.237 +function DisplayGeneralDataFromCert(cert) 1.238 +{ 1.239 + // Common Name 1.240 + addAttributeFromCert('commonname', cert.commonName); 1.241 + // Organization 1.242 + addAttributeFromCert('organization', cert.organization); 1.243 + // Organizational Unit 1.244 + addAttributeFromCert('orgunit', cert.organizationalUnit); 1.245 + // Serial Number 1.246 + addAttributeFromCert('serialnumber',cert.serialNumber); 1.247 + // SHA1 Fingerprint 1.248 + addAttributeFromCert('sha1fingerprint',cert.sha1Fingerprint); 1.249 + // MD5 Fingerprint 1.250 + addAttributeFromCert('md5fingerprint',cert.md5Fingerprint); 1.251 + // Validity start 1.252 + addAttributeFromCert('validitystart', cert.validity.notBeforeLocalDay); 1.253 + // Validity end 1.254 + addAttributeFromCert('validityend', cert.validity.notAfterLocalDay); 1.255 + 1.256 + //Now to populate the fields that correspond to the issuer. 1.257 + var issuerCommonname, issuerOrg, issuerOrgUnit; 1.258 + issuerCommonname = cert.issuerCommonName; 1.259 + issuerOrg = cert.issuerOrganization; 1.260 + issuerOrgUnit = cert.issuerOrganizationUnit; 1.261 + addAttributeFromCert('issuercommonname', issuerCommonname); 1.262 + addAttributeFromCert('issuerorganization', issuerOrg); 1.263 + addAttributeFromCert('issuerorgunit', issuerOrgUnit); 1.264 +} 1.265 + 1.266 +function updateCertDump() 1.267 +{ 1.268 + var asn1Tree = document.getElementById('prettyDumpTree'). 1.269 + treeBoxObject.view.QueryInterface(nsIASN1Tree); 1.270 + 1.271 + var tree = document.getElementById('treesetDump'); 1.272 + if (tree.currentIndex < 0) { 1.273 + doPrompt("No items are selected."); //This should never happen. 1.274 + } else { 1.275 + var item = tree.contentView.getItemAtIndex(tree.currentIndex); 1.276 + var dbKey = item.firstChild.firstChild.getAttribute('display'); 1.277 + // Get the cert from the cert database 1.278 + var certdb = Components.classes[nsX509CertDB].getService(nsIX509CertDB); 1.279 + var cert = certdb.findCertByDBKey(dbKey,null); 1.280 + asn1Tree.loadASN1Structure(cert.ASN1Structure); 1.281 + } 1.282 + displaySelected(); 1.283 +} 1.284 + 1.285 +function getCurrentCert() 1.286 +{ 1.287 + var realIndex; 1.288 + var tree = document.getElementById('treesetDump'); 1.289 + if (tree.view.selection.isSelected(tree.currentIndex) 1.290 + && document.getElementById('prettyprint_tab').selected) { 1.291 + /* if the user manually selected a cert on the Details tab, 1.292 + then take that one */ 1.293 + realIndex = tree.currentIndex; 1.294 + } else { 1.295 + /* otherwise, take the one at the bottom of the chain 1.296 + (i.e. the one of the end-entity, unless we're displaying 1.297 + CA certs) */ 1.298 + realIndex = tree.view.rowCount - 1; 1.299 + } 1.300 + if (realIndex >= 0) { 1.301 + var item = tree.contentView.getItemAtIndex(realIndex); 1.302 + var dbKey = item.firstChild.firstChild.getAttribute('display'); 1.303 + var certdb = Components.classes[nsX509CertDB].getService(nsIX509CertDB); 1.304 + var cert = certdb.findCertByDBKey(dbKey,null); 1.305 + return cert; 1.306 + } 1.307 + /* shouldn't really happen */ 1.308 + return null; 1.309 +}