/* hej emacs det h{r {r en -*- c -*- fil */

/*
 * Copyright (c) 2002 - 2004, Stockholms Universitet
 * (Stockholm University, Stockholm Sweden)
 * All rights reserved.
 * 
 * Redistribution is not permitted
 */

/* $Id: rxgk_proto.xg,v 1.1 2004/08/08 19:21:33 shadow Exp $ */

package RXGK_

const RXGK_MAX_TOKEN_LEN = 65536;
const RXGK_MAX_AUTHTOKEN = 256;

/* ctext is limited by mtu since its part of responce */
const RXGK_MAX_CTEXT	 = 768; 

const RXGK_SERVICE_ID   = 34567;

#define RXGK_ESTABLISH_KRB5_CONTEXT	1
#define RXGK_ESTABLISH_GSS_CONTEXT	2
#define RXGK_EXCHANGE_GSS_KEYS		3

typedef opaque RXGK_Token<RXGK_MAX_TOKEN_LEN>;

/*
 *
 */

const RXGK_KEY_VERSION		= 1;
const RXGK_KEY_MAXSIZE		= 256;
const RXGK_KEY_MAXPRINCIPAL	= 640;
const RXGK_KEY_ENCTYPES		= 32;

/*
 * Challange token in the 
 */

const RXGK_CR_TOKEN_VERSION	= 1;

struct RXGK_CHALLENGE_TOKEN {
    afs_int32	ct_version;
    afs_uint32	ct_nonce;
    afs_uint32	ct_enctype<RXGK_KEY_ENCTYPES>;	/* listed in order of pref */
};

/*
 * Reply token in the EstablishKrb5Context
 */

struct RXGK_REPLY_TOKEN {
    afs_int32	rt_version;
    afs_int32	rt_flags;	/* other support ops */
    afs_int32	rt_error;
    afs_uint32	rt_nonce;
    afs_uint32	rt_enctype;
    opaque	rt_key<RXGK_KEY_MAXSIZE>;
};

/*
 * Rx auth cred equivalent
 */

struct RXGK_AUTH_CRED {
    afs_int32	ac_version;	/* version of format of RXGK_AUTH_CRED */
    string	ac_principal<RXGK_KEY_MAXPRINCIPAL>; /* prefixed with mech */
    afs_int32	ac_starttime;
    afs_int32	ac_endtime;
    afs_int32	ac_enctype;
    opaque	ac_key<RXGK_KEY_MAXSIZE>;
};

/*
 * This is part of the rxs challange/response exchange.  Its somewhat
 * complicated since it support rekeying of a data stream.
 */

const RXGK_VERSION = 3;

const RXKG_OPCODE_CHALLENGE	= 1;
const RXKG_OPCODE_REKEY		= 2;

struct RXGK_Challenge {
    afs_uint32	rc_version;
    afs_uint32	rc_nonce;
    afs_uint32	rc_opcode;
    afs_uint32	rc_max_seq_skew;	/* packets accepted when rekey */
    afs_uint32	rc_min_level;
};

/* is the auth_token EstablishKrb5Context returned */
struct RXGK_Response {
    afs_uint32	rr_version;
    afs_uint32	rr_auth_token_kvno;
    opaque	rr_auth_token<RXGK_MAX_AUTHTOKEN>;
    opaque	rr_ctext<RXGK_MAX_CTEXT>;
};

struct RXGK_Response_Crypt {
    afs_uint32	nonce;
    afs_uint32  epoch;
    afs_uint32  cid;
    afs_uint32	call_numbers[4];
    afs_uint32	level;
    afs_uint32	key_version;
    afs_uint32	key_counter_hi;
    afs_uint32	key_counter_lo;
};

/*
 * Kerberos crypto framework enctypes 
 */

const RXGK_CRYPTO_NULL			= 0;
const RXGK_CRYPTO_DES_CBC_CRC		= 1;
const RXGK_CRYPTO_DES_CBC_MD4		= 2;
const RXGK_CRYPTO_DES_CBC_MD5		= 4;
const RXGK_CRYPTO_DES3_SHA1_KD		= 16;

const RXGK_CRYPTO_CKSUM_RSA_DES_MD5	= 8;

const RXGK_CLIENT_TO_SERVER		= 0;
const RXGK_SERVER_TO_CLIENT		= 1;

const RXGK_CLIENT_ENC_CHALLENGE		= 1026;
const RXGK_SERVER_ENC_REKEY		= 1026;
const RXGK_CLIENT_ENC_PACKETS		= 1027;
const RXGK_CLIENT_CKSUM_PACKETS		= 1028;
const RXGK_SERVER_ENC_PACKETS		= 1029;
const RXGK_SERVER_CKSUM_PACKETS		= 1030;

/*
 * In packet protection since header isn't checksum-ed
 */

struct rxgk_header_data {
    uint32_t call_number;
    uint32_t channel_and_seq;
};

/*
 * rx connection key
 */

struct RXGK_rxconn_key {
    afs_uint32 rxk_cid;
    afs_uint32 rxk_epoch;
};

#if 0

const RXGK_MAX_KEYCONTRIB= 256; /* MUST only be used from server->client */

struct RXGK_ReKey {
    opaque	rk_ctext<RXGK_MAX_CTEXT>;
};

struct RXGK_ReKey_Crypt {
    afs_int32	rkc_version;
    afs_int32	rkc_max_seq_num;
    afs_int32	rkc_kvno;		/* 16 bit number */
    opaque	rkc_keycontribution<RXGK_MAX_KEYCONTRIB>;
};

/* rx transport key */

struct RXGK_rxtransport_key {
    opaque	client_keycontribution<RXGK_MAX_KEYCONTRIB>;
    opaque	server_keycontribution<RXGK_MAX_KEYCONTRIB>;
};

#endif

/*
 * kerberos auth_token
 */

EstablishKrb5Context(IN RXGK_Token *token, 
		     IN RXGK_Token *challenge_token,
		     OUT RXGK_Token *reply_token,
		     OUT int32_t *auth_token_kvno,
		     OUT RXGK_Token *auth_token) = RXGK_ESTABLISH_KRB5_CONTEXT;

/*
 * Add gss stuff here
 */

#if 0

EstablishGssContext(IN RXGK_Token *in_token,
		    OUT RXGK_Token *out_token) = RXGK_ESTABLISH_GSS_CONTEXT;

ExchangeGSSKeys(IN RXGK_Token *challenge_token,
		OUT RXGK_Token *reply_token,
		OUT int32_t *auth_token_kvno,
		OUT RXGK_Token *auth_token) = RXGK_EXCHANGE_GSS_KEYS;

#endif

