json: Add subkey_algo and defaults to createkey

* src/gpgme-json.c (op_createkey, hlp_createkey): Add subkey_algo
handling.
(hlp_createkey): Fix documentation of expiry.
--
Due to the funny quick-gen-key interface generating a key
with an explicit algo would result in bad defaults (only an SC key),
without a subkey.

This adds handling that should probably be in GnuPG proper to fix
the semantics of createkey by adding default subkey_algo handling.
This commit is contained in:
Andre Heinecke 2018-08-20 16:38:36 +02:00
parent 75bc5e6356
commit 8103eeba80
No known key found for this signature in database
GPG Key ID: 2978E9D40CBABA5C

View File

@ -2878,8 +2878,15 @@ 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"
"expires: Seconds since epoch to expiry as Number. 0 means no expiry.\n" "subkey-algo: Algo of the encryption subkey. If ommited the same as algo\n"
" is used.\n"
" Except for dsa and ed25519 where the according\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"
@ -2891,12 +2898,14 @@ op_createkey (cjson_t request, cjson_t result)
{ {
gpg_error_t err; gpg_error_t err;
gpgme_ctx_t ctx = NULL; gpgme_ctx_t ctx = NULL;
unsigned int flags = 0; unsigned int flags = GPGME_CREATE_FORCE; /* Always force as the GUI should
handle checks, if required. */
unsigned long expires = 0; unsigned long expires = 0;
cjson_t j_tmp; cjson_t j_tmp;
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_TRHOUGH_BROWSER
/* GnuPG forbids keygen through the browser socket so for /* GnuPG forbids keygen through the browser socket so for
@ -2950,9 +2959,58 @@ op_createkey (cjson_t request, cjson_t result)
goto leave; goto leave;
} }
xjson_AddStringToObject0 (result, "fingerprint", res->fpr); /* Dup the fpr as the result might become invalid after context reuse. */
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)
{
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)
goto leave;
}
xjson_AddStringToObject0 (result, "fingerprint", new_fpr);
leave: leave:
xfree (new_fpr);
#ifdef GPG_AGENT_ALLOWS_KEYGEN_TRHOUGH_BROWSER #ifdef GPG_AGENT_ALLOWS_KEYGEN_TRHOUGH_BROWSER
release_context (ctx); release_context (ctx);
#else #else