001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Alexander Y. Kleymenov
020: * @version $Revision$
021: */package org.apache.harmony.xnet.provider.jsse;
022:
023: import org.apache.harmony.xnet.provider.jsse.SSLRecordProtocol;
024: import org.apache.harmony.xnet.provider.jsse.Logger;
025: import org.apache.harmony.xnet.provider.jsse.ContentType;
026:
027: /**
028: * This class encapsulates the functionality of Alert Protocol.
029: * Constant values are taken according to the TLS v1 specification
030: * (http://www.ietf.org/rfc/rfc2246.txt), p 7.2.
031: */
032: public class AlertProtocol {
033:
034: // ------------------------ AlertLevel codes --------------------------
035: /**
036: * Defines the severity of alert as warning
037: */
038: protected static final byte WARNING = 1;
039: /**
040: * Defines the severity of alert as fatal
041: */
042: protected static final byte FATAL = 2;
043:
044: // --------------------- AlertDescription codes -----------------------
045: /**
046: * Defines the description code of the close_notify alert
047: */
048: protected static final byte CLOSE_NOTIFY = 0;
049: /**
050: * Defines the description code of the unexpected_message alert
051: */
052: protected static final byte UNEXPECTED_MESSAGE = 10;
053: /**
054: * Defines the description code of the bad_record_mac alert
055: */
056: protected static final byte BAD_RECORD_MAC = 20;
057: /**
058: * Defines the description code of the decryption_failed alert
059: */
060: protected static final byte DECRYPTION_FAILED = 21;
061: /**
062: * Defines the description code of the record_overflow alert
063: */
064: protected static final byte RECORD_OVERFLOW = 22;
065: /**
066: * Defines the description code of the decompression_failure alert
067: */
068: protected static final byte DECOMPRESSION_FAILURE = 30;
069: /**
070: * Defines the description code of the handshake_failure alert
071: */
072: protected static final byte HANDSHAKE_FAILURE = 40;
073: /**
074: * Defines the description code of the bad_certificate alert
075: */
076: protected static final byte BAD_CERTIFICATE = 42;
077: /**
078: * Defines the description code of the unsupported_certificate alert
079: */
080: protected static final byte UNSUPPORTED_CERTIFICATE = 43;
081: /**
082: * Defines the description code of the certificate_revoked alert
083: */
084: protected static final byte CERTIFICATE_REVOKED = 44;
085: /**
086: * Defines the description code of the certificate_expired alert
087: */
088: protected static final byte CERTIFICATE_EXPIRED = 45;
089: /**
090: * Defines the description code of the certificate_unknown alert
091: */
092: protected static final byte CERTIFICATE_UNKNOWN = 46;
093: /**
094: * Defines the description code of the illegal_parameter alert
095: */
096: protected static final byte ILLEGAL_PARAMETER = 47;
097: /**
098: * Defines the description code of the unknown_ca alert
099: */
100: protected static final byte UNKNOWN_CA = 48;
101: /**
102: * Defines the description code of the access_denied alert
103: */
104: protected static final byte ACCESS_DENIED = 49;
105: /**
106: * Defines the description code of the decode_error alert
107: */
108: protected static final byte DECODE_ERROR = 50;
109: /**
110: * Defines the description code of the decrypt_error alert
111: */
112: protected static final byte DECRYPT_ERROR = 51;
113: /**
114: * Defines the description code of the export_restriction alert
115: */
116: protected static final byte EXPORT_RESTRICTION = 60;
117: /**
118: * Defines the description code of the protocol_version alert
119: */
120: protected static final byte PROTOCOL_VERSION = 70;
121: /**
122: * Defines the description code of the insufficient_security alert
123: */
124: protected static final byte INSUFFICIENT_SECURITY = 71;
125: /**
126: * Defines the description code of the internal_error alert
127: */
128: protected static final byte INTERNAL_ERROR = 80;
129: /**
130: * Defines the description code of the user_canceled alert
131: */
132: protected static final byte USER_CANCELED = 90;
133: /**
134: * Defines the description code of the no_renegotiation alert
135: */
136: protected static final byte NO_RENEGOTIATION = 100;
137:
138: // holds level and description codes
139: private final byte[] alert = new byte[2];
140: // record protocol to be used to wrap the alerts
141: private SSLRecordProtocol recordProtocol;
142:
143: private Logger.Stream logger = Logger.getStream("alert");
144:
145: /**
146: * Creates the instance of AlertProtocol.
147: * Note that class is not ready to work without providing of
148: * record protocol
149: * @see setRecordProtocol
150: */
151: protected AlertProtocol() {
152: }
153:
154: /**
155: * Sets up the record protocol to be used by this allert protocol.
156: */
157: protected void setRecordProtocol(SSLRecordProtocol recordProtocol) {
158: this .recordProtocol = recordProtocol;
159: }
160:
161: /**
162: * Reports an alert to be sent/received by transport.
163: * This method is usually called during processing
164: * of the income TSL record: if it contains alert message from another
165: * peer, or if warning alert occured during the processing of the
166: * message and this warning should be sent to another peer.
167: * @param level: alert level code
168: * @param description: alert description code
169: * @return
170: */
171: protected void alert(byte level, byte description) {
172: if (logger != null) {
173: logger.println("Alert.alert: " + level + " " + description);
174: }
175: this .alert[0] = level;
176: this .alert[1] = description;
177: }
178:
179: /**
180: * Returns the description code of alert or -100 if there
181: * is no alert.
182: */
183: protected byte getDescriptionCode() {
184: return (alert[0] != 0) ? alert[1] : -100;
185: }
186:
187: /**
188: * Resets the protocol to be in "no alert" state.
189: * This method shoud be called after processing of the reported alert.
190: */
191: protected void setProcessed() {
192: // free the info about alert
193: if (logger != null) {
194: logger.println("Alert.setProcessed");
195: }
196: this .alert[0] = 0;
197: }
198:
199: /**
200: * Checks if any alert has occured.
201: */
202: protected boolean hasAlert() {
203: return (alert[0] != 0);
204: }
205:
206: /**
207: * Checks if occured alert is fatal alert.
208: */
209: protected boolean isFatalAlert() {
210: return (alert[0] == 2);
211: }
212:
213: /**
214: * Returns the string representation of occured alert.
215: * If no alert has occured null is returned.
216: */
217: protected String getAlertDescription() {
218: switch (alert[1]) {
219: case CLOSE_NOTIFY:
220: return "close_notify";
221: case UNEXPECTED_MESSAGE:
222: return "unexpected_message";
223: case BAD_RECORD_MAC:
224: return "bad_record_mac";
225: case DECRYPTION_FAILED:
226: return "decryption_failed";
227: case RECORD_OVERFLOW:
228: return "record_overflow";
229: case DECOMPRESSION_FAILURE:
230: return "decompression_failure";
231: case HANDSHAKE_FAILURE:
232: return "handshake_failure";
233: case BAD_CERTIFICATE:
234: return "bad_certificate";
235: case UNSUPPORTED_CERTIFICATE:
236: return "unsupported_certificate";
237: case CERTIFICATE_REVOKED:
238: return "certificate_revoked";
239: case CERTIFICATE_EXPIRED:
240: return "certificate_expired";
241: case CERTIFICATE_UNKNOWN:
242: return "certificate_unknown";
243: case ILLEGAL_PARAMETER:
244: return "illegal_parameter";
245: case UNKNOWN_CA:
246: return "unknown_ca";
247: case ACCESS_DENIED:
248: return "access_denied";
249: case DECODE_ERROR:
250: return "decode_error";
251: case DECRYPT_ERROR:
252: return "decrypt_error";
253: case EXPORT_RESTRICTION:
254: return "export_restriction";
255: case PROTOCOL_VERSION:
256: return "protocol_version";
257: case INSUFFICIENT_SECURITY:
258: return "insufficient_security";
259: case INTERNAL_ERROR:
260: return "internal_error";
261: case USER_CANCELED:
262: return "user_canceled";
263: case NO_RENEGOTIATION:
264: return "no_renegotiation";
265: }
266: return null;
267: }
268:
269: /**
270: * Returns the record with reported alert message.
271: * The returned array of bytes is ready to be sent to another peer.
272: * Note, that this method does not automatically set the state of allert
273: * protocol in "no alert" state, so after wrapping the method setProcessed
274: * should be called.
275: */
276: protected byte[] wrap() {
277: byte[] res = recordProtocol
278: .wrap(ContentType.ALERT, alert, 0, 2);
279: return res;
280: }
281:
282: /**
283: * Shutdownes the protocol. It will be impossiblke to use the instance
284: * after the calling of this method.
285: */
286: protected void shutdown() {
287: alert[0] = 0;
288: alert[1] = 0;
289: recordProtocol = null;
290: }
291: }
|