jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java
author xuelei
Sat, 24 Nov 2012 04:09:19 -0800
changeset 14664 e71aa0962e70
parent 12428 e9feb65d37fa
child 16113 946ec9b22004
child 16045 9d08c3b9a6a0
permissions -rw-r--r--
8003950: Adds missing Override annotations and removes unnecessary imports in sun.security.ssl Reviewed-by: xuelei Contributed-by: Florian Weimer <fweimer@redhat.com>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
12428
e9feb65d37fa 7157903: JSSE client sockets are very slow
wetmore
parents: 10915
diff changeset
     2
 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
package sun.security.ssl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.nio.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * A OutputRecord class extension which uses external ByteBuffers
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * or the internal ByteArrayOutputStream for data manipulations.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * <P>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * Instead of rewriting this entire class
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * to use ByteBuffers, we leave things intact, so handshake, CCS,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * and alerts will continue to use the internal buffers, but application
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * data will use external buffers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * @author Brad Wetmore
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
final class EngineOutputRecord extends OutputRecord {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
10915
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
    46
    private SSLEngineImpl engine;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    private EngineWriter writer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    private boolean finishedMsg = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
     * All handshake hashing is done by the superclass
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
     * Default constructor makes a record supporting the maximum
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
     * SSL record size.  It allocates the header bytes directly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
     * @param type the content type for the record
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    EngineOutputRecord(byte type, SSLEngineImpl engine) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
        super(type, recordSize(type));
10915
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
    63
        this.engine = engine;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
        writer = engine.writer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
     * Get the size of the buffer we need for records of the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
     * type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
     * <P>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
     * Application data buffers will provide their own byte buffers,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
     * and will not use the internal byte caching.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    private static int recordSize(byte type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
        switch (type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
        case ct_change_cipher_spec:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
        case ct_alert:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
            return maxAlertRecordSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
        case ct_handshake:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
            return maxRecordSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
        case ct_application_data:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        throw new RuntimeException("Unknown record type: " + type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    void setFinishedMsg() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        finishedMsg = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
14664
e71aa0962e70 8003950: Adds missing Override annotations and removes unnecessary imports in sun.security.ssl
xuelei
parents: 12428
diff changeset
    95
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    public void flush() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        finishedMsg = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    boolean isFinishedMsg() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        return finishedMsg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     * Calculate the MAC value, storing the result either in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
     * the internal buffer, or at the end of the destination
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     * ByteBuffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     * <P>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * We assume that the higher levels have assured us enough
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * room, otherwise we'll indirectly throw a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     * BufferOverFlowException runtime exception.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
     * position should equal limit, and points to the next
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * free spot.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    private void addMAC(MAC signer, ByteBuffer bb)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        if (signer.MAClen() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
            byte[] hash = signer.compute(contentType(), bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
             * position was advanced to limit in compute above.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
             * Mark next area as writable (above layers should have
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
             * established that we have plenty of room), then write
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
             * out the hash.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
            bb.limit(bb.limit() + hash.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
            bb.put(hash);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     * Encrypt a ByteBuffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * We assume that the higher levels have assured us enough
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * room for the encryption (plus padding), otherwise we'll
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     * indirectly throw a BufferOverFlowException runtime exception.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * position and limit will be the same, and points to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * next free spot.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    void encrypt(CipherBox box, ByteBuffer bb) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        box.encrypt(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     * Override the actual write below.  We do things this way to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     * consistent with InputRecord.  InputRecord may try to write out
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * data to the peer, and *then* throw an Exception.  This forces
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     * data to be generated/output before the exception is ever
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     * generated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     */
12428
e9feb65d37fa 7157903: JSSE client sockets are very slow
wetmore
parents: 10915
diff changeset
   156
    @Override
e9feb65d37fa 7157903: JSSE client sockets are very slow
wetmore
parents: 10915
diff changeset
   157
    void writeBuffer(OutputStream s, byte [] buf, int off, int len,
e9feb65d37fa 7157903: JSSE client sockets are very slow
wetmore
parents: 10915
diff changeset
   158
            int debugOffset) throws IOException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
         * Copy data out of buffer, it's ready to go.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        ByteBuffer netBB = (ByteBuffer)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            ByteBuffer.allocate(len).put(buf, 0, len).flip();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        writer.putOutboundData(netBB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * Main method for writing non-application data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     * We MAC/encrypt, then send down for processing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    void write(MAC writeMAC, CipherBox writeCipher) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
         * Sanity check.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        switch (contentType()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        case ct_change_cipher_spec:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        case ct_alert:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        case ct_handshake:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
            throw new RuntimeException("unexpected byte buffers");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
         * Don't bother to really write empty records.  We went this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
         * far to drive the handshake machinery, for correctness; not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
         * writing empty records improves performance by cutting CPU
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
         * time and network resource usage.  Also, some protocol
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
         * implementations are fragile and don't like to see empty
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
         * records, so this increases robustness.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
         * (Even change cipher spec messages have a byte of data!)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        if (!isEmpty()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            // compress();              // eventually
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            addMAC(writeMAC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            encrypt(writeCipher);
12428
e9feb65d37fa 7157903: JSSE client sockets are very slow
wetmore
parents: 10915
diff changeset
   198
            write((OutputStream)null, false,  // send down for processing
e9feb65d37fa 7157903: JSSE client sockets are very slow
wetmore
parents: 10915
diff changeset
   199
                (ByteArrayOutputStream)null);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
     * Main wrap/write driver.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
    void write(EngineArgs ea, MAC writeMAC, CipherBox writeCipher)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
         * sanity check to make sure someone didn't inadvertantly
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
         * send us an impossible combination we don't know how
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
         * to process.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        assert(contentType() == ct_application_data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
         * Have we set the MAC's yet?  If not, we're not ready
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
         * to process application data yet.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        if (writeMAC == MAC.NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
         * Don't bother to really write empty records.  We went this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
         * far to drive the handshake machinery, for correctness; not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
         * writing empty records improves performance by cutting CPU
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
         * time and network resource usage.  Also, some protocol
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
         * implementations are fragile and don't like to see empty
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
         * records, so this increases robustness.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
         */
10915
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   232
        if (ea.getAppRemaining() == 0) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        /*
10915
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   237
         * By default, we counter chosen plaintext issues on CBC mode
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   238
         * ciphersuites in SSLv3/TLS1.0 by sending one byte of application
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   239
         * data in the first record of every payload, and the rest in
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   240
         * subsequent record(s). Note that the issues have been solved in
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   241
         * TLS 1.1 or later.
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   242
         *
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   243
         * It is not necessary to split the very first application record of
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   244
         * a freshly negotiated TLS session, as there is no previous
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   245
         * application data to guess.  To improve compatibility, we will not
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   246
         * split such records.
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   247
         *
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   248
         * Because of the compatibility, we'd better produce no more than
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   249
         * SSLSession.getPacketBufferSize() net data for each wrap. As we
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   250
         * need a one-byte record at first, the 2nd record size should be
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   251
         * equal to or less than Record.maxDataSizeMinusOneByteRecord.
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   252
         *
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   253
         * This avoids issues in the outbound direction.  For a full fix,
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   254
         * the peer must have similar protections.
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   255
         */
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   256
        int length;
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   257
        if (engine.needToSplitPayload(writeCipher, protocolVersion)) {
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   258
            write(ea, writeMAC, writeCipher, 0x01);
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   259
            ea.resetLim();      // reset application data buffer limit
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   260
            length = Math.min(ea.getAppRemaining(),
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   261
                        maxDataSizeMinusOneByteRecord);
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   262
        } else {
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   263
            length = Math.min(ea.getAppRemaining(), maxDataSize);
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   264
        }
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   265
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   266
        // Don't bother to really write empty records.
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   267
        if (length > 0) {
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   268
            write(ea, writeMAC, writeCipher, length);
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   269
        }
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   270
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   271
        return;
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   272
    }
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   273
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   274
    void write(EngineArgs ea, MAC writeMAC, CipherBox writeCipher,
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   275
            int length) throws IOException {
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 5506
diff changeset
   276
        /*
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
         * Copy out existing buffer values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        ByteBuffer dstBB = ea.netData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        int dstPos = dstBB.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        int dstLim = dstBB.limit();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
         * Where to put the data.  Jump over the header.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
         * Don't need to worry about SSLv2 rewrites, if we're here,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
         * that's long since done.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        int dstData = dstPos + headerSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        dstBB.position(dstData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        ea.gather(length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
         * "flip" but skip over header again, add MAC & encrypt
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
         * addMAC will expand the limit to reflect the new
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
         * data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        dstBB.limit(dstBB.position());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        dstBB.position(dstData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        addMAC(writeMAC, dstBB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
         * Encrypt may pad, so again the limit may have changed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        dstBB.limit(dstBB.position());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        dstBB.position(dstData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        encrypt(writeCipher, dstBB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        if (debug != null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                && (Debug.isOn("record") || Debug.isOn("handshake"))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            if ((debug != null && Debug.isOn("record"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
                    || contentType() == ct_change_cipher_spec)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                System.out.println(Thread.currentThread().getName()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                    // v3.0/v3.1 ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                    + ", WRITE: " + protocolVersion
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                    + " " + InputRecord.contentName(contentType())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                    + ", length = " + length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        int packetLength = dstBB.limit() - dstData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
         * Finish out the record header.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        dstBB.put(dstPos, contentType());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
        dstBB.put(dstPos + 1, protocolVersion.major);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        dstBB.put(dstPos + 2, protocolVersion.minor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        dstBB.put(dstPos + 3, (byte)(packetLength >> 8));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
        dstBB.put(dstPos + 4, (byte)packetLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
         * Position was already set by encrypt() above.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        dstBB.limit(dstLim);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
}