Page MenuHome GnuPG

Failed to sign with subkey with a signature function using gpgme_op_keysign
Closed, ResolvedPublic

Description

I added a key pair without a master key to the signers (signers list cleared beforehand), and this key pair has an RSA sub-key with a signature function. Then call gpgme_op_keysign on another key, and the error code “no secret key” is returned.
Is this caused by the missing master key? If so, how to distinguish whether the master key is indeed the case, I found that the GPGME document is not very clear about this.

Details

Version
1.15.2

Event Timeline

By " without a master key" do you mean a keypair where the private key for the primary key is missing?

A popular way is to export the subkey, delete the existing key pair, and then import the subkey back, so that the actual value of the master key will not appear in the key pair to protect the master key(The value of the master key will be backed up and stored in another safe place).
At this time, gpg -K will display the following for this key pair:

sec#  rsa3072 2021-05-28 [SC]
       9C6D3****************************************7624A
uid             [ Unknown ] *********** <********@******.com>
ssb   rsa3072 ****-**-** [E]
ssb   rsa4096 ****-**-** [S]

sec will be followed by a # sign to indicate that the master key is not in the key pair. After observing the variables when the program is running and reading the documentation, I haven't found how gpgme provides an API to handle this situation.

Yes, you need the secret part of the primary key. gpgme has this info but it is easy to miss. Even our gpgme/tests/run-keylist.c debug tool did not show it directly. I modified it to make this more clear, see the latest gpgme commit. Here is an example for my key:

$ ./run-keylist --verbose --with-secret  63113AE866587D0A
keyid   : 63113AE866587D0A
caps    : esc
flags   : secret
upd     : 0 (0)
fpr    0: AEA84EDCF01AD86C4701C85C63113AE866587D0A
grip   0: CE5C1F1B8C96F1A078A2D1932EEE738A854ED976
curve  0: ed25519
caps   0: sc
flags  0:
fpr    1: E05BA20ED4F17768613B03C53CD7B3A055039224
grip   1: 7A1E3130C9CBDBF203A0AD8E186D9C511D5019FF
curve  1: cv25519
caps   1: e
flags  1: secret
fpr    2: 8777461F2A074EBC480D359419CC1C9E085B107A
grip   2: FF35C6E765F440145095750DC97D43D496C5ABEA
curve  2: ed25519
caps   2: s
flags  2: secret

The first flags line gives the global value which here says that for some parts a secret key is available. But if you look at the first subkey object you see that the secret flag is not shown. This reflects the '#' in gpg's output. Make sure to run a secret key listing or use GPGME_KEYLIST_MODE_WITH_SECRET.

For signing (aka certifying) another key you need a (sub)key with the "certify" capability. Your signing subkey can only be used for signing data but not for certifying keys. This isn't specific to gpgme. See https://datatracker.ietf.org/doc/html/rfc4880#section-5.2.3.21.

Take care: It is not clear whether you may use a [C} subkey for certification. GnuPG currently accepts this but the RFC can also be read as primary keys needs to to do the certification.

Saturneric claimed this task.
This comment was removed by Saturneric.