1 module hunt.net.ssl.SSLEngine; 2 3 // dfmt off 4 version(WITH_HUNT_SECURITY): 5 // dfmt on 6 7 import hunt.net.ssl.SSLEngineResult; 8 import hunt.net.ssl.SSLSession; 9 10 import hunt.io.ByteBuffer; 11 12 import hunt.Exceptions; 13 14 /** 15 * A class which enables secure communications using protocols such as 16 * the Secure Sockets Layer (SSL) or 17 * <A HREF="http://www.ietf.org/rfc/rfc2246.txt"> IETF RFC 2246 "Transport 18 * Layer Security" (TLS) </A> protocols, but is transport independent. 19 * <P> 20 * The secure communications modes include: <UL> 21 * 22 * <LI> <em>Integrity Protection</em>. SSL/TLS protects against 23 * modification of messages by an active wiretapper. 24 * 25 * <LI> <em>Authentication</em>. In most modes, SSL/TLS provides 26 * peer authentication. Servers are usually authenticated, and 27 * clients may be authenticated as requested by servers. 28 * 29 * <LI> <em>Confidentiality (Privacy Protection)</em>. In most 30 * modes, SSL/TLS encrypts data being sent between client and 31 * server. This protects the confidentiality of data, so that 32 * passive wiretappers won't see sensitive data such as financial 33 * information or personal information of many kinds. 34 * 35 * </UL> 36 * 37 * These kinds of protection are specified by a "cipher suite", which 38 * is a combination of cryptographic algorithms used by a given SSL 39 * connection. During the negotiation process, the two endpoints must 40 * agree on a cipher suite that is available in both environments. If 41 * there is no such suite in common, no SSL connection can be 42 * established, and no data can be exchanged. 43 * <P> 44 * The cipher suite used is established by a negotiation process called 45 * "handshaking". The goal of this process is to create or rejoin a 46 * "session", which may protect many connections over time. After 47 * handshaking has completed, you can access session attributes by 48 * using the {@link #getSession()} method. 49 * <P> 50 * The <code>SSLSocket</code> class provides much of the same security 51 * functionality, but all of the inbound and outbound data is 52 * automatically transported using the underlying {@link 53 * java.net.Socket Socket}, which by design uses a blocking model. 54 * While this is appropriate for many applications, this model does not 55 * provide the scalability required by large servers. 56 * <P> 57 * The primary distinction of an <code>SSLEngine</code> is that it 58 * operates on inbound and outbound byte streams, independent of the 59 * transport mechanism. It is the responsibility of the 60 * <code>SSLEngine</code> user to arrange for reliable I/O transport to 61 * the peer. By separating the SSL/TLS abstraction from the I/O 62 * transport mechanism, the <code>SSLEngine</code> can be used for a 63 * wide variety of I/O types, such as {@link 64 * java.nio.channels.spi.AbstractSelectableChannel#configureBlocking(bool) 65 * non-blocking I/O (polling)}, {@link java.nio.channels.Selector 66 * selectable non-blocking I/O}, {@link java.net.Socket Socket} and the 67 * traditional Input/OutputStreams, local {@link java.nio.ByteBuffer 68 * ByteBuffers} or byte arrays, <A 69 * HREF="http://www.jcp.org/en/jsr/detail?id=203"> future asynchronous 70 * I/O models </A>, and so on. 71 * <P> 72 * At a high level, the <code>SSLEngine</code> appears thus: 73 * 74 * <pre> 75 * app data 76 * 77 * | ^ 78 * | | | 79 * v | | 80 * +----+-----|-----+----+ 81 * | | | 82 * | SSL|Engine | 83 * wrap() | | | unwrap() 84 * | OUTBOUND | INBOUND | 85 * | | | 86 * +----+-----|-----+----+ 87 * | | ^ 88 * | | | 89 * v | 90 * 91 * net data 92 * </pre> 93 * Application data (also known as plaintext or cleartext) is data which 94 * is produced or consumed by an application. Its counterpart is 95 * network data, which consists of either handshaking and/or ciphertext 96 * (encrypted) data, and destined to be transported via an I/O 97 * mechanism. Inbound data is data which has been received from the 98 * peer, and outbound data is destined for the peer. 99 * <P> 100 * (In the context of an <code>SSLEngine</code>, the term "handshake 101 * data" is taken to mean any data exchanged to establish and control a 102 * secure connection. Handshake data includes the SSL/TLS messages 103 * "alert", "change_cipher_spec," and "handshake.") 104 * <P> 105 * There are five distinct phases to an <code>SSLEngine</code>. 106 * 107 * <OL> 108 * <li> Creation - The <code>SSLEngine</code> has been created and 109 * initialized, but has not yet been used. During this phase, an 110 * application may set any <code>SSLEngine</code>-specific settings 111 * (enabled cipher suites, whether the <code>SSLEngine</code> should 112 * handshake in client or server mode, and so on). Once 113 * handshaking has begun, though, any new settings (except 114 * client/server mode, see below) will be used for 115 * the next handshake. 116 * 117 * <li> Initial Handshake - The initial handshake is a procedure by 118 * which the two peers exchange communication parameters until an 119 * SSLSession is established. Application data can not be sent during 120 * this phase. 121 * 122 * <li> Application Data - Once the communication parameters have 123 * been established and the handshake is complete, application data 124 * may flow through the <code>SSLEngine</code>. Outbound 125 * application messages are encrypted and integrity protected, 126 * and inbound messages reverse the process. 127 * 128 * <li> Rehandshaking - Either side may request a renegotiation of 129 * the session at any time during the Application Data phase. New 130 * handshaking data can be intermixed among the application data. 131 * Before starting the rehandshake phase, the application may 132 * reset the SSL/TLS communication parameters such as the list of 133 * enabled ciphersuites and whether to use client authentication, 134 * but can not change between client/server modes. As before, once 135 * handshaking has begun, any new <code>SSLEngine</code> 136 * configuration settings will not be used until the next 137 * handshake. 138 * 139 * <li> Closure - When the connection is no longer needed, the 140 * application should close the <code>SSLEngine</code> and should 141 * send/receive any remaining messages to the peer before 142 * closing the underlying transport mechanism. Once an engine is 143 * closed, it is not reusable: a new <code>SSLEngine</code> must 144 * be created. 145 * </OL> 146 * An <code>SSLEngine</code> is created by calling {@link 147 * SSLContext#createSSLEngine()} from an initialized 148 * <code>SSLContext</code>. Any configuration 149 * parameters should be set before making the first call to 150 * <code>wrap()</code>, <code>unwrap()</code>, or 151 * <code>beginHandshake()</code>. These methods all trigger the 152 * initial handshake. 153 * <P> 154 * Data moves through the engine by calling {@link #wrap(ByteBuffer, 155 * ByteBuffer) wrap()} or {@link #unwrap(ByteBuffer, ByteBuffer) 156 * unwrap()} on outbound or inbound data, respectively. Depending on 157 * the state of the <code>SSLEngine</code>, a <code>wrap()</code> call 158 * may consume application data from the source buffer and may produce 159 * network data in the destination buffer. The outbound data 160 * may contain application and/or handshake data. A call to 161 * <code>unwrap()</code> will examine the source buffer and may 162 * advance the handshake if the data is handshaking information, or 163 * may place application data in the destination buffer if the data 164 * is application. The state of the underlying SSL/TLS algorithm 165 * will determine when data is consumed and produced. 166 * <P> 167 * Calls to <code>wrap()</code> and <code>unwrap()</code> return an 168 * <code>SSLEngineResult</code> which indicates the status of the 169 * operation, and (optionally) how to interact with the engine to make 170 * progress. 171 * <P> 172 * The <code>SSLEngine</code> produces/consumes complete SSL/TLS 173 * packets only, and does not store application data internally between 174 * calls to <code>wrap()/unwrap()</code>. Thus input and output 175 * <code>ByteBuffer</code>s must be sized appropriately to hold the 176 * maximum record that can be produced. Calls to {@link 177 * SSLSession#getPacketBufferSize()} and {@link 178 * SSLSession#getApplicationBufferSize()} should be used to determine 179 * the appropriate buffer sizes. The size of the outbound application 180 * data buffer generally does not matter. If buffer conditions do not 181 * allow for the proper consumption/production of data, the application 182 * must determine (via {@link SSLEngineResult}) and correct the 183 * problem, and then try the call again. 184 * <P> 185 * For example, <code>unwrap()</code> will return a {@link 186 * SSLEngineResult.Status#BUFFER_OVERFLOW} result if the engine 187 * determines that there is not enough destination buffer space available. 188 * Applications should call {@link SSLSession#getApplicationBufferSize()} 189 * and compare that value with the space available in the destination buffer, 190 * enlarging the buffer if necessary. Similarly, if <code>unwrap()</code> 191 * were to return a {@link SSLEngineResult.Status#BUFFER_UNDERFLOW}, the 192 * application should call {@link SSLSession#getPacketBufferSize()} to ensure 193 * that the source buffer has enough room to hold a record (enlarging if 194 * necessary), and then obtain more inbound data. 195 * 196 * <pre>{@code 197 * SSLEngineResult r = engine.unwrap(src, dst); 198 * switch (r.getStatus()) { 199 * BUFFER_OVERFLOW: 200 * // Could attempt to drain the dst buffer of any already obtained 201 * // data, but we'll just increase it to the size needed. 202 * int appSize = engine.getSession().getApplicationBufferSize(); 203 * ByteBuffer b = ByteBuffer.allocate(appSize + dst.position()); 204 * dst.flip(); 205 * b.put(dst); 206 * dst = b; 207 * // retry the operation. 208 * break; 209 * BUFFER_UNDERFLOW: 210 * int netSize = engine.getSession().getPacketBufferSize(); 211 * // Resize buffer if needed. 212 * if (netSize > dst.capacity()) { 213 * ByteBuffer b = ByteBuffer.allocate(netSize); 214 * src.flip(); 215 * b.put(src); 216 * src = b; 217 * } 218 * // Obtain more inbound network data for src, 219 * // then retry the operation. 220 * break; 221 * // other cases: CLOSED, OK. 222 * } 223 * }</pre> 224 * 225 * <P> 226 * Unlike <code>SSLSocket</code>, all methods of SSLEngine are 227 * non-blocking. <code>SSLEngine</code> implementations may 228 * require the results of tasks that may take an extended period of 229 * time to complete, or may even block. For example, a TrustManager 230 * may need to connect to a remote certificate validation service, 231 * or a KeyManager might need to prompt a user to determine which 232 * certificate to use as part of client authentication. Additionally, 233 * creating cryptographic signatures and verifying them can be slow, 234 * seemingly blocking. 235 * <P> 236 * For any operation which may potentially block, the 237 * <code>SSLEngine</code> will create a {@link java.lang.Runnable} 238 * delegated task. When <code>SSLEngineResult</code> indicates that a 239 * delegated task result is needed, the application must call {@link 240 * #getDelegatedTask()} to obtain an outstanding delegated task and 241 * call its {@link java.lang.Runnable#run() run()} method (possibly using 242 * a different thread depending on the compute strategy). The 243 * application should continue obtaining delegated tasks until no more 244 * exist, and try the original operation again. 245 * <P> 246 * At the end of a communication session, applications should properly 247 * close the SSL/TLS link. The SSL/TLS protocols have closure handshake 248 * messages, and these messages should be communicated to the peer 249 * before releasing the <code>SSLEngine</code> and closing the 250 * underlying transport mechanism. A close can be initiated by one of: 251 * an SSLException, an inbound closure handshake message, or one of the 252 * close methods. In all cases, closure handshake messages are 253 * generated by the engine, and <code>wrap()</code> should be repeatedly 254 * called until the resulting <code>SSLEngineResult</code>'s status 255 * returns "CLOSED", or {@link #isOutboundDone()} returns true. All 256 * data obtained from the <code>wrap()</code> method should be sent to the 257 * peer. 258 * <P> 259 * {@link #closeOutbound()} is used to signal the engine that the 260 * application will not be sending any more data. 261 * <P> 262 * A peer will signal its intent to close by sending its own closure 263 * handshake message. After this message has been received and 264 * processed by the local <code>SSLEngine</code>'s <code>unwrap()</code> 265 * call, the application can detect the close by calling 266 * <code>unwrap()</code> and looking for a <code>SSLEngineResult</code> 267 * with status "CLOSED", or if {@link #isInboundDone()} returns true. 268 * If for some reason the peer closes the communication link without 269 * sending the proper SSL/TLS closure message, the application can 270 * detect the end-of-stream and can signal the engine via {@link 271 * #closeInbound()} that there will no more inbound messages to 272 * process. Some applications might choose to require orderly shutdown 273 * messages from a peer, in which case they can check that the closure 274 * was generated by a handshake message and not by an end-of-stream 275 * condition. 276 * <P> 277 * There are two groups of cipher suites which you will need to know 278 * about when managing cipher suites: 279 * 280 * <UL> 281 * <LI> <em>Supported</em> cipher suites: all the suites which are 282 * supported by the SSL implementation. This list is reported 283 * using {@link #getSupportedCipherSuites()}. 284 * 285 * <LI> <em>Enabled</em> cipher suites, which may be fewer than 286 * the full set of supported suites. This group is set using the 287 * {@link #setEnabledCipherSuites(string [])} method, and 288 * queried using the {@link #getEnabledCipherSuites()} method. 289 * Initially, a default set of cipher suites will be enabled on a 290 * new engine that represents the minimum suggested 291 * configuration. 292 * </UL> 293 * 294 * Implementation defaults require that only cipher suites which 295 * authenticate servers and provide confidentiality be enabled by 296 * default. Only if both sides explicitly agree to unauthenticated 297 * and/or non-private (unencrypted) communications will such a 298 * cipher suite be selected. 299 * <P> 300 * Each SSL/TLS connection must have one client and one server, thus 301 * each endpoint must decide which role to assume. This choice determines 302 * who begins the handshaking process as well as which type of messages 303 * should be sent by each party. The method {@link 304 * #setUseClientMode(bool)} configures the mode. Once the initial 305 * handshaking has started, an <code>SSLEngine</code> can not switch 306 * between client and server modes, even when performing renegotiations. 307 * <P> 308 * Applications might choose to process delegated tasks in different 309 * threads. When an <code>SSLEngine</code> 310 * is created, the current {@link java.security.AccessControlContext} 311 * is saved. All future delegated tasks will be processed using this 312 * context: that is, all access control decisions will be made using the 313 * context captured at engine creation. 314 * 315 * <HR> 316 * 317 * <B>Concurrency Notes</B>: 318 * There are two concurrency issues to be aware of: 319 * 320 * <OL> 321 * <li>The <code>wrap()</code> and <code>unwrap()</code> methods 322 * may execute concurrently of each other. 323 * 324 * <li> The SSL/TLS protocols employ ordered packets. 325 * Applications must take care to ensure that generated packets 326 * are delivered in sequence. If packets arrive 327 * out-of-order, unexpected or fatal results may occur. 328 * <P> 329 * For example: 330 * 331 * <pre> 332 * synchronized (outboundLock) { 333 * sslEngine.wrap(src, dst); 334 * outboundQueue.put(dst); 335 * } 336 * </pre> 337 * 338 * As a corollary, two threads must not attempt to call the same method 339 * (either <code>wrap()</code> or <code>unwrap()</code>) concurrently, 340 * because there is no way to guarantee the eventual packet ordering. 341 * </OL> 342 * 343 * @see SSLContext 344 * @see SSLSocket 345 * @see SSLServerSocket 346 * @see SSLSession 347 * 348 * @author Brad R. Wetmore 349 */ 350 351 abstract class SSLEngine { 352 353 private string peerHost = null; 354 private int peerPort = -1; 355 356 /** 357 * Constructor for an <code>SSLEngine</code> providing no hints 358 * for an internal session reuse strategy. 359 * 360 * @see SSLContext#createSSLEngine() 361 * @see SSLSessionContext 362 */ 363 protected this() { 364 } 365 366 /** 367 * Constructor for an <code>SSLEngine</code>. 368 * <P> 369 * <code>SSLEngine</code> implementations may use the 370 * <code>peerHost</code> and <code>peerPort</code> parameters as hints 371 * for their internal session reuse strategy. 372 * <P> 373 * Some cipher suites (such as Kerberos) require remote hostname 374 * information. Implementations of this class should use this 375 * constructor to use Kerberos. 376 * <P> 377 * The parameters are not authenticated by the 378 * <code>SSLEngine</code>. 379 * 380 * @param peerHost the name of the peer host 381 * @param peerPort the port number of the peer 382 * @see SSLContext#createSSLEngine(string, int) 383 * @see SSLSessionContext 384 */ 385 protected this(string peerHost, int peerPort) { 386 this.peerHost = peerHost; 387 this.peerPort = peerPort; 388 } 389 390 /** 391 * Returns the host name of the peer. 392 * <P> 393 * Note that the value is not authenticated, and should not be 394 * relied upon. 395 * 396 * @return the host name of the peer, or null if nothing is 397 * available. 398 */ 399 string getPeerHost() { 400 return peerHost; 401 } 402 403 /** 404 * Returns the port number of the peer. 405 * <P> 406 * Note that the value is not authenticated, and should not be 407 * relied upon. 408 * 409 * @return the port number of the peer, or -1 if nothing is 410 * available. 411 */ 412 int getPeerPort() { 413 return peerPort; 414 } 415 416 /** 417 * Attempts to encode a buffer of plaintext application data into 418 * SSL/TLS network data. 419 * <P> 420 * An invocation of this method behaves in exactly the same manner 421 * as the invocation: 422 * <blockquote><pre> 423 * {@link #wrap(ByteBuffer [], int, int, ByteBuffer) 424 * engine.wrap(new ByteBuffer [] { src }, 0, 1, dst);} 425 * </pre></blockquote> 426 * 427 * @param src 428 * a <code>ByteBuffer</code> containing outbound application data 429 * @param dst 430 * a <code>ByteBuffer</code> to hold outbound network data 431 * @return an <code>SSLEngineResult</code> describing the result 432 * of this operation. 433 * @throws SSLException 434 * A problem was encountered while processing the 435 * data that caused the <code>SSLEngine</code> to abort. 436 * See the class description for more information on 437 * engine closure. 438 * @throws ReadOnlyBufferException 439 * if the <code>dst</code> buffer is read-only. 440 * @throws IllegalArgumentException 441 * if either <code>src</code> or <code>dst</code> 442 * is null. 443 * @throws IllegalStateException if the client/server mode 444 * has not yet been set. 445 * @see #wrap(ByteBuffer [], int, int, ByteBuffer) 446 */ 447 SSLEngineResult wrap(ByteBuffer src, 448 ByteBuffer dst) { 449 return wrap([src], 0, 1, dst); 450 } 451 452 /** 453 * Attempts to encode plaintext bytes from a sequence of data 454 * buffers into SSL/TLS network data. 455 * <P> 456 * An invocation of this method behaves in exactly the same manner 457 * as the invocation: 458 * <blockquote><pre> 459 * {@link #wrap(ByteBuffer [], int, int, ByteBuffer) 460 * engine.wrap(srcs, 0, srcs.length, dst);} 461 * </pre></blockquote> 462 * 463 * @param srcs 464 * an array of <code>ByteBuffers</code> containing the 465 * outbound application data 466 * @param dst 467 * a <code>ByteBuffer</code> to hold outbound network data 468 * @return an <code>SSLEngineResult</code> describing the result 469 * of this operation. 470 * @throws SSLException 471 * A problem was encountered while processing the 472 * data that caused the <code>SSLEngine</code> to abort. 473 * See the class description for more information on 474 * engine closure. 475 * @throws ReadOnlyBufferException 476 * if the <code>dst</code> buffer is read-only. 477 * @throws IllegalArgumentException 478 * if either <code>srcs</code> or <code>dst</code> 479 * is null, or if any element in <code>srcs</code> is null. 480 * @throws IllegalStateException if the client/server mode 481 * has not yet been set. 482 * @see #wrap(ByteBuffer [], int, int, ByteBuffer) 483 */ 484 SSLEngineResult wrap(ByteBuffer [] srcs, 485 ByteBuffer dst) { 486 if (srcs is null) { 487 throw new IllegalArgumentException("src is null"); 488 } 489 return wrap(srcs, 0, cast(int)srcs.length, dst); 490 } 491 492 493 /** 494 * Attempts to encode plaintext bytes from a subsequence of data 495 * buffers into SSL/TLS network data. This <i>"gathering"</i> 496 * operation encodes, in a single invocation, a sequence of bytes 497 * from one or more of a given sequence of buffers. Gathering 498 * wraps are often useful when implementing network protocols or 499 * file formats that, for example, group data into segments 500 * consisting of one or more fixed-length headers followed by a 501 * variable-length body. See 502 * {@link java.nio.channels.GatheringByteChannel} for more 503 * information on gathering, and {@link 504 * java.nio.channels.GatheringByteChannel#write(ByteBuffer[], 505 * int, int)} for more information on the subsequence 506 * behavior. 507 * <P> 508 * Depending on the state of the SSLEngine, this method may produce 509 * network data without consuming any application data (for example, 510 * it may generate handshake data.) 511 * <P> 512 * The application is responsible for reliably transporting the 513 * network data to the peer, and for ensuring that data created by 514 * multiple calls to wrap() is transported in the same order in which 515 * it was generated. The application must properly synchronize 516 * multiple calls to this method. 517 * <P> 518 * If this <code>SSLEngine</code> has not yet started its initial 519 * handshake, this method will automatically start the handshake. 520 * <P> 521 * This method will attempt to produce SSL/TLS records, and will 522 * consume as much source data as possible, but will never consume 523 * more than the sum of the bytes remaining in each buffer. Each 524 * <code>ByteBuffer</code>'s position is updated to reflect the 525 * amount of data consumed or produced. The limits remain the 526 * same. 527 * <P> 528 * The underlying memory used by the <code>srcs</code> and 529 * <code>dst ByteBuffer</code>s must not be the same. 530 * <P> 531 * See the class description for more information on engine closure. 532 * 533 * @param srcs 534 * an array of <code>ByteBuffers</code> containing the 535 * outbound application data 536 * @param offset 537 * The offset within the buffer array of the first buffer from 538 * which bytes are to be retrieved; it must be non-negative 539 * and no larger than <code>srcs.length</code> 540 * @param length 541 * The maximum number of buffers to be accessed; it must be 542 * non-negative and no larger than 543 * <code>srcs.length</code> - <code>offset</code> 544 * @param dst 545 * a <code>ByteBuffer</code> to hold outbound network data 546 * @return an <code>SSLEngineResult</code> describing the result 547 * of this operation. 548 * @throws SSLException 549 * A problem was encountered while processing the 550 * data that caused the <code>SSLEngine</code> to abort. 551 * See the class description for more information on 552 * engine closure. 553 * @throws IndexOutOfBoundsException 554 * if the preconditions on the <code>offset</code> and 555 * <code>length</code> parameters do not hold. 556 * @throws ReadOnlyBufferException 557 * if the <code>dst</code> buffer is read-only. 558 * @throws IllegalArgumentException 559 * if either <code>srcs</code> or <code>dst</code> 560 * is null, or if any element in the <code>srcs</code> 561 * subsequence specified is null. 562 * @throws IllegalStateException if the client/server mode 563 * has not yet been set. 564 * @see java.nio.channels.GatheringByteChannel 565 * @see java.nio.channels.GatheringByteChannel#write( 566 * ByteBuffer[], int, int) 567 */ 568 abstract SSLEngineResult wrap(ByteBuffer [] srcs, int offset, 569 int length, ByteBuffer dst); 570 571 /** 572 * Attempts to decode SSL/TLS network data into a plaintext 573 * application data buffer. 574 * <P> 575 * An invocation of this method behaves in exactly the same manner 576 * as the invocation: 577 * <blockquote><pre> 578 * {@link #unwrap(ByteBuffer, ByteBuffer [], int, int) 579 * engine.unwrap(src, new ByteBuffer [] { dst }, 0, 1);} 580 * </pre></blockquote> 581 * 582 * @param src 583 * a <code>ByteBuffer</code> containing inbound network data. 584 * @param dst 585 * a <code>ByteBuffer</code> to hold inbound application data. 586 * @return an <code>SSLEngineResult</code> describing the result 587 * of this operation. 588 * @throws SSLException 589 * A problem was encountered while processing the 590 * data that caused the <code>SSLEngine</code> to abort. 591 * See the class description for more information on 592 * engine closure. 593 * @throws ReadOnlyBufferException 594 * if the <code>dst</code> buffer is read-only. 595 * @throws IllegalArgumentException 596 * if either <code>src</code> or <code>dst</code> 597 * is null. 598 * @throws IllegalStateException if the client/server mode 599 * has not yet been set. 600 * @see #unwrap(ByteBuffer, ByteBuffer [], int, int) 601 */ 602 SSLEngineResult unwrap(ByteBuffer src, 603 ByteBuffer dst) { 604 return unwrap(src, [dst], 0, 1); 605 } 606 607 /** 608 * Attempts to decode SSL/TLS network data into a sequence of plaintext 609 * application data buffers. 610 * <P> 611 * An invocation of this method behaves in exactly the same manner 612 * as the invocation: 613 * <blockquote><pre> 614 * {@link #unwrap(ByteBuffer, ByteBuffer [], int, int) 615 * engine.unwrap(src, dsts, 0, dsts.length);} 616 * </pre></blockquote> 617 * 618 * @param src 619 * a <code>ByteBuffer</code> containing inbound network data. 620 * @param dsts 621 * an array of <code>ByteBuffer</code>s to hold inbound 622 * application data. 623 * @return an <code>SSLEngineResult</code> describing the result 624 * of this operation. 625 * @throws SSLException 626 * A problem was encountered while processing the 627 * data that caused the <code>SSLEngine</code> to abort. 628 * See the class description for more information on 629 * engine closure. 630 * @throws ReadOnlyBufferException 631 * if any of the <code>dst</code> buffers are read-only. 632 * @throws IllegalArgumentException 633 * if either <code>src</code> or <code>dsts</code> 634 * is null, or if any element in <code>dsts</code> is null. 635 * @throws IllegalStateException if the client/server mode 636 * has not yet been set. 637 * @see #unwrap(ByteBuffer, ByteBuffer [], int, int) 638 */ 639 SSLEngineResult unwrap(ByteBuffer src, 640 ByteBuffer [] dsts) { 641 if (dsts is null) { 642 throw new IllegalArgumentException("dsts is null"); 643 } 644 return unwrap(src, dsts, 0, cast(int)dsts.length); 645 } 646 647 /** 648 * Attempts to decode SSL/TLS network data into a subsequence of 649 * plaintext application data buffers. This <i>"scattering"</i> 650 * operation decodes, in a single invocation, a sequence of bytes 651 * into one or more of a given sequence of buffers. Scattering 652 * unwraps are often useful when implementing network protocols or 653 * file formats that, for example, group data into segments 654 * consisting of one or more fixed-length headers followed by a 655 * variable-length body. See 656 * {@link java.nio.channels.ScatteringByteChannel} for more 657 * information on scattering, and {@link 658 * java.nio.channels.ScatteringByteChannel#read(ByteBuffer[], 659 * int, int)} for more information on the subsequence 660 * behavior. 661 * <P> 662 * Depending on the state of the SSLEngine, this method may consume 663 * network data without producing any application data (for example, 664 * it may consume handshake data.) 665 * <P> 666 * The application is responsible for reliably obtaining the network 667 * data from the peer, and for invoking unwrap() on the data in the 668 * order it was received. The application must properly synchronize 669 * multiple calls to this method. 670 * <P> 671 * If this <code>SSLEngine</code> has not yet started its initial 672 * handshake, this method will automatically start the handshake. 673 * <P> 674 * This method will attempt to consume one complete SSL/TLS network 675 * packet, but will never consume more than the sum of the bytes 676 * remaining in the buffers. Each <code>ByteBuffer</code>'s 677 * position is updated to reflect the amount of data consumed or 678 * produced. The limits remain the same. 679 * <P> 680 * The underlying memory used by the <code>src</code> and 681 * <code>dsts ByteBuffer</code>s must not be the same. 682 * <P> 683 * The inbound network buffer may be modified as a result of this 684 * call: therefore if the network data packet is required for some 685 * secondary purpose, the data should be duplicated before calling this 686 * method. Note: the network data will not be useful to a second 687 * SSLEngine, as each SSLEngine contains unique random state which 688 * influences the SSL/TLS messages. 689 * <P> 690 * See the class description for more information on engine closure. 691 * 692 * @param src 693 * a <code>ByteBuffer</code> containing inbound network data. 694 * @param dsts 695 * an array of <code>ByteBuffer</code>s to hold inbound 696 * application data. 697 * @param offset 698 * The offset within the buffer array of the first buffer from 699 * which bytes are to be transferred; it must be non-negative 700 * and no larger than <code>dsts.length</code>. 701 * @param length 702 * The maximum number of buffers to be accessed; it must be 703 * non-negative and no larger than 704 * <code>dsts.length</code> - <code>offset</code>. 705 * @return an <code>SSLEngineResult</code> describing the result 706 * of this operation. 707 * @throws SSLException 708 * A problem was encountered while processing the 709 * data that caused the <code>SSLEngine</code> to abort. 710 * See the class description for more information on 711 * engine closure. 712 * @throws IndexOutOfBoundsException 713 * If the preconditions on the <code>offset</code> and 714 * <code>length</code> parameters do not hold. 715 * @throws ReadOnlyBufferException 716 * if any of the <code>dst</code> buffers are read-only. 717 * @throws IllegalArgumentException 718 * if either <code>src</code> or <code>dsts</code> 719 * is null, or if any element in the <code>dsts</code> 720 * subsequence specified is null. 721 * @throws IllegalStateException if the client/server mode 722 * has not yet been set. 723 * @see java.nio.channels.ScatteringByteChannel 724 * @see java.nio.channels.ScatteringByteChannel#read( 725 * ByteBuffer[], int, int) 726 */ 727 abstract SSLEngineResult unwrap(ByteBuffer src, 728 ByteBuffer [] dsts, int offset, int length) ; 729 730 731 /** 732 * Returns a delegated <code>Runnable</code> task for 733 * this <code>SSLEngine</code>. 734 * <P> 735 * <code>SSLEngine</code> operations may require the results of 736 * operations that block, or may take an extended period of time to 737 * complete. This method is used to obtain an outstanding {@link 738 * java.lang.Runnable} operation (task). Each task must be assigned 739 * a thread (possibly the current) to perform the {@link 740 * java.lang.Runnable#run() run} operation. Once the 741 * <code>run</code> method returns, the <code>Runnable</code> object 742 * is no longer needed and may be discarded. 743 * <P> 744 * Delegated tasks run in the <code>AccessControlContext</code> 745 * in place when this object was created. 746 * <P> 747 * A call to this method will return each outstanding task 748 * exactly once. 749 * <P> 750 * Multiple delegated tasks can be run in parallel. 751 * 752 * @return a delegated <code>Runnable</code> task, or null 753 * if none are available. 754 */ 755 // abstract Runnable getDelegatedTask(); 756 757 758 /** 759 * Signals that no more inbound network data will be sent 760 * to this <code>SSLEngine</code>. 761 * <P> 762 * If the application initiated the closing process by calling 763 * {@link #closeOutbound()}, under some circumstances it is not 764 * required that the initiator wait for the peer's corresponding 765 * close message. (See section 7.2.1 of the TLS specification (<A 766 * HREF="http://www.ietf.org/rfc/rfc2246.txt">RFC 2246</A>) for more 767 * information on waiting for closure alerts.) In such cases, this 768 * method need not be called. 769 * <P> 770 * But if the application did not initiate the closure process, or 771 * if the circumstances above do not apply, this method should be 772 * called whenever the end of the SSL/TLS data stream is reached. 773 * This ensures closure of the inbound side, and checks that the 774 * peer followed the SSL/TLS close procedure properly, thus 775 * detecting possible truncation attacks. 776 * <P> 777 * This method is idempotent: if the inbound side has already 778 * been closed, this method does not do anything. 779 * <P> 780 * {@link #wrap(ByteBuffer, ByteBuffer) wrap()} should be 781 * called to flush any remaining handshake data. 782 * 783 * @throws SSLException 784 * if this engine has not received the proper SSL/TLS close 785 * notification message from the peer. 786 * 787 * @see #isInboundDone() 788 * @see #isOutboundDone() 789 */ 790 abstract void closeInbound() ; 791 792 793 /** 794 * Returns whether {@link #unwrap(ByteBuffer, ByteBuffer)} will 795 * accept any more inbound data messages. 796 * 797 * @return true if the <code>SSLEngine</code> will not 798 * consume anymore network data (and by implication, 799 * will not produce any more application data.) 800 * @see #closeInbound() 801 */ 802 abstract bool isInboundDone(); 803 804 805 /** 806 * Signals that no more outbound application data will be sent 807 * on this <code>SSLEngine</code>. 808 * <P> 809 * This method is idempotent: if the outbound side has already 810 * been closed, this method does not do anything. 811 * <P> 812 * {@link #wrap(ByteBuffer, ByteBuffer)} should be 813 * called to flush any remaining handshake data. 814 * 815 * @see #isOutboundDone() 816 */ 817 abstract void closeOutbound(); 818 819 820 /** 821 * Returns whether {@link #wrap(ByteBuffer, ByteBuffer)} will 822 * produce any more outbound data messages. 823 * <P> 824 * Note that during the closure phase, a <code>SSLEngine</code> may 825 * generate handshake closure data that must be sent to the peer. 826 * <code>wrap()</code> must be called to generate this data. When 827 * this method returns true, no more outbound data will be created. 828 * 829 * @return true if the <code>SSLEngine</code> will not produce 830 * any more network data 831 * 832 * @see #closeOutbound() 833 * @see #closeInbound() 834 */ 835 abstract bool isOutboundDone(); 836 837 838 /** 839 * Returns the names of the cipher suites which could be enabled for use 840 * on this engine. Normally, only a subset of these will actually 841 * be enabled by default, since this list may include cipher suites which 842 * do not meet quality of service requirements for those defaults. Such 843 * cipher suites might be useful in specialized applications. 844 * 845 * @return an array of cipher suite names 846 * @see #getEnabledCipherSuites() 847 * @see #setEnabledCipherSuites(string []) 848 */ 849 abstract string [] getSupportedCipherSuites(); 850 851 852 /** 853 * Returns the names of the SSL cipher suites which are currently 854 * enabled for use on this engine. When an SSLEngine is first 855 * created, all enabled cipher suites support a minimum quality of 856 * service. Thus, in some environments this value might be empty. 857 * <P> 858 * Even if a suite has been enabled, it might never be used. (For 859 * example, the peer does not support it, the requisite 860 * certificates/private keys for the suite are not available, or an 861 * anonymous suite is enabled but authentication is required.) 862 * 863 * @return an array of cipher suite names 864 * @see #getSupportedCipherSuites() 865 * @see #setEnabledCipherSuites(string []) 866 */ 867 abstract string [] getEnabledCipherSuites(); 868 869 870 /** 871 * Sets the cipher suites enabled for use on this engine. 872 * <P> 873 * Each cipher suite in the <code>suites</code> parameter must have 874 * been listed by getSupportedCipherSuites(), or the method will 875 * fail. Following a successful call to this method, only suites 876 * listed in the <code>suites</code> parameter are enabled for use. 877 * <P> 878 * See {@link #getEnabledCipherSuites()} for more information 879 * on why a specific cipher suite may never be used on a engine. 880 * 881 * @param suites Names of all the cipher suites to enable 882 * @throws IllegalArgumentException when one or more of the ciphers 883 * named by the parameter is not supported, or when the 884 * parameter is null. 885 * @see #getSupportedCipherSuites() 886 * @see #getEnabledCipherSuites() 887 */ 888 abstract void setEnabledCipherSuites(string[] suites ); 889 890 891 /** 892 * Returns the names of the protocols which could be enabled for use 893 * with this <code>SSLEngine</code>. 894 * 895 * @return an array of protocols supported 896 */ 897 abstract string [] getSupportedProtocols(); 898 899 900 /** 901 * Returns the names of the protocol versions which are currently 902 * enabled for use with this <code>SSLEngine</code>. 903 * 904 * @return an array of protocols 905 * @see #setEnabledProtocols(string []) 906 */ 907 abstract string [] getEnabledProtocols(); 908 909 910 /** 911 * Set the protocol versions enabled for use on this engine. 912 * <P> 913 * The protocols must have been listed by getSupportedProtocols() 914 * as being supported. Following a successful call to this method, 915 * only protocols listed in the <code>protocols</code> parameter 916 * are enabled for use. 917 * 918 * @param protocols Names of all the protocols to enable. 919 * @throws IllegalArgumentException when one or more of 920 * the protocols named by the parameter is not supported or 921 * when the protocols parameter is null. 922 * @see #getEnabledProtocols() 923 */ 924 abstract void setEnabledProtocols(string[] protocols); 925 926 927 /** 928 * Returns the <code>SSLSession</code> in use in this 929 * <code>SSLEngine</code>. 930 * <P> 931 * These can be long lived, and frequently correspond to an entire 932 * login session for some user. The session specifies a particular 933 * cipher suite which is being actively used by all connections in 934 * that session, as well as the identities of the session's client 935 * and server. 936 * <P> 937 * Unlike {@link SSLSocket#getSession()} 938 * this method does not block until handshaking is complete. 939 * <P> 940 * Until the initial handshake has completed, this method returns 941 * a session object which reports an invalid cipher suite of 942 * "SSL_NULL_WITH_NULL_NULL". 943 * 944 * @return the <code>SSLSession</code> for this <code>SSLEngine</code> 945 * @see SSLSession 946 */ 947 abstract SSLSession getSession(); 948 949 950 /** 951 * Returns the {@code SSLSession} being constructed during a SSL/TLS 952 * handshake. 953 * <p> 954 * TLS protocols may negotiate parameters that are needed when using 955 * an instance of this class, but before the {@code SSLSession} has 956 * been completely initialized and made available via {@code getSession}. 957 * For example, the list of valid signature algorithms may restrict 958 * the type of certificates that can used during TrustManager 959 * decisions, or the maximum TLS fragment packet sizes can be 960 * resized to better support the network environment. 961 * <p> 962 * This method provides early access to the {@code SSLSession} being 963 * constructed. Depending on how far the handshake has progressed, 964 * some data may not yet be available for use. For example, if a 965 * remote server will be sending a Certificate chain, but that chain 966 * has yet not been processed, the {@code getPeerCertificates} 967 * method of {@code SSLSession} will throw a 968 * SSLPeerUnverifiedException. Once that chain has been processed, 969 * {@code getPeerCertificates} will return the proper value. 970 * 971 * @see SSLSocket 972 * @see SSLSession 973 * @see ExtendedSSLSession 974 * @see X509ExtendedKeyManager 975 * @see X509ExtendedTrustManager 976 * 977 * @return null if this instance is not currently handshaking, or 978 * if the current handshake has not progressed far enough to 979 * create a basic SSLSession. Otherwise, this method returns the 980 * {@code SSLSession} currently being negotiated. 981 * @throws UnsupportedOperationException if the underlying provider 982 * does not implement the operation. 983 * 984 */ 985 SSLSession getHandshakeSession() { 986 throw new UnsupportedOperationException(""); 987 } 988 989 990 /** 991 * Initiates handshaking (initial or renegotiation) on this SSLEngine. 992 * <P> 993 * This method is not needed for the initial handshake, as the 994 * <code>wrap()</code> and <code>unwrap()</code> methods will 995 * implicitly call this method if handshaking has not already begun. 996 * <P> 997 * Note that the peer may also request a session renegotiation with 998 * this <code>SSLEngine</code> by sending the appropriate 999 * session renegotiate handshake message. 1000 * <P> 1001 * Unlike the {@link SSLSocket#startHandshake() 1002 * SSLSocket#startHandshake()} method, this method does not block 1003 * until handshaking is completed. 1004 * <P> 1005 * To force a complete SSL/TLS session renegotiation, the current 1006 * session should be invalidated prior to calling this method. 1007 * <P> 1008 * Some protocols may not support multiple handshakes on an existing 1009 * engine and may throw an <code>SSLException</code>. 1010 * 1011 * @throws SSLException 1012 * if a problem was encountered while signaling the 1013 * <code>SSLEngine</code> to begin a new handshake. 1014 * See the class description for more information on 1015 * engine closure. 1016 * @throws IllegalStateException if the client/server mode 1017 * has not yet been set. 1018 * @see SSLSession#invalidate() 1019 */ 1020 abstract void beginHandshake() ; 1021 1022 1023 /** 1024 * Returns the current handshake status for this <code>SSLEngine</code>. 1025 * 1026 * @return the current <code>HandshakeStatus</code>. 1027 */ 1028 abstract HandshakeStatus getHandshakeStatus(); 1029 1030 1031 /** 1032 * Configures the engine to use client (or server) mode when 1033 * handshaking. 1034 * <P> 1035 * This method must be called before any handshaking occurs. 1036 * Once handshaking has begun, the mode can not be reset for the 1037 * life of this engine. 1038 * <P> 1039 * Servers normally authenticate themselves, and clients 1040 * are not required to do so. 1041 * 1042 * @param mode true if the engine should start its handshaking 1043 * in "client" mode 1044 * @throws IllegalArgumentException if a mode change is attempted 1045 * after the initial handshake has begun. 1046 * @see #getUseClientMode() 1047 */ 1048 abstract void setUseClientMode(bool mode); 1049 1050 1051 /** 1052 * Returns true if the engine is set to use client mode when 1053 * handshaking. 1054 * 1055 * @return true if the engine should do handshaking 1056 * in "client" mode 1057 * @see #setUseClientMode(bool) 1058 */ 1059 abstract bool getUseClientMode(); 1060 1061 1062 /** 1063 * Configures the engine to <i>require</i> client authentication. This 1064 * option is only useful for engines in the server mode. 1065 * <P> 1066 * An engine's client authentication setting is one of the following: 1067 * <ul> 1068 * <li> client authentication required 1069 * <li> client authentication requested 1070 * <li> no client authentication desired 1071 * </ul> 1072 * <P> 1073 * Unlike {@link #setWantClientAuth(bool)}, if this option is set and 1074 * the client chooses not to provide authentication information 1075 * about itself, <i>the negotiations will stop and the engine will 1076 * begin its closure procedure</i>. 1077 * <P> 1078 * Calling this method overrides any previous setting made by 1079 * this method or {@link #setWantClientAuth(bool)}. 1080 * 1081 * @param need set to true if client authentication is required, 1082 * or false if no client authentication is desired. 1083 * @see #getNeedClientAuth() 1084 * @see #setWantClientAuth(bool) 1085 * @see #getWantClientAuth() 1086 * @see #setUseClientMode(bool) 1087 */ 1088 abstract void setNeedClientAuth(bool need); 1089 1090 1091 /** 1092 * Returns true if the engine will <i>require</i> client authentication. 1093 * This option is only useful to engines in the server mode. 1094 * 1095 * @return true if client authentication is required, 1096 * or false if no client authentication is desired. 1097 * @see #setNeedClientAuth(bool) 1098 * @see #setWantClientAuth(bool) 1099 * @see #getWantClientAuth() 1100 * @see #setUseClientMode(bool) 1101 */ 1102 abstract bool getNeedClientAuth(); 1103 1104 1105 /** 1106 * Configures the engine to <i>request</i> client authentication. 1107 * This option is only useful for engines in the server mode. 1108 * <P> 1109 * An engine's client authentication setting is one of the following: 1110 * <ul> 1111 * <li> client authentication required 1112 * <li> client authentication requested 1113 * <li> no client authentication desired 1114 * </ul> 1115 * <P> 1116 * Unlike {@link #setNeedClientAuth(bool)}, if this option is set and 1117 * the client chooses not to provide authentication information 1118 * about itself, <i>the negotiations will continue</i>. 1119 * <P> 1120 * Calling this method overrides any previous setting made by 1121 * this method or {@link #setNeedClientAuth(bool)}. 1122 * 1123 * @param want set to true if client authentication is requested, 1124 * or false if no client authentication is desired. 1125 * @see #getWantClientAuth() 1126 * @see #setNeedClientAuth(bool) 1127 * @see #getNeedClientAuth() 1128 * @see #setUseClientMode(bool) 1129 */ 1130 abstract void setWantClientAuth(bool want); 1131 1132 1133 /** 1134 * Returns true if the engine will <i>request</i> client authentication. 1135 * This option is only useful for engines in the server mode. 1136 * 1137 * @return true if client authentication is requested, 1138 * or false if no client authentication is desired. 1139 * @see #setNeedClientAuth(bool) 1140 * @see #getNeedClientAuth() 1141 * @see #setWantClientAuth(bool) 1142 * @see #setUseClientMode(bool) 1143 */ 1144 abstract bool getWantClientAuth(); 1145 1146 1147 /** 1148 * Controls whether new SSL sessions may be established by this engine. 1149 * If session creations are not allowed, and there are no 1150 * existing sessions to resume, there will be no successful 1151 * handshaking. 1152 * 1153 * @param flag true indicates that sessions may be created; this 1154 * is the default. false indicates that an existing session 1155 * must be resumed 1156 * @see #getEnableSessionCreation() 1157 */ 1158 abstract void setEnableSessionCreation(bool flag); 1159 1160 1161 /** 1162 * Returns true if new SSL sessions may be established by this engine. 1163 * 1164 * @return true indicates that sessions may be created; this 1165 * is the default. false indicates that an existing session 1166 * must be resumed 1167 * @see #setEnableSessionCreation(bool) 1168 */ 1169 abstract bool getEnableSessionCreation(); 1170 1171 /** 1172 * Returns the SSLParameters in effect for this SSLEngine. 1173 * The ciphersuites and protocols of the returned SSLParameters 1174 * are always non-null. 1175 * 1176 * @return the SSLParameters in effect for this SSLEngine. 1177 */ 1178 // SSLParameters getSSLParameters() { 1179 // SSLParameters params = new SSLParameters(); 1180 // params.setCipherSuites(getEnabledCipherSuites()); 1181 // params.setProtocols(getEnabledProtocols()); 1182 // if (getNeedClientAuth()) { 1183 // params.setNeedClientAuth(true); 1184 // } else if (getWantClientAuth()) { 1185 // params.setWantClientAuth(true); 1186 // } 1187 // return params; 1188 // } 1189 1190 /** 1191 * Applies SSLParameters to this engine. 1192 * 1193 * <p>This means: 1194 * <ul> 1195 * <li>If {@code params.getCipherSuites()} is non-null, 1196 * {@code setEnabledCipherSuites()} is called with that value.</li> 1197 * <li>If {@code params.getProtocols()} is non-null, 1198 * {@code setEnabledProtocols()} is called with that value.</li> 1199 * <li>If {@code params.getNeedClientAuth()} or 1200 * {@code params.getWantClientAuth()} return {@code true}, 1201 * {@code setNeedClientAuth(true)} and 1202 * {@code setWantClientAuth(true)} are called, respectively; 1203 * otherwise {@code setWantClientAuth(false)} is called.</li> 1204 * <li>If {@code params.getServerNames()} is non-null, the engine will 1205 * configure its server names with that value.</li> 1206 * <li>If {@code params.getSNIMatchers()} is non-null, the engine will 1207 * configure its SNI matchers with that value.</li> 1208 * </ul> 1209 * 1210 * @param params the parameters 1211 * @throws IllegalArgumentException if the setEnabledCipherSuites() or 1212 * the setEnabledProtocols() call fails 1213 */ 1214 // void setSSLParameters(SSLParameters params) { 1215 // string[] s; 1216 // s = params.getCipherSuites(); 1217 // if (s !is null) { 1218 // setEnabledCipherSuites(s); 1219 // } 1220 // s = params.getProtocols(); 1221 // if (s !is null) { 1222 // setEnabledProtocols(s); 1223 // } 1224 // if (params.getNeedClientAuth()) { 1225 // setNeedClientAuth(true); 1226 // } else if (params.getWantClientAuth()) { 1227 // setWantClientAuth(true); 1228 // } else { 1229 // setWantClientAuth(false); 1230 // } 1231 // } 1232 1233 }