src/java.base/share/classes/sun/security/ssl/Authenticator.java
changeset 50768 68fa3d4026ea
parent 47216 71c04702a3d5
child 53734 cb1642ccc732
equal deleted inserted replaced
50767:356eaea05bf0 50768:68fa3d4026ea
     1 /*
     1 /*
     2  * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
     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.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package sun.security.ssl;
    26 package sun.security.ssl;
    27 
    27 
       
    28 import java.nio.ByteBuffer;
       
    29 import java.security.InvalidKeyException;
       
    30 import java.security.NoSuchAlgorithmException;
    28 import java.util.Arrays;
    31 import java.util.Arrays;
       
    32 import javax.crypto.Mac;
       
    33 import javax.crypto.SecretKey;
       
    34 import sun.security.ssl.CipherSuite.MacAlg;
    29 
    35 
    30 /**
    36 /**
    31  * This class represents an SSL/TLS/DTLS message authentication token,
    37  * This class represents an SSL/TLS/DTLS message authentication token,
    32  * which encapsulates a sequence number and ensures that attempts to
    38  * which encapsulates a sequence number and ensures that attempts to
    33  * delete or reorder messages can be detected.
    39  * delete or reorder messages can be detected.
    34  *
       
    35  * Each connection state contains a sequence number, which is maintained
       
    36  * separately for read and write states.
       
    37  *
       
    38  * For SSL/TLS protocols, the sequence number MUST be set to zero
       
    39  * whenever a connection state is made the active state.
       
    40  *
       
    41  * DTLS uses an explicit sequence number, rather than an implicit one.
       
    42  * Sequence numbers are maintained separately for each epoch, with
       
    43  * each sequence number initially being 0 for each epoch.  The sequence
       
    44  * number used to compute the DTLS MAC is the 64-bit value formed by
       
    45  * concatenating the epoch and the sequence number.
       
    46  *
       
    47  * Sequence numbers do not wrap.  If an implementation would need to wrap
       
    48  * a sequence number, it must renegotiate instead.  A sequence number is
       
    49  * incremented after each record: specifically, the first record transmitted
       
    50  * under a particular connection state MUST use sequence number 0.
       
    51  */
    40  */
    52 class Authenticator {
    41 abstract class Authenticator {
    53 
       
    54     // byte array containing the additional authentication information for
    42     // byte array containing the additional authentication information for
    55     // each record
    43     // each record
    56     private final byte[] block;
    44     protected final byte[] block;   // at least 8 bytes for sequence number
    57 
    45 
    58     // the block size of SSL v3.0:
    46     private Authenticator(byte[] block) {
    59     // sequence number + record type + + record length
    47         this.block = block;
    60     private static final int BLOCK_SIZE_SSL = 8 + 1 + 2;
       
    61 
       
    62     // the block size of TLS v1.0 and later:
       
    63     // sequence number + record type + protocol version + record length
       
    64     private static final int BLOCK_SIZE_TLS = 8 + 1 + 2 + 2;
       
    65 
       
    66     // the block size of DTLS v1.0 and later:
       
    67     // epoch + sequence number + record type + protocol version + record length
       
    68     private static final int BLOCK_SIZE_DTLS = 2 + 6 + 1 + 2 + 2;
       
    69 
       
    70     private final boolean isDTLS;
       
    71 
       
    72     /**
       
    73      * Default construct, no message authentication token is initialized.
       
    74      *
       
    75      * Note that this construct can only be called for null MAC
       
    76      */
       
    77     protected Authenticator(boolean isDTLS) {
       
    78         if (isDTLS) {
       
    79             // For DTLS protocols, plaintexts use explicit epoch and
       
    80             // sequence number in each record.  The first 8 byte of
       
    81             // the block is initialized for null MAC so that the
       
    82             // epoch and sequence number can be acquired to generate
       
    83             // plaintext records.
       
    84             block = new byte[8];
       
    85         } else {
       
    86             block = new byte[0];
       
    87         }
       
    88 
       
    89         this.isDTLS = isDTLS;
       
    90     }
    48     }
    91 
    49 
    92     /**
    50     /**
    93      * Constructs the message authentication token for the specified
    51      * Constructs the message authentication token for the specified
    94      * SSL/TLS protocol.
    52      * SSL/TLS protocol.
    95      */
    53      */
    96     Authenticator(ProtocolVersion protocolVersion) {
    54     static Authenticator valueOf(ProtocolVersion protocolVersion) {
    97         if (protocolVersion.isDTLSProtocol()) {
    55         if (protocolVersion.isDTLS) {
    98             block = new byte[BLOCK_SIZE_DTLS];
    56             if (protocolVersion.useTLS13PlusSpec()) {
    99             block[9] = protocolVersion.major;
    57                 return new DTLS13Authenticator(protocolVersion);
   100             block[10] = protocolVersion.minor;
    58             } else {
   101 
    59                 return new DTLS10Authenticator(protocolVersion);
   102             this.isDTLS = true;
    60             }
   103         } else if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
       
   104             block = new byte[BLOCK_SIZE_TLS];
       
   105             block[9] = protocolVersion.major;
       
   106             block[10] = protocolVersion.minor;
       
   107 
       
   108             this.isDTLS = false;
       
   109         } else {
    61         } else {
   110             block = new byte[BLOCK_SIZE_SSL];
    62             if (protocolVersion.useTLS13PlusSpec()) {
   111 
    63                 return new TLS13Authenticator(protocolVersion);
   112             this.isDTLS = false;
    64             } else if (protocolVersion.useTLS10PlusSpec()) {
   113         }
    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
       
    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 
       
    94     static Authenticator nullTlsMac() {
       
    95         return new SSLNullMac();
       
    96     }
       
    97 
       
    98     static Authenticator nullDtlsMac() {
       
    99         return new DTLSNullMac();
   114     }
   100     }
   115 
   101 
   116     /**
   102     /**
   117      * Checks whether the sequence number is close to wrap.
   103      * Checks whether the sequence number is close to wrap.
   118      *
   104      *
   120      * Sequence numbers do not wrap. When the sequence number is near
   106      * Sequence numbers do not wrap. When the sequence number is near
   121      * to wrap, we need to close the connection immediately.
   107      * to wrap, we need to close the connection immediately.
   122      *
   108      *
   123      * @return true if the sequence number is close to wrap
   109      * @return true if the sequence number is close to wrap
   124      */
   110      */
   125     final boolean seqNumOverflow() {
   111     abstract boolean seqNumOverflow();
   126         /*
       
   127          * Conservatively, we don't allow more records to be generated
       
   128          * when there are only 2^8 sequence numbers left.
       
   129          */
       
   130         if (isDTLS) {
       
   131             return (block.length != 0 &&
       
   132                 // no epoch bytes, block[0] and block[1]
       
   133                 block[2] == (byte)0xFF && block[3] == (byte)0xFF &&
       
   134                 block[4] == (byte)0xFF && block[5] == (byte)0xFF &&
       
   135                 block[6] == (byte)0xFF);
       
   136         } else {
       
   137             return (block.length != 0 &&
       
   138                 block[0] == (byte)0xFF && block[1] == (byte)0xFF &&
       
   139                 block[2] == (byte)0xFF && block[3] == (byte)0xFF &&
       
   140                 block[4] == (byte)0xFF && block[5] == (byte)0xFF &&
       
   141                 block[6] == (byte)0xFF);
       
   142         }
       
   143     }
       
   144 
   112 
   145     /**
   113     /**
   146      * Checks whether the sequence number close to renew.
   114      * Checks whether the sequence number close to renew.
   147      *
   115      *
   148      * Sequence numbers are of type uint64 and may not exceed 2^64-1.
   116      * Sequence numbers are of type uint64 and may not exceed 2^64-1.
   150      * implementation would need to wrap a sequence number, it must
   118      * implementation would need to wrap a sequence number, it must
   151      * renegotiate instead.
   119      * renegotiate instead.
   152      *
   120      *
   153      * @return true if the sequence number is huge enough to renew
   121      * @return true if the sequence number is huge enough to renew
   154      */
   122      */
   155     final boolean seqNumIsHuge() {
   123     abstract boolean seqNumIsHuge();
   156         /*
       
   157          * Conservatively, we should ask for renegotiation when there are
       
   158          * only 2^32 sequence numbers left.
       
   159          */
       
   160         if (isDTLS) {
       
   161             return (block.length != 0 &&
       
   162                 // no epoch bytes, block[0] and block[1]
       
   163                 block[2] == (byte)0xFF && block[3] == (byte)0xFF);
       
   164         } else {
       
   165             return (block.length != 0 &&
       
   166                 block[0] == (byte)0xFF && block[1] == (byte)0xFF &&
       
   167                 block[2] == (byte)0xFF && block[3] == (byte)0xFF);
       
   168         }
       
   169     }
       
   170 
   124 
   171     /**
   125     /**
   172      * Gets the current sequence number, including the epoch number for
   126      * Gets the current sequence number, including the epoch number for
   173      * DTLS protocols.
   127      * DTLS protocols.
   174      *
   128      *
   179     }
   133     }
   180 
   134 
   181     /**
   135     /**
   182      * Sets the epoch number (only apply to DTLS protocols).
   136      * Sets the epoch number (only apply to DTLS protocols).
   183      */
   137      */
   184     final void setEpochNumber(int epoch) {
   138     void setEpochNumber(int epoch) {
   185         if (!isDTLS) {
   139         throw new UnsupportedOperationException(
   186             throw new RuntimeException(
       
   187                 "Epoch numbers apply to DTLS protocols only");
   140                 "Epoch numbers apply to DTLS protocols only");
   188         }
       
   189 
       
   190         block[0] = (byte)((epoch >> 8) & 0xFF);
       
   191         block[1] = (byte)(epoch & 0xFF);
       
   192     }
   141     }
   193 
   142 
   194     /**
   143     /**
   195      * Increase the sequence number.
   144      * Increase the sequence number.
   196      */
   145      */
   206     }
   155     }
   207 
   156 
   208     /**
   157     /**
   209      * Acquires the current message authentication information with the
   158      * Acquires the current message authentication information with the
   210      * specified record type and fragment length, and then increases the
   159      * specified record type and fragment length, and then increases the
   211      * sequence number.
   160      * sequence number if using implicit sequence number.
   212      *
   161      *
   213      * @param  type the record type
   162      * @param  type the record type
   214      * @param  length the fragment of the record
   163      * @param  length the fragment of the record
   215      * @param  sequence the explicit sequence number of the record
   164      * @param  sequence the explicit sequence number of the record
   216      *
   165      *
   217      * @return the byte array of the current message authentication information
   166      * @return the byte array of the current message authentication information
   218      */
   167      */
   219     final byte[] acquireAuthenticationBytes(
   168     byte[] acquireAuthenticationBytes(
   220             byte type, int length, byte[] sequence) {
   169             byte type, int length, byte[] sequence) {
   221 
   170         throw new UnsupportedOperationException("Used by AEAD algorithms only");
   222         byte[] copy = block.clone();
   171     }
   223         if (sequence != null) {
   172 
   224             if (sequence.length != 8) {
   173     private static class SSLAuthenticator extends Authenticator {
   225                 throw new RuntimeException(
   174         private SSLAuthenticator(byte[] block) {
   226                         "Insufficient explicit sequence number bytes");
   175             super(block);
   227             }
   176         }
   228 
   177 
   229             System.arraycopy(sequence, 0, copy, 0, sequence.length);
   178         @Override
   230         }   // Otherwise, use the implicit sequence number.
   179         boolean seqNumOverflow() {
   231 
   180             /*
   232         if (block.length != 0) {
   181              * Conservatively, we don't allow more records to be generated
   233             copy[8] = type;
   182              * when there are only 2^8 sequence numbers left.
   234 
   183              */
   235             copy[copy.length - 2] = (byte)(length >> 8);
   184             return (block.length != 0 &&
   236             copy[copy.length - 1] = (byte)(length);
   185                 block[0] == (byte)0xFF && block[1] == (byte)0xFF &&
   237 
   186                 block[2] == (byte)0xFF && block[3] == (byte)0xFF &&
   238             if (sequence == null || sequence.length != 0) {
   187                 block[4] == (byte)0xFF && block[5] == (byte)0xFF &&
       
   188                 block[6] == (byte)0xFF);
       
   189         }
       
   190 
       
   191         @Override
       
   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 {
       
   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 
       
   212         private SSL30Authenticator() {
       
   213             super(new byte[BLOCK_SIZE]);
       
   214         }
       
   215 
       
   216         @Override
       
   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 
       
   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
       
   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.
   239                 // Increase the implicit sequence number in the block array.
   256                 // Increase the implicit sequence number in the block array.
   240                 increaseSequenceNumber();
   257                 increaseSequenceNumber();
   241             }
   258             }
   242         }
   259 
   243 
   260             ad[8] = type;
   244         return copy;
   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 
       
   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
       
   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 {
       
   297         private DTLSAuthenticator(byte[] block) {
       
   298             super(block);
       
   299         }
       
   300 
       
   301         @Override
       
   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
       
   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
       
   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 {
       
   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 
       
   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
       
   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 
       
   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
       
   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 {
       
   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          */
       
   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          */
       
   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 
       
   455         private MacImpl() {
       
   456             macAlg = MacAlg.M_NULL;
       
   457             mac = null;
       
   458         }
       
   459 
       
   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
       
   494         public MacAlg macAlg() {
       
   495             return macAlg;
       
   496         }
       
   497 
       
   498         @Override
       
   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;
       
   522         public SSLNullMac() {
       
   523             super();
       
   524             this.macImpl = new MacImpl();
       
   525         }
       
   526 
       
   527         @Override
       
   528         public MacAlg macAlg() {
       
   529             return macImpl.macAlg;
       
   530         }
       
   531 
       
   532         @Override
       
   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;
       
   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
       
   551         public MacAlg macAlg() {
       
   552             return macImpl.macAlg;
       
   553         }
       
   554 
       
   555         @Override
       
   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;
       
   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
       
   574         public MacAlg macAlg() {
       
   575             return macImpl.macAlg;
       
   576         }
       
   577 
       
   578         @Override
       
   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;
       
   589         public DTLSNullMac() {
       
   590             super();
       
   591             this.macImpl = new MacImpl();
       
   592         }
       
   593 
       
   594         @Override
       
   595         public MacAlg macAlg() {
       
   596             return macImpl.macAlg;
       
   597         }
       
   598 
       
   599         @Override
       
   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;
       
   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
       
   618         public MacAlg macAlg() {
       
   619             return macImpl.macAlg;
       
   620         }
       
   621 
       
   622         @Override
       
   623         public byte[] compute(byte type, ByteBuffer bb,
       
   624                 byte[] sequence, boolean isSimulated) {
       
   625             return macImpl.compute(type, bb, sequence, isSimulated);
       
   626         }
   245     }
   627     }
   246 
   628 
   247     static final long toLong(byte[] recordEnS) {
   629     static final long toLong(byte[] recordEnS) {
   248         if (recordEnS != null && recordEnS.length == 8) {
   630         if (recordEnS != null && recordEnS.length == 8) {
   249             return ((recordEnS[0] & 0xFFL) << 56) |
   631             return ((recordEnS[0] & 0xFFL) << 56) |