diff options
Diffstat (limited to 'lib/librpc/secure_rpc/keyserv/setkey.c')
-rw-r--r-- | lib/librpc/secure_rpc/keyserv/setkey.c | 514 |
1 files changed, 0 insertions, 514 deletions
diff --git a/lib/librpc/secure_rpc/keyserv/setkey.c b/lib/librpc/secure_rpc/keyserv/setkey.c deleted file mode 100644 index d62dc9c..0000000 --- a/lib/librpc/secure_rpc/keyserv/setkey.c +++ /dev/null @@ -1,514 +0,0 @@ -#ifndef lint -static 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 - */ -keystatus -pk_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. - */ -keystatus -pk_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. - */ -keystatus -pk_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 keystatus -pk_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. - */ -static -extractdeskey(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 - */ -static -writecache(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 - */ -static -readcache(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); -} |