| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
package sun.security.ssl;  | 
 | 
 | 
 | 
import java.io.IOException;  | 
 | 
import java.nio.ByteBuffer;  | 
 | 
import javax.net.ssl.SSLException;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
interface Record { | 
 | 
    static final int    maxMacSize = 48;          | 
 | 
                                                // AEAD tag size  | 
 | 
    static final int    maxDataSize = 16384;      | 
 | 
    static final int    maxPadding = 256;         | 
 | 
    static final int    maxIVLength = 16;         | 
 | 
 | 
 | 
    static final int    maxFragmentSize = 18432;      | 
 | 
                                                    // 2^14 + 2048  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    static final boolean enableCBCProtection =  | 
 | 
            Utilities.getBooleanProperty("jsse.enableCBCProtection", true); | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    static final int OVERFLOW_OF_INT08 = (0x01 << 8);  | 
 | 
    static final int OVERFLOW_OF_INT16 = (0x01 << 16);  | 
 | 
    static final int OVERFLOW_OF_INT24 = (0x01 << 24);  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    static int getInt8(ByteBuffer m) throws IOException { | 
 | 
        verifyLength(m, 1);  | 
 | 
        return (m.get() & 0xFF);  | 
 | 
    }  | 
 | 
 | 
 | 
    static int getInt16(ByteBuffer m) throws IOException { | 
 | 
        verifyLength(m, 2);  | 
 | 
        return ((m.get() & 0xFF) << 8) |  | 
 | 
                (m.get() & 0xFF);  | 
 | 
    }  | 
 | 
 | 
 | 
    static int getInt24(ByteBuffer m) throws IOException { | 
 | 
        verifyLength(m, 3);  | 
 | 
        return ((m.get() & 0xFF) << 16) |  | 
 | 
               ((m.get() & 0xFF) <<  8) |  | 
 | 
                (m.get() & 0xFF);  | 
 | 
    }  | 
 | 
 | 
 | 
    static int getInt32(ByteBuffer m) throws IOException { | 
 | 
        verifyLength(m, 4);  | 
 | 
        return ((m.get() & 0xFF) << 24) |  | 
 | 
               ((m.get() & 0xFF) << 16) |  | 
 | 
               ((m.get() & 0xFF) <<  8) |  | 
 | 
                (m.get() & 0xFF);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    static byte[] getBytes8(ByteBuffer m) throws IOException { | 
 | 
        int len = Record.getInt8(m);  | 
 | 
        verifyLength(m, len);  | 
 | 
        byte[] b = new byte[len];  | 
 | 
 | 
 | 
        m.get(b);  | 
 | 
        return b;  | 
 | 
    }  | 
 | 
 | 
 | 
    static byte[] getBytes16(ByteBuffer m) throws IOException { | 
 | 
        int len = Record.getInt16(m);  | 
 | 
        verifyLength(m, len);  | 
 | 
        byte[] b = new byte[len];  | 
 | 
 | 
 | 
        m.get(b);  | 
 | 
        return b;  | 
 | 
    }  | 
 | 
 | 
 | 
    static byte[] getBytes24(ByteBuffer m) throws IOException { | 
 | 
        int len = Record.getInt24(m);  | 
 | 
        verifyLength(m, len);  | 
 | 
        byte[] b = new byte[len];  | 
 | 
 | 
 | 
        m.get(b);  | 
 | 
        return b;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    static void putInt8(ByteBuffer m, int i) throws IOException { | 
 | 
        verifyLength(m, 1);  | 
 | 
        m.put((byte)(i & 0xFF));  | 
 | 
    }  | 
 | 
 | 
 | 
    static void putInt16(ByteBuffer m, int i) throws IOException { | 
 | 
        verifyLength(m, 2);  | 
 | 
        m.put((byte)((i >> 8) & 0xFF));  | 
 | 
        m.put((byte)(i & 0xFF));  | 
 | 
    }  | 
 | 
 | 
 | 
    static void putInt24(ByteBuffer m, int i) throws IOException { | 
 | 
        verifyLength(m, 3);  | 
 | 
        m.put((byte)((i >> 16) & 0xFF));  | 
 | 
        m.put((byte)((i >> 8) & 0xFF));  | 
 | 
        m.put((byte)(i & 0xFF));  | 
 | 
    }  | 
 | 
 | 
 | 
    static void putInt32(ByteBuffer m, int i) throws IOException { | 
 | 
        m.put((byte)((i >> 24) & 0xFF));  | 
 | 
        m.put((byte)((i >> 16) & 0xFF));  | 
 | 
        m.put((byte)((i >> 8) & 0xFF));  | 
 | 
        m.put((byte)(i & 0xFF));  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    static void putBytes8(ByteBuffer m, byte[] s) throws IOException { | 
 | 
        if (s == null || s.length == 0) { | 
 | 
            verifyLength(m, 1);  | 
 | 
            putInt8(m, 0);  | 
 | 
        } else { | 
 | 
            verifyLength(m, 1 + s.length);  | 
 | 
            putInt8(m, s.length);  | 
 | 
            m.put(s);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    static void putBytes16(ByteBuffer m, byte[] s) throws IOException { | 
 | 
        if (s == null || s.length == 0) { | 
 | 
            verifyLength(m, 2);  | 
 | 
            putInt16(m, 0);  | 
 | 
        } else { | 
 | 
            verifyLength(m, 2 + s.length);  | 
 | 
            putInt16(m, s.length);  | 
 | 
            m.put(s);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    static void putBytes24(ByteBuffer m, byte[] s) throws IOException { | 
 | 
        if (s == null || s.length == 0) { | 
 | 
            verifyLength(m, 3);  | 
 | 
            putInt24(m, 0);  | 
 | 
        } else { | 
 | 
            verifyLength(m, 3 + s.length);  | 
 | 
            putInt24(m, s.length);  | 
 | 
            m.put(s);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
    static void verifyLength(  | 
 | 
            ByteBuffer m, int len) throws SSLException { | 
 | 
        if (len > m.remaining()) { | 
 | 
            throw new SSLException("Insufficient space in the buffer, " + | 
 | 
                    "may be cause by an unexpected end of handshake data.");  | 
 | 
        }  | 
 | 
    }  | 
 | 
}  |