GPGME_No_Matching_Secret_Key error code missing

Marcus Brinkmann Marcus.Brinkmann@ruhr-uni-bochum.de
Thu Feb 13 04:02:01 2003


On Thu, Feb 13, 2003 at 12:02:15AM +0100, Ingo Klöcker wrote:
> Me and Marc, for example. But we didn't have very much to do with the 
> Aegypten project. On the contrary Werner (yes, Werner Koch) was 
> involved in the Aegypten project. And obviously he thought that gpgme 
> was mature enough to be used for this project.

Well, I was involved in the Aegyten project as well, and I consider GPGME to be
mature enough to be used for this project.  Nevertheless there is still a
lot of work to do, and some of that work is in more informative error
reporting.  In your original mail, you seemed to assume that the vague
or incorrect error reporting is how we intended it to be, but that is
not the case:  We are perfectly aware that there is still a lot of things
that need to be done.  Some substantial work is done (see the unstable
0.4.x CVS tree), others is done when we hear from users that they need
it (if that is not enough you can obviously contract us to do it even
quicker).  Recently, a lot of new developments have been done based on
feedback from Miguel Coca, the maintainer of GPA.  I am happy to get
feedback from Aegypten users and developers now, so that we can polish
that end, too.

Now that this is out of the way, let's look at the technicalities.

> > I am still waiting for more
> > information on why Ingo sees No_Passphrase where I expect
> > Decryption_Failed or Invalid_Key. I am also open to a discussion if a
> > distinction between no passphrase and bad passphrase is useful.
> 
> I was wrong. If decryption is impossible due to lack of an appropriate 
> secret key then indeed Decryption_Failed is returned. No_Passphrase was 
> returned because no gpg-agent was running and therefore gpg couldn't 
> ask for the passphrase.

If no gpg-agent is running, gpgsm will start it itself, so this doesn't
explain the No_Passphrase.  If gpgsm can not start an agent, it will emit
the Assuan error 208 No Secret Key (in the decrypt case), which is mapped to
GPGME_Invalid_Key (a catch-all error for key problems - clearly not correct,
but it's not No_Passphrase either).  I am still at a loss how you can get a
No_Passphrase error, gpg-agent running or not.  It would be helpful to see
a log of gpgsm --server running the operation under the failure conditions.
Here is an example of a simulated gpg-agent unavailability error:

marcus@ulysses[0]:/tmp$ gpgsm --server 4< def.gpgsm  5> def.orig
Warning: using insecure memory!
OK GNU Privacy Guard's S/M server ready
INPUT FD=4
OK
OUTPUT FD=5
OK
DECRYPT
gpgsm: DBG: recp 0 - issuer: `CN=MrJoe,OU=Hacking,O=g10Dope,L=Bochum,ST=Some-State,C=DE'
gpgsm: DBG: recp 0 - serial: 01
gpgsm: can't connect server: `ERR 7 can't exec /usr/bin/gpg-agentx': Datei oder Verzeichnis nicht gefunden'
gpgsm: can't connect to the agent: connect failed
gpgsm: error decrypting session key: no agent
gpgsm: DBG: decrypting session key failed: no agent
S DECRYPTION_FAILED
ERR 208 no secret key

Note that only the uppercase messages are available to GPGME for
diagnostics.

It's best to give me the output of gpgsm --server as above (there are
logging features, too), when reporting problems with error values, because
sometimes it might be necessary to change gpgsm as well to produce best
results.  As you can see from the above example, gpgme can not always give
correct diagnostics given the current gpgsm behaviour.

To fix the bogus No_Passphrase you saw, we need to find out what sequence of
events triggered that.  I can not conclude that from just looking at GPGME,
I need the gpgsm server log for that (or a way to reproduce it).

> So what we need is:
> 1.) Missing_Key in addition to Decryption_Failed. Else we can't tell our 
> users why decryption failed.

Sure.  In fact, there is need for a whole lot of error values to
reflect potential errors in certificates.  These are currently all mapped to
Invalid_Key and most of them should probably get their own error value:

    case ASSUAN_Bad_Certificate:
    case ASSUAN_Bad_Certificate_Chain:
    case ASSUAN_Missing_Certificate:
    case ASSUAN_No_Public_Key:
    case ASSUAN_No_Secret_Key:
    case ASSUAN_Invalid_Name:
    case ASSUAN_Card_Error:
    case ASSUAN_Invalid_Card:
    case ASSUAN_No_PKCS15_App:
    case ASSUAN_Card_Not_Present:
    case ASSUAN_Invalid_Id:
    case ASSUAN_Bad_Signature:
    case ASSUAN_Cert_Revoked:
    case ASSUAN_No_CRL_For_Cert:
    case ASSUAN_CRL_Too_Old:
    case ASSUAN_Not_Trusted:

> 2.) Some error code which indicates that asking for the passphrase 
> failed/wasn't possible. Else the user will wonder why we tell him that 
> decryption failed because of no/wrong passphrase although he wasn't 
> asked to enter the passphrase.

Until I have more information, I am happy with giving Invalid_Engine with
all serious installation problems.  In case where more information is
useful, we first need it to be reported in the gpgsm server protocol (see
above).  Then we can think about mapping that in the GPGME interface.

> The question whether there should be a No_Passphrase _and_ a 
> Bad_Passphrase error code is difficult to answer. If the user didn't 
> enter a passphrase then this probably indicates that he didn't want to 
> enter a passphrase. This means that No_Passphrase could be treated as 
> Canceled. So yes, I think it makes sense to have No_Passphrase _and_ 
> Bad_Passphrase.

For me it is much simpler.  If somebody wants to make the distinction, we
can have both error codes.  I have a high barrier for adding features nobody
is going to use.

> Before you ask the obvious question wrt what I wrote above: No, I don't 
> think that in case the user didn't enter a passphrase gpgme should 
> return Canceled. IMO you should leave the interpretation of the error 
> codes to the application programmers since in some cases it might make 
> sense to treat No_Passphrase the same way as Bad_Passphrase while in 
> other cases it might make sense to treat it as Canceled.

gpg-agent (through pinentry) has a cancel button, and users of the passphrase
callback can achieve the same effect.  There is no need for the user to enter
an empty passphrase just to get the effect of a cancel.  I suspect that the no
passphrase case is legacy from a time before we had the better interfaces. 
So far I am tending to treating no passphrase as bad passphrase, now that
better interfaces are available and I have no indication that somebody
has a use for the distinction except in case of lack of a cancel button.
 
> It's always better to have more error codes than actually necessary than 
> to have too few.

And it's best to have exactly the right number of error codes ;)

Thanks,
Marcus

-- 
`Rhubarb is no Egyptian god.' GNU      http://www.gnu.org    marcus@gnu.org
Marcus Brinkmann              The Hurd http://www.gnu.org/software/hurd/
Marcus.Brinkmann@ruhr-uni-bochum.de
http://www.marcus-brinkmann.de/