⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setkey.c

📁 早期freebsd实现
💻 C
字号:
#ifndef lintstatic char sccsid[] = 	"@(#)setkey.c	2.2 88/08/10 4.0 RPCSRC; from Copyr 1988 Sun Micro";#endif/* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part.  Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. *  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. *  * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. *  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. *  * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. *  * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California  94043 *//* * Copyright (C) 1986, Sun Microsystems, Inc.  *//* * Do the real work of the keyserver . * Store secret keys. Compute common keys, * and use them to decrypt and encrypt DES keys . * Cache the common keys, so the * expensive computation is avoided.  */#include <stdio.h>#include <sys/file.h>#include <mp.h>#include <rpc/rpc.h>#include <rpc/key_prot.h>#include <des_crypt.h>#include <sys/errno.h>extern char *malloc();extern char ROOTKEY[];static MINT *MODULUS;static char *fetchsecretkey();static keystatus pk_crypt();/* * Set the modulus for all our Diffie-Hellman operations  */setmodulus(modx)	char *modx;{	MODULUS = xtom(modx);}/* * Set the secretkey key for this uid  */keystatuspk_setkey(uid, skey)	short uid;	keybuf skey;{	if (!storesecretkey(uid, skey)) {		return (KEY_SYSTEMERR);	}	return (KEY_SUCCESS);}/* * Encrypt the key using the public key associated with remote_name and the * secret key associated with uid.  */keystatuspk_encrypt(uid, remote_name, key)	short uid;	char *remote_name;	des_block *key;{	return (pk_crypt(uid, remote_name, key, DES_ENCRYPT));}/* * Decrypt the key using the public key associated with remote_name and the * secret key associated with uid.  */keystatuspk_decrypt(uid, remote_name, key)	short uid;	char *remote_name;	des_block *key;{	return (pk_crypt(uid, remote_name, key, DES_DECRYPT));}/* * Do the work of pk_encrypt && pk_decrypt  */static keystatuspk_crypt(uid, remote_name, key, mode)	short uid;	char *remote_name;	des_block *key;	int mode;{	char *xsecret;	char xpublic[HEXKEYBYTES + 1];	char xsecret_hold[HEXKEYBYTES + 1];	des_block deskey;	int err;	MINT *public;	MINT *secret;	MINT *common;	char zero[8];	xsecret = fetchsecretkey(uid);	if (xsecret == NULL) {		bzero(zero, sizeof(zero));		xsecret = xsecret_hold;		if (!getsecretkey("nobody", xsecret, zero) ||		    xsecret[0] == 0) {			return (KEY_NOSECRET);		}	}	if (!getpublickey(remote_name, xpublic) &&	    !getpublickey("nobody", xpublic)) {		return (KEY_UNKNOWN);	}	if (!readcache(xpublic, xsecret, &deskey)) {		public = xtom(xpublic);		secret = xtom(xsecret);		common = itom(0);		pow(public, secret, MODULUS, common);		extractdeskey(common, &deskey);		writecache(xpublic, xsecret, &deskey);		mfree(secret);		mfree(public);		mfree(common);	}	err = ecb_crypt(&deskey, key, sizeof(des_block), DES_HW | mode);	if (DES_FAILED(err)) {		return (KEY_SYSTEMERR);	}	return (KEY_SUCCESS);}/* * Choose middle 64 bits of the common key to use as our des key, possibly * overwriting the lower order bits by setting parity.  */staticextractdeskey(ck, deskey)	MINT *ck;	des_block *deskey;{	MINT *a;	short r;	int i;	short base = (1 << 8);	char *k;	a = itom(0);	move(ck, a);	for (i = 0; i < ((KEYSIZE - 64) / 2) / 8; i++) {		sdiv(a, base, a, &r);	}	k = deskey->c;	for (i = 0; i < 8; i++) {		sdiv(a, base, a, &r);		*k++ = r;	}	mfree(a);	des_setparity(deskey);}/* * Key storage management */struct secretkey_list {	short uid;	char secretkey[HEXKEYBYTES+1];	struct secretkey_list *next;};static struct secretkey_list *g_secretkeys;/* * Fetch the secret key for this uid  */static char *fetchsecretkey(uid)	short uid;{	struct secretkey_list *l;	for (l = g_secretkeys; l != NULL; l = l->next) {		if (l->uid == uid) {			return (l->secretkey);		}	}	return (NULL);}/* * Store the secretkey for this uid  */storesecretkey(uid, key)	short uid;	keybuf key;{	struct secretkey_list *new;	struct secretkey_list **l;	int nitems;	nitems = 0;	for (l = &g_secretkeys; *l != NULL && (*l)->uid != uid; 	     l = &(*l)->next) {		nitems++;	}	if (*l == NULL) {		new = (struct secretkey_list *)malloc(sizeof(*new));		if (new == NULL) {			return (0);		}		new->uid = uid;		new->next = NULL;		*l = new;	} else {		new = *l;	}	bcopy(key, new->secretkey, HEXKEYBYTES);	new->secretkey[HEXKEYBYTES] = 0;	seekitem(nitems);	writeitem(uid, new->secretkey);	return (1);}hexdigit(val)	int val;{	return ("0123456789abcdef"[val]);}bin2hex(bin, hex, size)	unsigned char *bin;	unsigned char *hex;	int size;{	int i;	for (i = 0; i < size; i++) {		*hex++ = hexdigit(*bin >> 4);		*hex++ = hexdigit(*bin++ & 0xf);	}}hexval(dig)	char dig;{	if ('0' <= dig && dig <= '9') {		return (dig - '0');	} else if ('a' <= dig && dig <= 'f') {		return (dig - 'a' + 10);	} else if ('A' <= dig && dig <= 'F') {		return (dig - 'A' + 10);	} else {		return (-1);	}}hex2bin(hex, bin, size)	unsigned char *hex;	unsigned char *bin;	int size;{	int i;	for (i = 0; i < size; i++) {		*bin = hexval(*hex++) << 4;		*bin++ |= hexval(*hex++);	}}static char KEYSTORE[] = "/etc/keystore";FILE *kf;openstore(){	kf = fopen(KEYSTORE, "r+");	if (kf == NULL) {		kf = fopen(KEYSTORE, "w+");		if (kf == NULL) {			return (0);		}	}	setbuf(kf, NULL);	return (1);}static char rootkey[KEYBYTES];static int haverootkey;struct storedkey {	short uid;	char crypt[KEYBYTES];};readkeys(){	struct secretkey_list *node;	struct secretkey_list **l;	int uid;	char secretkey[HEXKEYBYTES+1];	if (kf == NULL) {		return;	}	l = &g_secretkeys;	seekitem(0);	while (readitem(&uid, secretkey)) {		node = (struct secretkey_list *)malloc(sizeof(*node));		if (node == NULL) {			return;		}		node->uid = uid;		bcopy(secretkey, node->secretkey, HEXKEYBYTES + 1);		node->next = NULL;		*l = node;		l = &node->next;	}}writekeys(){	struct secretkey_list *k;	seekitem(0);	for (k = g_secretkeys; k != NULL; k = k->next) {		writeitem(k->uid, k->secretkey);	}}seekitem(item)	int item;{	if (kf != NULL) {		fseek(kf, item * sizeof(struct storedkey), 0);	}}writeitem(uid, key)	int uid;	char *key;{	struct storedkey item;	char rootkey_tmp[KEYBYTES];	int reencrypt;		if (kf == NULL) {		return (1);	}	if (uid == 0) {		writerootkey(key);		hex2bin(key, rootkey_tmp, KEYBYTES);		reencrypt = (haverootkey &&			     bcmp(rootkey, rootkey_tmp, KEYBYTES) != 0);		bcopy(rootkey_tmp, rootkey, KEYBYTES);		haverootkey = 1;		if (reencrypt) {			writekeys();			return (1);		}	}	if (!haverootkey) {		return (1);	}	item.uid = uid;	hex2bin(key, item.crypt, KEYBYTES);	ecb_crypt(rootkey, item.crypt, KEYBYTES, DES_ENCRYPT|DES_HW);	return (fwrite(&item, sizeof(item), 1, kf) >= 0);}readitem(uidp, key)	int *uidp;	char *key;{	struct storedkey item;	if (!haverootkey || kf == NULL) {		return (0);	}	if (fread(&item, sizeof(item), 1, kf) != 1) {		return (0);	}	*uidp = item.uid;	ecb_crypt(rootkey, item.crypt, KEYBYTES, DES_DECRYPT|DES_HW);	bin2hex(item.crypt, key, KEYBYTES);	key[HEXKEYBYTES] = 0;	return (1);}	/* * Root users store their key in /etc/$ROOTKEY so * that they can auto reboot without having to be * around to type a password. Storing this in a file * is rather dubious: it should really be in the EEPROM * so it does not go over the net for diskless machines. */writerootkey(secret)	char *secret;{	char newline = '\n';	int fd;	fd = open(ROOTKEY, O_WRONLY|O_TRUNC|O_CREAT, 0);	if (fd < 0) {		perror(ROOTKEY);	} else {		if (write(fd, secret, strlen(secret)) < 0 ||		    write(fd, &newline, sizeof(newline)) < 0) {			(void)fprintf(stderr, "%s: ", ROOTKEY);			perror("write");		}		close(fd);	}}/* * Exponential caching management */struct cachekey_list {	keybuf secret;	keybuf public;	des_block deskey;	struct cachekey_list *next;};static struct cachekey_list *g_cachedkeys;/* * cache result of expensive multiple precision exponential operation  */staticwritecache(pub, sec, deskey)	char *pub;	char *sec;	des_block *deskey;{	struct cachekey_list *new;	new = (struct cachekey_list *) malloc(sizeof(struct cachekey_list));	if (new == NULL) {		return;	}	bcopy(pub, new->public, sizeof(keybuf));	bcopy(sec, new->secret, sizeof(keybuf));	new->deskey = *deskey;	new->next = g_cachedkeys;	g_cachedkeys = new;}/* * Try to find the common key in the cache  */staticreadcache(pub, sec, deskey)	char *pub;	char *sec;	des_block *deskey;{	struct cachekey_list *found;	register struct cachekey_list **l;#define cachehit(pub, sec, list)	\		(bcmp(pub, (list)->public, sizeof(keybuf)) == 0 && \		bcmp(sec, (list)->secret, sizeof(keybuf)) == 0)	for (l = &g_cachedkeys;	     (*l) != NULL && !cachehit(pub, sec, *l);	     l = &(*l)->next);	if ((*l) == NULL) {		return (0);	}	found = *l;	(*l) = (*l)->next;	found->next = g_cachedkeys;	g_cachedkeys = found;	*deskey = found->deskey;	return (1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -