Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F36623418
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
34 KB
Subscribers
None
View Options
diff --git a/lang/js/DemoExtension/maindemo.js b/lang/js/DemoExtension/maindemo.js
index 67b811f6..6230c3f0 100644
--- a/lang/js/DemoExtension/maindemo.js
+++ b/lang/js/DemoExtension/maindemo.js
@@ -1,67 +1,67 @@
/* 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>
*/
/* global document, Gpgmejs */
document.addEventListener('DOMContentLoaded', function() {
Gpgmejs.init().then(function(gpgmejs){
document.getElementById('buttonencrypt').addEventListener('click',
function(){
let data = document.getElementById('cleartext').value;
let keyId = document.getElementById('pubkey').value;
gpgmejs.encrypt(data, keyId).then(
function(answer){
if (answer.data){
document.getElementById(
'answer').value = answer.data;
}
}, function(errormsg){
alert( errormsg.message);
});
});
document.getElementById('buttondecrypt').addEventListener('click',
function(){
let data = document.getElementById('ciphertext').value;
gpgmejs.decrypt(data).then(
function(answer){
if (answer.data){
document.getElementById(
'answer').value = answer.data;
}
}, function(errormsg){
alert(errormsg.message);
});
});
document.getElementById('getdefaultkey').addEventListener('click',
function(){
gpgmejs.Keyring.getDefaultKey().then(function(answer){
- document.getElementById('defaultkey').innerHtml =
+ document.getElementById('defaultkey').textContent =
answer.fingerprint;
}, function(errormsg){
alert(errormsg.message);
});
});
});
});
diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js
index 3e4f1c78..88c2b92f 100644
--- a/lang/js/src/Key.js
+++ b/lang/js/src/Key.js
@@ -1,563 +1,548 @@
/* 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 fingerprint.
* @param {String} fingerprint
*/
export function createKey(fingerprint){
if (!isFingerprint(fingerprint)){
return gpgme_error('PARAM_WRONG');
}
else return new GPGME_Key(fingerprint);
}
/**
* Representing the Keys as stored in GPG
* It allows to query almost all information defined in gpgme Key Objects
* Refer to validKeyProperties for available information, and the gpgme
* documentation on their meaning
* (https://www.gnupg.org/documentation/manuals/gpgme/Key-objects.html)
*
*/
export class GPGME_Key {
constructor(fingerprint){
this.fingerprint = fingerprint;
}
set fingerprint(fpr){
if (isFingerprint(fpr) === true) {
if (this._data === undefined) {
this._data = {fingerprint: fpr};
} else {
if (this._data.fingerprint === undefined){
this._data.fingerprint = fpr;
}
}
}
}
get fingerprint(){
if (!this._data || !this._data.fingerprint){
return gpgme_error('KEY_INVALID');
}
return this._data.fingerprint;
}
/**
*
* @param {Object} data Bulk set data for this key, with the Object as sent
* by gpgme-json.
* @returns {GPGME_Key|GPGME_Error} The Key object itself after values have
* been set
*/
setKeyData(data){
if (this._data === undefined) {
this._data = {};
}
if (
typeof(data) !== 'object') {
return gpgme_error('KEY_INVALID');
}
if (!this._data.fingerprint && isFingerprint(data.fingerprint)){
if (data.fingerprint !== this.fingerprint){
return gpgme_error('KEY_INVALID');
}
this._data.fingerprint = data.fingerprint;
} else if (this._data.fingerprint !== data.fingerprint){
return gpgme_error('KEY_INVALID');
}
let dataKeys = Object.keys(data);
for (let i=0; i< dataKeys.length; i++){
if (!validKeyProperties.hasOwnProperty(dataKeys[i])){
return gpgme_error('KEY_INVALID');
}
if (validKeyProperties[dataKeys[i]](data[dataKeys[i]]) !== true ){
return gpgme_error('KEY_INVALID');
}
switch (dataKeys[i]){
case 'subkeys':
this._data.subkeys = [];
for (let i=0; i< data.subkeys.length; i++) {
this._data.subkeys.push(
new GPGME_Subkey(data.subkeys[i]));
}
break;
case 'userids':
this._data.userids = [];
for (let i=0; i< data.userids.length; i++) {
this._data.userids.push(
new GPGME_UserId(data.userids[i]));
}
break;
case 'last_update':
this._data[dataKeys[i]] = new Date( data[dataKeys[i]] * 1000 );
break;
default:
this._data[dataKeys[i]] = data[dataKeys[i]];
}
}
return this;
}
/**
* Query any property of the Key list
* @param {String} property Key property to be retreived
* @param {*} cached (optional) if false, the data will be directly queried
* from gnupg.
* @returns {*|Promise<*>} the value, or if not cached, a Promise
* resolving on the value
*/
get(property, cached=true) {
if (cached === false) {
let me = this;
return new Promise(function(resolve, reject) {
if (!validKeyProperties.hasOwnProperty(property)){
reject('PARAM_WRONG');
} else if (property === 'armored'){
resolve(me.getArmor());
} else if (property === 'hasSecret'){
resolve(me.getHasSecret());
} else {
me.refreshKey().then(function(key){
resolve(key.get(property, true));
}, function(error){
reject(error);
});
}
});
} else {
if (!validKeyProperties.hasOwnProperty(property)){
return gpgme_error('PARAM_WRONG');
}
if (!this._data.hasOwnProperty(property)){
return gpgme_error('KEY_NO_INIT');
} else {
return (this._data[property]);
}
}
}
/**
* Reloads the Key from gnupg
*/
refreshKey() {
let me = this;
return new Promise(function(resolve, reject) {
if (!me._data.fingerprint){
reject(gpgme_error('KEY_INVALID'));
}
let msg = createMessage('keylist');
msg.setParameter('sigs', true);
msg.setParameter('keys', me._data.fingerprint);
msg.post().then(function(result){
if (result.keys.length === 1){
me.setKeyData(result.keys[0]);
resolve(me);
} else {
reject(gpgme_error('KEY_NOKEY'));
}
}, function (error) {
reject(gpgme_error('GNUPG_ERROR'), error);
});
});
}
/**
* Query the armored block of the non- secret parts of the Key directly
* from gpg.
* @returns {Promise<String>}
* @async
*/
getArmor(){
let me = this;
return new Promise(function(resolve, reject) {
if (!me._data.fingerprint){
reject(gpgme_error('KEY_INVALID'));
}
let msg = createMessage('export');
msg.setParameter('armor', true);
msg.setParameter('keys', me._data.fingerprint);
msg.post().then(function(result){
me._data.armored = result.data;
resolve(result.data);
}, function(error){
reject(error);
});
});
}
/**
* Find out if the Key includes a secret part
* @returns {Promise<Boolean>}
*
* @async
*/
- // TODO: Does not work yet, result is always false
getHasSecret(){
let me = this;
return new Promise(function(resolve, reject) {
if (!me._data.fingerprint){
reject(gpgme_error('KEY_INVALID'));
}
let msg = createMessage('keylist');
msg.setParameter('keys', me._data.fingerprint);
msg.setParameter('secret', true);
msg.post().then(function(result){
me._data.hasSecret = null;
- if (result.keys === undefined || result.keys.length < 1) {
+ if (
+ result.keys &&
+ result.keys.length === 1 &&
+ result.keys[0].secret === true
+ ) {
+ me._data.hasSecret = true;
+ resolve(true);
+ } else {
me._data.hasSecret = false;
resolve(false);
}
- else if (result.keys.length === 1){
- let key = result.keys[0];
- if (!key.subkeys){
- me._data.hasSecret = false;
- resolve(false);
- } else {
- for (let i=0; i < key.subkeys.length; i++) {
- if (key.subkeys[i].secret === true) {
- me._data.hasSecret = true;
- resolve(true);
- break;
- }
- if (i === (key.subkeys.length -1)) {
- me._data.hasSecret = false;
- resolve(false);
- }
- }
- }
- } else {
- reject(gpgme_error('CONN_UNEXPECTED_ANSWER'));
- }
}, function(error){
reject(error);
});
});
}
/**
* Convenience functions to be directly used as properties of the Key
* Notice that these rely on cached info and may be outdated. Use the async
* get(property, false) if you need the most current info
*/
/**
* @returns {String} The armored public Key block
*/
get armored(){
return this.get('armored', true);
}
/**
* @returns {Boolean} If the key is considered a "private Key",
* i.e. owns a secret subkey.
*/
get hasSecret(){
return this.get('hasSecret', true);
}
/**
* 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>} Success if key was deleted, rejects with a
* GPG error otherwise
*/
delete(){
let me = this;
return new Promise(function(resolve, reject){
if (!me._data.fingerprint){
reject(gpgme_error('KEY_INVALID'));
}
let msg = createMessage('delete');
msg.setParameter('key', me._data.fingerprint);
msg.post().then(function(result){
resolve(result.success);
}, function(error){
reject(error);
});
});
}
}
/**
* The subkeys of a Key. Currently, they cannot be refreshed separately
*/
class GPGME_Subkey {
constructor(data){
let keys = Object.keys(data);
for (let i=0; i< keys.length; i++) {
this.setProperty(keys[i], data[keys[i]]);
}
}
setProperty(property, value){
if (!this._data){
this._data = {};
}
if (validSubKeyProperties.hasOwnProperty(property)){
if (validSubKeyProperties[property](value) === true) {
if (property === 'timestamp' || property === 'expires'){
this._data[property] = new Date(value * 1000);
} else {
this._data[property] = value;
}
}
}
}
/**
*
* @param {String} property Information to request
* @returns {String | Number}
* TODO: date properties are numbers with Date in seconds
*/
get(property) {
if (this._data.hasOwnProperty(property)){
return (this._data[property]);
}
}
}
class GPGME_UserId {
constructor(data){
let keys = Object.keys(data);
for (let i=0; i< keys.length; i++) {
this.setProperty(keys[i], data[keys[i]]);
}
}
setProperty(property, value){
if (!this._data){
this._data = {};
}
if (validUserIdProperties.hasOwnProperty(property)){
if (validUserIdProperties[property](value) === true) {
if (property === 'last_update'){
this._data[property] = new Date(value*1000);
} else {
this._data[property] = value;
}
}
}
}
/**
*
* @param {String} property Information to request
* @returns {String | Number}
* TODO: date properties are numbers with Date in seconds
*/
get(property) {
if (this._data.hasOwnProperty(property)){
return (this._data[property]);
}
}
}
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);
}
};
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);
}
};
const validKeyProperties = {
//TODO better validation?
'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 43d257d2..8bec1cea 100644
--- a/lang/js/src/Keyring.js
+++ b/lang/js/src/Keyring.js
@@ -1,329 +1,327 @@
/* 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';
export class GPGME_Keyring {
constructor(){
}
/**
* @param {String} pattern (optional) pattern A pattern to search for,
* in userIds or KeyIds
* @param {Boolean} prepare_sync (optional, default true) if set to true,
* Key.armor and Key.hasSecret will be called, so they can be used
* inmediately. This allows for full synchronous use. If set to false,
* these will initially only be available as Promises in getArmor() and
* getHasSecret()
* @returns {Promise.<Array<GPGME_Key>>}
*
*/
getKeys(pattern, prepare_sync){
return new Promise(function(resolve, reject) {
let msg = createMessage('keylist');
if (pattern !== undefined){
msg.setParameter('keys', pattern);
}
msg.setParameter('sigs', true);
msg.post().then(function(result){
let resultset = [];
let promises = [];
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);
}
if (promises.length > 0) {
Promise.all(promises).then(function() {
resolve(resultset);
}, function(error){
reject(error);
});
} else {
resolve(resultset);
}
}
});
});
}
/**
* Fetches the armored public Key blocks for all Keys matchin the pattern
* (if no pattern is given, fetches all known to gnupg)
* @param {String|Array<String>} pattern (optional)
* @returns {Promise<String>} Armored Key blocks
*/
getKeysArmored(pattern) {
return new Promise(function(resolve, reject) {
let msg = createMessage('export');
msg.setParameter('armor', true);
if (pattern !== undefined){
msg.setParameter('keys', pattern);
}
msg.post().then(function(result){
resolve(result.data);
}, function(error){
reject(error);
});
});
}
/**
* Returns the Key to be used by default for signing operations,
* looking up the gpg configuration, or returning the first key that
* contains a secret key.
* @returns {Promise<GPGME_Key>}
*
* @async
* TODO: getHasSecret always returns false at this moment, so this fucntion
* still does not fully work as intended.
*
*/
getDefaultKey() {
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);
});
});
}
/**
*
* @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 getKeys()).
*
* @returns {Promise<Object>} result: A summary and an array of Keys
* considered
*
* @returns result.summary: Numerical summary of the result. See the
* feedbackValues variable for available values and the gnupg documentation
* https://www.gnupg.org/documentation/manuals/gpgme/Importing-Keys.html
* for details on their meaning.
* @returns {Array<Object>} result.Keys: Array of objects containing:
* @returns {GPGME_Key} Key.key The resulting key
* @returns {String} Key.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.
* @returns {Boolean} Key.changes.userId: userIds changed
* @returns {Boolean} Key.changes.signature: signatures changed
* @returns {Boolean} Key.changes.subkey: subkeys changed
*/
importKey(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);
});
});
}
deleteKey(fingerprint){
if (isFingerprint(fingerprint) === true) {
let key = createKey(fingerprint);
key.delete();
}
}
/**
* 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_ from inside gpgmejs.
*
* @param {String} userId The user Id, e.g. "Foo Bar <foo@bar.baz>"
- * @param {*} algo (optional) algorithm to be used. See
- * {@link supportedKeyAlgos } below for supported values.
- * @param {Number} keyLength (optional) TODO
+ * @param {*} 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'
*
* @returns{Promise<Key>}
*/
- generateKey(userId, algo = 'default', keyLength, expires){
+ generateKey(userId, algo = 'default', expires){
if (
typeof(userId) !== 'string' ||
supportedKeyAlgos.indexOf(algo) < 0 ||
(expires && !(expires instanceof Date))
- // TODO keylength
- // TODO check for completeness of algos
){
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);
+ msg.setParameter('algo', algo );
if (expires){
msg.setParameter('expires',
Math.floor(expires.valueOf()/1000));
}
- // TODO append keylength to algo
msg.post().then(function(response){
me.getKeys(response.fingerprint, true).then(
// TODO make prepare_sync (second parameter) optional here.
function(result){
resolve(result);
}, function(error){
reject(error);
});
}, function(error) {
reject(error);
});
});
}
}
/**
* A list of algorithms supported for key generation.
*/
const supportedKeyAlgos = [
'default',
- 'rsa',
- 'dsa',
- 'elg',
+ 'rsa', 'rsa2048', 'rsa3072', 'rsa4096',
+ 'dsa', 'dsa2048', 'dsa3072', 'dsa4096',
+ 'elg', 'elg2048', 'elg3072', 'elg4096',
'ed25519',
- 'cv25519'
+ '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
Thu, Feb 26, 6:52 PM (16 h, 9 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
d9/f3/b9a8102158faaaec1191608702ee
Attached To
rM GPGME
Event Timeline
Log In to Comment