js: implement import/delete Key, some fixes
authorMaximilian Krambach <maximilian.krambach@intevation.de>
Wed, 6 Jun 2018 09:57:41 +0000 (11:57 +0200)
committerMaximilian Krambach <maximilian.krambach@intevation.de>
Wed, 6 Jun 2018 09:57:41 +0000 (11:57 +0200)
--

* Keyring.js
   - implemented importKey: importing one or more armored public key
     blocks.
   - implemented deleteKey: deleting a public Key from gpg.

* Key.js renamed property Key.armor to Key.armored

* Helpers.js: toKeyIDArray does not complain anymore if there are no
  keys. Not having Keys in e.g. signing keys in encrypt is legitimate
  and common, the complaints were getting spammy

* Errors.js: gpgme_errors now always pass an optional additional
  message, for easier debugging in minified code

* Connection.js: Fix in gpgme-json responses containing objects

* eslintrc.json: Start using eslint. A cleanup to conform to it is not
  done yet

* Added further tests for the new functionality

12 files changed:
lang/js/.eslintrc.json [new file with mode: 0644]
lang/js/BrowserTestExtension/browsertest.html
lang/js/BrowserTestExtension/tests/KeyImportExport.js [new file with mode: 0644]
lang/js/BrowserTestExtension/tests/encryptDecryptTest.js
lang/js/BrowserTestExtension/tests/inputvalues.js
lang/js/src/Connection.js
lang/js/src/Errors.js
lang/js/src/Helpers.js
lang/js/src/Key.js
lang/js/src/Keyring.js
lang/js/unittest_inputvalues.js
lang/js/unittests.js

diff --git a/lang/js/.eslintrc.json b/lang/js/.eslintrc.json
new file mode 100644 (file)
index 0000000..65253cf
--- /dev/null
@@ -0,0 +1,29 @@
+{
+    "env": {
+        "browser": true,
+        "es6": true
+    },
+    "extends": "eslint:recommended",
+    "parserOptions": {
+        "sourceType": "module"
+    },
+    "rules": {
+        "indent": [
+            "warn",
+            4
+        ],
+        "linebreak-style": [
+            "error",
+            "unix"
+        ],
+        "quotes": [
+            "error",
+            "single"
+        ],
+        "semi": [
+            "error",
+            "always"
+        ],
+        "max-len": 1
+    }
+}
\ No newline at end of file
index 3d81a9e..f3d7a40 100644 (file)
@@ -18,6 +18,7 @@
     <script src="tests/encryptTest.js"></script>
     <script src="tests/encryptDecryptTest.js"></script>
     <script src="tests/signTest.js"></script>
+    <script src="tests/KeyImportExport.js"></script>
 <!-- run tests -->
     <script src="runbrowsertest.js"></script>
     </body>
diff --git a/lang/js/BrowserTestExtension/tests/KeyImportExport.js b/lang/js/BrowserTestExtension/tests/KeyImportExport.js
new file mode 100644 (file)
index 0000000..e6eb5a3
--- /dev/null
@@ -0,0 +1,83 @@
+/* gpgme.js - Javascript integration for gpgme
+ * Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME 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.
+ *
+ * GPGME 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 program; if not, see <http://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+/* global describe, it, expect, Gpgmejs, ImportablePublicKey */
+
+describe('Key importing', function () {
+    it('Prepare test Key (deleting it from gnupg, if present)', function(done){
+        let prm = Gpgmejs.init();
+        prm.then(function (context) {
+            expect(context.Keyring.getKeys).to.be.a('function');
+            context.Keyring.getKeys(ImportablePublicKey.fingerprint).then(
+                function(result){
+                    if (result.length === 1) {
+                        result[0].delete().then(function(result){
+                            expect(result).to.be.true;
+                            done();
+                        });
+                    } else {
+                        done();
+                    }
+                });
+        });
+    });
+
+    it('importing, updating, then deleting public Key', function (done) {
+        //This test runs in one large step, to ensure the proper state of the
+        // key in all stages.
+        let prm = Gpgmejs.init();
+        prm.then(function (context) {
+            context.Keyring.getKeys(ImportablePublicKey.fingerprint).then(
+                function(result){
+                    expect(result).to.be.an('array');
+                    expect(result.length).to.equal(0);
+                    context.Keyring.importKey(ImportablePublicKey.key, true)
+                        .then(function(result){
+                            expect(result[0]).to.not.be.undefined;
+                            expect(result[0].key).to.be.an('object');
+                            expect(result[0].key.fingerprint).to.equal(
+                                ImportablePublicKey.fingerprint);
+                            expect(result[0].status).to.equal('newkey');
+                            context.Keyring.importKey(
+                                ImportablePublicKey.keyChangedUserId,true)
+                                .then(function(res){
+                                    expect(res[0]).to.not.be.undefined;
+                                    expect(res[0].key).to.be.an('object');
+                                    expect(res[0].key.fingerprint).to.equal(
+                                        ImportablePublicKey.fingerprint);
+                                    expect(res[0].status).to.equal(
+                                        'change');
+                                    expect(
+                                        res[0].changes.userId).to.be.true;
+                                    expect(
+                                        res[0].changes.subkey).to.be.false;
+                                    expect(
+                                        res[0].changes.signature).to.be.true;
+                                    res[0].key.delete().then(function(result){
+                                        expect(result).to.be.true;
+                                        done();
+                                    });
+                                });
+                        });
+                });
+        });
+    });
+
+});
\ No newline at end of file
index f5d2be1..e5c2f74 100644 (file)
@@ -163,7 +163,6 @@ describe('Encryption and Decryption', function () {
     }).timeout(3000);
 
     it('Random data, input as base64', function (done) {
-        //TODO fails. The result is
         let data = bigBoringString(0.001);
         let b64data = btoa(data);
         let prm = Gpgmejs.init();
@@ -177,11 +176,11 @@ describe('Encryption and Decryption', function () {
                         'BEGIN PGP MESSAGE');
                     expect(answer.data).to.include(
                         'END PGP MESSAGE');
-                    context.decrypt(answer.data).then(
+                    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(data);
+                            expect(result.data).to.equal(b64data);
                             done();
                         });
                 });
index 52e3a7b..9dc1332 100644 (file)
  * SPDX-License-Identifier: LGPL-2.1+
  */
 
-var inputvalues = {
+var inputvalues = {// eslint-disable-line no-unused-vars
     encrypt: {
         good:{
             data : 'Hello World.',
-            // Fingerprint of a key that has been imported to gnupg (i.e. see testkey.pub; testkey.sec)
+            // Fingerprint of a key that has been imported to gnupg
+            // (i.e. see testkey.pub; testkey.sec)
             fingerprint : 'D41735B91236FDB882048C5A2301635EEFF0CB05',
             data_nonascii: '¡Äußerste µ€ før ñoquis@hóme! Добрый день',
 
@@ -45,7 +46,8 @@ var inputvalues = {
             ]
         },
         bad: {
-            // valid Hex value, but not usable (not imported to gnupg, or bogus fingerprint)
+            // valid Hex value, but not usable (not imported to gnupg, or
+            // bogus fingerprint)
             fingerprint: 'CDC3A2B2860625CCBFC5AAAAAC6D1B604967FC4A'
         }
     },
@@ -54,14 +56,13 @@ var inputvalues = {
         invalid_startups: [
             {all_passwords: true},
             'openpgpmode',
-            {api_style:"frankenstein"}
+            {api_style:'frankenstein'}
         ]
     }
 };
 
 // (Pseudo-)Random String covering all of utf8.
-function bigString(length){
-    var uint = '';
+function bigString(length){// eslint-disable-line no-unused-vars
     let arr = [];
     for (let i= 0; i < length; i++){
         arr.push(String.fromCharCode(
@@ -71,7 +72,7 @@ function bigString(length){
     return arr.join('');
 }
 
-function fixedLengthString(megabytes){
+function fixedLengthString(megabytes){// eslint-disable-line no-unused-vars
     let maxlength = 1024 * 1024 * megabytes / 2;
     let uint = new Uint8Array(maxlength);
     for (let i = 0; i < maxlength; i++){
@@ -83,7 +84,7 @@ function fixedLengthString(megabytes){
 }
 
 // (Pseudo-)Random Uint8Array, given size in Megabytes
-function bigUint8(megabytes){
+function bigUint8(megabytes){// eslint-disable-line no-unused-vars
     let maxlength = 1024 * 1024 * megabytes;
     let uint = new Uint8Array(maxlength);
     for (let i= 0; i < maxlength; i++){
@@ -92,11 +93,13 @@ function bigUint8(megabytes){
     return uint;
 }
 
-// (Pseudo-)Random string with very limited charset (ascii only, no control chars)
-function bigBoringString(megabytes){
+// (Pseudo-)Random string with very limited charset
+// (ascii only, no control chars)
+function bigBoringString(megabytes){// eslint-disable-line no-unused-vars
     let maxlength = 1024 * 1024 * megabytes;
     let string = [];
-    let chars = ' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+    let chars =
+        ' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
     for (let i= 0; i < maxlength; i++){
         string.push(chars[Math.floor(Math.random() * chars.length)]);
     }
@@ -105,12 +108,13 @@ function bigBoringString(megabytes){
 
 // Some String with simple chars, with different characteristics, but still
 // expected to occur in an averag message
+// eslint-disable-next-line no-unused-vars
 function slightlyLessBoringString(megabytes, set){
     let maxlength = 1024 * 1024 * megabytes;
     let string = [];
     let chars = '';
     if (set ===1 ) {
-        chars = '\n\"\r \'';
+        chars = '\n"\r \'';
     } else if (set === 2 ) {
         chars = '()=?`#+-{}[]';
     } else if (set === 3){
@@ -118,7 +122,7 @@ function slightlyLessBoringString(megabytes, set){
     } else if (set ===4) {
         chars = 'äüßµüþÖ~ɁÑ||@';
     } else {
-        chars = '*<>\n\"\r§$%&/()=?`#+-{}[] \'';
+        chars = '*<>\n"\r§$%&/()=?`#+-{}[] \'';
     }
     for (let i= 0; i < maxlength; i++){
         string.push(chars[Math.floor(Math.random() * chars.length)]);
@@ -127,7 +131,7 @@ function slightlyLessBoringString(megabytes, set){
 }
 
 // Data encrypted with testKey
-var encryptedData =
+var encryptedData =// eslint-disable-line no-unused-vars
     '-----BEGIN PGP MESSAGE-----\n' +
     '\n' +
     'hQEMA6B8jfIUScGEAQgAlANd3uyhmhYLzVcfz4LEqA8tgUC3n719YH0iuKEzG/dv\n' +
@@ -141,3 +145,76 @@ var encryptedData =
     'kSAQYOHplfA7YJWkrlRm\n' +
     '=zap6\n' +
     '-----END PGP MESSAGE-----\n';
+
+var ImportablePublicKey = {// eslint-disable-line no-unused-vars
+    fingerprint: '78034948BA7F5D0E9BDB67E4F63790C11E60278A',
+    key:'-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
+    '\n' +
+    'mQENBFsPvK0BCACaIgoIN+3g05mrTITULK/YDTrfg4W7RdzIZBxch5CM0zdu/dby\n' +
+    'esFwaJbVQIqu54CRz5xKAiWmRrQCaRvhvjY0na5r5UUIpbeQiOVrl65JtNbRmlik\n' +
+    'd9Prn1kZDUOZiCPIKn+/M2ecJ92YedM7I4/BbpiaFB11cVrPFg4thepn0LB3+Whp\n' +
+    '9HDm4orH9rjy6IUr6yjWNIr+LYRY6/Ip2vWcMVjleEpTFznXrm83hrJ0n0INtyox\n' +
+    'Nass4eDWkgo6ItxDFFLOORSmpfrToxZymSosWqgux/qG6sxHvLqlqy6Xe3ZYRFbG\n' +
+    '+JcA1oGdwOg/c0ndr6BYYiXTh8+uUJfEoZvzABEBAAG0HEJsYSBCbGEgPGJsYWJs\n' +
+    'YUBleGFtcGxlLm9yZz6JAVQEEwEIAD4WIQR4A0lIun9dDpvbZ+T2N5DBHmAnigUC\n' +
+    'Ww+8rQIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRD2N5DBHmAn\n' +
+    'igwIB/9K3E3Yev9taZP4KnXPhk1oMQRW1MWAsFGUr+70N85VwedpUawymW4vXi1+\n' +
+    'hMeTc39QjmZ0+VqHkJttkqEN6bLcEvgmU/mOlOgKdzy6eUcasYAzgoAKUqSX1SPs\n' +
+    '0Imo7Tj04wnfnVwvKxaeadi0VmdqIYaW75UlrzIaltsBctyeYH8sBrvaTLscb4ON\n' +
+    '46OM3Yw2G9+dBF0P+4UYFHP3EYZMlzNxfwF+i2HsYcNDHlcLfjENr9GwKn5FJqpY\n' +
+    'Iq3qmI37w1hVasHDxXdz1X06dpsa6Im4ACk6LXa7xIQlXxTgPAQV0sz2yB5eY+Md\n' +
+    'uzEXPGW+sq0WRp3hynn7kVP6QQYvuQENBFsPvK0BCACwvBcmbnGJk8XhEBRu2QN3\n' +
+    'jKgVs3CG5nE2Xh20JipZwAuGHugDLv6/jlizzz5jtj3SAHVtJB8lJW8I0cNSEIX8\n' +
+    'bRYH4C7lP2DTb9CgMcGErQIyK480+HIsbsZhJSNHdjUUl6IPEEVfSQzWaufmuswe\n' +
+    'e+giqHiTsaiW20ytXilwVGpjlHBaxn/bpskZ0YRasgnPqKgJD3d5kunNqWoyCpMc\n' +
+    'FYgDERvPbhhceFbvFE9G/u3gbcuV15mx53dDX0ImvPcvJnDOyJS9yr7ApdOV312p\n' +
+    'A1MLbxfPnbnVu+dGXn7D/VCDd5aBYVPm+5ANrk6z9lYKH9aO5wgXpLAdJvutCOL5\n' +
+    'ABEBAAGJATwEGAEIACYWIQR4A0lIun9dDpvbZ+T2N5DBHmAnigUCWw+8rQIbDAUJ\n' +
+    'A8JnAAAKCRD2N5DBHmAnigMVB/484G2+3R0cAaj3V/z4gW3MRSMhcYqEMyJ/ACdo\n' +
+    '7y8eoreYW843JWWVDRY6/YcYYGuBBP47WO4JuP2wIlVn17XOCSgnNjmmjsIYiAzk\n' +
+    'op772TB27o0VeiFX5iWcawy0EI7JCb23xpI+QP31ksL2yyRYFXCtXSUfcOrLpCY8\n' +
+    'aEQMQbAGtkag1wHTo/Tf/Vip8q0ZEQ4xOKTR2/ll6+inP8kzGyzadElUnH1Q1OUX\n' +
+    'd2Lj/7BpBHE2++hAjBQRgnyaONF7mpUNEuw64iBNs0Ce6Ki4RV2+EBLnFubnFNRx\n' +
+    'fFJcYXcijhuf3YCdWzqYmPpU/CtF4TgDlfSsdxHxVOmnZkY3\n' +
+    '=qP6s\n' +
+    '-----END PGP PUBLIC KEY BLOCK-----\n',
+
+    keyChangedUserId: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
+    '\n' +
+    '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\n' +
+    '=9WZ7\n' +
+    '-----END PGP PUBLIC KEY BLOCK-----\n'
+};
index 3480d81..8c4cba7 100644 (file)
@@ -103,7 +103,7 @@ export class Connection{
         }
         if (!message || !message instanceof GPGME_Message){
             this.disconnect();
-            return Promise.reject(gpgme_error('PARAM_WRONG'), message);
+            return Promise.reject(gpgme_error('PARAM_WRONG', 'Connection.post'));
         }
         if (message.isComplete !== true){
             this.disconnect();
@@ -221,12 +221,13 @@ class Answer{
                         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][i]);
+                            this._response[key].push(msg[key]);
                         }
                     }
                     else {
index 3b53eeb..2f2bfd5 100644 (file)
@@ -74,7 +74,7 @@ const err_list = {
     'KEY_NO_INIT': {
         msg:'This property has not been retrieved yet from GPG',
         type: 'error'
-    }
+    },
     // generic
     'PARAM_WRONG':{
         msg: 'Invalid parameter was found',
@@ -118,7 +118,11 @@ class GPGME_Error extends Error{
         if (code === 'GNUPG_ERROR' && typeof(msg) === 'string'){
             super(msg);
         } else if (err_list.hasOwnProperty(code)){
-            super(err_list[code].msg);
+            if (msg){
+                super(err_list[code].msg + "--" + msg);
+            } else {
+                super(err_list[code].msg);
+            }
         } else {
             super(err_list['GENERIC_ERROR'].msg);
         }
index b26f40f..5064d03 100644 (file)
@@ -29,7 +29,6 @@ import { GPGME_Key } from "./Key";
 
 export function toKeyIdArray(input){
     if (!input){
-        gpgme_error('MSG_NO_KEYS');
         return [];
     }
     if (!Array.isArray(input)){
@@ -61,7 +60,6 @@ export function toKeyIdArray(input){
         }
     }
     if (result.length === 0){
-        gpgme_error('MSG_NO_KEYS');
         return [];
     } else {
         return result;
index 454b191..d85c8b6 100644 (file)
@@ -207,7 +207,7 @@ export class GPGME_Key {
             msg.setParameter('armor', true);
             msg.setParameter('keys', me._data.fingerprint);
             msg.post().then(function(result){
-                me._data.armor = result.data;
+                me._data.armored = result.data;
                 resolve(result.data);
             }, function(error){
                 reject(error);
@@ -280,7 +280,7 @@ export class GPGME_Key {
     /**
      * Deletes the public Key from the GPG Keyring. Note that a deletion of a
      * secret key is not supported by the native backend.
-     * @returns {Boolean} Success if key was deleted, rejects with a GPG error
+     * @returns {Promise<Boolean>} Success if key was deleted, rejects with a GPG error
      * otherwise
      */
     delete(){
index 9081cbe..c5e613e 100644 (file)
@@ -18,9 +18,9 @@
  * SPDX-License-Identifier: LGPL-2.1+
  */
 
-import {createMessage} from './Message'
-import {GPGME_Key, createKey} from './Key'
-import { isFingerprint, toKeyIdArray } from './Helpers';
+import {createMessage} from './Message';
+import {createKey} from './Key';
+import { isFingerprint } from './Helpers';
 import { gpgme_error } from './Errors';
 
 export class GPGME_Keyring {
@@ -39,10 +39,8 @@ export class GPGME_Keyring {
      *
      */
     getKeys(pattern, prepare_sync){
-        let me = this;
         return new Promise(function(resolve, reject) {
-            let msg;
-            msg = createMessage('keylist');
+            let msg = createMessage('keylist');
             if (pattern !== undefined){
                 msg.setParameter('keys', pattern);
             }
@@ -50,25 +48,28 @@ export class GPGME_Keyring {
             msg.post().then(function(result){
                 let resultset = [];
                 let promises = [];
-                // TODO check if result.key is not empty
-                for (let i=0; i< result.keys.length; i++){
-                    let k = createKey(result.keys[i].fingerprint, me);
-                    k.setKeyData(result.keys[i]);
-                    if (prepare_sync === true){
-                        promises.push(k.getArmor());
-                        promises.push(k.getHasSecret());
+                if (result.keys.length === 0){
+                    resolve([]);
+                } else {
+                    for (let i=0; i< result.keys.length; i++){
+                        let k = createKey(result.keys[i].fingerprint);
+                        k.setKeyData(result.keys[i]);
+                        if (prepare_sync === true){
+                            promises.push(k.getArmor());
+                            promises.push(k.getHasSecret());
+                        }
+                        resultset.push(k);
                     }
-                    resultset.push(k);
-                }
-                if (promises.length > 0) {
-                    Promise.all(promises).then(function (res){
+                    if (promises.length > 0) {
+                        Promise.all(promises).then(function() {
+                            resolve(resultset);
+                        }, function(error){
+                            reject(error);
+                        });
+                    } else {
                         resolve(resultset);
-                    }, function(error){
-                        reject(error);
-                    });
+                    }
                 }
-            }, function(error){
-                reject(error);
             });
         });
     }
@@ -80,7 +81,6 @@ export class GPGME_Keyring {
      * @returns {Promise<String>} Armored Key blocks
      */
     getKeysArmored(pattern) {
-        if (pattern)
         return new Promise(function(resolve, reject) {
             let msg = createMessage('export');
             msg.setParameter('armor', true);
@@ -92,10 +92,102 @@ export class GPGME_Keyring {
             }, function(error){
                 reject(error);
             });
+        });
     }
 
     // getDefaultKey() Big TODO
-    // importKeys(armoredKeys)
-    // generateKey  --> TODO (Andre noch anfragen!)
 
-};
+    /**
+     *
+     * @param {String} armored Armored Key block of the Kex(s) to be imported into gnupg
+     * @param {Boolean} prepare_sync prepare the keys for synched use (see getKeys()).
+     * @returns {Promise<Array<Object>>} An array of objects for the Keys considered.
+    *       Key.key The key itself as a GPGME_Key
+     *      Key.status String:
+     *          'nochange' if the Key was not changed,
+     *          'newkey' if the Key was imported in gpg, and did not exist previously,
+     *          'change' if the key existed, but details were updated. For details,
+     *              Key.changes is available.
+     *      Key.changes.userId: Boolean userIds changed
+     *      Key.changes.signature: Boolean signatures changed
+     *      Key.changes.subkey: Boolean subkeys changed
+     * // TODO: not yet implemented: Information about Keys that failed
+     *          (e.g. malformed Keys, secretKeys are not accepted)
+     */
+    importKey(armored, prepare_sync) {
+        if (!armored || typeof(armored) !== 'string'){
+            return Promise.reject(gpgme_error('PARAM_WRONG'));
+        }
+        let me = this;
+        return new Promise(function(resolve, reject){
+            let msg = createMessage('import');
+            msg.setParameter('data', armored);
+            msg.post().then(function(response){
+                let infos = {};
+                let fprs = [];
+                for (var res=0; res < response.result[0].imports.length; res++) {
+                    let result = response.result[0].imports[res];
+                    let status = '';
+                    if (result.status === 0){
+                        status = 'nochange';
+                    } else if ((result.status & 1) === 1){
+                        status = 'newkey';
+                    } else {
+                        status = 'change';
+                    }
+                    let changes = {};
+                    changes.userId = (result.status & 2) === 2;
+                    changes.signature = (result.status & 4) === 4;
+                    changes.subkey = (result.status & 8) === 8;
+                    //16 new secret key: not implemented
+
+                    fprs.push(result.fingerprint);
+                    infos[result.fingerprint] = {
+                        changes: changes,
+                        status: status
+                    };
+                }
+                let resultset = [];
+                if (prepare_sync === true){
+                    me.getKeys(fprs, true).then(function(result){
+                        for (let i=0; i < result.length; i++) {
+                            resultset.push({
+                                key: result[i],
+                                changes: infos[result[i].fingerprint].changes,
+                                status: infos[result[i].fingerprint].status
+                            });
+                        }
+                        resolve(resultset);
+                    }, function(error){
+                        reject(error);
+                    });
+                } else {
+                    for (let i=0; i < fprs.length; i++) {
+                        resultset.push({
+                            key: createKey(fprs[i]),
+                            changes: infos[fprs[i]].changes,
+                            status: infos[fprs[i]].status
+                        });
+                    }
+                    resolve(resultset);
+                }
+
+            }, function(error){
+                reject(error);
+            });
+
+
+        });
+
+
+    }
+
+    deleteKey(fingerprint){
+        if (isFingerprint(fingerprint) === true) {
+            let key = createKey(fingerprint);
+            key.delete();
+        }
+    }
+
+    // generateKey
+}
index 2a21a6a..07147ba 100644 (file)
@@ -1,5 +1,5 @@
-import {Connection} from "./src/Connection";
-import {createKey} from "./src/Key";
+import {Connection} from './src/Connection';
+import {createKey} from './src/Key';
 
 let conn = new Connection;
 
@@ -23,14 +23,14 @@ export const helper_params = {
     valid_openpgplike: { primaryKey: {
         getFingerprint: function(){
             return '85DE2A8BA5A5AB3A8A7BE2000B8AED24D7534BC2';}
-        }
     }
-}
+    }
+};
 
 export const message_params = {
     invalid_op_action : 'dance',
     invalid_op_type : [234, 34, '<>'],
-    valid_encrypt_data: "مرحبا بالعالم",
+    valid_encrypt_data: 'مرحبا بالعالم',
     invalid_param_test: {
         valid_op: 'encrypt',
         invalid_param_names: [22,'dance', {}],
@@ -38,18 +38,89 @@ export const message_params = {
         invalid_values_0: [2134, 'All your passwords',
             createKey('12AE9F3E41B33BF77DF52B6BE8EE1992D7909B08', conn), null]
     }
-}
+};
 
 export const whatever_params = {
     four_invalid_params: ['<(((-<', '>°;==;~~', '^^', '{{{{o}}}}'],
-}
+};
 export const key_params = {
 // A Key you own (= having a secret Key) in GPG. See testkey.pub/testkey.sec
     validKeyFingerprint: 'D41735B91236FDB882048C5A2301635EEFF0CB05',
-// A Key you do not own (= having no secret Key) in GPG. See testkey2.pub
+    // A Key you do not own (= having no secret Key) in GPG. See testkey2.pub
     validFingerprintNoSecret: 'E059A1E0866D31AE131170884D9A2E13304153D1',
-// A Key not in your Keyring. This is just a random hex string.
+    // A Key not in your Keyring. This is just a random hex string.
     invalidKeyFingerprint: 'CDC3A2B2860625CCBFC5AAAAAC6D1B604967FC4A',
     validKeyProperties: ['expired', 'disabled','invalid','can_encrypt',
-    'can_sign','can_certify','can_authenticate','secret','is_qualified']
-}
+        'can_sign','can_certify','can_authenticate','secret','is_qualified']
+};
+export const armoredKey = {
+    fingerprint: '78034948BA7F5D0E9BDB67E4F63790C11E60278A',
+    key:'-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
+        '\n' +
+        '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\n' +
+        '=qP6s\n' +
+        '-----END PGP PUBLIC KEY BLOCK-----\n',
+    keyChangedUserId: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
+        '\n' +
+        'mQENBFsPvK0BCACaIgoIN+3g05mrTITULK/YDTrfg4W7RdzIZBxch5CM0zdu/dby\n' +
+        'esFwaJbVQIqu54CRz5xKAiWmRrQCaRvhvjY0na5r5UUIpbeQiOVrl65JtNbRmlik\n' +
+        'd9Prn1kZDUOZiCPIKn+/M2ecJ92YedM7I4/BbpiaFB11cVrPFg4thepn0LB3+Whp\n' +
+        '9HDm4orH9rjy6IUr6yjWNIr+LYRY6/Ip2vWcMVjleEpTFznXrm83hrJ0n0INtyox\n' +
+        'Nass4eDWkgo6ItxDFFLOORSmpfrToxZymSosWqgux/qG6sxHvLqlqy6Xe3ZYRFbG\n' +
+        '+JcA1oGdwOg/c0ndr6BYYiXTh8+uUJfEoZvzABEBAAG0HEJsYSBCbGEgPGJsYWJs\n' +
+        'YUBleGFtcGxlLm9yZz6JAVQEEwEIAD4WIQR4A0lIun9dDpvbZ+T2N5DBHmAnigUC\n' +
+        'Ww+8rQIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRD2N5DBHmAn\n' +
+        'igwIB/9K3E3Yev9taZP4KnXPhk1oMQRW1MWAsFGUr+70N85VwedpUawymW4vXi1+\n' +
+        'hMeTc39QjmZ0+VqHkJttkqEN6bLcEvgmU/mOlOgKdzy6eUcasYAzgoAKUqSX1SPs\n' +
+        '0Imo7Tj04wnfnVwvKxaeadi0VmdqIYaW75UlrzIaltsBctyeYH8sBrvaTLscb4ON\n' +
+        '46OM3Yw2G9+dBF0P+4UYFHP3EYZMlzNxfwF+i2HsYcNDHlcLfjENr9GwKn5FJqpY\n' +
+        'Iq3qmI37w1hVasHDxXdz1X06dpsa6Im4ACk6LXa7xIQlXxTgPAQV0sz2yB5eY+Md\n' +
+        'uzEXPGW+sq0WRp3hynn7kVP6QQYvtCZTb21lb25lIEVsc2UgPHNvbWVvbmVlbHNl\n' +
+        'QGV4YW1wbGUub3JnPokBVAQTAQgAPhYhBHgDSUi6f10Om9tn5PY3kMEeYCeKBQJb\n' +
+        'D705AhsDBQkDwmcABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEPY3kMEeYCeK\n' +
+        'aIUH/2o+Ra+GzxgZrVexXLL+FCSmcu0cxeWfMhL8jd96c6uXIT21qQMRU2jgvnUp\n' +
+        'Wdi/BeLKp5lYwywm04PFhmRVxWXLuLArCsDu+CFys+aPeybnjikPBZov6P8/cZV3\n' +
+        'cd6zxFvqB9J15HjDMcl/r5v6d4CgSLKlFebrO5WKxHa6zGK9TRMQrqTu1heKHRf6\n' +
+        '4+Wj+MZmYnPzEQePjiBw/VkJ1Nm37Dd24gKdcN/qJFwEOqvbI5RIjB7xqoDslZk9\n' +
+        'sAivBXwF0E9HKqvh4WZZeA7uaWNdGo/cQkD5rab5SdHGNPHLbzoRWScsM8WYtsME\n' +
+        'dEMp5iPuG9M63+TD7losAkJ/TlS5AQ0EWw+8rQEIALC8FyZucYmTxeEQFG7ZA3eM\n' +
+        'qBWzcIbmcTZeHbQmKlnAC4Ye6AMu/r+OWLPPPmO2PdIAdW0kHyUlbwjRw1IQhfxt\n' +
+        'FgfgLuU/YNNv0KAxwYStAjIrjzT4cixuxmElI0d2NRSXog8QRV9JDNZq5+a6zB57\n' +
+        '6CKoeJOxqJbbTK1eKXBUamOUcFrGf9umyRnRhFqyCc+oqAkPd3mS6c2pajIKkxwV\n' +
+        'iAMRG89uGFx4Vu8UT0b+7eBty5XXmbHnd0NfQia89y8mcM7IlL3KvsCl05XfXakD\n' +
+        'UwtvF8+dudW750ZefsP9UIN3loFhU+b7kA2uTrP2Vgof1o7nCBeksB0m+60I4vkA\n' +
+        'EQEAAYkBPAQYAQgAJhYhBHgDSUi6f10Om9tn5PY3kMEeYCeKBQJbD7ytAhsMBQkD\n' +
+        'wmcAAAoJEPY3kMEeYCeKAxUH/jzgbb7dHRwBqPdX/PiBbcxFIyFxioQzIn8AJ2jv\n' +
+        'Lx6it5hbzjclZZUNFjr9hxhga4EE/jtY7gm4/bAiVWfXtc4JKCc2OaaOwhiIDOSi\n' +
+        'nvvZMHbujRV6IVfmJZxrDLQQjskJvbfGkj5A/fWSwvbLJFgVcK1dJR9w6sukJjxo\n' +
+        'RAxBsAa2RqDXAdOj9N/9WKnyrRkRDjE4pNHb+WXr6Kc/yTMbLNp0SVScfVDU5Rd3\n' +
+        'YuP/sGkEcTb76ECMFBGCfJo40XualQ0S7DriIE2zQJ7oqLhFXb4QEucW5ucU1HF8\n' +
+        'UlxhdyKOG5/dgJ1bOpiY+lT8K0XhOAOV9Kx3EfFU6admRjc=\n' +
+        '=9WZ7\n' +
+        '-----END PGP PUBLIC KEY BLOCK-----\n'
+};
\ No newline at end of file
index 443aa68..d111844 100644 (file)
  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  * SPDX-License-Identifier: LGPL-2.1+
  */
-import "./node_modules/mocha/mocha";
-import "./node_modules/chai/chai";
-import { helper_params as hp } from "./unittest_inputvalues";
-import { message_params as mp } from "./unittest_inputvalues";
-import { whatever_params as wp } from "./unittest_inputvalues";
-import { key_params as kp } from "./unittest_inputvalues";
-import { Connection } from "./src/Connection";
-import { gpgme_error } from "./src/Errors";
-import { toKeyIdArray , isFingerprint } from "./src/Helpers";
-import { GPGME_Key , createKey } from "./src/Key";
-import { GPGME_Keyring } from "./src/Keyring";
-import {GPGME_Message, createMessage} from "./src/Message";
-import { setTimeout } from "timers";
+
+import './node_modules/mocha/mocha'; /*global mocha, it, describe*/
+import './node_modules/chai/chai';/*global chai*/
+import { helper_params as hp } from './unittest_inputvalues';
+import { message_params as mp } from './unittest_inputvalues';
+import { whatever_params as wp } from './unittest_inputvalues';
+import { key_params as kp } from './unittest_inputvalues';
+import { Connection } from './src/Connection';
+import { gpgme_error } from './src/Errors';
+import { toKeyIdArray , isFingerprint } from './src/Helpers';
+import { GPGME_Key , createKey } from './src/Key';
+import { GPGME_Keyring } from './src/Keyring';
+import {GPGME_Message, createMessage} from './src/Message';
 
 mocha.setup('bdd');
 var expect = chai.expect;
@@ -74,12 +74,14 @@ function unittests (){
             expect(test0.code).to.equal('CONN_TIMEOUT');
         });
 
-        it('Error Object returns generic code if code is not listed', function(){
-            let test0 = gpgme_error(hp.invalidErrorCode);
+        it('Error Object returns generic code if code is not listed',
+            function(){
+                let test0 = gpgme_error(hp.invalidErrorCode);
 
-            expect(test0).to.be.an.instanceof(Error);
-            expect(test0.code).to.equal('GENERIC_ERROR');
-        });
+                expect(test0).to.be.an.instanceof(Error);
+                expect(test0.code).to.equal('GENERIC_ERROR');
+            }
+        );
 
         it('Warnings like PARAM_IGNORED should not return errors', function(){
             let test0 = gpgme_error('PARAM_IGNORED');
@@ -201,7 +203,7 @@ function unittests (){
 
         it('Non-cached key async armored Key', function (done){
             let key = createKey(kp.validKeyFingerprint);
-            key.get('armor', false).then(function(result){
+            key.get('armored', false).then(function(result){
                 expect(result).to.be.a('string');
                 expect(result).to.include('KEY BLOCK-----');
                 done();
@@ -233,7 +235,7 @@ function unittests (){
                     expect(error).to.be.an.instanceof(Error);
                     expect(error.code).to.equal('KEY_NOKEY');
                     done();
-            });
+                });
         });
 
         it('createKey returns error if parameters are wrong', function(){
@@ -269,14 +271,74 @@ function unittests (){
             keyring.getKeys(null, true).then(function(result){
                 expect(result).to.be.an('array');
                 expect(result[0]).to.be.an.instanceof(GPGME_Key);
-                expect(result[0].get('armor')).to.be.a('string');
-                expect(result[0].get('armor')).to.include(
+                expect(result[0].get('armored')).to.be.a('string');
+                expect(result[0].get('armored')).to.include(
                     '-----END PGP PUBLIC KEY BLOCK-----');
                 done();
             });
         });
+
+        it('Loading specific Key from Keyring, to be used synchronously', function(done){
+            let keyring = new GPGME_Keyring;
+            keyring.getKeys(kp.validKeyFingerprint, true).then(function(result){
+                expect(result).to.be.an('array');
+                expect(result[0]).to.be.an.instanceof(GPGME_Key);
+                expect(result[0].get('armored')).to.be.a('string');
+                expect(result[0].get('armored')).to.include(
+                    '-----END PGP PUBLIC KEY BLOCK-----');
+                done();
+            });
+        });
+
+        it('Querying non-existing Key from Keyring', function(done){
+            let keyring = new GPGME_Keyring;
+            keyring.getKeys(kp.invalidKeyFingerprint, true).then(function(result){
+                expect(result).to.be.an('array');
+                expect(result.length).to.equal(0);
+                done();
+            });
+        });
     });
 
+    // describe('Keyring import/export', function(){
+    //     before(function(done) {
+    //         let keyring = new GPGME_Keyring;
+
+    //         keyring.getKeys(ak.fingerprint, false).then(function(result){
+    //             if (result.length === 1){
+    //                 result[0].delete().then(function(delete_result){
+    //                     if (delete_result === true){
+    //                         done();
+    //                     }
+    //                 });
+    //             } else {
+    //                 done();
+    //             }
+    //         });
+    //     });
+    //     it('Import Public Key', function(done){
+    //         keyring.importKey(ak.key).then(function(result){
+    //             expect(result).to.be.an('array');
+    //             expect(result[0].key).to.be.an.instanceof(GPGME_Key);
+    //             expect(result[0].changed).to.equal('newkey');
+    //             expect(result[0].key.keyring).to.equal(ak.fingerprint);
+    //             done();
+    //         });
+    //     });
+
+    //     it('Update Public Key', function(done){
+    //         keyring.importKey(ak.key).then(function(result){
+    //             expect(result).to.be.an('array');
+    //             expect(result[0].key).to.be.an.instanceof(GPGME_Key);
+    //             expect(result[0].changed).to.equal('change');
+    //             expect(result[0].changes.userId).to.be.true;
+    //             expect(result[0].changes.subkeys).to.be.false;
+    //             expect(result[0].key.keyring).to.equal(ak.fingerprint);
+    //             done();
+    //         });
+    //     });
+    // });
+
     describe('GPGME_Message', function(){
 
         it('creating encrypt Message', function(){
@@ -330,12 +392,12 @@ function unittests (){
             let test0 = createMessage(mp.invalid_param_test.valid_op);
             for (let i=0;
                 i < mp.invalid_param_test.invalid_param_names.length; i++){
-                    let ret = test0.setParameter(
-                        mp.invalid_param_test.invalid_param_names[i],
-                        'Somevalue');
+                let ret = test0.setParameter(
+                    mp.invalid_param_test.invalid_param_names[i],
+                    'Somevalue');
 
-                    expect(ret).to.be.an.instanceof(Error);
-                    expect(ret.code).to.equal('PARAM_WRONG');
+                expect(ret).to.be.an.instanceof(Error);
+                expect(ret.code).to.equal('PARAM_WRONG');
             }
         });
 
@@ -343,12 +405,12 @@ function unittests (){
             let test0 = createMessage(mp.invalid_param_test.valid_op);
             for (let j=0;
                 j < mp.invalid_param_test.invalid_values_0.length; j++){
-                    let ret = test0.setParameter(
-                        mp.invalid_param_test.validparam_name_0,
-                        mp.invalid_param_test.invalid_values_0[j]);
+                let ret = test0.setParameter(
+                    mp.invalid_param_test.validparam_name_0,
+                    mp.invalid_param_test.invalid_values_0[j]);
 
-                    expect(ret).to.be.an.instanceof(Error);
-                    expect(ret.code).to.equal('PARAM_WRONG');
+                expect(ret).to.be.an.instanceof(Error);
+                expect(ret.code).to.equal('PARAM_WRONG');
             }
         });
     });