src/java.base/share/classes/sun/security/ssl/OutputRecord.java
changeset 50768 68fa3d4026ea
parent 47216 71c04702a3d5
child 51407 910f7b56592f
equal deleted inserted replaced
50767:356eaea05bf0 50768:68fa3d4026ea
     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, used after Handshake.Finished
    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 endOfPt = destination.limit();
       
   292             destination.limit(endOfPt + 1);
       
   293             destination.put(endOfPt, contentType);
       
   294         }
       
   295 
       
   296         // use the right TLSCiphertext.opaque_type and legacy_record_version
       
   297         ProtocolVersion pv = protocolVersion;
       
   298         if (!encCipher.isNullCipher()) {
       
   299             pv = ProtocolVersion.TLS12;
       
   300             contentType = ContentType.APPLICATION_DATA.id;
       
   301         } else if (protocolVersion.useTLS13PlusSpec()) {
       
   302             pv = ProtocolVersion.TLS12;
       
   303         }
       
   304 
       
   305         byte[] sequenceNumber = encCipher.authenticator.sequenceNumber();
       
   306         encCipher.encrypt(contentType, destination);
       
   307 
       
   308         // Finish out the record header.
       
   309         int fragLen = destination.limit() - headerOffset - headerSize;
       
   310         destination.put(headerOffset, contentType);
       
   311         destination.put(headerOffset + 1, pv.major);
       
   312         destination.put(headerOffset + 2, pv.minor);
       
   313 
       
   314         // fragment length
       
   315         destination.put(headerOffset + 3, (byte)(fragLen >> 8));
       
   316         destination.put(headerOffset + 4, (byte)fragLen);
       
   317 
       
   318         // Update destination position to reflect the amount of data produced.
       
   319         destination.position(destination.limit());
       
   320 
       
   321         return Authenticator.toLong(sequenceNumber);
       
   322     }
       
   323 
       
   324     static long t10Encrypt(
       
   325             SSLWriteCipher encCipher, byte contentType, ByteBuffer destination,
       
   326             int headerOffset, int dstLim, int headerSize,
       
   327             ProtocolVersion protocolVersion) {
       
   328         byte[] sequenceNumber = encCipher.authenticator.sequenceNumber();
       
   329         encCipher.encrypt(contentType, destination);
       
   330 
       
   331         // Finish out the record header.
       
   332         int fragLen = destination.limit() - headerOffset - headerSize;
       
   333 
       
   334         destination.put(headerOffset, contentType);         // content type
       
   335         destination.put(headerOffset + 1, protocolVersion.major);
       
   336         destination.put(headerOffset + 2, protocolVersion.minor);
       
   337 
       
   338         // fragment length
       
   339         destination.put(headerOffset + 3, (byte)(fragLen >> 8));
       
   340         destination.put(headerOffset + 4, (byte)fragLen);
   316 
   341 
   317         // Update destination position to reflect the amount of data produced.
   342         // Update destination position to reflect the amount of data produced.
   318         destination.position(destination.limit());
   343         destination.position(destination.limit());
   319 
   344 
   320         return Authenticator.toLong(sequenceNumber);
   345         return Authenticator.toLong(sequenceNumber);
   322 
   347 
   323     // Encrypt a fragment and wrap up a record.
   348     // Encrypt a fragment and wrap up a record.
   324     //
   349     //
   325     // Uses the internal expandable buf variable and the current
   350     // Uses the internal expandable buf variable and the current
   326     // protocolVersion variable.
   351     // protocolVersion variable.
   327     void encrypt(Authenticator authenticator,
   352     long encrypt(
   328             CipherBox encCipher, byte contentType, int headerSize) {
   353             SSLWriteCipher encCipher, byte contentType, int headerSize) {
   329 
   354         if (protocolVersion.useTLS13PlusSpec()) {
       
   355             return t13Encrypt(encCipher, contentType, headerSize);
       
   356         } else {
       
   357             return t10Encrypt(encCipher, contentType, headerSize);
       
   358         }
       
   359     }
       
   360 
       
   361     private static final class T13PaddingHolder {
       
   362         private static final byte[] zeros = new byte[16];
       
   363     }
       
   364 
       
   365     long t13Encrypt(
       
   366             SSLWriteCipher encCipher, byte contentType, int headerSize) {
       
   367         if (!encCipher.isNullCipher()) {
       
   368             // inner plaintext
       
   369             write(contentType);
       
   370             write(T13PaddingHolder.zeros, 0, T13PaddingHolder.zeros.length);
       
   371         }
       
   372 
       
   373         byte[] sequenceNumber = encCipher.authenticator.sequenceNumber();
       
   374         int position = headerSize;
       
   375         int contentLen = count - position;
       
   376 
       
   377         // ensure the capacity
       
   378         int packetSize = encCipher.calculatePacketSize(contentLen, headerSize);
       
   379         if (packetSize > buf.length) {
       
   380             byte[] newBuf = new byte[packetSize];
       
   381             System.arraycopy(buf, 0, newBuf, 0, count);
       
   382             buf = newBuf;
       
   383         }
       
   384 
       
   385         // use the right TLSCiphertext.opaque_type and legacy_record_version
       
   386         ProtocolVersion pv = protocolVersion;
       
   387         if (!encCipher.isNullCipher()) {
       
   388             pv = ProtocolVersion.TLS12;
       
   389             contentType = ContentType.APPLICATION_DATA.id;
       
   390         } else {
       
   391             pv = ProtocolVersion.TLS12;
       
   392         }
       
   393 
       
   394         ByteBuffer destination = ByteBuffer.wrap(buf, position, contentLen);
       
   395         count = headerSize + encCipher.encrypt(contentType, destination);
       
   396 
       
   397         // Fill out the header, write it and the message.
       
   398         int fragLen = count - headerSize;
       
   399 
       
   400         buf[0] = contentType;
       
   401         buf[1] = pv.major;
       
   402         buf[2] = pv.minor;
       
   403         buf[3] = (byte)((fragLen >> 8) & 0xFF);
       
   404         buf[4] = (byte)(fragLen & 0xFF);
       
   405 
       
   406         return Authenticator.toLong(sequenceNumber);
       
   407     }
       
   408 
       
   409     long t10Encrypt(
       
   410             SSLWriteCipher encCipher, byte contentType, int headerSize) {
       
   411         byte[] sequenceNumber = encCipher.authenticator.sequenceNumber();
   330         int position = headerSize + writeCipher.getExplicitNonceSize();
   412         int position = headerSize + writeCipher.getExplicitNonceSize();
   331 
   413         int contentLen = count - position;
   332         // "flip" but skip over header again, add MAC & encrypt
   414 
   333         int macLen = 0;
   415         // ensure the capacity
   334         if (authenticator instanceof MAC) {
   416         int packetSize = encCipher.calculatePacketSize(contentLen, headerSize);
   335             MAC signer = (MAC)authenticator;
   417         if (packetSize > buf.length) {
   336             macLen = signer.MAClen();
   418             byte[] newBuf = new byte[packetSize];
   337             if (macLen != 0) {
   419             System.arraycopy(buf, 0, newBuf, 0, count);
   338                 byte[] hash = signer.compute(contentType,
   420             buf = newBuf;
   339                         buf, position, (count - position), false);
   421         }
   340 
   422         ByteBuffer destination = ByteBuffer.wrap(buf, position, contentLen);
   341                 write(hash, 0, hash.length);
   423         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 
   424 
   377         // Fill out the header, write it and the message.
   425         // Fill out the header, write it and the message.
   378         int fragLen = count - headerSize;
   426         int fragLen = count - headerSize;
   379         buf[0] = contentType;
   427         buf[0] = contentType;
   380         buf[1] = protocolVersion.major;
   428         buf[1] = protocolVersion.major;
   381         buf[2] = protocolVersion.minor;
   429         buf[2] = protocolVersion.minor;
   382         buf[3] = (byte)((fragLen >> 8) & 0xFF);
   430         buf[3] = (byte)((fragLen >> 8) & 0xFF);
   383         buf[4] = (byte)(fragLen & 0xFF);
   431         buf[4] = (byte)(fragLen & 0xFF);
       
   432 
       
   433         return Authenticator.toLong(sequenceNumber);
   384     }
   434     }
   385 
   435 
   386     static ByteBuffer encodeV2ClientHello(
   436     static ByteBuffer encodeV2ClientHello(
   387             byte[] fragment, int offset, int length) throws IOException {
   437             byte[] fragment, int offset, int length) throws IOException {
   388 
       
   389         int v3SessIdLenOffset = offset + 34;      //  2: client_version
   438         int v3SessIdLenOffset = offset + 34;      //  2: client_version
   390                                                   // 32: random
   439                                                   // 32: random
   391 
   440 
   392         int v3SessIdLen = fragment[v3SessIdLenOffset];
   441         int v3SessIdLen = fragment[v3SessIdLenOffset];
   393         int v3CSLenOffset = v3SessIdLenOffset + 1 + v3SessIdLen;
   442         int v3CSLenOffset = v3SessIdLenOffset + 1 + v3SessIdLen;
   447          */
   496          */
   448         int msgLen = dstBuf.position() - 2;   // Exclude the legth field itself
   497         int msgLen = dstBuf.position() - 2;   // Exclude the legth field itself
   449         dstBuf.position(0);
   498         dstBuf.position(0);
   450         dstBuf.put((byte)(0x80 | ((msgLen >>> 8) & 0xFF)));  // pos: 0
   499         dstBuf.put((byte)(0x80 | ((msgLen >>> 8) & 0xFF)));  // pos: 0
   451         dstBuf.put((byte)(msgLen & 0xFF));                   // pos: 1
   500         dstBuf.put((byte)(msgLen & 0xFF));                   // pos: 1
   452         dstBuf.put(HandshakeMessage.ht_client_hello);        // pos: 2
   501         dstBuf.put(SSLHandshake.CLIENT_HELLO.id);            // pos: 2
   453         dstBuf.put(fragment[offset]);         // major version, pos: 3
   502         dstBuf.put(fragment[offset]);         // major version, pos: 3
   454         dstBuf.put(fragment[offset + 1]);     // minor version, pos: 4
   503         dstBuf.put(fragment[offset + 1]);     // minor version, pos: 4
   455         dstBuf.put((byte)(v2CSLen >>> 8));                   // pos: 5
   504         dstBuf.put((byte)(v2CSLen >>> 8));                   // pos: 5
   456         dstBuf.put((byte)(v2CSLen & 0xFF));                  // pos: 6
   505         dstBuf.put((byte)(v2CSLen & 0xFF));                  // pos: 6
   457         dstBuf.put((byte)0x00);           // session_id_length, pos: 7
   506         dstBuf.put((byte)0x00);           // session_id_length, pos: 7