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