Home | History | Annotate | Download | only in jsse
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package org.apache.harmony.xnet.provider.jsse;
     19 
     20 /**
     21  * This class encapsulates the functionality of Alert Protocol.
     22  * Constant values are taken according to the TLS v1 specification
     23  * (http://www.ietf.org/rfc/rfc2246.txt), p 7.2.
     24  */
     25 public class AlertProtocol {
     26 
     27     // ------------------------ AlertLevel codes --------------------------
     28     /**
     29      * Defines the severity of alert as warning
     30      */
     31     protected static final byte WARNING = 1;
     32     /**
     33      * Defines the severity of alert as fatal
     34      */
     35     protected static final byte FATAL = 2;
     36 
     37     // --------------------- AlertDescription codes -----------------------
     38     /**
     39      * Defines the description code of the close_notify alert
     40      */
     41     protected static final byte CLOSE_NOTIFY = 0;
     42     /**
     43      * Defines the description code of the unexpected_message alert
     44      */
     45     protected static final byte UNEXPECTED_MESSAGE = 10;
     46     /**
     47      * Defines the description code of the bad_record_mac alert
     48      */
     49     protected static final byte BAD_RECORD_MAC = 20;
     50     /**
     51      * Defines the description code of the decryption_failed alert
     52      */
     53     protected static final byte DECRYPTION_FAILED = 21;
     54     /**
     55      * Defines the description code of the record_overflow alert
     56      */
     57     protected static final byte RECORD_OVERFLOW = 22;
     58     /**
     59      * Defines the description code of the decompression_failure alert
     60      */
     61     protected static final byte DECOMPRESSION_FAILURE = 30;
     62     /**
     63      * Defines the description code of the handshake_failure alert
     64      */
     65     protected static final byte HANDSHAKE_FAILURE = 40;
     66     /**
     67      * Defines the description code of the bad_certificate alert
     68      */
     69     protected static final byte BAD_CERTIFICATE = 42;
     70     /**
     71      * Defines the description code of the unsupported_certificate alert
     72      */
     73     protected static final byte UNSUPPORTED_CERTIFICATE = 43;
     74     /**
     75      * Defines the description code of the certificate_revoked alert
     76      */
     77     protected static final byte CERTIFICATE_REVOKED = 44;
     78     /**
     79      * Defines the description code of the certificate_expired alert
     80      */
     81     protected static final byte CERTIFICATE_EXPIRED = 45;
     82     /**
     83      * Defines the description code of the certificate_unknown alert
     84      */
     85     protected static final byte CERTIFICATE_UNKNOWN = 46;
     86     /**
     87      * Defines the description code of the illegal_parameter alert
     88      */
     89     protected static final byte ILLEGAL_PARAMETER = 47;
     90     /**
     91      * Defines the description code of the unknown_ca alert
     92      */
     93     protected static final byte UNKNOWN_CA = 48;
     94     /**
     95      * Defines the description code of the access_denied alert
     96      */
     97     protected static final byte ACCESS_DENIED = 49;
     98     /**
     99      * Defines the description code of the decode_error alert
    100      */
    101     protected static final byte DECODE_ERROR = 50;
    102     /**
    103      * Defines the description code of the decrypt_error alert
    104      */
    105     protected static final byte DECRYPT_ERROR = 51;
    106     /**
    107      * Defines the description code of the export_restriction alert
    108      */
    109     protected static final byte EXPORT_RESTRICTION = 60;
    110     /**
    111      * Defines the description code of the protocol_version alert
    112      */
    113     protected static final byte PROTOCOL_VERSION = 70;
    114     /**
    115      * Defines the description code of the insufficient_security alert
    116      */
    117     protected static final byte INSUFFICIENT_SECURITY = 71;
    118     /**
    119      * Defines the description code of the internal_error alert
    120      */
    121     protected static final byte INTERNAL_ERROR = 80;
    122     /**
    123      * Defines the description code of the user_canceled alert
    124      */
    125     protected static final byte USER_CANCELED = 90;
    126     /**
    127      * Defines the description code of the no_renegotiation alert
    128      */
    129     protected static final byte NO_RENEGOTIATION = 100;
    130     // holds level and description codes
    131     private final byte[] alert = new byte[2];
    132     // record protocol to be used to wrap the alerts
    133     private SSLRecordProtocol recordProtocol;
    134 
    135     private Logger.Stream logger = Logger.getStream("alert");
    136 
    137     /**
    138      * Creates the instance of AlertProtocol.
    139      * Note that class is not ready to work without providing of
    140      * record protocol
    141      * @see #setRecordProtocol
    142      */
    143     protected AlertProtocol() {}
    144 
    145     /**
    146      * Sets up the record protocol to be used by this allert protocol.
    147      */
    148     protected void setRecordProtocol(SSLRecordProtocol recordProtocol) {
    149         this.recordProtocol = recordProtocol;
    150     }
    151 
    152     /**
    153      * Reports an alert to be sent/received by transport.
    154      * This method is usually called during processing
    155      * of the income TSL record: if it contains alert message from another
    156      * peer, or if warning alert occured during the processing of the
    157      * message and this warning should be sent to another peer.
    158      * @param   level:  alert level code
    159      * @param   description: alert description code
    160      * @return
    161      */
    162     protected void alert(byte level, byte description) {
    163         if (logger != null) {
    164             logger.println("Alert.alert: "+level+" "+description);
    165         }
    166         this.alert[0] = level;
    167         this.alert[1] = description;
    168     }
    169 
    170     /**
    171      * Returns the description code of alert or -100 if there
    172      * is no alert.
    173      */
    174     protected byte getDescriptionCode() {
    175         return (alert[0] != 0) ? alert[1] : -100;
    176     }
    177 
    178     /**
    179      * Resets the protocol to be in "no alert" state.
    180      * This method shoud be called after processing of the reported alert.
    181      */
    182     protected void setProcessed() {
    183         // free the info about alert
    184         if (logger != null) {
    185             logger.println("Alert.setProcessed");
    186         }
    187         this.alert[0] = 0;
    188     }
    189 
    190     /**
    191      * Checks if any alert has occured.
    192      */
    193     protected boolean hasAlert() {
    194         return (alert[0] != 0);
    195     }
    196 
    197     /**
    198      * Checks if occured alert is fatal alert.
    199      */
    200     protected boolean isFatalAlert() {
    201         return (alert[0] == 2);
    202     }
    203 
    204     /**
    205      * Returns the string representation of occured alert.
    206      * If no alert has occured null is returned.
    207      */
    208     protected String getAlertDescription() {
    209         switch (alert[1]) {
    210         case CLOSE_NOTIFY:
    211             return "close_notify";
    212         case UNEXPECTED_MESSAGE:
    213             return "unexpected_message";
    214         case BAD_RECORD_MAC:
    215             return "bad_record_mac";
    216         case DECRYPTION_FAILED:
    217             return "decryption_failed";
    218         case RECORD_OVERFLOW:
    219             return "record_overflow";
    220         case DECOMPRESSION_FAILURE:
    221             return "decompression_failure";
    222         case HANDSHAKE_FAILURE:
    223             return "handshake_failure";
    224         case BAD_CERTIFICATE:
    225             return "bad_certificate";
    226         case UNSUPPORTED_CERTIFICATE:
    227             return "unsupported_certificate";
    228         case CERTIFICATE_REVOKED:
    229             return "certificate_revoked";
    230         case CERTIFICATE_EXPIRED:
    231             return "certificate_expired";
    232         case CERTIFICATE_UNKNOWN:
    233             return "certificate_unknown";
    234         case ILLEGAL_PARAMETER:
    235             return "illegal_parameter";
    236         case UNKNOWN_CA:
    237             return "unknown_ca";
    238         case ACCESS_DENIED:
    239             return "access_denied";
    240         case DECODE_ERROR:
    241             return "decode_error";
    242         case DECRYPT_ERROR:
    243             return "decrypt_error";
    244         case EXPORT_RESTRICTION:
    245             return "export_restriction";
    246         case PROTOCOL_VERSION:
    247             return "protocol_version";
    248         case INSUFFICIENT_SECURITY:
    249             return "insufficient_security";
    250         case INTERNAL_ERROR:
    251             return "internal_error";
    252         case USER_CANCELED:
    253             return "user_canceled";
    254         case NO_RENEGOTIATION:
    255             return "no_renegotiation";
    256         }
    257         return null;
    258     }
    259 
    260     /**
    261      * Returns the record with reported alert message.
    262      * The returned array of bytes is ready to be sent to another peer.
    263      * Note, that this method does not automatically set the state of alert
    264      * protocol in "no alert" state, so after wrapping the method setProcessed
    265      * should be called.
    266      */
    267     protected byte[] wrap() {
    268         byte[] res = recordProtocol.wrap(ContentType.ALERT, alert, 0, 2);
    269         return res;
    270     }
    271 
    272     /**
    273      * Shutdown the protocol. It will be impossible to use the instance
    274      * after the calling of this method.
    275      */
    276     protected void shutdown() {
    277         alert[0] = 0;
    278         alert[1] = 0;
    279         recordProtocol = null;
    280     }
    281 }
    282 
    283