[git] GPGME - branch, javascript-binding, updated. gpgme-1.11.1-56-gc072675
by Maximilian Krambach
cvs at cvs.gnupg.org
Fri Jun 8 17:58:22 CEST 2018
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG Made Easy".
The branch, javascript-binding has been updated
via c072675f3f2d734297a348c6de810148fb1424a2 (commit)
from 7a072270ac031152ee034df0f5b6ef5e8bf7d394 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit c072675f3f2d734297a348c6de810148fb1424a2
Author: Maximilian Krambach <maximilian.krambach at intevation.de>
Date: Fri Jun 8 17:54:58 2018 +0200
js: change chunksize handling and decoding
--
* the nativeApp now sends all data in one base64-encoded string, which
needs reassembly, but in a much easier way now.
* there are some new performance problems now, especially with
decrypting data
diff --git a/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js b/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js
index a84be27..bd72c1d 100644
--- a/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js
+++ b/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js
@@ -152,7 +152,7 @@ describe('Encryption and Decryption', function () {
let prm = Gpgmejs.init();
prm.then(function (context) {
context.encrypt(b64data,
- inputvalues.encrypt.good.fingerprint).then(
+ inputvalues.encrypt.good.fingerprint, true).then(
function (answer) {
expect(answer).to.not.be.empty;
expect(answer.data).to.be.a('string');
@@ -185,33 +185,7 @@ describe('Encryption and Decryption', function () {
'BEGIN PGP MESSAGE');
expect(answer.data).to.include(
'END PGP MESSAGE');
- context.decrypt(answer.data, true).then(
- function (result) {
- expect(result).to.not.be.empty;
- expect(result.data).to.be.a('string');
- expect(result.data).to.equal(b64data);
- done();
- });
- });
- });
- }).timeout(3000);
-
- it('Random data, input and output as base64', function (done) {
- let data = bigBoringString(0.0001);
- let b64data = btoa(data);
- let prm = Gpgmejs.init();
- prm.then(function (context) {
- context.encrypt(b64data,
- inputvalues.encrypt.good.fingerprint).then(
- function (answer) {
- expect(answer).to.not.be.empty;
- expect(answer.data).to.be.a('string');
-
- expect(answer.data).to.include(
- 'BEGIN PGP MESSAGE');
- expect(answer.data).to.include(
- 'END PGP MESSAGE');
- context.decrypt(answer.data, true).then(
+ context.decrypt(answer.data).then(
function (result) {
expect(result).to.not.be.empty;
expect(result.data).to.be.a('string');
@@ -222,5 +196,4 @@ describe('Encryption and Decryption', function () {
});
}).timeout(3000);
-
});
diff --git a/lang/js/BrowserTestExtension/tests/longRunningTests.js b/lang/js/BrowserTestExtension/tests/longRunningTests.js
index eefe126..e148d1c 100644
--- a/lang/js/BrowserTestExtension/tests/longRunningTests.js
+++ b/lang/js/BrowserTestExtension/tests/longRunningTests.js
@@ -24,7 +24,7 @@
/* global bigString, inputvalues */
describe('Long running Encryption/Decryption', function () {
- for (let i=0; i < 100; i++) {
+ for (let i=0; i < 101; i++) {
it('Successful encrypt/decrypt completely random data ' +
(i+1) + '/100', function (done) {
let prm = Gpgmejs.init();
@@ -43,30 +43,32 @@ describe('Long running Encryption/Decryption', function () {
function(result){
expect(result).to.not.be.empty;
expect(result.data).to.be.a('string');
+ /*
if (result.data.length !== data.length) {
- // console.log('diff: ' +
- // (result.data.length - data.length));
+ console.log('diff: ' +
+ (result.data.length - data.length));
for (let i=0; i < result.data.length; i++){
if (result.data[i] !== data[i]){
- // console.log('position: ' + i);
- // console.log('result : ' +
- // result.data.charCodeAt(i) +
- // result.data[i-2] +
- // result.data[i-1] +
- // result.data[i] +
- // result.data[i+1] +
- // result.data[i+2]);
- // console.log('original: ' +
- // data.charCodeAt(i) +
- // data[i-2] +
- // data[i-1] +
- // data[i] +
- // data[i+1] +
- // data[i+2]);
+ console.log('position: ' + i);
+ console.log('result : ' +
+ result.data.charCodeAt(i) +
+ result.data[i-2] +
+ result.data[i-1] +
+ result.data[i] +
+ result.data[i+1] +
+ result.data[i+2]);
+ console.log('original: ' +
+ data.charCodeAt(i) +
+ data[i-2] +
+ data[i-1] +
+ data[i] +
+ data[i+1] +
+ data[i+2]);
break;
}
}
}
+ */
expect(result.data).to.equal(data);
done();
});
diff --git a/lang/js/src/Connection.js b/lang/js/src/Connection.js
index e9c0b21..f399b22 100644
--- a/lang/js/src/Connection.js
+++ b/lang/js/src/Connection.js
@@ -108,6 +108,7 @@ export class Connection{
return Promise.reject(gpgme_error('MSG_INCOMPLETE'));
}
let me = this;
+ let chunksize = message.chunksize;
return new Promise(function(resolve, reject){
let answer = new Answer(message);
let listener = function(msg) {
@@ -115,22 +116,27 @@ export class Connection{
me._connection.onMessage.removeListener(listener);
me._connection.disconnect();
reject(gpgme_error('CONN_EMPTY_GPG_ANSWER'));
- } else if (msg.type === 'error'){
- me._connection.onMessage.removeListener(listener);
- me._connection.disconnect();
- reject(gpgme_error('GNUPG_ERROR', msg.msg));
} else {
- let answer_result = answer.add(msg);
+ let answer_result = answer.collect(msg);
if (answer_result !== true){
me._connection.onMessage.removeListener(listener);
me._connection.disconnect();
reject(answer_result);
- } else if (msg.more === true){
- me._connection.postMessage({'op': 'getmore'});
} else {
- me._connection.onMessage.removeListener(listener);
- me._connection.disconnect();
- resolve(answer.message);
+ if (msg.more === true){
+ me._connection.postMessage({
+ 'op': 'getmore',
+ 'chunksize': chunksize
+ });
+ } else {
+ me._connection.onMessage.removeListener(listener);
+ me._connection.disconnect();
+ if (answer.message instanceof Error){
+ reject(answer.message);
+ } else {
+ resolve(answer.message);
+ }
+ }
}
}
};
@@ -170,19 +176,32 @@ class Answer{
constructor(message){
this.operation = message.operation;
- this.expected = message.expected;
+ this.expect = message.expect;
}
- /**
- * Add the information to the answer
- * @param {Object} msg The message as received with nativeMessaging
- * returns true if successfull, gpgme_error otherwise
- */
- add(msg){
- if (this._response === undefined){
- this._response = {};
+ collect(msg){
+ if (typeof(msg) !== 'object' || !msg.hasOwnProperty('response')) {
+ return gpgme_error('CONN_UNEXPECTED_ANSWER');
+ }
+ if (this._responseb64 === undefined){
+ //this._responseb64 = [msg.response];
+ this._responseb64 = msg.response;
+ return true;
+ } else {
+ //this._responseb64.push(msg.response);
+ this._responseb64 += msg.response;
+ return true;
}
- let messageKeys = Object.keys(msg);
+ }
+
+ get message(){
+ if (this._responseb64 === undefined){
+ return gpgme_error('CONN_UNEXPECTED_ANSWER');
+ }
+ // let _decodedResponse = JSON.parse(atob(this._responseb64.join('')));
+ let _decodedResponse = JSON.parse(atob(this._responseb64));
+ let _response = {};
+ let messageKeys = Object.keys(_decodedResponse);
let poa = permittedOperations[this.operation].answer;
if (messageKeys.length === 0){
return gpgme_error('CONN_UNEXPECTED_ANSWER');
@@ -191,80 +210,42 @@ class Answer{
let key = messageKeys[i];
switch (key) {
case 'type':
- if ( msg.type !== 'error' && poa.type.indexOf(msg.type) < 0){
+ if (_decodedResponse.type === 'error'){
+ return (gpgme_error('GNUPG_ERROR', _decodedResponse.msg));
+ } else if (poa.type.indexOf(_decodedResponse.type) < 0){
return gpgme_error('CONN_UNEXPECTED_ANSWER');
}
break;
- case 'more':
+ case 'base64':
break;
- default:
- //data should be concatenated
- if (poa.data.indexOf(key) >= 0){
- if (!this._response.hasOwnProperty(key)){
- this._response[key] = '';
- }
- this._response[key] += msg[key];
- }
- //params should not change through the message
- else if (poa.params.indexOf(key) >= 0){
- if (!this._response.hasOwnProperty(key)){
- this._response[key] = msg[key];
- }
- else if (this._response[key] !== msg[key]){
- return gpgme_error('CONN_UNEXPECTED_ANSWER',msg[key]);
- }
+ case 'msg':
+ if (_decodedResponse.type === 'error'){
+ return (gpgme_error('GNUPG_ERROR', _decodedResponse.msg));
}
- //infos may be json objects etc. Not yet defined.
- // Pushing them into arrays for now
- else if (poa.infos.indexOf(key) >= 0){
- if (!this._response.hasOwnProperty(key)){
- this._response[key] = [];
- }
-
- if (Array.isArray(msg[key])) {
- for (let i=0; i< msg[key].length; i++) {
- this._response[key].push(msg[key][i]);
- }
- } else {
- this._response[key].push(msg[key]);
- }
+ break;
+ default:
+ if (!poa.data.hasOwnProperty(key)){
+ return gpgme_error('CONN_UNEXPECTED_ANSWER');
}
- else {
+ if( typeof(_decodedResponse[key]) !== poa.data[key] ){
return gpgme_error('CONN_UNEXPECTED_ANSWER');
}
- break;
- }
- }
- return true;
- }
-
- /**
- * @returns {Object} the assembled message, original data assumed to be
- * (javascript-) strings
- */
- get message(){
- let keys = Object.keys(this._response);
- let msg = {};
- let poa = permittedOperations[this.operation].answer;
- for (let i=0; i < keys.length; i++) {
- if (poa.data.indexOf(keys[i]) >= 0
- && this._response.base64 === true
- ) {
- msg[keys[i]] = atob(this._response[keys[i]]);
- if (this.expected === 'base64'){
- msg[keys[i]] = this._response[keys[i]];
- } else {
- msg[keys[i]] = decodeURIComponent(
- atob(this._response[keys[i]]).split('').map(
+ if (_decodedResponse.base64 === true
+ && poa.data[key] === 'string'
+ && this.expect === undefined
+ ){
+ _response[key] = decodeURIComponent(
+ atob(_decodedResponse[key]).split('').map(
function(c) {
return '%' +
- ('00' + c.charCodeAt(0).toString(16)).slice(-2);
+ ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
+ } else {
+ _response[key] = _decodedResponse[key];
}
- } else {
- msg[keys[i]] = this._response[keys[i]];
+ break;
}
}
- return msg;
+ return _response;
}
}
diff --git a/lang/js/src/Message.js b/lang/js/src/Message.js
index 0ddda6c..7ccf7ef 100644
--- a/lang/js/src/Message.js
+++ b/lang/js/src/Message.js
@@ -46,7 +46,6 @@ export class GPGME_Message {
constructor(operation){
this.operation = operation;
- this._expected = 'string';
}
set operation (op){
@@ -59,24 +58,50 @@ export class GPGME_Message {
}
}
}
-
get operation(){
return this._msg.op;
}
- set expected(string){
- if (string === 'base64'){
- this._expected = 'base64';
+ /**
+ * Set the maximum size of responses from gpgme in bytes. Values allowed
+ * range from 10kB to 1MB. The lower limit is arbitrary, the upper limit
+ * fixed by browsers' nativeMessaging specifications
+ */
+ set chunksize(value){
+ if (
+ Number.isInteger(value) &&
+ value > 10 * 1024 &&
+ value <= 1024 * 1024
+ ){
+ this._chunksize = value;
+ }
+ }
+ get chunksize(){
+ if (this._chunksize === undefined){
+ return 1024 * 1023;
+ } else {
+ return this._chunksize;
}
}
- get expected() {
- if (this._expected === 'base64'){
- return this._expected;
+ /**
+ * If expect is set to 'base64', the response is expected to be base64
+ * encoded binary
+ */
+ set expect(value){
+ if (value ==='base64'){
+ this._expect = value;
+ }
+ }
+
+ get expect(){
+ if ( this._expect === 'base64'){
+ return this._expect;
}
- return 'string';
+ return undefined;
}
+
/**
* Sets a parameter for the message. Note that the operation has to be set
* first, to be able to check if the parameter is permittted
@@ -188,6 +213,7 @@ export class GPGME_Message {
*/
get message(){
if (this.isComplete === true){
+ this._msg.chunksize = this.chunksize;
return this._msg;
}
else {
@@ -201,10 +227,13 @@ export class GPGME_Message {
return new Promise(function(resolve, reject) {
if (me.isComplete === true) {
let conn = new Connection;
+ if (me._msg.chunksize === undefined){
+ me._msg.chunksize = 1023*1024;
+ }
conn.post(me).then(function(response) {
resolve(response);
}, function(reason) {
- reject(gpgme_error('GNUPG_ERROR', reason));
+ reject(reason);
});
}
else {
diff --git a/lang/js/src/gpgmejs.js b/lang/js/src/gpgmejs.js
index cbad902..09bca7f 100644
--- a/lang/js/src/gpgmejs.js
+++ b/lang/js/src/gpgmejs.js
@@ -57,8 +57,8 @@ export class GpgME {
* Keys used to encrypt the message
* @param {GPGME_Key|String|Array<String>|Array<GPGME_Key>} secretKeys
* (optional) Keys used to sign the message
- * @param {Boolean} base64 (optional) The data is already considered to be
- * in base64 encoding
+ * @param {Boolean} base64 (optional) The data will be interpreted as
+ * base64 encoded data
* @param {Boolean} armor (optional) Request the output as armored block
* @param {Boolean} wildcard (optional) If true, recipient information will
* not be added to the message
@@ -109,24 +109,20 @@ export class GpgME {
* Decrypt a Message
* @param {String|Object} data text/data to be decrypted. Accepts Strings
* and Objects with a getText method
- * @param {Boolean} base64 (optional) Response is expected to be base64
- * encoded
* @returns {Promise<Object>} decrypted message:
- data: The decrypted data. This may be base64 encoded.
+ data: The decrypted data.
base64: Boolean indicating whether data is base64 encoded.
mime: A Boolean indicating whether the data is a MIME object.
signatures: Array of signature Objects TODO not yet implemented.
- // should be an object that can tell if all signatures are valid .
+ // should be an object that can tell if all signatures are valid.
* @async
*/
- decrypt(data, base64=false){
+ decrypt(data){
if (data === undefined){
return Promise.reject(gpgme_error('MSG_EMPTY'));
}
let msg = createMessage('decrypt');
- if (base64 === true){
- msg.expected = 'base64';
- }
+
if (msg instanceof Error){
return Promise.reject(msg);
}
@@ -165,10 +161,10 @@ export class GpgME {
}
msg.setParameter('mode', mode);
putData(msg, data);
- if (mode === 'detached') {
- msg.expected = 'base64';
- }
return new Promise(function(resolve,reject) {
+ if (mode ==='detached'){
+ msg.expect= 'base64';
+ }
msg.post().then( function(message) {
if (mode === 'clearsign'){
resolve({
diff --git a/lang/js/src/permittedOperations.js b/lang/js/src/permittedOperations.js
index 445a40c..6ac33af 100644
--- a/lang/js/src/permittedOperations.js
+++ b/lang/js/src/permittedOperations.js
@@ -37,11 +37,8 @@
5000 ms would be too short
answer: <Object>
type: <String< The content type of answer expected
- data: Array<String> The payload property of the answer. May be
- partial and in need of concatenation
- params: Array<String> Information that do not change throughout
- the message
- infos: Array<*> arbitrary information that may result in a list
+ data: <Object>
+ the properties expected and their type, eg: {'data':'string'}
}
}
*/
@@ -67,9 +64,6 @@ export const permittedOperations = {
allowed: ['string'],
array_allowed: true
},
- 'chunksize': {
- allowed: ['number']
- },
'base64': {
allowed: ['boolean']
},
@@ -101,9 +95,10 @@ export const permittedOperations = {
},
answer: {
type: ['ciphertext'],
- data: ['data'],
- params: ['base64'],
- infos: []
+ data: {
+ 'data': 'string',
+ 'base64':'boolean'
+ }
}
},
@@ -119,18 +114,18 @@ export const permittedOperations = {
allowed: ['string'],
allowed_data: ['cms', 'openpgp']
},
- 'chunksize': {
- allowed: ['number'],
- },
'base64': {
allowed: ['boolean']
}
},
answer: {
type: ['plaintext'],
- data: ['data'],
- params: ['base64', 'mime'],
- infos: ['signatures']
+ data: {
+ 'data': 'string',
+ 'base64': 'boolean',
+ 'mime': 'boolean',
+ 'signatures': 'object'
+ }
}
},
@@ -149,9 +144,6 @@ export const permittedOperations = {
allowed: ['string'],
allowed_data: ['cms', 'openpgp']
},
- 'chunksize': {
- allowed: ['number'],
- },
'sender': {
allowed: ['string'],
},
@@ -169,10 +161,11 @@ export const permittedOperations = {
},
answer: {
type: ['signature', 'ciphertext'],
- data: ['data'], // Unless armor mode is used a Base64 encoded binary
- // signature. In armor mode a string with an armored
- // OpenPGP or a PEM message.
- params: ['base64']
+ data: {
+ 'data': 'string',
+ 'base64':'boolean'
+ }
+
}
},
@@ -186,9 +179,6 @@ export const permittedOperations = {
allowed: ['string'],
allowed_data: ['cms', 'openpgp']
},
- 'chunksize': {
- allowed: ['number'],
- },
'secret': {
allowed: ['boolean']
},
@@ -220,9 +210,10 @@ export const permittedOperations = {
},
answer: {
type: ['keys'],
- data: [],
- params: ['base64'],
- infos: ['keys']
+ data: {
+ 'base64': 'boolean',
+ 'keys': 'object'
+ }
}
},
@@ -233,9 +224,6 @@ export const permittedOperations = {
allowed: ['string'],
allowed_data: ['cms', 'openpgp']
},
- 'chunksize': {
- allowed: ['number'],
- },
'keys': {
allowed: ['string'],
array_allowed: true
@@ -259,8 +247,10 @@ export const permittedOperations = {
},
answer: {
type: ['keys'],
- data: ['data'],
- params: ['base64']
+ data: {
+ 'data': 'string',
+ 'base64': 'boolean'
+ }
}
},
@@ -280,10 +270,10 @@ export const permittedOperations = {
},
},
answer: {
- infos: ['result'],
type: [],
- data: [],
- params: []
+ data: {
+ 'result': 'Object'
+ }
}
},
@@ -299,15 +289,15 @@ export const permittedOperations = {
allowed: ['string'],
allowed_data: ['cms', 'openpgp']
},
- // 'secret': { not yet implemented
+ // 'secret': { not implemented
// allowed: ['boolean']
// }
},
answer: {
- data: [],
- params:['success'],
- infos: []
+ data: {
+ 'success': 'boolean'
+ }
}
},
@@ -316,9 +306,10 @@ export const permittedOperations = {
optional: {},
answer: {
type: [''],
- data: ['gpgme'],
- infos: ['info'],
- params:[]
+ data: {
+ 'gpgme': 'string',
+ 'info': 'object'
+ }
}
}
diff --git a/lang/js/unittests.js b/lang/js/unittests.js
index ce1dd0c..169e8eb 100644
--- a/lang/js/unittests.js
+++ b/lang/js/unittests.js
@@ -339,7 +339,8 @@ function unittests (){
test0.setParameter('keys', hp.validFingerprints);
expect(test0.message).to.not.be.null;
- expect(test0.message).to.have.keys('op', 'data', 'keys');
+ expect(test0.message).to.have.keys('op', 'data', 'keys',
+ 'chunksize');
expect(test0.message.op).to.equal('encrypt');
expect(test0.message.data).to.equal(
mp.valid_encrypt_data);
-----------------------------------------------------------------------
Summary of changes:
.../tests/encryptDecryptTest.js | 31 +----
.../BrowserTestExtension/tests/longRunningTests.js | 38 +++---
lang/js/src/Connection.js | 143 +++++++++------------
lang/js/src/Message.js | 49 +++++--
lang/js/src/gpgmejs.js | 22 ++--
lang/js/src/permittedOperations.js | 81 ++++++------
lang/js/unittests.js | 3 +-
7 files changed, 170 insertions(+), 197 deletions(-)
hooks/post-receive
--
GnuPG Made Easy
http://git.gnupg.org
More information about the Gnupg-commits
mailing list