< prev index next >
src/java.base/share/classes/sun/security/ssl/ProtocolVersion.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 23,315 ****
* questions.
*/
package sun.security.ssl;
- import java.util.*;
import java.security.CryptoPrimitive;
! import sun.security.ssl.CipherSuite.*;
/**
! * Type safe enum for an SSL/TLS protocol version. Instances are obtained
! * using the static factory methods or by referencing the static members
! * in this class. Member variables are final and can be accessed without
! * accessor methods.
! *
! * There is only ever one instance per supported protocol version, this
! * means == can be used for comparision instead of equals() if desired.
! *
! * Checks for a particular version number should generally take this form:
! *
! * <pre>{@code
! * if (protocolVersion.v >= ProtocolVersion.TLS10) {
! * // TLS 1.0 code goes here
! * } else {
! * // SSL 3.0 code here
! * }
! * }</pre>
*
* @author Andreas Sterbenz
* @since 1.4.1
*/
! public final class ProtocolVersion implements Comparable<ProtocolVersion> {
!
! // The limit of maximum protocol version
! static final int LIMIT_MAX_VALUE = 0xFFFF;
!
! // The limit of minimum protocol version
! static final int LIMIT_MIN_VALUE = 0x0000;
// Dummy protocol version value for invalid SSLSession
! static final ProtocolVersion NONE = new ProtocolVersion(-1, "NONE");
- // If enabled, send/accept SSLv2 hello messages
- static final ProtocolVersion SSL20Hello =
- new ProtocolVersion(0x0002, "SSLv2Hello");
! // SSL 3.0
! static final ProtocolVersion SSL30 = new ProtocolVersion(0x0300, "SSLv3");
!
! // TLS 1.0
! static final ProtocolVersion TLS10 = new ProtocolVersion(0x0301, "TLSv1");
!
! // TLS 1.1
! static final ProtocolVersion TLS11 = new ProtocolVersion(0x0302, "TLSv1.1");
! // TLS 1.2
! static final ProtocolVersion TLS12 = new ProtocolVersion(0x0303, "TLSv1.2");
! // DTLS 1.0
! // {254, 255}, the version value of DTLS 1.0.
! static final ProtocolVersion DTLS10 =
! new ProtocolVersion(0xFEFF, "DTLSv1.0");
! // No DTLS 1.1, that version number was skipped in order to harmonize
! // version numbers with TLS.
! // DTLS 1.2
! // {254, 253}, the version value of DTLS 1.2.
! static final ProtocolVersion DTLS12 =
! new ProtocolVersion(0xFEFD, "DTLSv1.2");
! private static final boolean FIPS = SunJSSE.isFIPS();
! // minimum version we implement (SSL 3.0)
! static final ProtocolVersion MIN = FIPS ? TLS10 : SSL30;
! // maximum version we implement (TLS 1.2)
! static final ProtocolVersion MAX = TLS12;
! // SSL/TLS ProtocolVersion to use by default (TLS 1.2)
! static final ProtocolVersion DEFAULT_TLS = TLS12;
! // DTLS ProtocolVersion to use by default (TLS 1.2)
! static final ProtocolVersion DEFAULT_DTLS = DTLS12;
! // Default version for hello messages (SSLv2Hello)
! static final ProtocolVersion DEFAULT_HELLO = FIPS ? TLS10 : SSL30;
! // Available protocols
! //
! // Including all supported protocols except the disabled ones.
! static final Set<ProtocolVersion> availableProtocols;
! // version in 16 bit MSB format as it appears in records and
! // messages, i.e. 0x0301 for TLS 1.0
! public final int v;
! // major and minor version
! public final byte major, minor;
! // name used in JSSE (e.g. TLSv1 for TLS 1.0)
! final String name;
! // Initialize the available protocols.
! static {
! Set<ProtocolVersion> protocols = new HashSet<>(7);
! ProtocolVersion[] pvs = new ProtocolVersion[] {
! SSL20Hello, SSL30, TLS10, TLS11, TLS12, DTLS10, DTLS12};
! EnumSet<CryptoPrimitive> cryptoPrimitives =
! EnumSet.<CryptoPrimitive>of(CryptoPrimitive.KEY_AGREEMENT);
! for (ProtocolVersion p : pvs) {
! if (SSLAlgorithmConstraints.DEFAULT_SSL_ONLY.permits(
! cryptoPrimitives, p.name, null)) {
! protocols.add(p);
}
}
! availableProtocols =
! Collections.<ProtocolVersion>unmodifiableSet(protocols);
}
! // private
! private ProtocolVersion(int v, String name) {
! this.v = v;
! this.name = name;
! major = (byte)(v >>> 8);
! minor = (byte)(v & 0xFF);
}
! // private
! private static ProtocolVersion valueOf(int v) {
! if (v == SSL30.v) {
! return SSL30;
! } else if (v == TLS10.v) {
! return TLS10;
! } else if (v == TLS11.v) {
! return TLS11;
! } else if (v == TLS12.v) {
! return TLS12;
! } else if (v == SSL20Hello.v) {
! return SSL20Hello;
! } else if (v == DTLS10.v) {
! return DTLS10;
! } else if (v == DTLS12.v) {
! return DTLS12;
! } else {
! int major = (v >>> 8) & 0xFF;
! int minor = v & 0xFF;
! return new ProtocolVersion(v, "Unknown-" + major + "." + minor);
}
}
/**
! * Return a ProtocolVersion with the specified major and minor version
! * numbers. Never throws exceptions.
*/
! public static ProtocolVersion valueOf(int major, int minor) {
! return valueOf(((major & 0xFF) << 8) | (minor & 0xFF));
}
/**
! * Return a ProtocolVersion for the given name.
! *
! * @exception IllegalArgumentException if name is null or does not
! * identify a supported protocol
*/
! static ProtocolVersion valueOf(String name) {
! if (name == null) {
! throw new IllegalArgumentException("Protocol cannot be null");
}
! if (FIPS && (name.equals(SSL30.name) || name.equals(SSL20Hello.name))) {
throw new IllegalArgumentException(
! "Only TLS 1.0 or later allowed in FIPS mode");
}
! if (name.equals(SSL30.name)) {
! return SSL30;
! } else if (name.equals(TLS10.name)) {
! return TLS10;
! } else if (name.equals(TLS11.name)) {
! return TLS11;
! } else if (name.equals(TLS12.name)) {
! return TLS12;
! } else if (name.equals(SSL20Hello.name)) {
! return SSL20Hello;
! } else if (name.equals(DTLS10.name)) {
! return DTLS10;
! } else if (name.equals(DTLS12.name)) {
! return DTLS12;
! } else {
! throw new IllegalArgumentException(name);
}
}
! @Override
! public String toString() {
! return name;
}
/**
! * Compares this object with the specified object for order.
*/
! @Override
! public int compareTo(ProtocolVersion protocolVersion) {
! if (maybeDTLSProtocol()) {
! if (!protocolVersion.maybeDTLSProtocol()) {
! throw new IllegalArgumentException("Not DTLS protocol");
}
! return protocolVersion.v - this.v;
! } else {
! if (protocolVersion.maybeDTLSProtocol()) {
! throw new IllegalArgumentException("Not TLS protocol");
}
! return this.v - protocolVersion.v;
}
}
! /**
! * Returns true if a ProtocolVersion represents a DTLS protocol.
! */
! boolean isDTLSProtocol() {
! return this.v == DTLS12.v || this.v == DTLS10.v;
}
/**
! * Returns true if a ProtocolVersion may represent a DTLS protocol.
*/
! boolean maybeDTLSProtocol() {
! return (this.major & 0x80) != 0;
}
boolean useTLS12PlusSpec() {
! return maybeDTLSProtocol() ? (this.v <= DTLS12.v) : (this.v >= TLS12.v);
}
boolean useTLS11PlusSpec() {
! return maybeDTLSProtocol() ? true : (this.v >= TLS11.v);
}
boolean useTLS10PlusSpec() {
! return maybeDTLSProtocol() ? true : (this.v >= TLS10.v);
}
! boolean obsoletes(CipherSuite suite) {
! ProtocolVersion proto = this;
! if (proto.isDTLSProtocol()) {
! // DTLS bans stream ciphers.
! if (suite.cipher.cipherType == CipherType.STREAM_CIPHER) {
! return true;
! }
!
! proto = mapToTLSProtocol(this);
! }
!
! return (proto.v >= suite.obsoleted);
}
! boolean supports(CipherSuite suite) {
! ProtocolVersion proto = this;
! if (proto.isDTLSProtocol()) {
! // DTLS bans stream ciphers.
! if (suite.cipher.cipherType == CipherType.STREAM_CIPHER) {
! return false;
}
! proto = mapToTLSProtocol(this);
}
!
! return (proto.v >= suite.supported);
}
-
- // Map a specified protocol to the corresponding TLS version.
- //
- // DTLS 1.2 -> TLS 1.2
- // DTLS 1.0 -> TLS 1.1
- private static ProtocolVersion mapToTLSProtocol(
- ProtocolVersion protocolVersion) {
-
- if (protocolVersion.isDTLSProtocol()) {
- if (protocolVersion.v == DTLS10.v) {
- protocolVersion = TLS11;
- } else { // DTLS12
- protocolVersion = TLS12;
}
}
! return protocolVersion;
}
}
--- 23,402 ----
* questions.
*/
package sun.security.ssl;
import java.security.CryptoPrimitive;
! import java.util.ArrayList;
! import java.util.Collections;
! import java.util.EnumSet;
! import java.util.List;
/**
! * Enum for an SSL/TLS/DTLS protocol version.
*
* @author Andreas Sterbenz
* @since 1.4.1
*/
! enum ProtocolVersion {
! // TLS13 (0x0304, "TLSv1.3", false),
! TLS13 (SSLConfiguration.tls13VN, "TLSv1.3", false),
! TLS12 (0x0303, "TLSv1.2", false),
! TLS11 (0x0302, "TLSv1.1", false),
! TLS10 (0x0301, "TLSv1", false),
! SSL30 (0x0300, "SSLv3", false),
! SSL20Hello (0x0002, "SSLv2Hello", false),
!
! DTLS13 (0xFEFC, "DTLSv1.3", true),
! DTLS12 (0xFEFD, "DTLSv1.2", true),
! DTLS10 (0xFEFF, "DTLSv1.0", true),
// Dummy protocol version value for invalid SSLSession
! NONE (-1, "NONE", false);
! final int id;
! final String name;
! final boolean isDTLS;
! final byte major;
! final byte minor;
! final boolean isAvailable;
! // The limit of maximum protocol version
! static final int LIMIT_MAX_VALUE = 0xFFFF;
! // The limit of minimum protocol version
! static final int LIMIT_MIN_VALUE = 0x0000;
! // (D)TLS ProtocolVersion array for TLS 1.0 and previous versions.
! static final ProtocolVersion[] PROTOCOLS_TO_10 = new ProtocolVersion[] {
! TLS10, SSL30
! };
!
! // (D)TLS ProtocolVersion array for TLS 1.1/DTLS 1.0 and previous versions.
! static final ProtocolVersion[] PROTOCOLS_TO_11 = new ProtocolVersion[] {
! TLS11, TLS10, SSL30, DTLS10
! };
!
! // (D)TLS ProtocolVersion array for (D)TLS 1.2 and previous versions.
! static final ProtocolVersion[] PROTOCOLS_TO_12 = new ProtocolVersion[] {
! TLS12, TLS11, TLS10, SSL30, DTLS12, DTLS10
! };
!
! // (D)TLS ProtocolVersion array for (D)TLS 1.3 and previous versions.
! static final ProtocolVersion[] PROTOCOLS_TO_13 = new ProtocolVersion[] {
! TLS13, TLS12, TLS11, TLS10, SSL30, DTLS13, DTLS12, DTLS10
! };
!
! // No protocol version specified.
! static final ProtocolVersion[] PROTOCOLS_OF_NONE = new ProtocolVersion[] {
! NONE
! };
!
! // (D)TLS ProtocolVersion array for (D)TLS 1.3.
! static final ProtocolVersion[] PROTOCOLS_OF_30 = new ProtocolVersion[] {
! SSL30
! };
!
! // (D)TLS ProtocolVersion array for TLS 1.1/DTSL 1.0.
! static final ProtocolVersion[] PROTOCOLS_OF_11 = new ProtocolVersion[] {
! TLS11, DTLS10
! };
!
! // (D)TLS ProtocolVersion array for (D)TLS 1.2.
! static final ProtocolVersion[] PROTOCOLS_OF_12 = new ProtocolVersion[] {
! TLS12, DTLS12
! };
!
! // (D)TLS ProtocolVersion array for (D)TLS 1.3.
! static final ProtocolVersion[] PROTOCOLS_OF_13 = new ProtocolVersion[] {
! TLS13, DTLS13
! };
!
! // (D)TLS ProtocolVersion array for TSL 1.0/1.1 and DTLS 1.0.
! static final ProtocolVersion[] PROTOCOLS_10_11 = new ProtocolVersion[] {
! TLS11, TLS10, DTLS10
! };
!
! // (D)TLS ProtocolVersion array for TSL 1.1/1.2 and DTLS 1.0/1.2.
! static final ProtocolVersion[] PROTOCOLS_11_12 = new ProtocolVersion[] {
! TLS12, TLS11, DTLS12, DTLS10
! };
!
! // (D)TLS ProtocolVersion array for TSL 1.2/1.3 and DTLS 1.2/1.3.
! static final ProtocolVersion[] PROTOCOLS_12_13 = new ProtocolVersion[] {
! TLS13, TLS12, DTLS13, DTLS12
! };
!
! // (D)TLS ProtocolVersion array for TSL 1.0/1.1/1.2 and DTLS 1.0/1.2.
! static final ProtocolVersion[] PROTOCOLS_10_12 = new ProtocolVersion[] {
! TLS12, TLS11, TLS10, DTLS12, DTLS10
! };
! // Empty ProtocolVersion array
! static final ProtocolVersion[] PROTOCOLS_EMPTY = new ProtocolVersion[0];
! private ProtocolVersion(int id, String name, boolean isDTLS) {
! this.id = id;
! this.name = name;
! this.isDTLS = isDTLS;
! this.major = (byte)((id >>> 8) & 0xFF);
! this.minor = (byte)(id & 0xFF);
!
! this.isAvailable = SSLAlgorithmConstraints.DEFAULT_SSL_ONLY.permits(
! EnumSet.<CryptoPrimitive>of(CryptoPrimitive.KEY_AGREEMENT),
! name, null);
! }
! /**
! * Return a ProtocolVersion with the specified major and minor
! * version numbers.
! */
! static ProtocolVersion valueOf(byte major, byte minor) {
! for (ProtocolVersion pv : ProtocolVersion.values()) {
! if ((pv.major == major) && (pv.minor == minor)) {
! return pv;
! }
! }
! return null;
! }
! /**
! * Return a ProtocolVersion with the specified version number.
! */
! static ProtocolVersion valueOf(int id) {
! for (ProtocolVersion pv : ProtocolVersion.values()) {
! if (pv.id == id) {
! return pv;
! }
! }
! return null;
! }
! /**
! * Return name of a (D)TLS protocol specified by major and
! * minor version numbers.
! */
! static String nameOf(byte major, byte minor) {
! for (ProtocolVersion pv : ProtocolVersion.values()) {
! if ((pv.major == major) && (pv.minor == minor)) {
! return pv.name;
! }
! }
! return "(D)TLS-" + major + "." + minor;
! }
! /**
! * Return name of a (D)TLS protocol specified by a protocol number.
! */
! static String nameOf(int id) {
! return nameOf((byte)((id >>> 8) & 0xFF), (byte)(id & 0xFF));
! }
! /**
! * Return a ProtocolVersion for the given (D)TLS protocol name.
! */
! static ProtocolVersion nameOf(String name) {
! for (ProtocolVersion pv : ProtocolVersion.values()) {
! if (pv.name.equals(name)) {
! return pv;
! }
! }
! return null;
! }
! /**
! * Return true if the specific (D)TLS protocol is negotiable.
! */
! static boolean isNegotiable(
! byte major, byte minor, boolean isDTLS, boolean allowSSL20Hello) {
! int v = ((major & 0xFF) << 8) | (minor & 0xFF);
! if (isDTLS) {
! return v <= DTLS10.id;
! } else {
! if (v < SSL30.id) {
! if (!allowSSL20Hello || (v != SSL20Hello.id)) {
! return false;
! }
}
}
! return true;
}
! /**
! * Get names of a list of ProtocolVersion objects.
! */
! static String[] toStringArray(List<ProtocolVersion> protocolVersions) {
! if ((protocolVersions != null) && !protocolVersions.isEmpty()) {
! String[] protocolNames = new String[protocolVersions.size()];
! int i = 0;
! for (ProtocolVersion pv : protocolVersions) {
! protocolNames[i++] = pv.name;
}
! return protocolNames;
}
+
+ return new String[0];
}
/**
! * Get names of a list of protocol version identifiers.
*/
! static String[] toStringArray(int[] protocolVersions) {
! if ((protocolVersions != null) && protocolVersions.length != 0) {
! String[] protocolNames = new String[protocolVersions.length];
! int i = 0;
! for (int pv : protocolVersions) {
! protocolNames[i++] = ProtocolVersion.nameOf(pv);
! }
!
! return protocolNames;
! }
!
! return new String[0];
}
/**
! * Get a list of ProtocolVersion objects of an array protocol
! * version names.
*/
! static List<ProtocolVersion> namesOf(String[] protocolNames) {
! if (protocolNames == null || protocolNames.length == 0) {
! return Collections.emptyList();
}
! if ((protocolNames != null) && (protocolNames.length != 0)) {
! List<ProtocolVersion> pvs = new ArrayList<>(protocolNames.length);
! for (String pn : protocolNames) {
! ProtocolVersion pv = ProtocolVersion.nameOf(pn);
! if (pv == null) {
throw new IllegalArgumentException(
! "Unsupported protocol" + pn);
}
! pvs.add(pv);
}
+
+ return Collections.unmodifiableList(pvs);
}
! return Collections.<ProtocolVersion>emptyList();
}
/**
! * Return true if the specific protocol version name is
! * of (D)TLS 1.2 or newer version.
*/
! static boolean useTLS12PlusSpec(String name) {
! ProtocolVersion pv = ProtocolVersion.nameOf(name);
! if (pv != null && pv != NONE) {
! return pv.isDTLS ? (pv.id <= DTLS12.id) : (pv.id >= TLS12.id);
}
! return false;
}
! /**
! * Compares this object with the specified ProtocolVersion.
! *
! * @see java.lang.Comparable
! */
! int compare(ProtocolVersion that) {
! if (this == that) {
! return 0;
}
+
+ if (this == ProtocolVersion.NONE) {
+ return -1;
+ } else if (that == ProtocolVersion.NONE) {
+ return 1;
}
! if (isDTLS) {
! return that.id - this.id;
! } else {
! return this.id - that.id;
! }
}
/**
! * Return true if this ProtocolVersion object is of (D)TLS 1.3 or
! * newer version.
*/
! boolean useTLS13PlusSpec() {
! return isDTLS ? (this.id <= DTLS13.id) : (this.id >= TLS13.id);
}
+ /**
+ * Return true if this ProtocolVersion object is of (D)TLS 1.2 or
+ * newer version.
+ */
boolean useTLS12PlusSpec() {
! return isDTLS ? (this.id <= DTLS12.id) : (this.id >= TLS12.id);
}
+ /**
+ * Return true if this ProtocolVersion object is of
+ * TLS 1.1/DTLS 1.0 or newer version.
+ */
boolean useTLS11PlusSpec() {
! return isDTLS ? true : (this.id >= TLS11.id);
}
+ /**
+ * Return true if this ProtocolVersion object is of TLS 1.0 or
+ * newer version.
+ */
boolean useTLS10PlusSpec() {
! return isDTLS ? true : (this.id >= TLS10.id);
}
! /**
! * Return true if this ProtocolVersion object is of TLS 1.0 or
! * newer version.
! */
! static boolean useTLS10PlusSpec(int id, boolean isDTLS) {
! return isDTLS ? true : (id >= TLS10.id);
}
! /**
! * Return true if this ProtocolVersion object is of TLS 1.3 or
! * newer version.
! */
! static boolean useTLS13PlusSpec(int id, boolean isDTLS) {
! return isDTLS ? (id <= DTLS13.id) : (id >= TLS13.id);
}
! /**
! * Select the lower of that suggested protocol version and
! * the highest of the listed protocol versions.
! *
! * @param listedVersions the listed protocol version
! * @param suggestedVersion the suggested protocol version
! */
! static ProtocolVersion selectedFrom(
! List<ProtocolVersion> listedVersions, int suggestedVersion) {
! ProtocolVersion selectedVersion = ProtocolVersion.NONE;
! for (ProtocolVersion pv : listedVersions) {
! if (pv.id == suggestedVersion) {
! return pv;
! } else if (pv.isDTLS) {
! if (pv.id > suggestedVersion && pv.id < selectedVersion.id) {
! selectedVersion = pv;
}
! } else {
! if (pv.id < suggestedVersion && pv.id > selectedVersion.id) {
! selectedVersion = pv;
}
}
}
! return selectedVersion;
}
}
< prev index next >