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.conscrypt; 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 */ 161 protected void alert(byte level, byte description) { 162 if (logger != null) { 163 logger.println("Alert.alert: "+level+" "+description); 164 } 165 this.alert[0] = level; 166 this.alert[1] = description; 167 } 168 169 /** 170 * Returns the description code of alert or -100 if there 171 * is no alert. 172 */ 173 protected byte getDescriptionCode() { 174 return (alert[0] != 0) ? alert[1] : -100; 175 } 176 177 /** 178 * Resets the protocol to be in "no alert" state. 179 * This method shoud be called after processing of the reported alert. 180 */ 181 protected void setProcessed() { 182 // free the info about alert 183 if (logger != null) { 184 logger.println("Alert.setProcessed"); 185 } 186 this.alert[0] = 0; 187 } 188 189 /** 190 * Checks if any alert has occured. 191 */ 192 protected boolean hasAlert() { 193 return (alert[0] != 0); 194 } 195 196 /** 197 * Checks if occured alert is fatal alert. 198 */ 199 protected boolean isFatalAlert() { 200 return (alert[0] == 2); 201 } 202 203 /** 204 * Returns the string representation of occured alert. 205 * If no alert has occured null is returned. 206 */ 207 protected String getAlertDescription() { 208 switch (alert[1]) { 209 case CLOSE_NOTIFY: 210 return "close_notify"; 211 case UNEXPECTED_MESSAGE: 212 return "unexpected_message"; 213 case BAD_RECORD_MAC: 214 return "bad_record_mac"; 215 case DECRYPTION_FAILED: 216 return "decryption_failed"; 217 case RECORD_OVERFLOW: 218 return "record_overflow"; 219 case DECOMPRESSION_FAILURE: 220 return "decompression_failure"; 221 case HANDSHAKE_FAILURE: 222 return "handshake_failure"; 223 case BAD_CERTIFICATE: 224 return "bad_certificate"; 225 case UNSUPPORTED_CERTIFICATE: 226 return "unsupported_certificate"; 227 case CERTIFICATE_REVOKED: 228 return "certificate_revoked"; 229 case CERTIFICATE_EXPIRED: 230 return "certificate_expired"; 231 case CERTIFICATE_UNKNOWN: 232 return "certificate_unknown"; 233 case ILLEGAL_PARAMETER: 234 return "illegal_parameter"; 235 case UNKNOWN_CA: 236 return "unknown_ca"; 237 case ACCESS_DENIED: 238 return "access_denied"; 239 case DECODE_ERROR: 240 return "decode_error"; 241 case DECRYPT_ERROR: 242 return "decrypt_error"; 243 case EXPORT_RESTRICTION: 244 return "export_restriction"; 245 case PROTOCOL_VERSION: 246 return "protocol_version"; 247 case INSUFFICIENT_SECURITY: 248 return "insufficient_security"; 249 case INTERNAL_ERROR: 250 return "internal_error"; 251 case USER_CANCELED: 252 return "user_canceled"; 253 case NO_RENEGOTIATION: 254 return "no_renegotiation"; 255 } 256 return null; 257 } 258 259 /** 260 * Returns the record with reported alert message. 261 * The returned array of bytes is ready to be sent to another peer. 262 * Note, that this method does not automatically set the state of alert 263 * protocol in "no alert" state, so after wrapping the method setProcessed 264 * should be called. 265 */ 266 protected byte[] wrap() { 267 byte[] res = recordProtocol.wrap(ContentType.ALERT, alert, 0, 2); 268 return res; 269 } 270 271 /** 272 * Shutdown the protocol. It will be impossible to use the instance 273 * after the calling of this method. 274 */ 275 protected void shutdown() { 276 alert[0] = 0; 277 alert[1] = 0; 278 recordProtocol = null; 279 } 280 } 281 282