1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate #include <strings.h> 29*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 30*7c478bd9Sstevel@tonic-gate #include <errno.h> 31*7c478bd9Sstevel@tonic-gate #include <libintl.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/wanboot_impl.h> 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate #include "key_xdr.h" 35*7c478bd9Sstevel@tonic-gate #include "key_util.h" 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate /* 38*7c478bd9Sstevel@tonic-gate * Size of 'empty' pkcs12 key file (with no key in it) plus 1 39*7c478bd9Sstevel@tonic-gate * This is the minimum length for our RSA keys, because we 40*7c478bd9Sstevel@tonic-gate * only use RSA keys that are stored in PKCS12 format. 41*7c478bd9Sstevel@tonic-gate */ 42*7c478bd9Sstevel@tonic-gate #define PKCS12_MIN_LEN 76 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate /* 45*7c478bd9Sstevel@tonic-gate * Program name to be used by wbku_printerr() 46*7c478bd9Sstevel@tonic-gate */ 47*7c478bd9Sstevel@tonic-gate static const char *wbku_pname = NULL; 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate /* 50*7c478bd9Sstevel@tonic-gate * Note: must be kept in sync with codes in <key_util.h> 51*7c478bd9Sstevel@tonic-gate */ 52*7c478bd9Sstevel@tonic-gate static char *wbku_retmsgs[WBKU_NRET] = { 53*7c478bd9Sstevel@tonic-gate /* 0 WBKU_SUCCESS */ "Success", 54*7c478bd9Sstevel@tonic-gate /* 1 WBKU_INTERNAL_ERR */ "Internal error", 55*7c478bd9Sstevel@tonic-gate /* 2 WBKU_WRITE_ERR */ "Keystore write error", 56*7c478bd9Sstevel@tonic-gate /* 3 WBKU_NOKEY */ "Key does not exist in keystore", 57*7c478bd9Sstevel@tonic-gate /* 4 WBKU_BAD_KEYTYPE */ "Invalid keytype specified" 58*7c478bd9Sstevel@tonic-gate }; 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate /* 61*7c478bd9Sstevel@tonic-gate * Initialize library for calls to wbku_printerr(). 62*7c478bd9Sstevel@tonic-gate */ 63*7c478bd9Sstevel@tonic-gate void 64*7c478bd9Sstevel@tonic-gate wbku_errinit(const char *arg0) 65*7c478bd9Sstevel@tonic-gate { 66*7c478bd9Sstevel@tonic-gate wbku_pname = strrchr(arg0, '/'); 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate if (wbku_pname == NULL) 69*7c478bd9Sstevel@tonic-gate wbku_pname = arg0; 70*7c478bd9Sstevel@tonic-gate else 71*7c478bd9Sstevel@tonic-gate wbku_pname++; 72*7c478bd9Sstevel@tonic-gate } 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate /* 75*7c478bd9Sstevel@tonic-gate * Print an error message to standard error and optionally 76*7c478bd9Sstevel@tonic-gate * append a system error. 77*7c478bd9Sstevel@tonic-gate */ 78*7c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/ 79*7c478bd9Sstevel@tonic-gate void 80*7c478bd9Sstevel@tonic-gate wbku_printerr(const char *format, ...) 81*7c478bd9Sstevel@tonic-gate { 82*7c478bd9Sstevel@tonic-gate int err = errno; 83*7c478bd9Sstevel@tonic-gate va_list ap; 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate if (wbku_pname != NULL) 86*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: ", wbku_pname); 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate /* 89*7c478bd9Sstevel@tonic-gate * Note that gettext() is used in order to obtain the 90*7c478bd9Sstevel@tonic-gate * message from the consumer's domain. 91*7c478bd9Sstevel@tonic-gate */ 92*7c478bd9Sstevel@tonic-gate va_start(ap, format); 93*7c478bd9Sstevel@tonic-gate (void) vfprintf(stderr, gettext(format), ap); 94*7c478bd9Sstevel@tonic-gate va_end(ap); 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate if (strchr(format, '\n') == NULL) 97*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, ": %s\n", strerror(err)); 98*7c478bd9Sstevel@tonic-gate } 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate /* 101*7c478bd9Sstevel@tonic-gate * Return the appropriate message for a given WBKU return code. 102*7c478bd9Sstevel@tonic-gate */ 103*7c478bd9Sstevel@tonic-gate const char * 104*7c478bd9Sstevel@tonic-gate wbku_retmsg(wbku_retcode_t retcode) 105*7c478bd9Sstevel@tonic-gate { 106*7c478bd9Sstevel@tonic-gate if ((retcode < WBKU_SUCCESS) || (retcode >= WBKU_NRET)) 107*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "<unknown code>")); 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, wbku_retmsgs[retcode])); 110*7c478bd9Sstevel@tonic-gate } 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate /* 113*7c478bd9Sstevel@tonic-gate * This routine is a simple helper routine that initializes a 114*7c478bd9Sstevel@tonic-gate * wbku_key_attr_t object. 115*7c478bd9Sstevel@tonic-gate */ 116*7c478bd9Sstevel@tonic-gate static void 117*7c478bd9Sstevel@tonic-gate wbku_keyattr_init(wbku_key_attr_t *attr, wbku_key_type_t type, uint_t atype, 118*7c478bd9Sstevel@tonic-gate uint_t len, uint_t minlen, uint_t maxlen, 119*7c478bd9Sstevel@tonic-gate char *str, char *oid, boolean_t (*keycheck)(const uint8_t *)) 120*7c478bd9Sstevel@tonic-gate { 121*7c478bd9Sstevel@tonic-gate attr->ka_type = type; 122*7c478bd9Sstevel@tonic-gate attr->ka_atype = atype; 123*7c478bd9Sstevel@tonic-gate attr->ka_len = len; 124*7c478bd9Sstevel@tonic-gate attr->ka_minlen = minlen; 125*7c478bd9Sstevel@tonic-gate attr->ka_maxlen = maxlen; 126*7c478bd9Sstevel@tonic-gate attr->ka_str = str; 127*7c478bd9Sstevel@tonic-gate attr->ka_oid = oid; 128*7c478bd9Sstevel@tonic-gate attr->ka_keycheck = keycheck; 129*7c478bd9Sstevel@tonic-gate } 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate /* 133*7c478bd9Sstevel@tonic-gate * This routine is used to build a key attribute structure of the type 134*7c478bd9Sstevel@tonic-gate * defined by 'str' and 'flag'. This structure, 'attr', is the common 135*7c478bd9Sstevel@tonic-gate * structure used by the utilities that defines the attributes of a 136*7c478bd9Sstevel@tonic-gate * specific key type. 137*7c478bd9Sstevel@tonic-gate * 138*7c478bd9Sstevel@tonic-gate * Returns: 139*7c478bd9Sstevel@tonic-gate * WBKU_SUCCESS or WBKU_BAD_KEYTYPE. 140*7c478bd9Sstevel@tonic-gate */ 141*7c478bd9Sstevel@tonic-gate wbku_retcode_t 142*7c478bd9Sstevel@tonic-gate wbku_str_to_keyattr(const char *str, wbku_key_attr_t *attr, uint_t flag) 143*7c478bd9Sstevel@tonic-gate { 144*7c478bd9Sstevel@tonic-gate if (str == NULL) 145*7c478bd9Sstevel@tonic-gate return (WBKU_BAD_KEYTYPE); 146*7c478bd9Sstevel@tonic-gate 147*7c478bd9Sstevel@tonic-gate if (flag & WBKU_ENCR_KEY) { 148*7c478bd9Sstevel@tonic-gate if (strcmp(str, WBKU_KW_3DES) == 0) { 149*7c478bd9Sstevel@tonic-gate wbku_keyattr_init(attr, WBKU_KEY_3DES, 150*7c478bd9Sstevel@tonic-gate WBKU_ENCR_KEY, DES3_KEY_SIZE, DES3_KEY_SIZE, 151*7c478bd9Sstevel@tonic-gate DES3_KEY_SIZE, "3DES", WBKU_DES3_OID, 152*7c478bd9Sstevel@tonic-gate des3_keycheck); 153*7c478bd9Sstevel@tonic-gate return (WBKU_SUCCESS); 154*7c478bd9Sstevel@tonic-gate } 155*7c478bd9Sstevel@tonic-gate if (strcmp(str, WBKU_KW_AES_128) == 0) { 156*7c478bd9Sstevel@tonic-gate wbku_keyattr_init(attr, WBKU_KEY_AES_128, 157*7c478bd9Sstevel@tonic-gate WBKU_ENCR_KEY, AES_128_KEY_SIZE, AES_128_KEY_SIZE, 158*7c478bd9Sstevel@tonic-gate AES_128_KEY_SIZE, "AES", WBKU_AES_128_OID, NULL); 159*7c478bd9Sstevel@tonic-gate return (WBKU_SUCCESS); 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate if (strcmp(str, WBKU_KW_RSA) == 0) { 162*7c478bd9Sstevel@tonic-gate wbku_keyattr_init(attr, WBKU_KEY_RSA, 163*7c478bd9Sstevel@tonic-gate WBKU_ENCR_KEY, 0, PKCS12_MIN_LEN, 164*7c478bd9Sstevel@tonic-gate WBKU_MAX_KEYLEN, "RSA", WBKU_RSA_OID, NULL); 165*7c478bd9Sstevel@tonic-gate return (WBKU_SUCCESS); 166*7c478bd9Sstevel@tonic-gate } 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate if (flag & WBKU_HASH_KEY) { 169*7c478bd9Sstevel@tonic-gate if (strcmp(str, WBKU_KW_HMAC_SHA1) == 0) { 170*7c478bd9Sstevel@tonic-gate wbku_keyattr_init(attr, WBKU_KEY_HMAC_SHA1, 171*7c478bd9Sstevel@tonic-gate WBKU_HASH_KEY, WANBOOT_HMAC_KEY_SIZE, 172*7c478bd9Sstevel@tonic-gate WANBOOT_HMAC_KEY_SIZE, WANBOOT_HMAC_KEY_SIZE, 173*7c478bd9Sstevel@tonic-gate "HMAC/SHA1", WBKU_HMAC_SHA1_OID, NULL); 174*7c478bd9Sstevel@tonic-gate return (WBKU_SUCCESS); 175*7c478bd9Sstevel@tonic-gate } 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate return (WBKU_BAD_KEYTYPE); 178*7c478bd9Sstevel@tonic-gate } 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate /* 181*7c478bd9Sstevel@tonic-gate * This routine is used to search a key file (whose handle, fp, has been 182*7c478bd9Sstevel@tonic-gate * initialized by the caller) for the key of type 'ka'. The search is further 183*7c478bd9Sstevel@tonic-gate * constrained by the 'master' argument which is used to signify that the 184*7c478bd9Sstevel@tonic-gate * key being searched for is the master key. 185*7c478bd9Sstevel@tonic-gate * 186*7c478bd9Sstevel@tonic-gate * This routine may be used for a number of purposes: 187*7c478bd9Sstevel@tonic-gate * - Check for the existence of key of type foo. 188*7c478bd9Sstevel@tonic-gate * - Get the value for the key of type foo. 189*7c478bd9Sstevel@tonic-gate * - Return the file position of the key of type foo. 190*7c478bd9Sstevel@tonic-gate * 191*7c478bd9Sstevel@tonic-gate * To faciliate the uses above, both 'ppos' and 'ekey' will only be 192*7c478bd9Sstevel@tonic-gate * returned if they are not NULL pointers. 193*7c478bd9Sstevel@tonic-gate * 194*7c478bd9Sstevel@tonic-gate * Returns: 195*7c478bd9Sstevel@tonic-gate * WBKU_SUCCESS, WBKU_INTERNAL_ERR or WBKU_NOKEY. 196*7c478bd9Sstevel@tonic-gate */ 197*7c478bd9Sstevel@tonic-gate wbku_retcode_t 198*7c478bd9Sstevel@tonic-gate wbku_find_key(FILE *fp, fpos_t *ppos, wbku_key_attr_t *ka, uint8_t *ekey, 199*7c478bd9Sstevel@tonic-gate boolean_t master) 200*7c478bd9Sstevel@tonic-gate { 201*7c478bd9Sstevel@tonic-gate fpos_t pos; 202*7c478bd9Sstevel@tonic-gate XDR xdrs; 203*7c478bd9Sstevel@tonic-gate wbku_key keyobj; 204*7c478bd9Sstevel@tonic-gate int keyno; 205*7c478bd9Sstevel@tonic-gate int ret; 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate /* 208*7c478bd9Sstevel@tonic-gate * Always, start at the beginning. 209*7c478bd9Sstevel@tonic-gate */ 210*7c478bd9Sstevel@tonic-gate rewind(fp); 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate /* 213*7c478bd9Sstevel@tonic-gate * Initialize the XDR stream. 214*7c478bd9Sstevel@tonic-gate */ 215*7c478bd9Sstevel@tonic-gate xdrs.x_ops = NULL; 216*7c478bd9Sstevel@tonic-gate xdrstdio_create(&xdrs, fp, XDR_DECODE); 217*7c478bd9Sstevel@tonic-gate if (xdrs.x_ops == NULL) { 218*7c478bd9Sstevel@tonic-gate return (WBKU_INTERNAL_ERR); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate /* 222*7c478bd9Sstevel@tonic-gate * The XDR routines may examine the content of the keyobj 223*7c478bd9Sstevel@tonic-gate * structure to determine whether or not to provide memory 224*7c478bd9Sstevel@tonic-gate * resources. Since XDR does not provide an init routine 225*7c478bd9Sstevel@tonic-gate * for XDR generated objects, it seems that the safest thing 226*7c478bd9Sstevel@tonic-gate * to do is to bzero() the object as a means of initialization. 227*7c478bd9Sstevel@tonic-gate */ 228*7c478bd9Sstevel@tonic-gate bzero(&keyobj, sizeof (keyobj)); 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate /* 231*7c478bd9Sstevel@tonic-gate * Read a key and check to see if matches the criteria. 232*7c478bd9Sstevel@tonic-gate */ 233*7c478bd9Sstevel@tonic-gate for (keyno = 0; !feof(fp); keyno++) { 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate /* 236*7c478bd9Sstevel@tonic-gate * Returning the file position is conditional. 237*7c478bd9Sstevel@tonic-gate */ 238*7c478bd9Sstevel@tonic-gate if (ppos != NULL) { 239*7c478bd9Sstevel@tonic-gate if (fgetpos(fp, &pos) != 0) { 240*7c478bd9Sstevel@tonic-gate ret = WBKU_INTERNAL_ERR; 241*7c478bd9Sstevel@tonic-gate break; 242*7c478bd9Sstevel@tonic-gate } 243*7c478bd9Sstevel@tonic-gate } 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate /* 246*7c478bd9Sstevel@tonic-gate * Read the key. Unfortuantely, XDR does not provide 247*7c478bd9Sstevel@tonic-gate * the ability to tell an EOF from some other IO error. 248*7c478bd9Sstevel@tonic-gate * Therefore, a faliure to read is assumed to be EOF. 249*7c478bd9Sstevel@tonic-gate */ 250*7c478bd9Sstevel@tonic-gate if (!xdr_wbku_key(&xdrs, &keyobj)) { 251*7c478bd9Sstevel@tonic-gate ret = WBKU_NOKEY; 252*7c478bd9Sstevel@tonic-gate break; 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate /* 256*7c478bd9Sstevel@tonic-gate * Check this key against the criteria. 257*7c478bd9Sstevel@tonic-gate */ 258*7c478bd9Sstevel@tonic-gate if ((strcmp(keyobj.wk_oid, ka->ka_oid) == 0) && 259*7c478bd9Sstevel@tonic-gate (keyobj.wk_master == master)) { 260*7c478bd9Sstevel@tonic-gate 261*7c478bd9Sstevel@tonic-gate ka->ka_len = keyobj.wk_key_len; 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate /* 264*7c478bd9Sstevel@tonic-gate * Conditionally return the key value and file 265*7c478bd9Sstevel@tonic-gate * position. 266*7c478bd9Sstevel@tonic-gate */ 267*7c478bd9Sstevel@tonic-gate if (ekey != NULL) { 268*7c478bd9Sstevel@tonic-gate (void) memcpy(ekey, keyobj.wk_key_val, 269*7c478bd9Sstevel@tonic-gate ka->ka_len); 270*7c478bd9Sstevel@tonic-gate } 271*7c478bd9Sstevel@tonic-gate if (ppos != NULL) { 272*7c478bd9Sstevel@tonic-gate *ppos = pos; 273*7c478bd9Sstevel@tonic-gate } 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate xdr_free(xdr_wbku_key, (char *)&keyobj); 276*7c478bd9Sstevel@tonic-gate ret = WBKU_SUCCESS; 277*7c478bd9Sstevel@tonic-gate break; 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate xdr_free(xdr_wbku_key, (char *)&keyobj); 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate 282*7c478bd9Sstevel@tonic-gate xdr_destroy(&xdrs); 283*7c478bd9Sstevel@tonic-gate return (ret); 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate /* 287*7c478bd9Sstevel@tonic-gate * This routine writes a key object to the key file at the location 288*7c478bd9Sstevel@tonic-gate * specified by the caller. 289*7c478bd9Sstevel@tonic-gate * 290*7c478bd9Sstevel@tonic-gate * Returns: 291*7c478bd9Sstevel@tonic-gate * WBKU_SUCCESS, WBKU_INTERNAL_ERR or WBKU_WRITE_ERR. 292*7c478bd9Sstevel@tonic-gate */ 293*7c478bd9Sstevel@tonic-gate wbku_retcode_t 294*7c478bd9Sstevel@tonic-gate wbku_write_key(FILE *fp, const fpos_t *ppos, const wbku_key_attr_t *ka, 295*7c478bd9Sstevel@tonic-gate uint8_t *rand_key, boolean_t master) 296*7c478bd9Sstevel@tonic-gate { 297*7c478bd9Sstevel@tonic-gate XDR xdrs; 298*7c478bd9Sstevel@tonic-gate wbku_key keyobj; 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate /* 301*7c478bd9Sstevel@tonic-gate * Set the file position as specified by the caller. 302*7c478bd9Sstevel@tonic-gate */ 303*7c478bd9Sstevel@tonic-gate if (fsetpos(fp, ppos) != 0) { 304*7c478bd9Sstevel@tonic-gate return (WBKU_INTERNAL_ERR); 305*7c478bd9Sstevel@tonic-gate } 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate /* 308*7c478bd9Sstevel@tonic-gate * Initialize the XDR stream. 309*7c478bd9Sstevel@tonic-gate */ 310*7c478bd9Sstevel@tonic-gate xdrs.x_ops = NULL; 311*7c478bd9Sstevel@tonic-gate xdrstdio_create(&xdrs, fp, XDR_ENCODE); 312*7c478bd9Sstevel@tonic-gate if (xdrs.x_ops == NULL) { 313*7c478bd9Sstevel@tonic-gate return (WBKU_INTERNAL_ERR); 314*7c478bd9Sstevel@tonic-gate } 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate /* 317*7c478bd9Sstevel@tonic-gate * Build the key object. 318*7c478bd9Sstevel@tonic-gate */ 319*7c478bd9Sstevel@tonic-gate keyobj.wk_master = master; 320*7c478bd9Sstevel@tonic-gate keyobj.wk_oid = ka->ka_oid; 321*7c478bd9Sstevel@tonic-gate keyobj.wk_key_len = ka->ka_len; 322*7c478bd9Sstevel@tonic-gate keyobj.wk_key_val = (char *)rand_key; 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate /* 325*7c478bd9Sstevel@tonic-gate * Write it. 326*7c478bd9Sstevel@tonic-gate */ 327*7c478bd9Sstevel@tonic-gate if (!xdr_wbku_key(&xdrs, &keyobj)) { 328*7c478bd9Sstevel@tonic-gate xdr_free(xdr_wbku_key, (char *)&keyobj); 329*7c478bd9Sstevel@tonic-gate xdr_destroy(&xdrs); 330*7c478bd9Sstevel@tonic-gate return (WBKU_WRITE_ERR); 331*7c478bd9Sstevel@tonic-gate } 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate /* 334*7c478bd9Sstevel@tonic-gate * Free the stream and return success. 335*7c478bd9Sstevel@tonic-gate */ 336*7c478bd9Sstevel@tonic-gate xdr_destroy(&xdrs); 337*7c478bd9Sstevel@tonic-gate return (WBKU_SUCCESS); 338*7c478bd9Sstevel@tonic-gate } 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate /* 341*7c478bd9Sstevel@tonic-gate * This routine reads the contents of one keystore file and copies it to 342*7c478bd9Sstevel@tonic-gate * another, omitting the key of the type defined by 'ka'. 343*7c478bd9Sstevel@tonic-gate * 344*7c478bd9Sstevel@tonic-gate * Returns: 345*7c478bd9Sstevel@tonic-gate * WBKU_SUCCESS, WBKU_INTERNAL_ERR or WBKU_WRITE_ERR. 346*7c478bd9Sstevel@tonic-gate */ 347*7c478bd9Sstevel@tonic-gate wbku_retcode_t 348*7c478bd9Sstevel@tonic-gate wbku_delete_key(FILE *from_fp, FILE *to_fp, const wbku_key_attr_t *ka) 349*7c478bd9Sstevel@tonic-gate { 350*7c478bd9Sstevel@tonic-gate XDR from_xdrs; 351*7c478bd9Sstevel@tonic-gate XDR to_xdrs; 352*7c478bd9Sstevel@tonic-gate wbku_key keyobj; 353*7c478bd9Sstevel@tonic-gate int keyno; 354*7c478bd9Sstevel@tonic-gate int ret; 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate /* 357*7c478bd9Sstevel@tonic-gate * Always, start at the beginning. 358*7c478bd9Sstevel@tonic-gate */ 359*7c478bd9Sstevel@tonic-gate rewind(from_fp); 360*7c478bd9Sstevel@tonic-gate rewind(to_fp); 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate /* 363*7c478bd9Sstevel@tonic-gate * Initialize the XDR streams. 364*7c478bd9Sstevel@tonic-gate */ 365*7c478bd9Sstevel@tonic-gate from_xdrs.x_ops = NULL; 366*7c478bd9Sstevel@tonic-gate xdrstdio_create(&from_xdrs, from_fp, XDR_DECODE); 367*7c478bd9Sstevel@tonic-gate if (from_xdrs.x_ops == NULL) { 368*7c478bd9Sstevel@tonic-gate return (WBKU_INTERNAL_ERR); 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate to_xdrs.x_ops = NULL; 372*7c478bd9Sstevel@tonic-gate xdrstdio_create(&to_xdrs, to_fp, XDR_ENCODE); 373*7c478bd9Sstevel@tonic-gate if (to_xdrs.x_ops == NULL) { 374*7c478bd9Sstevel@tonic-gate xdr_destroy(&from_xdrs); 375*7c478bd9Sstevel@tonic-gate return (WBKU_INTERNAL_ERR); 376*7c478bd9Sstevel@tonic-gate } 377*7c478bd9Sstevel@tonic-gate 378*7c478bd9Sstevel@tonic-gate /* 379*7c478bd9Sstevel@tonic-gate * The XDR routines may examine the content of the keyobj 380*7c478bd9Sstevel@tonic-gate * structure to determine whether or not to provide memory 381*7c478bd9Sstevel@tonic-gate * resources. Since XDR does not provide an init routine 382*7c478bd9Sstevel@tonic-gate * for XDR generated objects, it seems that the safest thing 383*7c478bd9Sstevel@tonic-gate * to do is to bzero() the object as a means of initialization. 384*7c478bd9Sstevel@tonic-gate */ 385*7c478bd9Sstevel@tonic-gate bzero(&keyobj, sizeof (keyobj)); 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate /* 388*7c478bd9Sstevel@tonic-gate * Read a key and check to see if matches the criteria. 389*7c478bd9Sstevel@tonic-gate */ 390*7c478bd9Sstevel@tonic-gate ret = WBKU_SUCCESS; 391*7c478bd9Sstevel@tonic-gate for (keyno = 0; !feof(from_fp); keyno++) { 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate /* 394*7c478bd9Sstevel@tonic-gate * Read the key. Unfortuantely, XDR does not provide 395*7c478bd9Sstevel@tonic-gate * the ability to tell an EOF from some other IO error. 396*7c478bd9Sstevel@tonic-gate * Therefore, a faliure to read is assumed to be EOF. 397*7c478bd9Sstevel@tonic-gate */ 398*7c478bd9Sstevel@tonic-gate if (!xdr_wbku_key(&from_xdrs, &keyobj)) { 399*7c478bd9Sstevel@tonic-gate break; 400*7c478bd9Sstevel@tonic-gate } 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate /* 403*7c478bd9Sstevel@tonic-gate * If this isn't the key to skip, then write it. 404*7c478bd9Sstevel@tonic-gate */ 405*7c478bd9Sstevel@tonic-gate if (strcmp(keyobj.wk_oid, ka->ka_oid) != 0) { 406*7c478bd9Sstevel@tonic-gate /* 407*7c478bd9Sstevel@tonic-gate * Write this to the copy. 408*7c478bd9Sstevel@tonic-gate */ 409*7c478bd9Sstevel@tonic-gate if (!xdr_wbku_key(&to_xdrs, &keyobj)) { 410*7c478bd9Sstevel@tonic-gate xdr_free(xdr_wbku_key, (char *)&keyobj); 411*7c478bd9Sstevel@tonic-gate ret = WBKU_WRITE_ERR; 412*7c478bd9Sstevel@tonic-gate break; 413*7c478bd9Sstevel@tonic-gate } 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate } 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate xdr_free(xdr_wbku_key, (char *)&keyobj); 418*7c478bd9Sstevel@tonic-gate } 419*7c478bd9Sstevel@tonic-gate 420*7c478bd9Sstevel@tonic-gate xdr_destroy(&from_xdrs); 421*7c478bd9Sstevel@tonic-gate xdr_destroy(&to_xdrs); 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate return (ret); 424*7c478bd9Sstevel@tonic-gate } 425