src/java.base/share/classes/sun/security/ssl/Record.java
changeset 50768 68fa3d4026ea
parent 47216 71c04702a3d5
equal deleted inserted replaced
50767:356eaea05bf0 50768:68fa3d4026ea
     1 /*
     1 /*
     2  * Copyright (c) 1996, 2015, 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.IOException;
       
    29 import java.nio.ByteBuffer;
       
    30 import javax.net.ssl.SSLException;
       
    31 
    28 /**
    32 /**
    29  * SSL/TLS/DTLS records, as pulled off (and put onto) a TCP stream.  This is
    33  * SSL/(D)TLS record.
    30  * the base interface, which defines common information and interfaces
    34  *
       
    35  * This is the base interface, which defines common information and interfaces
    31  * used by both Input and Output records.
    36  * used by both Input and Output records.
    32  *
    37  *
    33  * @author David Brownell
    38  * @author David Brownell
    34  */
    39  */
    35 interface Record {
    40 interface Record {
    36 
       
    37     /*
       
    38      * There are four record types, which are part of the interface
       
    39      * to this level (along with the maximum record size).
       
    40      *
       
    41      * enum { change_cipher_spec(20), alert(21), handshake(22),
       
    42      *      application_data(23), (255) } ContentType;
       
    43      */
       
    44     static final byte   ct_change_cipher_spec = 20;
       
    45     static final byte   ct_alert = 21;
       
    46     static final byte   ct_handshake = 22;
       
    47     static final byte   ct_application_data = 23;
       
    48 
       
    49     static final int    maxMacSize = 48;        // the max supported MAC or
    41     static final int    maxMacSize = 48;        // the max supported MAC or
    50                                                 // AEAD tag size
    42                                                 // AEAD tag size
    51     static final int    maxDataSize = 16384;    // 2^14 bytes of data
    43     static final int    maxDataSize = 16384;    // 2^14 bytes of data
    52     static final int    maxPadding = 256;       // block cipher padding
    44     static final int    maxPadding = 256;       // block cipher padding
    53     static final int    maxIVLength = 16;       // the max supported IV length
    45     static final int    maxIVLength = 16;       // the max supported IV length
    57 
    49 
    58     /*
    50     /*
    59      * System property to enable/disable CBC protection in SSL3/TLS1.
    51      * System property to enable/disable CBC protection in SSL3/TLS1.
    60      */
    52      */
    61     static final boolean enableCBCProtection =
    53     static final boolean enableCBCProtection =
    62             Debug.getBooleanProperty("jsse.enableCBCProtection", true);
    54             Utilities.getBooleanProperty("jsse.enableCBCProtection", true);
    63 
    55 
    64     /*
    56     /*
    65      * The overflow values of integers of 8, 16 and 24 bits.
    57      * The overflow values of integers of 8, 16 and 24 bits.
    66      */
    58      */
    67     static final int OVERFLOW_OF_INT08 = (1 << 8);
    59     static final int OVERFLOW_OF_INT08 = (0x01 << 8);
    68     static final int OVERFLOW_OF_INT16 = (1 << 16);
    60     static final int OVERFLOW_OF_INT16 = (0x01 << 16);
    69     static final int OVERFLOW_OF_INT24 = (1 << 24);
    61     static final int OVERFLOW_OF_INT24 = (0x01 << 24);
    70 
    62 
    71     /**
    63     /*
    72      * Return a description for the given content type.
    64      * Read 8, 16, 24, and 32 bit integer data types, encoded
       
    65      * in standard big-endian form.
    73      */
    66      */
    74     static String contentName(byte contentType) {
    67     static int getInt8(ByteBuffer m) throws IOException {
    75         switch (contentType) {
    68         verifyLength(m, 1);
    76         case ct_change_cipher_spec:
    69         return (m.get() & 0xFF);
    77             return "Change Cipher Spec";
    70     }
    78         case ct_alert:
    71 
    79             return "Alert";
    72     static int getInt16(ByteBuffer m) throws IOException {
    80         case ct_handshake:
    73         verifyLength(m, 2);
    81             return "Handshake";
    74         return ((m.get() & 0xFF) << 8) |
    82         case ct_application_data:
    75                 (m.get() & 0xFF);
    83             return "Application Data";
    76     }
    84         default:
    77 
    85             return "contentType = " + contentType;
    78     static int getInt24(ByteBuffer m) throws IOException {
       
    79         verifyLength(m, 3);
       
    80         return ((m.get() & 0xFF) << 16) |
       
    81                ((m.get() & 0xFF) <<  8) |
       
    82                 (m.get() & 0xFF);
       
    83     }
       
    84 
       
    85     static int getInt32(ByteBuffer m) throws IOException {
       
    86         verifyLength(m, 4);
       
    87         return ((m.get() & 0xFF) << 24) |
       
    88                ((m.get() & 0xFF) << 16) |
       
    89                ((m.get() & 0xFF) <<  8) |
       
    90                 (m.get() & 0xFF);
       
    91     }
       
    92 
       
    93     /*
       
    94      * Read byte vectors with 8, 16, and 24 bit length encodings.
       
    95      */
       
    96     static byte[] getBytes8(ByteBuffer m) throws IOException {
       
    97         int len = Record.getInt8(m);
       
    98         verifyLength(m, len);
       
    99         byte[] b = new byte[len];
       
   100 
       
   101         m.get(b);
       
   102         return b;
       
   103     }
       
   104 
       
   105     static byte[] getBytes16(ByteBuffer m) throws IOException {
       
   106         int len = Record.getInt16(m);
       
   107         verifyLength(m, len);
       
   108         byte[] b = new byte[len];
       
   109 
       
   110         m.get(b);
       
   111         return b;
       
   112     }
       
   113 
       
   114     static byte[] getBytes24(ByteBuffer m) throws IOException {
       
   115         int len = Record.getInt24(m);
       
   116         verifyLength(m, len);
       
   117         byte[] b = new byte[len];
       
   118 
       
   119         m.get(b);
       
   120         return b;
       
   121     }
       
   122 
       
   123     /*
       
   124      * Write 8, 16, 24, and 32 bit integer data types, encoded
       
   125      * in standard big-endian form.
       
   126      */
       
   127     static void putInt8(ByteBuffer m, int i) throws IOException {
       
   128         verifyLength(m, 1);
       
   129         m.put((byte)(i & 0xFF));
       
   130     }
       
   131 
       
   132     static void putInt16(ByteBuffer m, int i) throws IOException {
       
   133         verifyLength(m, 2);
       
   134         m.put((byte)((i >> 8) & 0xFF));
       
   135         m.put((byte)(i & 0xFF));
       
   136     }
       
   137 
       
   138     static void putInt24(ByteBuffer m, int i) throws IOException {
       
   139         verifyLength(m, 3);
       
   140         m.put((byte)((i >> 16) & 0xFF));
       
   141         m.put((byte)((i >> 8) & 0xFF));
       
   142         m.put((byte)(i & 0xFF));
       
   143     }
       
   144 
       
   145     static void putInt32(ByteBuffer m, int i) throws IOException {
       
   146         m.put((byte)((i >> 24) & 0xFF));
       
   147         m.put((byte)((i >> 16) & 0xFF));
       
   148         m.put((byte)((i >> 8) & 0xFF));
       
   149         m.put((byte)(i & 0xFF));
       
   150     }
       
   151 
       
   152     /*
       
   153      * Write byte vectors with 8, 16, and 24 bit length encodings.
       
   154      */
       
   155     static void putBytes8(ByteBuffer m, byte[] s) throws IOException {
       
   156         if (s == null || s.length == 0) {
       
   157             verifyLength(m, 1);
       
   158             putInt8(m, 0);
       
   159         } else {
       
   160             verifyLength(m, 1 + s.length);
       
   161             putInt8(m, s.length);
       
   162             m.put(s);
    86         }
   163         }
    87     }
   164     }
    88 
   165 
    89     static boolean isValidContentType(byte contentType) {
   166     static void putBytes16(ByteBuffer m, byte[] s) throws IOException {
    90         return (contentType == 20) || (contentType == 21) ||
   167         if (s == null || s.length == 0) {
    91                (contentType == 22) || (contentType == 23);
   168             verifyLength(m, 2);
       
   169             putInt16(m, 0);
       
   170         } else {
       
   171             verifyLength(m, 2 + s.length);
       
   172             putInt16(m, s.length);
       
   173             m.put(s);
       
   174         }
       
   175     }
       
   176 
       
   177     static void putBytes24(ByteBuffer m, byte[] s) throws IOException {
       
   178         if (s == null || s.length == 0) {
       
   179             verifyLength(m, 3);
       
   180             putInt24(m, 0);
       
   181         } else {
       
   182             verifyLength(m, 3 + s.length);
       
   183             putInt24(m, s.length);
       
   184             m.put(s);
       
   185         }
       
   186     }
       
   187 
       
   188     // Verify that the buffer has sufficient remaining.
       
   189     static void verifyLength(
       
   190             ByteBuffer m, int len) throws SSLException {
       
   191         if (len > m.remaining()) {
       
   192             throw new SSLException("Insufficient space in the buffer, " +
       
   193                     "may be cause by an unexpected end of handshake data.");
       
   194         }
    92     }
   195     }
    93 }
   196 }