Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F34329129
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
39 KB
Subscribers
None
View Options
diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js
index f431a283..88c49d3f 100644
--- a/lang/js/src/Key.js
+++ b/lang/js/src/Key.js
@@ -1,608 +1,608 @@
/* 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+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/
import { isFingerprint, isLongId } from './Helpers';
import { gpgme_error } from './Errors';
import { createMessage } from './Message';
/**
* Validates the given fingerprint and creates a new {@link GPGME_Key}
* @param {String} fingerprint
* @param {Boolean} async If True, Key properties (except fingerprint) will be
* queried from gnupg on each call, making the operation up-to-date, the
* answers will be Promises, and the performance will likely suffer
* @returns {GPGME_Key|GPGME_Error}
*/
export function createKey(fingerprint, async = false){
if (!isFingerprint(fingerprint) || typeof(async) !== 'boolean'){
return gpgme_error('PARAM_WRONG');
}
else return Object.freeze(new GPGME_Key(fingerprint, async));
}
/**
* Represents the Keys as stored in the gnupg backend
* It allows to query almost all information defined in gpgme Key Objects
* Refer to {@link validKeyProperties} for available information, and the gpgme
* documentation on their meaning
* (https://www.gnupg.org/documentation/manuals/gpgme/Key-objects.html)
*
* @class
*/
export class GPGME_Key {
constructor(fingerprint, async){
/**
* @property {Boolean} If true, most answers will be asynchronous
*/
this.isAsync = async;
let _data = {fingerprint: fingerprint};
this.getFingerprint = function(){
if (!_data.fingerprint || !isFingerprint(_data.fingerprint)){
return gpgme_error('KEY_INVALID');
}
return _data.fingerprint;
};
/**
* Property indicating if the Key possesses a private/secret part. If
* this information is not yet cached, it returns an
* {@link GPGME_Error} with code 'KEY_NO_INIT'. Running
* {@link refreshKey} may help in this case.
* @returns {Boolean} If the Key has a secret subkey.
*/
this.hasSecret= function (){
- return this.get('hasSecret', true);
+ return this.get('hasSecret');
};
/**
* @param {Object} data Bulk set the data for this key, with an Object
* sent by gpgme-json.
* @returns {GPGME_Key|GPGME_Error} Itself after values have been set,
* an error if something went wrong.
* @private
*/
this.setKeyData = function (data){
if (typeof(data) !== 'object') {
return gpgme_error('KEY_INVALID');
}
if (!data.fingerprint || data.fingerprint !== _data.fingerprint){
return gpgme_error('KEY_INVALID');
}
let keys = Object.keys(data);
for (let i=0; i< keys.length; i++){
if (!validKeyProperties.hasOwnProperty(keys[i])){
return gpgme_error('KEY_INVALID');
}
//running the defined validation function
if (validKeyProperties[keys[i]](data[keys[i]]) !== true ){
return gpgme_error('KEY_INVALID');
}
switch (keys[i]){
case 'subkeys':
_data.subkeys = [];
for (let i=0; i< data.subkeys.length; i++) {
_data.subkeys.push(Object.freeze(
new GPGME_Subkey(data.subkeys[i])));
}
break;
case 'userids':
_data.userids = [];
for (let i=0; i< data.userids.length; i++) {
_data.userids.push(Object.freeze(
new GPGME_UserId(data.userids[i])));
}
break;
case 'last_update':
_data[keys[i]] = new Date( data[keys[i]] * 1000 );
break;
default:
_data[keys[i]] = data[keys[i]];
}
}
return this;
};
/**
* Query any property of the Key listed in {@link validKeyProperties}
* @param {String} property property to be retreived
* @returns {*|Promise<*>} the value (Boolean, String, Array, Object).
* If 'cached' is false, the value will be resolved as a Promise.
*/
this.get = function(property) {
if (this.isAsync === true) {
let me = this;
return new Promise(function(resolve, reject) {
if (property === 'armored'){
resolve(me.getArmor());
} else if (property === 'hasSecret'){
resolve(me.getHasSecret());
} else if (validKeyProperties.hasOwnProperty(property)){
let msg = createMessage('keylist');
msg.setParameter('keys', _data.fingerprint);
msg.post().then(function(result){
if (result.keys && result.keys.length === 1 &&
result.keys[0].hasOwnProperty(property)){
resolve(result.keys[0][property]);
} else {
reject(gpgme_error('CONN_UNEXPECTED_ANSWER'));
}
}, function(error){
reject(gpgme_error(error));
});
} else {
reject(gpgme_error('PARAM_WRONG'));
}
});
} else {
if (!validKeyProperties.hasOwnProperty(property)){
return gpgme_error('PARAM_WRONG');
}
if (!_data.hasOwnProperty(property)){
return gpgme_error('KEY_NO_INIT');
} else {
return (_data[property]);
}
}
};
/**
* Reloads the Key information from gnupg. This is only useful if you
* use the GPGME_Keys cached. Note that this is a performance hungry
* operation. If you desire more than a few refreshs, it may be
* advisable to run {@link Keyring.getKeys} instead.
* @returns {Promise<GPGME_Key|GPGME_Error>}
* @async
*/
this.refreshKey = function() {
let me = this;
return new Promise(function(resolve, reject) {
if (!_data.fingerprint){
reject(gpgme_error('KEY_INVALID'));
}
let msg = createMessage('keylist');
msg.setParameter('sigs', true);
msg.setParameter('keys', _data.fingerprint);
msg.post().then(function(result){
if (result.keys.length === 1){
me.setKeyData(result.keys[0]);
me.getHasSecret().then(function(){
me.getArmor().then(function(){
resolve(me);
}, function(error){
reject(error);
});
}, function(error){
reject(error);
});
} else {
reject(gpgme_error('KEY_NOKEY'));
}
}, function (error) {
reject(gpgme_error('GNUPG_ERROR'), error);
});
});
};
/**
* Query the armored block of the Key directly from gnupg. Please note
* that this will not get you any export of the secret/private parts of
* a Key
* @returns {Promise<String|GPGME_Error>}
* @async
*/
this.getArmor = function(){
return new Promise(function(resolve, reject) {
if (!_data.fingerprint){
reject(gpgme_error('KEY_INVALID'));
}
let msg = createMessage('export');
msg.setParameter('armor', true);
msg.setParameter('keys', _data.fingerprint);
msg.post().then(function(result){
_data.armored = result.data;
resolve(result.data);
}, function(error){
reject(error);
});
});
};
/**
* Find out if the Key includes a secret part. Note that this is a
* rather nonperformant operation, as it needs to query gnupg twice.
* If you want this inforrmation about more than a few Keys, it may be
* advisable to run {@link Keyring.getKeys} instead.
* @returns {Promise<Boolean|GPGME_Error>} True if a secret/private Key
* is available in the gnupg Keyring
* @async
*/
this.getHasSecret = function (){
return new Promise(function(resolve, reject) {
if (!_data.fingerprint){
reject(gpgme_error('KEY_INVALID'));
}
let msg = createMessage('keylist');
msg.setParameter('keys', _data.fingerprint);
msg.setParameter('secret', true);
msg.post().then(function(result){
_data.hasSecret = null;
if (
result.keys &&
result.keys.length === 1 &&
result.keys[0].secret === true
) {
_data.hasSecret = true;
resolve(true);
} else {
_data.hasSecret = false;
resolve(false);
}
}, function(error){
reject(error);
});
});
};
/**
* Deletes the (public) Key from the GPG Keyring. Note that a deletion
* of a secret key is not supported by the native backend.
* @returns {Promise<Boolean|GPGME_Error>} Success if key was deleted,
* rejects with a GPG error otherwise.
*/
this.delete= function (){
return new Promise(function(resolve, reject){
if (!_data.fingerprint){
reject(gpgme_error('KEY_INVALID'));
}
let msg = createMessage('delete');
msg.setParameter('key', _data.fingerprint);
msg.post().then(function(result){
resolve(result.success);
}, function(error){
reject(error);
});
});
};
}
/**
* @returns {String} The fingerprint defining this Key
*/
get fingerprint(){
return this.getFingerprint();
}
/**
* Property for the export of armored Key. If the armored Key is not
* cached, it returns an {@link GPGME_Error} with code 'KEY_NO_INIT'.
* Running {@link refreshKey} may help in this case.
* @returns {String|GPGME_Error} The armored public Key block.
*/
get armored(){
return this.get('armored', true);
}
}
/**
* Representing a subkey of a Key.
* @class
* @protected
*/
class GPGME_Subkey {
/**
* Initializes with the json data sent by gpgme-json
* @param {Object} data
* @private
*/
constructor(data){
let _data = {};
let keys = Object.keys(data);
/**
* Validates a subkey property against {@link validSubKeyProperties} and
* sets it if validation is successful
* @param {String} property
* @param {*} value
* @param private
*/
const setProperty = function (property, value){
if (validSubKeyProperties.hasOwnProperty(property)){
if (validSubKeyProperties[property](value) === true) {
if (property === 'timestamp' || property === 'expires'){
_data[property] = new Date(value * 1000);
} else {
_data[property] = value;
}
}
}
};
for (let i=0; i< keys.length; i++) {
setProperty(keys[i], data[keys[i]]);
}
/**
* Fetches any information about this subkey
* @param {String} property Information to request
* @returns {String | Number | Date}
*/
this.get = function(property) {
if (_data.hasOwnProperty(property)){
return (_data[property]);
}
};
}
}
/**
* Representing user attributes associated with a Key or subkey
* @class
* @protected
*/
class GPGME_UserId {
/**
* Initializes with the json data sent by gpgme-json
* @param {Object} data
* @private
*/
constructor(data){
let _data = {};
let keys = Object.keys(data);
const setProperty = function(property, value){
if (validUserIdProperties.hasOwnProperty(property)){
if (validUserIdProperties[property](value) === true) {
if (property === 'last_update'){
_data[property] = new Date(value*1000);
} else {
_data[property] = value;
}
}
}
};
for (let i=0; i< keys.length; i++) {
setProperty(keys[i], data[keys[i]]);
}
/**
* Validates a subkey property against {@link validUserIdProperties} and
* sets it if validation is successful
* @param {String} property
* @param {*} value
* @param private
*/
/**
* Fetches information about the user
* @param {String} property Information to request
* @returns {String | Number}
*/
this.get = function (property) {
if (_data.hasOwnProperty(property)){
return (_data[property]);
}
};
}
}
/**
* Validation definition for userIds. Each valid userId property is represented
* as a key- Value pair, with their value being a validation function to check
* against
* @protected
* @const
*/
const validUserIdProperties = {
'revoked': function(value){
return typeof(value) === 'boolean';
},
'invalid': function(value){
return typeof(value) === 'boolean';
},
'uid': function(value){
if (typeof(value) === 'string' || value === ''){
return true;
}
return false;
},
'validity': function(value){
if (typeof(value) === 'string'){
return true;
}
return false;
},
'name': function(value){
if (typeof(value) === 'string' || value === ''){
return true;
}
return false;
},
'email': function(value){
if (typeof(value) === 'string' || value === ''){
return true;
}
return false;
},
'address': function(value){
if (typeof(value) === 'string' || value === ''){
return true;
}
return false;
},
'comment': function(value){
if (typeof(value) === 'string' || value === ''){
return true;
}
return false;
},
'origin': function(value){
return Number.isInteger(value);
},
'last_update': function(value){
return Number.isInteger(value);
}
};
/**
* Validation definition for subKeys. Each valid userId property is represented
* as a key-value pair, with the value being a validation function
* @protected
* @const
*/
const validSubKeyProperties = {
'invalid': function(value){
return typeof(value) === 'boolean';
},
'can_encrypt': function(value){
return typeof(value) === 'boolean';
},
'can_sign': function(value){
return typeof(value) === 'boolean';
},
'can_certify': function(value){
return typeof(value) === 'boolean';
},
'can_authenticate': function(value){
return typeof(value) === 'boolean';
},
'secret': function(value){
return typeof(value) === 'boolean';
},
'is_qualified': function(value){
return typeof(value) === 'boolean';
},
'is_cardkey': function(value){
return typeof(value) === 'boolean';
},
'is_de_vs': function(value){
return typeof(value) === 'boolean';
},
'pubkey_algo_name': function(value){
return typeof(value) === 'string';
// TODO: check against list of known?['']
},
'pubkey_algo_string': function(value){
return typeof(value) === 'string';
// TODO: check against list of known?['']
},
'keyid': function(value){
return isLongId(value);
},
'pubkey_algo': function(value) {
return (Number.isInteger(value) && value >= 0);
},
'length': function(value){
return (Number.isInteger(value) && value > 0);
},
'timestamp': function(value){
return (Number.isInteger(value) && value > 0);
},
'expires': function(value){
return (Number.isInteger(value) && value > 0);
}
};
/**
* Validation definition for Keys. Each valid Key property is represented
* as a key-value pair, with their value being a validation function
* @protected
* @const
*/
const validKeyProperties = {
'fingerprint': function(value){
return isFingerprint(value);
},
'armored': function(value){
return typeof(value === 'string');
},
'revoked': function(value){
return typeof(value) === 'boolean';
},
'expired': function(value){
return typeof(value) === 'boolean';
},
'disabled': function(value){
return typeof(value) === 'boolean';
},
'invalid': function(value){
return typeof(value) === 'boolean';
},
'can_encrypt': function(value){
return typeof(value) === 'boolean';
},
'can_sign': function(value){
return typeof(value) === 'boolean';
},
'can_certify': function(value){
return typeof(value) === 'boolean';
},
'can_authenticate': function(value){
return typeof(value) === 'boolean';
},
'secret': function(value){
return typeof(value) === 'boolean';
},
'is_qualified': function(value){
return typeof(value) === 'boolean';
},
'protocol': function(value){
return typeof(value) === 'string';
//TODO check for implemented ones
},
'issuer_serial': function(value){
return typeof(value) === 'string';
},
'issuer_name': function(value){
return typeof(value) === 'string';
},
'chain_id': function(value){
return typeof(value) === 'string';
},
'owner_trust': function(value){
return typeof(value) === 'string';
},
'last_update': function(value){
return (Number.isInteger(value));
//TODO undefined/null possible?
},
'origin': function(value){
return (Number.isInteger(value));
},
'subkeys': function(value){
return (Array.isArray(value));
},
'userids': function(value){
return (Array.isArray(value));
},
'tofu': function(value){
return (Array.isArray(value));
},
'hasSecret': function(value){
return typeof(value) === 'boolean';
}
};
diff --git a/lang/js/src/Keyring.js b/lang/js/src/Keyring.js
index 31c4f92b..8715a47d 100644
--- a/lang/js/src/Keyring.js
+++ b/lang/js/src/Keyring.js
@@ -1,413 +1,415 @@
/* 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+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/
import {createMessage} from './Message';
import {createKey} from './Key';
import { isFingerprint } from './Helpers';
import { gpgme_error } from './Errors';
/**
* This class offers access to the gnupg keyring
*/
export class GPGME_Keyring {
constructor(){
/**
* Queries Keys (all Keys or a subset) from gnupg.
*
* @param {String | Array<String>} pattern (optional) A pattern to
* search for in userIds or KeyIds.
* @param {Boolean} prepare_sync (optional) if set to true, the
* 'hasSecret' and 'armored' properties will be fetched for the Keys as
* well. These require additional calls to gnupg, resulting in a
* performance hungry operation. Calling them here enables direct,
* synchronous use of these properties for all keys, without having to
* resort to a refresh() first.
* @param {Boolean} search (optional) retrieve Keys from external
* servers with the method(s) defined in gnupg (e.g. WKD/HKP lookup)
- * @returns {Promise.<Array<GPGME_Key>|GPGME_Error>}
+ * @returns {Promise<Array<GPGME_Key>>}
* @static
* @async
*/
this.getKeys = function(pattern, prepare_sync=false, search=false){
return new Promise(function(resolve, reject) {
let msg = createMessage('keylist');
if (pattern !== undefined && pattern !== null){
msg.setParameter('keys', pattern);
}
msg.setParameter('sigs', true);
if (search === true){
msg.setParameter('locate', true);
}
msg.post().then(function(result){
let resultset = [];
if (result.keys.length === 0){
resolve([]);
} else {
let secondrequest;
if (prepare_sync === true) {
secondrequest = function() {
let msg2 = createMessage('keylist');
msg2.setParameter('keys', pattern);
msg2.setParameter('secret', true);
return msg2.post();
};
} else {
secondrequest = function() {
return Promise.resolve(true);
};
}
secondrequest().then(function(answer) {
- for (let i=0; i < result.keys.length; i++){
+ for (let i=0; i < answer.keys.length; i++){
if (prepare_sync === true){
- result.keys[i].hasSecret = false;
+ result.keys[i].hasSecret = undefined;
if (answer && answer.keys) {
for (let j=0;
j < answer.keys.length; j++ ){
const a = answer.keys[j];
const b = result.keys[i];
if (
a.fingerprint === b.fingerprint
) {
if (a.secret === true){
- a.hasSecret = true;
+ b.hasSecret = true;
+ } else {
+ b.hasSecret = false;
}
break;
}
}
// TODO getArmor() to be used in sync
}
}
let k = createKey(result.keys[i].fingerprint);
k.setKeyData(result.keys[i]);
resultset.push(k);
}
resolve(resultset);
}, function(error){
reject(error);
});
}
});
});
};
/**
* @typedef {Object} exportResult The result of a getKeysArmored
* operation.
* @property {String} armored The public Key(s) as armored block. Note
* that the result is one armored block, and not a block per key.
* @property {Array<String>} secret_fprs (optional) list of
* fingerprints for those Keys that also have a secret Key available in
* gnupg. The secret key will not be exported, but the fingerprint can
* be used in operations needing a secret key.
*/
/**
* Fetches the armored public Key blocks for all Keys matching the
* pattern (if no pattern is given, fetches all keys known to gnupg).
* @param {String|Array<String>} pattern (optional) The Pattern to
* search for
* @param {Boolean} with_secret_fpr (optional) also return a list of
* fingerprints for the keys that have a secret key available
* @returns {Promise<exportResult|GPGME_Error>} Object containing the
* armored Key(s) and additional information.
* @static
* @async
*/
this.getKeysArmored = function(pattern, with_secret_fpr) {
return new Promise(function(resolve, reject) {
let msg = createMessage('export');
msg.setParameter('armor', true);
if (with_secret_fpr === true) {
msg.setParameter('with-sec-fprs', true);
}
if (pattern !== undefined && pattern !== null){
msg.setParameter('keys', pattern);
}
msg.post().then(function(answer){
const result = {armored: answer.data};
if (with_secret_fpr === true
&& answer.hasOwnProperty('sec-fprs')
) {
result.secret_fprs = answer['sec-fprs'];
}
resolve(result);
}, function(error){
reject(error);
});
});
};
/**
* Returns the Key used by default in gnupg.
* (a.k.a. 'primary Key or 'main key').
* It looks up the gpg configuration if set, or the first key that
* contains a secret key.
*
* @returns {Promise<GPGME_Key|GPGME_Error>}
* @async
* @static
*/
this.getDefaultKey = function() {
let me = this;
return new Promise(function(resolve, reject){
let msg = createMessage('config_opt');
msg.setParameter('component', 'gpg');
msg.setParameter('option', 'default-key');
msg.post().then(function(response){
if (response.value !== undefined
&& response.value.hasOwnProperty('string')
&& typeof(response.value.string) === 'string'
){
me.getKeys(response.value.string,true).then(
function(keys){
if(keys.length === 1){
resolve(keys[0]);
} else {
reject(gpgme_error('KEY_NO_DEFAULT'));
}
}, function(error){
reject(error);
});
} else {
// TODO: this is overly 'expensive' in communication
// and probably performance, too
me.getKeys(null,true).then(function(keys){
for (let i=0; i < keys.length; i++){
if (keys[i].get('hasSecret') === true){
resolve(keys[i]);
break;
}
if (i === keys.length -1){
reject(gpgme_error('KEY_NO_DEFAULT'));
}
}
}, function(error){
reject(error);
});
}
}, function(error){
reject(error);
});
});
};
/**
* @typedef {Object} importResult The result of a Key update
* @property {Object} summary Numerical summary of the result. See the
* feedbackValues variable for available Keys values and the gnupg
* documentation.
* https://www.gnupg.org/documentation/manuals/gpgme/Importing-Keys.html
* for details on their meaning.
* @property {Array<importedKeyResult>} Keys Array of Object containing
* GPGME_Keys with additional import information
*
*/
/**
* @typedef {Object} importedKeyResult
* @property {GPGME_Key} key The resulting key
* @property {String} status:
* '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.
* @property {Boolean} changes.userId Changes in userIds
* @property {Boolean} changes.signature Changes in signatures
* @property {Boolean} changes.subkey Changes in subkeys
*/
/**
* Import an armored Key block into gnupg. Note that this currently
* will not succeed on private Key blocks.
* @param {String} armored Armored Key block of the Key(s) to be
* imported into gnupg
* @param {Boolean} prepare_sync prepare the keys for synched use
* (see {@link getKeys}).
* @returns {Promise<importResult>} A summary and Keys considered.
* @async
* @static
*/
this.importKey = function (armored, prepare_sync) {
let feedbackValues = ['considered', 'no_user_id', 'imported',
'imported_rsa', 'unchanged', 'new_user_ids', 'new_sub_keys',
'new_signatures', 'new_revocations', 'secret_read',
'secret_imported', 'secret_unchanged', 'skipped_new_keys',
'not_imported', 'skipped_v3_keys'];
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 (let res=0; res<response.result.imports.length; res++){
let result = response.result.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
});
}
let summary = {};
for (let i=0; i < feedbackValues.length; i++ ){
summary[feedbackValues[i]] =
response[feedbackValues[i]];
}
resolve({
Keys:resultset,
summary: summary
});
}, 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);
});
});
};
/**
* Convenience function for deleting a Key. See {@link Key.delete} for
* further information about the return values.
* @param {String} fingerprint
* @returns {Promise<Boolean|GPGME_Error>}
* @async
* @static
*/
this.deleteKey = function(fingerprint){
if (isFingerprint(fingerprint) === true) {
let key = createKey(fingerprint);
return key.delete();
} else {
return Promise.reject(gpgme_error('KEY_INVALID'));
}
};
/**
* Generates a new Key pair directly in gpg, and returns a GPGME_Key
* representing that Key. Please note that due to security concerns,
* secret Keys can not be deleted or exported from inside gpgme.js.
*
* @param {String} userId The user Id, e.g. 'Foo Bar <foo@bar.baz>'
* @param {String} algo (optional) algorithm (and optionally key size)
* to be used. See {@link supportedKeyAlgos} below for supported
* values.
* @param {Date} expires (optional) Expiration date. If not set,
* expiration will be set to 'never'
*
* @return {Promise<Key|GPGME_Error>}
* @async
*/
this.generateKey = function (userId, algo = 'default', expires){
if (
typeof(userId) !== 'string' ||
supportedKeyAlgos.indexOf(algo) < 0 ||
(expires && !(expires instanceof Date))
){
return Promise.reject(gpgme_error('PARAM_WRONG'));
}
let me = this;
return new Promise(function(resolve, reject){
let msg = createMessage('createkey');
msg.setParameter('userid', userId);
msg.setParameter('algo', algo );
if (expires){
msg.setParameter('expires',
Math.floor(expires.valueOf()/1000));
}
msg.post().then(function(response){
me.getKeys(response.fingerprint, true).then(
// TODO prepare_sync?
function(result){
resolve(result);
}, function(error){
reject(error);
});
}, function(error) {
reject(error);
});
});
};
}
}
/**
* List of algorithms supported for key generation. Please refer to the gnupg
* documentation for details
*/
const supportedKeyAlgos = [
'default',
'rsa', 'rsa2048', 'rsa3072', 'rsa4096',
'dsa', 'dsa2048', 'dsa3072', 'dsa4096',
'elg', 'elg2048', 'elg3072', 'elg4096',
'ed25519',
'cv25519',
'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1',
'NIST P-256', 'NIST P-384', 'NIST P-521'
];
\ No newline at end of file
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Dec 30, 5:49 PM (1 d, 14 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
73/a5/c748f58dc1eabb232a9a34c8e820
Attached To
rM GPGME
Event Timeline
Log In to Comment