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 /* 237c478bd9Sstevel@tonic-gate * ident "%Z%%M% %I% %E% SMI" 247c478bd9Sstevel@tonic-gate * 257c478bd9Sstevel@tonic-gate * Copyright (c) 1999 by Sun Microsystems, Inc. 267c478bd9Sstevel@tonic-gate * All rights reserved. 277c478bd9Sstevel@tonic-gate * 287c478bd9Sstevel@tonic-gate */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate package com.sun.slp; 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate import java.util.*; 337c478bd9Sstevel@tonic-gate import java.io.*; 347c478bd9Sstevel@tonic-gate import java.security.*; 357c478bd9Sstevel@tonic-gate import java.security.cert.*; 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate /** 387c478bd9Sstevel@tonic-gate * The AuthBlock class models both the client and server side 397c478bd9Sstevel@tonic-gate * authentication blocks. 407c478bd9Sstevel@tonic-gate *<p> 417c478bd9Sstevel@tonic-gate * AuthBlocks are agnostic as to which components from a given 427c478bd9Sstevel@tonic-gate * message should be used in authentication. Thus each message 437c478bd9Sstevel@tonic-gate * must provide the correct components in the correct order. 447c478bd9Sstevel@tonic-gate *<p> 457c478bd9Sstevel@tonic-gate * These components are passed via Object[]s. The Object[] elements 467c478bd9Sstevel@tonic-gate * should be in externalized form, and should be ordered as stated 477c478bd9Sstevel@tonic-gate * in the protocol specification for auth blocks. AuthBlocks will 487c478bd9Sstevel@tonic-gate * add the externalized SPI string before the Object[] and the 497c478bd9Sstevel@tonic-gate * externalized timestamp after the vector. 507c478bd9Sstevel@tonic-gate *<p> 517c478bd9Sstevel@tonic-gate * The AuthBlock class provides a number of static convenience 527c478bd9Sstevel@tonic-gate * methods which operate on sets of AuthBlocks. The sets of 537c478bd9Sstevel@tonic-gate * AuthBlocks are stored in Hashtables, keyed by SPIs. 547c478bd9Sstevel@tonic-gate */ 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate class AuthBlock { 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate static private String SPI_PROPERTY = "sun.net.slp.SPIs"; 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate /** 617c478bd9Sstevel@tonic-gate * A convenience method for creating a set of auth blocks 627c478bd9Sstevel@tonic-gate * from internal data structures. 637c478bd9Sstevel@tonic-gate * 647c478bd9Sstevel@tonic-gate * @param message The ordered components of the SLP message 657c478bd9Sstevel@tonic-gate * over which the signature should be computed, 667c478bd9Sstevel@tonic-gate * in externalized (byte[]) form. 677c478bd9Sstevel@tonic-gate * @param lifetime The lifetime for this message, in seconds. 687c478bd9Sstevel@tonic-gate * @return A Hashtable of AuthBlocks, one for each SPI, null if no 697c478bd9Sstevel@tonic-gate * SPIs have been configured. 707c478bd9Sstevel@tonic-gate * @exception ServiceLocationException If a key management or crypto 717c478bd9Sstevel@tonic-gate * algorithm provider cannot be 727c478bd9Sstevel@tonic-gate * instantiated, a SYSTEM_ERROR exception 737c478bd9Sstevel@tonic-gate * is thrown. 747c478bd9Sstevel@tonic-gate * @exception IllegalArgumentException If any of the parameters are null 757c478bd9Sstevel@tonic-gate * or empty. 767c478bd9Sstevel@tonic-gate */ makeAuthBlocks(Object[] message, int lifetime)777c478bd9Sstevel@tonic-gate static Hashtable makeAuthBlocks(Object[] message, int lifetime) 787c478bd9Sstevel@tonic-gate throws ServiceLocationException, IllegalArgumentException { 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate Hashtable spis = getSignAs(); 817c478bd9Sstevel@tonic-gate if (spis == null) { 827c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 837c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 847c478bd9Sstevel@tonic-gate "cant_sign", new Object[0]); 857c478bd9Sstevel@tonic-gate } 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate Hashtable blocks = new Hashtable(); 887c478bd9Sstevel@tonic-gate Enumeration spisEnum = spis.keys(); 897c478bd9Sstevel@tonic-gate while (spisEnum.hasMoreElements()) { 907c478bd9Sstevel@tonic-gate String spi = (String) spisEnum.nextElement(); 917c478bd9Sstevel@tonic-gate int bsd = ((Integer)(spis.get(spi))).intValue(); 927c478bd9Sstevel@tonic-gate blocks.put(spi, new AuthBlock(message, spi, bsd, lifetime)); 937c478bd9Sstevel@tonic-gate } 947c478bd9Sstevel@tonic-gate return blocks; 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate /** 987c478bd9Sstevel@tonic-gate * A convenience method which creates a Hashtable of auth blocks 997c478bd9Sstevel@tonic-gate * from an input stream. 1007c478bd9Sstevel@tonic-gate * 1017c478bd9Sstevel@tonic-gate * @param hdr Header of message being parsed out. 1027c478bd9Sstevel@tonic-gate * @param message The ordered components of the SLP message 1037c478bd9Sstevel@tonic-gate * over which the signature should have been computed, 1047c478bd9Sstevel@tonic-gate * in externalized (byte[]) form. 1057c478bd9Sstevel@tonic-gate * @param dis Input stream with the auth block bytes queued up as the 1067c478bd9Sstevel@tonic-gate * next thing. 1077c478bd9Sstevel@tonic-gate * @param nBlocks Number of auth blocks to read. 1087c478bd9Sstevel@tonic-gate * @return A Hashtable of AuthBlocks. 1097c478bd9Sstevel@tonic-gate * @exception ServiceLocationException If anything goes wrong during 1107c478bd9Sstevel@tonic-gate * parsing. If nBlocks is 0, the 1117c478bd9Sstevel@tonic-gate * error code is AUTHENTICATION_ABSENT. 1127c478bd9Sstevel@tonic-gate * @exception IllegalArgumentException If any of the parameters are null 1137c478bd9Sstevel@tonic-gate * or empty. 1147c478bd9Sstevel@tonic-gate * @exception IOException If DataInputStream throws it. 1157c478bd9Sstevel@tonic-gate */ makeAuthBlocks(SrvLocHeader hdr, Object[] message, DataInputStream dis, byte nBlocks)1167c478bd9Sstevel@tonic-gate static Hashtable makeAuthBlocks(SrvLocHeader hdr, 1177c478bd9Sstevel@tonic-gate Object[] message, 1187c478bd9Sstevel@tonic-gate DataInputStream dis, 1197c478bd9Sstevel@tonic-gate byte nBlocks) 1207c478bd9Sstevel@tonic-gate throws ServiceLocationException, 1217c478bd9Sstevel@tonic-gate IllegalArgumentException, 1227c478bd9Sstevel@tonic-gate IOException { 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate Hashtable blocks = new Hashtable(); 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate for (byte cnt = 0; cnt < nBlocks; cnt++) { 1277c478bd9Sstevel@tonic-gate AuthBlock ab = new AuthBlock(hdr, message, dis); 1287c478bd9Sstevel@tonic-gate blocks.put(ab.getSPI(), ab); 1297c478bd9Sstevel@tonic-gate } 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate return blocks; 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate /** 1357c478bd9Sstevel@tonic-gate * A convenience method which verifies all auth blocks in the 1367c478bd9Sstevel@tonic-gate * input Hashtable. 1377c478bd9Sstevel@tonic-gate * 1387c478bd9Sstevel@tonic-gate * @param authBlocks A Hashtable containing AuthBlocks. 1397c478bd9Sstevel@tonic-gate * @exception ServiceLocationException Thrown if authentication fails, 1407c478bd9Sstevel@tonic-gate * with the error code 1417c478bd9Sstevel@tonic-gate * ServiceLocationException.AUTHENTICATION_FAILED. If any 1427c478bd9Sstevel@tonic-gate * other error occurs during authentication, the 1437c478bd9Sstevel@tonic-gate * error code is ServiceLocationException.SYSTEM_ERROR. 1447c478bd9Sstevel@tonic-gate * If the signature hasn't been calculated the 1457c478bd9Sstevel@tonic-gate * authentication fails. 1467c478bd9Sstevel@tonic-gate * @exception IllegalArgumentException If authBlocks is null or empty. 1477c478bd9Sstevel@tonic-gate */ verifyAll(Hashtable authBlocks)1487c478bd9Sstevel@tonic-gate static void verifyAll(Hashtable authBlocks) 1497c478bd9Sstevel@tonic-gate throws ServiceLocationException, IllegalArgumentException { 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate ensureNonEmpty(authBlocks, "authBlocks"); 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate Enumeration blocks = authBlocks.elements(); 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate while (blocks.hasMoreElements()) { 1567c478bd9Sstevel@tonic-gate AuthBlock ab = (AuthBlock) blocks.nextElement(); 1577c478bd9Sstevel@tonic-gate ab.verify(); 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate /** 1627c478bd9Sstevel@tonic-gate * A convenience method which finds the shortest lifetime in a 1637c478bd9Sstevel@tonic-gate * set of AuthBlocks. 1647c478bd9Sstevel@tonic-gate * 1657c478bd9Sstevel@tonic-gate * @param authBlocks A Hashtable containing AuthBlocks. 1667c478bd9Sstevel@tonic-gate * @return The shortest lifetime found. 1677c478bd9Sstevel@tonic-gate * @exception IllegalArgumentException If authBlocks is null or empty. 1687c478bd9Sstevel@tonic-gate */ getShortestLifetime(Hashtable authBlocks)1697c478bd9Sstevel@tonic-gate static int getShortestLifetime(Hashtable authBlocks) 1707c478bd9Sstevel@tonic-gate throws IllegalArgumentException { 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate ensureNonEmpty(authBlocks, "authBlocks"); 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate Enumeration blocks = authBlocks.elements(); 1757c478bd9Sstevel@tonic-gate int lifetime = Integer.MAX_VALUE; 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate while (blocks.hasMoreElements()) { 1787c478bd9Sstevel@tonic-gate AuthBlock ab = (AuthBlock) blocks.nextElement(); 1797c478bd9Sstevel@tonic-gate int abLife = ab.getLifetime(); 1807c478bd9Sstevel@tonic-gate lifetime = (lifetime < abLife) ? lifetime : abLife; 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate return lifetime; 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate /** 1877c478bd9Sstevel@tonic-gate * A convenience method which externalizes a set of AuthBlocks 1887c478bd9Sstevel@tonic-gate * into a ByteArrayOutputStream. The number of blocks is NOT 1897c478bd9Sstevel@tonic-gate * written onto the stream. 1907c478bd9Sstevel@tonic-gate * 1917c478bd9Sstevel@tonic-gate * @param hdr Header of message being externalized. 1927c478bd9Sstevel@tonic-gate * @param authBlocks A Hashtable containing AuthBlocks. 1937c478bd9Sstevel@tonic-gate * @param baos The output stream into which to write. 1947c478bd9Sstevel@tonic-gate * @exception ServiceLocationException Thrown if an error occurs during 1957c478bd9Sstevel@tonic-gate * output, with PARSE_ERROR error code. 1967c478bd9Sstevel@tonic-gate * @exception IllegalArgumentException If any parameters are null, or 1977c478bd9Sstevel@tonic-gate * if authBlocks is empty. 1987c478bd9Sstevel@tonic-gate */ externalizeAll(SrvLocHeader hdr, Hashtable authBlocks, ByteArrayOutputStream baos)1997c478bd9Sstevel@tonic-gate static void externalizeAll(SrvLocHeader hdr, 2007c478bd9Sstevel@tonic-gate Hashtable authBlocks, 2017c478bd9Sstevel@tonic-gate ByteArrayOutputStream baos) 2027c478bd9Sstevel@tonic-gate throws ServiceLocationException, IllegalArgumentException { 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate ensureNonEmpty(authBlocks, "authBlocks"); 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate Enumeration blocks = authBlocks.elements(); 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate while (blocks.hasMoreElements()) { 2097c478bd9Sstevel@tonic-gate AuthBlock ab = (AuthBlock) blocks.nextElement(); 2107c478bd9Sstevel@tonic-gate ab.externalize(hdr, baos); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate /** 2157c478bd9Sstevel@tonic-gate * Returns the message parts obtained from the AuthBlock contructor. 2167c478bd9Sstevel@tonic-gate * The Object[] will not have been altered. Note that all AuthBlocks 2177c478bd9Sstevel@tonic-gate * contain the same message Object[] Object. 2187c478bd9Sstevel@tonic-gate * 2197c478bd9Sstevel@tonic-gate * @param authBlocks A Hashtable containing AuthBlocks. 2207c478bd9Sstevel@tonic-gate * @return This auth block's message components Object[]. 2217c478bd9Sstevel@tonic-gate * @exception IllegalArgumentException If authBlocks is null or empty. 2227c478bd9Sstevel@tonic-gate */ getContents(Hashtable authBlocks)2237c478bd9Sstevel@tonic-gate static Object[] getContents(Hashtable authBlocks) 2247c478bd9Sstevel@tonic-gate throws IllegalArgumentException { 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate ensureNonEmpty(authBlocks, "authBlocks"); 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate Enumeration blocks = authBlocks.elements(); 2297c478bd9Sstevel@tonic-gate AuthBlock ab = (AuthBlock) blocks.nextElement(); 2307c478bd9Sstevel@tonic-gate return ab.getMessageParts(); 2317c478bd9Sstevel@tonic-gate } 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate /** 2347c478bd9Sstevel@tonic-gate * Creates a String describing all auth blocks in authBlocks. 2357c478bd9Sstevel@tonic-gate * We dont't use toString() since that would get Hashtable.toString(), 2367c478bd9Sstevel@tonic-gate * and we can format it a little prettier. 2377c478bd9Sstevel@tonic-gate * 2387c478bd9Sstevel@tonic-gate * @param authBlocks A Hashtable containing AuthBlocks. 2397c478bd9Sstevel@tonic-gate * @return A String description of all AuthBlocks in this Hashtable 2407c478bd9Sstevel@tonic-gate */ desc(Hashtable authBlocks)2417c478bd9Sstevel@tonic-gate static String desc(Hashtable authBlocks) { 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate if (authBlocks == null) { 2447c478bd9Sstevel@tonic-gate return "null"; 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate Enumeration blocks = authBlocks.elements(); 2487c478bd9Sstevel@tonic-gate int size = authBlocks.size(); 2497c478bd9Sstevel@tonic-gate String desc = size == 1 ? "1 Auth Block:\n" : size + " Auth Blocks:\n"; 2507c478bd9Sstevel@tonic-gate int cnt = 0; 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate while (blocks.hasMoreElements()) { 2537c478bd9Sstevel@tonic-gate AuthBlock ab = (AuthBlock) blocks.nextElement(); 2547c478bd9Sstevel@tonic-gate desc = desc + " " + (cnt++) + ": " + ab.toString(); 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate return desc; 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate /** 2617c478bd9Sstevel@tonic-gate * Returns the list of SPIs configured with this 'prop', or null 2627c478bd9Sstevel@tonic-gate * if the property hasn't been set. 2637c478bd9Sstevel@tonic-gate */ getSPIList(String prop)2647c478bd9Sstevel@tonic-gate static LinkedList getSPIList(String prop) { 2657c478bd9Sstevel@tonic-gate String spiProp = System.getProperty(prop); 2667c478bd9Sstevel@tonic-gate if (spiProp == null) { 2677c478bd9Sstevel@tonic-gate return null; 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate return commaSeparatedListToLinkedList(spiProp); 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate /** 2747c478bd9Sstevel@tonic-gate * Converts a comma-separaterd list in a String to a LinkedList. 2757c478bd9Sstevel@tonic-gate */ commaSeparatedListToLinkedList(String listStr)2767c478bd9Sstevel@tonic-gate static LinkedList commaSeparatedListToLinkedList(String listStr) { 2777c478bd9Sstevel@tonic-gate StringTokenizer stk_comma = new StringTokenizer(listStr, ","); 2787c478bd9Sstevel@tonic-gate LinkedList answer = new LinkedList(); 2797c478bd9Sstevel@tonic-gate while (stk_comma.hasMoreTokens()) { 2807c478bd9Sstevel@tonic-gate String spi = stk_comma.nextToken(); 2817c478bd9Sstevel@tonic-gate answer.add(spi); 2827c478bd9Sstevel@tonic-gate } 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate return answer; 2857c478bd9Sstevel@tonic-gate } 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate /** 2887c478bd9Sstevel@tonic-gate * Returns true if this principal is someDH, or if this principal's 2897c478bd9Sstevel@tonic-gate * cert has been signed by someDN. 2907c478bd9Sstevel@tonic-gate */ canSignAs(String someDN)2917c478bd9Sstevel@tonic-gate static boolean canSignAs(String someDN) throws ServiceLocationException { 2927c478bd9Sstevel@tonic-gate X509Certificate myCert = getSignAsCert(); 2937c478bd9Sstevel@tonic-gate if (myCert == null) { 2947c478bd9Sstevel@tonic-gate return false; 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate KeyStore ks = getKeyStore(); 2987c478bd9Sstevel@tonic-gate if (ks == null) { 2997c478bd9Sstevel@tonic-gate return false; 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate X509Certificate cert = getCert(someDN, ks); 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate return onCertChain( 3057c478bd9Sstevel@tonic-gate myCert.getSubjectDN().toString(), cert.getSubjectDN()); 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate /** 3097c478bd9Sstevel@tonic-gate * Checks if caDN is in ab's equivalency set, i.e. if caDN 3107c478bd9Sstevel@tonic-gate * is in ab's cert chain. 3117c478bd9Sstevel@tonic-gate */ checkEquiv(String caDN, AuthBlock ab)3127c478bd9Sstevel@tonic-gate static boolean checkEquiv(String caDN, AuthBlock ab) { 3137c478bd9Sstevel@tonic-gate // Get cert for input DN 3147c478bd9Sstevel@tonic-gate X509Certificate caCert; 3157c478bd9Sstevel@tonic-gate try { 3167c478bd9Sstevel@tonic-gate KeyStore ks = getKeyStore(); 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate caCert = getCert(caDN, ks); 3197c478bd9Sstevel@tonic-gate } catch (Exception e) { 3207c478bd9Sstevel@tonic-gate SLPConfig.getSLPConfig().writeLog( 3217c478bd9Sstevel@tonic-gate "cant_get_equivalency", 3227c478bd9Sstevel@tonic-gate new Object[] {caDN, e.getMessage()}); 3237c478bd9Sstevel@tonic-gate return false; 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate return ab.inEqSet(caCert.getSubjectDN()); 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate /** 3307c478bd9Sstevel@tonic-gate * Filters out from auths all auth blocks which have not been 3317c478bd9Sstevel@tonic-gate * signed by DNs equivalent to caDN. 3327c478bd9Sstevel@tonic-gate */ getEquivalentAuth(String caDN, Hashtable authBlocks)3337c478bd9Sstevel@tonic-gate static AuthBlock getEquivalentAuth(String caDN, Hashtable authBlocks) { 3347c478bd9Sstevel@tonic-gate if (authBlocks.size() == 0) { 3357c478bd9Sstevel@tonic-gate return null; 3367c478bd9Sstevel@tonic-gate } 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate // Get cert for input DN 3397c478bd9Sstevel@tonic-gate X509Certificate caCert; 3407c478bd9Sstevel@tonic-gate try { 3417c478bd9Sstevel@tonic-gate KeyStore ks = getKeyStore(); 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate caCert = getCert(caDN, ks); 3447c478bd9Sstevel@tonic-gate } catch (Exception e) { 3457c478bd9Sstevel@tonic-gate SLPConfig.getSLPConfig().writeLog( 3467c478bd9Sstevel@tonic-gate "cant_get_equivalency", 3477c478bd9Sstevel@tonic-gate new Object[] { caDN, e.getMessage()}); 3487c478bd9Sstevel@tonic-gate return null; 3497c478bd9Sstevel@tonic-gate } 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate Enumeration blocks = authBlocks.elements(); 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate while (blocks.hasMoreElements()) { 3547c478bd9Sstevel@tonic-gate AuthBlock ab = (AuthBlock) blocks.nextElement(); 3557c478bd9Sstevel@tonic-gate if (ab.inEqSet(caCert.getSubjectDN())) { 3567c478bd9Sstevel@tonic-gate return ab; 3577c478bd9Sstevel@tonic-gate } 3587c478bd9Sstevel@tonic-gate } 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate return null; 3617c478bd9Sstevel@tonic-gate } 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate /** 3657c478bd9Sstevel@tonic-gate * Gets a list of signing identities. Returns a Hashtable of 3667c478bd9Sstevel@tonic-gate * which the keys are SPI strings (DNs) and the values 3677c478bd9Sstevel@tonic-gate * are BSD Integers. 3687c478bd9Sstevel@tonic-gate */ getSignAs()3697c478bd9Sstevel@tonic-gate static Hashtable getSignAs() throws ServiceLocationException { 3707c478bd9Sstevel@tonic-gate X509Certificate cert = getSignAsCert(); 3717c478bd9Sstevel@tonic-gate Hashtable answer = new Hashtable(); 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate if (cert == null) { 3747c478bd9Sstevel@tonic-gate return null; 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate /* derive DN from alias */ 3787c478bd9Sstevel@tonic-gate String DN = cert.getSubjectDN().toString(); 3797c478bd9Sstevel@tonic-gate String e_DN = null; 3807c478bd9Sstevel@tonic-gate // escape DN 3817c478bd9Sstevel@tonic-gate try { 3827c478bd9Sstevel@tonic-gate e_DN = ServiceLocationAttribute.escapeAttributeString(DN, false); 3837c478bd9Sstevel@tonic-gate } catch (ServiceLocationException e) { 3847c478bd9Sstevel@tonic-gate // Shouldn't get here if badTag == false 3857c478bd9Sstevel@tonic-gate e_DN = DN; 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate DN = e_DN; 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate String alg = cert.getPublicKey().getAlgorithm(); 3907c478bd9Sstevel@tonic-gate int ibsd; 3917c478bd9Sstevel@tonic-gate if (alg.equals("DSA")) { 3927c478bd9Sstevel@tonic-gate ibsd = 2; 3937c478bd9Sstevel@tonic-gate } else if (alg.equals("RSA")) { 3947c478bd9Sstevel@tonic-gate ibsd = 1; 3957c478bd9Sstevel@tonic-gate } else { 3967c478bd9Sstevel@tonic-gate SLPConfig.getSLPConfig().writeLog("bad_alg_for_alias", 3977c478bd9Sstevel@tonic-gate new Object[] {alg}); 3987c478bd9Sstevel@tonic-gate return null; 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate answer.put(DN, new Integer(ibsd)); 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate return answer; 4047c478bd9Sstevel@tonic-gate } 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate /** 4077c478bd9Sstevel@tonic-gate * Returns the cert corresponding to our signing alias. 4087c478bd9Sstevel@tonic-gate * @@@ change this when AMI goes in to use private AMI interface. 4097c478bd9Sstevel@tonic-gate */ getSignAsCert()4107c478bd9Sstevel@tonic-gate static X509Certificate getSignAsCert() throws ServiceLocationException { 4117c478bd9Sstevel@tonic-gate String spiProp = System.getProperty("sun.net.slp.signAs"); 4127c478bd9Sstevel@tonic-gate if (spiProp == null) { 4137c478bd9Sstevel@tonic-gate SLPConfig.getSLPConfig().writeLog( 4147c478bd9Sstevel@tonic-gate "no_spis_given", new Object[0]); 4157c478bd9Sstevel@tonic-gate return null; 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate /* load key store */ 4197c478bd9Sstevel@tonic-gate KeyStore ks = getKeyPkg(); 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate StringTokenizer stk_comma = new StringTokenizer(spiProp, ","); 4227c478bd9Sstevel@tonic-gate X509Certificate cert = null; 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate // Can only sign with one alias, so ignore any extras 4257c478bd9Sstevel@tonic-gate if (stk_comma.hasMoreTokens()) { 4267c478bd9Sstevel@tonic-gate String alias = stk_comma.nextToken(); 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate /* get keypkg for this alias */ 4297c478bd9Sstevel@tonic-gate cert = getCert(alias, ks); 4307c478bd9Sstevel@tonic-gate } 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate return cert; 4337c478bd9Sstevel@tonic-gate } 4347c478bd9Sstevel@tonic-gate 4357c478bd9Sstevel@tonic-gate /** 4367c478bd9Sstevel@tonic-gate * Creates a new AuthBlock based on the SPI and message parts. 4377c478bd9Sstevel@tonic-gate * 4387c478bd9Sstevel@tonic-gate * @param message The ordered components of the SLP message 4397c478bd9Sstevel@tonic-gate * over which the signature should be computed, 4407c478bd9Sstevel@tonic-gate * in externalized (byte[]) form. 4417c478bd9Sstevel@tonic-gate * @param spi The SLP SPI for which to create the auth block. 4427c478bd9Sstevel@tonic-gate * @param lifetime The lifetime for this message, in seconds. 4437c478bd9Sstevel@tonic-gate * @exception ServiceLocationException If a key management or crypto 4447c478bd9Sstevel@tonic-gate * algorithm provider cannot be 4457c478bd9Sstevel@tonic-gate * instantiated, a SYSTEM_ERROR exception 4467c478bd9Sstevel@tonic-gate * is thrown. 4477c478bd9Sstevel@tonic-gate * @exception IllegalArgumentException If any of the parameters are null 4487c478bd9Sstevel@tonic-gate * or empty. 4497c478bd9Sstevel@tonic-gate */ AuthBlock(Object[] message, String spi, int bsd, int lifetime)4507c478bd9Sstevel@tonic-gate AuthBlock(Object[] message, String spi, int bsd, int lifetime) 4517c478bd9Sstevel@tonic-gate throws ServiceLocationException, IllegalArgumentException { 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate ensureNonEmpty(message, "message"); 4547c478bd9Sstevel@tonic-gate Assert.nonNullParameter(spi, "spi"); 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate // init crypto provider associated with bsd 4577c478bd9Sstevel@tonic-gate this.bsd = bsd; 4587c478bd9Sstevel@tonic-gate getSecurityProvider(bsd); 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate this.message = message; 4617c478bd9Sstevel@tonic-gate this.spi = spi; 4627c478bd9Sstevel@tonic-gate this.lifetime = lifetime; 4637c478bd9Sstevel@tonic-gate this.timeStamp = SLPConfig.currentSLPTime() + lifetime; 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate // Create the signature: create and sign the hash 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate try { 4687c478bd9Sstevel@tonic-gate // @@@ how to sign for different aliases? 4697c478bd9Sstevel@tonic-gate sig.initSign(null); 4707c478bd9Sstevel@tonic-gate computeHash(); 4717c478bd9Sstevel@tonic-gate abBytes = sig.sign(); 4727c478bd9Sstevel@tonic-gate } catch (InvalidKeyException e) { // @@@ will change for AMI 4737c478bd9Sstevel@tonic-gate SLPConfig conf = SLPConfig.getSLPConfig(); 474*55fea89dSDan Cross throw 4757c478bd9Sstevel@tonic-gate new IllegalArgumentException( 4767c478bd9Sstevel@tonic-gate conf.formatMessage( 4777c478bd9Sstevel@tonic-gate "cant_sign_for_spi", 478*55fea89dSDan Cross new Object[] { 479*55fea89dSDan Cross spi, 4807c478bd9Sstevel@tonic-gate e.getMessage() })); 4817c478bd9Sstevel@tonic-gate } catch (SignatureException e) { 4827c478bd9Sstevel@tonic-gate SLPConfig conf = SLPConfig.getSLPConfig(); 483*55fea89dSDan Cross throw 4847c478bd9Sstevel@tonic-gate new IllegalArgumentException( 4857c478bd9Sstevel@tonic-gate conf.formatMessage( 4867c478bd9Sstevel@tonic-gate "cant_sign_for_spi", 487*55fea89dSDan Cross new Object[] { 488*55fea89dSDan Cross spi, 4897c478bd9Sstevel@tonic-gate e.getMessage() })); 4907c478bd9Sstevel@tonic-gate } 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate // calculate the length 4937c478bd9Sstevel@tonic-gate abLength = 4947c478bd9Sstevel@tonic-gate 2 + // bsd 4957c478bd9Sstevel@tonic-gate 2 + // length 4967c478bd9Sstevel@tonic-gate 4 + // timestamp 4977c478bd9Sstevel@tonic-gate spiBytes.length + // externalized SPI string, with length 4987c478bd9Sstevel@tonic-gate abBytes.length; // structured auth block 4997c478bd9Sstevel@tonic-gate } 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate /** 5027c478bd9Sstevel@tonic-gate * Creates a new AuthBlock from an input stream. 5037c478bd9Sstevel@tonic-gate * 5047c478bd9Sstevel@tonic-gate * @param hdr The header of the message being parsed. 5057c478bd9Sstevel@tonic-gate * @param message The ordered components of the SLP message 5067c478bd9Sstevel@tonic-gate * over which the signature should have been computed, 5077c478bd9Sstevel@tonic-gate * in externalized (byte[]) form. 5087c478bd9Sstevel@tonic-gate * @param dis Input stream with the auth block bytes queued up as the 5097c478bd9Sstevel@tonic-gate * next thing. 5107c478bd9Sstevel@tonic-gate * @exception ServiceLocationException If anything goes wrong during 5117c478bd9Sstevel@tonic-gate * parsing. If nBlocks is 0, the 5127c478bd9Sstevel@tonic-gate * error code is AUTHENTICATION_ABSENT. 5137c478bd9Sstevel@tonic-gate * @exception IllegalArgumentException If any of the parameters are null 5147c478bd9Sstevel@tonic-gate * or empty. 5157c478bd9Sstevel@tonic-gate * @exception IOException If DataInputStream throws it. 5167c478bd9Sstevel@tonic-gate */ AuthBlock(SrvLocHeader hdr, Object[] message, DataInputStream dis)5177c478bd9Sstevel@tonic-gate AuthBlock(SrvLocHeader hdr, Object[] message, DataInputStream dis) 5187c478bd9Sstevel@tonic-gate throws ServiceLocationException, 5197c478bd9Sstevel@tonic-gate IllegalArgumentException, 5207c478bd9Sstevel@tonic-gate IOException { 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate Assert.nonNullParameter(hdr, "hdr"); 5237c478bd9Sstevel@tonic-gate ensureNonEmpty(message, "message"); 5247c478bd9Sstevel@tonic-gate Assert.nonNullParameter(dis, "dis"); 5257c478bd9Sstevel@tonic-gate 5267c478bd9Sstevel@tonic-gate this.message = message; 5277c478bd9Sstevel@tonic-gate this.eqSet = new HashSet(); 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate // parse in the auth block from the input stream; 5307c478bd9Sstevel@tonic-gate // first get the BSD and length 5317c478bd9Sstevel@tonic-gate bsd = hdr.getInt(dis); 5327c478bd9Sstevel@tonic-gate abLength = hdr.getInt(dis); 5337c478bd9Sstevel@tonic-gate 5347c478bd9Sstevel@tonic-gate int pos = 4; // bsd and length have already been consumed 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate // get the timestamp 5377c478bd9Sstevel@tonic-gate timeStamp = getInt32(dis); 5387c478bd9Sstevel@tonic-gate pos += 4; 5397c478bd9Sstevel@tonic-gate hdr.nbytes += 4; 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate // get the SPI 5427c478bd9Sstevel@tonic-gate StringBuffer buf = new StringBuffer(); 5437c478bd9Sstevel@tonic-gate hdr.getString(buf, dis); 5447c478bd9Sstevel@tonic-gate spi = buf.toString(); 5457c478bd9Sstevel@tonic-gate if (spi.length() == 0) { 5467c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 5477c478bd9Sstevel@tonic-gate ServiceLocationException.PARSE_ERROR, 5487c478bd9Sstevel@tonic-gate "no_spi_string", 5497c478bd9Sstevel@tonic-gate new Object[0]); 5507c478bd9Sstevel@tonic-gate } 5517c478bd9Sstevel@tonic-gate pos += (2 + spi.length()); 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate // get the structured auth block 5547c478bd9Sstevel@tonic-gate abBytes = new byte[abLength - pos]; 5557c478bd9Sstevel@tonic-gate dis.readFully(abBytes, 0, abLength - pos); 5567c478bd9Sstevel@tonic-gate hdr.nbytes += abBytes.length; 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate // calculate remaining lifetime from timestamp 5597c478bd9Sstevel@tonic-gate long time = timeStamp - SLPConfig.currentSLPTime(); 5607c478bd9Sstevel@tonic-gate time = time <= Integer.MAX_VALUE ? time : 0; // no crazy values 5617c478bd9Sstevel@tonic-gate lifetime = (int) time; 5627c478bd9Sstevel@tonic-gate lifetime = lifetime < 0 ? 0 : lifetime; 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate // Initialize the crypto provider 5657c478bd9Sstevel@tonic-gate getSecurityProvider(bsd); 5667c478bd9Sstevel@tonic-gate } 5677c478bd9Sstevel@tonic-gate 5687c478bd9Sstevel@tonic-gate /** 5697c478bd9Sstevel@tonic-gate * Gets the size of this auth block, after externalization, in bytes. 5707c478bd9Sstevel@tonic-gate * 5717c478bd9Sstevel@tonic-gate * @return The number of bytes in this auth block. 5727c478bd9Sstevel@tonic-gate */ 5737c478bd9Sstevel@tonic-gate int nBytes() { 5747c478bd9Sstevel@tonic-gate return abLength; 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate 5777c478bd9Sstevel@tonic-gate /** 5787c478bd9Sstevel@tonic-gate * Returns the message parts obtained from the AuthBlock contructor. 5797c478bd9Sstevel@tonic-gate * The Object[] will not have been altered. 5807c478bd9Sstevel@tonic-gate * 5817c478bd9Sstevel@tonic-gate * @return This auth block's message components Object[]. 5827c478bd9Sstevel@tonic-gate */ 5837c478bd9Sstevel@tonic-gate Object[] getMessageParts() { 5847c478bd9Sstevel@tonic-gate return message; 5857c478bd9Sstevel@tonic-gate } 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate /** 5887c478bd9Sstevel@tonic-gate * Verifies the signature on this auth block. 5897c478bd9Sstevel@tonic-gate * 5907c478bd9Sstevel@tonic-gate * @exception ServiceLocationException Thrown if authentication fails, 5917c478bd9Sstevel@tonic-gate * with the error code 5927c478bd9Sstevel@tonic-gate * ServiceLocationException.AUTHENTICATION_FAILED. If any 5937c478bd9Sstevel@tonic-gate * other error occurs during authentication, the 5947c478bd9Sstevel@tonic-gate * error code is ServiceLocationException.SYSTEM_ERROR. 5957c478bd9Sstevel@tonic-gate * If the signature hasn't been calculated, the 5967c478bd9Sstevel@tonic-gate * fails. 5977c478bd9Sstevel@tonic-gate */ 5987c478bd9Sstevel@tonic-gate void verify() throws ServiceLocationException { 5997c478bd9Sstevel@tonic-gate // Load the keystore 6007c478bd9Sstevel@tonic-gate KeyStore ks = null; 6017c478bd9Sstevel@tonic-gate try { 6027c478bd9Sstevel@tonic-gate ks = KeyStore.getInstance("amicerts", "SunAMI"); 6037c478bd9Sstevel@tonic-gate ks.load(null, null); 6047c478bd9Sstevel@tonic-gate } catch (Exception e) { 605*55fea89dSDan Cross throw 6067c478bd9Sstevel@tonic-gate new ServiceLocationException( 6077c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 6087c478bd9Sstevel@tonic-gate "no_keystore", 6097c478bd9Sstevel@tonic-gate new Object[] {e.getMessage()}); 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate // Unescape the SPI for cleaner logging 6137c478bd9Sstevel@tonic-gate String u_DN = null; 6147c478bd9Sstevel@tonic-gate try { 6157c478bd9Sstevel@tonic-gate u_DN = 6167c478bd9Sstevel@tonic-gate ServiceLocationAttribute.unescapeAttributeString(spi, false); 6177c478bd9Sstevel@tonic-gate } catch (ServiceLocationException e) { 6187c478bd9Sstevel@tonic-gate u_DN = spi; 6197c478bd9Sstevel@tonic-gate } 6207c478bd9Sstevel@tonic-gate 6217c478bd9Sstevel@tonic-gate // get cert for this spi 6227c478bd9Sstevel@tonic-gate X509Certificate cert = getCert(spi, ks); 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate // check cert validity 6257c478bd9Sstevel@tonic-gate try { 6267c478bd9Sstevel@tonic-gate cert.checkValidity(); 6277c478bd9Sstevel@tonic-gate } catch (CertificateException e) { 6287c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 6297c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 6307c478bd9Sstevel@tonic-gate "invalid_cert", 6317c478bd9Sstevel@tonic-gate new Object[] {u_DN, e.getMessage()}); 6327c478bd9Sstevel@tonic-gate } 6337c478bd9Sstevel@tonic-gate 6347c478bd9Sstevel@tonic-gate // check the lifetime 6357c478bd9Sstevel@tonic-gate if (lifetime == 0) { 6367c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 6377c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 6387c478bd9Sstevel@tonic-gate "timestamp_failure", 6397c478bd9Sstevel@tonic-gate new Object[] {u_DN}); 6407c478bd9Sstevel@tonic-gate } 6417c478bd9Sstevel@tonic-gate 6427c478bd9Sstevel@tonic-gate // make sure this SPI matches up with configured SPIs 6437c478bd9Sstevel@tonic-gate try { 6447c478bd9Sstevel@tonic-gate checkSPIs(cert, ks); 6457c478bd9Sstevel@tonic-gate } catch (GeneralSecurityException e) { 6467c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 6477c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 6487c478bd9Sstevel@tonic-gate "cant_match_spis", 6497c478bd9Sstevel@tonic-gate new Object[] {cert.getSubjectDN(), e.getMessage()}); 6507c478bd9Sstevel@tonic-gate } 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate 6537c478bd9Sstevel@tonic-gate // check the signature 6547c478bd9Sstevel@tonic-gate try { 6557c478bd9Sstevel@tonic-gate sig.initVerify(cert.getPublicKey()); 6567c478bd9Sstevel@tonic-gate } catch (InvalidKeyException ex) { 657*55fea89dSDan Cross throw 6587c478bd9Sstevel@tonic-gate new ServiceLocationException( 6597c478bd9Sstevel@tonic-gate ServiceLocationException.INTERNAL_SYSTEM_ERROR, 6607c478bd9Sstevel@tonic-gate "init_verify_failure", 6617c478bd9Sstevel@tonic-gate new Object[] { 6627c478bd9Sstevel@tonic-gate u_DN, 6637c478bd9Sstevel@tonic-gate ex.getMessage()}); 6647c478bd9Sstevel@tonic-gate } 6657c478bd9Sstevel@tonic-gate 6667c478bd9Sstevel@tonic-gate computeHash(); 6677c478bd9Sstevel@tonic-gate 6687c478bd9Sstevel@tonic-gate ServiceLocationException vex = 6697c478bd9Sstevel@tonic-gate new ServiceLocationException( 6707c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 6717c478bd9Sstevel@tonic-gate "verify_failure", 6727c478bd9Sstevel@tonic-gate new Object[] {u_DN}); 6737c478bd9Sstevel@tonic-gate 6747c478bd9Sstevel@tonic-gate try { 6757c478bd9Sstevel@tonic-gate if (!sig.verify(abBytes)) 6767c478bd9Sstevel@tonic-gate throw vex; 6777c478bd9Sstevel@tonic-gate } catch (SignatureException ex) { 6787c478bd9Sstevel@tonic-gate throw vex; 6797c478bd9Sstevel@tonic-gate } 6807c478bd9Sstevel@tonic-gate } 6817c478bd9Sstevel@tonic-gate 6827c478bd9Sstevel@tonic-gate /** 6837c478bd9Sstevel@tonic-gate * Convert the auth block into its on-the-wire format. 6847c478bd9Sstevel@tonic-gate * 6857c478bd9Sstevel@tonic-gate * @param hdr The header of the message being parsed out. 6867c478bd9Sstevel@tonic-gate * @param baos The output stream into which to write. 6877c478bd9Sstevel@tonic-gate * @exception ServiceLocationException Thrown if an error occurs during 6887c478bd9Sstevel@tonic-gate * output, with PARSE_ERROR error code. 6897c478bd9Sstevel@tonic-gate * @exception IllegalArgumentException If any baos is null. 6907c478bd9Sstevel@tonic-gate */ 6917c478bd9Sstevel@tonic-gate void externalize(SrvLocHeader hdr, ByteArrayOutputStream baos) 6927c478bd9Sstevel@tonic-gate throws ServiceLocationException, IllegalArgumentException { 6937c478bd9Sstevel@tonic-gate 6947c478bd9Sstevel@tonic-gate Assert.nonNullParameter(hdr, "hdr"); 6957c478bd9Sstevel@tonic-gate Assert.nonNullParameter(baos, "baos"); 6967c478bd9Sstevel@tonic-gate 6977c478bd9Sstevel@tonic-gate // Lay out the auth block, starting with the BSD 6987c478bd9Sstevel@tonic-gate hdr.putInt(bsd, baos); 6997c478bd9Sstevel@tonic-gate 7007c478bd9Sstevel@tonic-gate // write out the length 7017c478bd9Sstevel@tonic-gate hdr.putInt(abLength, baos); 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate // calculate and write out the timestamp 7047c478bd9Sstevel@tonic-gate putInt32(timeStamp, baos); 7057c478bd9Sstevel@tonic-gate hdr.nbytes += 4; 7067c478bd9Sstevel@tonic-gate 7077c478bd9Sstevel@tonic-gate // write the SPI string 7087c478bd9Sstevel@tonic-gate hdr.putString(spi, baos); 7097c478bd9Sstevel@tonic-gate 7107c478bd9Sstevel@tonic-gate // Finish by writting the structured auth block 7117c478bd9Sstevel@tonic-gate baos.write(abBytes, 0, abBytes.length); 7127c478bd9Sstevel@tonic-gate hdr.nbytes += abBytes.length; 7137c478bd9Sstevel@tonic-gate } 7147c478bd9Sstevel@tonic-gate 7157c478bd9Sstevel@tonic-gate /** 7167c478bd9Sstevel@tonic-gate * Returns the SPI associated with this auth block. 7177c478bd9Sstevel@tonic-gate * 7187c478bd9Sstevel@tonic-gate * @return The SLP SPI for this auth block. 7197c478bd9Sstevel@tonic-gate */ 7207c478bd9Sstevel@tonic-gate String getSPI() { 7217c478bd9Sstevel@tonic-gate return spi; 7227c478bd9Sstevel@tonic-gate } 7237c478bd9Sstevel@tonic-gate 7247c478bd9Sstevel@tonic-gate /** 7257c478bd9Sstevel@tonic-gate * Returns the lifetime computed from this auth block. 7267c478bd9Sstevel@tonic-gate * 7277c478bd9Sstevel@tonic-gate * @return The lifetime from this auth block. 7287c478bd9Sstevel@tonic-gate */ 7297c478bd9Sstevel@tonic-gate int getLifetime() { 7307c478bd9Sstevel@tonic-gate return lifetime; 7317c478bd9Sstevel@tonic-gate } 7327c478bd9Sstevel@tonic-gate 7337c478bd9Sstevel@tonic-gate /** 7347c478bd9Sstevel@tonic-gate * Given a BSD, sets this AuthBlock's Signature to the 7357c478bd9Sstevel@tonic-gate * right algorithm. 7367c478bd9Sstevel@tonic-gate */ 7377c478bd9Sstevel@tonic-gate private void getSecurityProvider(int bsd) 7387c478bd9Sstevel@tonic-gate throws ServiceLocationException { 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate String algo = "Unknown BSD"; 7417c478bd9Sstevel@tonic-gate try { 7427c478bd9Sstevel@tonic-gate if (bsd == 2) { 7437c478bd9Sstevel@tonic-gate // get DSA/SHA1 provider 7447c478bd9Sstevel@tonic-gate algo = "DSA"; 7457c478bd9Sstevel@tonic-gate sig = Signature.getInstance("SHA/DSA", "SunAMI"); 7467c478bd9Sstevel@tonic-gate return; 7477c478bd9Sstevel@tonic-gate } else if (bsd == 1) { 7487c478bd9Sstevel@tonic-gate algo = "MD5/RSA"; 7497c478bd9Sstevel@tonic-gate sig = Signature.getInstance("MD5/RSA", "SunAMI"); 7507c478bd9Sstevel@tonic-gate return; 7517c478bd9Sstevel@tonic-gate } else if (bsd == 3) { 7527c478bd9Sstevel@tonic-gate algo = "Keyed HMAC with MD5"; 7537c478bd9Sstevel@tonic-gate } 7547c478bd9Sstevel@tonic-gate } catch (GeneralSecurityException e) { 7557c478bd9Sstevel@tonic-gate // system error -- no such provider 7567c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 7577c478bd9Sstevel@tonic-gate ServiceLocationException.INTERNAL_SYSTEM_ERROR, 7587c478bd9Sstevel@tonic-gate "cant_get_security_provider", 7597c478bd9Sstevel@tonic-gate new Object[] { 7607c478bd9Sstevel@tonic-gate new Integer(bsd), 7617c478bd9Sstevel@tonic-gate algo, 7627c478bd9Sstevel@tonic-gate e.getMessage()}); 7637c478bd9Sstevel@tonic-gate } 7647c478bd9Sstevel@tonic-gate 7657c478bd9Sstevel@tonic-gate // Unknown or unsupported BSD 7667c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 7677c478bd9Sstevel@tonic-gate ServiceLocationException.INTERNAL_SYSTEM_ERROR, 7687c478bd9Sstevel@tonic-gate "cant_get_security_provider", 7697c478bd9Sstevel@tonic-gate new Object[] { 7707c478bd9Sstevel@tonic-gate new Integer(bsd), 7717c478bd9Sstevel@tonic-gate algo, 7727c478bd9Sstevel@tonic-gate "Unknown or unsupported BSD"}); 7737c478bd9Sstevel@tonic-gate } 7747c478bd9Sstevel@tonic-gate 7757c478bd9Sstevel@tonic-gate /** 7767c478bd9Sstevel@tonic-gate * throws an IllegalArgumentException if v is null or empty. 7777c478bd9Sstevel@tonic-gate * v can be either a Hashtable or a Object[]. 7787c478bd9Sstevel@tonic-gate */ 7797c478bd9Sstevel@tonic-gate static private void ensureNonEmpty(Object v, String param) 7807c478bd9Sstevel@tonic-gate throws IllegalArgumentException { 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate int size = 0; 7837c478bd9Sstevel@tonic-gate if (v != null) { 7847c478bd9Sstevel@tonic-gate if (v instanceof Object[]) { 7857c478bd9Sstevel@tonic-gate size = ((Object[]) v).length; 7867c478bd9Sstevel@tonic-gate } else { 7877c478bd9Sstevel@tonic-gate // this will force a class cast exception if not a Hashtable 7887c478bd9Sstevel@tonic-gate size = ((Hashtable) v).size(); 7897c478bd9Sstevel@tonic-gate } 7907c478bd9Sstevel@tonic-gate } 7917c478bd9Sstevel@tonic-gate 7927c478bd9Sstevel@tonic-gate if (v == null || size == 0) { 7937c478bd9Sstevel@tonic-gate SLPConfig conf = SLPConfig.getSLPConfig(); 794*55fea89dSDan Cross String msg = 7957c478bd9Sstevel@tonic-gate conf.formatMessage("null_or_empty_vector", 7967c478bd9Sstevel@tonic-gate new Object[] {param}); 7977c478bd9Sstevel@tonic-gate throw 7987c478bd9Sstevel@tonic-gate new IllegalArgumentException(msg); 7997c478bd9Sstevel@tonic-gate } 8007c478bd9Sstevel@tonic-gate } 8017c478bd9Sstevel@tonic-gate 8027c478bd9Sstevel@tonic-gate /** 8037c478bd9Sstevel@tonic-gate * Computes a hash over the SPI String, message componenets, 8047c478bd9Sstevel@tonic-gate * and timstamp. Which hash is used depends on which crypto 8057c478bd9Sstevel@tonic-gate * provider was installed. 8067c478bd9Sstevel@tonic-gate * 8077c478bd9Sstevel@tonic-gate * This method assumes that the class variables spi, sig, 8087c478bd9Sstevel@tonic-gate * message, and timeStamp have all been initialized. As a side 8097c478bd9Sstevel@tonic-gate * effect, it places the externalized SPI String into spiBytes. 8107c478bd9Sstevel@tonic-gate */ 8117c478bd9Sstevel@tonic-gate private void computeHash() throws ServiceLocationException { 8127c478bd9Sstevel@tonic-gate try { 8137c478bd9Sstevel@tonic-gate // get the SPI String bytes 8147c478bd9Sstevel@tonic-gate ByteArrayOutputStream baosT = new ByteArrayOutputStream(); 8157c478bd9Sstevel@tonic-gate SrvLocHeader.putStringField(spi, baosT, Defaults.UTF8); 8167c478bd9Sstevel@tonic-gate spiBytes = baosT.toByteArray(); 8177c478bd9Sstevel@tonic-gate sig.update(spiBytes); 8187c478bd9Sstevel@tonic-gate 8197c478bd9Sstevel@tonic-gate // Add each message component 8207c478bd9Sstevel@tonic-gate int mSize = message.length; 8217c478bd9Sstevel@tonic-gate for (int i = 0; i < mSize; i++) { 8227c478bd9Sstevel@tonic-gate sig.update((byte[]) message[i]); 8237c478bd9Sstevel@tonic-gate } 8247c478bd9Sstevel@tonic-gate 8257c478bd9Sstevel@tonic-gate // end by adding the timestamp 8267c478bd9Sstevel@tonic-gate baosT = new ByteArrayOutputStream(); 8277c478bd9Sstevel@tonic-gate putInt32(timeStamp, baosT); 8287c478bd9Sstevel@tonic-gate sig.update(baosT.toByteArray()); 8297c478bd9Sstevel@tonic-gate } catch (SignatureException e) { 8307c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 8317c478bd9Sstevel@tonic-gate ServiceLocationException.INTERNAL_SYSTEM_ERROR, 8327c478bd9Sstevel@tonic-gate "cant_compute_hash", 8337c478bd9Sstevel@tonic-gate new Object[] {e.getMessage()}); 8347c478bd9Sstevel@tonic-gate } 8357c478bd9Sstevel@tonic-gate } 8367c478bd9Sstevel@tonic-gate 8377c478bd9Sstevel@tonic-gate static private long getInt32(DataInputStream dis) throws IOException { 8387c478bd9Sstevel@tonic-gate byte[] bytes = new byte[4]; 8397c478bd9Sstevel@tonic-gate 8407c478bd9Sstevel@tonic-gate dis.readFully(bytes, 0, 4); 8417c478bd9Sstevel@tonic-gate 8427c478bd9Sstevel@tonic-gate long a = (long)(bytes[0] & 0xFF); 8437c478bd9Sstevel@tonic-gate long b = (long)(bytes[1] & 0xFF); 8447c478bd9Sstevel@tonic-gate long c = (long)(bytes[2] & 0xFF); 8457c478bd9Sstevel@tonic-gate long d = (long)(bytes[3] & 0xFF); 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate long i = a << 24; 8487c478bd9Sstevel@tonic-gate i += b << 16; 8497c478bd9Sstevel@tonic-gate i += c << 8; 8507c478bd9Sstevel@tonic-gate i += d; 8517c478bd9Sstevel@tonic-gate 8527c478bd9Sstevel@tonic-gate return i; 8537c478bd9Sstevel@tonic-gate } 8547c478bd9Sstevel@tonic-gate 8557c478bd9Sstevel@tonic-gate static private void putInt32(long i, ByteArrayOutputStream baos) { 8567c478bd9Sstevel@tonic-gate baos.write((byte) ((i >> 24) & 0xFF)); 8577c478bd9Sstevel@tonic-gate baos.write((byte) ((i >> 16) & 0xFF)); 8587c478bd9Sstevel@tonic-gate baos.write((byte) ((i >> 8) & 0xFF)); 8597c478bd9Sstevel@tonic-gate baos.write((byte) (i & 0XFF)); 8607c478bd9Sstevel@tonic-gate } 8617c478bd9Sstevel@tonic-gate 8627c478bd9Sstevel@tonic-gate /** 8637c478bd9Sstevel@tonic-gate * Determines if this process' SPI configuration allows 8647c478bd9Sstevel@tonic-gate * messages signed by 'cert' to be verified. This method 8657c478bd9Sstevel@tonic-gate * also verifies and validates 'cert's cert chain. 8667c478bd9Sstevel@tonic-gate */ 8677c478bd9Sstevel@tonic-gate private void checkSPIs(X509Certificate cert, KeyStore ks) 8687c478bd9Sstevel@tonic-gate throws ServiceLocationException, GeneralSecurityException { 8697c478bd9Sstevel@tonic-gate 8707c478bd9Sstevel@tonic-gate // get the list of configured SPIs 8717c478bd9Sstevel@tonic-gate String conf_spis = System.getProperty("sun.net.slp.SPIs"); 8727c478bd9Sstevel@tonic-gate if (conf_spis == null) { 8737c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 8747c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 8757c478bd9Sstevel@tonic-gate "no_spis_configured", new Object[0]); 8767c478bd9Sstevel@tonic-gate } 8777c478bd9Sstevel@tonic-gate 8787c478bd9Sstevel@tonic-gate // Get cert chain 8797c478bd9Sstevel@tonic-gate java.security.cert.Certificate[] chain = 8807c478bd9Sstevel@tonic-gate ks.getCertificateChain(cert.getSubjectDN().toString()); 8817c478bd9Sstevel@tonic-gate if (chain == null) { 8827c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 8837c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 8847c478bd9Sstevel@tonic-gate "no_cert_chain", 8857c478bd9Sstevel@tonic-gate new Object[] {cert.getSubjectDN().toString()}); 8867c478bd9Sstevel@tonic-gate } 8877c478bd9Sstevel@tonic-gate 8887c478bd9Sstevel@tonic-gate // validate all links in chain 8897c478bd9Sstevel@tonic-gate int i = 0; 8907c478bd9Sstevel@tonic-gate try { 8917c478bd9Sstevel@tonic-gate // Add cert's own subjec to equiv set 8927c478bd9Sstevel@tonic-gate eqSet.add(((X509Certificate)chain[0]).getSubjectDN()); 8937c478bd9Sstevel@tonic-gate 8947c478bd9Sstevel@tonic-gate for (i = 1; i < chain.length; i++) { 8957c478bd9Sstevel@tonic-gate ((X509Certificate)chain[i]).checkValidity(); 8967c478bd9Sstevel@tonic-gate chain[i-1].verify(chain[i].getPublicKey(), "SunAMI"); 8977c478bd9Sstevel@tonic-gate 8987c478bd9Sstevel@tonic-gate // OK, so add to equivalency set 8997c478bd9Sstevel@tonic-gate eqSet.add(((X509Certificate)chain[i]).getSubjectDN()); 9007c478bd9Sstevel@tonic-gate } 9017c478bd9Sstevel@tonic-gate } catch (ClassCastException e) { 9027c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 9037c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 9047c478bd9Sstevel@tonic-gate "not_x509cert", 9057c478bd9Sstevel@tonic-gate new Object[] { chain[i].getType(), e.getMessage() }); 9067c478bd9Sstevel@tonic-gate } 9077c478bd9Sstevel@tonic-gate 9087c478bd9Sstevel@tonic-gate if (configuredToVerify(chain, conf_spis, ks)) { 9097c478bd9Sstevel@tonic-gate return; 9107c478bd9Sstevel@tonic-gate } 9117c478bd9Sstevel@tonic-gate 9127c478bd9Sstevel@tonic-gate // if we get here, no SPIs matched, so the authentication fails 9137c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 9147c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 9157c478bd9Sstevel@tonic-gate "cant_match_spis", 9167c478bd9Sstevel@tonic-gate new Object[] {cert.getSubjectDN().toString(), ""}); 9177c478bd9Sstevel@tonic-gate } 9187c478bd9Sstevel@tonic-gate 9197c478bd9Sstevel@tonic-gate /** 9207c478bd9Sstevel@tonic-gate * Determines if, given a set of SPIs 'conf_spis', we can 9217c478bd9Sstevel@tonic-gate * verify a message signed by the Principal named by 'cert'. 9227c478bd9Sstevel@tonic-gate */ 9237c478bd9Sstevel@tonic-gate static private boolean configuredToVerify( 9247c478bd9Sstevel@tonic-gate java.security.cert.Certificate[] chain, 9257c478bd9Sstevel@tonic-gate String conf_spis, 9267c478bd9Sstevel@tonic-gate KeyStore ks) { 9277c478bd9Sstevel@tonic-gate 9287c478bd9Sstevel@tonic-gate StringTokenizer stk = new StringTokenizer(conf_spis, ","); 9297c478bd9Sstevel@tonic-gate while (stk.hasMoreTokens()) { 9307c478bd9Sstevel@tonic-gate String spi; 9317c478bd9Sstevel@tonic-gate 9327c478bd9Sstevel@tonic-gate try { 9337c478bd9Sstevel@tonic-gate spi = stk.nextToken(); 9347c478bd9Sstevel@tonic-gate } catch (NoSuchElementException e) { 9357c478bd9Sstevel@tonic-gate break; 9367c478bd9Sstevel@tonic-gate } 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate // get CA cert to get CA Principal 9397c478bd9Sstevel@tonic-gate Principal ca; 9407c478bd9Sstevel@tonic-gate try { 9417c478bd9Sstevel@tonic-gate X509Certificate cacert = getCert(spi, ks); 9427c478bd9Sstevel@tonic-gate ca = cacert.getSubjectDN(); 9437c478bd9Sstevel@tonic-gate } catch (ServiceLocationException e) { 9447c478bd9Sstevel@tonic-gate SLPConfig.getSLPConfig().writeLog( 9457c478bd9Sstevel@tonic-gate "cant_process_spi", 9467c478bd9Sstevel@tonic-gate new Object[] {spi, e.getMessage()}); 9477c478bd9Sstevel@tonic-gate continue; 9487c478bd9Sstevel@tonic-gate } 9497c478bd9Sstevel@tonic-gate 9507c478bd9Sstevel@tonic-gate if (onCertChain(ca, chain)) { 9517c478bd9Sstevel@tonic-gate return true; 9527c478bd9Sstevel@tonic-gate } 9537c478bd9Sstevel@tonic-gate } 9547c478bd9Sstevel@tonic-gate 9557c478bd9Sstevel@tonic-gate return false; 9567c478bd9Sstevel@tonic-gate } 9577c478bd9Sstevel@tonic-gate 9587c478bd9Sstevel@tonic-gate /** 9597c478bd9Sstevel@tonic-gate * Determines if sub if equivalent to ca by getting sub's cert 9607c478bd9Sstevel@tonic-gate * chain and walking the chain looking for ca. 9617c478bd9Sstevel@tonic-gate * This routine does not verify the cert chain. 9627c478bd9Sstevel@tonic-gate */ 9637c478bd9Sstevel@tonic-gate private static boolean onCertChain(String sub, Principal ca) 9647c478bd9Sstevel@tonic-gate throws ServiceLocationException { 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate java.security.cert.Certificate[] chain; 9677c478bd9Sstevel@tonic-gate 9687c478bd9Sstevel@tonic-gate ServiceLocationException ex = new ServiceLocationException( 9697c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_UNKNOWN, 9707c478bd9Sstevel@tonic-gate "no_cert_chain", 9717c478bd9Sstevel@tonic-gate new Object[] {sub}); 9727c478bd9Sstevel@tonic-gate 9737c478bd9Sstevel@tonic-gate try { 9747c478bd9Sstevel@tonic-gate // Get cert keystore 9757c478bd9Sstevel@tonic-gate KeyStore ks = getKeyStore(); 9767c478bd9Sstevel@tonic-gate 9777c478bd9Sstevel@tonic-gate // Get cert chain for subject 9787c478bd9Sstevel@tonic-gate chain = ks.getCertificateChain(sub); 9797c478bd9Sstevel@tonic-gate } catch (KeyStoreException e) { 9807c478bd9Sstevel@tonic-gate throw ex; 9817c478bd9Sstevel@tonic-gate } 9827c478bd9Sstevel@tonic-gate 9837c478bd9Sstevel@tonic-gate if (chain == null) { 9847c478bd9Sstevel@tonic-gate throw ex; 9857c478bd9Sstevel@tonic-gate } 9867c478bd9Sstevel@tonic-gate 9877c478bd9Sstevel@tonic-gate // walk the cert chain 9887c478bd9Sstevel@tonic-gate return onCertChain(ca, chain); 9897c478bd9Sstevel@tonic-gate } 9907c478bd9Sstevel@tonic-gate 9917c478bd9Sstevel@tonic-gate /** 9927c478bd9Sstevel@tonic-gate * Operates the same as above, but rather than getting the cert 9937c478bd9Sstevel@tonic-gate * chain for sub, uses a given cert chain. 9947c478bd9Sstevel@tonic-gate */ 9957c478bd9Sstevel@tonic-gate private static boolean onCertChain(Principal ca, 9967c478bd9Sstevel@tonic-gate java.security.cert.Certificate[] chain) 9977c478bd9Sstevel@tonic-gate { 9987c478bd9Sstevel@tonic-gate // walk the cert chain 9997c478bd9Sstevel@tonic-gate for (int i = 0; i < chain.length; i++) { 10007c478bd9Sstevel@tonic-gate Principal sub = ((X509Certificate)chain[i]).getSubjectDN(); 10017c478bd9Sstevel@tonic-gate if (ca.equals(sub)) { 10027c478bd9Sstevel@tonic-gate return true; 10037c478bd9Sstevel@tonic-gate } 10047c478bd9Sstevel@tonic-gate } 10057c478bd9Sstevel@tonic-gate 10067c478bd9Sstevel@tonic-gate return false; 10077c478bd9Sstevel@tonic-gate } 10087c478bd9Sstevel@tonic-gate 10097c478bd9Sstevel@tonic-gate /** 10107c478bd9Sstevel@tonic-gate * Returns true if someDN is in this AuthBlock's equivalence set. 10117c478bd9Sstevel@tonic-gate */ 10127c478bd9Sstevel@tonic-gate private boolean inEqSet(Principal someDN) { 10137c478bd9Sstevel@tonic-gate return eqSet.contains(someDN); 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate 10167c478bd9Sstevel@tonic-gate /** 10177c478bd9Sstevel@tonic-gate * Retrieves from the KeyStore 'ks' the X509Certificate named 10187c478bd9Sstevel@tonic-gate * by DN. 10197c478bd9Sstevel@tonic-gate */ 10207c478bd9Sstevel@tonic-gate static private X509Certificate getCert(String DN, KeyStore ks) 10217c478bd9Sstevel@tonic-gate throws ServiceLocationException { 10227c478bd9Sstevel@tonic-gate 10237c478bd9Sstevel@tonic-gate X509Certificate cert = null; 10247c478bd9Sstevel@tonic-gate 10257c478bd9Sstevel@tonic-gate // Unescape DN 10267c478bd9Sstevel@tonic-gate try { 10277c478bd9Sstevel@tonic-gate DN = ServiceLocationAttribute.unescapeAttributeString(DN, false); 10287c478bd9Sstevel@tonic-gate } catch (ServiceLocationException e) { 10297c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 10307c478bd9Sstevel@tonic-gate ServiceLocationException.PARSE_ERROR, 10317c478bd9Sstevel@tonic-gate "spi_parse_error", 10327c478bd9Sstevel@tonic-gate new Object[] {DN, e.getMessage()}); 10337c478bd9Sstevel@tonic-gate } 10347c478bd9Sstevel@tonic-gate 10357c478bd9Sstevel@tonic-gate try { 10367c478bd9Sstevel@tonic-gate cert = (X509Certificate)ks.getCertificate(DN); 10377c478bd9Sstevel@tonic-gate } catch (ClassCastException e) { 10387c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 10397c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 10407c478bd9Sstevel@tonic-gate "not_x509cert", 10417c478bd9Sstevel@tonic-gate new Object[] {cert.getType(), e.getMessage()}); 10427c478bd9Sstevel@tonic-gate } catch (KeyStoreException e) { 10437c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 10447c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 10457c478bd9Sstevel@tonic-gate "no_cert", 10467c478bd9Sstevel@tonic-gate new Object[] {DN, e.getMessage()}); 10477c478bd9Sstevel@tonic-gate } 10487c478bd9Sstevel@tonic-gate 10497c478bd9Sstevel@tonic-gate if (cert == null) { 10507c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 10517c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 10527c478bd9Sstevel@tonic-gate "no_cert", 10537c478bd9Sstevel@tonic-gate new Object[] {DN, "" }); 10547c478bd9Sstevel@tonic-gate } 10557c478bd9Sstevel@tonic-gate 10567c478bd9Sstevel@tonic-gate return cert; 10577c478bd9Sstevel@tonic-gate } 10587c478bd9Sstevel@tonic-gate 10597c478bd9Sstevel@tonic-gate /** 10607c478bd9Sstevel@tonic-gate * Gets a handle to the trusted key package for this process. 10617c478bd9Sstevel@tonic-gate */ 10627c478bd9Sstevel@tonic-gate static private synchronized KeyStore getKeyPkg() 10637c478bd9Sstevel@tonic-gate throws ServiceLocationException { 10647c478bd9Sstevel@tonic-gate 10657c478bd9Sstevel@tonic-gate if (keypkg != null) { 10667c478bd9Sstevel@tonic-gate return keypkg; 10677c478bd9Sstevel@tonic-gate } 10687c478bd9Sstevel@tonic-gate 10697c478bd9Sstevel@tonic-gate /* else load key store */ 10707c478bd9Sstevel@tonic-gate try { 10717c478bd9Sstevel@tonic-gate keypkg = KeyStore.getInstance("amiks", "SunAMI"); 10727c478bd9Sstevel@tonic-gate keypkg.load(null, null); 10737c478bd9Sstevel@tonic-gate } catch (Exception e) { 10747c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 10757c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 10767c478bd9Sstevel@tonic-gate "no_keystore", 10777c478bd9Sstevel@tonic-gate new Object[] {e.getMessage()}); 10787c478bd9Sstevel@tonic-gate } 10797c478bd9Sstevel@tonic-gate 10807c478bd9Sstevel@tonic-gate return keypkg; 10817c478bd9Sstevel@tonic-gate } 10827c478bd9Sstevel@tonic-gate 10837c478bd9Sstevel@tonic-gate /** 10847c478bd9Sstevel@tonic-gate * Gets a handle to a certificate repository. 10857c478bd9Sstevel@tonic-gate */ 10867c478bd9Sstevel@tonic-gate static private synchronized KeyStore getKeyStore() 10877c478bd9Sstevel@tonic-gate throws ServiceLocationException { 10887c478bd9Sstevel@tonic-gate 10897c478bd9Sstevel@tonic-gate if (keystore != null) { 10907c478bd9Sstevel@tonic-gate return keystore; 10917c478bd9Sstevel@tonic-gate } 10927c478bd9Sstevel@tonic-gate 10937c478bd9Sstevel@tonic-gate try { 10947c478bd9Sstevel@tonic-gate keystore = KeyStore.getInstance("amicerts", "SunAMI"); 10957c478bd9Sstevel@tonic-gate keystore.load(null, null); 10967c478bd9Sstevel@tonic-gate } catch (Exception e) { 1097*55fea89dSDan Cross throw 10987c478bd9Sstevel@tonic-gate new ServiceLocationException( 10997c478bd9Sstevel@tonic-gate ServiceLocationException.AUTHENTICATION_FAILED, 11007c478bd9Sstevel@tonic-gate "no_keystore", 11017c478bd9Sstevel@tonic-gate new Object[] {e.getMessage()}); 11027c478bd9Sstevel@tonic-gate } 11037c478bd9Sstevel@tonic-gate 11047c478bd9Sstevel@tonic-gate return keystore; 11057c478bd9Sstevel@tonic-gate } 11067c478bd9Sstevel@tonic-gate 11077c478bd9Sstevel@tonic-gate public String toString() { 11087c478bd9Sstevel@tonic-gate return "SPI=``" + spi + "''\n" + 11097c478bd9Sstevel@tonic-gate " BSD=``" + bsd + "''\n" + 11107c478bd9Sstevel@tonic-gate " timeStamp=``" + timeStamp + "''\n" + 11117c478bd9Sstevel@tonic-gate " AuthBlock bytes=" + abLength + " bytes\n"; 11127c478bd9Sstevel@tonic-gate } 11137c478bd9Sstevel@tonic-gate 11147c478bd9Sstevel@tonic-gate 11157c478bd9Sstevel@tonic-gate // Instance variables 11167c478bd9Sstevel@tonic-gate int bsd; 11177c478bd9Sstevel@tonic-gate String spi; 11187c478bd9Sstevel@tonic-gate Object[] message; 11197c478bd9Sstevel@tonic-gate int lifetime; // need both: lifetime is for optimization, 11207c478bd9Sstevel@tonic-gate long timeStamp; // timeStamp is needed to compute the hash 11217c478bd9Sstevel@tonic-gate SrvLocHeader hdr; 11227c478bd9Sstevel@tonic-gate Signature sig; 11237c478bd9Sstevel@tonic-gate int abLength; 11247c478bd9Sstevel@tonic-gate byte[] abBytes; 11257c478bd9Sstevel@tonic-gate byte[] spiBytes; 11267c478bd9Sstevel@tonic-gate HashSet eqSet; // built only during authblock verification 11277c478bd9Sstevel@tonic-gate 11287c478bd9Sstevel@tonic-gate // cached per process 11297c478bd9Sstevel@tonic-gate static private KeyStore keystore; // Certificate repository 11307c478bd9Sstevel@tonic-gate static private KeyStore keypkg; // My own keypkg 11317c478bd9Sstevel@tonic-gate } 1132