src/java.base/share/classes/sun/security/ssl/OutputRecord.java
branchJDK-8145252-TLS13-branch
changeset 56542 56aaa6cb3693
parent 47216 71c04702a3d5
child 56686 07dc566630ee
equal deleted inserted replaced
56541:92cbbfc996f3 56542:56aaa6cb3693
     1 /*
     1 /*
     2  * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1996, 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.io.*;
    28 import java.io.ByteArrayOutputStream;
    29 import java.nio.*;
    29 import java.io.Closeable;
    30 import java.util.Arrays;
    30 import java.io.IOException;
    31 
    31 import java.io.OutputStream;
    32 import javax.net.ssl.SSLException;
    32 import java.nio.ByteBuffer;
    33 import sun.security.util.HexDumpEncoder;
    33 import sun.security.ssl.SSLCipher.SSLWriteCipher;
    34 
       
    35 
    34 
    36 /**
    35 /**
    37  * {@code OutputRecord} takes care of the management of SSL/TLS/DTLS output
    36  * {@code OutputRecord} takes care of the management of SSL/(D)TLS
    38  * records, including buffering, encryption, handshake messages marshal, etc.
    37  * output records, including buffering, encryption, handshake
       
    38  * messages marshal, etc.
    39  *
    39  *
    40  * @author David Brownell
    40  * @author David Brownell
    41  */
    41  */
    42 abstract class OutputRecord extends ByteArrayOutputStream
    42 abstract class OutputRecord
    43             implements Record, Closeable {
    43         extends ByteArrayOutputStream implements Record, Closeable {
    44 
    44     SSLWriteCipher              writeCipher;
    45     /* Class and subclass dynamic debugging support */
    45     // Needed for KeyUpdate
    46     static final Debug          debug = Debug.getInstance("ssl");
    46     TransportContext            tc;
    47 
    47 
    48     Authenticator               writeAuthenticator;
    48     final HandshakeHash         handshakeHash;
    49     CipherBox                   writeCipher;
       
    50 
       
    51     HandshakeHash               handshakeHash;
       
    52     boolean                     firstMessage;
    49     boolean                     firstMessage;
    53 
    50 
    54     // current protocol version, sent as record version
    51     // current protocol version, sent as record version
    55     ProtocolVersion             protocolVersion;
    52     ProtocolVersion             protocolVersion;
    56 
    53 
    73 
    70 
    74     /*
    71     /*
    75      * Mappings from V3 cipher suite encodings to their pure V2 equivalents.
    72      * Mappings from V3 cipher suite encodings to their pure V2 equivalents.
    76      * This is taken from the SSL V3 specification, Appendix E.
    73      * This is taken from the SSL V3 specification, Appendix E.
    77      */
    74      */
    78     private static int[] V3toV2CipherMap1 =
    75     private static final int[] V3toV2CipherMap1 =
    79         {-1, -1, -1, 0x02, 0x01, -1, 0x04, 0x05, -1, 0x06, 0x07};
    76         {-1, -1, -1, 0x02, 0x01, -1, 0x04, 0x05, -1, 0x06, 0x07};
    80     private static int[] V3toV2CipherMap3 =
    77     private static final int[] V3toV2CipherMap3 =
    81         {-1, -1, -1, 0x80, 0x80, -1, 0x80, 0x80, -1, 0x40, 0xC0};
    78         {-1, -1, -1, 0x80, 0x80, -1, 0x80, 0x80, -1, 0x40, 0xC0};
    82 
    79 
    83     OutputRecord() {
    80     OutputRecord(HandshakeHash handshakeHash, SSLWriteCipher writeCipher) {
    84         this.writeCipher = CipherBox.NULL;
    81         this.writeCipher = writeCipher;
    85         this.firstMessage = true;
    82         this.firstMessage = true;
    86         this.fragmentSize = Record.maxDataSize;
    83         this.fragmentSize = Record.maxDataSize;
       
    84 
       
    85         this.handshakeHash = handshakeHash;
    87 
    86 
    88         // Please set packetSize and protocolVersion in the implementation.
    87         // Please set packetSize and protocolVersion in the implementation.
    89     }
    88     }
    90 
    89 
    91     void setVersion(ProtocolVersion protocolVersion) {
    90     void setVersion(ProtocolVersion protocolVersion) {
    95     /*
    94     /*
    96      * Updates helloVersion of this record.
    95      * Updates helloVersion of this record.
    97      */
    96      */
    98     synchronized void setHelloVersion(ProtocolVersion helloVersion) {
    97     synchronized void setHelloVersion(ProtocolVersion helloVersion) {
    99         this.helloVersion = helloVersion;
    98         this.helloVersion = helloVersion;
   100     }
       
   101 
       
   102     /*
       
   103      * For handshaking, we need to be able to hash every byte above the
       
   104      * record marking layer.  This is where we're guaranteed to see those
       
   105      * bytes, so this is where we can hash them.
       
   106      */
       
   107     void setHandshakeHash(HandshakeHash handshakeHash) {
       
   108         this.handshakeHash = handshakeHash;
       
   109     }
    99     }
   110 
   100 
   111     /*
   101     /*
   112      * Return true iff the record is empty -- to avoid doing the work
   102      * Return true iff the record is empty -- to avoid doing the work
   113      * of sending empty records over the network.
   103      * of sending empty records over the network.
   115     boolean isEmpty() {
   105     boolean isEmpty() {
   116         return false;
   106         return false;
   117     }
   107     }
   118 
   108 
   119     boolean seqNumIsHuge() {
   109     boolean seqNumIsHuge() {
   120         return (writeAuthenticator != null) &&
   110         return (writeCipher.authenticator != null) &&
   121                         writeAuthenticator.seqNumIsHuge();
   111                         writeCipher.authenticator.seqNumIsHuge();
   122     }
   112     }
   123 
   113 
   124     // SSLEngine and SSLSocket
   114     // SSLEngine and SSLSocket
   125     abstract void encodeAlert(byte level, byte description) throws IOException;
   115     abstract void encodeAlert(byte level, byte description) throws IOException;
   126 
   116 
   130 
   120 
   131     // SSLEngine and SSLSocket
   121     // SSLEngine and SSLSocket
   132     abstract void encodeChangeCipherSpec() throws IOException;
   122     abstract void encodeChangeCipherSpec() throws IOException;
   133 
   123 
   134     // apply to SSLEngine only
   124     // apply to SSLEngine only
   135     Ciphertext encode(ByteBuffer[] sources, int offset, int length,
   125     Ciphertext encode(
   136             ByteBuffer destination) throws IOException {
   126         ByteBuffer[] srcs, int srcsOffset, int srcsLength,
       
   127         ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws IOException {
       
   128 
   137         throw new UnsupportedOperationException();
   129         throw new UnsupportedOperationException();
   138     }
   130     }
   139 
   131 
   140     // apply to SSLEngine only
   132     // apply to SSLEngine only
   141     void encodeV2NoCipher() throws IOException {
   133     void encodeV2NoCipher() throws IOException {
   142         throw new UnsupportedOperationException();
   134         throw new UnsupportedOperationException();
   143     }
   135     }
   144 
   136 
   145     // apply to SSLSocket only
   137     // apply to SSLSocket only
   146     void deliver(byte[] source, int offset, int length) throws IOException {
   138     void deliver(
       
   139             byte[] source, int offset, int length) throws IOException {
   147         throw new UnsupportedOperationException();
   140         throw new UnsupportedOperationException();
   148     }
   141     }
   149 
   142 
   150     // apply to SSLSocket only
   143     // apply to SSLSocket only
   151     void setDeliverStream(OutputStream outputStream) {
   144     void setDeliverStream(OutputStream outputStream) {
   152         throw new UnsupportedOperationException();
   145         throw new UnsupportedOperationException();
   153     }
   146     }
   154 
   147 
   155     // apply to SSLEngine only
   148     void changeWriteCiphers(SSLWriteCipher writeCipher,
   156     Ciphertext acquireCiphertext(ByteBuffer destination) throws IOException {
   149             boolean useChangeCipherSpec) throws IOException {
   157         throw new UnsupportedOperationException();
   150         if (useChangeCipherSpec) {
   158     }
   151             encodeChangeCipherSpec();
   159 
   152         }
   160     void changeWriteCiphers(Authenticator writeAuthenticator,
       
   161             CipherBox writeCipher) throws IOException {
       
   162 
       
   163         encodeChangeCipherSpec();
       
   164 
   153 
   165         /*
   154         /*
   166          * Dispose of any intermediate state in the underlying cipher.
   155          * Dispose of any intermediate state in the underlying cipher.
   167          * For PKCS11 ciphers, this will release any attached sessions,
   156          * For PKCS11 ciphers, this will release any attached sessions,
   168          * and thus make finalization faster.
   157          * and thus make finalization faster.
   170          * Since MAC's doFinal() is called for every SSL/TLS packet, it's
   159          * Since MAC's doFinal() is called for every SSL/TLS packet, it's
   171          * not necessary to do the same with MAC's.
   160          * not necessary to do the same with MAC's.
   172          */
   161          */
   173         writeCipher.dispose();
   162         writeCipher.dispose();
   174 
   163 
   175         this.writeAuthenticator = writeAuthenticator;
       
   176         this.writeCipher = writeCipher;
   164         this.writeCipher = writeCipher;
   177         this.isFirstAppOutputRecord = true;
   165         this.isFirstAppOutputRecord = true;
   178     }
   166     }
   179 
   167 
   180     void changePacketSize(int packetSize) {
   168     void changePacketSize(int packetSize) {
   189         return packetSize;
   177         return packetSize;
   190     }
   178     }
   191 
   179 
   192     // apply to DTLS SSLEngine
   180     // apply to DTLS SSLEngine
   193     void initHandshaker() {
   181     void initHandshaker() {
       
   182         // blank
       
   183     }
       
   184 
       
   185     // apply to DTLS SSLEngine
       
   186     void finishHandshake() {
   194         // blank
   187         // blank
   195     }
   188     }
   196 
   189 
   197     // apply to DTLS SSLEngine
   190     // apply to DTLS SSLEngine
   198     void launchRetransmission() {
   191     void launchRetransmission() {
   205             isClosed = true;
   198             isClosed = true;
   206             writeCipher.dispose();
   199             writeCipher.dispose();
   207         }
   200         }
   208     }
   201     }
   209 
   202 
       
   203     synchronized boolean isClosed() {
       
   204         return isClosed;
       
   205     }
       
   206 
   210     //
   207     //
   211     // shared helpers
   208     // shared helpers
   212     //
   209     //
   213 
   210 
   214     // Encrypt a fragment and wrap up a record.
   211     // Encrypt a fragment and wrap up a record.
   215     //
   212     //
   216     // To be consistent with the spec of SSLEngine.wrap() methods, the
   213     // To be consistent with the spec of SSLEngine.wrap() methods, the
   217     // destination ByteBuffer's position is updated to reflect the amount
   214     // destination ByteBuffer's position is updated to reflect the amount
   218     // of data produced.  The limit remains the same.
   215     // of data produced.  The limit remains the same.
   219     static long encrypt(Authenticator authenticator,
   216     static long encrypt(
   220             CipherBox encCipher, byte contentType, ByteBuffer destination,
   217             SSLWriteCipher encCipher, byte contentType, ByteBuffer destination,
   221             int headerOffset, int dstLim, int headerSize,
   218             int headerOffset, int dstLim, int headerSize,
   222             ProtocolVersion protocolVersion, boolean isDTLS) {
   219             ProtocolVersion protocolVersion) {
   223 
   220         boolean isDTLS = protocolVersion.isDTLS;
   224         byte[] sequenceNumber = null;
       
   225         int dstContent = destination.position();
       
   226 
       
   227         // Acquire the current sequence number before using.
       
   228         if (isDTLS) {
   221         if (isDTLS) {
   229             sequenceNumber = authenticator.sequenceNumber();
   222             if (protocolVersion.useTLS13PlusSpec()) {
   230         }
   223                 return d13Encrypt(encCipher,
   231 
   224                         contentType, destination, headerOffset,
   232         // The sequence number may be shared for different purpose.
   225                         dstLim, headerSize, protocolVersion);
   233         boolean sharedSequenceNumber = false;
   226             } else {
   234 
   227                 return d10Encrypt(encCipher,
   235         // "flip" but skip over header again, add MAC & encrypt
   228                         contentType, destination, headerOffset,
   236         if (authenticator instanceof MAC) {
   229                         dstLim, headerSize, protocolVersion);
   237             MAC signer = (MAC)authenticator;
       
   238             if (signer.MAClen() != 0) {
       
   239                 byte[] hash = signer.compute(contentType, destination, false);
       
   240 
       
   241                 /*
       
   242                  * position was advanced to limit in MAC compute above.
       
   243                  *
       
   244                  * Mark next area as writable (above layers should have
       
   245                  * established that we have plenty of room), then write
       
   246                  * out the hash.
       
   247                  */
       
   248                 destination.limit(destination.limit() + hash.length);
       
   249                 destination.put(hash);
       
   250 
       
   251                 // reset the position and limit
       
   252                 destination.limit(destination.position());
       
   253                 destination.position(dstContent);
       
   254 
       
   255                 // The signer has used and increased the sequence number.
       
   256                 if (isDTLS) {
       
   257                     sharedSequenceNumber = true;
       
   258                 }
       
   259             }
       
   260         }
       
   261 
       
   262         if (!encCipher.isNullCipher()) {
       
   263             if (protocolVersion.useTLS11PlusSpec() &&
       
   264                     (encCipher.isCBCMode() || encCipher.isAEADMode())) {
       
   265                 byte[] nonce = encCipher.createExplicitNonce(
       
   266                         authenticator, contentType, destination.remaining());
       
   267                 destination.position(headerOffset + headerSize);
       
   268                 destination.put(nonce);
       
   269             }
       
   270             if (!encCipher.isAEADMode()) {
       
   271                 // The explicit IV in TLS 1.1 and later can be encrypted.
       
   272                 destination.position(headerOffset + headerSize);
       
   273             }   // Otherwise, DON'T encrypt the nonce_explicit for AEAD mode
       
   274 
       
   275             // Encrypt may pad, so again the limit may be changed.
       
   276             encCipher.encrypt(destination, dstLim);
       
   277 
       
   278             // The cipher has used and increased the sequence number.
       
   279             if (isDTLS && encCipher.isAEADMode()) {
       
   280                 sharedSequenceNumber = true;
       
   281             }
   230             }
   282         } else {
   231         } else {
   283             destination.position(destination.limit());
   232             if (protocolVersion.useTLS13PlusSpec()) {
   284         }
   233                 return t13Encrypt(encCipher,
       
   234                         contentType, destination, headerOffset,
       
   235                         dstLim, headerSize, protocolVersion);
       
   236             } else {
       
   237                 return t10Encrypt(encCipher,
       
   238                         contentType, destination, headerOffset,
       
   239                         dstLim, headerSize, protocolVersion);
       
   240             }
       
   241         }
       
   242     }
       
   243 
       
   244     static long d13Encrypt(
       
   245             SSLWriteCipher encCipher, byte contentType, ByteBuffer destination,
       
   246             int headerOffset, int dstLim, int headerSize,
       
   247             ProtocolVersion protocolVersion) {
       
   248         throw new UnsupportedOperationException("Not supported yet.");
       
   249     }
       
   250 
       
   251     private static long d10Encrypt(
       
   252             SSLWriteCipher encCipher, byte contentType, ByteBuffer destination,
       
   253             int headerOffset, int dstLim, int headerSize,
       
   254             ProtocolVersion protocolVersion) {
       
   255         byte[] sequenceNumber = encCipher.authenticator.sequenceNumber();
       
   256         encCipher.encrypt(contentType, destination);
   285 
   257 
   286         // Finish out the record header.
   258         // Finish out the record header.
   287         int fragLen = destination.limit() - headerOffset - headerSize;
   259         int fragLen = destination.limit() - headerOffset - headerSize;
   288 
   260 
   289         destination.put(headerOffset, contentType);         // content type
   261         destination.put(headerOffset, contentType);         // content type
   290         destination.put(headerOffset + 1, protocolVersion.major);
   262         destination.put(headerOffset + 1, protocolVersion.major);
   291         destination.put(headerOffset + 2, protocolVersion.minor);
   263         destination.put(headerOffset + 2, protocolVersion.minor);
   292         if (!isDTLS) {
   264 
   293             // fragment length
   265         // epoch and sequence_number
   294             destination.put(headerOffset + 3, (byte)(fragLen >> 8));
   266         destination.put(headerOffset + 3, sequenceNumber[0]);
   295             destination.put(headerOffset + 4, (byte)fragLen);
   267         destination.put(headerOffset + 4, sequenceNumber[1]);
   296         } else {
   268         destination.put(headerOffset + 5, sequenceNumber[2]);
   297             // epoch and sequence_number
   269         destination.put(headerOffset + 6, sequenceNumber[3]);
   298             destination.put(headerOffset + 3, sequenceNumber[0]);
   270         destination.put(headerOffset + 7, sequenceNumber[4]);
   299             destination.put(headerOffset + 4, sequenceNumber[1]);
   271         destination.put(headerOffset + 8, sequenceNumber[5]);
   300             destination.put(headerOffset + 5, sequenceNumber[2]);
   272         destination.put(headerOffset + 9, sequenceNumber[6]);
   301             destination.put(headerOffset + 6, sequenceNumber[3]);
   273         destination.put(headerOffset + 10, sequenceNumber[7]);
   302             destination.put(headerOffset + 7, sequenceNumber[4]);
   274 
   303             destination.put(headerOffset + 8, sequenceNumber[5]);
   275         // fragment length
   304             destination.put(headerOffset + 9, sequenceNumber[6]);
   276         destination.put(headerOffset + 11, (byte)(fragLen >> 8));
   305             destination.put(headerOffset + 10, sequenceNumber[7]);
   277         destination.put(headerOffset + 12, (byte)fragLen);
   306 
   278 
   307             // fragment length
   279         // Update destination position to reflect the amount of data produced.
   308             destination.put(headerOffset + 11, (byte)(fragLen >> 8));
   280         destination.position(destination.limit());
   309             destination.put(headerOffset + 12, (byte)fragLen);
   281 
   310 
   282         return Authenticator.toLong(sequenceNumber);
   311             // Increase the sequence number for next use if it is not shared.
   283     }
   312             if (!sharedSequenceNumber) {
   284 
   313                 authenticator.increaseSequenceNumber();
   285     static long t13Encrypt(
   314             }
   286             SSLWriteCipher encCipher, byte contentType, ByteBuffer destination,
   315         }
   287             int headerOffset, int dstLim, int headerSize,
       
   288             ProtocolVersion protocolVersion) {
       
   289         if (!encCipher.isNullCipher()) {
       
   290             // inner plaintext, using zero length padding.
       
   291             int pos = destination.position();
       
   292             destination.position(destination.limit());
       
   293             destination.limit(destination.limit() + 1);
       
   294             destination.put(contentType);
       
   295             destination.position(pos);
       
   296         }
       
   297 
       
   298         // use the right TLSCiphertext.opaque_type and legacy_record_version
       
   299         ProtocolVersion pv = protocolVersion;
       
   300         if (!encCipher.isNullCipher()) {
       
   301             pv = ProtocolVersion.TLS12;
       
   302             contentType = ContentType.APPLICATION_DATA.id;
       
   303         } else if (protocolVersion.useTLS13PlusSpec()) {
       
   304             pv = ProtocolVersion.TLS12;
       
   305         }
       
   306 
       
   307         byte[] sequenceNumber = encCipher.authenticator.sequenceNumber();
       
   308         encCipher.encrypt(contentType, destination);
       
   309 
       
   310         // Finish out the record header.
       
   311         int fragLen = destination.limit() - headerOffset - headerSize;
       
   312         destination.put(headerOffset, contentType);
       
   313         destination.put(headerOffset + 1, pv.major);
       
   314         destination.put(headerOffset + 2, pv.minor);
       
   315 
       
   316         // fragment length
       
   317         destination.put(headerOffset + 3, (byte)(fragLen >> 8));
       
   318         destination.put(headerOffset + 4, (byte)fragLen);
       
   319 
       
   320         // Update destination position to reflect the amount of data produced.
       
   321         destination.position(destination.limit());
       
   322 
       
   323         return Authenticator.toLong(sequenceNumber);
       
   324     }
       
   325 
       
   326     static long t10Encrypt(
       
   327             SSLWriteCipher encCipher, byte contentType, ByteBuffer destination,
       
   328             int headerOffset, int dstLim, int headerSize,
       
   329             ProtocolVersion protocolVersion) {
       
   330         byte[] sequenceNumber = encCipher.authenticator.sequenceNumber();
       
   331         encCipher.encrypt(contentType, destination);
       
   332 
       
   333         // Finish out the record header.
       
   334         int fragLen = destination.limit() - headerOffset - headerSize;
       
   335 
       
   336         destination.put(headerOffset, contentType);         // content type
       
   337         destination.put(headerOffset + 1, protocolVersion.major);
       
   338         destination.put(headerOffset + 2, protocolVersion.minor);
       
   339 
       
   340         // fragment length
       
   341         destination.put(headerOffset + 3, (byte)(fragLen >> 8));
       
   342         destination.put(headerOffset + 4, (byte)fragLen);
   316 
   343 
   317         // Update destination position to reflect the amount of data produced.
   344         // Update destination position to reflect the amount of data produced.
   318         destination.position(destination.limit());
   345         destination.position(destination.limit());
   319 
   346 
   320         return Authenticator.toLong(sequenceNumber);
   347         return Authenticator.toLong(sequenceNumber);
   322 
   349 
   323     // Encrypt a fragment and wrap up a record.
   350     // Encrypt a fragment and wrap up a record.
   324     //
   351     //
   325     // Uses the internal expandable buf variable and the current
   352     // Uses the internal expandable buf variable and the current
   326     // protocolVersion variable.
   353     // protocolVersion variable.
   327     void encrypt(Authenticator authenticator,
   354     long encrypt(
   328             CipherBox encCipher, byte contentType, int headerSize) {
   355             SSLWriteCipher encCipher, byte contentType, int headerSize) {
   329 
   356         if (protocolVersion.useTLS13PlusSpec()) {
       
   357             return t13Encrypt(encCipher, contentType, headerSize);
       
   358         } else {
       
   359             return t10Encrypt(encCipher, contentType, headerSize);
       
   360         }
       
   361     }
       
   362 
       
   363     private static final class T13PaddingHolder {
       
   364         private static final byte[] zeros = new byte[16];
       
   365     }
       
   366 
       
   367     long t13Encrypt(
       
   368             SSLWriteCipher encCipher, byte contentType, int headerSize) {
       
   369         if (!encCipher.isNullCipher()) {
       
   370             // inner plaintext
       
   371             write(contentType);
       
   372             write(T13PaddingHolder.zeros, 0, T13PaddingHolder.zeros.length);
       
   373         }
       
   374 
       
   375         byte[] sequenceNumber = encCipher.authenticator.sequenceNumber();
       
   376         int position = headerSize;
       
   377         int contentLen = count - position;
       
   378 
       
   379         // ensure the capacity
       
   380         int packetSize = encCipher.calculatePacketSize(contentLen, headerSize);
       
   381         if (packetSize > buf.length) {
       
   382             byte[] newBuf = new byte[packetSize];
       
   383             System.arraycopy(buf, 0, newBuf, 0, count);
       
   384             buf = newBuf;
       
   385         }
       
   386 
       
   387         // use the right TLSCiphertext.opaque_type and legacy_record_version
       
   388         ProtocolVersion pv = protocolVersion;
       
   389         if (!encCipher.isNullCipher()) {
       
   390             pv = ProtocolVersion.TLS12;
       
   391             contentType = ContentType.APPLICATION_DATA.id;
       
   392         } else {
       
   393             pv = ProtocolVersion.TLS12;
       
   394         }
       
   395 
       
   396         ByteBuffer destination = ByteBuffer.wrap(buf, position, contentLen);
       
   397         count = headerSize + encCipher.encrypt(contentType, destination);
       
   398 
       
   399         // Fill out the header, write it and the message.
       
   400         int fragLen = count - headerSize;
       
   401 
       
   402         buf[0] = contentType;
       
   403         buf[1] = pv.major;
       
   404         buf[2] = pv.minor;
       
   405         buf[3] = (byte)((fragLen >> 8) & 0xFF);
       
   406         buf[4] = (byte)(fragLen & 0xFF);
       
   407 
       
   408         return Authenticator.toLong(sequenceNumber);
       
   409     }
       
   410 
       
   411     long t10Encrypt(
       
   412             SSLWriteCipher encCipher, byte contentType, int headerSize) {
       
   413         byte[] sequenceNumber = encCipher.authenticator.sequenceNumber();
   330         int position = headerSize + writeCipher.getExplicitNonceSize();
   414         int position = headerSize + writeCipher.getExplicitNonceSize();
   331 
   415         int contentLen = count - position;
   332         // "flip" but skip over header again, add MAC & encrypt
   416 
   333         int macLen = 0;
   417         // ensure the capacity
   334         if (authenticator instanceof MAC) {
   418         int packetSize = encCipher.calculatePacketSize(contentLen, headerSize);
   335             MAC signer = (MAC)authenticator;
   419         if (packetSize > buf.length) {
   336             macLen = signer.MAClen();
   420             byte[] newBuf = new byte[packetSize];
   337             if (macLen != 0) {
   421             System.arraycopy(buf, 0, newBuf, 0, count);
   338                 byte[] hash = signer.compute(contentType,
   422             buf = newBuf;
   339                         buf, position, (count - position), false);
   423         }
   340 
   424         ByteBuffer destination = ByteBuffer.wrap(buf, position, contentLen);
   341                 write(hash, 0, hash.length);
   425         count = headerSize + encCipher.encrypt(contentType, destination);
   342             }
       
   343         }
       
   344 
       
   345         if (!encCipher.isNullCipher()) {
       
   346             // Requires explicit IV/nonce for CBC/AEAD cipher suites for
       
   347             // TLS 1.1 or later.
       
   348             if (protocolVersion.useTLS11PlusSpec() &&
       
   349                     (encCipher.isCBCMode() || encCipher.isAEADMode())) {
       
   350 
       
   351                 byte[] nonce = encCipher.createExplicitNonce(
       
   352                         authenticator, contentType, (count - position));
       
   353                 int noncePos = position - nonce.length;
       
   354                 System.arraycopy(nonce, 0, buf, noncePos, nonce.length);
       
   355             }
       
   356 
       
   357             if (!encCipher.isAEADMode()) {
       
   358                 // The explicit IV in TLS 1.1 and later can be encrypted.
       
   359                 position = headerSize;
       
   360             }   // Otherwise, DON'T encrypt the nonce_explicit for AEAD mode
       
   361 
       
   362             // increase buf capacity if necessary
       
   363             int fragSize = count - position;
       
   364             int packetSize =
       
   365                     encCipher.calculatePacketSize(fragSize, macLen, headerSize);
       
   366             if (packetSize > (buf.length - position)) {
       
   367                 byte[] newBuf = new byte[position + packetSize];
       
   368                 System.arraycopy(buf, 0, newBuf, 0, count);
       
   369                 buf = newBuf;
       
   370             }
       
   371 
       
   372             // Encrypt may pad, so again the count may be changed.
       
   373             count = position +
       
   374                     encCipher.encrypt(buf, position, (count - position));
       
   375         }
       
   376 
   426 
   377         // Fill out the header, write it and the message.
   427         // Fill out the header, write it and the message.
   378         int fragLen = count - headerSize;
   428         int fragLen = count - headerSize;
   379         buf[0] = contentType;
   429         buf[0] = contentType;
   380         buf[1] = protocolVersion.major;
   430         buf[1] = protocolVersion.major;
   381         buf[2] = protocolVersion.minor;
   431         buf[2] = protocolVersion.minor;
   382         buf[3] = (byte)((fragLen >> 8) & 0xFF);
   432         buf[3] = (byte)((fragLen >> 8) & 0xFF);
   383         buf[4] = (byte)(fragLen & 0xFF);
   433         buf[4] = (byte)(fragLen & 0xFF);
       
   434 
       
   435         return Authenticator.toLong(sequenceNumber);
   384     }
   436     }
   385 
   437 
   386     static ByteBuffer encodeV2ClientHello(
   438     static ByteBuffer encodeV2ClientHello(
   387             byte[] fragment, int offset, int length) throws IOException {
   439             byte[] fragment, int offset, int length) throws IOException {
   388 
       
   389         int v3SessIdLenOffset = offset + 34;      //  2: client_version
   440         int v3SessIdLenOffset = offset + 34;      //  2: client_version
   390                                                   // 32: random
   441                                                   // 32: random
   391 
   442 
   392         int v3SessIdLen = fragment[v3SessIdLenOffset];
   443         int v3SessIdLen = fragment[v3SessIdLenOffset];
   393         int v3CSLenOffset = v3SessIdLenOffset + 1 + v3SessIdLen;
   444         int v3CSLenOffset = v3SessIdLenOffset + 1 + v3SessIdLen;
   447          */
   498          */
   448         int msgLen = dstBuf.position() - 2;   // Exclude the legth field itself
   499         int msgLen = dstBuf.position() - 2;   // Exclude the legth field itself
   449         dstBuf.position(0);
   500         dstBuf.position(0);
   450         dstBuf.put((byte)(0x80 | ((msgLen >>> 8) & 0xFF)));  // pos: 0
   501         dstBuf.put((byte)(0x80 | ((msgLen >>> 8) & 0xFF)));  // pos: 0
   451         dstBuf.put((byte)(msgLen & 0xFF));                   // pos: 1
   502         dstBuf.put((byte)(msgLen & 0xFF));                   // pos: 1
   452         dstBuf.put(HandshakeMessage.ht_client_hello);        // pos: 2
   503         dstBuf.put(SSLHandshake.CLIENT_HELLO.id);            // pos: 2
   453         dstBuf.put(fragment[offset]);         // major version, pos: 3
   504         dstBuf.put(fragment[offset]);         // major version, pos: 3
   454         dstBuf.put(fragment[offset + 1]);     // minor version, pos: 4
   505         dstBuf.put(fragment[offset + 1]);     // minor version, pos: 4
   455         dstBuf.put((byte)(v2CSLen >>> 8));                   // pos: 5
   506         dstBuf.put((byte)(v2CSLen >>> 8));                   // pos: 5
   456         dstBuf.put((byte)(v2CSLen & 0xFF));                  // pos: 6
   507         dstBuf.put((byte)(v2CSLen & 0xFF));                  // pos: 6
   457         dstBuf.put((byte)0x00);           // session_id_length, pos: 7
   508         dstBuf.put((byte)0x00);           // session_id_length, pos: 7