Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | const nsIX509Cert = Components.interfaces.nsIX509Cert; |
michael@0 | 6 | const nsIX509Cert3 = Components.interfaces.nsIX509Cert3; |
michael@0 | 7 | const nsX509CertDB = "@mozilla.org/security/x509certdb;1"; |
michael@0 | 8 | const nsIX509CertDB = Components.interfaces.nsIX509CertDB; |
michael@0 | 9 | const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1"; |
michael@0 | 10 | const nsIPK11TokenDB = Components.interfaces.nsIPK11TokenDB; |
michael@0 | 11 | const nsIPKIParamBlock = Components.interfaces.nsIPKIParamBlock; |
michael@0 | 12 | const nsIASN1Object = Components.interfaces.nsIASN1Object; |
michael@0 | 13 | const nsIASN1Sequence = Components.interfaces.nsIASN1Sequence; |
michael@0 | 14 | const nsIASN1PrintableItem = Components.interfaces.nsIASN1PrintableItem; |
michael@0 | 15 | const nsIASN1Tree = Components.interfaces.nsIASN1Tree; |
michael@0 | 16 | const nsASN1Tree = "@mozilla.org/security/nsASN1Tree;1" |
michael@0 | 17 | |
michael@0 | 18 | var bundle; |
michael@0 | 19 | |
michael@0 | 20 | function doPrompt(msg) |
michael@0 | 21 | { |
michael@0 | 22 | let prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]. |
michael@0 | 23 | getService(Components.interfaces.nsIPromptService); |
michael@0 | 24 | prompts.alert(window, null, msg); |
michael@0 | 25 | } |
michael@0 | 26 | |
michael@0 | 27 | function AddCertChain(node, chain, idPrefix) |
michael@0 | 28 | { |
michael@0 | 29 | var idfier = idPrefix+"chain_"; |
michael@0 | 30 | var child = document.getElementById(node); |
michael@0 | 31 | var numCerts = chain.length; |
michael@0 | 32 | var currCert; |
michael@0 | 33 | var displayVal; |
michael@0 | 34 | var addTwistie; |
michael@0 | 35 | for (var i=numCerts-1; i>=0; i--) { |
michael@0 | 36 | currCert = chain.queryElementAt(i, nsIX509Cert); |
michael@0 | 37 | if (currCert.commonName) { |
michael@0 | 38 | displayVal = currCert.commonName; |
michael@0 | 39 | } else { |
michael@0 | 40 | displayVal = currCert.windowTitle; |
michael@0 | 41 | } |
michael@0 | 42 | if (0 == i) { |
michael@0 | 43 | addTwistie = false; |
michael@0 | 44 | } else { |
michael@0 | 45 | addTwistie = true; |
michael@0 | 46 | } |
michael@0 | 47 | child = addChildrenToTree(child, displayVal, currCert.dbKey,addTwistie); |
michael@0 | 48 | } |
michael@0 | 49 | } |
michael@0 | 50 | |
michael@0 | 51 | function AddUsage(usage,verifyInfoBox) |
michael@0 | 52 | { |
michael@0 | 53 | var text = document.createElement("textbox"); |
michael@0 | 54 | text.setAttribute("value", usage); |
michael@0 | 55 | text.setAttribute("style", "margin: 2px 5px"); |
michael@0 | 56 | text.setAttribute("readonly", "true"); |
michael@0 | 57 | text.setAttribute("class", "scrollfield"); |
michael@0 | 58 | verifyInfoBox.appendChild(text); |
michael@0 | 59 | } |
michael@0 | 60 | |
michael@0 | 61 | function setWindowName() |
michael@0 | 62 | { |
michael@0 | 63 | // Get the cert from the cert database |
michael@0 | 64 | var certdb = Components.classes[nsX509CertDB].getService(nsIX509CertDB); |
michael@0 | 65 | var myName = self.name; |
michael@0 | 66 | bundle = document.getElementById("pippki_bundle"); |
michael@0 | 67 | var cert; |
michael@0 | 68 | |
michael@0 | 69 | var certDetails = bundle.getString('certDetails'); |
michael@0 | 70 | if (myName != "") { |
michael@0 | 71 | document.title = certDetails + '"' + myName + '"'; // XXX l10n? |
michael@0 | 72 | // Get the token |
michael@0 | 73 | // XXX ignore this for now. NSS will find the cert on a token |
michael@0 | 74 | // by "tokenname:certname", which is what we have. |
michael@0 | 75 | //var tokenName = ""; |
michael@0 | 76 | //var pk11db = Components.classes[nsPK11TokenDB].getService(nsIPK11TokenDB); |
michael@0 | 77 | //var token = pk11db.findTokenByName(tokenName); |
michael@0 | 78 | |
michael@0 | 79 | //var cert = certdb.findCertByNickname(token, myName); |
michael@0 | 80 | cert = certdb.findCertByNickname(null, myName); |
michael@0 | 81 | } else { |
michael@0 | 82 | var pkiParams = window.arguments[0].QueryInterface(nsIPKIParamBlock); |
michael@0 | 83 | var isupport = pkiParams.getISupportAtIndex(1); |
michael@0 | 84 | cert = isupport.QueryInterface(nsIX509Cert); |
michael@0 | 85 | document.title = certDetails + '"' + cert.windowTitle + '"'; // XXX l10n? |
michael@0 | 86 | } |
michael@0 | 87 | |
michael@0 | 88 | // |
michael@0 | 89 | // Set the cert attributes for viewing |
michael@0 | 90 | // |
michael@0 | 91 | |
michael@0 | 92 | // The chain of trust |
michael@0 | 93 | var chain = cert.getChain(); |
michael@0 | 94 | AddCertChain("treesetDump", chain, "dump_"); |
michael@0 | 95 | DisplayGeneralDataFromCert(cert); |
michael@0 | 96 | BuildPrettyPrint(cert); |
michael@0 | 97 | |
michael@0 | 98 | if (cert instanceof nsIX509Cert3) |
michael@0 | 99 | { |
michael@0 | 100 | cert.requestUsagesArrayAsync(new listener()); |
michael@0 | 101 | } |
michael@0 | 102 | } |
michael@0 | 103 | |
michael@0 | 104 | |
michael@0 | 105 | function addChildrenToTree(parentTree,label,value,addTwistie) |
michael@0 | 106 | { |
michael@0 | 107 | var treeChild1 = document.createElement("treechildren"); |
michael@0 | 108 | var treeElement = addTreeItemToTreeChild(treeChild1,label,value,addTwistie); |
michael@0 | 109 | parentTree.appendChild(treeChild1); |
michael@0 | 110 | return treeElement; |
michael@0 | 111 | } |
michael@0 | 112 | |
michael@0 | 113 | function addTreeItemToTreeChild(treeChild,label,value,addTwistie) |
michael@0 | 114 | { |
michael@0 | 115 | var treeElem1 = document.createElement("treeitem"); |
michael@0 | 116 | if (addTwistie) { |
michael@0 | 117 | treeElem1.setAttribute("container","true"); |
michael@0 | 118 | treeElem1.setAttribute("open","true"); |
michael@0 | 119 | } |
michael@0 | 120 | var treeRow = document.createElement("treerow"); |
michael@0 | 121 | var treeCell = document.createElement("treecell"); |
michael@0 | 122 | treeCell.setAttribute("label",label); |
michael@0 | 123 | if (value) |
michael@0 | 124 | treeCell.setAttribute("display",value); |
michael@0 | 125 | treeRow.appendChild(treeCell); |
michael@0 | 126 | treeElem1.appendChild(treeRow); |
michael@0 | 127 | treeChild.appendChild(treeElem1); |
michael@0 | 128 | return treeElem1; |
michael@0 | 129 | } |
michael@0 | 130 | |
michael@0 | 131 | function displaySelected() { |
michael@0 | 132 | var asn1Tree = document.getElementById('prettyDumpTree'). |
michael@0 | 133 | treeBoxObject.view.QueryInterface(nsIASN1Tree); |
michael@0 | 134 | var items = asn1Tree.selection; |
michael@0 | 135 | var certDumpVal = document.getElementById('certDumpVal'); |
michael@0 | 136 | if (items.currentIndex != -1) { |
michael@0 | 137 | var value = asn1Tree.getDisplayData(items.currentIndex); |
michael@0 | 138 | certDumpVal.value = value; |
michael@0 | 139 | } else { |
michael@0 | 140 | certDumpVal.value =""; |
michael@0 | 141 | } |
michael@0 | 142 | } |
michael@0 | 143 | |
michael@0 | 144 | function BuildPrettyPrint(cert) |
michael@0 | 145 | { |
michael@0 | 146 | var certDumpTree = Components.classes[nsASN1Tree]. |
michael@0 | 147 | createInstance(nsIASN1Tree); |
michael@0 | 148 | certDumpTree.loadASN1Structure(cert.ASN1Structure); |
michael@0 | 149 | document.getElementById('prettyDumpTree'). |
michael@0 | 150 | treeBoxObject.view = certDumpTree; |
michael@0 | 151 | } |
michael@0 | 152 | |
michael@0 | 153 | function addAttributeFromCert(nodeName, value) |
michael@0 | 154 | { |
michael@0 | 155 | var node = document.getElementById(nodeName); |
michael@0 | 156 | if (!value) { |
michael@0 | 157 | value = bundle.getString('notPresent'); |
michael@0 | 158 | } |
michael@0 | 159 | node.setAttribute('value', value); |
michael@0 | 160 | } |
michael@0 | 161 | |
michael@0 | 162 | |
michael@0 | 163 | |
michael@0 | 164 | function listener() { |
michael@0 | 165 | } |
michael@0 | 166 | |
michael@0 | 167 | listener.prototype.QueryInterface = |
michael@0 | 168 | function(iid) { |
michael@0 | 169 | if (iid.equals(Components.interfaces.nsISupports) || |
michael@0 | 170 | iid.equals(Components.interfaces.nsICertVerificationListener)) |
michael@0 | 171 | return this; |
michael@0 | 172 | |
michael@0 | 173 | throw Components.results.NS_ERROR_NO_INTERFACE; |
michael@0 | 174 | } |
michael@0 | 175 | |
michael@0 | 176 | listener.prototype.notify = |
michael@0 | 177 | function(cert, result) { |
michael@0 | 178 | DisplayVerificationData(cert, result); |
michael@0 | 179 | } |
michael@0 | 180 | |
michael@0 | 181 | function DisplayVerificationData(cert, result) |
michael@0 | 182 | { |
michael@0 | 183 | document.getElementById("verify_pending").setAttribute("hidden", "true"); |
michael@0 | 184 | |
michael@0 | 185 | if (!result || !cert) |
michael@0 | 186 | return; // no results could be produced |
michael@0 | 187 | |
michael@0 | 188 | if (!(cert instanceof Components.interfaces.nsIX509Cert)) |
michael@0 | 189 | return; |
michael@0 | 190 | |
michael@0 | 191 | // Verification and usage |
michael@0 | 192 | var verifystr = ""; |
michael@0 | 193 | var o1 = {}; |
michael@0 | 194 | var o2 = {}; |
michael@0 | 195 | var o3 = {}; |
michael@0 | 196 | |
michael@0 | 197 | if (!(result instanceof Components.interfaces.nsICertVerificationResult)) |
michael@0 | 198 | return; |
michael@0 | 199 | |
michael@0 | 200 | result.getUsagesArrayResult(o1, o2, o3); |
michael@0 | 201 | |
michael@0 | 202 | var verifystate = o1.value; |
michael@0 | 203 | var count = o2.value; |
michael@0 | 204 | var usageList = o3.value; |
michael@0 | 205 | if (verifystate == cert.VERIFIED_OK) { |
michael@0 | 206 | verifystr = bundle.getString('certVerified'); |
michael@0 | 207 | } else if (verifystate == cert.CERT_REVOKED) { |
michael@0 | 208 | verifystr = bundle.getString('certNotVerified_CertRevoked'); |
michael@0 | 209 | } else if (verifystate == cert.CERT_EXPIRED) { |
michael@0 | 210 | verifystr = bundle.getString('certNotVerified_CertExpired'); |
michael@0 | 211 | } else if (verifystate == cert.CERT_NOT_TRUSTED) { |
michael@0 | 212 | verifystr = bundle.getString('certNotVerified_CertNotTrusted'); |
michael@0 | 213 | } else if (verifystate == cert.ISSUER_NOT_TRUSTED) { |
michael@0 | 214 | verifystr = bundle.getString('certNotVerified_IssuerNotTrusted'); |
michael@0 | 215 | } else if (verifystate == cert.ISSUER_UNKNOWN) { |
michael@0 | 216 | verifystr = bundle.getString('certNotVerified_IssuerUnknown'); |
michael@0 | 217 | } else if (verifystate == cert.INVALID_CA) { |
michael@0 | 218 | verifystr = bundle.getString('certNotVerified_CAInvalid'); |
michael@0 | 219 | } else if (verifystate == cert.SIGNATURE_ALGORITHM_DISABLED) { |
michael@0 | 220 | verifystr = bundle.getString('certNotVerified_AlgorithmDisabled'); |
michael@0 | 221 | } else { /* if (verifystate == cert.NOT_VERIFIED_UNKNOWN || == USAGE_NOT_ALLOWED) */ |
michael@0 | 222 | verifystr = bundle.getString('certNotVerified_Unknown'); |
michael@0 | 223 | } |
michael@0 | 224 | var verified=document.getElementById('verified'); |
michael@0 | 225 | verified.textContent = verifystr; |
michael@0 | 226 | if (count > 0) { |
michael@0 | 227 | var verifyInfoBox = document.getElementById('verify_info_box'); |
michael@0 | 228 | for (var i=0; i<count; i++) { |
michael@0 | 229 | AddUsage(usageList[i],verifyInfoBox); |
michael@0 | 230 | } |
michael@0 | 231 | } |
michael@0 | 232 | } |
michael@0 | 233 | |
michael@0 | 234 | function DisplayGeneralDataFromCert(cert) |
michael@0 | 235 | { |
michael@0 | 236 | // Common Name |
michael@0 | 237 | addAttributeFromCert('commonname', cert.commonName); |
michael@0 | 238 | // Organization |
michael@0 | 239 | addAttributeFromCert('organization', cert.organization); |
michael@0 | 240 | // Organizational Unit |
michael@0 | 241 | addAttributeFromCert('orgunit', cert.organizationalUnit); |
michael@0 | 242 | // Serial Number |
michael@0 | 243 | addAttributeFromCert('serialnumber',cert.serialNumber); |
michael@0 | 244 | // SHA1 Fingerprint |
michael@0 | 245 | addAttributeFromCert('sha1fingerprint',cert.sha1Fingerprint); |
michael@0 | 246 | // MD5 Fingerprint |
michael@0 | 247 | addAttributeFromCert('md5fingerprint',cert.md5Fingerprint); |
michael@0 | 248 | // Validity start |
michael@0 | 249 | addAttributeFromCert('validitystart', cert.validity.notBeforeLocalDay); |
michael@0 | 250 | // Validity end |
michael@0 | 251 | addAttributeFromCert('validityend', cert.validity.notAfterLocalDay); |
michael@0 | 252 | |
michael@0 | 253 | //Now to populate the fields that correspond to the issuer. |
michael@0 | 254 | var issuerCommonname, issuerOrg, issuerOrgUnit; |
michael@0 | 255 | issuerCommonname = cert.issuerCommonName; |
michael@0 | 256 | issuerOrg = cert.issuerOrganization; |
michael@0 | 257 | issuerOrgUnit = cert.issuerOrganizationUnit; |
michael@0 | 258 | addAttributeFromCert('issuercommonname', issuerCommonname); |
michael@0 | 259 | addAttributeFromCert('issuerorganization', issuerOrg); |
michael@0 | 260 | addAttributeFromCert('issuerorgunit', issuerOrgUnit); |
michael@0 | 261 | } |
michael@0 | 262 | |
michael@0 | 263 | function updateCertDump() |
michael@0 | 264 | { |
michael@0 | 265 | var asn1Tree = document.getElementById('prettyDumpTree'). |
michael@0 | 266 | treeBoxObject.view.QueryInterface(nsIASN1Tree); |
michael@0 | 267 | |
michael@0 | 268 | var tree = document.getElementById('treesetDump'); |
michael@0 | 269 | if (tree.currentIndex < 0) { |
michael@0 | 270 | doPrompt("No items are selected."); //This should never happen. |
michael@0 | 271 | } else { |
michael@0 | 272 | var item = tree.contentView.getItemAtIndex(tree.currentIndex); |
michael@0 | 273 | var dbKey = item.firstChild.firstChild.getAttribute('display'); |
michael@0 | 274 | // Get the cert from the cert database |
michael@0 | 275 | var certdb = Components.classes[nsX509CertDB].getService(nsIX509CertDB); |
michael@0 | 276 | var cert = certdb.findCertByDBKey(dbKey,null); |
michael@0 | 277 | asn1Tree.loadASN1Structure(cert.ASN1Structure); |
michael@0 | 278 | } |
michael@0 | 279 | displaySelected(); |
michael@0 | 280 | } |
michael@0 | 281 | |
michael@0 | 282 | function getCurrentCert() |
michael@0 | 283 | { |
michael@0 | 284 | var realIndex; |
michael@0 | 285 | var tree = document.getElementById('treesetDump'); |
michael@0 | 286 | if (tree.view.selection.isSelected(tree.currentIndex) |
michael@0 | 287 | && document.getElementById('prettyprint_tab').selected) { |
michael@0 | 288 | /* if the user manually selected a cert on the Details tab, |
michael@0 | 289 | then take that one */ |
michael@0 | 290 | realIndex = tree.currentIndex; |
michael@0 | 291 | } else { |
michael@0 | 292 | /* otherwise, take the one at the bottom of the chain |
michael@0 | 293 | (i.e. the one of the end-entity, unless we're displaying |
michael@0 | 294 | CA certs) */ |
michael@0 | 295 | realIndex = tree.view.rowCount - 1; |
michael@0 | 296 | } |
michael@0 | 297 | if (realIndex >= 0) { |
michael@0 | 298 | var item = tree.contentView.getItemAtIndex(realIndex); |
michael@0 | 299 | var dbKey = item.firstChild.firstChild.getAttribute('display'); |
michael@0 | 300 | var certdb = Components.classes[nsX509CertDB].getService(nsIX509CertDB); |
michael@0 | 301 | var cert = certdb.findCertByDBKey(dbKey,null); |
michael@0 | 302 | return cert; |
michael@0 | 303 | } |
michael@0 | 304 | /* shouldn't really happen */ |
michael@0 | 305 | return null; |
michael@0 | 306 | } |