1 /* 2 * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.ssl; 27 28 import java.util.*; 29 30 /** 31 * A list of ProtocolVersions. Also maintains the list of supported protocols. 32 * Instances of this class are immutable. Some member variables are final 33 * and can be accessed directly without method accessors. 34 * 35 * @author Andreas Sterbenz 36 * @since 1.4.1 37 */ 38 final class ProtocolList { 39 40 // the sorted protocol version list 41 private final ArrayList<ProtocolVersion> protocols; 42 43 private String[] protocolNames; 44 45 // the minimum and maximum ProtocolVersions in this list 46 final ProtocolVersion min, max; 47 48 // the format for the hello version to use 49 final ProtocolVersion helloVersion; 50 ProtocolList(String[] names)51 ProtocolList(String[] names) { 52 this(convert(names)); 53 } 54 ProtocolList(ArrayList<ProtocolVersion> versions)55 ProtocolList(ArrayList<ProtocolVersion> versions) { 56 this.protocols = versions; 57 58 if ((protocols.size() == 1) && 59 protocols.contains(ProtocolVersion.SSL20Hello)) { 60 throw new IllegalArgumentException("SSLv2Hello cannot be " + 61 "enabled unless at least one other supported version " + 62 "is also enabled."); 63 } 64 65 if (protocols.size() != 0) { 66 Collections.sort(protocols); 67 min = protocols.get(0); 68 max = protocols.get(protocols.size() - 1); 69 helloVersion = protocols.get(0); 70 } else { 71 min = ProtocolVersion.NONE; 72 max = ProtocolVersion.NONE; 73 helloVersion = ProtocolVersion.NONE; 74 } 75 } 76 convert(String[] names)77 private static ArrayList<ProtocolVersion> convert(String[] names) { 78 if (names == null) { 79 throw new IllegalArgumentException("Protocols may not be null"); 80 } 81 82 ArrayList<ProtocolVersion> versions = new ArrayList<>(3); 83 for (int i = 0; i < names.length; i++ ) { 84 ProtocolVersion version = ProtocolVersion.valueOf(names[i]); 85 if (versions.contains(version) == false) { 86 versions.add(version); 87 } 88 } 89 90 return versions; 91 } 92 93 /** 94 * Return whether this list contains the specified protocol version. 95 * SSLv2Hello is not a real protocol version we support, we always 96 * return false for it. 97 */ contains(ProtocolVersion protocolVersion)98 boolean contains(ProtocolVersion protocolVersion) { 99 if (protocolVersion == ProtocolVersion.SSL20Hello) { 100 return false; 101 } 102 return protocols.contains(protocolVersion); 103 } 104 105 /** 106 * Return a reference to the internal Collection of CipherSuites. 107 * The Collection MUST NOT be modified. 108 */ collection()109 Collection<ProtocolVersion> collection() { 110 return protocols; 111 } 112 113 /** 114 * Select a protocol version from the list. 115 * 116 * Return the lower of the protocol version of that suggested by 117 * the <code>protocolVersion</code> and the highest version of this 118 * protocol list, or null if no protocol version is available. 119 * 120 * The method is used by TLS server to negotiated the protocol 121 * version between client suggested protocol version in the 122 * client hello and protocol versions supported by the server. 123 */ selectProtocolVersion(ProtocolVersion protocolVersion)124 ProtocolVersion selectProtocolVersion(ProtocolVersion protocolVersion) { 125 ProtocolVersion selectedVersion = null; 126 for (ProtocolVersion pv : protocols) { 127 if (pv.v > protocolVersion.v) { 128 break; // Safe to break here as this.protocols is sorted 129 } 130 selectedVersion = pv; 131 } 132 133 return selectedVersion; 134 } 135 136 /** 137 * Return an array with the names of the ProtocolVersions in this list. 138 */ toStringArray()139 synchronized String[] toStringArray() { 140 if (protocolNames == null) { 141 protocolNames = new String[protocols.size()]; 142 int i = 0; 143 for (ProtocolVersion version : protocols) { 144 protocolNames[i++] = version.name; 145 } 146 } 147 return protocolNames.clone(); 148 } 149 toString()150 public String toString() { 151 return protocols.toString(); 152 } 153 } 154