|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
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."); |
|
} |
|
} |
|
} |