json: Remove subkey-algo from createkey command.

* src/gpgme-json.c (op_createkey): Remove subkey-algo param.
(GPG_AGENT_ALLOWS_KEYGEN_TRHOUGH_BROWSER): Fix typo.
* lang/js/src/Keyring.js: Remove subkey-algo support.
* lang/js/src/permittedOperations.js: Ditto.
--

We do not want to expose details of the protocol's key generation and
thus the subkey-algo does not make sense.  Right now we support only
the default and future-default algorithms.  A user can configure them
anyway using new-default-key-algo in gpg.conf.  Eventually we may
officially support a more flexible way of creating special structured
OpenPGP keys but right now that is not part of the API.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2018-09-19 11:51:31 +02:00
parent 7f14958606
commit c569adb5e3
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
4 changed files with 10 additions and 95 deletions

View File

@ -25,7 +25,8 @@ List of Copyright holders
Copyright (C) 2002 John Goerzen Copyright (C) 2002 John Goerzen
Copyright (C) 2014, 2015 Martin Albrecht Copyright (C) 2014, 2015 Martin Albrecht
Copyright (C) 2015, 2018 Ben McGinnes Copyright (C) 2015, 2018 Ben McGinnes
Copyright (C) 2015-2016 Bundesamt für Sicherheit in der Informationstechnik Copyright (C) 2015, 2016, 2018
Bundesamt für Sicherheit in der Informationstechnik
Copyright (C) 2016 Intevation GmbH Copyright (C) 2016 Intevation GmbH

View File

@ -387,13 +387,11 @@ export class GPGME_Keyring {
* values. If ommitted, 'default' is used. * values. If ommitted, 'default' is used.
* @param {Number} option.expires (optional) Expiration time in seconds * @param {Number} option.expires (optional) Expiration time in seconds
* from now. If not set or set to 0, expiration will be 'never' * from now. If not set or set to 0, expiration will be 'never'
* @param {String} options.subkey_algo (optional) algorithm of the
* encryption subkey. If ommited the same as algo is used.
* *
* @return {Promise<Key|GPGME_Error>} * @return {Promise<Key|GPGME_Error>}
* @async * @async
*/ */
generateKey ({ userId, algo = 'default', expires= 0, subkey_algo } = {}){ generateKey ({ userId, algo = 'default', expires= 0 } = {}){
if (typeof userId !== 'string' if (typeof userId !== 'string'
// eslint-disable-next-line no-use-before-define // eslint-disable-next-line no-use-before-define
|| (algo && supportedKeyAlgos.indexOf(algo) < 0 ) || (algo && supportedKeyAlgos.indexOf(algo) < 0 )
@ -402,17 +400,11 @@ export class GPGME_Keyring {
return Promise.reject(gpgme_error('PARAM_WRONG')); return Promise.reject(gpgme_error('PARAM_WRONG'));
} }
// eslint-disable-next-line no-use-before-define // eslint-disable-next-line no-use-before-define
if (subkey_algo && supportedKeyAlgos.indexOf(subkey_algo) < 0){
return Promise.reject(gpgme_error('PARAM_WRONG'));
}
let me = this; let me = this;
return new Promise(function (resolve, reject){ return new Promise(function (resolve, reject){
let msg = createMessage('createkey'); let msg = createMessage('createkey');
msg.setParameter('userid', userId); msg.setParameter('userid', userId);
msg.setParameter('algo', algo); msg.setParameter('algo', algo);
if (subkey_algo) {
msg.setParameter('subkey-algo',subkey_algo );
}
msg.setParameter('expires', expires); msg.setParameter('expires', expires);
msg.post().then(function (response){ msg.post().then(function (response){
me.getKeys({ me.getKeys({

View File

@ -348,9 +348,6 @@ export const permittedOperations = {
algo: { algo: {
allowed: ['string'] allowed: ['string']
}, },
'subkey-algo': {
allowed: ['string']
},
expires: { expires: {
allowed: ['number'], allowed: ['number'],
} }

View File

@ -2973,15 +2973,10 @@ static const char hlp_createkey[] =
"userid: The user id. E.g. \"Foo Bar <foo@bar.baz>\"\n" "userid: The user id. E.g. \"Foo Bar <foo@bar.baz>\"\n"
"\n" "\n"
"Optional parameters:\n" "Optional parameters:\n"
"algo: Algo of the key as string. See doc for gpg --quick-gen-key.\n" "algo: Algo of the key as string. See doc for gpg --quick-gen-key.\n"
"subkey-algo: Algo of the encryption subkey. If ommited the same as algo\n" " Supported values are \"default\" and \"future-default\".\n"
" is used.\n" "expires: Seconds from now to expiry as Number. 0 means no expiry.\n"
" Except for dsa and ed25519 where the according\n" " The default is to use a standard expiration interval.\n"
" elg / cv25519 algo will be used as subkey-algo.\n"
"\n"
" If algo is omitted or default or future-default subkey-algo\n"
" is ignored.\n"
"expires: Seconds from now to expiry as Number. 0 means no expiry.\n"
"\n" "\n"
"Response on success:\n" "Response on success:\n"
"fingerprint: The fingerprint of the created key.\n" "fingerprint: The fingerprint of the created key.\n"
@ -3000,9 +2995,8 @@ op_createkey (cjson_t request, cjson_t result)
const char *algo = "default"; const char *algo = "default";
const char *userid; const char *userid;
gpgme_genkey_result_t res; gpgme_genkey_result_t res;
char *new_fpr = NULL;
#ifdef GPG_AGENT_ALLOWS_KEYGEN_TRHOUGH_BROWSER #ifdef GPG_AGENT_ALLOWS_KEYGEN_THROUGH_BROWSER
/* GnuPG forbids keygen through the browser socket so for /* GnuPG forbids keygen through the browser socket so for
this we create an unrestricted context. this we create an unrestricted context.
See GnuPG-Bug-Id: T4010 for more info */ See GnuPG-Bug-Id: T4010 for more info */
@ -3054,79 +3048,10 @@ op_createkey (cjson_t request, cjson_t result)
goto leave; goto leave;
} }
/* Dup the fpr as the result might become invalid after context reuse. */ xjson_AddStringToObject0 (result, "fingerprint", res->fpr);
new_fpr = xstrdup (res->fpr);
if (algo && strcmp ("default", algo) && strcmp ("future-default", algo))
{
/* We need to add the encryption subkey manually */
gpgme_ctx_t keylistctx = create_onetime_context (GPGME_PROTOCOL_OpenPGP);
gpgme_key_t new_key = NULL;
char *subkey_algo = NULL;
j_tmp = cJSON_GetObjectItem (request, "subkey_algo");
if (j_tmp && cjson_is_string (j_tmp))
{
subkey_algo = xstrdup (j_tmp->valuestring);
}
if (!subkey_algo)
{
subkey_algo = strdup (algo);
if (!strncmp ("dsa", subkey_algo, 3))
{
subkey_algo[0] = 'e';
subkey_algo[1] = 'l';
subkey_algo[2] = 'g';
}
if (!strcmp ("ed25519", subkey_algo))
{
strcpy (subkey_algo, "cv25519");
}
}
err = gpgme_get_key (keylistctx, new_fpr, &new_key, 1);
release_onetime_context (keylistctx);
if (err || !new_key)
{
gpg_error_object (result, err, "Error finding created key: %s",
gpg_strerror (err));
xfree (subkey_algo);
goto leave;
}
err = gpgme_op_createsubkey (ctx, new_key, subkey_algo,
0, expires, flags |= GPGME_CREATE_ENCR);
xfree (subkey_algo);
if (err)
{
/* This can happen for example if the user cancels the
* pinentry to unlock the primary key when adding the
* subkey. To avoid an artifact of a pimary key without
* an encryption capable subkey we delete the created
* key and treat the whole operation as failed. */
gpgme_error_t err2;
gpg_error_object (result, err, "Error creating subkey: %s",
gpg_strerror (err));
log_info ("Deleting primary key after keygen failure.\n");
err2 = gpgme_op_delete_ext (ctx, new_key, GPGME_DELETE_FORCE |
GPGME_DELETE_ALLOW_SECRET);
if (err2)
{
log_error ("Error deleting primary key: %s",
gpg_strerror (err));
}
gpgme_key_unref (new_key);
goto leave;
}
gpgme_key_unref (new_key);
}
xjson_AddStringToObject0 (result, "fingerprint", new_fpr);
leave: leave:
xfree (new_fpr); #ifdef GPG_AGENT_ALLOWS_KEYGEN_THROUGH_BROWSER
#ifdef GPG_AGENT_ALLOWS_KEYGEN_TRHOUGH_BROWSER
release_context (ctx); release_context (ctx);
#else #else
gpgme_release (ctx); gpgme_release (ctx);