michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * These are helper functions to be included michael@0: * pippki UI js files. michael@0: */ michael@0: michael@0: function setText(id, value) { michael@0: var element = document.getElementById(id); michael@0: if (!element) return; michael@0: if (element.hasChildNodes()) michael@0: element.removeChild(element.firstChild); michael@0: var textNode = document.createTextNode(value); michael@0: element.appendChild(textNode); michael@0: } michael@0: michael@0: const nsICertificateDialogs = Components.interfaces.nsICertificateDialogs; michael@0: const nsCertificateDialogs = "@mozilla.org/nsCertificateDialogs;1" michael@0: michael@0: function viewCertHelper(parent, cert) { michael@0: if (!cert) michael@0: return; michael@0: michael@0: var cd = Components.classes[nsCertificateDialogs].getService(nsICertificateDialogs); michael@0: cd.viewCert(parent, cert); michael@0: } michael@0: michael@0: function getDERString(cert) michael@0: { michael@0: var length = {}; michael@0: var derArray = cert.getRawDER(length); michael@0: var derString = ''; michael@0: for (var i = 0; i < derArray.length; i++) { michael@0: derString += String.fromCharCode(derArray[i]); michael@0: } michael@0: return derString; michael@0: } michael@0: michael@0: function getPKCS7String(cert, chainMode) michael@0: { michael@0: var length = {}; michael@0: cert.QueryInterface(Components.interfaces.nsIX509Cert3); michael@0: var pkcs7Array = cert.exportAsCMS(chainMode, length); michael@0: var pkcs7String = ''; michael@0: for (var i = 0; i < pkcs7Array.length; i++) { michael@0: pkcs7String += String.fromCharCode(pkcs7Array[i]); michael@0: } michael@0: return pkcs7String; michael@0: } michael@0: michael@0: function getPEMString(cert) michael@0: { michael@0: var derb64 = btoa(getDERString(cert)); michael@0: // Wrap the Base64 string into lines of 64 characters, michael@0: // with CRLF line breaks (as specified in RFC 1421). michael@0: var wrapped = derb64.replace(/(\S{64}(?!$))/g, "$1\r\n"); michael@0: return "-----BEGIN CERTIFICATE-----\r\n" michael@0: + wrapped michael@0: + "\r\n-----END CERTIFICATE-----\r\n"; michael@0: } michael@0: michael@0: function alertPromptService(title, message) michael@0: { michael@0: var ps = null; michael@0: var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]. michael@0: getService(Components.interfaces.nsIPromptService); michael@0: ps.alert(window, title, message); michael@0: } michael@0: michael@0: function exportToFile(parent, cert) michael@0: { michael@0: var bundle = document.getElementById("pippki_bundle"); michael@0: if (!cert) michael@0: return; michael@0: michael@0: var nsIFilePicker = Components.interfaces.nsIFilePicker; michael@0: var fp = Components.classes["@mozilla.org/filepicker;1"]. michael@0: createInstance(nsIFilePicker); michael@0: fp.init(parent, bundle.getString("SaveCertAs"), michael@0: nsIFilePicker.modeSave); michael@0: var filename = cert.commonName; michael@0: if (!filename.length) michael@0: filename = cert.windowTitle; michael@0: // remove all whitespace from the default filename michael@0: fp.defaultString = filename.replace(/\s*/g,''); michael@0: fp.defaultExtension = "crt"; michael@0: fp.appendFilter(bundle.getString("CertFormatBase64"), "*.crt; *.pem"); michael@0: fp.appendFilter(bundle.getString("CertFormatBase64Chain"), "*.crt; *.pem"); michael@0: fp.appendFilter(bundle.getString("CertFormatDER"), "*.der"); michael@0: fp.appendFilter(bundle.getString("CertFormatPKCS7"), "*.p7c"); michael@0: fp.appendFilter(bundle.getString("CertFormatPKCS7Chain"), "*.p7c"); michael@0: fp.appendFilters(nsIFilePicker.filterAll); michael@0: var res = fp.show(); michael@0: if (res != nsIFilePicker.returnOK && res != nsIFilePicker.returnReplace) michael@0: return; michael@0: michael@0: var content = ''; michael@0: switch (fp.filterIndex) { michael@0: case 1: michael@0: content = getPEMString(cert); michael@0: var chain = cert.getChain(); michael@0: for (var i = 1; i < chain.length; i++) michael@0: content += getPEMString(chain.queryElementAt(i, Components.interfaces.nsIX509Cert)); michael@0: break; michael@0: case 2: michael@0: content = getDERString(cert); michael@0: break; michael@0: case 3: michael@0: content = getPKCS7String(cert, Components.interfaces.nsIX509Cert3.CMS_CHAIN_MODE_CertOnly); michael@0: break; michael@0: case 4: michael@0: content = getPKCS7String(cert, Components.interfaces.nsIX509Cert3.CMS_CHAIN_MODE_CertChainWithRoot); michael@0: break; michael@0: case 0: michael@0: default: michael@0: content = getPEMString(cert); michael@0: break; michael@0: } michael@0: var msg; michael@0: var written = 0; michael@0: try { michael@0: var file = Components.classes["@mozilla.org/file/local;1"]. michael@0: createInstance(Components.interfaces.nsILocalFile); michael@0: file.initWithPath(fp.file.path); michael@0: var fos = Components.classes["@mozilla.org/network/file-output-stream;1"]. michael@0: createInstance(Components.interfaces.nsIFileOutputStream); michael@0: // flags: PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE michael@0: fos.init(file, 0x02 | 0x08 | 0x20, 00644, 0); michael@0: written = fos.write(content, content.length); michael@0: fos.close(); michael@0: } michael@0: catch(e) { michael@0: switch (e.result) { michael@0: case Components.results.NS_ERROR_FILE_ACCESS_DENIED: michael@0: msg = bundle.getString("writeFileAccessDenied"); michael@0: break; michael@0: case Components.results.NS_ERROR_FILE_IS_LOCKED: michael@0: msg = bundle.getString("writeFileIsLocked"); michael@0: break; michael@0: case Components.results.NS_ERROR_FILE_NO_DEVICE_SPACE: michael@0: case Components.results.NS_ERROR_FILE_DISK_FULL: michael@0: msg = bundle.getString("writeFileNoDeviceSpace"); michael@0: break; michael@0: default: michael@0: msg = e.message; michael@0: break; michael@0: } michael@0: } michael@0: if (written != content.length) { michael@0: if (!msg.length) michael@0: msg = bundle.getString("writeFileUnknownError"); michael@0: alertPromptService(bundle.getString("writeFileFailure"), michael@0: bundle.getFormattedString("writeFileFailed", michael@0: [fp.file.path, msg])); michael@0: } michael@0: }