jdk/src/share/classes/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java
changeset 23733 b9b80421cfa7
parent 22309 1990211a42e5
equal deleted inserted replaced
23732:44fe768edfd2 23733:b9b80421cfa7
    24  */
    24  */
    25 
    25 
    26 package sun.security.internal.spec;
    26 package sun.security.internal.spec;
    27 
    27 
    28 import java.security.spec.AlgorithmParameterSpec;
    28 import java.security.spec.AlgorithmParameterSpec;
       
    29 import java.security.AccessController;
       
    30 import java.security.PrivilegedAction;
    29 
    31 
    30 /**
    32 /**
    31  * Parameters for SSL/TLS RSA Premaster secret generation.
    33  * Parameters for SSL/TLS RSA premaster secret.
    32  * This class is used by SSL/TLS client to initialize KeyGenerators of the
       
    33  * type "TlsRsaPremasterSecret".
       
    34  *
    34  *
    35  * <p>Instances of this class are immutable.
    35  * <p>Instances of this class are immutable.
    36  *
    36  *
    37  * @since   1.6
    37  * @since   1.6
    38  * @author  Andreas Sterbenz
    38  * @author  Andreas Sterbenz
    41  */
    41  */
    42 @Deprecated
    42 @Deprecated
    43 public class TlsRsaPremasterSecretParameterSpec
    43 public class TlsRsaPremasterSecretParameterSpec
    44         implements AlgorithmParameterSpec {
    44         implements AlgorithmParameterSpec {
    45 
    45 
    46     private final int majorVersion;
    46     /*
    47     private final int minorVersion;
    47      * The TLS spec says that the version in the RSA premaster secret must
    48     private final byte[] encodedSecret;
    48      * be the maximum version supported by the client (i.e. the version it
       
    49      * requested in its client hello version). However, we (and other
       
    50      * implementations) used to send the active negotiated version. The
       
    51      * system property below allows to toggle the behavior.
       
    52      */
       
    53     private final static String PROP_NAME =
       
    54                                 "com.sun.net.ssl.rsaPreMasterSecretFix";
       
    55 
       
    56     /*
       
    57      * Default is "false" (old behavior) for compatibility reasons in
       
    58      * SSLv3/TLSv1.  Later protocols (TLSv1.1+) do not use this property.
       
    59      */
       
    60     private final static boolean rsaPreMasterSecretFix =
       
    61             AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
       
    62                 public Boolean run() {
       
    63                     String value = System.getProperty(PROP_NAME);
       
    64                     if (value != null && value.equalsIgnoreCase("true")) {
       
    65                         return Boolean.TRUE;
       
    66                     }
       
    67 
       
    68                     return Boolean.FALSE;
       
    69                 }
       
    70             });
       
    71 
       
    72     private final int clientVersion;
       
    73     private final int serverVersion;
    49 
    74 
    50     /**
    75     /**
    51      * Constructs a new TlsRsaPremasterSecretParameterSpec.
    76      * Constructs a new TlsRsaPremasterSecretParameterSpec.
    52      * <P>
       
    53      * The version numbers will be placed inside the premaster secret to
       
    54      * detect version rollbacks attacks as described in the TLS specification.
       
    55      * Note that they do not indicate the protocol version negotiated for
       
    56      * the handshake.
       
    57      *
    77      *
    58      * @param majorVersion the major number of the protocol version
    78      * @param clientVersion the version of the TLS protocol by which the
    59      * @param minorVersion the minor number of the protocol version
    79      *        client wishes to communicate during this session
       
    80      * @param serverVersion the negotiated version of the TLS protocol which
       
    81      *        contains the lower of that suggested by the client in the client
       
    82      *        hello and the highest supported by the server.
    60      *
    83      *
    61      * @throws IllegalArgumentException if minorVersion or majorVersion are
    84      * @throws IllegalArgumentException if clientVersion or serverVersion are
    62      *   negative or larger than 255
    85      *   negative or larger than (2^16 - 1)
    63      */
    86      */
    64     public TlsRsaPremasterSecretParameterSpec(int majorVersion,
    87     public TlsRsaPremasterSecretParameterSpec(
    65             int minorVersion) {
    88             int clientVersion, int serverVersion) {
    66         this.majorVersion =
    89 
    67             TlsMasterSecretParameterSpec.checkVersion(majorVersion);
    90         this.clientVersion = checkVersion(clientVersion);
    68         this.minorVersion =
    91         this.serverVersion = checkVersion(serverVersion);
    69             TlsMasterSecretParameterSpec.checkVersion(minorVersion);
       
    70         this.encodedSecret = null;
       
    71     }
    92     }
    72 
    93 
    73     /**
    94     /**
    74      * Constructs a new TlsRsaPremasterSecretParameterSpec.
    95      * Returns the version of the TLS protocol by which the client wishes to
    75      * <P>
    96      * communicate during this session.
    76      * The version numbers will be placed inside the premaster secret to
       
    77      * detect version rollbacks attacks as described in the TLS specification.
       
    78      * Note that they do not indicate the protocol version negotiated for
       
    79      * the handshake.
       
    80      * <P>
       
    81      * Usually, the encoded secret key is a random number that acts as
       
    82      * dummy pre_master_secret to avoid vulnerabilities described by
       
    83      * section 7.4.7.1, RFC 5246.
       
    84      *
    97      *
    85      * @param majorVersion the major number of the protocol version
    98      * @return the version of the TLS protocol in ClientHello message
    86      * @param minorVersion the minor number of the protocol version
       
    87      * @param encodedSecret the encoded secret key
       
    88      *
       
    89      * @throws IllegalArgumentException if minorVersion or majorVersion are
       
    90      *   negative or larger than 255, or encodedSecret is not exactly 48 bytes.
       
    91      */
    99      */
    92     public TlsRsaPremasterSecretParameterSpec(int majorVersion,
   100     public int getClientVersion() {
    93             int minorVersion, byte[] encodedSecret) {
   101         return clientVersion;
    94         this.majorVersion =
       
    95             TlsMasterSecretParameterSpec.checkVersion(majorVersion);
       
    96         this.minorVersion =
       
    97             TlsMasterSecretParameterSpec.checkVersion(minorVersion);
       
    98 
       
    99         if (encodedSecret == null || encodedSecret.length != 48) {
       
   100             throw new IllegalArgumentException(
       
   101                         "Encoded secret is not exactly 48 bytes");
       
   102         }
       
   103         this.encodedSecret = encodedSecret.clone();
       
   104     }
   102     }
   105 
   103 
   106     /**
   104     /**
   107      * Returns the major version.
   105      * Returns the negotiated version of the TLS protocol which contains the
       
   106      * lower of that suggested by the client in the client hello and the
       
   107      * highest supported by the server.
   108      *
   108      *
   109      * @return the major version.
   109      * @return the negotiated version of the TLS protocol in ServerHello message
   110      */
   110      */
   111     public int getMajorVersion() {
   111     public int getServerVersion() {
   112         return majorVersion;
   112         return serverVersion;
   113     }
   113     }
   114 
   114 
   115     /**
   115     /**
   116      * Returns the minor version.
   116      * Returns the major version used in RSA premaster secret.
   117      *
   117      *
   118      * @return the minor version.
   118      * @return the major version used in RSA premaster secret.
   119      */
   119      */
   120     public int getMinorVersion() {
   120     public int getMajorVersion() {
   121         return minorVersion;
   121         if (rsaPreMasterSecretFix || clientVersion >= 0x0302) {
       
   122                                                         // 0x0302: TLSv1.1
       
   123             return (clientVersion >>> 8) & 0xFF;
       
   124         }
       
   125 
       
   126         return (serverVersion >>> 8) & 0xFF;
   122     }
   127     }
   123 
   128 
   124     /**
   129     /**
   125      * Returns the encoded secret.
   130      * Returns the minor version used in RSA premaster secret.
   126      *
   131      *
   127      * @return the encoded secret, may be null if no encoded secret.
   132      * @return the minor version used in RSA premaster secret.
   128      */
   133      */
   129     public byte[] getEncodedSecret() {
   134     public int getMinorVersion() {
   130         return encodedSecret == null ? null : encodedSecret.clone();
   135         if (rsaPreMasterSecretFix || clientVersion >= 0x0302) {
       
   136                                                         // 0x0302: TLSv1.1
       
   137             return clientVersion & 0xFF;
       
   138         }
       
   139 
       
   140         return serverVersion & 0xFF;
       
   141     }
       
   142 
       
   143     private int checkVersion(int version) {
       
   144         if ((version < 0) || (version > 0xFFFF)) {
       
   145             throw new IllegalArgumentException(
       
   146                         "Version must be between 0 and 65,535");
       
   147         }
       
   148         return version;
   131     }
   149     }
   132 }
   150 }