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/DTLS 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.isDTLS) {
56             if (protocolVersion.useTLS13PlusSpec()) {
57                 return new DTLS13Authenticator(protocolVersion);
58             } else {
59                 return new DTLS10Authenticator(protocolVersion);
60             }
61         } else {
62             if (protocolVersion.useTLS13PlusSpec()) {
63                 return new TLS13Authenticator(protocolVersion);
64             } else if (protocolVersion.useTLS10PlusSpec()) {
65                 return new TLS10Authenticator(protocolVersion);
66             } else {
67                 return new SSL30Authenticator();
68             }
69         }
70     }
71 
72     @SuppressWarnings({"unchecked"})
73     static <T extends Authenticator & MAC> T
valueOf(ProtocolVersion protocolVersion, MacAlg macAlg, SecretKey key)74          valueOf(ProtocolVersion protocolVersion, MacAlg macAlg,
75                  SecretKey key) throws NoSuchAlgorithmException,
76                         InvalidKeyException {
77         if (protocolVersion.isDTLS) {
78             if (protocolVersion.useTLS13PlusSpec()) {
79                 throw new RuntimeException("No MacAlg used in DTLS 1.3");
80             } else {
81                 return (T)(new DTLS10Mac(protocolVersion, macAlg, key));
82             }
83         } else {
84             if (protocolVersion.useTLS13PlusSpec()) {
85                 throw new RuntimeException("No MacAlg used in TLS 1.3");
86             } else if (protocolVersion.useTLS10PlusSpec()) {
87                 return (T)(new TLS10Mac(protocolVersion, macAlg, key));
88             } else {
89                 return (T)(new SSL30Mac(protocolVersion, macAlg, key));
90             }
91         }
92     }
93 
nullTlsMac()94     static Authenticator nullTlsMac() {
95         return new SSLNullMac();
96     }
97 
nullDtlsMac()98     static Authenticator nullDtlsMac() {
99         return new DTLSNullMac();
100     }
101 
102     /**
103      * Checks whether the sequence number is close to wrap.
104      *
105      * Sequence numbers are of type uint64 and may not exceed 2^64-1.
106      * Sequence numbers do not wrap. When the sequence number is near
107      * to wrap, we need to close the connection immediately.
108      *
109      * @return true if the sequence number is close to wrap
110      */
seqNumOverflow()111     abstract boolean seqNumOverflow();
112 
113     /**
114      * Checks whether the sequence number close to renew.
115      *
116      * Sequence numbers are of type uint64 and may not exceed 2^64-1.
117      * Sequence numbers do not wrap.  If a TLS
118      * implementation would need to wrap a sequence number, it must
119      * renegotiate instead.
120      *
121      * @return true if the sequence number is huge enough to renew
122      */
seqNumIsHuge()123     abstract boolean seqNumIsHuge();
124 
125     /**
126      * Gets the current sequence number, including the epoch number for
127      * DTLS protocols.
128      *
129      * @return the byte array of the current sequence number
130      */
sequenceNumber()131     final byte[] sequenceNumber() {
132         return Arrays.copyOf(block, 8);
133     }
134 
135     /**
136      * Sets the epoch number (only apply to DTLS protocols).
137      */
setEpochNumber(int epoch)138     void setEpochNumber(int epoch) {
139         throw new UnsupportedOperationException(
140                 "Epoch numbers apply to DTLS protocols only");
141     }
142 
143     /**
144      * Increase the sequence number.
145      */
increaseSequenceNumber()146     final void increaseSequenceNumber() {
147         /*
148          * The sequence number in the block array is a 64-bit
149          * number stored in big-endian format.
150          */
151         int k = 7;
152         while ((k >= 0) && (++block[k] == 0)) {
153             k--;
154         }
155     }
156 
157     /**
158      * Acquires the current message authentication information with the
159      * specified record type and fragment length, and then increases the
160      * sequence number if using implicit sequence number.
161      *
162      * @param  type the record type
163      * @param  length the fragment of the record
164      * @param  sequence the explicit sequence number of the record
165      *
166      * @return the byte array of the current message authentication information
167      */
acquireAuthenticationBytes( byte type, int length, byte[] sequence)168     byte[] acquireAuthenticationBytes(
169             byte type, int length, byte[] sequence) {
170         throw new UnsupportedOperationException("Used by AEAD algorithms only");
171     }
172 
173     private static class SSLAuthenticator extends Authenticator {
SSLAuthenticator(byte[] block)174         private SSLAuthenticator(byte[] block) {
175             super(block);
176         }
177 
178         @Override
seqNumOverflow()179         boolean seqNumOverflow() {
180             /*
181              * Conservatively, we don't allow more records to be generated
182              * when there are only 2^8 sequence numbers left.
183              */
184             return (block.length != 0 &&
185                 block[0] == (byte)0xFF && block[1] == (byte)0xFF &&
186                 block[2] == (byte)0xFF && block[3] == (byte)0xFF &&
187                 block[4] == (byte)0xFF && block[5] == (byte)0xFF &&
188                 block[6] == (byte)0xFF);
189         }
190 
191         @Override
seqNumIsHuge()192         boolean seqNumIsHuge() {
193             return (block.length != 0 &&
194                 block[0] == (byte)0xFF && block[1] == (byte)0xFF &&
195                 block[2] == (byte)0xFF && block[3] == (byte)0xFF);
196         }
197     }
198 
199     // For null MAC only.
200     private static class SSLNullAuthenticator extends SSLAuthenticator {
SSLNullAuthenticator()201         private SSLNullAuthenticator() {
202             super(new byte[8]);
203         }
204     }
205 
206     // For SSL 3.0
207     private static class SSL30Authenticator extends SSLAuthenticator {
208         // Block size of SSL v3.0:
209         //     sequence number + record type + + record length
210         private static final int BLOCK_SIZE = 11;   // 8 + 1 + 2
211 
SSL30Authenticator()212         private SSL30Authenticator() {
213             super(new byte[BLOCK_SIZE]);
214         }
215 
216         @Override
acquireAuthenticationBytes( byte type, int length, byte[] sequence)217         byte[] acquireAuthenticationBytes(
218                 byte type, int length, byte[] sequence) {
219             byte[] ad = block.clone();
220 
221             // Increase the implicit sequence number in the block array.
222             increaseSequenceNumber();
223 
224             ad[8] = type;
225             ad[9] = (byte)(length >> 8);
226             ad[10] = (byte)(length);
227 
228             return ad;
229         }
230     }
231 
232     // For TLS 1.0 - 1.2
233     private static class TLS10Authenticator extends SSLAuthenticator {
234         // Block size of TLS v1.0/1.1/1.2.
235         //     sequence number + record type + protocol version + record length
236         private static final int BLOCK_SIZE = 13;   // 8 + 1 + 2 + 2
237 
TLS10Authenticator(ProtocolVersion protocolVersion)238         private TLS10Authenticator(ProtocolVersion protocolVersion) {
239             super(new byte[BLOCK_SIZE]);
240             block[9] = protocolVersion.major;
241             block[10] = protocolVersion.minor;
242         }
243 
244         @Override
acquireAuthenticationBytes( byte type, int length, byte[] sequence)245         byte[] acquireAuthenticationBytes(
246                 byte type, int length, byte[] sequence) {
247             byte[] ad = block.clone();
248             if (sequence != null) {
249                 if (sequence.length != 8) {
250                     throw new RuntimeException(
251                             "Insufficient explicit sequence number bytes");
252                 }
253 
254                 System.arraycopy(sequence, 0, ad, 0, sequence.length);
255             } else {    // Otherwise, use the implicit sequence number.
256                 // Increase the implicit sequence number in the block array.
257                 increaseSequenceNumber();
258             }
259 
260             ad[8] = type;
261             ad[11] = (byte)(length >> 8);
262             ad[12] = (byte)(length);
263 
264             return ad;
265         }
266     }
267 
268     // For TLS 1.3
269     private static final class TLS13Authenticator extends SSLAuthenticator {
270         // Block size of TLS v1.3:
271         //     record type + protocol version + record length + sequence number
272         private static final int BLOCK_SIZE = 13;   // 1 + 2 + 2 + 8
273 
TLS13Authenticator(ProtocolVersion protocolVersion)274         private TLS13Authenticator(ProtocolVersion protocolVersion) {
275             super(new byte[BLOCK_SIZE]);
276             block[9] = ProtocolVersion.TLS12.major;
277             block[10] = ProtocolVersion.TLS12.minor;
278         }
279 
280         @Override
acquireAuthenticationBytes( byte type, int length, byte[] sequence)281         byte[] acquireAuthenticationBytes(
282                 byte type, int length, byte[] sequence) {
283             byte[] ad = Arrays.copyOfRange(block, 8, 13);
284 
285             // Increase the implicit sequence number in the block array.
286             increaseSequenceNumber();
287 
288             ad[0] = type;
289             ad[3] = (byte)(length >> 8);
290             ad[4] = (byte)(length & 0xFF);
291 
292             return ad;
293         }
294     }
295 
296     private static class DTLSAuthenticator extends Authenticator {
DTLSAuthenticator(byte[] block)297         private DTLSAuthenticator(byte[] block) {
298             super(block);
299         }
300 
301         @Override
seqNumOverflow()302         boolean seqNumOverflow() {
303             /*
304              * Conservatively, we don't allow more records to be generated
305              * when there are only 2^8 sequence numbers left.
306              */
307             return (block.length != 0 &&
308                 // no epoch bytes, block[0] and block[1]
309                 block[2] == (byte)0xFF && block[3] == (byte)0xFF &&
310                 block[4] == (byte)0xFF && block[5] == (byte)0xFF &&
311                 block[6] == (byte)0xFF);
312         }
313 
314         @Override
seqNumIsHuge()315         boolean seqNumIsHuge() {
316             return (block.length != 0 &&
317                 // no epoch bytes, block[0] and block[1]
318                 block[2] == (byte)0xFF && block[3] == (byte)0xFF);
319         }
320 
321         @Override
setEpochNumber(int epoch)322         void setEpochNumber(int epoch) {
323             block[0] = (byte)((epoch >> 8) & 0xFF);
324             block[1] = (byte)(epoch & 0xFF);
325         }
326     }
327 
328     // For null MAC only.
329     private static class DTLSNullAuthenticator extends DTLSAuthenticator {
DTLSNullAuthenticator()330         private DTLSNullAuthenticator() {
331             // For DTLS protocols, plaintexts use explicit epoch and
332             // sequence number in each record.  The first 8 byte of
333             // the block is initialized for null MAC so that the
334             // epoch and sequence number can be acquired to generate
335             // plaintext records.
336             super(new byte[8]);
337         }
338     }
339 
340     // DTLS 1.0/1.2
341     private static class DTLS10Authenticator extends DTLSAuthenticator {
342         // Block size of DTLS v1.0 and later:
343         //     epoch + sequence number +
344         //     record type + protocol version + record length
345         private static final int BLOCK_SIZE = 13;  // 2 + 6 + 1 + 2 + 2;
346 
DTLS10Authenticator(ProtocolVersion protocolVersion)347         private DTLS10Authenticator(ProtocolVersion protocolVersion) {
348             super(new byte[BLOCK_SIZE]);
349             block[9] = protocolVersion.major;
350             block[10] = protocolVersion.minor;
351         }
352 
353         @Override
acquireAuthenticationBytes( byte type, int length, byte[] sequence)354         byte[] acquireAuthenticationBytes(
355                 byte type, int length, byte[] sequence) {
356             byte[] ad = block.clone();
357             if (sequence != null) {
358                 if (sequence.length != 8) {
359                     throw new RuntimeException(
360                             "Insufficient explicit sequence number bytes");
361                 }
362 
363                 System.arraycopy(sequence, 0, ad, 0, sequence.length);
364             } else {    // Otherwise, use the implicit sequence number.
365                 // Increase the implicit sequence number in the block array.
366                 increaseSequenceNumber();
367             }
368 
369             ad[8] = type;
370             ad[11] = (byte)(length >> 8);
371             ad[12] = (byte)(length);
372 
373             return ad;
374         }
375     }
376 
377     // DTLS 1.3
378     private static final class DTLS13Authenticator extends DTLSAuthenticator {
379         // Block size of DTLS v1.0 and later:
380         //     epoch + sequence number +
381         //     record type + protocol version + record length
382         private static final int BLOCK_SIZE = 13;  // 2 + 6 + 1 + 2 + 2;
383 
DTLS13Authenticator(ProtocolVersion protocolVersion)384         private DTLS13Authenticator(ProtocolVersion protocolVersion) {
385             super(new byte[BLOCK_SIZE]);
386             block[9] = ProtocolVersion.TLS12.major;
387             block[10] = ProtocolVersion.TLS12.minor;
388         }
389 
390         @Override
acquireAuthenticationBytes( byte type, int length, byte[] sequence)391         byte[] acquireAuthenticationBytes(
392                 byte type, int length, byte[] sequence) {
393             byte[] ad = Arrays.copyOfRange(block, 8, 13);
394 
395             // Increase the implicit sequence number in the block array.
396             increaseSequenceNumber();
397 
398             ad[0] = type;
399             ad[3] = (byte)(length >> 8);
400             ad[4] = (byte)(length & 0xFF);
401 
402             return ad;
403         }
404     }
405 
406     interface MAC {
macAlg()407         MacAlg macAlg();
408 
409         /**
410          * Compute and returns the MAC for the remaining data
411          * in this ByteBuffer.
412          *
413          * On return, the bb position == limit, and limit will
414          * have not changed.
415          *
416          * @param type record type
417          * @param bb a ByteBuffer in which the position and limit
418          *          demarcate the data to be MAC'd.
419          * @param isSimulated if true, simulate the MAC computation
420          * @param sequence the explicit sequence number, or null if using
421          *        the implicit sequence number for the computation
422          *
423          * @return the MAC result
424          */
compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)425         byte[] compute(byte type, ByteBuffer bb,
426                 byte[] sequence, boolean isSimulated);
427 
428 
429         /**
430          * Compute and returns the MAC for the remaining data
431          * in this ByteBuffer.
432          *
433          * On return, the bb position == limit, and limit will
434          * have not changed.
435          *
436          * @param type record type
437          * @param bb a ByteBuffer in which the position and limit
438          *        demarcate the data to be MAC'd.
439          * @param isSimulated if true, simulate the MAC computation
440          *
441          * @return the MAC result
442          */
compute(byte type, ByteBuffer bb, boolean isSimulated)443         default byte[] compute(byte type, ByteBuffer bb, boolean isSimulated) {
444             return compute(type, bb, null, isSimulated);
445         }
446     }
447 
448     private class MacImpl implements MAC {
449         // internal identifier for the MAC algorithm
450         private final MacAlg macAlg;
451 
452         // JCE Mac object
453         private final Mac mac;
454 
MacImpl()455         private MacImpl() {
456             macAlg = MacAlg.M_NULL;
457             mac = null;
458         }
459 
MacImpl(ProtocolVersion protocolVersion, MacAlg macAlg, SecretKey key)460         private MacImpl(ProtocolVersion protocolVersion, MacAlg macAlg,
461                 SecretKey key) throws NoSuchAlgorithmException,
462                         InvalidKeyException {
463             if (macAlg == null) {
464                 throw new RuntimeException("Null MacAlg");
465             }
466 
467             // using SSL MAC computation?
468             boolean useSSLMac = (protocolVersion.id < ProtocolVersion.TLS10.id);
469             String algorithm;
470             switch (macAlg) {
471                 case M_MD5:
472                     algorithm = useSSLMac ? "SslMacMD5" : "HmacMD5";
473                     break;
474                 case M_SHA:
475                     algorithm = useSSLMac ? "SslMacSHA1" : "HmacSHA1";
476                     break;
477                 case M_SHA256:
478                     algorithm = "HmacSHA256";    // TLS 1.2+
479                     break;
480                 case M_SHA384:
481                     algorithm = "HmacSHA384";    // TLS 1.2+
482                     break;
483                 default:
484                     throw new RuntimeException("Unknown MacAlg " + macAlg);
485             }
486 
487             Mac m = JsseJce.getMac(algorithm);
488             m.init(key);
489             this.macAlg = macAlg;
490             this.mac = m;
491         }
492 
493         @Override
macAlg()494         public MacAlg macAlg() {
495             return macAlg;
496         }
497 
498         @Override
compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)499         public byte[] compute(byte type, ByteBuffer bb,
500                 byte[] sequence, boolean isSimulated) {
501 
502             if (macAlg.size == 0) {
503                 return new byte[0];
504             }
505 
506             if (!isSimulated) {
507                 // Uses the explicit sequence number for the computation.
508                 byte[] additional =
509                     acquireAuthenticationBytes(type, bb.remaining(), sequence);
510                 mac.update(additional);
511             }
512             mac.update(bb);
513 
514             return mac.doFinal();
515         }
516     }
517 
518     // NULL SSL MAC
519     private static final
520             class SSLNullMac extends SSLNullAuthenticator implements MAC {
521         private final MacImpl macImpl;
SSLNullMac()522         public SSLNullMac() {
523             super();
524             this.macImpl = new MacImpl();
525         }
526 
527         @Override
macAlg()528         public MacAlg macAlg() {
529             return macImpl.macAlg;
530         }
531 
532         @Override
compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)533         public byte[] compute(byte type, ByteBuffer bb,
534                 byte[] sequence, boolean isSimulated) {
535             return macImpl.compute(type, bb, sequence, isSimulated);
536         }
537     }
538 
539     // For SSL 3.0
540     private static final
541             class SSL30Mac extends SSL30Authenticator implements MAC {
542         private final MacImpl macImpl;
SSL30Mac(ProtocolVersion protocolVersion, MacAlg macAlg, SecretKey key)543         public SSL30Mac(ProtocolVersion protocolVersion,
544                 MacAlg macAlg, SecretKey key) throws NoSuchAlgorithmException,
545                         InvalidKeyException {
546             super();
547             this.macImpl = new MacImpl(protocolVersion, macAlg, key);
548         }
549 
550         @Override
macAlg()551         public MacAlg macAlg() {
552             return macImpl.macAlg;
553         }
554 
555         @Override
compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)556         public byte[] compute(byte type, ByteBuffer bb,
557                 byte[] sequence, boolean isSimulated) {
558             return macImpl.compute(type, bb, sequence, isSimulated);
559         }
560     }
561 
562     // For TLS 1.0 - 1.2
563     private static final
564             class TLS10Mac extends TLS10Authenticator implements MAC {
565         private final MacImpl macImpl;
TLS10Mac(ProtocolVersion protocolVersion, MacAlg macAlg, SecretKey key)566         public TLS10Mac(ProtocolVersion protocolVersion,
567                 MacAlg macAlg, SecretKey key) throws NoSuchAlgorithmException,
568                         InvalidKeyException {
569             super(protocolVersion);
570             this.macImpl = new MacImpl(protocolVersion, macAlg, key);
571         }
572 
573         @Override
macAlg()574         public MacAlg macAlg() {
575             return macImpl.macAlg;
576         }
577 
578         @Override
compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)579         public byte[] compute(byte type, ByteBuffer bb,
580                 byte[] sequence, boolean isSimulated) {
581             return macImpl.compute(type, bb, sequence, isSimulated);
582         }
583     }
584 
585     // NULL DTLS MAC
586     private static final
587             class DTLSNullMac extends DTLSNullAuthenticator implements MAC {
588         private final MacImpl macImpl;
DTLSNullMac()589         public DTLSNullMac() {
590             super();
591             this.macImpl = new MacImpl();
592         }
593 
594         @Override
macAlg()595         public MacAlg macAlg() {
596             return macImpl.macAlg;
597         }
598 
599         @Override
compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)600         public byte[] compute(byte type, ByteBuffer bb,
601                 byte[] sequence, boolean isSimulated) {
602             return macImpl.compute(type, bb, sequence, isSimulated);
603         }
604     }
605 
606     // DTLS 1.0/1.2
607     private static final class DTLS10Mac
608             extends DTLS10Authenticator implements MAC {
609         private final MacImpl macImpl;
DTLS10Mac(ProtocolVersion protocolVersion, MacAlg macAlg, SecretKey key)610         public DTLS10Mac(ProtocolVersion protocolVersion,
611                 MacAlg macAlg, SecretKey key) throws NoSuchAlgorithmException,
612                         InvalidKeyException {
613             super(protocolVersion);
614             this.macImpl = new MacImpl(protocolVersion, macAlg, key);
615         }
616 
617         @Override
macAlg()618         public MacAlg macAlg() {
619             return macImpl.macAlg;
620         }
621 
622         @Override
compute(byte type, ByteBuffer bb, byte[] sequence, boolean isSimulated)623         public byte[] compute(byte type, ByteBuffer bb,
624                 byte[] sequence, boolean isSimulated) {
625             return macImpl.compute(type, bb, sequence, isSimulated);
626         }
627     }
628 
toLong(byte[] recordEnS)629     static final long toLong(byte[] recordEnS) {
630         if (recordEnS != null && recordEnS.length == 8) {
631             return ((recordEnS[0] & 0xFFL) << 56) |
632                    ((recordEnS[1] & 0xFFL) << 48) |
633                    ((recordEnS[2] & 0xFFL) << 40) |
634                    ((recordEnS[3] & 0xFFL) << 32) |
635                    ((recordEnS[4] & 0xFFL) << 24) |
636                    ((recordEnS[5] & 0xFFL) << 16) |
637                    ((recordEnS[6] & 0xFFL) <<  8) |
638                     (recordEnS[7] & 0xFFL);
639         }
640 
641         return -1L;
642     }
643 }
644