blob: 2097bb0933be1968e833c1c78fd533ca39cbe041 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.harmony.xnet.provider.jsse;
/**
* This class encapsulates the functionality of Alert Protocol.
* Constant values are taken according to the TLS v1 specification
* (http://www.ietf.org/rfc/rfc2246.txt), p 7.2.
*/
public class AlertProtocol {
// ------------------------ AlertLevel codes --------------------------
/**
* Defines the severity of alert as warning
*/
protected static final byte WARNING = 1;
/**
* Defines the severity of alert as fatal
*/
protected static final byte FATAL = 2;
// --------------------- AlertDescription codes -----------------------
/**
* Defines the description code of the close_notify alert
*/
protected static final byte CLOSE_NOTIFY = 0;
/**
* Defines the description code of the unexpected_message alert
*/
protected static final byte UNEXPECTED_MESSAGE = 10;
/**
* Defines the description code of the bad_record_mac alert
*/
protected static final byte BAD_RECORD_MAC = 20;
/**
* Defines the description code of the decryption_failed alert
*/
protected static final byte DECRYPTION_FAILED = 21;
/**
* Defines the description code of the record_overflow alert
*/
protected static final byte RECORD_OVERFLOW = 22;
/**
* Defines the description code of the decompression_failure alert
*/
protected static final byte DECOMPRESSION_FAILURE = 30;
/**
* Defines the description code of the handshake_failure alert
*/
protected static final byte HANDSHAKE_FAILURE = 40;
/**
* Defines the description code of the bad_certificate alert
*/
protected static final byte BAD_CERTIFICATE = 42;
/**
* Defines the description code of the unsupported_certificate alert
*/
protected static final byte UNSUPPORTED_CERTIFICATE = 43;
/**
* Defines the description code of the certificate_revoked alert
*/
protected static final byte CERTIFICATE_REVOKED = 44;
/**
* Defines the description code of the certificate_expired alert
*/
protected static final byte CERTIFICATE_EXPIRED = 45;
/**
* Defines the description code of the certificate_unknown alert
*/
protected static final byte CERTIFICATE_UNKNOWN = 46;
/**
* Defines the description code of the illegal_parameter alert
*/
protected static final byte ILLEGAL_PARAMETER = 47;
/**
* Defines the description code of the unknown_ca alert
*/
protected static final byte UNKNOWN_CA = 48;
/**
* Defines the description code of the access_denied alert
*/
protected static final byte ACCESS_DENIED = 49;
/**
* Defines the description code of the decode_error alert
*/
protected static final byte DECODE_ERROR = 50;
/**
* Defines the description code of the decrypt_error alert
*/
protected static final byte DECRYPT_ERROR = 51;
/**
* Defines the description code of the export_restriction alert
*/
protected static final byte EXPORT_RESTRICTION = 60;
/**
* Defines the description code of the protocol_version alert
*/
protected static final byte PROTOCOL_VERSION = 70;
/**
* Defines the description code of the insufficient_security alert
*/
protected static final byte INSUFFICIENT_SECURITY = 71;
/**
* Defines the description code of the internal_error alert
*/
protected static final byte INTERNAL_ERROR = 80;
/**
* Defines the description code of the user_canceled alert
*/
protected static final byte USER_CANCELED = 90;
/**
* Defines the description code of the no_renegotiation alert
*/
protected static final byte NO_RENEGOTIATION = 100;
// holds level and description codes
private final byte[] alert = new byte[2];
// record protocol to be used to wrap the alerts
private SSLRecordProtocol recordProtocol;
private Logger.Stream logger = Logger.getStream("alert");
/**
* Creates the instance of AlertProtocol.
* Note that class is not ready to work without providing of
* record protocol
* @see #setRecordProtocol
*/
protected AlertProtocol() {}
/**
* Sets up the record protocol to be used by this allert protocol.
*/
protected void setRecordProtocol(SSLRecordProtocol recordProtocol) {
this.recordProtocol = recordProtocol;
}
/**
* Reports an alert to be sent/received by transport.
* This method is usually called during processing
* of the income TSL record: if it contains alert message from another
* peer, or if warning alert occured during the processing of the
* message and this warning should be sent to another peer.
* @param level: alert level code
* @param description: alert description code
* @return
*/
protected void alert(byte level, byte description) {
if (logger != null) {
logger.println("Alert.alert: "+level+" "+description);
}
this.alert[0] = level;
this.alert[1] = description;
}
/**
* Returns the description code of alert or -100 if there
* is no alert.
*/
protected byte getDescriptionCode() {
return (alert[0] != 0) ? alert[1] : -100;
}
/**
* Resets the protocol to be in "no alert" state.
* This method shoud be called after processing of the reported alert.
*/
protected void setProcessed() {
// free the info about alert
if (logger != null) {
logger.println("Alert.setProcessed");
}
this.alert[0] = 0;
}
/**
* Checks if any alert has occured.
*/
protected boolean hasAlert() {
return (alert[0] != 0);
}
/**
* Checks if occured alert is fatal alert.
*/
protected boolean isFatalAlert() {
return (alert[0] == 2);
}
/**
* Returns the string representation of occured alert.
* If no alert has occured null is returned.
*/
protected String getAlertDescription() {
switch (alert[1]) {
case CLOSE_NOTIFY:
return "close_notify";
case UNEXPECTED_MESSAGE:
return "unexpected_message";
case BAD_RECORD_MAC:
return "bad_record_mac";
case DECRYPTION_FAILED:
return "decryption_failed";
case RECORD_OVERFLOW:
return "record_overflow";
case DECOMPRESSION_FAILURE:
return "decompression_failure";
case HANDSHAKE_FAILURE:
return "handshake_failure";
case BAD_CERTIFICATE:
return "bad_certificate";
case UNSUPPORTED_CERTIFICATE:
return "unsupported_certificate";
case CERTIFICATE_REVOKED:
return "certificate_revoked";
case CERTIFICATE_EXPIRED:
return "certificate_expired";
case CERTIFICATE_UNKNOWN:
return "certificate_unknown";
case ILLEGAL_PARAMETER:
return "illegal_parameter";
case UNKNOWN_CA:
return "unknown_ca";
case ACCESS_DENIED:
return "access_denied";
case DECODE_ERROR:
return "decode_error";
case DECRYPT_ERROR:
return "decrypt_error";
case EXPORT_RESTRICTION:
return "export_restriction";
case PROTOCOL_VERSION:
return "protocol_version";
case INSUFFICIENT_SECURITY:
return "insufficient_security";
case INTERNAL_ERROR:
return "internal_error";
case USER_CANCELED:
return "user_canceled";
case NO_RENEGOTIATION:
return "no_renegotiation";
}
return null;
}
/**
* Returns the record with reported alert message.
* The returned array of bytes is ready to be sent to another peer.
* Note, that this method does not automatically set the state of alert
* protocol in "no alert" state, so after wrapping the method setProcessed
* should be called.
*/
protected byte[] wrap() {
byte[] res = recordProtocol.wrap(ContentType.ALERT, alert, 0, 2);
return res;
}
/**
* Shutdown the protocol. It will be impossible to use the instance
* after the calling of this method.
*/
protected void shutdown() {
alert[0] = 0;
alert[1] = 0;
recordProtocol = null;
}
}