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