src/java.base/share/classes/sun/security/ssl/ProtocolVersion.java
changeset 50768 68fa3d4026ea
parent 47216 71c04702a3d5
child 51458 97300133cc23
equal deleted inserted replaced
50767:356eaea05bf0 50768:68fa3d4026ea
     1 /*
     1 /*
     2  * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package sun.security.ssl;
    26 package sun.security.ssl;
    27 
    27 
    28 import java.util.*;
       
    29 import java.security.CryptoPrimitive;
    28 import java.security.CryptoPrimitive;
    30 import sun.security.ssl.CipherSuite.*;
    29 import java.util.ArrayList;
       
    30 import java.util.Collections;
       
    31 import java.util.EnumSet;
       
    32 import java.util.List;
    31 
    33 
    32 /**
    34 /**
    33  * Type safe enum for an SSL/TLS protocol version. Instances are obtained
    35  * Enum for an SSL/TLS/DTLS protocol version.
    34  * using the static factory methods or by referencing the static members
       
    35  * in this class. Member variables are final and can be accessed without
       
    36  * accessor methods.
       
    37  *
       
    38  * There is only ever one instance per supported protocol version, this
       
    39  * means == can be used for comparision instead of equals() if desired.
       
    40  *
       
    41  * Checks for a particular version number should generally take this form:
       
    42  *
       
    43  * <pre>{@code
       
    44  * if (protocolVersion.v >= ProtocolVersion.TLS10) {
       
    45  *   // TLS 1.0 code goes here
       
    46  * } else {
       
    47  *   // SSL 3.0 code here
       
    48  * }
       
    49  * }</pre>
       
    50  *
    36  *
    51  * @author  Andreas Sterbenz
    37  * @author  Andreas Sterbenz
    52  * @since   1.4.1
    38  * @since   1.4.1
    53  */
    39  */
    54 public final class ProtocolVersion implements Comparable<ProtocolVersion> {
    40 enum ProtocolVersion {
       
    41 //    TLS13           (0x0304,    "TLSv1.3",      false),
       
    42     TLS13           (SSLConfiguration.tls13VN,    "TLSv1.3",      false),
       
    43     TLS12           (0x0303,    "TLSv1.2",      false),
       
    44     TLS11           (0x0302,    "TLSv1.1",      false),
       
    45     TLS10           (0x0301,    "TLSv1",        false),
       
    46     SSL30           (0x0300,    "SSLv3",        false),
       
    47     SSL20Hello      (0x0002,    "SSLv2Hello",   false),
       
    48 
       
    49     DTLS12          (0xFEFD,    "DTLSv1.2",     true),
       
    50     DTLS10          (0xFEFF,    "DTLSv1.0",     true),
       
    51 
       
    52     // Dummy protocol version value for invalid SSLSession
       
    53     NONE            (-1,        "NONE",         false);
       
    54 
       
    55 
       
    56     final int id;
       
    57     final String name;
       
    58     final boolean isDTLS;
       
    59     final byte major;
       
    60     final byte minor;
       
    61     final boolean isAvailable;
    55 
    62 
    56     // The limit of maximum protocol version
    63     // The limit of maximum protocol version
    57     static final int LIMIT_MAX_VALUE = 0xFFFF;
    64     static final int LIMIT_MAX_VALUE = 0xFFFF;
    58 
    65 
    59     // The limit of minimum protocol version
    66     // The limit of minimum protocol version
    60     static final int LIMIT_MIN_VALUE = 0x0000;
    67     static final int LIMIT_MIN_VALUE = 0x0000;
    61 
    68 
    62     // Dummy protocol version value for invalid SSLSession
    69     // (D)TLS ProtocolVersion array for TLS 1.0 and previous versions.
    63     static final ProtocolVersion NONE = new ProtocolVersion(-1, "NONE");
    70     static final ProtocolVersion[] PROTOCOLS_TO_10 = new ProtocolVersion[] {
    64 
    71             TLS10, SSL30
    65     // If enabled, send/accept SSLv2 hello messages
    72         };
    66     static final ProtocolVersion SSL20Hello =
    73 
    67                                 new ProtocolVersion(0x0002, "SSLv2Hello");
    74     // (D)TLS ProtocolVersion array for TLS 1.1/DTLS 1.0 and previous versions.
    68 
    75     static final ProtocolVersion[] PROTOCOLS_TO_11 = new ProtocolVersion[] {
    69     // SSL 3.0
    76             TLS11, TLS10, SSL30, DTLS10
    70     static final ProtocolVersion SSL30 = new ProtocolVersion(0x0300, "SSLv3");
    77         };
    71 
    78 
    72     // TLS 1.0
    79     // (D)TLS ProtocolVersion array for (D)TLS 1.2 and previous versions.
    73     static final ProtocolVersion TLS10 = new ProtocolVersion(0x0301, "TLSv1");
    80     static final ProtocolVersion[] PROTOCOLS_TO_12 = new ProtocolVersion[] {
    74 
    81             TLS12, TLS11, TLS10, SSL30, DTLS12, DTLS10
    75     // TLS 1.1
    82     };
    76     static final ProtocolVersion TLS11 = new ProtocolVersion(0x0302, "TLSv1.1");
    83 
    77 
    84     // (D)TLS ProtocolVersion array for (D)TLS 1.3 and previous versions.
    78     // TLS 1.2
    85     static final ProtocolVersion[] PROTOCOLS_TO_13 = new ProtocolVersion[] {
    79     static final ProtocolVersion TLS12 = new ProtocolVersion(0x0303, "TLSv1.2");
    86             TLS13, TLS12, TLS11, TLS10, SSL30, DTLS12, DTLS10
    80 
    87         };
    81     // DTLS 1.0
    88 
    82     // {254, 255}, the version value of DTLS 1.0.
    89     // No protocol version specified.
    83     static final ProtocolVersion DTLS10 =
    90     static final ProtocolVersion[] PROTOCOLS_OF_NONE = new ProtocolVersion[] {
    84                                 new ProtocolVersion(0xFEFF, "DTLSv1.0");
    91             NONE
    85 
    92         };
    86     // No DTLS 1.1, that version number was skipped in order to harmonize
    93 
    87     // version numbers with TLS.
    94     // (D)TLS ProtocolVersion array for SSL 3.0.
    88 
    95     static final ProtocolVersion[] PROTOCOLS_OF_30 = new ProtocolVersion[] {
    89     // DTLS 1.2
    96             SSL30
    90     // {254, 253}, the version value of DTLS 1.2.
    97         };
    91     static final ProtocolVersion DTLS12 =
    98 
    92                                 new ProtocolVersion(0xFEFD, "DTLSv1.2");
    99     // (D)TLS ProtocolVersion array for TLS 1.1/DTSL 1.0.
    93 
   100     static final ProtocolVersion[] PROTOCOLS_OF_11 = new ProtocolVersion[] {
    94     private static final boolean FIPS = SunJSSE.isFIPS();
   101             TLS11, DTLS10
    95 
   102         };
    96     // minimum version we implement (SSL 3.0)
   103 
    97     static final ProtocolVersion MIN = FIPS ? TLS10 : SSL30;
   104     // (D)TLS ProtocolVersion array for (D)TLS 1.2.
    98 
   105     static final ProtocolVersion[] PROTOCOLS_OF_12 = new ProtocolVersion[] {
    99     // maximum version we implement (TLS 1.2)
   106             TLS12, DTLS12
   100     static final ProtocolVersion MAX = TLS12;
   107         };
   101 
   108 
   102     // SSL/TLS ProtocolVersion to use by default (TLS 1.2)
   109     // (D)TLS ProtocolVersion array for (D)TLS 1.3.
   103     static final ProtocolVersion DEFAULT_TLS = TLS12;
   110     static final ProtocolVersion[] PROTOCOLS_OF_13 = new ProtocolVersion[] {
   104 
   111             TLS13
   105     // DTLS ProtocolVersion to use by default (TLS 1.2)
   112         };
   106     static final ProtocolVersion DEFAULT_DTLS = DTLS12;
   113 
   107 
   114     // (D)TLS ProtocolVersion array for TSL 1.0/1.1 and DTLS 1.0.
   108     // Default version for hello messages (SSLv2Hello)
   115     static final ProtocolVersion[] PROTOCOLS_10_11 = new ProtocolVersion[] {
   109     static final ProtocolVersion DEFAULT_HELLO = FIPS ? TLS10 : SSL30;
   116             TLS11, TLS10, DTLS10
   110 
   117         };
   111     // Available protocols
   118 
   112     //
   119     // (D)TLS ProtocolVersion array for TSL 1.1/1.2 and DTLS 1.0/1.2.
   113     // Including all supported protocols except the disabled ones.
   120     static final ProtocolVersion[] PROTOCOLS_11_12 = new ProtocolVersion[] {
   114     static final Set<ProtocolVersion> availableProtocols;
   121             TLS12, TLS11, DTLS12, DTLS10
   115 
   122         };
   116     // version in 16 bit MSB format as it appears in records and
   123 
   117     // messages, i.e. 0x0301 for TLS 1.0
   124     // (D)TLS ProtocolVersion array for TSL 1.2/1.3 and DTLS 1.2/1.3.
   118     public final int v;
   125     static final ProtocolVersion[] PROTOCOLS_12_13 = new ProtocolVersion[] {
   119 
   126             TLS13, TLS12, DTLS12
   120     // major and minor version
   127         };
   121     public final byte major, minor;
   128 
   122 
   129     // (D)TLS ProtocolVersion array for TSL 1.0/1.1/1.2 and DTLS 1.0/1.2.
   123     // name used in JSSE (e.g. TLSv1 for TLS 1.0)
   130     static final ProtocolVersion[] PROTOCOLS_10_12 = new ProtocolVersion[] {
   124     final String name;
   131             TLS12, TLS11, TLS10, DTLS12, DTLS10
   125 
   132         };
   126     // Initialize the available protocols.
   133 
   127     static {
   134     // TLS ProtocolVersion array for TLS 1.2 and previous versions.
   128         Set<ProtocolVersion> protocols = new HashSet<>(7);
   135     static final ProtocolVersion[] PROTOCOLS_TO_TLS12 = new ProtocolVersion[] {
   129 
   136             TLS12, TLS11, TLS10, SSL30
   130         ProtocolVersion[] pvs = new ProtocolVersion[] {
   137     };
   131                 SSL20Hello, SSL30, TLS10, TLS11, TLS12, DTLS10, DTLS12};
   138 
   132         EnumSet<CryptoPrimitive> cryptoPrimitives =
   139     // TLS ProtocolVersion array for TLS 1.1 and previous versions.
   133             EnumSet.<CryptoPrimitive>of(CryptoPrimitive.KEY_AGREEMENT);
   140     static final ProtocolVersion[] PROTOCOLS_TO_TLS11 = new ProtocolVersion[] {
   134         for (ProtocolVersion p : pvs) {
   141             TLS11, TLS10, SSL30
   135             if (SSLAlgorithmConstraints.DEFAULT_SSL_ONLY.permits(
   142     };
   136                     cryptoPrimitives, p.name, null)) {
   143 
   137                 protocols.add(p);
   144     // TLS ProtocolVersion array for TLS 1.0 and previous versions.
   138             }
   145     static final ProtocolVersion[] PROTOCOLS_TO_TLS10 = new ProtocolVersion[] {
   139         }
   146             TLS10, SSL30
   140 
   147     };
   141         availableProtocols =
   148 
   142                 Collections.<ProtocolVersion>unmodifiableSet(protocols);
   149     // Empty ProtocolVersion array
   143     }
   150     static final ProtocolVersion[] PROTOCOLS_EMPTY = new ProtocolVersion[0];
   144 
   151 
   145     // private
   152     private ProtocolVersion(int id, String name, boolean isDTLS) {
   146     private ProtocolVersion(int v, String name) {
   153         this.id = id;
   147         this.v = v;
       
   148         this.name = name;
   154         this.name = name;
   149         major = (byte)(v >>> 8);
   155         this.isDTLS = isDTLS;
   150         minor = (byte)(v & 0xFF);
   156         this.major = (byte)((id >>> 8) & 0xFF);
   151     }
   157         this.minor = (byte)(id & 0xFF);
   152 
   158 
   153     // private
   159         this.isAvailable = SSLAlgorithmConstraints.DEFAULT_SSL_ONLY.permits(
   154     private static ProtocolVersion valueOf(int v) {
   160                 EnumSet.<CryptoPrimitive>of(CryptoPrimitive.KEY_AGREEMENT),
   155         if (v == SSL30.v) {
   161                 name, null);
   156             return SSL30;
   162     }
   157         } else if (v == TLS10.v) {
   163 
   158             return TLS10;
   164     /**
   159         } else if (v == TLS11.v) {
   165      * Return a ProtocolVersion with the specified major and minor
   160             return TLS11;
   166      * version numbers.
   161         } else if (v == TLS12.v) {
   167      */
   162             return TLS12;
   168     static ProtocolVersion valueOf(byte major, byte minor) {
   163         } else if (v == SSL20Hello.v) {
   169         for (ProtocolVersion pv : ProtocolVersion.values()) {
   164             return SSL20Hello;
   170             if ((pv.major == major) && (pv.minor == minor)) {
   165         } else if (v == DTLS10.v) {
   171                 return pv;
   166             return DTLS10;
   172             }
   167         } else if (v == DTLS12.v) {
   173         }
   168             return DTLS12;
   174 
       
   175         return null;
       
   176     }
       
   177 
       
   178     /**
       
   179      * Return a ProtocolVersion with the specified version number.
       
   180      */
       
   181     static ProtocolVersion valueOf(int id) {
       
   182         for (ProtocolVersion pv : ProtocolVersion.values()) {
       
   183             if (pv.id == id) {
       
   184                 return pv;
       
   185             }
       
   186         }
       
   187 
       
   188         return null;
       
   189     }
       
   190 
       
   191     /**
       
   192      * Return name of a (D)TLS protocol specified by major and
       
   193      * minor version numbers.
       
   194      */
       
   195     static String nameOf(byte major, byte minor) {
       
   196         for (ProtocolVersion pv : ProtocolVersion.values()) {
       
   197             if ((pv.major == major) && (pv.minor == minor)) {
       
   198                 return pv.name;
       
   199             }
       
   200         }
       
   201 
       
   202         return "(D)TLS-" + major + "." + minor;
       
   203     }
       
   204 
       
   205     /**
       
   206      * Return name of a (D)TLS protocol specified by a protocol number.
       
   207      */
       
   208     static String nameOf(int id) {
       
   209         return nameOf((byte)((id >>> 8) & 0xFF), (byte)(id & 0xFF));
       
   210     }
       
   211 
       
   212     /**
       
   213      * Return a ProtocolVersion for the given (D)TLS protocol name.
       
   214      */
       
   215     static ProtocolVersion nameOf(String name) {
       
   216         for (ProtocolVersion pv : ProtocolVersion.values()) {
       
   217             if (pv.name.equals(name)) {
       
   218                 return pv;
       
   219             }
       
   220         }
       
   221 
       
   222         return null;
       
   223     }
       
   224 
       
   225     /**
       
   226      * Return true if the specific (D)TLS protocol is negotiable.
       
   227      *
       
   228      * Used to filter out SSLv2Hello and protocol numbers less than the
       
   229      * minimal supported protocol versions.
       
   230      */
       
   231     static boolean isNegotiable(
       
   232             byte major, byte minor, boolean isDTLS, boolean allowSSL20Hello) {
       
   233         int v = ((major & 0xFF) << 8) | (minor & 0xFF);
       
   234         if (isDTLS) {
       
   235             return v <= DTLS10.id;
   169         } else {
   236         } else {
   170             int major = (v >>> 8) & 0xFF;
   237             if (v < SSL30.id) {
   171             int minor = v & 0xFF;
   238                if (!allowSSL20Hello || (v != SSL20Hello.id)) {
   172             return new ProtocolVersion(v, "Unknown-" + major + "." + minor);
   239                    return false;
   173         }
   240                }
   174     }
   241             }
   175 
   242             return true;
   176     /**
   243         }
   177      * Return a ProtocolVersion with the specified major and minor version
   244     }
   178      * numbers. Never throws exceptions.
   245 
   179      */
   246     /**
   180     public static ProtocolVersion valueOf(int major, int minor) {
   247      * Get names of a list of ProtocolVersion objects.
   181         return valueOf(((major & 0xFF) << 8) | (minor & 0xFF));
   248      */
   182     }
   249     static String[] toStringArray(List<ProtocolVersion> protocolVersions) {
   183 
   250         if ((protocolVersions != null) && !protocolVersions.isEmpty()) {
   184     /**
   251             String[] protocolNames = new String[protocolVersions.size()];
   185      * Return a ProtocolVersion for the given name.
   252             int i = 0;
       
   253             for (ProtocolVersion pv : protocolVersions) {
       
   254                 protocolNames[i++] = pv.name;
       
   255             }
       
   256 
       
   257             return protocolNames;
       
   258         }
       
   259 
       
   260         return new String[0];
       
   261     }
       
   262 
       
   263     /**
       
   264      * Get names of a list of protocol version identifiers.
       
   265      */
       
   266     static String[] toStringArray(int[] protocolVersions) {
       
   267         if ((protocolVersions != null) && protocolVersions.length != 0) {
       
   268             String[] protocolNames = new String[protocolVersions.length];
       
   269             int i = 0;
       
   270             for (int pv : protocolVersions) {
       
   271                 protocolNames[i++] = ProtocolVersion.nameOf(pv);
       
   272             }
       
   273 
       
   274             return protocolNames;
       
   275         }
       
   276 
       
   277         return new String[0];
       
   278     }
       
   279 
       
   280     /**
       
   281      * Get a list of ProtocolVersion objects of an array protocol
       
   282      * version names.
       
   283      */
       
   284     static List<ProtocolVersion> namesOf(String[] protocolNames) {
       
   285         if (protocolNames == null || protocolNames.length == 0) {
       
   286             return Collections.<ProtocolVersion>emptyList();
       
   287         }
       
   288 
       
   289         List<ProtocolVersion> pvs = new ArrayList<>(protocolNames.length);
       
   290         for (String pn : protocolNames) {
       
   291             ProtocolVersion pv = ProtocolVersion.nameOf(pn);
       
   292             if (pv == null) {
       
   293                 throw new IllegalArgumentException(
       
   294                         "Unsupported protocol" + pn);
       
   295             }
       
   296 
       
   297             pvs.add(pv);
       
   298         }
       
   299 
       
   300         return Collections.unmodifiableList(pvs);
       
   301     }
       
   302 
       
   303     /**
       
   304      * Return true if the specific protocol version name is
       
   305      * of (D)TLS 1.2 or newer version.
       
   306      */
       
   307     static boolean useTLS12PlusSpec(String name) {
       
   308         ProtocolVersion pv = ProtocolVersion.nameOf(name);
       
   309         if (pv != null && pv != NONE) {
       
   310             return pv.isDTLS ? (pv.id <= DTLS12.id) : (pv.id >= TLS12.id);
       
   311         }
       
   312 
       
   313         return false;
       
   314     }
       
   315 
       
   316     /**
       
   317      * Compares this object with the specified ProtocolVersion.
   186      *
   318      *
   187      * @exception IllegalArgumentException if name is null or does not
   319      * @see java.lang.Comparable
   188      * identify a supported protocol
   320      */
   189      */
   321     int compare(ProtocolVersion that) {
   190     static ProtocolVersion valueOf(String name) {
   322         if (this == that) {
   191         if (name == null) {
   323             return 0;
   192             throw new IllegalArgumentException("Protocol cannot be null");
   324         }
   193         }
   325 
   194 
   326         if (this == ProtocolVersion.NONE) {
   195         if (FIPS && (name.equals(SSL30.name) || name.equals(SSL20Hello.name))) {
   327             return -1;
   196             throw new IllegalArgumentException(
   328         } else if (that == ProtocolVersion.NONE) {
   197                     "Only TLS 1.0 or later allowed in FIPS mode");
   329             return 1;
   198         }
   330         }
   199 
   331 
   200         if (name.equals(SSL30.name)) {
   332         if (isDTLS) {
   201             return SSL30;
   333             return that.id - this.id;
   202         } else if (name.equals(TLS10.name)) {
       
   203             return TLS10;
       
   204         } else if (name.equals(TLS11.name)) {
       
   205             return TLS11;
       
   206         } else if (name.equals(TLS12.name)) {
       
   207             return TLS12;
       
   208         } else if (name.equals(SSL20Hello.name)) {
       
   209             return SSL20Hello;
       
   210         } else if (name.equals(DTLS10.name)) {
       
   211             return DTLS10;
       
   212         } else if (name.equals(DTLS12.name)) {
       
   213             return DTLS12;
       
   214         } else {
   334         } else {
   215             throw new IllegalArgumentException(name);
   335             return this.id - that.id;
   216         }
   336         }
   217     }
   337     }
   218 
   338 
   219     @Override
   339     /**
   220     public String toString() {
   340      * Return true if this ProtocolVersion object is of (D)TLS 1.3 or
   221         return name;
   341      * newer version.
   222     }
   342      */
   223 
   343     boolean useTLS13PlusSpec() {
   224     /**
   344         return isDTLS ? (this.id < DTLS12.id) : (this.id >= TLS13.id);
   225      * Compares this object with the specified object for order.
   345     }
   226      */
   346 
   227     @Override
   347     /**
   228     public int compareTo(ProtocolVersion protocolVersion) {
   348      * Return true if this ProtocolVersion object is of (D)TLS 1.2 or
   229         if (maybeDTLSProtocol()) {
   349      * newer version.
   230             if (!protocolVersion.maybeDTLSProtocol()) {
   350      */
   231                 throw new IllegalArgumentException("Not DTLS protocol");
       
   232             }
       
   233 
       
   234             return protocolVersion.v - this.v;
       
   235         } else {
       
   236             if (protocolVersion.maybeDTLSProtocol()) {
       
   237                 throw new IllegalArgumentException("Not TLS protocol");
       
   238             }
       
   239 
       
   240             return this.v - protocolVersion.v;
       
   241         }
       
   242     }
       
   243 
       
   244     /**
       
   245      * Returns true if a ProtocolVersion represents a DTLS protocol.
       
   246      */
       
   247     boolean isDTLSProtocol() {
       
   248         return this.v == DTLS12.v || this.v == DTLS10.v;
       
   249     }
       
   250 
       
   251     /**
       
   252      * Returns true if a ProtocolVersion may represent a DTLS protocol.
       
   253      */
       
   254     boolean maybeDTLSProtocol() {
       
   255         return (this.major & 0x80) != 0;
       
   256     }
       
   257 
       
   258     boolean useTLS12PlusSpec() {
   351     boolean useTLS12PlusSpec() {
   259         return maybeDTLSProtocol() ? (this.v <= DTLS12.v) : (this.v >= TLS12.v);
   352         return isDTLS ? (this.id <= DTLS12.id) : (this.id >= TLS12.id);
   260     }
   353     }
   261 
   354 
       
   355     /**
       
   356      * Return true if this ProtocolVersion object is of
       
   357      * TLS 1.1/DTLS 1.0 or newer version.
       
   358      */
   262     boolean useTLS11PlusSpec() {
   359     boolean useTLS11PlusSpec() {
   263         return maybeDTLSProtocol() ? true : (this.v >= TLS11.v);
   360         return isDTLS ? true : (this.id >= TLS11.id);
   264     }
   361     }
   265 
   362 
       
   363     /**
       
   364      * Return true if this ProtocolVersion object is of TLS 1.0 or
       
   365      * newer version.
       
   366      */
   266     boolean useTLS10PlusSpec() {
   367     boolean useTLS10PlusSpec() {
   267         return maybeDTLSProtocol() ? true : (this.v >= TLS10.v);
   368         return isDTLS ? true : (this.id >= TLS10.id);
   268     }
   369     }
   269 
   370 
   270     boolean obsoletes(CipherSuite suite) {
   371     /**
   271         ProtocolVersion proto = this;
   372      * Return true if this ProtocolVersion object is of TLS 1.0 or
   272         if (proto.isDTLSProtocol()) {
   373      * newer version.
   273             // DTLS bans stream ciphers.
   374      */
   274             if (suite.cipher.cipherType == CipherType.STREAM_CIPHER) {
   375     static boolean useTLS10PlusSpec(int id, boolean isDTLS) {
   275                 return true;
   376         return isDTLS ? true : (id >= TLS10.id);
   276             }
   377     }
   277 
   378 
   278             proto = mapToTLSProtocol(this);
   379     /**
   279         }
   380      * Return true if this ProtocolVersion object is of (D)TLS 1.3 or
   280 
   381      * newer version.
   281         return (proto.v >= suite.obsoleted);
   382      */
   282     }
   383     static boolean useTLS13PlusSpec(int id, boolean isDTLS) {
   283 
   384         return isDTLS ? (id < DTLS12.id) : (id >= TLS13.id);
   284     boolean supports(CipherSuite suite) {
   385     }
   285         ProtocolVersion proto = this;
   386 
   286         if (proto.isDTLSProtocol()) {
   387     /**
   287             // DTLS bans stream ciphers.
   388      * Select the lower of that suggested protocol version and
   288             if (suite.cipher.cipherType == CipherType.STREAM_CIPHER) {
   389      * the highest of the listed protocol versions.
   289                 return false;
   390      *
   290             }
   391      * @param listedVersions    the listed protocol version
   291 
   392      * @param suggestedVersion  the suggested protocol version
   292             proto = mapToTLSProtocol(this);
   393      */
   293         }
   394     static ProtocolVersion selectedFrom(
   294 
   395             List<ProtocolVersion> listedVersions, int suggestedVersion) {
   295         return (proto.v >= suite.supported);
   396         ProtocolVersion selectedVersion = ProtocolVersion.NONE;
   296     }
   397         for (ProtocolVersion pv : listedVersions) {
   297 
   398             if (pv.id == suggestedVersion) {
   298     // Map a specified protocol to the corresponding TLS version.
   399                 return pv;
   299     //
   400             } else if (pv.isDTLS) {
   300     // DTLS 1.2 -> TLS 1.2
   401                 if (pv.id > suggestedVersion && pv.id < selectedVersion.id) {
   301     // DTLS 1.0 -> TLS 1.1
   402                     selectedVersion = pv;
   302     private static ProtocolVersion mapToTLSProtocol(
   403                 }
   303             ProtocolVersion protocolVersion) {
   404             } else {
   304 
   405                 if (pv.id < suggestedVersion && pv.id > selectedVersion.id) {
   305         if (protocolVersion.isDTLSProtocol()) {
   406                     selectedVersion = pv;
   306             if (protocolVersion.v == DTLS10.v) {
   407                 }
   307                 protocolVersion = TLS11;
   408             }
   308             } else {    // DTLS12
   409         }
   309                 protocolVersion = TLS12;
   410 
   310             }
   411         return selectedVersion;
   311         }
       
   312 
       
   313         return protocolVersion;
       
   314     }
   412     }
   315 }
   413 }