<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="jquery.min.js"></script> <script type="text/javascript" src="js/ciphers/hash/sha.js"></script> <script type="text/javascript" src="js/ciphers/hash/md5.js"></script> <script type="text/javascript" src="js/ciphers/hash/ripe-md.js"></script> <!-- crypto libs --> <script type="text/javascript" src="js/ciphers/symmetricencryption/aes.js"></script> <script type="text/javascript" src="js/ciphers/symmetricencryption/cast5.js"></script> <script type="text/javascript" src="js/ciphers/symmetricencryption/dessrc.js"></script> <script type="text/javascript" src="js/ciphers/symmetricencryption/twofish.js"></script> <script type="text/javascript" src="js/ciphers/symmetricencryption/blowfish.js"></script> <script type="text/javascript" src="js/ciphers/asymetricencryption/jsbn.js"></script> <script type="text/javascript" src="js/ciphers/asymetricencryption/jsbn2.js"></script> <script type="text/javascript" src="js/ciphers/asymetricencryption/dsa.js"></script> <script type="text/javascript" src="js/ciphers/asymetricencryption/elgamal.js"></script> <script type="text/javascript" src="js/ciphers/asymetricencryption/rsa.js"></script> <script type="text/javascript" src="js/ciphers/openpgp.crypto.js"></script> <script type="text/javascript" src="js/ciphers/openpgp.cfb.js"></script> <!-- compression --> <!-- encoding --> <script type="text/javascript" src="js/encoding/base64.js"></script> <script type="text/javascript" src="js/encoding/openpgp.encoding.asciiarmor.js"></script> <script type="text/javascript" src="js/encoding/openpgp.encoding.js"></script> <!-- openpgp types --> <script type="text/javascript" src="js/type/openpgp.type.keyid.js"></script> <script type="text/javascript" src="js/type/openpgp.type.mpi.js"></script> <script type="text/javascript" src="js/type/openpgp.type.s2k.js"></script> <!-- openpgp packets --> <script type="text/javascript" src="js/packet/openpgp.packet.compressed.js"></script> <script type="text/javascript" src="js/packet/openpgp.packet.encrypteddata.js"></script> <script type="text/javascript" src="js/packet/openpgp.packet.encryptedintegrityprotecteddata.js"></script> <script type="text/javascript" src="js/packet/openpgp.packet.encryptedsessionkey.js"></script> <script type="text/javascript" src="js/packet/openpgp.packet.keymaterial.js"></script> <script type="text/javascript" src="js/packet/openpgp.packet.literaldata.js"></script> <script type="text/javascript" src="js/packet/openpgp.packet.marker.js"></script> <script type="text/javascript" src="js/packet/openpgp.packet.modificationdetectioncode.js"></script> <script type="text/javascript" src="js/packet/openpgp.packet.onepasssignature.js"></script> <script type="text/javascript" src="js/packet/openpgp.packet.signature.js"></script> <script type="text/javascript" src="js/packet/openpgp.packet.userattribute.js"></script> <script type="text/javascript" src="js/packet/openpgp.packet.userid.js"></script> <script type="text/javascript" src="js/packet/openpgp.packet.js"></script> <!-- openpgp impl. --> <script type="text/javascript" src="js/openpgp.js"></script> <script type="text/javascript" src="js/openpgp.config.js"></script> <script type="text/javascript" src="js/openpgp.keyring.js"></script> <script type="text/javascript" src="js/openpgp.msg.message.js"></script> <script type="text/javascript" src="js/openpgp.msg.privatekey.js"></script> <script type="text/javascript" src="js/openpgp.msg.publickey.js"></script> <script type="text/javascript" src="js/util.js"></script> <title>GPG4Browsers</title> </head> <style> #enterPassword { display: none; position: fixed; top: 50%; left: 50%; margin-top: -10px; margin-left: -300px; background-color: #8888FF; z-index:4; border: 2px solid white; box-shadow: 0px 0px 4px 4px #666; background-color: #fff; border: 2px solid white; box-shadow: 0px 0px 4px 4px #666; padding: 3px; } #keyselect { display: none; margin: 0 auto; position: fixed; top: 50%; left: 50%; font-size: 89%; margin-top: -235px; margin-left: -300px; background-color: #8888FF; z-index:4; border: 2px solid white; box-shadow: 0px 0px 4px 4px #666; background-color: #fff; width: 600px; height: 470px; } #keyselecttable { width: 100%; } #keyselecttable th { background-color: #eee; border-bottom: 1px solid #000; padding: 2px; text-align: left; } #keyselecttable td { padding: 2px; border-bottom: 1px solid #aaa; } #reciepientTable { border: none; border-spacing: 2px; overflow: auto; } input, select { width: 570px; } .reciepientSelect { width: 50px; } .disabledkeys, .keys, .otherkeys { width: 15px; } .reciepientAdd { width: 21px; height: 21px; } #displayWindow, #composeWindow { margin-top: 2px; border: 1px solid #AAA; background-color: white; box-shadow: 2px 2px 5px #888; z-index: 2; padding-left: 10px; padding-right: 10px; padding-bottom: 10px; border-radius: 5px; width: 670px; } body { background-color: #EFEFEF; } #keyselecttable tbody { overflow: auto; } #displaySender, #displayCC, </style> <script language="javascript"> // we rely on jquery here var current_message = null; var account_email = null; function start() { openpgp.init(); chrome.extension.sendRequest({}, function(response) { request = response; if (request.action == 0) { // compose message account_email = request.account; show_compose_window(); } else if (request.action == 1) { // decrypt message current_message = request; account_email = request.account; show_message_window(response); } else { show_compose_window(); } } ); } function show_compose_window() { $("#composerAddress").html(openpgp_encoding_html_encode(account_email)); $("#displayWindow").hide(); $("#composeWindow").show(); if (openpgp.config.config.composition_behavior == 0) { $('#sign_message').attr("checked","checked"); $('#encrypt_message').attr("checked","checked"); } else if (openpgp.config.config.composition_behavior == 1) { $('#sign_message').attr("checked","checked"); $('#encrypt_message').removeAttr("checked"); } else if (openpgp.config.config.composition_behavior == 2) { $('#encrypt_message').attr("checked","checked"); $('#sign_message').removeAttr("checked"); } } var msg = null; function rfn(result) { if (result == -2) util.print_warning("unable to decrypt message: no private key available"); else if (result == -1) util.print_error("No valid passphrase supplied"); else if (result == -3) util.print_error("unable to decrypt message: error during decryption"); else { current_message.decrypted = result; $("#displayMessage").html(openpgp_encoding_html_encode(result)); } } function show_message_window(request) { current_request = request; $("#composeWindow").hide(); $("#displayWindow").show(); $("#displaySender").html(openpgp_encoding_html_encode(request.from)); for (var i = 0; i < request.to.length; i++) $("#displayReceipients").html(openpgp_encoding_html_encode(request.to[i])); if (request.cc != null && request.cc.length > 0) { $("#displayCC").html(""); for (var i = 0; i < request.cc.length; i++) $("#displayCC").append(openpgp_encoding_html_encode(request.cc[i])); $("#displayCC").show(); } else { $("#displayCC").hide(); } if (request.bcc != null) { $("#displayBCC").html(openpgp_encoding_html_encode(request.bcc)); $("#displayBCC").show(); } else { $("#displayBCC").hide(); } $("#displaySubject").html(openpgp_encoding_html_encode(request.subject)); $("#displayMessage").html(openpgp_encoding_html_encode(request.body)); msg = openpgp.read_message(request.body); if (msg != null) for (var m = 0; m < msg.length; m++) { if (!(msg[m].sessionKeys == null)) { var found = false; for (var i = 0; i < msg[m].sessionKeys.length; i++) { if (openpgp.keyring.getPrivateKeyForKeyId(msg[m].sessionKeys[i].keyId)) { var key = openpgp.keyring.getPrivateKeyForKeyId(msg[m].sessionKeys[i].keyId); if (key.length != 0) found = true; for (var j = 0; j < key.length; j++) { if (!key[j].keymaterial.hasUnencryptedSecretKeyData) { get_password(key[j], msg[m], msg[m].sessionKeys[i], rfn); } else { rfn(msg[m].decrypt_message(key[j], null)); } } } else { rfn(-2); } } if (!found || openpgp.keyring.privateKeys.length == 0) rfn(-2); } else if (msg[m].type == 2) { if (msg[m].verifySignature()) rfn(msg[m].text); } } } var encryptionkeys = new Array(); var otherkeys = new Array(); var reciepient_count = 2; function add_reciepient() { add_reciepient(null,null,null); } function add_reciepient(method, name, isdisabled) { $("#reciepientTable").append("<tr class=\"reciepientsRow\"><td><select class=\"reciepientSelect\" "+((isdisabled != null) ? "disabled=\"disabled\" ":"")+"id=\"reciepient_method_"+reciepient_count+"\">"+ "<option value=\"0\""+((method == 0) ? " selected=\"selected\"" : "")+">To:</option>"+ "<option value=\"1\""+((method == 1) ? " selected=\"selected\"" : "")+">Cc:</option>"+ "<option value=\"2\""+((method == 2) ? " selected=\"selected\"" : "")+">Bcc:</option>"+ "</select></td><td>"+ "<input name=\"recepient_"+reciepient_count+"\" type=\"text\" value=\""+((name != null) ? name : "")+"\"></input>"+ "</td><td><input class=\"reciepientAdd\" id=\"reciepientAdd_"+reciepient_count+"\" type=\"button\" value=\"+\" onmousedown=\"add_reciepient();\"></input></td></tr>"); for (var i =1; i < reciepient_count; i++) $("#reciepientAdd_"+i).remove(); reciepient_count++; } function prepare_send_mail() { var i = 1; var addr = new Array(); while ($('[name="recepient_'+i+'"]').val() != null) { addr[i-1] = $('[name="recepient_'+i+'"]').val(); i++; } if ($('#encrypt_message').attr('checked') != null) showKeySelection(addr); else showEncryptionConfirmation(); } function show_reply(reply_all) { if (reply_all) { // adding replys "To" if (current_message.to.length < 2) add_reciepient(0,current_message.to[0], null); else for (var i = 0; i < request.to.length; i++) if (!getEmailAddress(request.to[i]).match(account_email)) { add_reciepient(0,current_message.to[i], null); } // adding reply copies (CC) if (current_request.cc != null) for (var i = 0; i < current_request.cc.length; i++) if (!getEmailAddress(current_request.cc[i]).match(account_email)) { add_reciepient(1,current_message.cc[i], null); } } $("#subjectInput").val("Re: "+current_message.subject); $("#composerAddress").html(openpgp_encoding_html_encode(account_email)); $("#messageBody").html(openpgp_encoding_html_encode(quote_message(current_message.from, new Date(current_message.date), current_message.decrypted))); $("#firstto").val(current_message.from); $("#displayWindow").hide(); show_compose_window(); } function quote_message (sender, date, msg) { return "\n\nOn "+date.toLocaleDateString()+" "+date.toLocaleTimeString()+" \""+getName(sender)+"\" wrote:"+"\n> "+msg.replace(/\n/g,"\n> "); } function get_password(key, msg, sessionkey, successfn) { $("#enterPasswordSubmit").removeAttr("disabled"); $("#enterPasswordInput").removeAttr("disabled"); $("#enterPasswordInput").attr("value",""); $('#enterPassword').css('background-color','#fff'); var count = 0; $("#enterPasswordText").html("Please enter password for keyID: 0x"+util.hexstrdump(key.key.obj.getKeyId())); $("#enterPasswordKeyId").html(key.key.obj.userIds[0]); $("#enterPasswordSubmit").click(function() { $("#enterPassword").fadeOut(100); $("#enterPasswordSubmit").attr("disabled","disabled"); $("#enterPasswordInput").attr("disabled","disabled"); if (key.keymaterial.decryptSecretMPIs($("#enterPasswordInput").val())) { $("#block-bg").hide(); if (msg == null) { successfn(); } successfn(msg.decrypt(key, sessionkey)); } else { if (count == 2) { $("#block-bg").hide(); successfn(-1); current_message.decrypted = current_message.body; count = 0; return; } $('#enterPassword').css('background-color','#f88'); $("#enterPasswordSubmit").removeAttr("disabled"); $("#enterPasswordInput").removeAttr("disabled"); $("#enterPasswordText").html("enterered Password was wrong. try again for keyID: 0x"+util.hexstrdump(key.key.keyId)); $('#enterPasswordInput').focus(); $('#enterPassword').fadeIn(100); count++; } }); $("#block-bg").show(); $("#enterPassword").show(); $('#enterPasswordInput').focus(); } function send_mail(encrypted_text) { var i = 1; var to = ""; var cc = ""; var bcc = ""; while($('[name="recepient_'+i+'"]').val() != null) { if ($('#reciepient_method_'+i).val() == 0) if (to != "") to += ", "+$('[name="recepient_'+i+'"]').val(); else to = $('[name="recepient_'+i+'"]').val(); else if ($('#reciepient_method_'+i).val() == 1) if (cc != "") cc += ", "+$('[name="recepient_'+i+'"]').val(); else cc = $('[name="recepient_'+i+'"]').val(); else if ($('#reciepient_method_'+i).val() == 2) if (bcc != "") bcc += ", "+$('[name="recepient_'+i+'"]').val(); else bcc = $('[name="recepient_'+i+'"]').val(); i++; } var subject = $("#subjectInput").val(); $("#enterPassword").hide(); chrome.extension.sendRequest({action: 2, to: to, bcc: bcc, cc: cc, subject: subject, body: encrypted_text}, function() {}); window.close(); } function getName(email_address) { var o = email_address.indexOf("<"); if (o == -1) return email_address; return email_address.split("<")[0].trim(); } function getEmailAddress(reciepient) { var o = reciepient.indexOf("<"); var c = reciepient.indexOf(">"); if (o == -1 || c == -1) return reciepient; return reciepient.substring(o+1,u); } function showMessages(html) { if ($('#displayWindow').is(':visible')) $('#MessageDisplayOpenPGP').append(html); else if ($('#composeWindow').is(':visible')) $('#MessageComposeOpenPGP').append(html); } function doDownload(mimetype, data) { window.open("data:"+mimetype+";fileName=\"msg.txt\";charset=\"ISO8859-1\";base64,"+s2r(data)); } function showKeySelection(emailaddresses) { $('#keyselecttable').empty(); $('#keyselecttable').append('<tr><th><input class="disabledkeys" type="checkbox" disabled="disabled" checked="checked"></input></th><th>Account / User ID</th><th>Trust</th><th>Key ID</th></tr>'); encryptionkeys = new Array(); otherkeys = new Array(); for (var j = 0; j < emailaddresses.length; j++) { var addr = emailaddresses[j].match(/([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/gi); for (var i = 0; i < openpgp.keyring.publicKeys.length; i++) { for (var k = 0; k < openpgp.keyring.publicKeys[i].obj.userIds.length; k++) { if (openpgp.keyring.publicKeys[i].obj.userIds[k].verify(openpgp.keyring.publicKeys[i].obj.publicKeyPacket) != 0) continue; if (addr == openpgp.keyring.publicKeys[i].obj.userIds[k].text.match(/([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/gi)) { encryptionkeys[keys.length] = openpgp.keyring.publicKeys[i]; emailaddresses.splice(j,1); } else { otherkeys[otherkeys.length] = openpgp.keyring.publicKeys[i]; } } } } // we got all keys if (emailaddresses.length == 0) { showEncryptionConfirmation(); } $('#keyselecttext').empty(); $('#keyselecttext').append("Select keys for the following email addresses:<br>"); for (var i= 0; i < emailaddresses.length; i++) { $('#keyselecttext').append("<i>"+openpgp_encoding_html_encode(emailaddresses[i])+"</i>, "); } for (var i=0; i < encryptionkeys.length; i++) $('#keyselecttable').append('<tr class="validkey"><td><input class="keys" value="'+i+'" type="checkbox" checked="checked"></input></td><td></td>'+ openpgp_encoding_html_encode(encryptionkeys[i].obj.userIds[0].text)+'<td>valid</td><td>0x'+openpgp_encoding_html_encode(util.hexstrdump(encryptionkeys[i].obj.getKeyId()).substring(8))+'</td></tr>'); for (var i = 0; i < otherkeys.length; i++) { if (!otherkeys[i].obj.verifyBasicSignatures()) { $('#keyselecttable').append('<tr class="invalidkey"><td><input class="disabledkeys" type="checkbox" disabled="disabled"></input></td><td><i style="color: #888;">'+ openpgp_encoding_html_encode(otherkeys[i].obj.userIds[0].text)+'</i></td><td>invalid</td><td>0x'+openpgp_encoding_html_encode(util.hexstrdump(otherkeys[i].obj.getKeyId()).substring(8))+'</td></tr>'); } else { $('#keyselecttable').append('<tr class="validkey"><td><input class="otherkeys" value="'+i+'"type="checkbox"></input></td><td>'+ openpgp_encoding_html_encode(otherkeys[i].obj.userIds[0].text)+'</td><td>valid</td><td>0x'+openpgp_encoding_html_encode(util.hexstrdump(otherkeys[i].obj.getKeyId()).substring(8))+'</td></tr>'); } } $('#keyselect').show(); $('#block-bg').show(); } function showEncryptionConfirmation() { if ($('#encrypt_message').attr('checked') != null) { $('#keyselect').hide(); var keys = new Array(); var input1 = $('input.keys:checked'); var input2 = $('input.otherkeys:checked'); for (var i = 0; i < input1.length; i++) { keys[keys.length] = encryptionkeys[parseInt(input1[i].getAttribute("value"))].obj; } for (var i = 0; i < input2.length; i++) { keys[keys.length] = otherkeys[parseInt(input2[i].getAttribute("value"))].obj; } if ($('#sign_message').attr('checked') != null) { var privatekey = openpgp.keyring.getPrivateKeyForAddress(account_email); if (privatekey.length == 0) { alert("no private key found! Go to options and import or create one."); showEncryptioncancel(); } get_password({ key: privatekey[0], keymaterial: privatekey[0].obj.privateKeyPacket},null,null, function(ret) { if (!(ret < 0)) send_mail(openpgp.write_signed_and_encrypted_message(privatekey[0].obj, keys, $('#messageBody').val())); }); } else { send_mail(openpgp.write_encrypted_message(keys, $('#messageBody').val())); } } else { var privatekey = openpgp.keyring.getPrivateKeyForAddress(account_email); if (privatekey.length == 0) { alert("no private key found! Go to options and import or create one."); showEncryptioncancel(); } get_password({ key: privatekey[0], keymaterial: privatekey[0].obj.privateKeyPacket},null,null, function(ret) { if (!(ret < 0)) send_mail(openpgp.write_signed_message(privatekey[0].obj, $('#messageBody').val())); }); } } function showEncryptionCancel() { $('#keyselect').hide(); $('#block-bg').hide(); } </script> <body onload="start();" style="font-family: sans-serif;"> <table id="displayWindow"> <tr><td colspan="2"><button type="submit" onmousedown="show_reply(false);" style="width: 80px; height: 50px"> <- Reply</button> <button type="submit" onmousedown="show_reply(true);" style="width: 100px; height: 50px"> <= Reply All</button> <button type="submit" onmousedown="forward();" style="width: 80px; height: 50px">Forward -></button></td></tr> <tr><td>From:</td><td id="displaySender" style="font-weight: bold;"></td></tr> <tr><td>To:</td><td id="displayReceipients" style="font-weight: bold;"></td></tr> <tr><td>CC:</td><td id="displayCC" style="display: none;"></td></tr> <tr><td>BCC:</td><td id="displayBCC" style="display: none;"></td></tr> <tr><td>Subject:</td><td id="displaySubject"></td></tr> <tr><td id="MessageDisplayOpenPGP" colspan="2"></td></tr> <tr><td colspan="2"><textarea cols="80" rows="30" readonly="readonly" id="displayMessage"></textarea></td></tr> <tr><td colspan="2"><button type="button" onclick="doDownload('application/octet-stream',$('#displayMessage').val());">Download</button></td></tr> </table> <table id="composeWindow"> <tr><td> <table id="reciepientTable"> <tr><td style="text-align: left;"><button id="encrypt" style="width: 50px; height: 50px" onmousedown="prepare_send_mail();">send</button></td><td colspan="2" style="text-align: left; font-size: 89%; border-bottom: 1px solid #aaa"><input style="width: 20px;" type="checkbox" id="sign_message"> Sign message <br/><input style="width: 20px;" type="checkbox" id="encrypt_message"> Encrypt message </td></tr> <tr class="reciepientsRow"><td>From:</td><td id="composerAddress"></td></tr> <tr class="reciepientsRow"><td><select class="reciepientSelect" id="reciepient_method_1" disabled="disabled"><option value="0">To:</option><option value="1">Cc:</option><option value="2">Bcc:</option></select></td><td><input id="firstto" name="recepient_1" type="text"></input></td><td><input class="reciepientAdd" id="reciepientAdd_1" type="button" value="+" onmousedown="add_reciepient();"></input></td></tr> </table></td></tr> <tr><td id="composeSubject">Subject:<input id="subjectInput" type="text" name="subject"></input></td></tr> <tr><td id="MessageComposeOpenPGP" colspan="2"></td></tr> <tr><td><textarea rows="30" cols="80" id="messageBody"></textarea></td></tr> </table> <div id="enterPassword"> <span id="enterPasswordText">Enter your Password for key</span> <span id="enterPasswordKeyId"></span>:<br/> <input type="password" id="enterPasswordInput" onkeypress="if (event.keyCode == 13) $('#enterPasswordSubmit').click(); "><button type="submit" id="enterPasswordSubmit">OK</button> </div> <div id="keyselect"> <div id="keyselecttext" style="margin: 5px;"></div> <div style="overflow: auto; height: 390px;"> <table id="keyselecttable"> </table> </div> <div style="text-align: right; margin: 5px;"> <button type="submit" onmousedown="showEncryptionConfirmation();">OK</button> <button type="submit" onmousedown="showEncryptionCancel();">Cancel</button> </div> </div> <div id="encryptionConfirmation"> </div> <div id="block-bg" style=" width: 100%; height: 100%; z-index: 2; display: none; position: fixed; top: 0px; background-color: black; opacity: 0.5;"></div> </body> </html>