diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js
index 30449d63..1e0d3195 100644
--- a/lang/js/src/Key.js
+++ b/lang/js/src/Key.js
@@ -1,205 +1,233 @@
/* 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 .
* SPDX-License-Identifier: LGPL-2.1+
*/
/**
* The key class allows to query the information defined in gpgme Key Objects
* (see https://www.gnupg.org/documentation/manuals/gpgme/Key-objects.html)
*
* This is a stub, as the gpgme-json side is not yet implemented
*
*/
import { isFingerprint } from './Helpers'
import { gpgme_error } from './Errors'
import { createMessage } from './Message';
import { permittedOperations } from './permittedOperations';
+import { Connection } from './Connection';
+
+
+export function createKey(fingerprint, parent){
+ if (!isFingerprint(fingerprint)){
+ return gpgme_error('KEY_INVALID');
+ }
+ if ( parent instanceof Connection){
+ return new GPGME_Key(fingerprint, parent);
+ } else if ( parent.hasOwnProperty('connection') &&
+ parent.connection instanceof Connection){
+ return new GPGME_Key(fingerprint, parent.connection);
+ }
+}
export class GPGME_Key {
- constructor(fingerprint){
+ constructor(fingerprint, connection){
this.fingerprint = fingerprint;
+ this.connection = connection;
+ }
+
+ set connection(conn){
+ if (this._connection instanceof Connection) {
+ gpgme_error('CONN_ALREADY_CONNECTED');
+ } else if (conn instanceof Connection ) {
+ this._connection = conn;
+ }
+ }
+
+ get connection(){
+ if (!this._connection instanceof Connection){
+ return gpgme_error('CONN_NO_CONNECT');
+ } else {
+ return this._connection;
+ }
}
set fingerprint(fpr){
if (isFingerprint(fpr) === true && !this._fingerprint){
this._fingerprint = fpr;
}
}
get fingerprint(){
return this._fingerprint;
}
/**
* hasSecret returns true if a secret subkey is included in this Key
*/
get hasSecret(){
- return checkKey(this._fingerprint, 'secret');
+ return this.checkKey('secret');
}
get isRevoked(){
- return checkKey(this._fingerprint, 'revoked');
+ return this.checkKey('revoked');
}
get isExpired(){
- return checkKey(this._fingerprint, 'expired');
+ return this.checkKey('expired');
}
get isDisabled(){
- return checkKey(this._fingerprint, 'disabled');
+ return this.checkKey('disabled');
}
get isInvalid(){
- return checkKey(this._fingerprint, 'invalid');
+ return this.checkKey('invalid');
}
get canEncrypt(){
- return checkKey(this._fingerprint, 'can_encrypt');
+ return this.checkKey('can_encrypt');
}
get canSign(){
- return checkKey(this._fingerprint, 'can_sign');
+ return this.checkKey('can_sign');
}
get canCertify(){
- return checkKey(this._fingerprint, 'can_certify');
+ return this.checkKey('can_certify');
}
get canAuthenticate(){
- return checkKey(this._fingerprint, 'can_authenticate');
+ return this.checkKey('can_authenticate');
}
get isQualified(){
- return checkKey(this._fingerprint, 'is_qualified');
+ return this.checkKey('is_qualified');
}
get armored(){
- let me = this;
- return new Promise(function(resolve, reject){
- let conn = new Connection();
- conn.setFlag('armor', true);
- conn.post('export',{'fpr': me._fingerprint});
+ let msg = createMessage ('export_key');
+ msg.setParameter('armor', true);
+ if (msg instanceof Error){
+ return gpgme_error('INVALID_KEY');
+ }
+ this.connection.post(msg).then(function(result){
+ return result.data;
});
// TODO return value not yet checked. Should result in an armored block
// in correct encoding
- // TODO openpgpjs also returns secKey if private = true?
}
/**
* TODO returns true if this is the default key used to sign
*/
get isDefault(){
throw('NOT_YET_IMPLEMENTED');
}
/**
* get the Key's subkeys as GPGME_Key objects
* @returns {Array}
*/
get subkeys(){
- return checkKey(this._fingerprint, 'subkeys').then(function(result){
+ return this.checkKey('subkeys').then(function(result){
// TBD expecting a list of fingerprints
if (!Array.isArray(result)){
result = [result];
}
let resultset = [];
for (let i=0; i < result.length; i++){
- let subkey = new GPGME_Key(result[i]);
+ let subkey = new GPGME_Key(result[i], this.connection);
if (subkey instanceof GPGME_Key){
resultset.push(subkey);
}
}
return Promise.resolve(resultset);
}, function(error){
- //TODO checkKey fails
+ //TODO this.checkKey fails
});
}
/**
* creation time stamp of the key
* @returns {Date|null} TBD
*/
get timestamp(){
- return checkKey(this._fingerprint, 'timestamp');
+ return this.checkKey('timestamp');
//TODO GPGME: -1 if the timestamp is invalid, and 0 if it is not available.
}
/**
* The expiration timestamp of this key TBD
* @returns {Date|null} TBD
*/
get expires(){
- return checkKey(this._fingerprint, 'expires');
+ return this.checkKey('expires');
// TODO convert to Date; check for 0
}
/**
* getter name TBD
* @returns {String|Array} The user ids associated with this key
*/
get userIds(){
- return checkKey(this._fingerprint, 'uids');
+ return this.checkKey('uids');
}
/**
* @returns {String} The public key algorithm supported by this subkey
*/
get pubkey_algo(){
- return checkKey(this._fingerprint, 'pubkey_algo');
+ return this.checkKey('pubkey_algo');
}
-};
-/**
- * generic function to query gnupg information on a key.
- * @param {*} fingerprint The identifier of the Keyring
- * @param {*} property The gpgme-json property to check
- *
- */
-function checkKey(fingerprint, property){
- return Promise.reject(gpgme_error('NOT_YET_IMPLEMENTED'));
- if (!property || !permittedOperations[keyinfo].hasOwnProperty(property)){
- return Promise.reject(gpgme_error('PARAM_WRONG'));
- }
- return new Promise(function(resolve, reject){
- if (!isFingerprint(fingerprint)){
- reject(gpgme_error('KEY_INVALID'));
+ /**
+ * generic function to query gnupg information on a key.
+ * @param {*} property The gpgme-json property to check.
+ * TODO: check if Promise.then(return)
+ */
+ checkKey(property){
+ return gpgme_error('NOT_YET_IMPLEMENTED');
+ // TODO: async is not what is to be ecpected from Key information :(
+ if (!property || typeof(property) !== 'string' ||
+ !permittedOperations['keyinfo'].hasOwnProperty(property)){
+ return gpgme_error('PARAM_WRONG');
}
let msg = createMessage ('keyinfo');
if (msg instanceof Error){
- reject(gpgme_error('PARAM_WRONG'));
+ return gpgme_error('PARAM_WRONG');
}
msg.setParameter('fingerprint', this.fingerprint);
- return (this.connection.post(msg)).then(function(result, error){
+ this.connection.post(msg).then(function(result, error){
if (error){
- reject(gpgme_error('GNUPG_ERROR',error.msg));
+ return gpgme_error('GNUPG_ERROR',error.msg);
} else if (result.hasOwnProperty(property)){
- resolve(result[property]);
+ return result[property];
}
else if (property == 'secret'){
- // TBD property undefined means "not true" in case of secret?
- resolve(false);
+ // TBD property undefined means "not true" in case of secret?
+ return false;
} else {
- reject(gpgme_error('CONN_UNEXPECTED_ANSWER'));
+ return gpgme_error('CONN_UNEXPECTED_ANSWER');
}
}, function(error){
- //TODO error handling
+ return gpgme_error('GENERIC_ERROR');
});
- });
+ }
};
\ No newline at end of file
diff --git a/lang/js/src/Keyring.js b/lang/js/src/Keyring.js
index d1f4122e..2cf87c24 100644
--- a/lang/js/src/Keyring.js
+++ b/lang/js/src/Keyring.js
@@ -1,161 +1,162 @@
/* 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 .
* SPDX-License-Identifier: LGPL-2.1+
*/
import {createMessage} from './Message'
import {GPGME_Key} from './Key'
import { isFingerprint, isLongId } from './Helpers';
import { gpgme_error } from './Errors';
import { Connection } from './Connection';
export class GPGME_Keyring {
constructor(connection){
this.connection = connection;
}
set connection(connection){
if (!this._connection && connection instanceof Connection){
this._connection = connection;
}
}
get connection(){
if (this._connection instanceof Connection){
if (this._connection.isConnected){
return this._connection;
}
return gpgme_error('CONN_DISCONNECTED');
}
return gpgme_error('CONN_NO_CONNECT');
}
/**
* @param {String} (optional) pattern A pattern to search for, in userIds or KeyIds
* @param {Boolean} (optional) Include listing of secret keys
* @returns {Promise.>}
*
*/
getKeys(pattern, include_secret){
let msg = createMessage('listkeys');
if (msg instanceof Error){
return Promise.reject(msg);
}
if (pattern && typeof(pattern) === 'string'){
msg.setParameter('pattern', pattern);
}
if (include_secret){
msg.setParameter('with-secret', true);
}
+ let me = this;
this.connection.post(msg).then(function(result){
let fpr_list = [];
let resultset = [];
if (!Array.isArray(result.keys)){
//TODO check assumption keys = Array
fpr_list = [result.keys];
} else {
fpr_list = result.keys;
}
for (let i=0; i < fpr_list.length; i++){
- let newKey = new GPGME_Key(fpr_list[i]);
+ let newKey = new GPGME_Key(fpr_list[i], me._connection);
if (newKey instanceof GPGME_Key){
resultset.push(newKey);
}
}
return Promise.resolve(resultset);
}, function(error){
//TODO error handling
});
}
/**
* @param {Object} flags subset filter expecting at least one of the
* filters described below. True will filter on the condition, False will
* reverse the filter, if not present or undefined, the filter will not be
* considered. Please note that some combination may not make sense
* @param {Boolean} flags.secret Only Keys containing a secret part.
* @param {Boolean} flags.revoked revoked Keys only
* @param {Boolean} flags.expired Expired Keys only
* @param {String} (optional) pattern A pattern to search for, in userIds or KeyIds
* @returns {Promise Array}
*
*/
getSubset(flags, pattern){
if (flags === undefined) {
throw('ERR_WRONG_PARAM');
};
let secretflag = false;
if (flags.hasOwnProperty(secret) && flags.secret){
secretflag = true;
}
this.getKeys(pattern, secretflag).then(function(queryset){
let resultset = [];
for (let i=0; i < queryset.length; i++ ){
let conditions = [];
let anticonditions = [];
if (secretflag === true){
conditions.push('hasSecret');
} else if (secretflag === false){
anticonditions.push('hasSecret');
}
/**
if (flags.defaultKey === true){
conditions.push('isDefault');
} else if (flags.defaultKey === false){
anticonditions.push('isDefault');
}
*/
/**
* if (flags.valid === true){
anticonditions.push('isInvalid');
} else if (flags.valid === false){
conditions.push('isInvalid');
}
*/
if (flags.revoked === true){
conditions.push('isRevoked');
} else if (flags.revoked === false){
anticonditions.push('isRevoked');
}
if (flags.expired === true){
conditions.push('isExpired');
} else if (flags.expired === false){
anticonditions.push('isExpired');
}
let decision = undefined;
for (let con = 0; con < conditions.length; con ++){
if (queryset[i][conditions[con]] !== true){
decision = false;
}
}
for (let acon = 0; acon < anticonditions.length; acon ++){
if (queryset[i][anticonditions[acon]] === true){
decision = false;
}
}
if (decision !== false){
resultset.push(queryset[i]);
}
}
return Promise.resolve(resultset);
}, function(error){
//TODO error handling
});
}
};
diff --git a/lang/js/src/gpgmejs_openpgpjs.js b/lang/js/src/gpgmejs_openpgpjs.js
index c80d5a86..b233f0fa 100644
--- a/lang/js/src/gpgmejs_openpgpjs.js
+++ b/lang/js/src/gpgmejs_openpgpjs.js
@@ -1,280 +1,290 @@
/* 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 .
* SPDX-License-Identifier: LGPL-2.1+
*/
/**
* This is a compatibility API to be used as openpgpjs syntax.
* Non-implemented options will throw an error if set (not null or undefined)
* TODO Some info about differences
*/
import { GpgME } from "./gpgmejs";
import {GPGME_Keyring} from "./Keyring"
- import { GPGME_Key } from "./Key";
+ import { GPGME_Key, createKey } from "./Key";
import { isFingerprint } from "./Helpers"
import { gpgme_error } from "./Errors"
+import { Connection } from "./Connection";
export class GpgME_openpgpmode {
constructor(connection, config = {}){
this.initGpgME(connection, config);
}
get Keyring(){
if (this._keyring){
return this._keyring;
}
return undefined;
}
initGpgME(connection, config = {}){
if (connection && typeof(config) ==='object'){
this._config = config;
- if (!this._GPGME){
+ if (!this._GpgME){
this._GpgME = new GpgME(connection, config);
}
if (!this._keyring){
this._keyring = new GPGME_Keyring_openpgpmode(connection);
}
}
}
/**
* Encrypt Message
* Supported:
* @param {String|Uint8Array} data
* //an openpgp Message also accepted here. TODO: is this wanted?
* @param {Key|Array} publicKeys
* //Strings of Fingerprints
* @param {Boolean} wildcard
* TODO:
* @param {Key|Array} privateKeys // -> encryptsign
* @param {module:enums.compression} compression //TODO accepts integer, if 0 (no compression) it won't compress
* @param {Boolean} armor // TODO base64 switch
* @param {Boolean} detached // --> encryptsign
* unsupported:
* @param {String|Array} passwords
* @param {Object} sessionKey
* @param {Signature} signature
* @param {Boolean} returnSessionKey
* @param {String} filename
*
* Can be set, but will be ignored:
*
* @returns {Promise