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 } |