1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.ssl;
  27 
  28 import javax.net.ssl.SSLEngineResult.HandshakeStatus;
  29 import static sun.security.ssl.HandshakeMessage.*;
  30 
  31 /*
  32  * enumation of record type
  33  */
  34 final class Ciphertext {
  35     final static Ciphertext CIPHERTEXT_NULL = new Ciphertext();
  36 
  37     RecordType recordType;
  38     long recordSN;
  39     
  40     HandshakeStatus handshakeStatus;    // null if not used or not handshaking
  41 
  42     Ciphertext() {
  43         this.recordType = null;
  44         this.recordSN = -1L;
  45         this.handshakeStatus = null;
  46     }
  47 
  48     Ciphertext(RecordType recordType, long recordSN) {
  49         this.recordType = recordType;
  50         this.recordSN = recordSN;
  51         this.handshakeStatus = null;
  52     }
  53 
  54     static enum RecordType {
  55         RECORD_CHANGE_CIPHER_SPEC (
  56                 Record.ct_change_cipher_spec, ht_not_applicable),
  57         RECORD_ALERT (
  58                 Record.ct_alert, ht_not_applicable),
  59         RECORD_HELLO_REQUEST (
  60                 Record.ct_handshake, ht_hello_request),
  61         RECORD_CLIENT_HELLO (
  62                 Record.ct_handshake, ht_client_hello),
  63         RECORD_SERVER_HELLO (
  64                 Record.ct_handshake, ht_server_hello),
  65         RECORD_HELLO_VERIFY_REQUEST (
  66                 Record.ct_handshake, ht_hello_verify_request),
  67         RECORD_NEW_SESSION_TICKET (
  68                 Record.ct_handshake, ht_new_session_ticket),
  69         RECORD_CERTIFICATE (
  70                 Record.ct_handshake, ht_certificate),
  71         RECORD_SERVER_KEY_EXCHANGE (
  72                 Record.ct_handshake, ht_server_key_exchange),
  73         RECORD_CERTIFICATE_REQUEST (
  74                 Record.ct_handshake, ht_certificate_request),
  75         RECORD_SERVER_HELLO_DONE (
  76                 Record.ct_handshake, ht_server_hello_done),
  77         RECORD_CERTIFICATE_VERIFY (
  78                 Record.ct_handshake, ht_certificate_verify),
  79         RECORD_CLIENT_KEY_EXCHANGE (
  80                 Record.ct_handshake, ht_client_key_exchange),
  81         RECORD_FINISHED (
  82                 Record.ct_handshake, ht_finished),
  83         RECORD_CERTIFICATE_URL (
  84                 Record.ct_handshake, ht_certificate_url),
  85         RECORD_CERTIFICATE_STATUS (
  86                 Record.ct_handshake, ht_certificate_status),
  87         RECORD_SUPPLIEMENTAL_DATA (
  88                 Record.ct_handshake, ht_supplemental_data),
  89         RECORD_APPLICATION_DATA (
  90                 Record.ct_application_data, ht_not_applicable);
  91 
  92         byte contentType;
  93         byte handshakeType;
  94 
  95         private RecordType(byte contentType, byte handshakeType) {
  96             this.contentType = contentType;
  97             this.handshakeType = handshakeType;
  98         }
  99 
 100         static RecordType valueOf(byte contentType, byte handshakeType) {
 101             if (contentType == Record.ct_change_cipher_spec) {
 102                 return RECORD_CHANGE_CIPHER_SPEC;
 103             } else if (contentType == Record.ct_alert) {
 104                 return RECORD_ALERT;
 105             } else if (contentType == Record.ct_application_data) {
 106                 return RECORD_APPLICATION_DATA;
 107             } else if (handshakeType == ht_hello_request) {
 108                 return RECORD_HELLO_REQUEST;
 109             } else if (handshakeType == ht_client_hello) {
 110                 return RECORD_CLIENT_HELLO;
 111             } else if (handshakeType == ht_server_hello) {
 112                 return RECORD_SERVER_HELLO;
 113             } else if (handshakeType == ht_hello_verify_request) {
 114                 return RECORD_HELLO_VERIFY_REQUEST;
 115             } else if (handshakeType == ht_new_session_ticket) {
 116                 return RECORD_NEW_SESSION_TICKET;
 117             } else if (handshakeType == ht_certificate) {
 118                 return RECORD_CERTIFICATE;
 119             } else if (handshakeType == ht_server_key_exchange) {
 120                 return RECORD_SERVER_KEY_EXCHANGE;
 121             } else if (handshakeType == ht_certificate_request) {
 122                 return RECORD_CERTIFICATE_REQUEST;
 123             } else if (handshakeType == ht_server_hello_done) {
 124                 return RECORD_SERVER_HELLO_DONE;
 125             } else if (handshakeType == ht_certificate_verify) {
 126                 return RECORD_CERTIFICATE_VERIFY;
 127             } else if (handshakeType == ht_client_key_exchange) {
 128                 return RECORD_CLIENT_KEY_EXCHANGE;
 129             } else if (handshakeType == ht_finished) {
 130                 return RECORD_FINISHED;
 131             } else if (handshakeType == ht_certificate_url) {
 132                 return RECORD_CERTIFICATE_URL;
 133             } else if (handshakeType == ht_certificate_status) {
 134                 return RECORD_CERTIFICATE_STATUS;
 135             } else if (handshakeType == ht_supplemental_data) {
 136                 return RECORD_SUPPLIEMENTAL_DATA;
 137             }
 138     
 139             // otherwise, invalid record type
 140             throw new IllegalArgumentException(
 141                     "Invalid record type (ContentType:" + contentType +
 142                     ", HandshakeType:" + handshakeType + ")");
 143         }
 144     }
 145 }