Merge pull request #16 from tlsnotary/firefox_verifycert

Firefox verifycert
This commit is contained in:
dansmith_btc (on Freenode IRC)
2015-09-11 15:34:40 +02:00
27 changed files with 696 additions and 406 deletions

11
bootstrap.js vendored
View File

@@ -206,11 +206,22 @@ function loadjs(){
include(addon, "jsbn2.js");
include(addon, "pako.js");
include(addon, "tlsn.js");
include(addon, "notification_bar.js");
include(addon, "testing/testing.js");
include(addon, "testing/manager_test.js");
include(addon, "verifychain/buffer.js2");
include(addon, "verifychain/asn1.js2");
include(addon, "verifychain/jsrsasign-latest-all-min.js2");
include(addon, "verifychain/rootcertslist.js");
include(addon, "verifychain/rootcerts.js");
include(addon, "verifychain/verifychain.js");
include(addon, "testdriver.js");
}
function shutdown(data, reason) {
gBrowser.removeProgressListener(myListener);
Services.obs.removeObserver(httpRequestBlocker, "http-on-modify-request");
Services.ww.unregisterNotification(windowWatcher);
eachWindow(unloadFromWindow);
}

View File

@@ -3,13 +3,18 @@ var tabs = {};
var appId = "oclohfdjoojomkfddjclanpogcnjhemd"; //id of the helper app
var is_chrome = true;
var fsRootPath; //path to local storage root, e.g. filesystem:chrome-extension://abcdabcd/persistent
var manager_path; //manager.html which was copied into Downloads/ dir
function getPref(value, type){
function getPref(pref, type){
return new Promise(function(resolve, reject) {
chrome.storage.local.get(value, function(items){
if (!items.hasOwnProperty('first')) resolve("undefined");
resolve(items[value]);
chrome.storage.local.get(pref, function(obj){
if (Object.keys(obj).length === 0){
resolve('undefined');
return;
}
else {
resolve(obj[pref]);
}
});
});
}
@@ -17,7 +22,9 @@ function getPref(value, type){
function setPref(pref, type, value){
return new Promise(function(resolve, reject) {
chrome.storage.local.set({pref:value}, function(){
var obj = {};
obj[pref] = value;
chrome.storage.local.set(obj, function(){
resolve();
});
});
@@ -25,23 +32,55 @@ function setPref(pref, type, value){
function import_reliable_sites(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState != 4)
return;
import_resource('pubkeys.txt')
.then(function(text_ba){
parse_reliable_sites(ba2str(text_ba));
});
}
if (xhr.responseText) {
parse_reliable_sites(xhr.responseText);
//we can import chrome:// and file:// URL
function import_resource(filename, isFileURI){
if (typeof(isFileURI) === 'undefined'){
isFileURI = false;
}
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.responseType = "arraybuffer";
xhr.onreadystatechange = function(){
if (xhr.readyState != 4)
return;
if (xhr.response) {
resolve(ab2ba(xhr.response));
}
};
var path = isFileURI ? filename : chrome.extension.getURL('content/'+toFilePath(filename));
xhr.open('get', path, true);
xhr.send();
});
}
//converts an array of file names into a string with correct slashes
function toFilePath(pathArray){
if (typeof(pathArray) === 'string') return pathArray;
var expanded = '';
for(var i=0; i < pathArray.length; i++){
expanded += pathArray[i];
//not trailing slash for last element
if (i < (pathArray.length-1) ){
expanded += '/';
}
};
xhr.open('get', chrome.extension.getURL('content/pubkeys.txt'), true);
xhr.send();
}
return expanded;
}
function startListening(){
console.log('tab listener started')
chrome.webRequest.onSendHeaders.addListener(
function(details) {
console.log('in tab listener', details);
if (details.type === "main_frame"){
tabs[details.tabId] = details;
}
@@ -64,11 +103,10 @@ function getHeaders(){
}
var tab = tabs[t[0].id];
var x = tab.url.split('/');
var host = x[2];
var host = x[2].split(':')[0];
x.splice(0,3);
var tab_url = x.join('/');
var headers = '';
headers += tab.method + " /" + tab_url + " HTTP/1.1" + "\r\n";
var resource_url = x.join('/');
var headers = tab.method + " /" + resource_url + " HTTP/1.1" + "\r\n";
headers += "Host: " + host + "\r\n";
for (var i = 0; i < tab.requestHeaders.length; i++){
var h = tab.requestHeaders[i];
@@ -77,7 +115,12 @@ function getHeaders(){
if (tab.method == "GET"){
headers += "\r\n";
}
resolve({'headers':headers, 'server':host});
var port = 443;
if (tab.url.split(':').length === 3){
//the port is explicitely provided in URL
port = parseInt(tab.url.split(':')[2].split('/')[0]);
}
resolve({'headers':headers, 'server':host, 'port':port});
});
});
}
@@ -90,7 +133,7 @@ function loadBusyIcon(){
function loadNormalIcon(){
chrome.browserAction.setIcon({path:"content/icon128.png"});
chrome.browserAction.setIcon({path:"icon.png"});
chrome.browserAction.setPopup({popup:"content/chrome/popup.html"});
}
@@ -99,9 +142,11 @@ function browser_specific_init(){
window.webkitRequestFileSystem(window.PERSISTENT, 50*1024*1024, function(fs){
fsRootPath = fs.root.toURL();
});
chrome.storage.local.get('valid_hashes', function(items){
if (!items.hasOwnProperty('first')) return;
valid_hashes = items.valid_hashes;
getPref('valid_hashes')
.then(function(hashes){
if (hashes !== 'undefined'){
valid_hashes = hashes;
}
});
chrome.runtime.getPlatformInfo(function(p){
if(p.os === "win"){
@@ -109,11 +154,46 @@ function browser_specific_init(){
}
});
//put icon into downloads dir. This is the icon for injected notification
//put manager files also there so we could inject code to get the manager's DOM when testing
//(Chrome forbids injecting into chrome-extension://* URIs but allows into file://* URIs)
chrome.downloads.setShelfEnabled(false);
setTimeout(function(){chrome.downloads.setShelfEnabled(true);}, 2000);
chrome.downloads.download({url:chrome.extension.getURL("content/icon16.png"),
conflictAction:'overwrite',
filename:'pagesigner.tmp.dir/icon16.png'});
var files_to_copy = ['icon16.png', 'manager.css', 'manager.html', 'manager.js2', 'sweetalert.css', 'sweetalert.min.js2', 'check.png', 'cross.png'];
var copied_so_far = 0;
for (var i=0; i < files_to_copy.length; i++){
chrome.downloads.download(
{url:chrome.extension.getURL('content/' + files_to_copy[i]),
conflictAction:'overwrite',
filename:'pagesigner.tmp.dir/' + files_to_copy[i]},
function(downloadID){
var erase_when_download_completed = function(id){
chrome.downloads.search({id:id}, function(item){
if (item[0].state !== 'complete'){
setTimeout(function(){
erase_when_download_completed(id)
}, 100);
}
else {
if (item[0].filename.endsWith('manager.html')){
var path = item[0].filename;
if (os_win){
path = '/' + encodeURI(path.replace(/\\/g, '/'));
}
manager_path = 'file://' + path;
}
//dont litter the Downloads menu
chrome.downloads.erase({id:downloadID});
copied_so_far++;
if (copied_so_far === files_to_copy.length){
chrome.downloads.setShelfEnabled(true);
}
}
});
}
erase_when_download_completed(downloadID);
});
}
chrome.runtime.onMessage.addListener(function(data){
if (data.destination !== 'extension') return;
@@ -128,8 +208,14 @@ function browser_specific_init(){
verify_tlsn_and_show_data(data.args.data, true);
}
else if (data.message === 'export'){
chrome.downloads.download({url:fsRootPath+data.args.dir+'/pgsg.pgsg',
if (testing){
chrome.downloads.download({url:fsRootPath+data.args.dir+'/pgsg.pgsg',
'saveAs':false, filename:'pagesigner.tmp.dir/' + data.args.file+'.pgsg'});
}
else {
chrome.downloads.download({url:fsRootPath+data.args.dir+'/pgsg.pgsg',
'saveAs':true, filename:data.args.file+'.pgsg'});
}
}
else if (data.message === 'notarize'){
startNotarizing();
@@ -181,48 +267,7 @@ function browser_specific_init(){
}
function getModulus(cert){
var c = Certificate.decode(new Buffer(cert), 'der');
var pk = c.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data;
var pkba = ua2ba(pk);
//expected modulus length 256, 384, 512
var modlen = 256;
if (pkba.length > 384) modlen = 384;
if (pkba.length > 512) modlen = 512;
var modulus = pkba.slice(pkba.length - modlen - 5, pkba.length -5);
return modulus;
}
function permutator(inputArr) {
var results = [];
function permute(arr, memo) {
var cur, memo = memo || [];
for (var i = 0; i < arr.length; i++) {
cur = arr.splice(i, 1);
if (arr.length === 0) {
results.push(memo.concat(cur));
}
permute(arr.slice(), memo.concat(cur));
arr.splice(i, 0, cur[0]);
}
return results;
}
return permute(inputArr);
}
function verifyCert(chain){
var chainperms = permutator(chain);
for (var i=0; i < chainperms.length; i++){
if (verifyCertChain(chainperms[i])){
return true;
}
}
return false;
}
function makeSessionDir(server, is_imported){
@@ -361,12 +406,12 @@ function openTabs(sdir){
chrome.tabs.reload(id, {bypassCache:true}, function(){
//this callback triggers too early sometimes. Wait to make sure page reloaded
setTimeout(function(){
chrome.tabs.insertCSS(id, {file: 'content/chrome/injectbar.css'}, function(a){
chrome.tabs.executeScript(id, {file: 'content/chrome/injectbar.js'}, function(a){
chrome.tabs.executeScript(id, {code:
'document.getElementById("domainName").textContent="' + commonName.toString() + '";' +
'var sdir ="' + dirname.toString() + '";'});
});
chrome.tabs.executeScript(id, {file: 'content/notification_bar.js'}, function(a){
chrome.tabs.executeScript(id, {code:
'viewTabDocument = document;' +
'install_bar();' +
'document.getElementById("domainName").textContent="' + commonName.toString() + '";' +
'document["pagesigner-session-dir"]="' + dirname.toString() + '";'});
});
}, 500);
});
@@ -376,18 +421,6 @@ function openTabs(sdir){
}
function getCommonName(cert){
var c = Certificate.decode(new Buffer(cert), 'der');
var fields = c.tbsCertificate.subject.value;
for (var i=0; i < fields.length; i++){
if (fields[i][0].type.toString() !== [2,5,4,3].toString()) continue;
//first 2 bytes are DER-like metadata
return ba2str(fields[i][0].value.slice(2));
}
return 'unknown';
}
function Socket(name, port){
this.name = name;
this.port = port;
@@ -467,7 +500,7 @@ Socket.prototype.recv = function(){
if (! rv.is_complete){
console.log("check_complete_records failed");
buf = rv.incomprecs;
setTimeout(check, 100);
setTimeout(function(){check()}, 100);
return;
}
clearTimeout(timer);
@@ -476,7 +509,7 @@ Socket.prototype.recv = function(){
return;
}
console.log('Another timeout in recv');
setTimeout(check, 100);
setTimeout(function(){check()}, 100);
});
};
check();
@@ -492,16 +525,15 @@ function get_xhr(){
}
function openManager(){
var url = chrome.extension.getURL('content/manager.html');
//re-focus tab if manager already open
chrome.tabs.query({}, function(tabs){
for(var i=0; i < tabs.length; i++){
if (tabs[i].url.startsWith(url)){
if (tabs[i].url === manager_path){
chrome.tabs.update(tabs[i].id, {active:true});
return;
}
}
chrome.tabs.create({url:url});
chrome.tabs.create({url:manager_path});
});
}
@@ -527,8 +559,22 @@ function renamePGSG(dir, newname){
function sendMessage(data){
chrome.runtime.sendMessage({'destination':'manager',
'data':data});
//get the manager tab and inject the data into it
chrome.tabs.query({}, function(tabs){
for(var i=0; i < tabs.length; i++){
if (tabs[i].url === manager_path){
var jsonstring = JSON.stringify(data);
chrome.tabs.executeScript(tabs[i].id, {code:
'var idiv = document.getElementById("extension2manager");' +
//seems like chrome unstringifies jsonstring, so we stringify it again
'var json = JSON.stringify(' + jsonstring + ');' +
'console.log("json is", json);' +
'idiv.textContent = json;'+
'idiv.click();'
});
}
}
});
}
@@ -574,6 +620,8 @@ function getDirEntry(dirName){
.then(function(rootDirEntry){
rootDirEntry.getDirectory(dirName, {}, function(dirEntry){
resolve(dirEntry);
}, function(what){
reject(what);
});
});
});
@@ -650,7 +698,7 @@ function sendAlert(alertData){
alert("You can only notarize pages which start with https://");
return;
}
chrome.tabs.executeScript(tabs[0].id, {file:"content/sweetalert.min.js"}, function(){
chrome.tabs.executeScript(tabs[0].id, {file:"content/sweetalert.min.js2"}, function(){
chrome.tabs.insertCSS(tabs[0].id, {file:"content/sweetalert.css"}, function(){
chrome.tabs.executeScript(tabs[0].id, {code:"swal("+ JSON.stringify(alertData) +")"});
});

View File

@@ -0,0 +1,9 @@
console.log("injecting some code");
document.addEventListener("hello", function(evt) {
var data = evt.detail;
console.log("got hello with", data);
chrome.runtime.sendMessage(data);
});
//this element is accessible by content scripts and by page javascript
document.getElementById('content_script_injected_into_page').textContent = 'true';

View File

@@ -1,10 +0,0 @@
.visible {
visibility: visible;
opacity: 1;
-webkit-transition: opacity 2s linear;
}
.hidden {
visibility: hidden;
opacity: 0;
-webkit-transition: visibility 0s 2s, opacity 2s linear;
}

View File

@@ -1,42 +0,0 @@
var table = document.createElement("table");
table.style.position = "fixed";
table.style.top = "0px";
table.style.left = "100px";
table.style.background = "rgba(242, 241, 240, 0.9)";
table.style.width = "80%";
table.style.height = "32px";
table.className = "hidden";
var row = document.createElement("tr");
var cell1 = document.createElement("td");
var cell2 = document.createElement("td");
var cell3 = document.createElement("td");
cell3.style.align = "right";
var img = document.createElement("img");
img.src = "icon16.png";
var text = document.createElement("text");
text.textContent = "PageSigner successfully verified that the webpage below was received from ";
var domain = document.createElement("text");
domain.id = "domainName";
var button = document.createElement("button");
button.id = "viewRaw";
button.textContent = "View raw data with HTTP headers";
button.style.MozBorderRadius = "4px";
button.style.WebkitBorderRadius = "4px";
button.style.borderRadius = "4px";
button.onclick = function(){
chrome.runtime.sendMessage({destination:'extension', message:'viewraw', args:{dir:sdir}});
}
cell3.appendChild(button)
cell2.appendChild(text);
cell2.appendChild(domain);
cell1.appendChild(img);
row.appendChild(cell1);
row.appendChild(cell2);
row.appendChild(cell3);
table.appendChild(row);
document.body.appendChild(table);
setTimeout(function(){
//make a transition to visible
table.className = "visible";
}, 0);

View File

@@ -46,7 +46,7 @@ img {
<table style="width:100%">
<tr class="border_bottom">
<td id="notarize"><img src="../icon.png"></img>Notarize this page</td>
<td id="notarize"><img src="../../icon.png"></img>Notarize this page</td>
</tr>
<tr class="border_bottom">
<td id="manage"><img src="../manage.png"></img>Manage files</td>
@@ -55,7 +55,7 @@ img {
<td id="import"><img src="../verify.png"></img>Import .pgsg file</td>
</tr>
<tr>
<td id="about"><img src="../icon.png"></img>About</td>
<td id="about"><img src="../../icon.png"></img>About</td>
</tr>
</table>

View File

@@ -30,3 +30,11 @@ document.getElementById("about").addEventListener("click",
left:500})
window.close();
});
//if this file is opened in a tab during testing, it will have a hash appended to the URL
setTimeout(function(){
var hash = window.location.hash;
if (hash === "#manage"){
document.getElementById('manage').click();
}
}, 100);

View File

@@ -4,6 +4,7 @@
let prompts = Services.prompt;
let prefs = Services.prefs;
var testing_import_path; //used only in testing
const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
PREFS_BRANCH = Services.prefs.getBranch("extensions.pagesigner.button-position."),
@@ -13,27 +14,30 @@ const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
let main = {
notarize: function() {
if (testing){
startTesting();
}
else {
startNotarizing();
}
startNotarizing();
},
verify: function() {
function importPath(path){
OS.File.read(path)
.then(function(imported_data){
var data_ba = ua2ba(imported_data);
verify_tlsn_and_show_data(data_ba, true);
populateTable(); //TODO, why again? v_t_a_s_d already does that
});
};
if (testing){
importPath(testing_import_path);
return;
}
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, "Select the .pgsg file you want to import and verify", nsIFilePicker.modeOpen);
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
var path = fp.file.path;
OS.File.read(path).
then(function(imported_data){
var data_ba = ua2ba(imported_data);
verify_tlsn_and_show_data(data_ba, true);
populateTable();
});
importPath(fp.file.path);
}
},
manage: function() {

View File

@@ -20,7 +20,7 @@ var atob = win.atob;
var JSON = win.JSON;
var is_chrome = false;
var fsRootPath; //path to pagesigner folder in FF profile dir
var manager_path; //manager.html which was copied into profile's pagesigner dir
function getPref(prefname, type){
return new Promise(function(resolve, reject) {
@@ -53,13 +53,64 @@ function setPref(prefname, type, value){
function import_reliable_sites(){
OS.File.read(OS.Path.join(OS.Constants.Path.profileDir,"extensions","pagesigner@tlsnotary","content","pubkeys.txt"), { encoding: "utf-8" }).
then(function onSuccess(text) {
parse_reliable_sites(text);
import_resource('pubkeys.txt')
.then(function(ba) {
parse_reliable_sites(ba2str(ba));
});
}
//converts an array of file names into a string with correct slashes
function toFilePath(pathArray){
if (typeof(pathArray) === 'string') return pathArray;
var expanded = '';
for(var i=0; i < pathArray.length; i++){
expanded = OS.Path.join(pathArray, dirName[i]);
}
return expanded;
}
//reads from addon content folder but also can read an arbitrary file://
function import_resource(filename, isFileURI){
if (typeof(isFileURI) === 'undefined'){
isFileURI = false;
}
return new Promise(function(resolve, reject) {
var path = 'content';
if (typeof(filename) === 'string'){
path += '/'+filename;
}
else {
for (var i=0; i < filename.length; i++){
path += '/'+filename[i];
}
}
path = isFileURI ? filename : thisaddon.getResourceURI(path).spec;
var xhr = get_xhr();
xhr.responseType = "arraybuffer";
xhr.onreadystatechange = function(){
if (xhr.readyState != 4)
return;
if (xhr.response) {
resolve(ab2ba(xhr.response));
}
};
xhr.open('get', path, true);
xhr.send();
/*
OS.File.read(OS.Path.fromFileURI(thisaddon.getResourceURI(path).spec))
.then(function onSuccess(ba) {
//returns Uint8Array which is compatible with our internal byte array
resolve(ba);
});
*/
});
}
function startListening(){
//from now on, we will check the security status of all loaded tabs
@@ -91,11 +142,10 @@ function getHeaders(){
//passed tests, secure, grab headers, update status bar and start audit:
var x = sanitized_url.split('/');
x.splice(0,3);
var tab_url = x.join('/');
var resource_url = x.join('/');
var httpChannel = dict_of_httpchannels[sanitized_url];
var headers = "";
headers += httpChannel.requestMethod + " /" + tab_url + " HTTP/1.1" + "\r\n";
var headers = httpChannel.requestMethod + " /" + resource_url + " HTTP/1.1" + "\r\n";
httpChannel.visitRequestHeaders(function(header,value){
headers += header +": " + value + "\r\n";});
if (httpChannel.requestMethod == "GET"){
@@ -114,8 +164,13 @@ function getHeaders(){
//FF's uploaddata contains Content-Type and Content-Length headers + '\r\n\r\n' + http body
headers += uploaddata;
}
var server = headers.split('\r\n')[1].split(':')[1].replace(/ /g,'');
resolve({'headers':headers, 'server':server});
var host = headers.split('\r\n')[1].split(':')[1].replace(/ /g,'');
var port = 443;
if (tab_url_full.split(':').length === 3){
//the port is explicitely provided in URL
port = parseInt(tab_url_full.split(':')[2].split('/')[0]);
}
resolve({'headers':headers, 'server':host, 'port':port});
});
}
@@ -139,130 +194,186 @@ function browser_specific_init(){
});
fsRootPath = OS.Path.join(OS.Constants.Path.profileDir, "pagesigner");
manager_path = OS.Path.toFileURI(OS.Path.join(fsRootPath, "manager.html"));
//copy the manager file to local filesystem for security + takes care of some odd behaviour
//when trying to add eventListener to chrome:// resources
var contentDir = OS.Path.join(OS.Constants.Path.profileDir,"extensions","pagesigner@tlsnotary","content");
var html = OS.Path.join(contentDir, "manager.html");
var js = OS.Path.join(contentDir, "manager.js");
var css = OS.Path.join(contentDir, "manager.css");
var check = OS.Path.join(contentDir, "check.png");
var cross = OS.Path.join(contentDir, "cross.png");
var swalcss = OS.Path.join(contentDir, "sweetalert.css");
var swaljs = OS.Path.join(contentDir, "sweetalert.min.js");
var html = OS.Path.fromFileURI(thisaddon.getResourceURI('content/manager.html').spec);
var js = OS.Path.fromFileURI(thisaddon.getResourceURI('content/manager.js2').spec);
var css = OS.Path.fromFileURI(thisaddon.getResourceURI('content/manager.css').spec);
var check = OS.Path.fromFileURI(thisaddon.getResourceURI('content/check.png').spec);
var cross = OS.Path.fromFileURI(thisaddon.getResourceURI('content/cross.png').spec);
var swalcss = OS.Path.fromFileURI(thisaddon.getResourceURI('content/sweetalert.css').spec);
var swaljs = OS.Path.fromFileURI(thisaddon.getResourceURI('content/sweetalert.min.js2').spec);
var icon = OS.Path.fromFileURI(thisaddon.getResourceURI('content/icon16.png').spec);
var dest_html = OS.Path.join(fsRootPath, "manager.html");
var dest_js = OS.Path.join(fsRootPath, "manager.js");
var dest_js = OS.Path.join(fsRootPath, "manager.js2");
var dest_css = OS.Path.join(fsRootPath, "manager.css");
var dest_check = OS.Path.join(fsRootPath, "check.png");
var dest_cross = OS.Path.join(fsRootPath, "cross.png");
var dest_swalcss = OS.Path.join(fsRootPath, "sweetalert.css");
var dest_swaljs = OS.Path.join(fsRootPath, "sweetalert.min.js");
var dest_swaljs = OS.Path.join(fsRootPath, "sweetalert.min.js2");
var dest_icon = OS.Path.join(fsRootPath, "icon16.png");
OS.File.makeDir(fsRootPath, {ignoreExisting:true})
.then(function(){
OS.File.copy(html, dest_html);
})
.then(function(){
return OS.File.copy(js, dest_js, {noOverwrite:true});
return OS.File.copy(js, dest_js);
})
.then(function(){
OS.File.copy(css, dest_css, {noOverwrite:true});
OS.File.copy(css, dest_css);
})
.then(function(){
OS.File.copy(check, dest_check, {noOverwrite:true});
OS.File.copy(check, dest_check);
})
.then(function(){
OS.File.copy(cross, dest_cross, {noOverwrite:true});
OS.File.copy(cross, dest_cross);
})
.then(function(){
OS.File.copy(swalcss, dest_swalcss, {noOverwrite:true});
OS.File.copy(swalcss, dest_swalcss);
})
.then(function(){
OS.File.copy(swaljs, dest_swaljs, {noOverwrite:true});
OS.File.copy(swaljs, dest_swaljs);
})
.then(function(){
OS.File.copy(icon, dest_icon);
});
init();
}
var idiv;
var listener;
var d;
function openManager(){
//if manager is open, focus it
var idiv, listener, managerDocument; //these must be global otherwise we'll get no events
function openManager(is_loading){
if (typeof(is_loading) === 'undefined'){
is_loading = false;
}
var t;
var was_manager_open = false;
var tabs = gBrowser.tabs;
for(var i=0; i < tabs.length; i++){
var url = gBrowser.getBrowserForTab(tabs[i]).contentWindow.location.href;
if (url.search('/pagesigner/manager.html') > -1){
gBrowser.selectedTab = tabs[i];
if (url == manager_path){
t = tabs[i];
if (! is_loading){
//on Win7 i was getting 'load' event even when I clicked another tab
//we want to select the tab only if manager was called from the menu
gBrowser.selectedTab = t;
}
was_manager_open = true;
}
}
if (was_manager_open && (gBrowser.getBrowserForTab(t).contentWindow.document === managerDocument)){
console.log('ignoring the same managerDocument in tab');
return;
}
var promise;
if (was_manager_open && !is_loading){
//this may be a dangling manager from previous browser session
//if so, then reload it
if (gBrowser.getBrowserForTab(t).contentWindow.document !== managerDocument){
console.log('detected a dangling manager tab');
promise = Promise.resolve();
}
else {
console.log('focusing existing manager');
return;
}
}
Promise.resolve() //dont want to indent the whole .then() section
.then(function(){
var uri = OS.Path.join(fsRootPath, "manager.html");
var t = gBrowser.addTab(uri);
gBrowser.selectedTab = t;
else if (was_manager_open && is_loading){
var readyListener = function(e){
//will trigger on reload (sometimes triggers twice but this should not affect us)
d = gBrowser.getBrowserForTab(e.target).contentWindow.document;
var install_listener = function(d){
listener = d.getElementById('manager2extension');
idiv = d.getElementById('extension2manager');
if (!listener){ //maybe the DOM hasnt yet loaded
setTimeout(function(){
install_listener(d);
}, 100);
return;
console.log('reloading existing manager');
promise = Promise.resolve();
}
else if (!was_manager_open){
promise = new Promise(function(resolve, reject) {
console.log('opening a new manager');
t = gBrowser.addTab(manager_path);
gBrowser.selectedTab = t;
function check_uri(){
if (gBrowser.getBrowserForTab(t).contentWindow.location.href !== manager_path){
console.log('data tab href not ready, waiting');
setTimeout(function(){check_uri();}, 100);
}
else {
resolve();
}
var onEvent = function(){
console.log('in click event');
if (listener.textContent === '') return;//spurious click
var data = JSON.parse(listener.textContent);
listener.textContent = '';
if (data.destination !== 'extension') return;
if (data.message === 'refresh'){
populateTable();
}
else if (data.message === 'export'){
var path = OS.Path.join(fsRootPath, data.args.dir, 'pgsg.pgsg');
console.log('saving full path', path);
savePGSGFile(path, data.args.file);
}
else if (data.message === 'delete'){
OS.File.removeDir(OS.Path.join(fsRootPath, data.args.dir))
.then(function(){
populateTable();
});
}
else if (data.message === 'rename'){
//to update dir's modtime, we remove the file and recreate it
writeFile(data.args.dir, "meta", str2ba(data.args.newname), true)
.then(function(){
populateTable();
});
}
else if (data.message === 'viewdata'){
openTabs(data.args.dir);
}
else if (data.message === 'viewraw'){
var path = OS.Path.join(fsRootPath, data.args.dir, 'raw.txt');
gBrowser.selectedTab = gBrowser.addTab(path);
}
};
listener.addEventListener('click', onEvent);
onEvent(); //maybe the page asked for refresh before listener installed
};
install_listener(d);
check_uri();
});
}
promise
.then(function(){
//DOM may not be available immediately
managerDocument = gBrowser.getBrowserForTab(t).contentWindow.document;
return new Promise(function(resolve, reject) {
function wait_for_DOM(){
listener = managerDocument.getElementById('manager2extension');
idiv = managerDocument.getElementById('extension2manager');
if (listener && idiv){
resolve();
}
else {
console.log('manager DOM not ready yet, waiting');
setTimeout(function(){wait_for_DOM()}, 100);
}
}
wait_for_DOM();
});
})
.then(function(){
function onEvent(){
console.log('in click event');
if (listener.textContent === '') return;//spurious click
var data = JSON.parse(listener.textContent);
listener.textContent = '';
if (data.destination !== 'extension') return;
if (data.message === 'refresh'){
populateTable();
}
else if (data.message === 'export'){
var path = OS.Path.join(fsRootPath, data.args.dir, 'pgsg.pgsg');
console.log('saving full path', path);
savePGSGFile(path, data.args.file);
}
else if (data.message === 'delete'){
OS.File.removeDir(OS.Path.join(fsRootPath, data.args.dir))
.then(function(){
populateTable();
});
}
else if (data.message === 'rename'){
//to update dir's modtime, we remove the file and recreate it
writeFile(data.args.dir, "meta", str2ba(data.args.newname), true)
.then(function(){
populateTable();
});
}
else if (data.message === 'viewdata'){
var dir = OS.Path.join(fsRootPath, data.args.dir);
openTabs(dir);
}
else if (data.message === 'viewraw'){
var path = OS.Path.join(fsRootPath, data.args.dir, 'raw.txt');
gBrowser.selectedTab = gBrowser.addTab(path);
}
};
t.addEventListener('load', readyListener);
listener.addEventListener('click', onEvent);
onEvent(); //maybe the page asked for refresh before listener installed
//add tab event listener which will trigger when user reloads the tab ie with F5
function onLoadEvent(e){
console.log('in tab load event handler');
openManager(true);
};
if (!was_manager_open){
//installed only once on first tab load
t.addEventListener('load', onLoadEvent);
}
});
}
@@ -296,14 +407,17 @@ function getDirEntry(dirName){
OS.File.stat(path)
.then(function(stat){
resolve(stat);
})
.catch(function(what){
reject(what);
});
});
}
function getName(obj){
//XXX this is not x-platform
return obj.path.split('/').pop();
var delimiter = os_win ? '\\' : '/';
return obj.path.split(delimiter).pop();
}
@@ -358,6 +472,24 @@ function sendMessage(data){
function savePGSGFile(existing_path, name){
var copyFile = function(src, dst){
OS.File.copy(src, dst)
.then(function(){
console.log("File write OK");
},
function (e){
console.log("Caught error writing file: "+e);
});
};
if (testing){
var dldir = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).get("DfltDwnld", Ci.nsIFile).path;
var dst = OS.Path.join(dldir, 'pagesigner.tmp.dir', name + '.pgsg');
copyFile(existing_path, dst);
return;
}
var nsIFilePicker = Ci.nsIFilePicker;
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
fp.init(window, "Save PageSigner file As", nsIFilePicker.modeSave);
@@ -366,17 +498,8 @@ function savePGSGFile(existing_path, name){
fp.defaultString = name + ".pgsg";
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
var path = fp.file.path;
//write the file
let promise = OS.File.copy(existing_path, fp.file.path);
promise.then(function(){
console.log("File write OK");
},
function (e){
console.log("Caught error writing file: "+e);
}
);
}
copyFile(existing_path, fp.file.path);
}
}
@@ -387,56 +510,6 @@ function showAboutInfo(){
}
//extracts modulus from PEM certificate
function getModulus(cert){
const nsIX509Cert = Ci.nsIX509Cert;
const nsIX509CertDB = Ci.nsIX509CertDB;
const nsX509CertDB = "@mozilla.org/security/x509certdb;1";
let certdb = Cc[nsX509CertDB].getService(nsIX509CertDB);
let cert_obj = certdb.constructX509FromBase64(b64encode(cert));
const nsASN1Tree = "@mozilla.org/security/nsASN1Tree;1";
const nsIASN1Tree = Ci.nsIASN1Tree;
var hexmodulus = "";
var certDumpTree = Cc[nsASN1Tree].createInstance(nsIASN1Tree);
certDumpTree.loadASN1Structure(cert_obj.ASN1Structure);
var modulus_str = certDumpTree.getDisplayData(12);
if (! modulus_str.startsWith( "Modulus (" ) ){
//most likely an ECC certificate
alert ("Unfortunately this website is not compatible with PageSigner. (could not parse RSA certificate)");
return;
}
var lines = modulus_str.split('\n');
var line = "";
for (var i = 1; i<lines.length; ++i){
line = lines[i];
//an empty line is where the pubkey part ends
if (line === "") {break;}
//remove all whitespaces (g is a global flag)
hexmodulus += line.replace(/\s/g, '');
}
return hex2ba(hexmodulus);
}
//verify the certificate against Firefox's certdb
function verifyCert(chain){
const nsIX509Cert = Ci.nsIX509Cert;
const nsIX509CertDB = Ci.nsIX509CertDB;
const nsX509CertDB = "@mozilla.org/security/x509certdb;1";
let certdb = Cc[nsX509CertDB].getService(nsIX509CertDB);
let cert_obj = certdb.constructX509FromBase64(b64encode(chain[0]));
let a = {}, b = {};
let retval = certdb.verifyCertNow(cert_obj, nsIX509Cert.CERT_USAGE_SSLServerWithStepUp, nsIX509CertDB.FLAG_LOCAL_ONLY, a, b);
if (retval === 0){ //success
return true;
}
else {
return false;
}
}
function dumpSecurityInfo(channel,urldata) {
// Do we have a valid channel argument?
if (! channel instanceof Ci.nsIChannel) {
@@ -478,23 +551,19 @@ var httpRequestBlocker = {
notificationCallbacks = httpChannel.notificationCallbacks;
}
else if (httpChannel.loadGroup && httpChannel.loadGroup.notificationCallbacks) {
notificationCallbacks = httpChannel.loadGroup.notificationCallbacks;
notificationCallbacks = httpChannel.loadGroup.notificationCallbacks;
}
else {
console.log('no notificationCallbacks');
return;
}
var path = notificationCallbacks.getInterface(Components.interfaces.nsIDOMWindow).top.location.pathname;
} catch (e){
console.log('no interface');
return; //xhr dont have any interface
}
if (block_urls.indexOf(path) > -1){
console.log('found matching tab, blocking request', path);
httpChannel.cancel(Components.results.NS_BINDING_ABORTED);
return;
}
console.log('not blocking request', path);
}
};
@@ -567,8 +636,10 @@ function makeSessionDir(server, is_imported){
imported_str = "-IMPORTED";
}
var newdir = OS.Path.join(localDir, time+'-'+server+imported_str);
OS.File.makeDir(newdir);
resolve(newdir);
OS.File.makeDir(newdir)
.then(function(){
resolve(newdir);
});
});
}
@@ -590,23 +661,24 @@ function writeFile(dirName, fileName, data, is_update){
}
return new Promise(function(resolve, reject) {
var path = OS.Path.join(fsRootPath, dirName, fileName);
var promise;
if (is_update){
promise = OS.File.remove(path);
}
else {
promise = Promise.resolve();
}
var promise = is_update ? OS.File.remove(path) : Promise.resolve();
promise
.then(function(){
return OS.File.open(path, {create:true});
})
.then(function(f){
return f.close();
})
.then(function(){
return OS.File.writeAtomic(path, ba2ua(data));
})
.then(function(){
resolve();
});
})
.catch(function(e){
console.log('caught error in writeFile', e);
alert('error in writeFile');
})
});
}
@@ -625,6 +697,8 @@ function openTabs(sdir){
}
var commonName;
var dataFileURI;
var t;
getFileContent(sdir, "metaDomainName")
.then(function(data_ba){
commonName = ba2str(data_ba);
@@ -633,27 +707,70 @@ function openTabs(sdir){
.then(function(data){
var name = ba2str(data);
var data_path = OS.Path.join(fsRootPath, sdir, name);
dataFileURI = OS.Path.toFileURI(data_path);
block_urls.push(data_path);
var t = gBrowser.addTab(data_path);
t = gBrowser.addTab(data_path);
gBrowser.selectedTab = t;
setTimeout(function(){
gBrowser.getBrowserForTab(t).reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE);
}, 500);
install_notification(t, commonName, raw_path);
//resolve when URI is ours
console.log('opening data tab');
return new Promise(function(resolve, reject) {
function check_uri(){
if (gBrowser.getBrowserForTab(t).contentWindow.location.href !== dataFileURI){
console.log('data tab href not ready, waiting');
setTimeout(function(){check_uri();}, 100);
}
else {
resolve();
}
};
check_uri();
});
})
.then(function(){
//reload the tab and check URI
console.log('reloading data tab');
//set a token on old document object
gBrowser.getBrowserForTab(t).contentWindow.document['pagesigner-before-reload'] = true;
gBrowser.getBrowserForTab(t).reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE);
//after reload FF marks previous document as [dead Object],
return new Promise(function(resolve, reject) {
function check_new_document(){
var doc = gBrowser.getBrowserForTab(t).contentWindow.document;
if (doc.hasOwnProperty('pagesigner-before-reload')){
console.log('data tab href not ready, waiting');
setTimeout(function(){check_new_document();}, 100);
}
else {
resolve();
}
};
check_new_document();
});
})
.then(function(){
viewTabDocument = gBrowser.getBrowserForTab(t).contentWindow.document;
//even though .document is immediately available, its .body property may not be
return new Promise(function(resolve, reject) {
function wait_for_body(){
if (viewTabDocument.body === null){
console.log('body not available, waiting');
setTimeout(function(){wait_for_body()}, 100);
}
else {
console.log('viewTabDocument is ', viewTabDocument);
console.log('body is ', viewTabDocument.body);
install_bar();
viewTabDocument.getElementById("domainName").textContent = commonName;
viewTabDocument['pagesigner-session-dir'] = sdir;
console.log('injected stuff into viewTabDocument');
}
};
wait_for_body();
});
});
}
function getCommonName(cert){
const nsIX509Cert = Ci.nsIX509Cert;
const nsIX509CertDB = Ci.nsIX509CertDB;
const nsX509CertDB = "@mozilla.org/security/x509certdb;1";
let certdb = Cc[nsX509CertDB].getService(nsIX509CertDB);
let cert_obj = certdb.constructX509FromBase64(b64encode(cert));
return cert_obj.commonName;
}
function Socket(name, port){
this.name = name;
this.port = port;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 962 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -6,7 +6,8 @@ var previous_session_start_time; // used to make sure user doesnt exceed rate li
var chosen_notary;
var tdict = {};
var valid_hashes = [];
var os_win = false; //is OS windows? used to fix / in paths
var os_win = false; //is OS windows? used to fix / in paths
var browser_init_finished = false; //signal to test script when it can start
function init(){
@@ -58,6 +59,7 @@ function init(){
}
import_reliable_sites();
startListening();
browser_init_finished = true;
});
}
@@ -114,14 +116,12 @@ function parse_reliable_sites(text){
if ( (extime - now) < 1000*60*60*24*90){
continue;
}
reliable_sites.push( {'name':name, 'expires':expires, 'modulus':modulus} );
reliable_sites.push( {'name':name, 'port':443, 'expires':expires, 'modulus':modulus} );
}
}
}
//callback is used in testing to signal when this page's n10n finished
function startNotarizing(callback){
if (! oracles_intact){
@@ -130,16 +130,17 @@ function startNotarizing(callback){
}
var modulus;
var certsha256;
var headers;
var server;
var headers, server, port, chain;
getHeaders()
.then(function(obj){
headers = obj.headers;
server = obj.server;
port = obj.port;
loadBusyIcon();
return get_certificate(server);
return get_certificate(server, port);
})
.then(function(chain){
.then(function(certchain){
chain = certchain;
if (! verifyCert(chain)){
sendAlert({title:"PageSigner error", text:"This website cannot be audited by PageSigner because it presented an untrusted certificate"});
return;
@@ -177,7 +178,7 @@ function startNotarizing(callback){
});
})
.then(function(args){
return start_audit(modulus, certsha256, server, headers, args[0], args[1], args[2]);
return start_audit(modulus, certsha256, server, port, headers, args[0], args[1], args[2]);
})
.then(function(args2){
return save_session_and_open_data(args2, server);
@@ -530,7 +531,7 @@ function process_entries(pgsg_subdirs){
}
Promise.all(promises)
.then(function(){
console.log('about to sendTable', tdict);
//console.log('about to sendTable', tdict);
sendTable();
})
.catch(function(e){
@@ -615,16 +616,65 @@ function fixWinPath(path){
}
//startsWith is a pretty recent method, let's implement it here if it's not provided
//reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
if (!String.prototype.startsWith) {
String.prototype.startsWith = function(searchString, position) {
position = position || 0;
return this.lastIndexOf(searchString, position) === position;
};
function getModulus(cert){
var c = Certificate.decode(new Buffer(cert), 'der');
var pk = c.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data;
var pkba = ua2ba(pk);
//expected modulus length 256, 384, 512
var modlen = 256;
if (pkba.length > 384) modlen = 384;
if (pkba.length > 512) modlen = 512;
var modulus = pkba.slice(pkba.length - modlen - 5, pkba.length -5);
return modulus;
}
function getCommonName(cert){
var c = Certificate.decode(new Buffer(cert), 'der');
var fields = c.tbsCertificate.subject.value;
for (var i=0; i < fields.length; i++){
if (fields[i][0].type.toString() !== [2,5,4,3].toString()) continue;
//first 2 bytes are DER-like metadata
return ba2str(fields[i][0].value.slice(2));
}
return 'unknown';
}
function permutator(inputArr) {
var results = [];
function permute(arr, memo) {
var cur, memo = memo || [];
for (var i = 0; i < arr.length; i++) {
cur = arr.splice(i, 1);
if (arr.length === 0) {
results.push(memo.concat(cur));
}
permute(arr.slice(), memo.concat(cur));
arr.splice(i, 0, cur[0]);
}
return results;
}
return permute(inputArr);
}
function verifyCert(chain){
var chainperms = permutator(chain);
for (var i=0; i < chainperms.length; i++){
if (verifyCertChain(chainperms[i])){
return true;
}
}
return false;
}
//This must be at the bottom, otherwise we'd have to define each function
//before it gets used.
browser_specific_init();

View File

@@ -39,8 +39,8 @@ a {
</table>
</div>
<script src="manager.js"></script>
<script src="sweetalert.min.js"></script>
<script src="manager.js2"></script>
<script src="sweetalert.min.js2"></script>
</body>
</html>

View File

@@ -4,25 +4,29 @@ if (navigator.userAgent.search('Chrome') > -1){
}
var idiv;
function onload(){
if (is_chrome){
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.destination !== 'manager') return;
console.log('got request', request);
process_data(request.data);
});
}
else {
idiv = document.getElementById('extension2manager');
idiv.addEventListener('click', function(e){
console.log('changed to', idiv.textContent);
if (idiv.textContent === '') return; //spurious clicks can happen
var data = JSON.parse(idiv.textContent);
process_data(data);
});
}
//These divs are used only in testing. We cant use a variable because Chrome
//content scripts cant access vars, only DOM elements
var div = document.createElement('div');
div.id = 'content_script_injected_into_page';
div.textContent = 'false';
div.style.display = 'none';
document.body.appendChild(div);
var div2 = document.createElement('div');
div2.id = 'table_populated';
div2.textContent = 'false';
div2.style.display = 'none';
document.body.appendChild(div2);
//----------END OF TESTING DIVS----------
idiv = document.getElementById('extension2manager');
idiv.addEventListener('click', function(e){
console.log('changed to', idiv.textContent);
if (idiv.textContent === '') return; //spurious clicks can happen
var data = JSON.parse(idiv.textContent);
process_data(data);
});
sendMessage({'destination':'extension', 'message':'refresh'});
}
@@ -51,6 +55,8 @@ function process_data(rows){
'verifier':r.verifier,
'dir':r.dir});
}
document.getElementById('table_populated').textContent = 'true';
table_populated = true;
}
@@ -128,13 +134,12 @@ function addRow(args){
img.height = 30;
img.width = 30;
var label;
var extrapath = is_chrome ? '/content/' : '';
if (args.valid){
img.src = extrapath + 'check.png';
img.src = 'check.png';
label = 'valid';
}
else {
img.src = extrapath + 'cross.png';
img.src = 'cross.png';
label = 'invalid';
}
text = document.createElement("text");
@@ -186,6 +191,7 @@ function doRename(t, oldname, dir){
},
function(new_name){
if(!(isValid(new_name))){
console.log('detected invalid name', new_name);
//swal glitch - need a timeout
setTimeout(function(){
swal({title:"Invalid filename", text:'Please only use alphanumerical characters', type:'warning'});
@@ -206,7 +212,18 @@ function doRename(t, oldname, dir){
function sendMessage(msg){
console.log('in sendMessage', msg);
if (is_chrome){
chrome.runtime.sendMessage(msg);
var evt = document.createEvent("CustomEvent");
evt.initCustomEvent("hello", true, true, msg);
var dispatch_when_injected = function(){
if (document.getElementById('content_script_injected_into_page').textContent !== 'true'){
console.log('chrome has not yet injected, retrying');
setTimeout(function(){dispatch_when_injected();}, 100);
}
else {
document.dispatchEvent(evt);
}
}
dispatch_when_injected();
}
else {
var json = JSON.stringify(msg);

View File

@@ -0,0 +1,68 @@
var viewTabDocument;
function install_bar(){
//when running from Firefox, the var gBrowser is available
var using_chrome = typeof(gBrowser) === 'undefined';
var using_firefox = typeof(gBrowser) !== 'undefined';
var document = viewTabDocument;
var table = document.createElement("table");
table.style.position = "fixed";
table.style.top = "0px";
table.style.left = "100px";
table.style.background = "rgba(242, 241, 240, 0.9)";
table.style.width = "80%";
table.style.height = "32px";
table.style.visibility = 'hidden';
table.style.opacity = '0';
table.style.webkitTransition = 'visibility 0s 2s, opacity 2s linear';
table.style.transition = 'visibility 0s 2s, opacity 2s linear';
var row = document.createElement("tr");
var cell1 = document.createElement("td");
var cell2 = document.createElement("td");
var cell3 = document.createElement("td");
cell3.style.align = "right";
var img = document.createElement("img");
img.src = using_chrome ? "icon16.png" : "../icon16.png";
var text = document.createElement("text");
text.textContent = "PageSigner verified that this page was received from ";
var domain = document.createElement("text");
domain.id = "domainName";
var sdir = document.createElement("text");
sdir.id = "sdir";
var button = document.createElement("button");
button.id = "viewRaw";
button.textContent = "View raw data with HTTP headers";
button.style.MozBorderRadius = "4px";
button.style.WebkitBorderRadius = "4px";
button.style.borderRadius = "4px";
button.onclick = function(){
var dir = document['pagesigner-session-dir'];
if (using_chrome){
chrome.runtime.sendMessage({destination:'extension', message:'viewraw', args:{dir:dir}});
}
else if (using_firefox){
var path = OS.Path.join(fsRootPath, dir, 'raw.txt');
gBrowser.selectedTab = gBrowser.addTab(path);
}
};
cell3.appendChild(button)
cell2.appendChild(text);
cell2.appendChild(domain);
cell1.appendChild(img);
row.appendChild(cell1);
row.appendChild(cell2);
row.appendChild(cell3);
table.appendChild(row);
table.appendChild(sdir);
document.body.appendChild(table);
document['pagesigner-session-dir'] = sdir;
setTimeout(function(){
//make a transition to visible
table.style.visibility = 'visible';
table.style.opacity = '1';
table.style.webkitTransition = 'opacity 2s linear';
table.style.transition = 'opacity 2s linear';
}, 0);
}

View File

@@ -0,0 +1 @@
//Do not remove this empty file

View File

@@ -0,0 +1,2 @@
//This is an empty file. Browsers expect to find this file in content/testing/testing.js
//When running a testsuite, this file will be replaced

View File

@@ -140,7 +140,7 @@ function prepare_pms(modulus, tryno){
var rs_choice = random_rs.name;
console.log('random reliable site', rs_choice);
var pms_session = new TLSNClientSession();
pms_session.__init__({'server':rs_choice, 'ccs':53, 'tlsver':global_tlsver});
pms_session.__init__({'server':rs_choice, 'port':random_rs.port, 'ccs':53, 'tlsver':global_tlsver});
pms_session.server_modulus = random_rs.modulus;
pms_session.sckt = new Socket(pms_session.server_name, pms_session.ssl_port);
return pms_session.sckt.connect()
@@ -167,7 +167,7 @@ function prepare_pms(modulus, tryno){
#Change Cipher Spec record is returned by the server (we could
#also check the server finished, but it isn't necessary)*/
var record_to_find = new TLSRecord();
record_to_find.__init__(chcis, [0x01], global_tlsver);
record_to_find.__init__(chcis, [0x01], pms_session.tlsver);
if (response.toString().indexOf(record_to_find.serialized.toString()) < 0){
console.log("PMS trial failed, retrying. ("+response.toString()+")");
throw("PMS trial failed");
@@ -233,9 +233,9 @@ function decrypt_html(tlsn_session){
}
function get_certificate(server){
function get_certificate(server, port){
var probe_session = new TLSNClientSession();
probe_session.__init__({'server':server, 'tlsver':global_tlsver});
probe_session.__init__({'server':server, 'port':port, 'tlsver':global_tlsver});
probe_session.sckt = new Socket(probe_session.server_name,probe_session.ssl_port);
return probe_session.sckt.connect()
.then(function(){
@@ -250,9 +250,9 @@ function get_certificate(server){
}
function start_audit(modulus, certhash, name, headers, ee_secret, ee_pad_secret, rsapms2){
function start_audit(modulus, certhash, name, port, headers, ee_secret, ee_pad_secret, rsapms2){
var tlsn_session = new TLSNClientSession();
tlsn_session.__init__({'server':name, 'tlsver':global_tlsver});
tlsn_session.__init__({'server':name, 'port':port, 'tlsver':global_tlsver});
tlsn_session.server_modulus = modulus;
tlsn_session.server_mod_length = modulus.length;
tlsn_session.auditee_secret = ee_secret;

BIN
icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 962 B

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -5,7 +5,7 @@
<Description about="urn:mozilla:install-manifest">
<em:id>pagesigner@tlsnotary</em:id>
<em:version>1.0</em:version>
<em:version>1.0.1</em:version>
<em:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
<em:unpack>true</em:unpack>
@@ -26,8 +26,7 @@
<em:creator>TLSNotary Group</em:creator>
<em:homepageURL>https://tlsnotary.org</em:homepageURL>
<em:optionsURL>chrome://pagesigner/content/firefox/settings.xul</em:optionsURL>
<em:iconURL>chrome://pagesigner/content/icon32.png</em:iconURL>
<em:icon64URL>chrome://pagesigner/content/icon64.png</em:icon64URL>
<em:icon64URL>icon.png</em:icon64URL>
<em:optionsType>2</em:optionsType>
</Description>
</RDF>

View File

@@ -3,13 +3,13 @@
"name": "PageSigner",
"description": "PageSigner - a cryptographically secure webpage screenshot tool",
"version": "1.0",
"version": "1.0.1",
"author": "TLSNotary Group",
"permissions": [
"background",
"*://*/*", //need https to listen for requests and http to send stuff to oracle
"file://*", //ideally we should limit acces only to pagesigner.tmp.dir but Chrome can't do that
"file:///*pagesigner.tmp.dir*", //to inject notification bar when showing notarized html
"webRequest",
"webRequestBlocking",
"activeTab",
@@ -22,7 +22,7 @@
],
"icons": {
"128": "content/icon128.png" //chrome will scaled down as needed
"64": "icon.png" //Chrome will scale down as needed
},
//this is needed for asn1.js
@@ -30,10 +30,17 @@
"browser_action": {
"default_icon": "content/icon128.png",
"default_icon": "icon.png",
"default_popup": "content/chrome/popup.html"
},
"content_scripts":[
{
"matches":["file:///*pagesigner.tmp.dir/manager.html"],
"js":["content/chrome/inject_into_manager.js"]
}
],
"background": {
"scripts": [
"content/chrome/chrome_specific.js",
@@ -54,9 +61,10 @@
"content/pako.js",
"content/tlsn.js",
"content/main.js",
"content/verifychain/buffer.js",
"content/verifychain/asn1.js",
"content/verifychain/jsrsasign-latest-all-min.js",
"content/testing/testing.js",
"content/verifychain/buffer.js2",
"content/verifychain/asn1.js2",
"content/verifychain/jsrsasign-latest-all-min.js2",
"content/verifychain/rootcertslist.js",
"content/verifychain/rootcerts.js",
"content/verifychain/verifychain.js"