1 /*
2  * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
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
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
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
23  * questions.
24  */
25 
26 package sun.security.ssl;
27 
28 import java.nio.ByteBuffer;
29 import java.security.InvalidKeyException;
30 import java.security.NoSuchAlgorithmException;
31 import java.util.Arrays;
32 import javax.crypto.Mac;
33 import javax.crypto.SecretKey;
34 import sun.security.ssl.CipherSuite.MacAlg;
35 
36 /**
37  * This class represents an SSL/TLS message authentication token,
38  * which encapsulates a sequence number and ensures that attempts to
39  * delete or reorder messages can be detected.
40  */
41 abstract class Authenticator {
42     // byte array containing the additional authentication information for
43     // each record
44     protected final byte[] block;   // at least 8 bytes for sequence number
45 
Authenticator(byte[] block)46     private Authenticator(byte[] block) {
47         this.block = block;
48     }
49 
50     /**
51      * Constructs the message authentication token for the specified
52      * SSL/TLS protocol.
53      */
valueOf(ProtocolVersion protocolVersion)54     static Authenticator valueOf(ProtocolVersion protocolVersion) {
55         if (protocolVersion.useTLS13PlusSpec()) {
56             return new TLS13Authenticator(protocolVersion);
57         } else if (protocolVersion.useTLS10PlusSpec()) {
58             return new TLS10Authenticator(protocolVersion);
59         } else {
60             return new SSL30Authenticator();
61         }
62     }
63 
64     @SuppressWarnings({"unchecked"})
65     static <T extends Authenticator & MAC> T
valueOf(ProtocolVersion protocolVersion, MacAlg macAlg, SecretKey key)66          valueOf(ProtocolVersion protocolVersion, MacAlg macAlg,
67                  SecretKey key) throws NoSuchAlgorithmException,
68                         InvalidKeyException {
69         if (protocolVersion.useTLS13PlusSpec()) {
70             throw new RuntimeException("No MacAlg used in TLS 1.3");
71         } else if (protocolVersion.useTLS10PlusSpec()) {
72             return (T)(new TLS10Mac(protocolVersion, macAlg, key));
73         } else {
74             return (T)(new SSL30Mac(protocolVersion, macAlg, key));
75         }
76     }
77 
nullTlsMac()78     static Authenticator nullTlsMac() {
79         return new SSLNullMac();
80     }
81 
82     /**
83      * Checks whether the sequence number is close to wrap.
84      *
85      * Sequence numbers are of type uint64 and may not exceed 2^64-1.
86      * Sequence numbers do not wrap. When the sequence number is near
87      * to wrap, we need to close the connection immediately.
88      *
89      * @return true if the sequence number is close to wrap
90      */
seqNumOverflow()91     abstract boolean seqNumOverflow();
92 
93     /**
94      * Checks whether the sequence number close to renew.
95      *
96      * Sequence numbers are of type uint64 and may not exceed 2^64-1.
97      * Sequence numbers do not wrap.  If a TLS
98      * implementation would need to wrap a sequence number, it must
99      * renegotiate instead.
100      *
101      * @return true if the sequence number is huge enough to renew
102      */
seqNumIsHuge()103     abstract boolean seqNumIsHuge();
104 
105     /**
106      * Gets the current sequence number.
107      *
108      * @return the byte array of the current sequence number
109      */
sequenceNumber()110     final byte[] sequenceNumber() {
111         return Arrays.copyOf(block, 8);
112     }
113 
114     /**
115      * Increase the sequence number.
116      */
increaseSequenceNumber()117     final void increaseSequenceNumber() {
118         /*
119          * The sequence number in the block array is a 64-bit
120          * number stored in big-endian format.
121          */
122         int k = 7;
123         while ((k >= 0) && (++block[k] == 0)) {
124             k--;
125         }
126     }
127 
128     /**
129      * Acquires the current message authentication information with the
130      * specified record type and fragment length, and then increases the
131      * sequence number if using implicit sequence number.
132      *
133      * @param  type the record type
134      * @param  length the fragment of the record
135      * @param  sequence the explicit sequence number of the record
136      *
137      * @return the byte array of the current message authentication information
138      */
acquireAuthenticationBytes( byte type, int length, byte[] sequence)139     byte[] acquireAuthenticationBytes(
140             byte type, int length, byte[] sequence) {
141         throw new UnsupportedOperationException("Used by AEAD algorithms only");
142     }
143 
144     private static class SSLAuthenticator extends Authenticator {
SSLAuthenticator(byte[] block)145         private SSLAuthenticator(byte[] block) {
146             super(block);
147         }
148 
149         @Override
seqNumOverflow()150         boolean seqNumOverflow() {
151             /*
152              * Conservatively, we don't allow more records to be generated
153              * when there are only 2^8 sequence numbers left.
154              */
155             return (block.length != 0 &&
156                 block[0] == (byte)0xFF && block[1] == (byte)0xFF &&
157                 block[2] == (byte)0xFF && block[3] == (byte)0xFF &&
158                 block[4] == (byte)0xFF && block[5] == (byte)0xFF &&
159                 block[6] == (byte)0xFF);
160         }
161 
162         @Override
seqNumIsHuge()163         boolean seqNumIsHuge() {
164             return (block.length != 0 &&
165                 block[0] == (byte)0xFF && block[1] == (byte)0xFF &&
166                 block[2] == (byte)0xFF && block[3] == (byte)0xFF);
167         }
168     }
169 
170     // For null MAC only.
171     private static class SSLNullAuthenticator extends SSLAuthenticator {
SSLNullAuthenticator()172         private SSLNullAuthenticator() {
173             super(new byte[8]);
174         }
175     }
176 
177     // For SSL 3.0
178     private static class SSL30Authenticator extends SSLAuthenticator {
179         // Block size of SSL v3.0:
180         //     sequence number + record type + + record length
181         private static final int BLOCK_SIZE = 11;   // 8 + 1 + 2
182 
SSL30Authenticator()183         private SSL30Authenticator() {
184             super(new byte[BLOCK_SIZE]);
185         }
186 
187         @Override
acquireAuthenticationBytes( byte type, int length, byte[] sequence)188         byte[] acquireAuthenticationBytes(
189                 byte type, int length, byte[] sequence) {
190             byte[] ad = block.clone();
191 
192             // Increase the implicit sequence number in the block array.
193             increaseSequenceNumber();
194 
195             ad[8] = type;
196             ad[9] = (byte)(length >> 8);
197             ad[10] = (byte)(length);
198 
199             return ad;
200         }
201     }
202 
203     // For TLS 1.0 - 1.2
204     private static class TLS10Authenticator extends SSLAuthenticator {
205         // Block size of TLS v1.0/1.1/1.2.
206         //     sequence number + record type + protocol version + record length
207         private static final int BLOCK_SIZE = 13;   // 8 + 1 + 2 + 2
208 
TLS10Authenticator(ProtocolVersion protocolVersion)209         private TLS10Authenticator(ProtocolVersion protocolVersion) {
210             super(new byte[BLOCK_SIZE]);
211             block[9] = protocolVersion.major;
212             block[10] = protocolVersion.minor;
213         }
214 
215         @Override
acquireAuthenticationBytes( byte type, int length, byte[] sequence)216         byte[] acquireAuthenticationBytes(
217                 byte type, int length, byte[] sequence) {
218             byte[] ad = block.clone();
219             if (sequence != null) {
220                 if (sequence.length != 8) {
221                     throw new RuntimeException(
222                             "Insufficient explicit sequence number bytes");
223                 }
224 
225                 System.arraycopy(sequence, 0, ad, 0, sequence.length);
226             } else {    // Otherwise, use the implicit sequence number.
227                 // Increase the implicit sequence number in the block array.
228                 increaseSequenceNumber();
229             }
230 
231             ad[8] = type;
232             ad[11] = (byte)(length >> 8);
233             ad[12] = (byte)(length);
234 
235             return ad;
236         }
237     }
238 
239     // For TLS 1.3
240     private static final class TLS13Authenticator extends SSLAuthenticator {
241         // Block size of TLS v1.3:
242         //     record type + protocol version + record length + sequence number
243         private static final int BLOCK_SIZE = 13;   // 1 + 2 + 2 + 8
244 
TLS13Authenticator(ProtocolVersion protocolVersion)245         private TLS13Authenticator(ProtocolVersion protocolVersion) {
246             super(new byte[BLOCK_SIZE]);
247             block[9] = ProtocolVersion.TLS12.major;
248             block[10] = ProtocolVersion.TLS12.minor;
249         }
250 
251         @Override
acquireAuthenticationBytes( byte type, int length, byte[] sequence)252         byte[] acquireAuthenticationBytes(
253                 byte type, int length, byte[] sequence) {
254             byte[] ad = Arrays.copyOfRange(block, 8, 13);
255 
256             // Increase the implicit sequence number in the block array.
257             increaseSequenceNumber();
258 
259             ad[0] = type;
260             ad[3] = (byte)(length >> 8);
261             ad[4] = (byte)(length & 0xFF);
262 
263             return ad;
264         }
265     }
266 
267     interface MAC {
macAlg()268         MacAlg macAlg();
269 
270         /**
271          * Compute and returns the MAC for the remaining data
272          * in this ByteBuffer.
273          *
274          * On return, the bb position == limit, and limit will
275          * have not changed.
276          *
277          * @param type record type
278          * @param bb a ByteBuffer in which the position and limit
279          *          demarcate the data to be MAC'd.
280          * @param isSimulated if true, simulate the MAC computation
281          * @param sequence the explicit sequence number, or null if using
282          *        the implicit sequence number for the computation
283          *
284          * @return the MAC result
285          */
compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)286         byte[] compute(byte type, ByteBuffer bb,
287                 byte[] sequence, boolean isSimulated);
288 
289 
290         /**
291          * Compute and returns the MAC for the remaining data
292          * in this ByteBuffer.
293          *
294          * On return, the bb position == limit, and limit will
295          * have not changed.
296          *
297          * @param type record type
298          * @param bb a ByteBuffer in which the position and limit
299          *        demarcate the data to be MAC'd.
300          * @param isSimulated if true, simulate the MAC computation
301          *
302          * @return the MAC result
303          */
compute(byte type, ByteBuffer bb, boolean isSimulated)304         default byte[] compute(byte type, ByteBuffer bb, boolean isSimulated) {
305             return compute(type, bb, null, isSimulated);
306         }
307     }
308 
309     private class MacImpl implements MAC {
310         // internal identifier for the MAC algorithm
311         private final MacAlg macAlg;
312 
313         // JCE Mac object
314         private final Mac mac;
315 
MacImpl()316         private MacImpl() {
317             macAlg = MacAlg.M_NULL;
318             mac = null;
319         }
320 
MacImpl(ProtocolVersion protocolVersion, MacAlg macAlg, SecretKey key)321         private MacImpl(ProtocolVersion protocolVersion, MacAlg macAlg,
322                 SecretKey key) throws NoSuchAlgorithmException,
323                         InvalidKeyException {
324             if (macAlg == null) {
325                 throw new RuntimeException("Null MacAlg");
326             }
327 
328             // using SSL MAC computation?
329             boolean useSSLMac = (protocolVersion.id < ProtocolVersion.TLS10.id);
330             String algorithm;
331             switch (macAlg) {
332                 case M_MD5:
333                     algorithm = useSSLMac ? "SslMacMD5" : "HmacMD5";
334                     break;
335                 case M_SHA:
336                     algorithm = useSSLMac ? "SslMacSHA1" : "HmacSHA1";
337                     break;
338                 case M_SHA256:
339                     algorithm = "HmacSHA256";    // TLS 1.2+
340                     break;
341                 case M_SHA384:
342                     algorithm = "HmacSHA384";    // TLS 1.2+
343                     break;
344                 default:
345                     throw new RuntimeException("Unknown MacAlg " + macAlg);
346             }
347 
348             Mac m = JsseJce.getMac(algorithm);
349             m.init(key);
350             this.macAlg = macAlg;
351             this.mac = m;
352         }
353 
354         @Override
macAlg()355         public MacAlg macAlg() {
356             return macAlg;
357         }
358 
359         @Override
compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)360         public byte[] compute(byte type, ByteBuffer bb,
361                 byte[] sequence, boolean isSimulated) {
362 
363             if (macAlg.size == 0) {
364                 return new byte[0];
365             }
366 
367             if (!isSimulated) {
368                 // Uses the explicit sequence number for the computation.
369                 byte[] additional =
370                     acquireAuthenticationBytes(type, bb.remaining(), sequence);
371                 mac.update(additional);
372             }
373             mac.update(bb);
374 
375             return mac.doFinal();
376         }
377     }
378 
379     // NULL SSL MAC
380     private static final
381             class SSLNullMac extends SSLNullAuthenticator implements MAC {
382         private final MacImpl macImpl;
SSLNullMac()383         public SSLNullMac() {
384             super();
385             this.macImpl = new MacImpl();
386         }
387 
388         @Override
macAlg()389         public MacAlg macAlg() {
390             return macImpl.macAlg;
391         }
392 
393         @Override
compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)394         public byte[] compute(byte type, ByteBuffer bb,
395                 byte[] sequence, boolean isSimulated) {
396             return macImpl.compute(type, bb, sequence, isSimulated);
397         }
398     }
399 
400     // For SSL 3.0
401     private static final
402             class SSL30Mac extends SSL30Authenticator implements MAC {
403         private final MacImpl macImpl;
SSL30Mac(ProtocolVersion protocolVersion, MacAlg macAlg, SecretKey key)404         public SSL30Mac(ProtocolVersion protocolVersion,
405                 MacAlg macAlg, SecretKey key) throws NoSuchAlgorithmException,
406                         InvalidKeyException {
407             super();
408             this.macImpl = new MacImpl(protocolVersion, macAlg, key);
409         }
410 
411         @Override
macAlg()412         public MacAlg macAlg() {
413             return macImpl.macAlg;
414         }
415 
416         @Override
compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)417         public byte[] compute(byte type, ByteBuffer bb,
418                 byte[] sequence, boolean isSimulated) {
419             return macImpl.compute(type, bb, sequence, isSimulated);
420         }
421     }
422 
423     // For TLS 1.0 - 1.2
424     private static final
425             class TLS10Mac extends TLS10Authenticator implements MAC {
426         private final MacImpl macImpl;
TLS10Mac(ProtocolVersion protocolVersion, MacAlg macAlg, SecretKey key)427         public TLS10Mac(ProtocolVersion protocolVersion,
428                 MacAlg macAlg, SecretKey key) throws NoSuchAlgorithmException,
429                         InvalidKeyException {
430             super(protocolVersion);
431             this.macImpl = new MacImpl(protocolVersion, macAlg, key);
432         }
433 
434         @Override
macAlg()435         public MacAlg macAlg() {
436             return macImpl.macAlg;
437         }
438 
439         @Override
compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)440         public byte[] compute(byte type, ByteBuffer bb,
441                 byte[] sequence, boolean isSimulated) {
442             return macImpl.compute(type, bb, sequence, isSimulated);
443         }
444     }
445 
toLong(byte[] recordEnS)446     static final long toLong(byte[] recordEnS) {
447         if (recordEnS != null && recordEnS.length == 8) {
448             return ((recordEnS[0] & 0xFFL) << 56) |
449                    ((recordEnS[1] & 0xFFL) << 48) |
450                    ((recordEnS[2] & 0xFFL) << 40) |
451                    ((recordEnS[3] & 0xFFL) << 32) |
452                    ((recordEnS[4] & 0xFFL) << 24) |
453                    ((recordEnS[5] & 0xFFL) << 16) |
454                    ((recordEnS[6] & 0xFFL) <<  8) |
455                     (recordEnS[7] & 0xFFL);
456         }
457 
458         return -1L;
459     }
460 }
461