rxgk (wire) error codes (was Re: [AFS3-std] rxgk implementation notes)

Benjamin Kaduk kaduk@MIT.EDU
Wed, 20 Mar 2013 17:36:59 -0400 (EDT)


On Thu, 28 Feb 2013, Benjamin Kaduk wrote:

> On Thu, 28 Feb 2013, Jeffrey Hutzelman wrote:
>
>> On Thu, 2013-02-28 at 17:05 -0500, Benjamin Kaduk wrote:
>> 
>>> Relatedly, there's not an obvious error code to return when such encoding
>>> fails or we can't allocate memory for the new object.  I've been using,
>>> e.g., RXGEN_SS_MARSHAL for now, but I wonder if there are more RXGK error
>>> codes waiting to be added, here.  There's also some temptation to make
>>> things like BADLEVEL apply to the authentication step as well as just
>>> token negotiation; that would probably warrant changing the associated
>>> error string.
>> 
>> There should be some generic rx-level error codes that are appropriate.
>> The rxgen-level codes are appropriate, I think, for handling data sent
>> and received as RPC arguments, but challenge/response ought not to
>> generate those, and they're probably also not appropriate for cases
>> where the encrypted part of a token doesn't decrypt successfully.  So
>> yet, there may be room for another error or two here.
>
> We have SEALED_INCON and BADCHALLENGE and BAD_TOKEN.  I guess I can make a 
> list of some of the places that seem hard.  It's tempting to use ENOMEM in 
> quite a few places, but that's not exactly a wire error code...

Doing a survey of my existing codebase:

Client-side (not on the wire), we call into the XDR routines for unpacking 
structures given to us as RXGK_Data (both encrypted and unencrypted); 
using RXGEN_CC_UNMARSHAL is probably okay, though I should be using ENOMEM 
in a couple of places (I forgot that these were not going to go on the 
wire).

In the client-side security object routines, though, we do need to deal 
with XDR failures that will go on the wire (e.g., for the authenticator 
appdata field, which is an encoded afsUUID).  Probably RXGEN_CC_MARSHAL is 
okay, here ... whether it's also the right thing for an ENOMEM condition 
is less clear.

The return value of rxi_GetCallNumberVector currently goes on the wire 
as-is; I haven't checked whether that's appropriate.

Likewise (client-side), if we fail to decode the challenge, 
RXGEN_CC_UNMARSHAL seems the right return value.

The crypto module which is currently wrapping libkrb5 must translate krb5 
errors to RX errors.  Currently is:
     switch (err) {
         case 0:
             return 0;
         case KRB5_RCACHE_BADVNO:
         case KRB5_CCACHE_BADVNO:
         case KRB5_KEYTAB_BADVNO:
         case KRB5_BAD_ENCTYPE:
             return RXGK_BADKEYNO;
         case KRB5_CRYPTO_INTERNAL:
         case KRB5_BAD_MSIZE:
         case KRB5_BADMSGTYPE:
             return RXGK_SEALED_INCON;
         default:
             return RXGK_INCONSISTENCY;

The crypto routines have to allocate memory, too.  What return value to 
use when the allocation fails?  (Currently RXGK_INCONSISTENCY)

server-side is also doing XDR en/decoding, the RXGEN_SS_*MARSHAL codes 
seem okay.  We do get to use RXGK_BADCHALLENGE when decoding the challenge 
fails, though.  I guess I should make the authenticator checking bits use 
that code as well.

I will get GSS error codes from the key derivation routine.  I haven't 
traced through the full call path, but I think some of them are not 
translated properly.  On the other hand, there is a separate 
gss_major_status field, so perhaps we are safe.

We call into hcrypto for RAND_bytes() to make a nonce.  If this fails, I 
currently return RXGEN_SS_MARSHAL, but that seems dubious.

The code to gss_wrap the ClientInfo structure for returning to the client 
does some sketchy things with returning GSS_S_FAILURE and 
ENOMEM/RXGEN_SS_MARSHAL/GSS_S_BAD_QOP/etc. in the minor status, but I'm 
not sure that this constitutes a pressing need for more error codes.

My code does not support more than 1.5-hop GSS negotiations, and uses 
RX_INVALID_OPERATION to indicate this.





Looking back over the above, it seems that the only real questions are 
what to do with ENOMEM, and whether we're okay using the RXGEN*MARSHAL 
codes for the slew of non-challenge/response/authenticator types that we 
are en/decoding.

-Ben