17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 23*49e7ca49Speteh * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* 287c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 297c478bd9Sstevel@tonic-gate * The Regents of the University of California 307c478bd9Sstevel@tonic-gate * All Rights Reserved 317c478bd9Sstevel@tonic-gate * 327c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 337c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 347c478bd9Sstevel@tonic-gate * contributors. 357c478bd9Sstevel@tonic-gate */ 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate /* 407c478bd9Sstevel@tonic-gate * Do the real work of the keyserver. 417c478bd9Sstevel@tonic-gate * Store secret keys. Compute common keys, 427c478bd9Sstevel@tonic-gate * and use them to decrypt and encrypt DES keys. 437c478bd9Sstevel@tonic-gate * Cache the common keys, so the expensive computation is avoided. 447c478bd9Sstevel@tonic-gate */ 457c478bd9Sstevel@tonic-gate #include <stdio.h> 467c478bd9Sstevel@tonic-gate #include <stdlib.h> 477c478bd9Sstevel@tonic-gate #include <mp.h> 487c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 497c478bd9Sstevel@tonic-gate #include <rpc/key_prot.h> 507c478bd9Sstevel@tonic-gate #include <rpc/des_crypt.h> 517c478bd9Sstevel@tonic-gate #include <rpcsvc/nis_dhext.h> 527c478bd9Sstevel@tonic-gate #include <sys/errno.h> 537c478bd9Sstevel@tonic-gate #include <string.h> 547c478bd9Sstevel@tonic-gate #include <thread.h> 557c478bd9Sstevel@tonic-gate #include <syslog.h> 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate #include "debug.h" 587c478bd9Sstevel@tonic-gate #include "keyserv_cache.h" 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate extern char ROOTKEY[]; 617c478bd9Sstevel@tonic-gate extern mechanism_t **mechs; 627c478bd9Sstevel@tonic-gate extern char **cache_options; 637c478bd9Sstevel@tonic-gate extern int *cache_size; 647c478bd9Sstevel@tonic-gate extern int disk_caching; 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate static MINT *MODULUS; 677c478bd9Sstevel@tonic-gate static int hash_keys(); 687c478bd9Sstevel@tonic-gate static keystatus pk_crypt(); 697c478bd9Sstevel@tonic-gate static keystatus pk_crypt3(); 707c478bd9Sstevel@tonic-gate static int nodefaultkeys = 0; 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate #define DES "des" 737c478bd9Sstevel@tonic-gate #define DESALIAS "dh192-0" 747c478bd9Sstevel@tonic-gate #define DHMECHSTR "diffie_hellman" 757c478bd9Sstevel@tonic-gate #define CLASSIC_PK_DH(k, a) (((k) == 192) && ((a) == 0)) 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate /* 787c478bd9Sstevel@tonic-gate * Exponential caching management 797c478bd9Sstevel@tonic-gate */ 807c478bd9Sstevel@tonic-gate struct cachekey_list { 817c478bd9Sstevel@tonic-gate keybuf secret; 827c478bd9Sstevel@tonic-gate keybuf public; 837c478bd9Sstevel@tonic-gate des_block deskey; 847c478bd9Sstevel@tonic-gate struct cachekey_list *next; 857c478bd9Sstevel@tonic-gate }; 867c478bd9Sstevel@tonic-gate #define KEY_HASH_SIZE 256 877c478bd9Sstevel@tonic-gate static struct cachekey_list *g_cachedkeys[KEY_HASH_SIZE]; 887c478bd9Sstevel@tonic-gate static rwlock_t g_cachedkeys_lock = DEFAULTRWLOCK; 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate #ifdef DEBUG 917c478bd9Sstevel@tonic-gate int 927c478bd9Sstevel@tonic-gate test_debug(debug_level level, char *file, int line) 937c478bd9Sstevel@tonic-gate { 947c478bd9Sstevel@tonic-gate if (level < debugging) 957c478bd9Sstevel@tonic-gate return (0); 967c478bd9Sstevel@tonic-gate fprintf(stderr, "file %s,\tline %d :\t", file, line); 977c478bd9Sstevel@tonic-gate return (1); 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate int 1017c478bd9Sstevel@tonic-gate real_debug(char *fmt, ...) 1027c478bd9Sstevel@tonic-gate { 1037c478bd9Sstevel@tonic-gate va_list args; 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate va_start(args, fmt); 1067c478bd9Sstevel@tonic-gate (void) vfprintf(stderr, fmt, args); 1077c478bd9Sstevel@tonic-gate va_end(args); 1087c478bd9Sstevel@tonic-gate fprintf(stderr, "\n"); 1097c478bd9Sstevel@tonic-gate fflush(stderr); 1107c478bd9Sstevel@tonic-gate return (1); 1117c478bd9Sstevel@tonic-gate } 1127c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate struct cacheuid_list { 1157c478bd9Sstevel@tonic-gate uid_t uid; 1167c478bd9Sstevel@tonic-gate int refcnt; 1177c478bd9Sstevel@tonic-gate keybuf3 *secretkey; 1187c478bd9Sstevel@tonic-gate keybuf3 *publickey; 1197c478bd9Sstevel@tonic-gate netnamestr netname; 1207c478bd9Sstevel@tonic-gate des_block key; 1217c478bd9Sstevel@tonic-gate struct cacheuid_list *next; 1227c478bd9Sstevel@tonic-gate }; 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate #define NUMHASHBUCKETS 256 1257c478bd9Sstevel@tonic-gate #define HASH_UID(x) (x & 0xff) 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate struct mechdata { 1287c478bd9Sstevel@tonic-gate struct cacheuid_list *bucket[NUMHASHBUCKETS]; 1297c478bd9Sstevel@tonic-gate }; 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate struct psdata { 1327c478bd9Sstevel@tonic-gate struct cachekey3_list *common[NUMHASHBUCKETS]; 1337c478bd9Sstevel@tonic-gate }; 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate struct mechentry { 1367c478bd9Sstevel@tonic-gate mutex_t mech_lock; 1377c478bd9Sstevel@tonic-gate struct mechdata *mechdata; 1387c478bd9Sstevel@tonic-gate mutex_t ps_lock; 1397c478bd9Sstevel@tonic-gate struct psdata *psdata; 1407c478bd9Sstevel@tonic-gate }; 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate /* 1437c478bd9Sstevel@tonic-gate * we don't need to worry about locking for the keylen + algtype 1447c478bd9Sstevel@tonic-gate * sparse array because it is created once and for all during 1457c478bd9Sstevel@tonic-gate * initialization when there are no threads. The mechentry field 1467c478bd9Sstevel@tonic-gate * and everything underneath it needs protection and this is what 1477c478bd9Sstevel@tonic-gate * the *_lock fields are for. 1487c478bd9Sstevel@tonic-gate */ 1497c478bd9Sstevel@tonic-gate struct algtypelist { 1507c478bd9Sstevel@tonic-gate algtype_t algtype; 1517c478bd9Sstevel@tonic-gate struct algtypelist *next; 1527c478bd9Sstevel@tonic-gate struct mechentry mech; 1537c478bd9Sstevel@tonic-gate }; 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate struct keylenlist { 1567c478bd9Sstevel@tonic-gate keylen_t keylen; 1577c478bd9Sstevel@tonic-gate struct algtypelist *ap; 1587c478bd9Sstevel@tonic-gate struct keylenlist *next; 1597c478bd9Sstevel@tonic-gate }; 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate #define KEYSERV_VERSION "1.0" 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate static struct mechtable { 1647c478bd9Sstevel@tonic-gate char *version; 1657c478bd9Sstevel@tonic-gate struct keylenlist *kp; 1667c478bd9Sstevel@tonic-gate } mechtable = {KEYSERV_VERSION, NULL}; 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate static struct keylenlist ** 1697c478bd9Sstevel@tonic-gate getkeylen(keylen_t k) 1707c478bd9Sstevel@tonic-gate { 1717c478bd9Sstevel@tonic-gate struct keylenlist **kpp; 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG1, ("getkeylen key: %d", k)); 1747c478bd9Sstevel@tonic-gate for (kpp = &mechtable.kp; 1757c478bd9Sstevel@tonic-gate *kpp != NULL && (*kpp)->keylen != k; 1767c478bd9Sstevel@tonic-gate kpp = &(*kpp)->next) 1777c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("getkeylen failed %x", kpp)); 1787c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("getkeylen return: %x", kpp)); 1797c478bd9Sstevel@tonic-gate return (kpp); 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate static void 1837c478bd9Sstevel@tonic-gate appendkeylist(struct keylenlist **kpp, keylen_t k) 1847c478bd9Sstevel@tonic-gate { 1857c478bd9Sstevel@tonic-gate struct keylenlist *kp; 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate if (*kpp == NULL) { 1887c478bd9Sstevel@tonic-gate kp = (struct keylenlist *)malloc(sizeof (*kp)); 1897c478bd9Sstevel@tonic-gate if (kp == NULL) { 1907c478bd9Sstevel@tonic-gate debug(KEYSERV_INFO, ("appendkeylist : malloc failed")); 1917c478bd9Sstevel@tonic-gate return; 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("appendkeylist : %x %x %d", kpp, kp, k)); 1947c478bd9Sstevel@tonic-gate kp->keylen = k; 1957c478bd9Sstevel@tonic-gate kp->ap = NULL; 1967c478bd9Sstevel@tonic-gate kp->next = NULL; 1977c478bd9Sstevel@tonic-gate *kpp = kp; 1987c478bd9Sstevel@tonic-gate } else { 1997c478bd9Sstevel@tonic-gate /*EMPTY*/ 2007c478bd9Sstevel@tonic-gate /* do nothing; only happens for multiple algtypes */ 2017c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, 2027c478bd9Sstevel@tonic-gate ("appendkeylist called for non tail element")); 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate static struct algtypelist ** 2077c478bd9Sstevel@tonic-gate getalgtype(struct keylenlist **kpp, algtype_t a) 2087c478bd9Sstevel@tonic-gate { 2097c478bd9Sstevel@tonic-gate struct algtypelist **app; 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG1, ("getalgtype key: %d", a)); 2127c478bd9Sstevel@tonic-gate for (app = &(*kpp)->ap; 2137c478bd9Sstevel@tonic-gate *app != NULL && (*app)->algtype != a; 2147c478bd9Sstevel@tonic-gate app = &(*app)->next) 2157c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("getalgtype key: %x", app)); 2167c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("getalgtype return: %x", app)); 2177c478bd9Sstevel@tonic-gate return (app); 2187c478bd9Sstevel@tonic-gate } 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate static void 2217c478bd9Sstevel@tonic-gate appendalgtype(struct algtypelist **app, algtype_t a) 2227c478bd9Sstevel@tonic-gate { 2237c478bd9Sstevel@tonic-gate struct algtypelist *ap; 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate if (*app == NULL) { 2267c478bd9Sstevel@tonic-gate ap = (struct algtypelist *)malloc(sizeof (*ap)); 2277c478bd9Sstevel@tonic-gate if (ap == NULL) { 2287c478bd9Sstevel@tonic-gate debug(KEYSERV_INFO, ("appendalgtype : malloc failed")); 2297c478bd9Sstevel@tonic-gate return; 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("appendalgtype : %x %x %d", app, ap, a)); 2327c478bd9Sstevel@tonic-gate ap->algtype = a; 2337c478bd9Sstevel@tonic-gate mutex_init(&ap->mech.mech_lock, USYNC_THREAD, NULL); 2347c478bd9Sstevel@tonic-gate mutex_init(&ap->mech.ps_lock, USYNC_THREAD, NULL); 2357c478bd9Sstevel@tonic-gate ap->mech.mechdata = NULL; 2367c478bd9Sstevel@tonic-gate ap->mech.psdata = NULL; 2377c478bd9Sstevel@tonic-gate ap->next = NULL; 2387c478bd9Sstevel@tonic-gate *app = ap; 2397c478bd9Sstevel@tonic-gate } else { 2407c478bd9Sstevel@tonic-gate /*EMPTY*/ 2417c478bd9Sstevel@tonic-gate /* don't mind duplicate (keylen,algtype) paris for now. */ 2427c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, 2437c478bd9Sstevel@tonic-gate ("appendalgtype called for non tail element")); 2447c478bd9Sstevel@tonic-gate } 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate static struct mechentry * 2487c478bd9Sstevel@tonic-gate getmechtype(keylen_t k, algtype_t a) 2497c478bd9Sstevel@tonic-gate { 2507c478bd9Sstevel@tonic-gate struct keylenlist **kpp; 2517c478bd9Sstevel@tonic-gate struct algtypelist **app; 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG1, ("getmechtype %d %d", k, a)); 2547c478bd9Sstevel@tonic-gate kpp = getkeylen(k); 2557c478bd9Sstevel@tonic-gate if (*kpp == NULL) { 2567c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("getmechtype %d not found in keys", k)); 2577c478bd9Sstevel@tonic-gate return (0); 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate app = getalgtype(kpp, a); 2607c478bd9Sstevel@tonic-gate if (*app == NULL) { 2617c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("getmechtype %d not found in algs", a)); 2627c478bd9Sstevel@tonic-gate return (0); 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("getmechtype found %x", app)); 2657c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("getmechtype return %x", &(*app)->mech)); 2667c478bd9Sstevel@tonic-gate return (&(*app)->mech); 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate static keybuf3 * 2707c478bd9Sstevel@tonic-gate getkeybuf3(int k) 2717c478bd9Sstevel@tonic-gate { 2727c478bd9Sstevel@tonic-gate keybuf3 *buf; 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("getkeybuf3 malloc %d", k)); 2757c478bd9Sstevel@tonic-gate buf = (keybuf3 *) malloc(sizeof (*buf)); 2767c478bd9Sstevel@tonic-gate if (buf == NULL) { 2777c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("getkeybuf3 malloc failed")); 2787c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "file %s line %d: malloc failed", 2797c478bd9Sstevel@tonic-gate __FILE__, __LINE__); 2807c478bd9Sstevel@tonic-gate return (NULL); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate buf->keybuf3_len = k; 2837c478bd9Sstevel@tonic-gate /* XXX special case k==0 */ 2847c478bd9Sstevel@tonic-gate if (k == 0) { 2857c478bd9Sstevel@tonic-gate buf->keybuf3_val = NULL; 2867c478bd9Sstevel@tonic-gate } else { 2877c478bd9Sstevel@tonic-gate buf->keybuf3_val = (char *)malloc(k); 2887c478bd9Sstevel@tonic-gate if (buf->keybuf3_val == NULL) { 2897c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("getkeybuf3 malloc failed")); 2907c478bd9Sstevel@tonic-gate free(buf); 2917c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "file %s line %d: malloc failed", 2927c478bd9Sstevel@tonic-gate __FILE__, __LINE__); 2937c478bd9Sstevel@tonic-gate return (NULL); 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG1, ("getkeybuf3 ret %x", buf)); 2977c478bd9Sstevel@tonic-gate return (buf); 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate static void 3017c478bd9Sstevel@tonic-gate freekeybuf3(keybuf3 *kp) 3027c478bd9Sstevel@tonic-gate { 3037c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG1, ("freekeybuf3 %x", kp)); 3047c478bd9Sstevel@tonic-gate if (kp == NULL) 3057c478bd9Sstevel@tonic-gate return; 3067c478bd9Sstevel@tonic-gate if (kp->keybuf3_val) { 3077c478bd9Sstevel@tonic-gate /* XXX kp->keybuf3_len != 0? */ 3087c478bd9Sstevel@tonic-gate free(kp->keybuf3_val); 3097c478bd9Sstevel@tonic-gate } 3107c478bd9Sstevel@tonic-gate free(kp); 3117c478bd9Sstevel@tonic-gate } 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate static keybuf3 * 3147c478bd9Sstevel@tonic-gate cpykeybuf3(keybuf3 *src) 3157c478bd9Sstevel@tonic-gate { 3167c478bd9Sstevel@tonic-gate keybuf3 *dst; 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate if (src == NULL) { 3197c478bd9Sstevel@tonic-gate return (NULL); 3207c478bd9Sstevel@tonic-gate } 3217c478bd9Sstevel@tonic-gate if ((dst = getkeybuf3(src->keybuf3_len)) == NULL) { 3227c478bd9Sstevel@tonic-gate return (NULL); 3237c478bd9Sstevel@tonic-gate } 3247c478bd9Sstevel@tonic-gate memcpy(dst->keybuf3_val, src->keybuf3_val, src->keybuf3_len); 3257c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("cpykeybuf3 ret %x", dst)); 3267c478bd9Sstevel@tonic-gate return (dst); 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate static keybuf3 * 3307c478bd9Sstevel@tonic-gate setkeybuf3(char *src, int len) 3317c478bd9Sstevel@tonic-gate { 3327c478bd9Sstevel@tonic-gate keybuf3 *dst; 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate if ((dst = getkeybuf3(++len)) == NULL) { 3357c478bd9Sstevel@tonic-gate return (NULL); 3367c478bd9Sstevel@tonic-gate } 3377c478bd9Sstevel@tonic-gate memcpy(dst->keybuf3_val, src, len); 3387c478bd9Sstevel@tonic-gate return (dst); 3397c478bd9Sstevel@tonic-gate } 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate static int 3427c478bd9Sstevel@tonic-gate cmpkeybuf3(keybuf3 *k1, keybuf3 *k2) 3437c478bd9Sstevel@tonic-gate { 3447c478bd9Sstevel@tonic-gate if ((k1 == NULL) || (k2 == NULL)) { 3457c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "cmpkeybuf3: invalid parameter: %x, %x", 3467c478bd9Sstevel@tonic-gate k1, k2); 3477c478bd9Sstevel@tonic-gate return (0); 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate if (k1->keybuf3_len != k2->keybuf3_len) { 3507c478bd9Sstevel@tonic-gate return (0); 3517c478bd9Sstevel@tonic-gate } 3527c478bd9Sstevel@tonic-gate return (!memcmp(k1->keybuf3_val, k2->keybuf3_val, k1->keybuf3_len)); 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate static int 3567c478bd9Sstevel@tonic-gate storekeybuf3(keybuf3 *dst, keybuf3 *src) 3577c478bd9Sstevel@tonic-gate { 3587c478bd9Sstevel@tonic-gate keybuf3 *tmp; 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate if ((tmp = cpykeybuf3(src)) == NULL) { 3617c478bd9Sstevel@tonic-gate return (0); 3627c478bd9Sstevel@tonic-gate } 3637c478bd9Sstevel@tonic-gate *dst = *tmp; 3647c478bd9Sstevel@tonic-gate free(tmp); /* but not the contents */ 3657c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("storekeybuf3 ret %d %x", 3667c478bd9Sstevel@tonic-gate dst->keybuf3_len, dst->keybuf3_val)); 3677c478bd9Sstevel@tonic-gate return (1); 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate static deskeyarray * 3717c478bd9Sstevel@tonic-gate getdeskeyarray(int k) 3727c478bd9Sstevel@tonic-gate { 3737c478bd9Sstevel@tonic-gate deskeyarray *buf; 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("getdeskeyarray malloc %d", k)); 3767c478bd9Sstevel@tonic-gate buf = (deskeyarray *) malloc(sizeof (*buf)); 3777c478bd9Sstevel@tonic-gate if (buf == NULL) { 3787c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("getdeskeyarray malloc failed")); 3797c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "file %s line %d: malloc failed", 3807c478bd9Sstevel@tonic-gate __FILE__, __LINE__); 3817c478bd9Sstevel@tonic-gate return (NULL); 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate buf->deskeyarray_len = k; 3847c478bd9Sstevel@tonic-gate /* XXX special case k==0 */ 3857c478bd9Sstevel@tonic-gate if (k == 0) { 3867c478bd9Sstevel@tonic-gate buf->deskeyarray_val = NULL; 3877c478bd9Sstevel@tonic-gate } else { 3887c478bd9Sstevel@tonic-gate buf->deskeyarray_val = (des_block *) 3897c478bd9Sstevel@tonic-gate malloc(k * sizeof (des_block)); 3907c478bd9Sstevel@tonic-gate if (buf->deskeyarray_val == NULL) { 3917c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("getdeskeyarray malloc failed")); 3927c478bd9Sstevel@tonic-gate free(buf); 3937c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "file %s line %d: malloc failed", 3947c478bd9Sstevel@tonic-gate __FILE__, __LINE__); 3957c478bd9Sstevel@tonic-gate return (NULL); 3967c478bd9Sstevel@tonic-gate } 3977c478bd9Sstevel@tonic-gate } 3987c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG1, ("getdeskeyarray ret %x", buf)); 3997c478bd9Sstevel@tonic-gate return (buf); 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate static deskeyarray * 4037c478bd9Sstevel@tonic-gate cpydeskeyarray(deskeyarray *src) 4047c478bd9Sstevel@tonic-gate { 4057c478bd9Sstevel@tonic-gate deskeyarray *dst; 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate if (src == NULL) { 4087c478bd9Sstevel@tonic-gate return (NULL); 4097c478bd9Sstevel@tonic-gate } 4107c478bd9Sstevel@tonic-gate if ((dst = getdeskeyarray(src->deskeyarray_len)) == NULL) { 4117c478bd9Sstevel@tonic-gate return (NULL); 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate memcpy(dst->deskeyarray_val, src->deskeyarray_val, 4147c478bd9Sstevel@tonic-gate src->deskeyarray_len * sizeof (des_block)); 4157c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("cpydeskeyarray ret %x", dst)); 4167c478bd9Sstevel@tonic-gate return (dst); 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate static int 4207c478bd9Sstevel@tonic-gate storedeskeyarray(deskeyarray *dst, deskeyarray *src) 4217c478bd9Sstevel@tonic-gate { 4227c478bd9Sstevel@tonic-gate deskeyarray *tmp; 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate if ((tmp = cpydeskeyarray(src)) == NULL) { 4257c478bd9Sstevel@tonic-gate return (0); 4267c478bd9Sstevel@tonic-gate } 4277c478bd9Sstevel@tonic-gate *dst = *tmp; 4287c478bd9Sstevel@tonic-gate free(tmp); /* but not the contents */ 4297c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("storedeskeyarray ret %d %x", 4307c478bd9Sstevel@tonic-gate dst->deskeyarray_len, dst->deskeyarray_val)); 4317c478bd9Sstevel@tonic-gate return (1); 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate int 4357c478bd9Sstevel@tonic-gate setdeskeyarray(deskeyarray *dst, int k) 4367c478bd9Sstevel@tonic-gate { 4377c478bd9Sstevel@tonic-gate deskeyarray *tmp; 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate if ((tmp = getdeskeyarray(k)) == NULL) { 4407c478bd9Sstevel@tonic-gate return (0); 4417c478bd9Sstevel@tonic-gate } 4427c478bd9Sstevel@tonic-gate *dst = *tmp; 4437c478bd9Sstevel@tonic-gate free(tmp); /* but not the contents */ 4447c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("setdeskeyarray ret %d %x", 4457c478bd9Sstevel@tonic-gate dst->deskeyarray_len, dst->deskeyarray_val)); 4467c478bd9Sstevel@tonic-gate return (1); 4477c478bd9Sstevel@tonic-gate } 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate static int 4507c478bd9Sstevel@tonic-gate cachehit3(keybuf3 *public, keybuf3 *secret, struct cachekey3_list *cp) 4517c478bd9Sstevel@tonic-gate { 4527c478bd9Sstevel@tonic-gate return (cmpkeybuf3(public, cp->public) && 4537c478bd9Sstevel@tonic-gate cmpkeybuf3(secret, cp->secret)); 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate static struct cacheuid_list ** 4577c478bd9Sstevel@tonic-gate mapuid2cache(uid_t uid, struct mechdata *mdp) 4587c478bd9Sstevel@tonic-gate { 4597c478bd9Sstevel@tonic-gate struct cacheuid_list **cpp; 4607c478bd9Sstevel@tonic-gate int hash = HASH_UID(uid); 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("mapuid2cache %d %d %x", uid, hash, mdp)); 4637c478bd9Sstevel@tonic-gate for (cpp = &mdp->bucket[hash]; 4647c478bd9Sstevel@tonic-gate *cpp != NULL && (*cpp)->uid != uid; 4657c478bd9Sstevel@tonic-gate cpp = &(*cpp)->next) { 4667c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("mapuid2cache %x", cpp)); 4677c478bd9Sstevel@tonic-gate } 4687c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("mapuid2cache ret %x", cpp)); 4697c478bd9Sstevel@tonic-gate return (cpp); 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate static int 4737c478bd9Sstevel@tonic-gate appendsecretkey3(struct mechentry *mp, uid_t uid, setkeyarg3 *skey) 4747c478bd9Sstevel@tonic-gate { 4757c478bd9Sstevel@tonic-gate struct mechdata *mdp; 4767c478bd9Sstevel@tonic-gate struct cacheuid_list **cpp, *cp; 4777c478bd9Sstevel@tonic-gate keybuf3 nullkey = {0, NULL}; 4787c478bd9Sstevel@tonic-gate 4797c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("appendsecretkey3 %x", mp)); 4807c478bd9Sstevel@tonic-gate if ((skey == NULL) || (mp == NULL)) { 4817c478bd9Sstevel@tonic-gate return (0); 4827c478bd9Sstevel@tonic-gate } 4837c478bd9Sstevel@tonic-gate if (skey->key.keybuf3_len == 0) { 4847c478bd9Sstevel@tonic-gate return (0); 4857c478bd9Sstevel@tonic-gate } 4867c478bd9Sstevel@tonic-gate mutex_lock(&mp->mech_lock); 4877c478bd9Sstevel@tonic-gate if ((mdp = mp->mechdata) == NULL) { 4887c478bd9Sstevel@tonic-gate mdp = (struct mechdata *)calloc(1, sizeof (*mdp)); 4897c478bd9Sstevel@tonic-gate if (mdp == NULL) { 4907c478bd9Sstevel@tonic-gate mutex_unlock(&mp->mech_lock); 4917c478bd9Sstevel@tonic-gate debug(KEYSERV_INFO, 4927c478bd9Sstevel@tonic-gate ("appendsecretkey3 : calloc failed")); 4937c478bd9Sstevel@tonic-gate return (0); 4947c478bd9Sstevel@tonic-gate } 4957c478bd9Sstevel@tonic-gate mp->mechdata = mdp; 4967c478bd9Sstevel@tonic-gate } 4977c478bd9Sstevel@tonic-gate cpp = mapuid2cache(uid, mdp); 4987c478bd9Sstevel@tonic-gate if (*cpp == NULL) { 4997c478bd9Sstevel@tonic-gate cp = (struct cacheuid_list *)malloc(sizeof (*cp)); 5007c478bd9Sstevel@tonic-gate if (cp == NULL) { 5017c478bd9Sstevel@tonic-gate mutex_unlock(&mp->mech_lock); 5027c478bd9Sstevel@tonic-gate debug(KEYSERV_INFO, 5037c478bd9Sstevel@tonic-gate ("appendsecretkey3 : malloc failed")); 5047c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "file %s line %d: malloc failed", 5057c478bd9Sstevel@tonic-gate __FILE__, __LINE__); 5067c478bd9Sstevel@tonic-gate return (0); 5077c478bd9Sstevel@tonic-gate } 5087c478bd9Sstevel@tonic-gate memset(cp, 0, sizeof (*cp)); 5097c478bd9Sstevel@tonic-gate cp->uid = uid; 5107c478bd9Sstevel@tonic-gate *cpp = cp; 5117c478bd9Sstevel@tonic-gate } else { 5127c478bd9Sstevel@tonic-gate cp = *cpp; 5137c478bd9Sstevel@tonic-gate } 5147c478bd9Sstevel@tonic-gate freekeybuf3(cp->secretkey); 5157c478bd9Sstevel@tonic-gate if ((cp->secretkey = cpykeybuf3(&skey->key)) == NULL) { 5167c478bd9Sstevel@tonic-gate mutex_unlock(&mp->mech_lock); 5177c478bd9Sstevel@tonic-gate return (0); 5187c478bd9Sstevel@tonic-gate } 5197c478bd9Sstevel@tonic-gate freekeybuf3(cp->publickey); 5207c478bd9Sstevel@tonic-gate if ((cp->publickey = cpykeybuf3(&nullkey)) == NULL) { 5217c478bd9Sstevel@tonic-gate mutex_unlock(&mp->mech_lock); 5227c478bd9Sstevel@tonic-gate return (0); 5237c478bd9Sstevel@tonic-gate } 5247c478bd9Sstevel@tonic-gate mutex_unlock(&mp->mech_lock); 5257c478bd9Sstevel@tonic-gate return (1); 5267c478bd9Sstevel@tonic-gate } 5277c478bd9Sstevel@tonic-gate 5287c478bd9Sstevel@tonic-gate /* 5297c478bd9Sstevel@tonic-gate * Store the vers 3 secretkey for this uid 5307c478bd9Sstevel@tonic-gate */ 5317c478bd9Sstevel@tonic-gate static int 5327c478bd9Sstevel@tonic-gate storesecretkey3(uid_t uid, setkeyarg3 *skey) 5337c478bd9Sstevel@tonic-gate { 5347c478bd9Sstevel@tonic-gate struct mechentry *mp; 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate if (skey == NULL) { 5377c478bd9Sstevel@tonic-gate return (0); 5387c478bd9Sstevel@tonic-gate } 5397c478bd9Sstevel@tonic-gate if ((mp = getmechtype(skey->keylen, skey->algtype)) == NULL) { 5407c478bd9Sstevel@tonic-gate return (0); 5417c478bd9Sstevel@tonic-gate } 5427c478bd9Sstevel@tonic-gate return (appendsecretkey3(mp, uid, skey)); 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate /* 5467c478bd9Sstevel@tonic-gate * Set the vers 3 secretkey key for this uid 5477c478bd9Sstevel@tonic-gate */ 5487c478bd9Sstevel@tonic-gate keystatus 5497c478bd9Sstevel@tonic-gate pk_setkey3(uid_t uid, setkeyarg3 *skey) 5507c478bd9Sstevel@tonic-gate { 5517c478bd9Sstevel@tonic-gate if (!storesecretkey3(uid, skey)) { 5527c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 5537c478bd9Sstevel@tonic-gate } 5547c478bd9Sstevel@tonic-gate return (KEY_SUCCESS); 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate /* 5587c478bd9Sstevel@tonic-gate * Set the secretkey key for this uid 5597c478bd9Sstevel@tonic-gate */ 5607c478bd9Sstevel@tonic-gate keystatus 5617c478bd9Sstevel@tonic-gate pk_setkey(uid, skey) 5627c478bd9Sstevel@tonic-gate uid_t uid; 5637c478bd9Sstevel@tonic-gate keybuf skey; 5647c478bd9Sstevel@tonic-gate { 5657c478bd9Sstevel@tonic-gate int storesecretkey(uid_t, keybuf); 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate if (!storesecretkey(uid, skey)) { 5687c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 5697c478bd9Sstevel@tonic-gate } 5707c478bd9Sstevel@tonic-gate return (KEY_SUCCESS); 5717c478bd9Sstevel@tonic-gate } 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate int 5747c478bd9Sstevel@tonic-gate storeotherrootkeys(FILE *fp, char *netname, char *passwd, char *osecret) 5757c478bd9Sstevel@tonic-gate { 5767c478bd9Sstevel@tonic-gate des_block master; 5777c478bd9Sstevel@tonic-gate struct keylenlist *kp; 5787c478bd9Sstevel@tonic-gate struct algtypelist *ap; 5797c478bd9Sstevel@tonic-gate keybuf3 *secret; 5807c478bd9Sstevel@tonic-gate setkeyarg3 skey; 5817c478bd9Sstevel@tonic-gate 5827c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("storeotherrootkeys %s %s", 5837c478bd9Sstevel@tonic-gate netname, passwd)); 5847c478bd9Sstevel@tonic-gate passwd2des_g(passwd, netname, strlen(netname), &master, FALSE); 5857c478bd9Sstevel@tonic-gate for (kp = mechtable.kp; kp != NULL; kp = kp->next) { 5867c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, 5877c478bd9Sstevel@tonic-gate ("storeotherrootkeys key %d", kp->keylen)); 5887c478bd9Sstevel@tonic-gate for (ap = kp->ap; ap != NULL; ap = ap->next) { 5897c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, 5907c478bd9Sstevel@tonic-gate ("storeotherrootkeys alg: %d", ap->algtype)); 5917c478bd9Sstevel@tonic-gate if ((secret = getkeybuf3(kp->keylen/4+1)) == NULL) { 5927c478bd9Sstevel@tonic-gate return (0); 5937c478bd9Sstevel@tonic-gate } 5947c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, 5957c478bd9Sstevel@tonic-gate ("storeotherrootkeys calling getsecretkey_g")); 5967c478bd9Sstevel@tonic-gate if (!getsecretkey_g(netname, 5977c478bd9Sstevel@tonic-gate kp->keylen, ap->algtype, 5987c478bd9Sstevel@tonic-gate secret->keybuf3_val, secret->keybuf3_len, 5997c478bd9Sstevel@tonic-gate passwd)) { 6007c478bd9Sstevel@tonic-gate debug(KEYSERV_INFO, 6017c478bd9Sstevel@tonic-gate ("Can't find %s's secret key", netname)); 6027c478bd9Sstevel@tonic-gate return (0); 6037c478bd9Sstevel@tonic-gate } 6047c478bd9Sstevel@tonic-gate if (*secret->keybuf3_val == 0) { /* XXX */ 6057c478bd9Sstevel@tonic-gate debug(KEYSERV_INFO, 6067c478bd9Sstevel@tonic-gate ("Password does not decrypt secret key for %s", 6077c478bd9Sstevel@tonic-gate netname)); 6087c478bd9Sstevel@tonic-gate return (0); 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate skey.key = *secret; 6117c478bd9Sstevel@tonic-gate free(secret); /* but not the buffer it points to */ 6127c478bd9Sstevel@tonic-gate skey.userkey = master; 6137c478bd9Sstevel@tonic-gate skey.keylen = kp->keylen; 6147c478bd9Sstevel@tonic-gate skey.algtype = ap->algtype; 6157c478bd9Sstevel@tonic-gate if (CLASSIC_PK_DH(kp->keylen, ap->algtype)) { 6167c478bd9Sstevel@tonic-gate pk_setkey((uid_t)0, osecret); 6177c478bd9Sstevel@tonic-gate fprintf(fp, "%s\n", osecret); 6187c478bd9Sstevel@tonic-gate } 6197c478bd9Sstevel@tonic-gate if (pk_setkey3(0, &skey) != KEY_SUCCESS) { 6207c478bd9Sstevel@tonic-gate return (0); 6217c478bd9Sstevel@tonic-gate } 6227c478bd9Sstevel@tonic-gate if (!CLASSIC_PK_DH(kp->keylen, ap->algtype)) { 6237c478bd9Sstevel@tonic-gate fprintf(fp, "%s %d\n", skey.key.keybuf3_val, 6247c478bd9Sstevel@tonic-gate ap->algtype); 6257c478bd9Sstevel@tonic-gate } 6267c478bd9Sstevel@tonic-gate } 6277c478bd9Sstevel@tonic-gate } 6287c478bd9Sstevel@tonic-gate return (1); 6297c478bd9Sstevel@tonic-gate } 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate /* 6327c478bd9Sstevel@tonic-gate * prohibit the nobody key on this machine k (the -d flag) 6337c478bd9Sstevel@tonic-gate */ 634*49e7ca49Speteh int 6357c478bd9Sstevel@tonic-gate pk_nodefaultkeys() 6367c478bd9Sstevel@tonic-gate { 6377c478bd9Sstevel@tonic-gate nodefaultkeys = 1; 6387c478bd9Sstevel@tonic-gate return (0); 6397c478bd9Sstevel@tonic-gate } 6407c478bd9Sstevel@tonic-gate 6417c478bd9Sstevel@tonic-gate static void 6427c478bd9Sstevel@tonic-gate freedisklist(struct cacheuid_list *cp) 6437c478bd9Sstevel@tonic-gate { 6447c478bd9Sstevel@tonic-gate if (cp == NULL) { 6457c478bd9Sstevel@tonic-gate return; 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate free(cp->netname); /* ok even if this is NULL */ 6487c478bd9Sstevel@tonic-gate freekeybuf3(cp->secretkey); 6497c478bd9Sstevel@tonic-gate freekeybuf3(cp->publickey); 6507c478bd9Sstevel@tonic-gate } 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate keystatus 6537c478bd9Sstevel@tonic-gate pk_clear3(uid_t uid) 6547c478bd9Sstevel@tonic-gate { 6557c478bd9Sstevel@tonic-gate struct keylenlist *kp; 6567c478bd9Sstevel@tonic-gate struct algtypelist *ap; 6577c478bd9Sstevel@tonic-gate struct mechdata *mdp; 6587c478bd9Sstevel@tonic-gate struct cacheuid_list **cpp, *cp; 6597c478bd9Sstevel@tonic-gate 6607c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("pk_clear3 %d", uid)); 6617c478bd9Sstevel@tonic-gate for (kp = mechtable.kp; kp != NULL; kp = kp->next) { 6627c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("pk_clear3 key %d", kp->keylen)); 6637c478bd9Sstevel@tonic-gate for (ap = kp->ap; ap != NULL; ap = ap->next) { 6647c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, 6657c478bd9Sstevel@tonic-gate ("pk_clear3 alg: %d", ap->algtype)); 6667c478bd9Sstevel@tonic-gate mutex_lock(&ap->mech.mech_lock); 6677c478bd9Sstevel@tonic-gate if ((mdp = ap->mech.mechdata) == NULL) { 6687c478bd9Sstevel@tonic-gate mutex_unlock(&ap->mech.mech_lock); 6697c478bd9Sstevel@tonic-gate continue; 6707c478bd9Sstevel@tonic-gate } 6717c478bd9Sstevel@tonic-gate cpp = mapuid2cache(uid, mdp); 6727c478bd9Sstevel@tonic-gate if (*cpp == NULL) { 6737c478bd9Sstevel@tonic-gate mutex_unlock(&ap->mech.mech_lock); 6747c478bd9Sstevel@tonic-gate continue; 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate cp = (*cpp)->next; 6777c478bd9Sstevel@tonic-gate freedisklist(*cpp); 6787c478bd9Sstevel@tonic-gate *cpp = cp; 6797c478bd9Sstevel@tonic-gate mutex_unlock(&ap->mech.mech_lock); 6807c478bd9Sstevel@tonic-gate } 6817c478bd9Sstevel@tonic-gate } 6827c478bd9Sstevel@tonic-gate /* XXX clear stuff out of the common key cache as well? */ 6837c478bd9Sstevel@tonic-gate /* XXX return success only if something was removed? */ 6847c478bd9Sstevel@tonic-gate return (KEY_SUCCESS); 6857c478bd9Sstevel@tonic-gate } 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate /* 6887c478bd9Sstevel@tonic-gate * Set the modulus for all our Diffie-Hellman operations 6897c478bd9Sstevel@tonic-gate */ 690*49e7ca49Speteh int 6917c478bd9Sstevel@tonic-gate setmodulus(modx) 6927c478bd9Sstevel@tonic-gate char *modx; 6937c478bd9Sstevel@tonic-gate { 6947c478bd9Sstevel@tonic-gate MODULUS = mp_xtom(modx); 6957c478bd9Sstevel@tonic-gate return (0); 6967c478bd9Sstevel@tonic-gate } 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate /* 6997c478bd9Sstevel@tonic-gate * Encrypt the key using the public key associated with remote_name and the 7007c478bd9Sstevel@tonic-gate * secret key associated with uid. 7017c478bd9Sstevel@tonic-gate */ 7027c478bd9Sstevel@tonic-gate keystatus 7037c478bd9Sstevel@tonic-gate pk_encrypt(uid, remote_name, remote_key, key) 7047c478bd9Sstevel@tonic-gate uid_t uid; 7057c478bd9Sstevel@tonic-gate char *remote_name; 7067c478bd9Sstevel@tonic-gate netobj *remote_key; 7077c478bd9Sstevel@tonic-gate des_block *key; 7087c478bd9Sstevel@tonic-gate { 7097c478bd9Sstevel@tonic-gate return (pk_crypt(uid, remote_name, remote_key, key, DES_ENCRYPT)); 7107c478bd9Sstevel@tonic-gate } 7117c478bd9Sstevel@tonic-gate 7127c478bd9Sstevel@tonic-gate /* 7137c478bd9Sstevel@tonic-gate * Encrypt the key using the public key associated with remote_name and the 7147c478bd9Sstevel@tonic-gate * secret key associated with uid using vers 3 7157c478bd9Sstevel@tonic-gate */ 7167c478bd9Sstevel@tonic-gate keystatus 7177c478bd9Sstevel@tonic-gate pk_encrypt3( 7187c478bd9Sstevel@tonic-gate uid_t uid, 7197c478bd9Sstevel@tonic-gate cryptkeyarg3 *arg, 7207c478bd9Sstevel@tonic-gate deskeyarray *key 7217c478bd9Sstevel@tonic-gate ) 7227c478bd9Sstevel@tonic-gate { 7237c478bd9Sstevel@tonic-gate return (pk_crypt3(uid, arg, key, DES_ENCRYPT)); 7247c478bd9Sstevel@tonic-gate } 7257c478bd9Sstevel@tonic-gate 7267c478bd9Sstevel@tonic-gate /* 7277c478bd9Sstevel@tonic-gate * Decrypt the key using the public key associated with remote_name and the 7287c478bd9Sstevel@tonic-gate * secret key associated with uid. 7297c478bd9Sstevel@tonic-gate */ 7307c478bd9Sstevel@tonic-gate keystatus 7317c478bd9Sstevel@tonic-gate pk_decrypt(uid, remote_name, remote_key, key) 7327c478bd9Sstevel@tonic-gate uid_t uid; 7337c478bd9Sstevel@tonic-gate char *remote_name; 7347c478bd9Sstevel@tonic-gate netobj *remote_key; 7357c478bd9Sstevel@tonic-gate des_block *key; 7367c478bd9Sstevel@tonic-gate { 7377c478bd9Sstevel@tonic-gate return (pk_crypt(uid, remote_name, remote_key, key, DES_DECRYPT)); 7387c478bd9Sstevel@tonic-gate } 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate /* 7417c478bd9Sstevel@tonic-gate * Decrypt the key using the public key associated with remote_name and the 7427c478bd9Sstevel@tonic-gate * secret key associated with uid using vers 3 7437c478bd9Sstevel@tonic-gate */ 7447c478bd9Sstevel@tonic-gate keystatus 7457c478bd9Sstevel@tonic-gate pk_decrypt3( 7467c478bd9Sstevel@tonic-gate uid_t uid, 7477c478bd9Sstevel@tonic-gate cryptkeyarg3 *arg, 7487c478bd9Sstevel@tonic-gate deskeyarray *key 7497c478bd9Sstevel@tonic-gate ) 7507c478bd9Sstevel@tonic-gate { 7517c478bd9Sstevel@tonic-gate return (pk_crypt3(uid, arg, key, DES_DECRYPT)); 7527c478bd9Sstevel@tonic-gate } 7537c478bd9Sstevel@tonic-gate 7547c478bd9Sstevel@tonic-gate /* 7557c478bd9Sstevel@tonic-gate * Key storage management 7567c478bd9Sstevel@tonic-gate */ 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate #define KEY_ONLY 0 7597c478bd9Sstevel@tonic-gate #define KEY_NAME 1 7607c478bd9Sstevel@tonic-gate struct secretkey_netname_list { 7617c478bd9Sstevel@tonic-gate uid_t uid; 7627c478bd9Sstevel@tonic-gate key_netstarg keynetdata; 7637c478bd9Sstevel@tonic-gate uchar_t sc_flag; 7647c478bd9Sstevel@tonic-gate struct secretkey_netname_list *next; 7657c478bd9Sstevel@tonic-gate }; 7667c478bd9Sstevel@tonic-gate 7677c478bd9Sstevel@tonic-gate #define HASH_UID(x) (x & 0xff) 7687c478bd9Sstevel@tonic-gate static struct secretkey_netname_list *g_secretkey_netname[KEY_HASH_SIZE]; 7697c478bd9Sstevel@tonic-gate static rwlock_t g_secretkey_netname_lock = DEFAULTRWLOCK; 7707c478bd9Sstevel@tonic-gate 7717c478bd9Sstevel@tonic-gate /* 7727c478bd9Sstevel@tonic-gate * Store the keys and netname for this uid 7737c478bd9Sstevel@tonic-gate */ 7747c478bd9Sstevel@tonic-gate static int 7757c478bd9Sstevel@tonic-gate store_netname(uid, netstore) 7767c478bd9Sstevel@tonic-gate uid_t uid; 7777c478bd9Sstevel@tonic-gate key_netstarg *netstore; 7787c478bd9Sstevel@tonic-gate { 7797c478bd9Sstevel@tonic-gate struct secretkey_netname_list *new; 7807c478bd9Sstevel@tonic-gate struct secretkey_netname_list **l; 7817c478bd9Sstevel@tonic-gate int hash = HASH_UID(uid); 7827c478bd9Sstevel@tonic-gate 7837c478bd9Sstevel@tonic-gate (void) rw_wrlock(&g_secretkey_netname_lock); 7847c478bd9Sstevel@tonic-gate for (l = &g_secretkey_netname[hash]; *l != NULL && (*l)->uid != uid; 7857c478bd9Sstevel@tonic-gate l = &(*l)->next) { 7867c478bd9Sstevel@tonic-gate } 7877c478bd9Sstevel@tonic-gate if (*l == NULL) { 7887c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 7897c478bd9Sstevel@tonic-gate new = (struct secretkey_netname_list *)malloc(sizeof (*new)); 7907c478bd9Sstevel@tonic-gate if (new == NULL) { 7917c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_secretkey_netname_lock); 7927c478bd9Sstevel@tonic-gate return (0); 7937c478bd9Sstevel@tonic-gate } 7947c478bd9Sstevel@tonic-gate new->uid = uid; 7957c478bd9Sstevel@tonic-gate new->next = NULL; 7967c478bd9Sstevel@tonic-gate *l = new; 7977c478bd9Sstevel@tonic-gate } else { 7987c478bd9Sstevel@tonic-gate new = *l; 7997c478bd9Sstevel@tonic-gate if (new->keynetdata.st_netname) 8007c478bd9Sstevel@tonic-gate (void) free(new->keynetdata.st_netname); 8017c478bd9Sstevel@tonic-gate } 8027c478bd9Sstevel@tonic-gate memcpy(new->keynetdata.st_priv_key, netstore->st_priv_key, 8037c478bd9Sstevel@tonic-gate HEXKEYBYTES); 8047c478bd9Sstevel@tonic-gate memcpy(new->keynetdata.st_pub_key, netstore->st_pub_key, HEXKEYBYTES); 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate if (netstore->st_netname) 8077c478bd9Sstevel@tonic-gate new->keynetdata.st_netname = strdup(netstore->st_netname); 8087c478bd9Sstevel@tonic-gate else 8097c478bd9Sstevel@tonic-gate new->keynetdata.st_netname = (char *)NULL; 8107c478bd9Sstevel@tonic-gate new->sc_flag = KEY_NAME; 8117c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_secretkey_netname_lock); 8127c478bd9Sstevel@tonic-gate return (1); 8137c478bd9Sstevel@tonic-gate 8147c478bd9Sstevel@tonic-gate } 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate static int 8177c478bd9Sstevel@tonic-gate appendnetname3(struct mechentry *mp, uid_t uid, key_netstarg3 *net) 8187c478bd9Sstevel@tonic-gate { 8197c478bd9Sstevel@tonic-gate struct mechdata *mdp; 8207c478bd9Sstevel@tonic-gate struct cacheuid_list **cpp, *cp; 8217c478bd9Sstevel@tonic-gate 8227c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("appendnetname3 %x", mp)); 8237c478bd9Sstevel@tonic-gate if ((mp == NULL) || (net == NULL)) { 8247c478bd9Sstevel@tonic-gate return (0); 8257c478bd9Sstevel@tonic-gate } 8267c478bd9Sstevel@tonic-gate mutex_lock(&mp->mech_lock); 8277c478bd9Sstevel@tonic-gate if ((mdp = mp->mechdata) == NULL) { 8287c478bd9Sstevel@tonic-gate mdp = (struct mechdata *)calloc(1, sizeof (*mdp)); 8297c478bd9Sstevel@tonic-gate if (mdp == NULL) { 8307c478bd9Sstevel@tonic-gate mutex_unlock(&mp->mech_lock); 8317c478bd9Sstevel@tonic-gate debug(KEYSERV_INFO, ("appendnetname3 : calloc failed")); 8327c478bd9Sstevel@tonic-gate return (0); 8337c478bd9Sstevel@tonic-gate } 8347c478bd9Sstevel@tonic-gate mp->mechdata = mdp; 8357c478bd9Sstevel@tonic-gate } 8367c478bd9Sstevel@tonic-gate cpp = mapuid2cache(uid, mdp); 8377c478bd9Sstevel@tonic-gate if (*cpp == NULL) { 8387c478bd9Sstevel@tonic-gate cp = (struct cacheuid_list *)malloc(sizeof (*cp)); 8397c478bd9Sstevel@tonic-gate if (cp == NULL) { 8407c478bd9Sstevel@tonic-gate mutex_unlock(&mp->mech_lock); 8417c478bd9Sstevel@tonic-gate debug(KEYSERV_INFO, ("appendnetname3 : malloc failed")); 8427c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "file %s line %d: malloc failed", 8437c478bd9Sstevel@tonic-gate __FILE__, __LINE__); 8447c478bd9Sstevel@tonic-gate return (0); 8457c478bd9Sstevel@tonic-gate } 8467c478bd9Sstevel@tonic-gate memset(cp, 0, sizeof (*cp)); 8477c478bd9Sstevel@tonic-gate cp->uid = uid; 8487c478bd9Sstevel@tonic-gate *cpp = cp; 8497c478bd9Sstevel@tonic-gate } else { 8507c478bd9Sstevel@tonic-gate cp = *cpp; 8517c478bd9Sstevel@tonic-gate } 8527c478bd9Sstevel@tonic-gate freekeybuf3(cp->secretkey); 8537c478bd9Sstevel@tonic-gate if ((cp->secretkey = cpykeybuf3(&net->st_priv_key)) == NULL) { 8547c478bd9Sstevel@tonic-gate mutex_unlock(&mp->mech_lock); 8557c478bd9Sstevel@tonic-gate return (0); 8567c478bd9Sstevel@tonic-gate } 8577c478bd9Sstevel@tonic-gate freekeybuf3(cp->publickey); 8587c478bd9Sstevel@tonic-gate if ((cp->publickey = cpykeybuf3(&net->st_pub_key)) == NULL) { 8597c478bd9Sstevel@tonic-gate mutex_unlock(&mp->mech_lock); 8607c478bd9Sstevel@tonic-gate return (0); 8617c478bd9Sstevel@tonic-gate } 8627c478bd9Sstevel@tonic-gate free(cp->netname); 8637c478bd9Sstevel@tonic-gate if (net->st_netname) { 8647c478bd9Sstevel@tonic-gate cp->netname = strdup(net->st_netname); 8657c478bd9Sstevel@tonic-gate } else { 8667c478bd9Sstevel@tonic-gate cp->netname = (char *)NULL; 8677c478bd9Sstevel@tonic-gate } 8687c478bd9Sstevel@tonic-gate mutex_unlock(&mp->mech_lock); 8697c478bd9Sstevel@tonic-gate return (1); 8707c478bd9Sstevel@tonic-gate } 8717c478bd9Sstevel@tonic-gate 8727c478bd9Sstevel@tonic-gate keystatus 8737c478bd9Sstevel@tonic-gate pk_netput(uid, netstore) 8747c478bd9Sstevel@tonic-gate uid_t uid; 8757c478bd9Sstevel@tonic-gate key_netstarg *netstore; 8767c478bd9Sstevel@tonic-gate { 8777c478bd9Sstevel@tonic-gate 8787c478bd9Sstevel@tonic-gate if (!store_netname(uid, netstore)) { 8797c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 8807c478bd9Sstevel@tonic-gate } 8817c478bd9Sstevel@tonic-gate return (KEY_SUCCESS); 8827c478bd9Sstevel@tonic-gate } 8837c478bd9Sstevel@tonic-gate 8847c478bd9Sstevel@tonic-gate /* 8857c478bd9Sstevel@tonic-gate * Store the keys and netname for this uid vers 3 8867c478bd9Sstevel@tonic-gate */ 8877c478bd9Sstevel@tonic-gate static int 8887c478bd9Sstevel@tonic-gate store_netname3(uid_t uid, key_netstarg3 *net) 8897c478bd9Sstevel@tonic-gate { 8907c478bd9Sstevel@tonic-gate struct mechentry *mp; 8917c478bd9Sstevel@tonic-gate key_netstarg netstore; 8927c478bd9Sstevel@tonic-gate 8937c478bd9Sstevel@tonic-gate if (net == NULL) { 8947c478bd9Sstevel@tonic-gate return (0); 8957c478bd9Sstevel@tonic-gate } 8967c478bd9Sstevel@tonic-gate if ((mp = getmechtype(net->keylen, net->algtype)) == NULL) { 8977c478bd9Sstevel@tonic-gate return (0); 8987c478bd9Sstevel@tonic-gate } 8997c478bd9Sstevel@tonic-gate if (uid == 0 && CLASSIC_PK_DH(net->keylen, net->algtype)) { 9007c478bd9Sstevel@tonic-gate memcpy(netstore.st_priv_key, net->st_priv_key.keybuf3_val, 9017c478bd9Sstevel@tonic-gate HEXKEYBYTES); 9027c478bd9Sstevel@tonic-gate memset(netstore.st_pub_key, 0, HEXKEYBYTES); 9037c478bd9Sstevel@tonic-gate netstore.st_netname = net->st_netname; 9047c478bd9Sstevel@tonic-gate if (pk_netput(uid, &netstore) != KEY_SUCCESS) { 9057c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 9067c478bd9Sstevel@tonic-gate "keyserv: could not set root's key and netname.\n"); 9077c478bd9Sstevel@tonic-gate return (0); 9087c478bd9Sstevel@tonic-gate } 9097c478bd9Sstevel@tonic-gate } 9107c478bd9Sstevel@tonic-gate return (appendnetname3(mp, uid, net)); 9117c478bd9Sstevel@tonic-gate } 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate keystatus 9147c478bd9Sstevel@tonic-gate pk_netput3(uid_t uid, key_netstarg3 *netstore) 9157c478bd9Sstevel@tonic-gate { 9167c478bd9Sstevel@tonic-gate 9177c478bd9Sstevel@tonic-gate if (!store_netname3(uid, netstore)) { 9187c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 9197c478bd9Sstevel@tonic-gate } 9207c478bd9Sstevel@tonic-gate return (KEY_SUCCESS); 9217c478bd9Sstevel@tonic-gate } 9227c478bd9Sstevel@tonic-gate 9237c478bd9Sstevel@tonic-gate int 9247c478bd9Sstevel@tonic-gate addmasterkey(char *master, char *netname, algtype_t algtype) 9257c478bd9Sstevel@tonic-gate { 9267c478bd9Sstevel@tonic-gate keybuf3 *secret, *public; 9277c478bd9Sstevel@tonic-gate int bytelen = strlen(master); 9287c478bd9Sstevel@tonic-gate keylen_t keylen = bytelen*4; 9297c478bd9Sstevel@tonic-gate key_netstarg3 tmp; 9307c478bd9Sstevel@tonic-gate 9317c478bd9Sstevel@tonic-gate if ((secret = setkeybuf3(master, bytelen)) == NULL) { 9327c478bd9Sstevel@tonic-gate return (0); 9337c478bd9Sstevel@tonic-gate } 9347c478bd9Sstevel@tonic-gate if ((public = getkeybuf3(bytelen+1)) == NULL) { 9357c478bd9Sstevel@tonic-gate /* the +1 is mandated by getpublickey_g() */ 9367c478bd9Sstevel@tonic-gate return (0); 9377c478bd9Sstevel@tonic-gate } 9387c478bd9Sstevel@tonic-gate /* 9397c478bd9Sstevel@tonic-gate * getpublickey_g(netname, keylen, algtype, 9407c478bd9Sstevel@tonic-gate * public->keybuf3_val, public->keybuf3_len); 9417c478bd9Sstevel@tonic-gate * cannot be called since rpc.nisd is not up yet 9427c478bd9Sstevel@tonic-gate * so we continue to return a zero filled public key 9437c478bd9Sstevel@tonic-gate * as in the earlier version 9447c478bd9Sstevel@tonic-gate */ 9457c478bd9Sstevel@tonic-gate memset(public->keybuf3_val, 0, bytelen+1); 9467c478bd9Sstevel@tonic-gate tmp.st_priv_key = *secret; 9477c478bd9Sstevel@tonic-gate free(secret); 9487c478bd9Sstevel@tonic-gate tmp.st_pub_key = *public; 9497c478bd9Sstevel@tonic-gate free(public); 9507c478bd9Sstevel@tonic-gate tmp.st_netname = strdup(netname); 9517c478bd9Sstevel@tonic-gate tmp.keylen = keylen; 9527c478bd9Sstevel@tonic-gate tmp.algtype = algtype; 9537c478bd9Sstevel@tonic-gate return (store_netname3(0, &tmp)); 9547c478bd9Sstevel@tonic-gate } 9557c478bd9Sstevel@tonic-gate 9567c478bd9Sstevel@tonic-gate /* 9577c478bd9Sstevel@tonic-gate * Fetch the keys and netname for this uid 9587c478bd9Sstevel@tonic-gate */ 9597c478bd9Sstevel@tonic-gate static int 9607c478bd9Sstevel@tonic-gate fetch_netname(uid, key_netst) 9617c478bd9Sstevel@tonic-gate uid_t uid; 9627c478bd9Sstevel@tonic-gate struct key_netstarg *key_netst; 9637c478bd9Sstevel@tonic-gate { 9647c478bd9Sstevel@tonic-gate struct secretkey_netname_list *l; 9657c478bd9Sstevel@tonic-gate int hash = HASH_UID(uid); 9667c478bd9Sstevel@tonic-gate 9677c478bd9Sstevel@tonic-gate (void) rw_rdlock(&g_secretkey_netname_lock); 9687c478bd9Sstevel@tonic-gate for (l = g_secretkey_netname[hash]; l != NULL; l = l->next) { 9697c478bd9Sstevel@tonic-gate if ((l->uid == uid) && (l->sc_flag == KEY_NAME)) { 9707c478bd9Sstevel@tonic-gate 9717c478bd9Sstevel@tonic-gate memcpy(key_netst->st_priv_key, 9727c478bd9Sstevel@tonic-gate l->keynetdata.st_priv_key, HEXKEYBYTES); 9737c478bd9Sstevel@tonic-gate 9747c478bd9Sstevel@tonic-gate memcpy(key_netst->st_pub_key, 9757c478bd9Sstevel@tonic-gate l->keynetdata.st_pub_key, HEXKEYBYTES); 9767c478bd9Sstevel@tonic-gate 9777c478bd9Sstevel@tonic-gate if (l->keynetdata.st_netname) 9787c478bd9Sstevel@tonic-gate strcpy(key_netst->st_netname, 9797c478bd9Sstevel@tonic-gate l->keynetdata.st_netname); 9807c478bd9Sstevel@tonic-gate else 9817c478bd9Sstevel@tonic-gate key_netst->st_netname = NULL; 9827c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_secretkey_netname_lock); 9837c478bd9Sstevel@tonic-gate return (1); 9847c478bd9Sstevel@tonic-gate } 9857c478bd9Sstevel@tonic-gate } 9867c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_secretkey_netname_lock); 9877c478bd9Sstevel@tonic-gate return (0); 9887c478bd9Sstevel@tonic-gate } 9897c478bd9Sstevel@tonic-gate 9907c478bd9Sstevel@tonic-gate static void 9917c478bd9Sstevel@tonic-gate remove_ref(struct cacheuid_list *cp) 9927c478bd9Sstevel@tonic-gate { 9937c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("remove_ref %x", cp)); 9947c478bd9Sstevel@tonic-gate /* 9957c478bd9Sstevel@tonic-gate * XXX 9967c478bd9Sstevel@tonic-gate * if we are going to do this along the lines of vn_rele, 9977c478bd9Sstevel@tonic-gate * more stuff needs to be done here and the access to refcnt 9987c478bd9Sstevel@tonic-gate * needs to be mutex locked. Keep it simple for now. 9997c478bd9Sstevel@tonic-gate */ 10007c478bd9Sstevel@tonic-gate cp->refcnt--; 10017c478bd9Sstevel@tonic-gate } 10027c478bd9Sstevel@tonic-gate 10037c478bd9Sstevel@tonic-gate static void 10047c478bd9Sstevel@tonic-gate add_ref(struct cacheuid_list **cpp) 10057c478bd9Sstevel@tonic-gate { 10067c478bd9Sstevel@tonic-gate struct cacheuid_list *cp; 10077c478bd9Sstevel@tonic-gate 10087c478bd9Sstevel@tonic-gate if (cpp == NULL) { 10097c478bd9Sstevel@tonic-gate return; 10107c478bd9Sstevel@tonic-gate } 10117c478bd9Sstevel@tonic-gate /*LINTED assignment operator "=" found where "==" was expected*/ 10127c478bd9Sstevel@tonic-gate if (cp = *cpp) { 10137c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("add_ref %x", cp)); 10147c478bd9Sstevel@tonic-gate cp->refcnt++; 10157c478bd9Sstevel@tonic-gate } 10167c478bd9Sstevel@tonic-gate } 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate static struct cacheuid_list * 10197c478bd9Sstevel@tonic-gate getcachekey3(uid_t uid, struct mechentry *mp) 10207c478bd9Sstevel@tonic-gate { 10217c478bd9Sstevel@tonic-gate struct cacheuid_list **cpp, *cp; 10227c478bd9Sstevel@tonic-gate struct mechdata *mdp; 10237c478bd9Sstevel@tonic-gate 10247c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG1, ("getcachekey3 %d %x", uid, mp)); 10257c478bd9Sstevel@tonic-gate if (mp == NULL) { 10267c478bd9Sstevel@tonic-gate return (0); 10277c478bd9Sstevel@tonic-gate } 10287c478bd9Sstevel@tonic-gate mutex_lock(&mp->mech_lock); 10297c478bd9Sstevel@tonic-gate if ((mdp = mp->mechdata) == NULL) { 10307c478bd9Sstevel@tonic-gate mutex_unlock(&mp->mech_lock); 10317c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("getcachekey3 ret 0")); 10327c478bd9Sstevel@tonic-gate return (0); 10337c478bd9Sstevel@tonic-gate } 10347c478bd9Sstevel@tonic-gate cpp = mapuid2cache(uid, mdp); 10357c478bd9Sstevel@tonic-gate cp = *cpp; 10367c478bd9Sstevel@tonic-gate add_ref(cpp); 10377c478bd9Sstevel@tonic-gate mutex_unlock(&mp->mech_lock); 10387c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("getcachekey3 ret %x", *cpp)); 10397c478bd9Sstevel@tonic-gate return (cp); 10407c478bd9Sstevel@tonic-gate } 10417c478bd9Sstevel@tonic-gate 10427c478bd9Sstevel@tonic-gate /* 10437c478bd9Sstevel@tonic-gate * Fetch any available cache for this uid (vers 3) 10447c478bd9Sstevel@tonic-gate */ 10457c478bd9Sstevel@tonic-gate static struct cacheuid_list * 10467c478bd9Sstevel@tonic-gate getanycache3(uid_t uid) 10477c478bd9Sstevel@tonic-gate { 10487c478bd9Sstevel@tonic-gate struct keylenlist *kp; 10497c478bd9Sstevel@tonic-gate struct algtypelist *ap; 10507c478bd9Sstevel@tonic-gate struct mechdata *mdp; 10517c478bd9Sstevel@tonic-gate struct cacheuid_list **cpp, *cp; 10527c478bd9Sstevel@tonic-gate 10537c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("getanycache3 %d", uid)); 10547c478bd9Sstevel@tonic-gate for (kp = mechtable.kp; kp != NULL; kp = kp->next) { 10557c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("getanycache3 key %d", kp->keylen)); 10567c478bd9Sstevel@tonic-gate for (ap = kp->ap; ap != NULL; ap = ap->next) { 10577c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, 10587c478bd9Sstevel@tonic-gate ("getanycache3 alg: %d", ap->algtype)); 10597c478bd9Sstevel@tonic-gate mutex_lock(&ap->mech.mech_lock); 10607c478bd9Sstevel@tonic-gate if ((mdp = ap->mech.mechdata) == NULL) { 10617c478bd9Sstevel@tonic-gate mutex_unlock(&ap->mech.mech_lock); 10627c478bd9Sstevel@tonic-gate continue; 10637c478bd9Sstevel@tonic-gate } 10647c478bd9Sstevel@tonic-gate cpp = mapuid2cache(uid, mdp); 10657c478bd9Sstevel@tonic-gate if (*cpp == NULL) { 10667c478bd9Sstevel@tonic-gate mutex_unlock(&ap->mech.mech_lock); 10677c478bd9Sstevel@tonic-gate continue; 10687c478bd9Sstevel@tonic-gate } 10697c478bd9Sstevel@tonic-gate cp = *cpp; 10707c478bd9Sstevel@tonic-gate cp->refcnt++; 10717c478bd9Sstevel@tonic-gate mutex_unlock(&ap->mech.mech_lock); 10727c478bd9Sstevel@tonic-gate return (cp); 10737c478bd9Sstevel@tonic-gate } 10747c478bd9Sstevel@tonic-gate } 10757c478bd9Sstevel@tonic-gate return (NULL); 10767c478bd9Sstevel@tonic-gate } 10777c478bd9Sstevel@tonic-gate 10787c478bd9Sstevel@tonic-gate static struct cacheuid_list * 10797c478bd9Sstevel@tonic-gate fetchcache3(uid_t uid, keylen_t k, algtype_t a) 10807c478bd9Sstevel@tonic-gate { 10817c478bd9Sstevel@tonic-gate struct mechentry *mp; 10827c478bd9Sstevel@tonic-gate struct cacheuid_list *cp; 10837c478bd9Sstevel@tonic-gate 10847c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("fetchcache3 %d %d %d", uid, k, a)); 10857c478bd9Sstevel@tonic-gate if ((mp = getmechtype(k, a)) == NULL) { 10867c478bd9Sstevel@tonic-gate return (NULL); 10877c478bd9Sstevel@tonic-gate } 10887c478bd9Sstevel@tonic-gate if ((cp = getcachekey3(uid, mp)) == NULL) { 10897c478bd9Sstevel@tonic-gate return (NULL); 10907c478bd9Sstevel@tonic-gate } 10917c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("fetchcache3 ret %x", cp)); 10927c478bd9Sstevel@tonic-gate return (cp); 10937c478bd9Sstevel@tonic-gate } 10947c478bd9Sstevel@tonic-gate 10957c478bd9Sstevel@tonic-gate /* 10967c478bd9Sstevel@tonic-gate * Fetch the keys and netname for this uid vers 3 10977c478bd9Sstevel@tonic-gate */ 10987c478bd9Sstevel@tonic-gate static int 10997c478bd9Sstevel@tonic-gate fetch_netname3(uid_t uid, mechtype *net, key_netstarg3 *ret) 11007c478bd9Sstevel@tonic-gate { 11017c478bd9Sstevel@tonic-gate struct cacheuid_list *cp; 11027c478bd9Sstevel@tonic-gate 11037c478bd9Sstevel@tonic-gate if ((net == NULL) || (ret == NULL)) { 11047c478bd9Sstevel@tonic-gate return (0); 11057c478bd9Sstevel@tonic-gate } 11067c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("fetch_netname3 %d %d %d", 11077c478bd9Sstevel@tonic-gate uid, net->keylen, net->algtype)); 11087c478bd9Sstevel@tonic-gate if (net->keylen == 0) { 11097c478bd9Sstevel@tonic-gate cp = getanycache3(uid); 11107c478bd9Sstevel@tonic-gate } else { 11117c478bd9Sstevel@tonic-gate cp = fetchcache3(uid, net->keylen, net->algtype); 11127c478bd9Sstevel@tonic-gate } 11137c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("fetch_netname3 cp %x", cp)); 11147c478bd9Sstevel@tonic-gate if (cp == NULL) { 11157c478bd9Sstevel@tonic-gate return (0); 11167c478bd9Sstevel@tonic-gate } 11177c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("fetch_netname3 sec %x", cp->secretkey)); 11187c478bd9Sstevel@tonic-gate if (!storekeybuf3(&ret->st_priv_key, cp->secretkey)) { 11197c478bd9Sstevel@tonic-gate return (0); 11207c478bd9Sstevel@tonic-gate } 11217c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("fetch_netname3 pub %x", cp->publickey)); 11227c478bd9Sstevel@tonic-gate if (!storekeybuf3(&ret->st_pub_key, cp->publickey)) { 11237c478bd9Sstevel@tonic-gate return (0); 11247c478bd9Sstevel@tonic-gate } 11257c478bd9Sstevel@tonic-gate if (cp->netname) { 11267c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("fetch_netname3 net %s", cp->netname)); 11277c478bd9Sstevel@tonic-gate ret->st_netname = strdup(cp->netname); 11287c478bd9Sstevel@tonic-gate } else { 11297c478bd9Sstevel@tonic-gate ret->st_netname = NULL; 11307c478bd9Sstevel@tonic-gate } 11317c478bd9Sstevel@tonic-gate remove_ref(cp); 11327c478bd9Sstevel@tonic-gate return (1); 11337c478bd9Sstevel@tonic-gate } 11347c478bd9Sstevel@tonic-gate 11357c478bd9Sstevel@tonic-gate keystatus 11367c478bd9Sstevel@tonic-gate pk_netget(uid, netstore) 11377c478bd9Sstevel@tonic-gate uid_t uid; 11387c478bd9Sstevel@tonic-gate key_netstarg *netstore; 11397c478bd9Sstevel@tonic-gate { 11407c478bd9Sstevel@tonic-gate if (!fetch_netname(uid, netstore)) { 11417c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 11427c478bd9Sstevel@tonic-gate } 11437c478bd9Sstevel@tonic-gate return (KEY_SUCCESS); 11447c478bd9Sstevel@tonic-gate } 11457c478bd9Sstevel@tonic-gate 11467c478bd9Sstevel@tonic-gate keystatus 11477c478bd9Sstevel@tonic-gate pk_netget3(uid_t uid, mechtype *net, key_netstarg3 *ret) 11487c478bd9Sstevel@tonic-gate { 11497c478bd9Sstevel@tonic-gate if (!fetch_netname3(uid, net, ret)) { 11507c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 11517c478bd9Sstevel@tonic-gate } 11527c478bd9Sstevel@tonic-gate return (KEY_SUCCESS); 11537c478bd9Sstevel@tonic-gate } 11547c478bd9Sstevel@tonic-gate 11557c478bd9Sstevel@tonic-gate #define cachehit(pub, sec, list) \ 11567c478bd9Sstevel@tonic-gate (memcmp(pub, (list)->public, sizeof (keybuf)) == 0 && \ 11577c478bd9Sstevel@tonic-gate memcmp(sec, (list)->secret, sizeof (keybuf)) == 0) 11587c478bd9Sstevel@tonic-gate 11597c478bd9Sstevel@tonic-gate /* 11607c478bd9Sstevel@tonic-gate * Try to find the common key in the cache 11617c478bd9Sstevel@tonic-gate */ 1162*49e7ca49Speteh static int 11637c478bd9Sstevel@tonic-gate readcache(pub, sec, deskey, hash) 11647c478bd9Sstevel@tonic-gate char *pub; 11657c478bd9Sstevel@tonic-gate char *sec; 11667c478bd9Sstevel@tonic-gate des_block *deskey; 11677c478bd9Sstevel@tonic-gate int hash; 11687c478bd9Sstevel@tonic-gate { 11697c478bd9Sstevel@tonic-gate register struct cachekey_list **l; 11707c478bd9Sstevel@tonic-gate 11717c478bd9Sstevel@tonic-gate for (l = &g_cachedkeys[hash]; (*l) != NULL && !cachehit(pub, sec, *l); 11727c478bd9Sstevel@tonic-gate l = &(*l)->next) 11737c478bd9Sstevel@tonic-gate ; 11747c478bd9Sstevel@tonic-gate if ((*l) == NULL) 11757c478bd9Sstevel@tonic-gate return (0); 11767c478bd9Sstevel@tonic-gate *deskey = (*l)->deskey; 11777c478bd9Sstevel@tonic-gate return (1); 11787c478bd9Sstevel@tonic-gate } 11797c478bd9Sstevel@tonic-gate 11807c478bd9Sstevel@tonic-gate /* 11817c478bd9Sstevel@tonic-gate * cache result of expensive multiple precision exponential operation 11827c478bd9Sstevel@tonic-gate */ 1183*49e7ca49Speteh static int 11847c478bd9Sstevel@tonic-gate writecache(pub, sec, deskey, hash) 11857c478bd9Sstevel@tonic-gate char *pub; 11867c478bd9Sstevel@tonic-gate char *sec; 11877c478bd9Sstevel@tonic-gate des_block *deskey; 11887c478bd9Sstevel@tonic-gate int hash; 11897c478bd9Sstevel@tonic-gate { 11907c478bd9Sstevel@tonic-gate struct cachekey_list *new; 11917c478bd9Sstevel@tonic-gate 11927c478bd9Sstevel@tonic-gate new = (struct cachekey_list *)malloc(sizeof (struct cachekey_list)); 11937c478bd9Sstevel@tonic-gate if (new == NULL) { 11947c478bd9Sstevel@tonic-gate return (0); 11957c478bd9Sstevel@tonic-gate } 11967c478bd9Sstevel@tonic-gate memcpy(new->public, pub, sizeof (keybuf)); 11977c478bd9Sstevel@tonic-gate memcpy(new->secret, sec, sizeof (keybuf)); 11987c478bd9Sstevel@tonic-gate new->deskey = *deskey; 11997c478bd9Sstevel@tonic-gate 12007c478bd9Sstevel@tonic-gate new->next = g_cachedkeys[hash]; 12017c478bd9Sstevel@tonic-gate g_cachedkeys[hash] = new; 12027c478bd9Sstevel@tonic-gate return (1); 12037c478bd9Sstevel@tonic-gate } 12047c478bd9Sstevel@tonic-gate 12057c478bd9Sstevel@tonic-gate /* 12067c478bd9Sstevel@tonic-gate * Choose middle 64 bits of the common key to use as our des key, possibly 12077c478bd9Sstevel@tonic-gate * overwriting the lower order bits by setting parity. 12087c478bd9Sstevel@tonic-gate */ 1209*49e7ca49Speteh static int 12107c478bd9Sstevel@tonic-gate extractdeskey(ck, deskey) 12117c478bd9Sstevel@tonic-gate MINT *ck; 12127c478bd9Sstevel@tonic-gate des_block *deskey; 12137c478bd9Sstevel@tonic-gate { 12147c478bd9Sstevel@tonic-gate void _mp_move(MINT *, MINT *); 12157c478bd9Sstevel@tonic-gate MINT *a; 12167c478bd9Sstevel@tonic-gate short r; 12177c478bd9Sstevel@tonic-gate int i; 12187c478bd9Sstevel@tonic-gate short base = (1 << 8); 12197c478bd9Sstevel@tonic-gate char *k; 12207c478bd9Sstevel@tonic-gate 12217c478bd9Sstevel@tonic-gate a = mp_itom(0); 12227c478bd9Sstevel@tonic-gate _mp_move(ck, a); 12237c478bd9Sstevel@tonic-gate for (i = 0; i < ((KEYSIZE - 64) / 2) / 8; i++) { 12247c478bd9Sstevel@tonic-gate mp_sdiv(a, base, a, &r); 12257c478bd9Sstevel@tonic-gate } 12267c478bd9Sstevel@tonic-gate k = deskey->c; 12277c478bd9Sstevel@tonic-gate for (i = 0; i < 8; i++) { 12287c478bd9Sstevel@tonic-gate mp_sdiv(a, base, a, &r); 12297c478bd9Sstevel@tonic-gate *k++ = r; 12307c478bd9Sstevel@tonic-gate } 12317c478bd9Sstevel@tonic-gate mp_mfree(a); 12327c478bd9Sstevel@tonic-gate des_setparity((char *)deskey); 12337c478bd9Sstevel@tonic-gate return (0); 12347c478bd9Sstevel@tonic-gate } 12357c478bd9Sstevel@tonic-gate 12367c478bd9Sstevel@tonic-gate static bool_t 12377c478bd9Sstevel@tonic-gate fetchsecretkey(uid, buf) 12387c478bd9Sstevel@tonic-gate uid_t uid; 12397c478bd9Sstevel@tonic-gate char *buf; 12407c478bd9Sstevel@tonic-gate { 12417c478bd9Sstevel@tonic-gate struct secretkey_netname_list *l; 12427c478bd9Sstevel@tonic-gate int hash = HASH_UID(uid); 12437c478bd9Sstevel@tonic-gate 12447c478bd9Sstevel@tonic-gate (void) rw_rdlock(&g_secretkey_netname_lock); 12457c478bd9Sstevel@tonic-gate for (l = g_secretkey_netname[hash]; l != NULL; l = l->next) { 12467c478bd9Sstevel@tonic-gate if (l->uid == uid) { 12477c478bd9Sstevel@tonic-gate memcpy(buf, l->keynetdata.st_priv_key, 12487c478bd9Sstevel@tonic-gate sizeof (keybuf)); 12497c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_secretkey_netname_lock); 12507c478bd9Sstevel@tonic-gate return (TRUE); 12517c478bd9Sstevel@tonic-gate } 12527c478bd9Sstevel@tonic-gate } 12537c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_secretkey_netname_lock); 12547c478bd9Sstevel@tonic-gate return (FALSE); 12557c478bd9Sstevel@tonic-gate } 12567c478bd9Sstevel@tonic-gate 12577c478bd9Sstevel@tonic-gate static keybuf3 * 12587c478bd9Sstevel@tonic-gate fetchsecretkey3(uid_t uid, keylen_t k, algtype_t a) 12597c478bd9Sstevel@tonic-gate { 12607c478bd9Sstevel@tonic-gate struct cacheuid_list *cp; 12617c478bd9Sstevel@tonic-gate 12627c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("fetchsecretkey3 %d %d %d", uid, k, a)); 12637c478bd9Sstevel@tonic-gate if ((cp = fetchcache3(uid, k, a)) == NULL) { 12647c478bd9Sstevel@tonic-gate return (NULL); 12657c478bd9Sstevel@tonic-gate } 12667c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("fetchsecretkey3 ret %x", cp->secretkey)); 12677c478bd9Sstevel@tonic-gate return (cp->secretkey); 12687c478bd9Sstevel@tonic-gate } 12697c478bd9Sstevel@tonic-gate 12707c478bd9Sstevel@tonic-gate /* 12717c478bd9Sstevel@tonic-gate * Do the work of pk_encrypt && pk_decrypt 12727c478bd9Sstevel@tonic-gate */ 12737c478bd9Sstevel@tonic-gate static keystatus 12747c478bd9Sstevel@tonic-gate pk_crypt(uid, remote_name, remote_key, key, mode) 12757c478bd9Sstevel@tonic-gate uid_t uid; 12767c478bd9Sstevel@tonic-gate char *remote_name; 12777c478bd9Sstevel@tonic-gate netobj *remote_key; 12787c478bd9Sstevel@tonic-gate des_block *key; 12797c478bd9Sstevel@tonic-gate int mode; 12807c478bd9Sstevel@tonic-gate { 12817c478bd9Sstevel@tonic-gate char xsecret[1024]; 12827c478bd9Sstevel@tonic-gate char xpublic[1024]; 12837c478bd9Sstevel@tonic-gate des_block deskey; 12847c478bd9Sstevel@tonic-gate int err; 12857c478bd9Sstevel@tonic-gate MINT *public; 12867c478bd9Sstevel@tonic-gate MINT *secret; 12877c478bd9Sstevel@tonic-gate MINT *common; 12887c478bd9Sstevel@tonic-gate char zero[8]; 12897c478bd9Sstevel@tonic-gate int hash; 12907c478bd9Sstevel@tonic-gate 12917c478bd9Sstevel@tonic-gate if (!fetchsecretkey(uid, xsecret) || xsecret[0] == 0) { 12927c478bd9Sstevel@tonic-gate memset(zero, 0, sizeof (zero)); 12937c478bd9Sstevel@tonic-gate if (nodefaultkeys) 12947c478bd9Sstevel@tonic-gate return (KEY_NOSECRET); 12957c478bd9Sstevel@tonic-gate 12967c478bd9Sstevel@tonic-gate if (!getsecretkey("nobody", xsecret, zero) || xsecret[0] == 0) { 12977c478bd9Sstevel@tonic-gate return (KEY_NOSECRET); 12987c478bd9Sstevel@tonic-gate } 12997c478bd9Sstevel@tonic-gate } 13007c478bd9Sstevel@tonic-gate if (remote_key) { 13017c478bd9Sstevel@tonic-gate memcpy(xpublic, remote_key->n_bytes, remote_key->n_len); 13027c478bd9Sstevel@tonic-gate } else { 13037c478bd9Sstevel@tonic-gate if (!getpublickey(remote_name, xpublic)) { 13047c478bd9Sstevel@tonic-gate if (nodefaultkeys || !getpublickey("nobody", xpublic)) 13057c478bd9Sstevel@tonic-gate return (KEY_UNKNOWN); 13067c478bd9Sstevel@tonic-gate } 13077c478bd9Sstevel@tonic-gate } 13087c478bd9Sstevel@tonic-gate 13097c478bd9Sstevel@tonic-gate xsecret[HEXKEYBYTES] = '\0'; 13107c478bd9Sstevel@tonic-gate xpublic[HEXKEYBYTES] = '\0'; 13117c478bd9Sstevel@tonic-gate 13127c478bd9Sstevel@tonic-gate hash = hash_keys(xpublic, xsecret); 13137c478bd9Sstevel@tonic-gate (void) rw_rdlock(&g_cachedkeys_lock); 13147c478bd9Sstevel@tonic-gate if (!readcache(xpublic, xsecret, &deskey, hash)) { 13157c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_cachedkeys_lock); 13167c478bd9Sstevel@tonic-gate (void) rw_wrlock(&g_cachedkeys_lock); 13177c478bd9Sstevel@tonic-gate if (!readcache(xpublic, xsecret, &deskey, hash)) { 13187c478bd9Sstevel@tonic-gate public = mp_xtom(xpublic); 13197c478bd9Sstevel@tonic-gate secret = mp_xtom(xsecret); 13207c478bd9Sstevel@tonic-gate /* Sanity Check on public and private keys */ 13217c478bd9Sstevel@tonic-gate if (public == NULL || secret == NULL) { 13227c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_cachedkeys_lock); 13237c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 13247c478bd9Sstevel@tonic-gate } 13257c478bd9Sstevel@tonic-gate common = mp_itom(0); 13267c478bd9Sstevel@tonic-gate mp_pow(public, secret, MODULUS, common); 13277c478bd9Sstevel@tonic-gate extractdeskey(common, &deskey); 13287c478bd9Sstevel@tonic-gate writecache(xpublic, xsecret, &deskey, hash); 13297c478bd9Sstevel@tonic-gate mp_mfree(secret); 13307c478bd9Sstevel@tonic-gate mp_mfree(public); 13317c478bd9Sstevel@tonic-gate mp_mfree(common); 13327c478bd9Sstevel@tonic-gate } 13337c478bd9Sstevel@tonic-gate } 13347c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_cachedkeys_lock); 13357c478bd9Sstevel@tonic-gate 13367c478bd9Sstevel@tonic-gate err = ecb_crypt((char *)&deskey, (char *)key, sizeof (des_block), 13377c478bd9Sstevel@tonic-gate DES_HW | mode); 13387c478bd9Sstevel@tonic-gate if (DES_FAILED(err)) { 13397c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 13407c478bd9Sstevel@tonic-gate } 13417c478bd9Sstevel@tonic-gate return (KEY_SUCCESS); 13427c478bd9Sstevel@tonic-gate } 13437c478bd9Sstevel@tonic-gate 13447c478bd9Sstevel@tonic-gate static int 13457c478bd9Sstevel@tonic-gate hash_keys3(keybuf3 *p, keybuf3 *s) 13467c478bd9Sstevel@tonic-gate { 13477c478bd9Sstevel@tonic-gate int i; 13487c478bd9Sstevel@tonic-gate int hash = 0; 13497c478bd9Sstevel@tonic-gate char *pub = p->keybuf3_val; 13507c478bd9Sstevel@tonic-gate char *sec = s->keybuf3_val; 13517c478bd9Sstevel@tonic-gate 13527c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("hash_keys3 public %d %s", 13537c478bd9Sstevel@tonic-gate p->keybuf3_len, pub)); 13547c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("hash_keys3 secret %d %s", 13557c478bd9Sstevel@tonic-gate s->keybuf3_len, sec)); 13567c478bd9Sstevel@tonic-gate for (i = 0; i < s->keybuf3_len; i += 6, pub += 6, sec += 6) { 13577c478bd9Sstevel@tonic-gate hash ^= *pub; 13587c478bd9Sstevel@tonic-gate hash ^= *sec; 13597c478bd9Sstevel@tonic-gate } 13607c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("hash_keys3 ret %d", hash & 0xff)); 13617c478bd9Sstevel@tonic-gate return (hash & 0xff); 13627c478bd9Sstevel@tonic-gate } 13637c478bd9Sstevel@tonic-gate 13647c478bd9Sstevel@tonic-gate static struct cachekey3_list ** 13657c478bd9Sstevel@tonic-gate map_ps2cache(keybuf3 *public, keybuf3 *secret, struct psdata *pdp) 13667c478bd9Sstevel@tonic-gate { 13677c478bd9Sstevel@tonic-gate struct cachekey3_list **cpp; 13687c478bd9Sstevel@tonic-gate int hash = hash_keys3(public, secret); 13697c478bd9Sstevel@tonic-gate 13707c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("map_ps2cache %x %d", pdp, hash)); 13717c478bd9Sstevel@tonic-gate for (cpp = &pdp->common[hash]; 13727c478bd9Sstevel@tonic-gate *cpp != NULL && !(cachehit3(public, secret, *cpp)); 13737c478bd9Sstevel@tonic-gate cpp = &(*cpp)->next) { 13747c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, ("map_ps2cache %x", cpp)); 13757c478bd9Sstevel@tonic-gate } 13767c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("map_ps2cache ret %x", cpp)); 13777c478bd9Sstevel@tonic-gate return (cpp); 13787c478bd9Sstevel@tonic-gate } 13797c478bd9Sstevel@tonic-gate 13807c478bd9Sstevel@tonic-gate static struct cachekey3_list * 13817c478bd9Sstevel@tonic-gate getdeskey3( 13827c478bd9Sstevel@tonic-gate keylen_t keylen, 13837c478bd9Sstevel@tonic-gate algtype_t algtype, 13847c478bd9Sstevel@tonic-gate int desarylen, 13857c478bd9Sstevel@tonic-gate keybuf3 *public, 13867c478bd9Sstevel@tonic-gate keybuf3 *secret, 13877c478bd9Sstevel@tonic-gate uid_t uid 13887c478bd9Sstevel@tonic-gate ) 13897c478bd9Sstevel@tonic-gate { 13907c478bd9Sstevel@tonic-gate struct mechentry *mp; 13917c478bd9Sstevel@tonic-gate struct psdata *pdp; 13927c478bd9Sstevel@tonic-gate struct cachekey3_list **cpp, *cp, *cachep; 13937c478bd9Sstevel@tonic-gate struct cacheuid_list *cu; 13947c478bd9Sstevel@tonic-gate int i; 13957c478bd9Sstevel@tonic-gate int cached = 0; 13967c478bd9Sstevel@tonic-gate 13977c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("getdeskey3 %d %d %d %x %x", 13987c478bd9Sstevel@tonic-gate keylen, algtype, desarylen, public, secret)); 13997c478bd9Sstevel@tonic-gate if ((mp = getmechtype(keylen, algtype)) == NULL) { 14007c478bd9Sstevel@tonic-gate return (0); 14017c478bd9Sstevel@tonic-gate } 14027c478bd9Sstevel@tonic-gate (void) mutex_lock(&mp->ps_lock); 14037c478bd9Sstevel@tonic-gate if ((pdp = mp->psdata) == NULL) { 14047c478bd9Sstevel@tonic-gate if ((pdp = (struct psdata *)calloc(1, sizeof (*pdp))) == 14057c478bd9Sstevel@tonic-gate NULL) { 14067c478bd9Sstevel@tonic-gate mutex_unlock(&mp->ps_lock); 14077c478bd9Sstevel@tonic-gate debug(KEYSERV_INFO, ("getdeskey3 : calloc failed")); 14087c478bd9Sstevel@tonic-gate return (0); 14097c478bd9Sstevel@tonic-gate } 14107c478bd9Sstevel@tonic-gate mp->psdata = pdp; 14117c478bd9Sstevel@tonic-gate } 14127c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("getdeskey3 %x", pdp)); 14137c478bd9Sstevel@tonic-gate cpp = map_ps2cache(public, secret, pdp); 14147c478bd9Sstevel@tonic-gate if (*cpp == NULL) { 14157c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("getdeskey3 calling fetchcache3")); 14167c478bd9Sstevel@tonic-gate if (disk_caching && 14177c478bd9Sstevel@tonic-gate (cu = fetchcache3(uid, keylen, algtype)) != NULL) { 14187c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, 14197c478bd9Sstevel@tonic-gate ("getdeskey3 calling cache_retrieve")); 14207c478bd9Sstevel@tonic-gate if ((cachep = cache_retrieve(keylen, algtype, uid, 14217c478bd9Sstevel@tonic-gate public, cu->key)) != NULL) { 14227c478bd9Sstevel@tonic-gate if (cmpkeybuf3(cachep->secret, cu->secretkey)) { 14237c478bd9Sstevel@tonic-gate cached = 1; 14247c478bd9Sstevel@tonic-gate } else { 14257c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, 14267c478bd9Sstevel@tonic-gate ("getdeskey3 calling cache_remove")); 14277c478bd9Sstevel@tonic-gate cache_remove(keylen, algtype, 14287c478bd9Sstevel@tonic-gate uid, NULL); 14297c478bd9Sstevel@tonic-gate } 14307c478bd9Sstevel@tonic-gate } 14317c478bd9Sstevel@tonic-gate } 14327c478bd9Sstevel@tonic-gate if (cached) { 14337c478bd9Sstevel@tonic-gate cp = cachep; 14347c478bd9Sstevel@tonic-gate } else { 14357c478bd9Sstevel@tonic-gate if ((cp = (struct cachekey3_list *) 14367c478bd9Sstevel@tonic-gate malloc(sizeof (*cp))) == NULL) { 14377c478bd9Sstevel@tonic-gate mutex_unlock(&mp->ps_lock); 14387c478bd9Sstevel@tonic-gate debug(KEYSERV_INFO, 14397c478bd9Sstevel@tonic-gate ("getdeskey3 : malloc failed")); 14407c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 14417c478bd9Sstevel@tonic-gate "file %s line %d: malloc failed", 14427c478bd9Sstevel@tonic-gate __FILE__, __LINE__); 14437c478bd9Sstevel@tonic-gate return (0); 14447c478bd9Sstevel@tonic-gate } 14457c478bd9Sstevel@tonic-gate cp->refcnt = 0; 14467c478bd9Sstevel@tonic-gate cp->next = NULL; 14477c478bd9Sstevel@tonic-gate if ((cp->public = cpykeybuf3(public)) == NULL) { 14487c478bd9Sstevel@tonic-gate mutex_unlock(&mp->ps_lock); 14497c478bd9Sstevel@tonic-gate return (0); 14507c478bd9Sstevel@tonic-gate } 14517c478bd9Sstevel@tonic-gate if ((cp->secret = cpykeybuf3(secret)) == NULL) { 14527c478bd9Sstevel@tonic-gate mutex_unlock(&mp->ps_lock); 14537c478bd9Sstevel@tonic-gate return (0); 14547c478bd9Sstevel@tonic-gate } 14557c478bd9Sstevel@tonic-gate if (!setdeskeyarray(&cp->deskey, desarylen)) { 14567c478bd9Sstevel@tonic-gate mutex_unlock(&mp->ps_lock); 14577c478bd9Sstevel@tonic-gate return (0); 14587c478bd9Sstevel@tonic-gate } 14597c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("getdeskey3 %x %x %x", 14607c478bd9Sstevel@tonic-gate cp->public, cp->secret, 14617c478bd9Sstevel@tonic-gate cp->deskey.deskeyarray_val)); 14627c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, 14637c478bd9Sstevel@tonic-gate ("getdeskey3 calling __gen_common_dhkeys_g")); 14647c478bd9Sstevel@tonic-gate if (!__gen_common_dhkeys_g(public->keybuf3_val, 14657c478bd9Sstevel@tonic-gate secret->keybuf3_val, 14667c478bd9Sstevel@tonic-gate keylen, algtype, 14677c478bd9Sstevel@tonic-gate cp->deskey.deskeyarray_val, desarylen)) { 14687c478bd9Sstevel@tonic-gate mutex_unlock(&mp->ps_lock); 14697c478bd9Sstevel@tonic-gate return (0); 14707c478bd9Sstevel@tonic-gate } 14717c478bd9Sstevel@tonic-gate for (i = 0; i < desarylen; i++) { 14727c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, 14737c478bd9Sstevel@tonic-gate ("getdeskey3 gendh key : (%x,%x)", 14747c478bd9Sstevel@tonic-gate cp->deskey.deskeyarray_val[i].key.high, 14757c478bd9Sstevel@tonic-gate cp->deskey.deskeyarray_val[i].key.low)); 14767c478bd9Sstevel@tonic-gate } 14777c478bd9Sstevel@tonic-gate if (disk_caching && cu != NULL) { 14787c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, 14797c478bd9Sstevel@tonic-gate ("getdeskey3 calling cache_insert")); 14807c478bd9Sstevel@tonic-gate cache_insert(keylen, algtype, uid, cp->deskey, 14817c478bd9Sstevel@tonic-gate cu->key, public, secret); 14827c478bd9Sstevel@tonic-gate } 14837c478bd9Sstevel@tonic-gate } 14847c478bd9Sstevel@tonic-gate *cpp = cp; 14857c478bd9Sstevel@tonic-gate } else { 14867c478bd9Sstevel@tonic-gate cp = *cpp; 14877c478bd9Sstevel@tonic-gate } 14887c478bd9Sstevel@tonic-gate cp->refcnt++; 14897c478bd9Sstevel@tonic-gate mutex_unlock(&mp->ps_lock); 14907c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("getdeskey3 ret %x", cp)); 14917c478bd9Sstevel@tonic-gate return (cp); 14927c478bd9Sstevel@tonic-gate } 14937c478bd9Sstevel@tonic-gate 14947c478bd9Sstevel@tonic-gate keystatus 14957c478bd9Sstevel@tonic-gate pk_get_conv_key3(uid_t uid, deskeyarg3 *arg, cryptkeyres3 *res) 14967c478bd9Sstevel@tonic-gate { 14977c478bd9Sstevel@tonic-gate keybuf3 *xsecret, *xpublic; 14987c478bd9Sstevel@tonic-gate char zero[8]; 14997c478bd9Sstevel@tonic-gate struct cachekey3_list *cp; 15007c478bd9Sstevel@tonic-gate 15017c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, ("pk_get_conv_key3 %d %x %x", 15027c478bd9Sstevel@tonic-gate uid, arg, res)); 15037c478bd9Sstevel@tonic-gate if ((xsecret = fetchsecretkey3(uid, 15047c478bd9Sstevel@tonic-gate arg->keylen, arg->algtype)) == NULL) { 15057c478bd9Sstevel@tonic-gate if (nodefaultkeys) 15067c478bd9Sstevel@tonic-gate return (KEY_NOSECRET); 15077c478bd9Sstevel@tonic-gate memset(zero, 0, sizeof (zero)); 15087c478bd9Sstevel@tonic-gate if ((xsecret = getkeybuf3(arg->keylen/4+1)) == NULL) { 15097c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 15107c478bd9Sstevel@tonic-gate } 15117c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, 15127c478bd9Sstevel@tonic-gate ("pk_get_conv_key3 calling getsecretkey_g")); 15137c478bd9Sstevel@tonic-gate if (!getsecretkey_g("nobody", 15147c478bd9Sstevel@tonic-gate arg->keylen, arg->algtype, 15157c478bd9Sstevel@tonic-gate xsecret->keybuf3_val, xsecret->keybuf3_len, 15167c478bd9Sstevel@tonic-gate zero) || *xsecret->keybuf3_val == 0) { /* XXX */ 15177c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, 15187c478bd9Sstevel@tonic-gate ("pk_get_conv_key3 calling getsecretkey_g failed")); 15197c478bd9Sstevel@tonic-gate return (KEY_NOSECRET); 15207c478bd9Sstevel@tonic-gate } 15217c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, 15227c478bd9Sstevel@tonic-gate ("pk_get_conv_key3 calling getsecretkey_g succeeded")); 15237c478bd9Sstevel@tonic-gate } 15247c478bd9Sstevel@tonic-gate xpublic = &arg->pub_key; 15257c478bd9Sstevel@tonic-gate if ((cp = getdeskey3(arg->keylen, arg->algtype, arg->nkeys, 15267c478bd9Sstevel@tonic-gate xpublic, xsecret, uid)) == NULL) { 15277c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 15287c478bd9Sstevel@tonic-gate } 15297c478bd9Sstevel@tonic-gate storedeskeyarray(&res->cryptkeyres3_u.deskey, &cp->deskey); 15307c478bd9Sstevel@tonic-gate return (KEY_SUCCESS); 15317c478bd9Sstevel@tonic-gate } 15327c478bd9Sstevel@tonic-gate 15337c478bd9Sstevel@tonic-gate /* 15347c478bd9Sstevel@tonic-gate * Do the work of pk_encrypt3 && pk_decrypt3 15357c478bd9Sstevel@tonic-gate */ 15367c478bd9Sstevel@tonic-gate static keystatus 15377c478bd9Sstevel@tonic-gate pk_crypt3( 15387c478bd9Sstevel@tonic-gate uid_t uid, 15397c478bd9Sstevel@tonic-gate cryptkeyarg3 *arg, 15407c478bd9Sstevel@tonic-gate deskeyarray *key, 15417c478bd9Sstevel@tonic-gate int mode 15427c478bd9Sstevel@tonic-gate ) 15437c478bd9Sstevel@tonic-gate { 15447c478bd9Sstevel@tonic-gate keybuf3 *xsecret = NULL, *xpublic = NULL; 15457c478bd9Sstevel@tonic-gate char zero[8]; 15467c478bd9Sstevel@tonic-gate struct cachekey3_list *cp; 15477c478bd9Sstevel@tonic-gate int err; 15487c478bd9Sstevel@tonic-gate int xsecret_alloc = 0; 15497c478bd9Sstevel@tonic-gate char ivec[8]; 15507c478bd9Sstevel@tonic-gate 15517c478bd9Sstevel@tonic-gate memset(ivec, 0, 8); 15527c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG1, ("pk_crypt3 %d %x %x %d", 15537c478bd9Sstevel@tonic-gate uid, arg, key, mode)); 15547c478bd9Sstevel@tonic-gate if ((xsecret = fetchsecretkey3(uid, 15557c478bd9Sstevel@tonic-gate arg->keylen, arg->algtype)) == NULL) { 15567c478bd9Sstevel@tonic-gate if (nodefaultkeys) 15577c478bd9Sstevel@tonic-gate return (KEY_NOSECRET); 15587c478bd9Sstevel@tonic-gate memset(zero, 0, sizeof (zero)); 15597c478bd9Sstevel@tonic-gate if ((xsecret = getkeybuf3(arg->keylen/4+1)) == NULL) { 15607c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 15617c478bd9Sstevel@tonic-gate } 15627c478bd9Sstevel@tonic-gate xsecret_alloc = 1; 15637c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG1, ("pk_crypt3 calling getsecretkey_g")); 15647c478bd9Sstevel@tonic-gate if (!getsecretkey_g("nobody", 15657c478bd9Sstevel@tonic-gate arg->keylen, arg->algtype, 15667c478bd9Sstevel@tonic-gate xsecret->keybuf3_val, xsecret->keybuf3_len, 15677c478bd9Sstevel@tonic-gate zero) || *xsecret->keybuf3_val == 0) { /* XXX */ 15687c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, 15697c478bd9Sstevel@tonic-gate ("pk_crypt3 calling getsecretkey_g failed")); 15707c478bd9Sstevel@tonic-gate freekeybuf3(xsecret); 15717c478bd9Sstevel@tonic-gate return (KEY_NOSECRET); 15727c478bd9Sstevel@tonic-gate } 15737c478bd9Sstevel@tonic-gate /* XXX optimize to cache nobody's secret key? */ 15747c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, 15757c478bd9Sstevel@tonic-gate ("pk_crypt3 calling getsecretkey_g succeeded")); 15767c478bd9Sstevel@tonic-gate } 15777c478bd9Sstevel@tonic-gate if (arg->remotekey.keybuf3_len) { 15787c478bd9Sstevel@tonic-gate if ((xpublic = cpykeybuf3(&arg->remotekey)) == NULL) { 15797c478bd9Sstevel@tonic-gate if (xsecret_alloc) freekeybuf3(xsecret); 15807c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 15817c478bd9Sstevel@tonic-gate } 15827c478bd9Sstevel@tonic-gate } else { 15837c478bd9Sstevel@tonic-gate if ((xpublic = getkeybuf3(arg->keylen/4+1)) == NULL) { 15847c478bd9Sstevel@tonic-gate if (xsecret_alloc) freekeybuf3(xsecret); 15857c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 15867c478bd9Sstevel@tonic-gate } 15877c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG1, ("pk_crypt3 calling getpublickey_g")); 15887c478bd9Sstevel@tonic-gate if (!getpublickey_g(arg->remotename, 15897c478bd9Sstevel@tonic-gate arg->keylen, arg->algtype, 15907c478bd9Sstevel@tonic-gate xpublic->keybuf3_val, xpublic->keybuf3_len)) { 15917c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, 15927c478bd9Sstevel@tonic-gate ("pk_crypt3 calling getpublickey_g nobody")); 15937c478bd9Sstevel@tonic-gate if (nodefaultkeys || !getpublickey_g("nobody", 15947c478bd9Sstevel@tonic-gate arg->keylen, arg->algtype, 15957c478bd9Sstevel@tonic-gate xpublic->keybuf3_val, xpublic->keybuf3_len)) { 15967c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, 15977c478bd9Sstevel@tonic-gate ("pk_crypt3 calling getpublickey_g nobody failed")); 15987c478bd9Sstevel@tonic-gate if (xsecret_alloc) freekeybuf3(xsecret); 15997c478bd9Sstevel@tonic-gate freekeybuf3(xpublic); 16007c478bd9Sstevel@tonic-gate return (KEY_UNKNOWN); 16017c478bd9Sstevel@tonic-gate } 16027c478bd9Sstevel@tonic-gate } 16037c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG0, 16047c478bd9Sstevel@tonic-gate ("pk_crypt3 calling getpublickey_g succeeded")); 16057c478bd9Sstevel@tonic-gate } 16067c478bd9Sstevel@tonic-gate 16077c478bd9Sstevel@tonic-gate if ((cp = getdeskey3(arg->keylen, arg->algtype, 16087c478bd9Sstevel@tonic-gate arg->deskey.deskeyarray_len, xpublic, xsecret, uid)) == NULL) { 16097c478bd9Sstevel@tonic-gate if (xsecret_alloc) freekeybuf3(xsecret); 16107c478bd9Sstevel@tonic-gate freekeybuf3(xpublic); 16117c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 16127c478bd9Sstevel@tonic-gate } 16137c478bd9Sstevel@tonic-gate storedeskeyarray(key, &arg->deskey); 16147c478bd9Sstevel@tonic-gate if (CLASSIC_PK_DH(arg->keylen, arg->algtype)) { 16157c478bd9Sstevel@tonic-gate /*EMPTY*/ 16167c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG1, 16177c478bd9Sstevel@tonic-gate ("pk_crypt3 WARNING received 192-bit key")); 16187c478bd9Sstevel@tonic-gate } else { 16197c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, 16207c478bd9Sstevel@tonic-gate ("pk_crypt3 calling __cbc_triple_crypt")); 16217c478bd9Sstevel@tonic-gate err = __cbc_triple_crypt(cp->deskey.deskeyarray_val, 16227c478bd9Sstevel@tonic-gate (char *)key->deskeyarray_val, 16237c478bd9Sstevel@tonic-gate cp->deskey.deskeyarray_len*sizeof (des_block), 16247c478bd9Sstevel@tonic-gate DES_HW | mode, ivec); 16257c478bd9Sstevel@tonic-gate if (DES_FAILED(err)) { 16267c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, 16277c478bd9Sstevel@tonic-gate ("pk_crypt3 calling ecb_crypt/__cbc_triple_crypt failed")); 16287c478bd9Sstevel@tonic-gate if (xsecret_alloc) freekeybuf3(xsecret); 16297c478bd9Sstevel@tonic-gate freekeybuf3(xpublic); 16307c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 16317c478bd9Sstevel@tonic-gate } 16327c478bd9Sstevel@tonic-gate debug(KEYSERV_DEBUG, 16337c478bd9Sstevel@tonic-gate ("pk_crypt3 calling __cbc_triple_crypt succeeded")); 16347c478bd9Sstevel@tonic-gate } 16357c478bd9Sstevel@tonic-gate if (xsecret_alloc) freekeybuf3(xsecret); 16367c478bd9Sstevel@tonic-gate freekeybuf3(xpublic); 16377c478bd9Sstevel@tonic-gate return (KEY_SUCCESS); 16387c478bd9Sstevel@tonic-gate } 16397c478bd9Sstevel@tonic-gate 16407c478bd9Sstevel@tonic-gate keystatus 16417c478bd9Sstevel@tonic-gate pk_get_conv_key(uid, pubkey, result) 16427c478bd9Sstevel@tonic-gate uid_t uid; 16437c478bd9Sstevel@tonic-gate keybuf pubkey; 16447c478bd9Sstevel@tonic-gate cryptkeyres *result; 16457c478bd9Sstevel@tonic-gate { 16467c478bd9Sstevel@tonic-gate char xsecret[1024]; 16477c478bd9Sstevel@tonic-gate char xpublic[1024]; 16487c478bd9Sstevel@tonic-gate MINT *public; 16497c478bd9Sstevel@tonic-gate MINT *secret; 16507c478bd9Sstevel@tonic-gate MINT *common; 16517c478bd9Sstevel@tonic-gate char zero[8]; 16527c478bd9Sstevel@tonic-gate int hash; 16537c478bd9Sstevel@tonic-gate 16547c478bd9Sstevel@tonic-gate if (!fetchsecretkey(uid, xsecret) || xsecret[0] == 0) { 16557c478bd9Sstevel@tonic-gate memset(zero, 0, sizeof (zero)); 16567c478bd9Sstevel@tonic-gate if (nodefaultkeys) 16577c478bd9Sstevel@tonic-gate return (KEY_NOSECRET); 16587c478bd9Sstevel@tonic-gate 16597c478bd9Sstevel@tonic-gate if (!getsecretkey("nobody", xsecret, zero) || 16607c478bd9Sstevel@tonic-gate xsecret[0] == 0) 16617c478bd9Sstevel@tonic-gate return (KEY_NOSECRET); 16627c478bd9Sstevel@tonic-gate } 16637c478bd9Sstevel@tonic-gate 16647c478bd9Sstevel@tonic-gate memcpy(xpublic, pubkey, sizeof (keybuf)); 16657c478bd9Sstevel@tonic-gate xsecret[HEXKEYBYTES] = '\0'; 16667c478bd9Sstevel@tonic-gate xpublic[HEXKEYBYTES] = '\0'; 16677c478bd9Sstevel@tonic-gate 16687c478bd9Sstevel@tonic-gate hash = hash_keys(xpublic, xsecret); 16697c478bd9Sstevel@tonic-gate (void) rw_rdlock(&g_cachedkeys_lock); 16707c478bd9Sstevel@tonic-gate if (!readcache(xpublic, xsecret, &result->cryptkeyres_u.deskey, hash)) { 16717c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_cachedkeys_lock); 16727c478bd9Sstevel@tonic-gate (void) rw_wrlock(&g_cachedkeys_lock); 16737c478bd9Sstevel@tonic-gate if (!readcache(xpublic, xsecret, &result->cryptkeyres_u.deskey, 16747c478bd9Sstevel@tonic-gate hash)) { 16757c478bd9Sstevel@tonic-gate public = mp_xtom(xpublic); 16767c478bd9Sstevel@tonic-gate secret = mp_xtom(xsecret); 16777c478bd9Sstevel@tonic-gate /* Sanity Check on public and private keys */ 16787c478bd9Sstevel@tonic-gate if (public == NULL || secret == NULL) { 16797c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_cachedkeys_lock); 16807c478bd9Sstevel@tonic-gate return (KEY_SYSTEMERR); 16817c478bd9Sstevel@tonic-gate } 16827c478bd9Sstevel@tonic-gate common = mp_itom(0); 16837c478bd9Sstevel@tonic-gate mp_pow(public, secret, MODULUS, common); 16847c478bd9Sstevel@tonic-gate extractdeskey(common, &result->cryptkeyres_u.deskey); 16857c478bd9Sstevel@tonic-gate writecache(xpublic, xsecret, 16867c478bd9Sstevel@tonic-gate &result->cryptkeyres_u.deskey, hash); 16877c478bd9Sstevel@tonic-gate mp_mfree(secret); 16887c478bd9Sstevel@tonic-gate mp_mfree(public); 16897c478bd9Sstevel@tonic-gate mp_mfree(common); 16907c478bd9Sstevel@tonic-gate } 16917c478bd9Sstevel@tonic-gate } 16927c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_cachedkeys_lock); 16937c478bd9Sstevel@tonic-gate 16947c478bd9Sstevel@tonic-gate return (KEY_SUCCESS); 16957c478bd9Sstevel@tonic-gate } 16967c478bd9Sstevel@tonic-gate 16977c478bd9Sstevel@tonic-gate #define findsec(sec, list) \ 16987c478bd9Sstevel@tonic-gate (memcmp(sec, (list)->secret, sizeof (keybuf)) == 0) 16997c478bd9Sstevel@tonic-gate 17007c478bd9Sstevel@tonic-gate /* 17017c478bd9Sstevel@tonic-gate * Remove common keys from the cache. 17027c478bd9Sstevel@tonic-gate */ 1703*49e7ca49Speteh static int 17047c478bd9Sstevel@tonic-gate removecache(sec) 17057c478bd9Sstevel@tonic-gate char *sec; 17067c478bd9Sstevel@tonic-gate { 17077c478bd9Sstevel@tonic-gate struct cachekey_list *found; 17087c478bd9Sstevel@tonic-gate register struct cachekey_list **l; 17097c478bd9Sstevel@tonic-gate int i; 17107c478bd9Sstevel@tonic-gate 17117c478bd9Sstevel@tonic-gate (void) rw_wrlock(&g_cachedkeys_lock); 17127c478bd9Sstevel@tonic-gate for (i = 0; i < KEY_HASH_SIZE; i++) { 17137c478bd9Sstevel@tonic-gate for (l = &g_cachedkeys[i]; (*l) != NULL; ) { 17147c478bd9Sstevel@tonic-gate if (findsec(sec, *l)) { 17157c478bd9Sstevel@tonic-gate found = *l; 17167c478bd9Sstevel@tonic-gate *l = (*l)->next; 17177c478bd9Sstevel@tonic-gate memset((char *)found, 0, 17187c478bd9Sstevel@tonic-gate sizeof (struct cachekey_list)); 17197c478bd9Sstevel@tonic-gate free(found); 17207c478bd9Sstevel@tonic-gate } else { 17217c478bd9Sstevel@tonic-gate l = &(*l)->next; 17227c478bd9Sstevel@tonic-gate } 17237c478bd9Sstevel@tonic-gate } 17247c478bd9Sstevel@tonic-gate } 17257c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_cachedkeys_lock); 17267c478bd9Sstevel@tonic-gate return (1); 17277c478bd9Sstevel@tonic-gate } 17287c478bd9Sstevel@tonic-gate 17297c478bd9Sstevel@tonic-gate /* 17307c478bd9Sstevel@tonic-gate * Store the secretkey for this uid 17317c478bd9Sstevel@tonic-gate */ 1732*49e7ca49Speteh int 17337c478bd9Sstevel@tonic-gate storesecretkey(uid, key) 17347c478bd9Sstevel@tonic-gate uid_t uid; 17357c478bd9Sstevel@tonic-gate keybuf key; 17367c478bd9Sstevel@tonic-gate { 17377c478bd9Sstevel@tonic-gate struct secretkey_netname_list *new; 17387c478bd9Sstevel@tonic-gate struct secretkey_netname_list **l; 17397c478bd9Sstevel@tonic-gate int hash = HASH_UID(uid); 17407c478bd9Sstevel@tonic-gate 17417c478bd9Sstevel@tonic-gate (void) rw_wrlock(&g_secretkey_netname_lock); 17427c478bd9Sstevel@tonic-gate for (l = &g_secretkey_netname[hash]; *l != NULL && (*l)->uid != uid; 17437c478bd9Sstevel@tonic-gate l = &(*l)->next) { 17447c478bd9Sstevel@tonic-gate } 17457c478bd9Sstevel@tonic-gate if (*l == NULL) { 17467c478bd9Sstevel@tonic-gate if (key[0] == '\0') { 17477c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_secretkey_netname_lock); 17487c478bd9Sstevel@tonic-gate return (0); 17497c478bd9Sstevel@tonic-gate } 17507c478bd9Sstevel@tonic-gate new = (struct secretkey_netname_list *)malloc(sizeof (*new)); 17517c478bd9Sstevel@tonic-gate if (new == NULL) { 17527c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_secretkey_netname_lock); 17537c478bd9Sstevel@tonic-gate return (0); 17547c478bd9Sstevel@tonic-gate } 17557c478bd9Sstevel@tonic-gate new->uid = uid; 17567c478bd9Sstevel@tonic-gate new->sc_flag = KEY_ONLY; 17577c478bd9Sstevel@tonic-gate memset(new->keynetdata.st_pub_key, 0, HEXKEYBYTES); 17587c478bd9Sstevel@tonic-gate new->keynetdata.st_netname = NULL; 17597c478bd9Sstevel@tonic-gate new->next = NULL; 17607c478bd9Sstevel@tonic-gate *l = new; 17617c478bd9Sstevel@tonic-gate } else { 17627c478bd9Sstevel@tonic-gate new = *l; 17637c478bd9Sstevel@tonic-gate if (key[0] == '\0') 17647c478bd9Sstevel@tonic-gate removecache(new->keynetdata.st_priv_key); 17657c478bd9Sstevel@tonic-gate } 17667c478bd9Sstevel@tonic-gate 17677c478bd9Sstevel@tonic-gate memcpy(new->keynetdata.st_priv_key, key, 17687c478bd9Sstevel@tonic-gate HEXKEYBYTES); 17697c478bd9Sstevel@tonic-gate (void) rw_unlock(&g_secretkey_netname_lock); 17707c478bd9Sstevel@tonic-gate return (1); 17717c478bd9Sstevel@tonic-gate } 17727c478bd9Sstevel@tonic-gate 1773*49e7ca49Speteh static int 17747c478bd9Sstevel@tonic-gate hexdigit(val) 17757c478bd9Sstevel@tonic-gate int val; 17767c478bd9Sstevel@tonic-gate { 17777c478bd9Sstevel@tonic-gate return ("0123456789abcdef"[val]); 17787c478bd9Sstevel@tonic-gate } 17797c478bd9Sstevel@tonic-gate 1780*49e7ca49Speteh int 17817c478bd9Sstevel@tonic-gate bin2hex(bin, hex, size) 17827c478bd9Sstevel@tonic-gate unsigned char *bin; 17837c478bd9Sstevel@tonic-gate unsigned char *hex; 17847c478bd9Sstevel@tonic-gate int size; 17857c478bd9Sstevel@tonic-gate { 17867c478bd9Sstevel@tonic-gate int i; 17877c478bd9Sstevel@tonic-gate 17887c478bd9Sstevel@tonic-gate for (i = 0; i < size; i++) { 17897c478bd9Sstevel@tonic-gate *hex++ = hexdigit(*bin >> 4); 17907c478bd9Sstevel@tonic-gate *hex++ = hexdigit(*bin++ & 0xf); 17917c478bd9Sstevel@tonic-gate } 17927c478bd9Sstevel@tonic-gate return (0); 17937c478bd9Sstevel@tonic-gate } 17947c478bd9Sstevel@tonic-gate 1795*49e7ca49Speteh static int 17967c478bd9Sstevel@tonic-gate hexval(dig) 17977c478bd9Sstevel@tonic-gate char dig; 17987c478bd9Sstevel@tonic-gate { 17997c478bd9Sstevel@tonic-gate if ('0' <= dig && dig <= '9') { 18007c478bd9Sstevel@tonic-gate return (dig - '0'); 18017c478bd9Sstevel@tonic-gate } else if ('a' <= dig && dig <= 'f') { 18027c478bd9Sstevel@tonic-gate return (dig - 'a' + 10); 18037c478bd9Sstevel@tonic-gate } else if ('A' <= dig && dig <= 'F') { 18047c478bd9Sstevel@tonic-gate return (dig - 'A' + 10); 18057c478bd9Sstevel@tonic-gate } else { 18067c478bd9Sstevel@tonic-gate return (-1); 18077c478bd9Sstevel@tonic-gate } 18087c478bd9Sstevel@tonic-gate } 18097c478bd9Sstevel@tonic-gate 1810*49e7ca49Speteh int 18117c478bd9Sstevel@tonic-gate hex2bin(hex, bin, size) 18127c478bd9Sstevel@tonic-gate unsigned char *hex; 18137c478bd9Sstevel@tonic-gate unsigned char *bin; 18147c478bd9Sstevel@tonic-gate int size; 18157c478bd9Sstevel@tonic-gate { 18167c478bd9Sstevel@tonic-gate int i; 18177c478bd9Sstevel@tonic-gate 18187c478bd9Sstevel@tonic-gate for (i = 0; i < size; i++) { 18197c478bd9Sstevel@tonic-gate *bin = hexval(*hex++) << 4; 18207c478bd9Sstevel@tonic-gate *bin++ |= hexval(*hex++); 18217c478bd9Sstevel@tonic-gate } 18227c478bd9Sstevel@tonic-gate return (0); 18237c478bd9Sstevel@tonic-gate } 18247c478bd9Sstevel@tonic-gate 18257c478bd9Sstevel@tonic-gate static int 18267c478bd9Sstevel@tonic-gate hash_keys(pub, sec) 18277c478bd9Sstevel@tonic-gate char *pub; 18287c478bd9Sstevel@tonic-gate char *sec; 18297c478bd9Sstevel@tonic-gate { 18307c478bd9Sstevel@tonic-gate int i; 18317c478bd9Sstevel@tonic-gate int hash = 0; 18327c478bd9Sstevel@tonic-gate 18337c478bd9Sstevel@tonic-gate for (i = 0; i < HEXKEYBYTES; i += 6, pub += 6, sec += 6) { 18347c478bd9Sstevel@tonic-gate hash ^= *pub; 18357c478bd9Sstevel@tonic-gate hash ^= *sec; 18367c478bd9Sstevel@tonic-gate } 18377c478bd9Sstevel@tonic-gate return (hash & 0xff); 18387c478bd9Sstevel@tonic-gate } 18397c478bd9Sstevel@tonic-gate 18407c478bd9Sstevel@tonic-gate /* 18417c478bd9Sstevel@tonic-gate * problem: keyserv loads keys from /etc/.rootkey based on nisauthconf(1M) 18427c478bd9Sstevel@tonic-gate * which is too nis+-centric (see secure_rpc(3N)). 18437c478bd9Sstevel@tonic-gate * 18447c478bd9Sstevel@tonic-gate * So we want to make sure there is always a AUTH_DES compat entry 18457c478bd9Sstevel@tonic-gate * in the "list" of nis+ mechs so that the 192bit key always gets loaded so 18467c478bd9Sstevel@tonic-gate * non-nis+ services that use AUTH_DES (e.g. nfs) won't get hosed. The real 18477c478bd9Sstevel@tonic-gate * hacky part of it is we muck with the array returned from 18487c478bd9Sstevel@tonic-gate * __nis_get_mechanisms which we really don't have any business 18497c478bd9Sstevel@tonic-gate * doing cause we should not know/care how that is implemented. A better 18507c478bd9Sstevel@tonic-gate * way would be to change the __nis_get_mechanisms interface or add another 18517c478bd9Sstevel@tonic-gate * one similiar to it that forces the "des" compat entry into the list. 18527c478bd9Sstevel@tonic-gate * 18537c478bd9Sstevel@tonic-gate * Return ptr to mechs array on success, else NULL on memory errs. 18547c478bd9Sstevel@tonic-gate */ 18557c478bd9Sstevel@tonic-gate mechanism_t ** 18567c478bd9Sstevel@tonic-gate getmechwrap() 18577c478bd9Sstevel@tonic-gate { 18587c478bd9Sstevel@tonic-gate mechanism_t **mechs = __nis_get_mechanisms(FALSE); 18597c478bd9Sstevel@tonic-gate mechanism_t **mechsbak = NULL; 18607c478bd9Sstevel@tonic-gate mechanism_t *desmech = NULL; 18617c478bd9Sstevel@tonic-gate int i = 0; 18627c478bd9Sstevel@tonic-gate 18637c478bd9Sstevel@tonic-gate if (mechs) { 18647c478bd9Sstevel@tonic-gate /* got some valid mechs and possibly the AUTH_DES compat one */ 18657c478bd9Sstevel@tonic-gate for (i = 0; mechs[i]; i++) { 18667c478bd9Sstevel@tonic-gate if (AUTH_DES_COMPAT_CHK(mechs[i])) 18677c478bd9Sstevel@tonic-gate return (mechs); 18687c478bd9Sstevel@tonic-gate } 18697c478bd9Sstevel@tonic-gate /* i == number of ptrs not counting terminating NULL */ 18707c478bd9Sstevel@tonic-gate } 18717c478bd9Sstevel@tonic-gate 18727c478bd9Sstevel@tonic-gate /* AUTH_DES compat entry not found, let's add it */ 18737c478bd9Sstevel@tonic-gate if ((desmech = malloc(sizeof (mechanism_t))) == NULL) { 18747c478bd9Sstevel@tonic-gate if (mechs) 18757c478bd9Sstevel@tonic-gate __nis_release_mechanisms(mechs); 18767c478bd9Sstevel@tonic-gate return (NULL); 18777c478bd9Sstevel@tonic-gate } 18787c478bd9Sstevel@tonic-gate desmech->mechname = NULL; 18797c478bd9Sstevel@tonic-gate desmech->alias = NIS_SEC_CF_DES_ALIAS; 18807c478bd9Sstevel@tonic-gate desmech->keylen = AUTH_DES_KEYLEN; 18817c478bd9Sstevel@tonic-gate desmech->algtype = AUTH_DES_ALGTYPE; 18827c478bd9Sstevel@tonic-gate desmech->qop = NULL; 18837c478bd9Sstevel@tonic-gate desmech->secserv = rpc_gss_svc_default; 18847c478bd9Sstevel@tonic-gate 18857c478bd9Sstevel@tonic-gate mechsbak = mechs; 18867c478bd9Sstevel@tonic-gate /* mechs == NULL and i == 0 is valid "no mechs configed" case */ 18877c478bd9Sstevel@tonic-gate if ((mechs = (mechanism_t **)realloc(mechs, 18887c478bd9Sstevel@tonic-gate sizeof (mechanism_t *) * (i + 2))) == NULL) { 18897c478bd9Sstevel@tonic-gate if (mechsbak) 18907c478bd9Sstevel@tonic-gate __nis_release_mechanisms(mechsbak); 18917c478bd9Sstevel@tonic-gate free(desmech); 18927c478bd9Sstevel@tonic-gate return (NULL); 18937c478bd9Sstevel@tonic-gate } 18947c478bd9Sstevel@tonic-gate mechs[i] = desmech; 18957c478bd9Sstevel@tonic-gate mechs[i+1] = NULL; 18967c478bd9Sstevel@tonic-gate 18977c478bd9Sstevel@tonic-gate return (mechs); 18987c478bd9Sstevel@tonic-gate } 18997c478bd9Sstevel@tonic-gate 19007c478bd9Sstevel@tonic-gate int 19017c478bd9Sstevel@tonic-gate init_mechs() 19027c478bd9Sstevel@tonic-gate { 19037c478bd9Sstevel@tonic-gate int nmechs, oldmechseen; 19047c478bd9Sstevel@tonic-gate mechanism_t **mechpp; 19057c478bd9Sstevel@tonic-gate char **cpp; 19067c478bd9Sstevel@tonic-gate 19077c478bd9Sstevel@tonic-gate if (!(mechs = getmechwrap())) 19087c478bd9Sstevel@tonic-gate return (-1); 19097c478bd9Sstevel@tonic-gate 19107c478bd9Sstevel@tonic-gate /* 19117c478bd9Sstevel@tonic-gate * find how many mechanisms were specified and also 19127c478bd9Sstevel@tonic-gate * setup the mechanism table for unique keylen/algtype pair 19137c478bd9Sstevel@tonic-gate */ 19147c478bd9Sstevel@tonic-gate nmechs = 0; 19157c478bd9Sstevel@tonic-gate for (mechpp = mechs; *mechpp != NULL; mechpp++) { 19167c478bd9Sstevel@tonic-gate struct keylenlist **kpp; 19177c478bd9Sstevel@tonic-gate struct algtypelist **app; 19187c478bd9Sstevel@tonic-gate 19197c478bd9Sstevel@tonic-gate nmechs++; 19207c478bd9Sstevel@tonic-gate if (((*mechpp)->keylen < 0) || ((*mechpp)->algtype < 0)) { 19217c478bd9Sstevel@tonic-gate continue; 19227c478bd9Sstevel@tonic-gate } 19237c478bd9Sstevel@tonic-gate kpp = getkeylen((*mechpp)->keylen); 19247c478bd9Sstevel@tonic-gate appendkeylist(kpp, (*mechpp)->keylen); 19257c478bd9Sstevel@tonic-gate app = getalgtype(kpp, (*mechpp)->algtype); 19267c478bd9Sstevel@tonic-gate appendalgtype(app, (*mechpp)->algtype); 19277c478bd9Sstevel@tonic-gate } 19287c478bd9Sstevel@tonic-gate 19297c478bd9Sstevel@tonic-gate /* 19307c478bd9Sstevel@tonic-gate * set of mechs for getsubopt() 19317c478bd9Sstevel@tonic-gate */ 19327c478bd9Sstevel@tonic-gate cache_options = (char **)calloc((size_t)nmechs + 1, 19337c478bd9Sstevel@tonic-gate sizeof (*cache_options)); 19347c478bd9Sstevel@tonic-gate if (cache_options == NULL) { 19357c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "unable to allocate option array"); 19367c478bd9Sstevel@tonic-gate return (-1); 19377c478bd9Sstevel@tonic-gate } 19387c478bd9Sstevel@tonic-gate /* 19397c478bd9Sstevel@tonic-gate * cache sizes 19407c478bd9Sstevel@tonic-gate */ 19417c478bd9Sstevel@tonic-gate cache_size = (int *)calloc((size_t)nmechs, sizeof (int)); 19427c478bd9Sstevel@tonic-gate if (cache_size == NULL) { 19437c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "unable to allocate cache array"); 19447c478bd9Sstevel@tonic-gate return (-1); 19457c478bd9Sstevel@tonic-gate } 19467c478bd9Sstevel@tonic-gate 19477c478bd9Sstevel@tonic-gate oldmechseen = 0; 19487c478bd9Sstevel@tonic-gate cpp = cache_options; 19497c478bd9Sstevel@tonic-gate for (mechpp = mechs; *mechpp != NULL; mechpp++) { 19507c478bd9Sstevel@tonic-gate /* 19517c478bd9Sstevel@tonic-gate * usual case: a DH-style mechanism type, with an alias 19527c478bd9Sstevel@tonic-gate */ 19537c478bd9Sstevel@tonic-gate if ((*mechpp)->mechname != NULL && 19547c478bd9Sstevel@tonic-gate strncmp((*mechpp)->mechname, DHMECHSTR, 19557c478bd9Sstevel@tonic-gate strlen(DHMECHSTR)) == 0 && 19567c478bd9Sstevel@tonic-gate (*mechpp)->alias != NULL) { 19577c478bd9Sstevel@tonic-gate /* 19587c478bd9Sstevel@tonic-gate * Is this trad 192-DH? already added? 19597c478bd9Sstevel@tonic-gate */ 19607c478bd9Sstevel@tonic-gate if (strcmp((*mechpp)->alias, DESALIAS) == 0) { 19617c478bd9Sstevel@tonic-gate if (oldmechseen) { 19627c478bd9Sstevel@tonic-gate continue; 19637c478bd9Sstevel@tonic-gate } 19647c478bd9Sstevel@tonic-gate oldmechseen++; 19657c478bd9Sstevel@tonic-gate } 19667c478bd9Sstevel@tonic-gate 19677c478bd9Sstevel@tonic-gate *cpp++ = (*mechpp)->alias; 19687c478bd9Sstevel@tonic-gate continue; 19697c478bd9Sstevel@tonic-gate } 19707c478bd9Sstevel@tonic-gate 19717c478bd9Sstevel@tonic-gate /* 19727c478bd9Sstevel@tonic-gate * HACK: we recognise a special alias for traditional 19737c478bd9Sstevel@tonic-gate * 192-bit DH, unless the latter has already been mentioned 19747c478bd9Sstevel@tonic-gate * in it's full form 19757c478bd9Sstevel@tonic-gate */ 19767c478bd9Sstevel@tonic-gate if ((*mechpp)->mechname == NULL && (*mechpp)->alias != NULL && 19777c478bd9Sstevel@tonic-gate strcmp((*mechpp)->alias, DES) == 0 && !oldmechseen) { 19787c478bd9Sstevel@tonic-gate *cpp++ = DESALIAS; 19797c478bd9Sstevel@tonic-gate oldmechseen++; 19807c478bd9Sstevel@tonic-gate continue; 19817c478bd9Sstevel@tonic-gate } 19827c478bd9Sstevel@tonic-gate 19837c478bd9Sstevel@tonic-gate /* 19847c478bd9Sstevel@tonic-gate * Ignore anything else 19857c478bd9Sstevel@tonic-gate */ 19867c478bd9Sstevel@tonic-gate } 19877c478bd9Sstevel@tonic-gate 19887c478bd9Sstevel@tonic-gate /* Terminate the options list */ 19897c478bd9Sstevel@tonic-gate *cpp = NULL; 19907c478bd9Sstevel@tonic-gate 19917c478bd9Sstevel@tonic-gate return (0); 19927c478bd9Sstevel@tonic-gate } 1993