core: Detect bad passphrase error on certificate import
* src/import.c (gpgme_op_import_result): Check fpr for NULL. (parse_error): New. (import_status_handler): Handle error status line. * doc/gpgme.texi (gpgme_import_status_t): Mention that fpr can be NULL. * tests/gpg/t-import.c (check_result): Check fpr for NULL. * tests/run-threaded.c (delete_impres): Check fpr for NULL. -- When importing an encrypted certificate a wrong passphrase may be entered. In this case gpgsm emits a status line with a bad passphrase error and an "invalid object" error. To make it possible for callers to handle a wrong passphrase error more gracefully, an import status with bad passphrase error is added to the import result for each status line with bad passphrase error. GnuPG-bug-id: 5713
This commit is contained in:
parent
0636e229d7
commit
305d8668ca
@ -5115,7 +5115,9 @@ This is a pointer to the next status structure in the linked list, or
|
|||||||
@code{NULL} if this is the last element.
|
@code{NULL} if this is the last element.
|
||||||
|
|
||||||
@item char *fpr
|
@item char *fpr
|
||||||
This is the fingerprint of the key that was considered.
|
This is the fingerprint of the key that was considered, or @code{NULL}
|
||||||
|
if the fingerprint of the key is not known, e.g. because the key to
|
||||||
|
import was encrypted and decryption failed.
|
||||||
|
|
||||||
@item gpgme_error_t result
|
@item gpgme_error_t result
|
||||||
If the import was not successful, this is the error value that caused
|
If the import was not successful, this is the error value that caused
|
||||||
|
54
src/import.c
54
src/import.c
@ -103,7 +103,7 @@ gpgme_op_import_result (gpgme_ctx_t ctx)
|
|||||||
while (impstat)
|
while (impstat)
|
||||||
{
|
{
|
||||||
TRACE_LOG ("import[%i] for %s = 0x%x (%s)",
|
TRACE_LOG ("import[%i] for %s = 0x%x (%s)",
|
||||||
i, impstat->fpr, impstat->status,
|
i, impstat->fpr ? impstat->fpr : "null", impstat->status,
|
||||||
gpgme_strerror (impstat->result));
|
gpgme_strerror (impstat->result));
|
||||||
impstat = impstat->next;
|
impstat = impstat->next;
|
||||||
i++;
|
i++;
|
||||||
@ -223,6 +223,49 @@ parse_import_res (char *args, gpgme_import_result_t result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Parses an error on a status line and adds a corresponding import status.
|
||||||
|
Currently, only supports "import.parsep12 11". */
|
||||||
|
static gpgme_error_t
|
||||||
|
parse_error (char *args, gpgme_import_status_t *import_status)
|
||||||
|
{
|
||||||
|
gpgme_import_status_t import;
|
||||||
|
char *tail;
|
||||||
|
long int nr;
|
||||||
|
|
||||||
|
tail = strchr (args, ' ');
|
||||||
|
if (!tail)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*tail = '\0';
|
||||||
|
if (strcmp( args, "import.parsep12" ))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
args = tail + 1;
|
||||||
|
|
||||||
|
gpg_err_set_errno (0);
|
||||||
|
nr = strtol (args, &tail, 0);
|
||||||
|
if (errno || args == tail || !(*tail == ' ' || !*tail))
|
||||||
|
{
|
||||||
|
/* The crypto backend does not behave. */
|
||||||
|
return trace_gpg_error (GPG_ERR_INV_ENGINE);
|
||||||
|
}
|
||||||
|
if (nr != GPG_ERR_BAD_PASSPHRASE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
import = malloc (sizeof (*import));
|
||||||
|
if (!import)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
import->next = NULL;
|
||||||
|
|
||||||
|
import->result = gpg_error (GPG_ERR_BAD_PASSPHRASE);
|
||||||
|
import->status = 0;
|
||||||
|
import->fpr = 0;
|
||||||
|
|
||||||
|
*import_status = import;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gpgme_error_t
|
static gpgme_error_t
|
||||||
import_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
import_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
||||||
{
|
{
|
||||||
@ -252,6 +295,15 @@ import_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
|||||||
err = parse_import_res (args, &opd->result);
|
err = parse_import_res (args, &opd->result);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GPGME_STATUS_ERROR:
|
||||||
|
err = parse_error (args, opd->lastp);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (*opd->lastp)
|
||||||
|
opd->lastp = &(*opd->lastp)->next;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -149,16 +149,17 @@ check_result (gpgme_import_result_t result, const char *fpr, int secret)
|
|||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (strcmp (fpr, result->imports->fpr))
|
if (!result->imports->fpr || strcmp (fpr, result->imports->fpr))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Unexpected fingerprint %s\n",
|
fprintf (stderr, "Unexpected fingerprint %s\n",
|
||||||
result->imports->fpr);
|
result->imports->fpr ? result->imports->fpr : "null");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
if (result->imports->next && strcmp (fpr, result->imports->next->fpr))
|
if (result->imports->next
|
||||||
|
&& (!result->imports->next->fpr || strcmp (fpr, result->imports->next->fpr)))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Unexpected fingerprint on second status %s\n",
|
fprintf (stderr, "Unexpected fingerprint on second status %s\n",
|
||||||
result->imports->next->fpr);
|
result->imports->next->fpr ? result->imports->next->fpr : "null");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
if (result->imports->result != 0)
|
if (result->imports->result != 0)
|
||||||
|
@ -517,6 +517,7 @@ delete_impres (gpgme_import_result_t r, gpgme_protocol_t proto)
|
|||||||
|
|
||||||
for (st=r->imports; st; st = st->next)
|
for (st=r->imports; st; st = st->next)
|
||||||
{
|
{
|
||||||
|
if (st->fpr)
|
||||||
delete_fpr (st->fpr, proto);
|
delete_fpr (st->fpr, proto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user