summaryrefslogtreecommitdiffstats
path: root/lib/librpc/secure_rpc/keyserv/setkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/librpc/secure_rpc/keyserv/setkey.c')
-rw-r--r--lib/librpc/secure_rpc/keyserv/setkey.c514
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);
-}
OpenPOWER on IntegriCloud