ruby-gpgme icon indicating copy to clipboard operation
ruby-gpgme copied to clipboard

Deleting a private key on macOS Big Sur hangs

Open dvkch opened this issue 3 years ago • 4 comments

I've encountered an issue where deleting a key would hang forever, using the following code:

GPGME::Key.find(:public, key_id).each { |k| k.delete!(true) }

# or
GPGME::Key.find(:private key_id).each { |k| k.delete!(true) }
(B(B(0lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk(B(B(0x(B Do you really want to permanently delete the OpenPGP secret key: (0x(B(B(0x(B "EnsoTest <[email protected]>"(0x(B(B(0x(B 2048-bit RSA key, ID 0FDD92544BA73B80,(0x(B(B(0x(B created 2020-08-25.(0x(B(B(0x(B ?(0x(B(B(0x(B(B(0x(B(B(0x(B     (B<Delete key>(B

If the key is a public key with no associated private key it works fine. If this is a public key with an associated private key, or if it is a private key itself, it will hang for around 2 minutes.

I have been able to reproduce this every time when running rspec on a Rails 6.0 project; the key was generated once and is re-added to the my test env using:

private_key = IO.read('spec/support/test_gpg')
key_id = GPGME::Key.import(private_key).imports.map(&:fpr)

Maybe there is an additional argument or configuration that is missing to prevent user confirmation via STDIN ?

dvkch avatar Nov 08 '21 15:11 dvkch

@dvkch were you able to find any workaround to input the user confirmation?

errfanwadia avatar Sep 11 '22 23:09 errfanwadia

@errfanwadia Unfortunately not. There might be a way in Ruby to connect to STDIN and STDOUT to know when the lib asks for confirmation and write it to STDOUT programmatically from another thread, but I haven't had the chance to test it though

dvkch avatar Sep 13 '22 17:09 dvkch

The current gem is not supporting this for now but the gpg/gpgme has an additional function gpgme_op_delete_ext where we can put the flags for the force delete:

/* Flags for the key delete functions.  */
#define GPGME_DELETE_ALLOW_SECRET (1 << 0)  /* Also delete secret key.     */
#define GPGME_DELETE_FORCE        (1 << 1)  /* Do not ask user to confirm.  */

see:

  • https://github.com/gpg/gpgme/blob/47f3d92bf340f2a24b3c837a3afa5e1890b413ac/src/delete.c#L192
  • https://github.com/gpg/gpgme/blob/47f3d92bf340f2a24b3c837a3afa5e1890b413ac/src/gpgme.h.in#L1961

evgenii avatar Mar 01 '24 12:03 evgenii

@errfanwadia Unfortunately not. There might be a way in Ruby to connect to STDIN and STDOUT to know when the lib asks for confirmation and write it to STDOUT programmatically from another thread, but I haven't had the chance to test it though

you can definitely do this, but it is kind of painful obviously. All 3 are predefined as IO objects named STDOUT, STDIN, and STDERR. Instead tho, you might consider just marking the key untrusted. It will still be there, but not get used normally.

kernelsmith avatar Aug 27 '24 18:08 kernelsmith