20 * |
20 * |
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
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 |
22 * or visit www.oracle.com if you need additional information or have any |
23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
|
26 |
25 |
27 package sun.security.ssl; |
26 package sun.security.ssl; |
28 |
27 |
29 import java.security.InvalidKeyException; |
28 import java.security.InvalidKeyException; |
30 import java.security.NoSuchAlgorithmException; |
29 import java.security.NoSuchAlgorithmException; |
48 * @author David Brownell |
47 * @author David Brownell |
49 * @author Andreas Sterbenz |
48 * @author Andreas Sterbenz |
50 */ |
49 */ |
51 final class MAC extends Authenticator { |
50 final class MAC extends Authenticator { |
52 |
51 |
53 final static MAC NULL = new MAC(); |
52 final static MAC TLS_NULL = new MAC(false); |
54 |
53 |
55 // Value of the null MAC is fixed |
54 // Value of the null MAC is fixed |
56 private static final byte nullMAC[] = new byte[0]; |
55 private static final byte nullMAC[] = new byte[0]; |
57 |
56 |
58 // internal identifier for the MAC algorithm |
57 // internal identifier for the MAC algorithm |
59 private final MacAlg macAlg; |
58 private final MacAlg macAlg; |
60 |
59 |
61 // JCE Mac object |
60 // JCE Mac object |
62 private final Mac mac; |
61 private final Mac mac; |
63 |
62 |
64 private MAC() { |
63 MAC(boolean isDTLS) { |
|
64 super(isDTLS); |
|
65 |
65 macAlg = M_NULL; |
66 macAlg = M_NULL; |
66 mac = null; |
67 mac = null; |
67 } |
68 } |
68 |
69 |
69 /** |
70 /** |
70 * Set up, configured for the given SSL/TLS MAC type and version. |
71 * Set up, configured for the given MAC type and version. |
71 */ |
72 */ |
72 MAC(MacAlg macAlg, ProtocolVersion protocolVersion, SecretKey key) |
73 MAC(MacAlg macAlg, ProtocolVersion protocolVersion, SecretKey key) |
73 throws NoSuchAlgorithmException, InvalidKeyException { |
74 throws NoSuchAlgorithmException, InvalidKeyException { |
74 super(protocolVersion); |
75 super(protocolVersion); |
75 this.macAlg = macAlg; |
76 this.macAlg = macAlg; |
76 |
77 |
77 String algorithm; |
78 String algorithm; |
78 boolean tls = (protocolVersion.v >= ProtocolVersion.TLS10.v); |
79 |
|
80 // using SSL MAC computation? |
|
81 boolean useSSLMac = (protocolVersion.v < ProtocolVersion.TLS10.v); |
79 |
82 |
80 if (macAlg == M_MD5) { |
83 if (macAlg == M_MD5) { |
81 algorithm = tls ? "HmacMD5" : "SslMacMD5"; |
84 algorithm = useSSLMac ? "SslMacMD5" : "HmacMD5"; |
82 } else if (macAlg == M_SHA) { |
85 } else if (macAlg == M_SHA) { |
83 algorithm = tls ? "HmacSHA1" : "SslMacSHA1"; |
86 algorithm = useSSLMac ? "SslMacSHA1" : "HmacSHA1"; |
84 } else if (macAlg == M_SHA256) { |
87 } else if (macAlg == M_SHA256) { |
85 algorithm = "HmacSHA256"; // TLS 1.2+ |
88 algorithm = "HmacSHA256"; // TLS 1.2+ |
86 } else if (macAlg == M_SHA384) { |
89 } else if (macAlg == M_SHA384) { |
87 algorithm = "HmacSHA384"; // TLS 1.2+ |
90 algorithm = "HmacSHA384"; // TLS 1.2+ |
88 } else { |
91 } else { |
120 * @param type record type |
123 * @param type record type |
121 * @param buf compressed record on which the MAC is computed |
124 * @param buf compressed record on which the MAC is computed |
122 * @param offset start of compressed record data |
125 * @param offset start of compressed record data |
123 * @param len the size of the compressed record |
126 * @param len the size of the compressed record |
124 * @param isSimulated if true, simulate the MAC computation |
127 * @param isSimulated if true, simulate the MAC computation |
|
128 * |
|
129 * @return the MAC result |
125 */ |
130 */ |
126 final byte[] compute(byte type, byte buf[], |
131 final byte[] compute(byte type, byte buf[], |
127 int offset, int len, boolean isSimulated) { |
132 int offset, int len, boolean isSimulated) { |
128 if (macAlg.size == 0) { |
133 if (macAlg.size == 0) { |
129 return nullMAC; |
134 return nullMAC; |
130 } |
135 } |
131 |
136 |
132 if (!isSimulated) { |
137 if (!isSimulated) { |
133 byte[] additional = acquireAuthenticationBytes(type, len); |
138 // Uses the implicit sequence number for the computation. |
|
139 byte[] additional = acquireAuthenticationBytes(type, len, null); |
134 mac.update(additional); |
140 mac.update(additional); |
135 } |
141 } |
136 mac.update(buf, offset, len); |
142 mac.update(buf, offset, len); |
137 |
143 |
138 return mac.doFinal(); |
144 return mac.doFinal(); |
147 * |
153 * |
148 * @param type record type |
154 * @param type record type |
149 * @param bb a ByteBuffer in which the position and limit |
155 * @param bb a ByteBuffer in which the position and limit |
150 * demarcate the data to be MAC'd. |
156 * demarcate the data to be MAC'd. |
151 * @param isSimulated if true, simulate the MAC computation |
157 * @param isSimulated if true, simulate the MAC computation |
|
158 * @param sequence the explicit sequence number, or null if using |
|
159 * the implicit sequence number for the computation |
|
160 * |
|
161 * @return the MAC result |
152 */ |
162 */ |
153 final byte[] compute(byte type, ByteBuffer bb, boolean isSimulated) { |
163 final byte[] compute(byte type, ByteBuffer bb, |
|
164 byte[] sequence, boolean isSimulated) { |
|
165 |
154 if (macAlg.size == 0) { |
166 if (macAlg.size == 0) { |
155 return nullMAC; |
167 return nullMAC; |
156 } |
168 } |
157 |
169 |
158 if (!isSimulated) { |
170 if (!isSimulated) { |
|
171 // Uses the explicit sequence number for the computation. |
159 byte[] additional = |
172 byte[] additional = |
160 acquireAuthenticationBytes(type, bb.remaining()); |
173 acquireAuthenticationBytes(type, bb.remaining(), sequence); |
161 mac.update(additional); |
174 mac.update(additional); |
162 } |
175 } |
163 mac.update(bb); |
176 mac.update(bb); |
164 |
177 |
165 return mac.doFinal(); |
178 return mac.doFinal(); |
166 } |
179 } |
167 |
180 |
|
181 /** |
|
182 * Compute and returns the MAC for the remaining data |
|
183 * in this ByteBuffer. |
|
184 * |
|
185 * On return, the bb position == limit, and limit will |
|
186 * have not changed. |
|
187 * |
|
188 * @param type record type |
|
189 * @param bb a ByteBuffer in which the position and limit |
|
190 * demarcate the data to be MAC'd. |
|
191 * @param isSimulated if true, simulate the the MAC computation |
|
192 * |
|
193 * @return the MAC result |
|
194 */ |
|
195 final byte[] compute(byte type, ByteBuffer bb, boolean isSimulated) { |
|
196 // Uses the implicit sequence number for the computation. |
|
197 return compute(type, bb, null, isSimulated); |
|
198 } |
168 } |
199 } |
169 |
|