/*
 * Key server protocol definition
 * Copyright (c) 2010, Oracle America, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials
 *       provided with the distribution.
 *     * Neither the name of the "Oracle America, Inc." nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The keyserver is a public key storage/encryption/decryption service
 * The encryption method used is based on the Diffie-Hellman exponential
 * key exchange technology.
 *
 * The key server is local to each machine, akin to the portmapper.
 * Under TI-RPC, communication with the keyserver is through the
 * loopback transport.
 *
 * NOTE: This .x file generates the USER level headers for the keyserver.
 * the KERNEL level headers are created by hand as they kernel has special
 * requirements.
 */

%#if 0
%#pragma ident	"@(#)key_prot.x	1.7	94/04/29 SMI"
%#endif
%
%/* Copyright (c)  1990, 1991 Sun Microsystems, Inc. */
%
%/*
% * Compiled from key_prot.x using rpcgen.
% * DO NOT EDIT THIS FILE!
% * This is NOT source code!
% */

/*
 * PROOT and MODULUS define the way the Diffie-Hellman key is generated.
 *
 * MODULUS should be chosen as a prime of the form: MODULUS == 2*p + 1,
 * where p is also prime.
 *
 * PROOT satisfies the following two conditions:
 * (1) (PROOT ** 2) % MODULUS != 1
 * (2) (PROOT ** p) % MODULUS != 1
 *
 */

const PROOT = 3;
const HEXMODULUS = "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b";

const HEXKEYBYTES = 48;		/* HEXKEYBYTES == strlen(HEXMODULUS) */
const KEYSIZE = 192;		/* KEYSIZE == bit length of key */
const KEYBYTES = 24;		/* byte length of key */

/*
 * The first 16 hex digits of the encrypted secret key are used as
 * a checksum in the database.
 */
const KEYCHECKSUMSIZE = 16;

/*
 * status of operation
 */
enum keystatus {
	KEY_SUCCESS,	/* no problems */
	KEY_NOSECRET,	/* no secret key stored */
	KEY_UNKNOWN,	/* unknown netname */
	KEY_SYSTEMERR 	/* system error (out of memory, encryption failure) */
};

typedef opaque keybuf[HEXKEYBYTES];	/* store key in hex */

typedef string netnamestr<MAXNETNAMELEN>;

/*
 * Argument to ENCRYPT or DECRYPT
 */
struct cryptkeyarg {
	netnamestr remotename;
	des_block deskey;
};

/*
 * Argument to ENCRYPT_PK or DECRYPT_PK
 */
struct cryptkeyarg2 {
	netnamestr remotename;
	netobj	remotekey;	/* Contains a length up to 1024 bytes */
	des_block deskey;
};


/*
 * Result of ENCRYPT, DECRYPT, ENCRYPT_PK, and DECRYPT_PK
 */
union cryptkeyres switch (keystatus status) {
case KEY_SUCCESS:
	des_block deskey;
default:
	void;
};

const MAXGIDS  = 16;	/* max number of gids in gid list */

/*
 * Unix credential
 */
struct unixcred {
	u_int uid;
	u_int gid;
	u_int gids<MAXGIDS>;
};

/*
 * Result returned from GETCRED
 */
union getcredres switch (keystatus status) {
case KEY_SUCCESS:
	unixcred cred;
default:
	void;
};
/*
 * key_netstarg;
 */

struct key_netstarg {
	keybuf st_priv_key;
	keybuf st_pub_key;
	netnamestr st_netname;
};

union key_netstres switch (keystatus status){
case KEY_SUCCESS:
	key_netstarg knet;
default:
	void;
};

#ifdef RPC_HDR
%
%#ifndef opaque
%#define opaque char
%#endif
%
#endif
program KEY_PROG {
	version KEY_VERS {

		/*
		 * This is my secret key.
	 	 * Store it for me.
		 */
		keystatus
		KEY_SET(keybuf) = 1;

		/*
		 * I want to talk to X.
		 * Encrypt a conversation key for me.
	 	 */
		cryptkeyres
		KEY_ENCRYPT(cryptkeyarg) = 2;

		/*
		 * X just sent me a message.
		 * Decrypt the conversation key for me.
		 */
		cryptkeyres
		KEY_DECRYPT(cryptkeyarg) = 3;

		/*
		 * Generate a secure conversation key for me
		 */
		des_block
		KEY_GEN(void) = 4;

		/*
		 * Get me the uid, gid and group-access-list associated
		 * with this netname (for kernel which cannot use NIS)
		 */
		getcredres
		KEY_GETCRED(netnamestr) = 5;
	} = 1;
	version KEY_VERS2 {

		/*
		 * #######
		 * Procedures 1-5 are identical to version 1
		 * #######
		 */

		/*
		 * This is my secret key.
	 	 * Store it for me.
		 */
		keystatus
		KEY_SET(keybuf) = 1;

		/*
		 * I want to talk to X.
		 * Encrypt a conversation key for me.
	 	 */
		cryptkeyres
		KEY_ENCRYPT(cryptkeyarg) = 2;

		/*
		 * X just sent me a message.
		 * Decrypt the conversation key for me.
		 */
		cryptkeyres
		KEY_DECRYPT(cryptkeyarg) = 3;

		/*
		 * Generate a secure conversation key for me
		 */
		des_block
		KEY_GEN(void) = 4;

		/*
		 * Get me the uid, gid and group-access-list associated
		 * with this netname (for kernel which cannot use NIS)
		 */
		getcredres
		KEY_GETCRED(netnamestr) = 5;

		/*
		 * I want to talk to X. and I know X's public key
		 * Encrypt a conversation key for me.
	 	 */
		cryptkeyres
		KEY_ENCRYPT_PK(cryptkeyarg2) = 6;

		/*
		 * X just sent me a message. and I know X's public key
		 * Decrypt the conversation key for me.
		 */
		cryptkeyres
		KEY_DECRYPT_PK(cryptkeyarg2) = 7;

		/*
		 * Store my public key, netname and private key.
		 */
		keystatus
		KEY_NET_PUT(key_netstarg) = 8;

		/*
		 * Retrieve my public key, netname and private key.
		 */
 		key_netstres
		KEY_NET_GET(void) = 9;

		/*
		 * Return me the conversation key that is constructed
		 * from my secret key and this publickey.
		 */

		cryptkeyres
		KEY_GET_CONV(keybuf) = 10;


	} = 2;
} = 100029;
