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 javax.net.ssl; 19 20 import java.nio.ByteBuffer; 21 22 /** 23 * The abstract implementation of secure communications using SSL, TLS, or other 24 * protocols. It includes the setup, handshake, and encrypt/decrypt 25 * functionality needed to create a secure connection. 26 * 27 * @since 1.5 28 */ 29 public abstract class SSLEngine { 30 private final String peerHost; 31 private final int peerPort; 32 33 /** 34 * Creates a new {@code SSLEngine} instance. 35 */ 36 protected SSLEngine() { 37 super(); 38 peerHost = null; 39 peerPort = -1; 40 } 41 42 /** 43 * Creates a new {@code SSLEngine} instance with the specified host and 44 * port. 45 * 46 * @param host 47 * the name of the host. 48 * @param port 49 * the port of the host. 50 */ 51 protected SSLEngine(String host, int port) { 52 super(); 53 this.peerHost = host; 54 this.peerPort = port; 55 } 56 57 /** 58 * Returns the name of the peer host. 59 * 60 * @return the name of the peer host, or {@code null} if none is available. 61 */ 62 public String getPeerHost() { 63 return peerHost; 64 } 65 66 /** 67 * Returns the port number of the peer host. 68 * 69 * @return the port number of the peer host, or {@code -1} is none is 70 * available. 71 */ 72 public int getPeerPort() { 73 return peerPort; 74 } 75 76 /** 77 * Initiates a handshake on this engine. 78 * <p> 79 * Calling this method is not needed for the initial handshake: it will be 80 * called by {@code wrap} or {@code unwrap} if the initial handshake has not 81 * been started yet. 82 * 83 * @throws SSLException 84 * if starting the handshake fails. 85 * @throws IllegalStateException 86 * if the engine does not have all the needed settings (e.g. 87 * client/server mode not set). 88 */ 89 public abstract void beginHandshake() throws SSLException; 90 91 /** 92 * Notifies this engine instance that no more inbound network data will be 93 * sent to this engine. 94 * 95 * @throws SSLException 96 * if this engine did not receive a needed protocol specific 97 * close notification message from the peer. 98 */ 99 public abstract void closeInbound() throws SSLException; 100 101 /** 102 * Notifies this engine instance that no more outbound application data will 103 * be sent to this engine. 104 */ 105 public abstract void closeOutbound(); 106 107 /** 108 * Returns a delegate task for this engine instance. Some engine operations 109 * may require the results of blocking or long running operations, and the 110 * {@code SSLEngineResult} instances returned by this engine may indicate 111 * that a delegated task result is needed. In this case the 112 * {@link Runnable#run() run} method of the returned {@code Runnable} 113 * delegated task must be called. 114 * 115 * @return a delegate task, or {@code null} if none are available. 116 */ 117 public abstract Runnable getDelegatedTask(); 118 119 /** 120 * Returns the SSL cipher suite names that are enabled in this engine 121 * instance. 122 * 123 * @return the SSL cipher suite names that are enabled in this engine 124 * instance. 125 */ 126 public abstract String[] getEnabledCipherSuites(); 127 128 /** 129 * Returns the protocol version names that are enabled in this engine 130 * instance. 131 * 132 * @return the protocol version names that are enabled in this engine 133 * instance. 134 */ 135 public abstract String[] getEnabledProtocols(); 136 137 /** 138 * Returns whether new SSL sessions may be established by this engine. 139 * 140 * @return {@code true} if new session may be established, {@code false} if 141 * existing sessions must be reused. 142 */ 143 public abstract boolean getEnableSessionCreation(); 144 145 /** 146 * Returns the status of the handshake of this engine instance. 147 * 148 * @return the status of the handshake of this engine instance. 149 */ 150 public abstract SSLEngineResult.HandshakeStatus getHandshakeStatus(); 151 152 /** 153 * Returns whether this engine instance will require client authentication. 154 * 155 * @return {@code true} if this engine will require client authentication, 156 * {@code false} if no client authentication is needed. 157 */ 158 public abstract boolean getNeedClientAuth(); 159 160 /** 161 * Returns the SSL session for this engine instance. 162 * 163 * @return the SSL session for this engine instance. 164 */ 165 public abstract SSLSession getSession(); 166 167 /** 168 * Returns the SSL cipher suite names that are supported by this engine. 169 * These cipher suites can be enabled using 170 * {@link #setEnabledCipherSuites(String[])}. 171 * 172 * @return the SSL cipher suite names that are supported by this engine. 173 */ 174 public abstract String[] getSupportedCipherSuites(); 175 176 /** 177 * Returns the protocol names that are supported by this engine. These 178 * protocols can be enables using {@link #setEnabledProtocols(String[])}. 179 * 180 * @return the protocol names that are supported by this engine. 181 */ 182 public abstract String[] getSupportedProtocols(); 183 184 /** 185 * Returns whether this engine is set to act in client mode when 186 * handshaking. 187 * 188 * @return {@code true} if the engine is set to do handshaking in client 189 * mode. 190 */ 191 public abstract boolean getUseClientMode(); 192 193 /** 194 * Returns whether this engine will request client authentication. 195 * 196 * @return {@code true} if client authentication will be requested, 197 * {@code false} otherwise. 198 */ 199 public abstract boolean getWantClientAuth(); 200 201 /** 202 * Returns whether no more inbound data will be accepted by this engine. 203 * 204 * @return {@code true} if no more inbound data will be accepted by this 205 * engine, {@code false} otherwise. 206 */ 207 public abstract boolean isInboundDone(); 208 209 /** 210 * Returns whether no more outbound data will be produced by this engine. 211 * 212 * @return {@code true} if no more outbound data will be producted by this 213 * engine, {@code otherwise} false. 214 */ 215 public abstract boolean isOutboundDone(); 216 217 /** 218 * Sets the SSL cipher suite names that should be enabled in this engine 219 * instance. Only cipher suites listed by {@code getSupportedCipherSuites()} 220 * are allowed. 221 * 222 * @param suites 223 * the SSL cipher suite names to be enabled. 224 * @throws IllegalArgumentException 225 * if one of the specified cipher suites is not supported, or if 226 * {@code suites} is {@code null}. 227 */ 228 public abstract void setEnabledCipherSuites(String[] suites); 229 230 /** 231 * Sets the protocol version names that should be enabled in this engine 232 * instance. Only protocols listed by {@code getSupportedProtocols()} are 233 * allowed. 234 * 235 * @param protocols 236 * the protocol version names to be enabled. 237 * @throws IllegalArgumentException 238 * if one of the protocol version names is not supported, or if 239 * {@code protocols} is {@code null}. 240 */ 241 public abstract void setEnabledProtocols(String[] protocols); 242 243 /** 244 * Sets whether new SSL sessions may be established by this engine instance. 245 * 246 * @param flag 247 * {@code true} if new SSL sessions may be established, 248 * {@code false} if existing SSL sessions must be reused. 249 */ 250 public abstract void setEnableSessionCreation(boolean flag); 251 252 /** 253 * Sets whether this engine must require client authentication. The client 254 * authentication is one of: 255 * <ul> 256 * <li>authentication required</li> 257 * <li>authentication requested</li> 258 * <li>no authentication needed</li> 259 * </ul> 260 * This method overrides the setting of {@link #setWantClientAuth(boolean)}. 261 * 262 * @param need 263 * {@code true} if client authentication is required, 264 * {@code false} if no authentication is needed. 265 */ 266 public abstract void setNeedClientAuth(boolean need); 267 268 /** 269 * Sets whether this engine should act in client (or server) mode when 270 * handshaking. 271 * 272 * @param mode 273 * {@code true} if this engine should act in client mode, 274 * {@code false} if not. 275 * @throws IllegalArgumentException 276 * if this method is called after starting the initial 277 * handshake. 278 */ 279 public abstract void setUseClientMode(boolean mode); 280 281 /** 282 * Sets whether this engine should request client authentication. The client 283 * authentication is one of the following: 284 * <ul> 285 * <li>authentication required</li> 286 * <li>authentication requested</li> 287 * <li>no authentication needed</li> 288 * </ul> 289 * This method overrides the setting of {@link #setNeedClientAuth(boolean)}. 290 * 291 * @param want 292 * {@code true} if client authentication should be requested, 293 * {@code false} if no authentication is needed. 294 */ 295 public abstract void setWantClientAuth(boolean want); 296 297 /** 298 * Decodes the incoming network data buffer into application data buffers. 299 * If a handshake has not been started yet, it will automatically be 300 * started. 301 * 302 * @param src 303 * the buffer with incoming network data 304 * @param dsts 305 * the array of destination buffers for incoming application 306 * data. 307 * @param offset 308 * the offset in the array of destination buffers to which data 309 * is to be transferred. 310 * @param length 311 * the maximum number of destination buffers to be used. 312 * @return the result object of this operation. 313 * @throws SSLException 314 * if a problem occurred while processing the data. 315 * @throws IndexOutOfBoundsException 316 * if {@code length} is greater than 317 * {@code dsts.length - offset}. 318 * @throws java.nio.ReadOnlyBufferException 319 * if one of the destination buffers is read-only. 320 * @throws IllegalArgumentException 321 * if {@code src}, {@code dsts}, or one of the entries in 322 * {@code dsts} is {@code null}. 323 * @throws IllegalStateException 324 * if the engine does not have all the needed settings (e.g. 325 * client/server mode not set). 326 */ 327 public abstract SSLEngineResult unwrap(ByteBuffer src, 328 ByteBuffer[] dsts, 329 int offset, 330 int length) throws SSLException; 331 332 /** 333 * Encodes the outgoing application data buffers into the network data 334 * buffer. If a handshake has not been started yet, it will automatically be 335 * started. 336 * 337 * @param srcs 338 * the array of source buffers of outgoing application data. 339 * @param offset 340 * the offset in the array of source buffers from which data is 341 * to be retrieved. 342 * @param length 343 * the maximum number of source buffers to be used. 344 * @param dst 345 * the destination buffer for network data. 346 * @return the result object of this operation. 347 * @throws SSLException 348 * if a problem occurred while processing the data. 349 * @throws IndexOutOfBoundsException 350 * if {@code length} is greater than 351 * {@code srcs.length - offset}. 352 * @throws java.nio.ReadOnlyBufferException 353 * if the destination buffer is readonly. 354 * @throws IllegalArgumentException 355 * if {@code srcs}, {@code dst}, or one the entries in 356 * {@code srcs} is {@code null}. 357 * @throws IllegalStateException 358 * if the engine does not have all the needed settings (e.g. 359 * client/server mode not set). 360 */ 361 public abstract SSLEngineResult wrap(ByteBuffer[] srcs, int offset, int length, ByteBuffer dst) 362 throws SSLException; 363 364 /** 365 * Decodes the incoming network data buffer into the application data 366 * buffer. If a handshake has not been started yet, it will automatically be 367 * started. 368 * 369 * @param src 370 * the buffer with incoming network data 371 * @param dst 372 * the destination buffer for incoming application data. 373 * @return the result object of this operation. 374 * @throws SSLException 375 * if a problem occurred while processing the data. 376 * @throws java.nio.ReadOnlyBufferException 377 * if one of the destination buffers is read-only. 378 * @throws IllegalArgumentException 379 * if {@code src} or {@code dst} is {@code null}. 380 * @throws IllegalStateException 381 * if the engine does not have all the needed settings (e.g. 382 * client/server mode not set). 383 */ 384 public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer dst) throws SSLException { 385 return unwrap(src, new ByteBuffer[] { dst }, 0, 1); 386 } 387 388 /** 389 * Decodes the incoming network data buffer into the application data 390 * buffers. If a handshake has not been started yet, it will automatically 391 * be started. 392 * 393 * @param src 394 * the buffer with incoming network data 395 * @param dsts 396 * the array of destination buffers for incoming application 397 * data. 398 * @return the result object of this operation. 399 * @throws SSLException 400 * if a problem occurred while processing the data. 401 * @throws java.nio.ReadOnlyBufferException 402 * if one of the destination buffers is read-only. 403 * @throws IllegalArgumentException 404 * if {@code src} or {@code dsts} is {@code null}. 405 * @throws IllegalStateException 406 * if the engine does not have all the needed settings (e.g. 407 * client/server mode not set). 408 */ 409 public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts) throws SSLException { 410 if (dsts == null) { 411 throw new IllegalArgumentException("Byte buffer array dsts is null"); 412 } 413 return unwrap(src, dsts, 0, dsts.length); 414 } 415 416 /** 417 * Encodes the outgoing application data buffers into the network data 418 * buffer. If a handshake has not been started yet, it will automatically be 419 * started. 420 * 421 * @param srcs 422 * the array of source buffers of outgoing application data. 423 * @param dst 424 * the destination buffer for network data. 425 * @return the result object of this operation. 426 * @throws SSLException 427 * if a problem occurred while processing the data. 428 * @throws java.nio.ReadOnlyBufferException 429 * if the destination buffer is readonly. 430 * @throws IllegalArgumentException 431 * if {@code srcs} or {@code dst} is {@code null}. 432 * @throws IllegalStateException 433 * if the engine does not have all the needed settings (e.g. 434 * client/server mode not set). 435 */ 436 public SSLEngineResult wrap(ByteBuffer[] srcs, ByteBuffer dst) throws SSLException { 437 if (srcs == null) { 438 throw new IllegalArgumentException("Byte buffer array srcs is null"); 439 } 440 return wrap(srcs, 0, srcs.length, dst); 441 } 442 443 /** 444 * Encodes the outgoing application data buffer into the network data 445 * buffer. If a handshake has not been started yet, it will automatically be 446 * started. 447 * 448 * @param src 449 * the source buffers of outgoing application data. 450 * @param dst 451 * the destination buffer for network data. 452 * @return the result object of this operation. 453 * @throws SSLException 454 * if a problem occurred while processing the data. 455 * @throws java.nio.ReadOnlyBufferException 456 * if the destination buffer is readonly. 457 * @throws IllegalArgumentException 458 * if {@code src} or {@code dst} is {@code null}. 459 * @throws IllegalStateException 460 * if the engine does not have all the needed settings (e.g. 461 * client/server mode not set). 462 */ 463 public SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException { 464 return wrap(new ByteBuffer[] { src }, 0, 1, dst); 465 } 466 467 /** 468 * Returns a new SSLParameters based on this SSLSocket's current 469 * cipher suites, protocols, and client authentication settings. 470 * 471 * @since 1.6 472 */ 473 public SSLParameters getSSLParameters() { 474 SSLParameters p = new SSLParameters(); 475 p.setCipherSuites(getEnabledCipherSuites()); 476 p.setProtocols(getEnabledProtocols()); 477 p.setNeedClientAuth(getNeedClientAuth()); 478 p.setWantClientAuth(getWantClientAuth()); 479 return p; 480 } 481 482 /** 483 * Sets various SSL handshake parameters based on the SSLParameter 484 * argument. Specifically, sets the SSLEngine's enabled cipher 485 * suites if the parameter's cipher suites are non-null. Similarly 486 * sets the enabled protocols. If the parameters specify the want 487 * or need for client authentication, those requirements are set 488 * on the SSLEngine, otherwise both are set to false. 489 * @since 1.6 490 */ 491 public void setSSLParameters(SSLParameters p) { 492 String[] cipherSuites = p.getCipherSuites(); 493 if (cipherSuites != null) { 494 setEnabledCipherSuites(cipherSuites); 495 } 496 String[] protocols = p.getProtocols(); 497 if (protocols != null) { 498 setEnabledProtocols(protocols); 499 } 500 if (p.getNeedClientAuth()) { 501 setNeedClientAuth(true); 502 } else if (p.getWantClientAuth()) { 503 setWantClientAuth(true); 504 } else { 505 setWantClientAuth(false); 506 } 507 } 508 } 509