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
26package sun.security.ssl;
27
28import javax.net.ssl.SSLEngineResult.HandshakeStatus;
29import static sun.security.ssl.HandshakeMessage.*;
30
31/*
32 * enumeration of record type
33 */
34final class Ciphertext {
35    static final 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}
146