diff --git a/.gitignore b/.gitignore
index 7c65f83d..6a4cd57f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,7 @@ npm*
test/lib/
resources/keyring_nodebug.js
resources/openpgp_nodebug.js
+resources/keyring.js
+resources/keyring.min.js
+resources/openpgp.js
+resources/openpgp.min.js
diff --git a/README.md b/README.md
index 3bfc433b..622b7068 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,15 @@
-[](http://travis-ci.org/openpgpjs/openpgpjs)
+OpenPGP.js [](http://travis-ci.org/openpgpjs/openpgpjs)
+==========
# What is OpenPGP.js?
[OpenPGP.js](http://openpgpjs.org/) is a Javascript implementation of the OpenPGP protocol. This is defined in [RFC 4880](http://tools.ietf.org/html/rfc4880).
# How do I use it?
-As a developer, the best place to start is in the `resources/` directory. Within this you will find a basic example implementation and the "binary" files for this library. It is likely that you will want to use `resources/openpgp.min.js` on your site, this is a minified version of our library.
+To build the library, download a tagged version from [releases](https://github.com/openpgpjs/openpgpjs/releases) and the build the library like so:
+
+ npm install && grunt
+
+Then take the use the minified file from `resources/openpgp.min.js` and use it in your project.
# I need some help
## Mailing List
@@ -15,7 +20,7 @@ A jsdoc build of our code comments is available at [doc/index.html](doc/index.ht
# How do I get involved?
You want to help, great! Go ahead and fork our repo, make your changes
-and make a pull request. **For any significant changes, use the "devel" branch. This will eventually be merged into the current master.** Please be sure that you run `make minify` from the root directory to concatenate and minify the library into the `resources/` directory.
+and make a pull request.
It is extra awesome if you write tests for the code you change. Our test coverage is relatively weak, so if you can add cases that is great.
diff --git a/plugins/chrome/background.html b/plugins/chrome/background.html
deleted file mode 100644
index afb49f28..00000000
--- a/plugins/chrome/background.html
+++ /dev/null
@@ -1,133 +0,0 @@
-
-
-
-
-
-
diff --git a/plugins/chrome/contentscripts.js b/plugins/chrome/contentscripts.js
deleted file mode 100644
index 8f244488..00000000
--- a/plugins/chrome/contentscripts.js
+++ /dev/null
@@ -1,244 +0,0 @@
-// GPG4Browsers - An OpenPGP implementation in javascript
-// Copyright (C) 2011 Recurity Labs GmbH
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-if (window.location.href.indexOf("https://mail.google.com/mail/?view=cm") == 0) {
- // we are running in the compose window
-} else {
- // we are running in the normal interface
- chrome.extension.sendRequest({account: document.getElementsByTagName("script")[4].text.split(",")[10].replace(/"/g,"").trim()}, function(response) {});
-
-}
-
-var current_message_type = -1;
-var current_message = null;
-
-/**
- * searches the given text for a pgp message. If a message is available the openpgp message dialog is shown
- * @param text text to be searched
- */
-function find_openpgp(text) {
- text = text.replace(/\r\n/g,"\n");
- if (document.location.hash != current_message) {
- if (/-----BEGIN PGP MESSAGE-----/.test(text) && /-----END PGP MESSAGE-----/.test(text)) {
- current_message= document.location.hash;
- current_message_type = 0;
- current_pgp_block = text.substring(text.indexOf("-----BEGIN PGP MESSAGE-----"), text.indexOf("-----END PGP MESSAGE-----")+25);
- current_pgp_block = current_pgp_block.replace(/\n/g,"").replace(/ /g,"\n").replace(//g,"");
- if (pgp_verifyCheckSum(current_pgp_block))
- show_pgp_alert();
-
- } else if (/-----BEGIN PGP SIGNED MESSAGE-----/.test(text) && /-----END PGP SIGNATURE-----/.test(text)) {
- current_message= document.location.hash;
- current_message_type = 1;
- current_pgp_block = text.substring(text.indexOf("-----BEGIN PGP SIGNED MESSAGE-----"), text.indexOf("-----END PGP SIGNATURE-----")+26);
- current_pgp_block = current_pgp_block.replace(/\n/g,"").replace(/ /g,"\n").replace(//g,"");
- if (pgp_verifyCheckSum(current_pgp_block.substring(current_pgp_block.indexOf("-----BEGIN PGP SIGNATURE-----"))))
- show_pgp_alert();
- } else {
- hide_pgp_alert();
- }
- }
-}
-
-var doc = null;
-
-/**
- * call routine to open the openpgp.html page for handling a message
- * @return null
- */
-function start_pgp_dialog() {
- //Gmail does not provide a generic way. to get message data out of the HTML interface so we parse the DOM
- Gmail.getMail(function(msg) {
- msg.action = 1;
- chrome.extension.sendRequest(msg, function(response) {
- // hide_pgp_alert(); // hide pgp alert after opening the openpgp window
- });
- });
-}
-
-/**
- * showing the pgp alert
- * @return
- */
-function show_pgp_alert() {
- var div = document.createElement("div");
- var buttonyes = document.createElement("button");
- var buttonno = document.createElement("button");
- buttonyes.setAttribute("type", "submit");
- buttonyes.addEventListener("mousedown", function () {
- var msg = start_pgp_dialog();
- });
- buttonno.setAttribute("type", "submit");
- buttonno.addEventListener("mousedown", function() { hide_pgp_alert(); }, true);
- buttonyes.appendChild(document.createTextNode("Yes"));
- buttonno.appendChild(document.createTextNode("No"));
- div.setAttribute("id", "gpg4browsers_alert");
- div.setAttribute("style","position: fixed; top: 0px; width: 100%; background-color: #eeeeff; border-bottom: 1px solid #aaa;");
- if (current_message_type == 0)
- div.appendChild(document.createTextNode("This mail is encrypted. Do you want to open it with OpenPGP.js?"));
- else if (current_message_type == 1)
- div.appendChild(document.createTextNode("This mail is signed. Do you want to open it with OpenPGP.js?"));
- div.appendChild(buttonyes);
- div.appendChild(buttonno);
- document.body.appendChild(div);
-};
-
-/**
- * hiding the pgp alert
- * @return
- */
-function hide_pgp_alert() {
- if (document.getElementById("gpg4browsers_alert") != null) {
- document.getElementById("gpg4browsers_alert").parentNode.removeChild(document.getElementById("gpg4browsers_alert"));
- }
-}
-
-/**
- * background process timer to constantly check the displayed page for pgp messages
- */
-window.setInterval(function() {
- find_openpgp(document.body.innerHTML);
- if (document.getElementById("canvas_frame") != null)
- find_openpgp(document.getElementById("canvas_frame").contentDocument.body.innerHTML);
-}, 1000);
-
-
-/**
- * verifies the checksum of an base64 encrypted pgp block
- * @param text containing the base64 block and the base64 encoded checksum
- * @return true if the checksum was correct, false otherwise
- */
-function pgp_verifyCheckSum(text) {
- var splittedtext = text.split('-----');
- var data = r2s(splittedtext[2].split('\n\n')[1].split("\n=")[0]);
- var checksum = splittedtext[2].split('\n\n')[1].split("\n=")[1].replace(/\n/g,"");
- var c = getCheckSum(data);
- var d = checksum;
- return c[0] == d[0] && c[1] == d[1] && c[2] == d[2];
-}
-
-/**
- * calculates the checksum over a given block of data
- * @param data block to be used
- * @return a string containing the base64 encoded checksum
- */
-function getCheckSum(data) {
- var c = createcrc24(data);
- var str = "" + String.fromCharCode(c >> 16)+
- String.fromCharCode((c >> 8) & 0xFF)+
- String.fromCharCode(c & 0xFF);
- return s2r(str);
-}
-
-
-/**
- * calculation routine for a CRC-24 checksum
- * @param data
- * @return
- */
-function createcrc24 (data) {
- var crc = 0xB704CE;
- var i;
- var mypos = 0;
- var len = data.length;
- while (len--) {
- crc ^= (data[mypos++].charCodeAt()) << 16;
- for (i = 0; i < 8; i++) {
- crc <<= 1;
- if (crc & 0x1000000)
- crc ^= 0x1864CFB;
- }
- }
- return crc & 0xFFFFFF;
-}
-
-// base64 implementation
-
-var b64s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
-
-/**
- * Converting Base64 data to a string
- * @param t base64 encoded data string
- * @return data string
- */
-function r2s(t) {
- var c, n;
- var r = '', s = 0, a = 0;
- var tl = t.length;
-
- for (n = 0; n < tl; n++) {
- c = b64s.indexOf(t.charAt(n));
- if (c >= 0) {
- if (s)
- r += String.fromCharCode(a | (c >> (6 - s)) & 255);
- s = (s + 2) & 7;
- a = (c << s) & 255;
- }
- }
- return r;
-}
-
-/**
- * Converting a data string to a base64 encoded string
- * @param t data string
- * @return base64 encoded data string
- */
-function s2r(t) {
- var a, c, n;
- var r = '', l = 0, s = 0;
- var tl = t.length;
-
- for (n = 0; n < tl; n++) {
- c = t.charCodeAt(n);
- if (s == 0) {
- r += b64s.charAt((c >> 2) & 63);
- a = (c & 3) << 4;
- } else if (s == 1) {
- r += b64s.charAt((a | (c >> 4) & 15));
- a = (c & 15) << 2;
- } else if (s == 2) {
- r += b64s.charAt(a | ((c >> 6) & 3));
- l += 1;
- if ((l % 60) == 0)
- r += "\n";
- r += b64s.charAt(c & 63);
- }
- l += 1;
- if ((l % 60) == 0)
- r += "\n";
-
- s += 1;
- if (s == 3)
- s = 0;
- }
- if (s > 0) {
- r += b64s.charAt(a);
- l += 1;
- if ((l % 60) == 0)
- r += "\n";
- r += '=';
- l += 1;
- }
- if (s == 1) {
- if ((l % 60) == 0)
- r += "\n";
- r += '=';
- }
-
- return r;
-}
diff --git a/plugins/chrome/images/icons/logo.png b/plugins/chrome/images/icons/logo.png
deleted file mode 100755
index eb8767cf..00000000
Binary files a/plugins/chrome/images/icons/logo.png and /dev/null differ
diff --git a/plugins/chrome/jquery.min.js b/plugins/chrome/jquery.min.js
deleted file mode 100644
index b2ac1747..00000000
--- a/plugins/chrome/jquery.min.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/*!
- * jQuery JavaScript Library v1.6.1
- * http://jquery.com/
- *
- * Copyright 2011, John Resig
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- * Copyright 2011, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
- *
- * Date: Thu May 12 15:04:36 2011 -0400
- */
-(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!cj[a]){var b=f("<"+a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),c.body.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write("");b=cl.createElement(a),cl.body.appendChild(b),d=f.css(b,"display"),c.body.removeChild(ck)}cj[a]=d}return cj[a]}function cu(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function ct(){cq=b}function cs(){setTimeout(ct,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g=0===c})}function W(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function O(a,b){return(a&&a!=="*"?a+".":"")+b.replace(A,"`").replace(B,"&")}function N(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function L(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function F(){return!0}function E(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function H(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(H,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=d.userAgent,x,y,z,A=Object.prototype.toString,B=Object.prototype.hasOwnProperty,C=Array.prototype.push,D=Array.prototype.slice,E=String.prototype.trim,F=Array.prototype.indexOf,G={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.1",length:0,size:function(){return this.length},toArray:function(){return D.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?C.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),y.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(D.apply(this,arguments),"slice",D.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:C,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;y.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!y){y=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",z,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",z),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&H()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):G[A.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!B.call(a,"constructor")&&!B.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||B.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};f=c.createElement("select"),g=f.appendChild(c.createElement("option")),h=a.getElementsByTagName("input")[0],j={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},h.checked=!0,j.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,j.optDisabled=!g.disabled;try{delete a.test}catch(s){j.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function b(){j.noCloneEvent=!1,a.detachEvent("onclick",b)}),a.cloneNode(!0).fireEvent("onclick")),h=c.createElement("input"),h.value="t",h.setAttribute("type","radio"),j.radioValue=h.value==="t",h.setAttribute("checked","checked"),a.appendChild(h),k=c.createDocumentFragment(),k.appendChild(a.firstChild),j.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",l=c.createElement("body"),m={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"};for(q in m)l.style[q]=m[q];l.appendChild(a),b.insertBefore(l,b.firstChild),j.appendChecked=h.checked,j.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,j.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="",j.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="