private void doTasks() {
    Runnable runnable = null;

    while ((runnable = tlsEngine.getDelegatedTask()) != null) {
      runnable.run();
    } // end of while ((runnable = engine.getDelegatedTask()) != 0)
  }
Example #2
0
  protected boolean handleSSLHandshake2() throws IOException {
    // We need to make sure the handshake process finished as a whole
    //		boolean proceed = false;
    SSLEngineResult engineResult = null;
    isHanshakeDone = false;
    while (true) {
      switch (engine.getHandshakeStatus()) {
        case NOT_HANDSHAKING:
        case FINISHED:
          isHanshakeDone = true;
          return true;
        case NEED_TASK:
          Executor exec = Executors.newSingleThreadExecutor();
          Runnable task;
          while ((task = engine.getDelegatedTask()) != null) {
            exec.execute(task);
          }
          continue;
        case NEED_WRAP:
          // We need to call a wrap on the engine
          appSendBuffer.flip();
          engineResult = engine.wrap(appSendBuffer, netSendBuffer);
          appSendBuffer.compact();
          if (engineResult.getStatus() == Status.BUFFER_OVERFLOW
              || engineResult.getStatus()
                  == Status
                      .OK) { // The enigne sys we need to flush the current buffer into the network
            // So just set the selector to the write mode
            channel.register(selector, SelectionKey.OP_WRITE);
            selector.wakeup();
            // System.out.println("Handshake wants to do a write ");
            return false;
          } else if (engineResult.getStatus() == Status.CLOSED) {
            throw new IOException("Connection closed");
          } else {
            continue;
          }

        case NEED_UNWRAP:
          // We need to call unwarap method of the engine
          netRecvBuffer.flip();
          engineResult = engine.unwrap(netRecvBuffer, appRecvBuffer);
          netRecvBuffer.compact();
          // System.out.println(engine.isInboundDone());
          if (engineResult.getStatus() == Status.BUFFER_UNDERFLOW) {
            if (!engine.isInboundDone()) {
              channel.register(selector, SelectionKey.OP_READ);
              selector.wakeup();
              // System.out.println("Handshake wants to do a read ");
              return false;
            } else continue;
          } else if (engineResult.getStatus() == Status.CLOSED) {
            throw new IOException("Connection closed");
          } else {
            continue;
          }
      }
    }
  }
Example #3
0
  /**
   * Perform tasks, if any, during the handshake phase
   *
   * @return The handshake status ( {@link javax.net.ssl.SSLEngineResult.HandshakeStatus})
   */
  private SSLEngineResult.HandshakeStatus tasks() {
    Runnable task = null;
    while ((task = sslEngine.getDelegatedTask()) != null) {
      // Run the task in blocking mode
      task.run();
    }

    return sslEngine.getHandshakeStatus();
  }
Example #4
0
  /**
   * Fetches all delegated tasks from the {@link SSLEngine} and runs them by invoking them directly.
   */
  private void runDelegatedTasks() {
    for (; ; ) {
      Runnable task = engine.getDelegatedTask();
      if (task == null) {
        break;
      }

      task.run();
    }
  }
Example #5
0
  private void runDelegatedTasks() {
    for (; ; ) {
      Runnable task = engine.getDelegatedTask();
      if (task == null) {
        break;
      }

      delegatedTaskExecutor.execute(task);
    }
  }
Example #6
0
 private static void runDelegatedTasks(SSLEngine engine) {
   Runnable runnable;
   System.out.println("Running delegated tasks...");
   while ((runnable = engine.getDelegatedTask()) != null) {
     runnable.run();
   }
   HandshakeStatus hs = engine.getHandshakeStatus();
   if (hs == HandshakeStatus.NEED_TASK) {
     throw new Error("Handshake shouldn't need additional tasks.");
   }
 }
Example #7
0
  /*
   * Do all the outstanding handshake tasks in the current Thread.
   */
  private SSLEngineResult.HandshakeStatus doTasks() {

    Runnable runnable;

    /*
     * We could run this in a separate thread, but
     * do in the current for now.
     */
    while ((runnable = sslEngine.getDelegatedTask()) != null) {
      runnable.run();
    }
    return sslEngine.getHandshakeStatus();
  }
  /*
   * If the result indicates that we have outstanding tasks to do,
   * go ahead and run them in this thread.
   */
  private static void runDelegatedTasks(SSLEngineResult result, SSLEngine engine) throws Exception {

    if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
      Runnable runnable;
      while ((runnable = engine.getDelegatedTask()) != null) {
        log("\trunning delegated task...");
        runnable.run();
      }
      HandshakeStatus hsStatus = engine.getHandshakeStatus();
      if (hsStatus == HandshakeStatus.NEED_TASK) {
        throw new Exception("handshake shouldn't need additional tasks");
      }
      log("\tnew HandshakeStatus: " + hsStatus);
    }
  }
  private void checkResult(
      SSLEngine engine,
      SSLEngineResult result,
      HandshakeStatus rqdHsStatus,
      boolean consumed,
      boolean produced)
      throws Exception {

    HandshakeStatus hsStatus = result.getHandshakeStatus();

    if (hsStatus == HandshakeStatus.NEED_TASK) {
      Runnable runnable;
      while ((runnable = engine.getDelegatedTask()) != null) {
        runnable.run();
      }
      hsStatus = engine.getHandshakeStatus();
    }

    if (hsStatus != rqdHsStatus) {
      throw new Exception("Required " + rqdHsStatus + ", got " + hsStatus);
    }

    int bc = result.bytesConsumed();
    int bp = result.bytesProduced();

    if (consumed) {
      if (bc <= 0) {
        throw new Exception("Should have consumed bytes");
      }
    } else {
      if (bc > 0) {
        throw new Exception("Should not have consumed bytes");
      }
    }

    if (produced) {
      if (bp <= 0) {
        throw new Exception("Should have produced bytes");
      }
    } else {
      if (bp > 0) {
        throw new Exception("Should not have produced bytes");
      }
    }
  }
Example #10
0
  private void runDelegatedTasks() {
    for (; ; ) {
      final Runnable task;
      synchronized (handshakeLock) {
        task = engine.getDelegatedTask();
      }

      if (task == null) {
        break;
      }

      delegatedTaskExecutor.execute(
          new Runnable() {
            public void run() {
              synchronized (handshakeLock) {
                task.run();
              }
            }
          });
    }
  }
 private ByteBuffer unwrap(ByteBuffer b) throws SSLException {
   in.clear();
   while (b.hasRemaining()) {
     sslEngineResult = sslEngine.unwrap(b, in);
     if (sslEngineResult.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
       if (DEBUG) {
         log("Handshake NEED TASK");
       }
       Runnable task;
       while ((task = sslEngine.getDelegatedTask()) != null) {
         if (DEBUG) {
           log("Running task: " + task);
         }
         task.run();
       }
     } else if (sslEngineResult.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED
         || sslEngineResult.getStatus() == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
       return in;
     }
   }
   return in;
 }
  boolean step() {
    switch (engine.getHandshakeStatus()) {
      case NOT_HANDSHAKING:
        boolean anything = false;
        {
          if (wrapSrc.position() > 0) anything |= this.wrap();
          if (unwrapSrc.position() > 0) anything |= this.unwrap();
        }
        return anything;

      case NEED_WRAP:
        if (!this.wrap()) return false;
        break;

      case NEED_UNWRAP:
        if (!this.unwrap()) return false;
        break;

      case NEED_TASK:
        final Runnable sslTask = engine.getDelegatedTask();
        Runnable wrappedTask =
            new Runnable() {
              @Override
              public void run() {
                sslTask.run();

                // continue handling I/O
                ioWorker.execute(NonBlockingSSL.this.stepTask);
              }
            };
        taskWorkers.execute(wrappedTask);
        return false;

      case FINISHED:
        throw new IllegalStateException("FINISHED");
    }

    return true;
  }
Example #13
0
 private void handshake() throws IOException {
   while (!isEstablished()) {
     switch (engine.getHandshakeStatus()) {
       case NOT_HANDSHAKING:
       case FINISHED:
         throw new IllegalStateException("Not handshaking");
       case NEED_TASK:
         Runnable task = engine.getDelegatedTask();
         if (task != null) {
           task.run();
         }
         break;
       case NEED_WRAP:
         wrap(EMPTY);
         break;
       case NEED_UNWRAP:
         if (!unwrap()) {
           return;
         }
         break;
     }
   }
 }
Example #14
0
 Runnable getDelegatedTask() {
   return _engine.getDelegatedTask();
 }
  @Test
  public void testTcpClose() throws Exception {
    // This test replaces SSLSocket() with a very manual SSL client
    // so we can close TCP underneath SSL.

    SocketChannel client = SocketChannel.open(_connector.socket().getLocalSocketAddress());
    client.socket().setSoTimeout(500);

    SocketChannel server = _connector.accept();
    server.configureBlocking(false);
    _manager.accept(server);

    SSLEngine engine = __sslCtxFactory.newSSLEngine();
    engine.setUseClientMode(true);
    engine.beginHandshake();

    ByteBuffer appOut = ByteBuffer.allocate(engine.getSession().getApplicationBufferSize());
    ByteBuffer sslOut = ByteBuffer.allocate(engine.getSession().getPacketBufferSize() * 2);
    ByteBuffer appIn = ByteBuffer.allocate(engine.getSession().getApplicationBufferSize());
    ByteBuffer sslIn = ByteBuffer.allocate(engine.getSession().getPacketBufferSize() * 2);

    boolean debug = false;

    if (debug) System.err.println(engine.getHandshakeStatus());
    int loop = 20;
    while (engine.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING) {
      if (--loop == 0) throw new IllegalStateException();

      if (engine.getHandshakeStatus() == HandshakeStatus.NEED_WRAP) {
        if (debug)
          System.err.printf(
              "sslOut %d-%d-%d%n", sslOut.position(), sslOut.limit(), sslOut.capacity());
        if (debug)
          System.err.printf(
              "appOut %d-%d-%d%n", appOut.position(), appOut.limit(), appOut.capacity());
        SSLEngineResult result = engine.wrap(appOut, sslOut);
        if (debug) System.err.println(result);
        sslOut.flip();
        int flushed = client.write(sslOut);
        if (debug) System.err.println("out=" + flushed);
        sslOut.clear();
      }

      if (engine.getHandshakeStatus() == HandshakeStatus.NEED_UNWRAP) {
        if (debug)
          System.err.printf("sslIn %d-%d-%d%n", sslIn.position(), sslIn.limit(), sslIn.capacity());
        if (sslIn.position() == 0) {
          int filled = client.read(sslIn);
          if (debug) System.err.println("in=" + filled);
        }
        sslIn.flip();
        if (debug)
          System.err.printf("sslIn %d-%d-%d%n", sslIn.position(), sslIn.limit(), sslIn.capacity());
        SSLEngineResult result = engine.unwrap(sslIn, appIn);
        if (debug) System.err.println(result);
        if (debug)
          System.err.printf("sslIn %d-%d-%d%n", sslIn.position(), sslIn.limit(), sslIn.capacity());
        if (sslIn.hasRemaining()) sslIn.compact();
        else sslIn.clear();
        if (debug)
          System.err.printf("sslIn %d-%d-%d%n", sslIn.position(), sslIn.limit(), sslIn.capacity());
      }

      if (engine.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
        Runnable task;
        while ((task = engine.getDelegatedTask()) != null) task.run();
        if (debug) System.err.println(engine.getHandshakeStatus());
      }
    }

    if (debug) System.err.println("\nSay Hello");

    // write a message
    appOut.put("HelloWorld".getBytes(StandardCharsets.UTF_8));
    appOut.flip();
    SSLEngineResult result = engine.wrap(appOut, sslOut);
    if (debug) System.err.println(result);
    sslOut.flip();
    int flushed = client.write(sslOut);
    if (debug) System.err.println("out=" + flushed);
    sslOut.clear();
    appOut.clear();

    // read the response
    int filled = client.read(sslIn);
    if (debug) System.err.println("in=" + filled);
    sslIn.flip();
    result = engine.unwrap(sslIn, appIn);
    if (debug) System.err.println(result);
    if (sslIn.hasRemaining()) sslIn.compact();
    else sslIn.clear();

    appIn.flip();
    String reply = new String(appIn.array(), appIn.arrayOffset(), appIn.remaining());
    appIn.clear();

    Assert.assertEquals("HelloWorld", reply);

    if (debug) System.err.println("Shutting down output");
    client.socket().shutdownOutput();

    filled = client.read(sslIn);
    if (debug) System.err.println("in=" + filled);

    if (filled >= 0) {
      // this is the old behaviour.
      sslIn.flip();
      try {
        // Since the client closed abruptly, the server is sending a close alert with a failure
        engine.unwrap(sslIn, appIn);
        Assert.fail();
      } catch (SSLException x) {
        // Expected
      }
    }

    sslIn.clear();
    filled = client.read(sslIn);
    Assert.assertEquals(-1, filled);

    Assert.assertFalse(server.isOpen());
  }
  @Test
  public void checkSslEngineBehaviour() throws Exception {
    SSLEngine server = __sslCtxFactory.newSSLEngine();
    SSLEngine client = __sslCtxFactory.newSSLEngine();

    ByteBuffer netC2S = ByteBuffer.allocate(server.getSession().getPacketBufferSize());
    ByteBuffer netS2C = ByteBuffer.allocate(server.getSession().getPacketBufferSize());
    ByteBuffer serverIn = ByteBuffer.allocate(server.getSession().getApplicationBufferSize());
    ByteBuffer serverOut = ByteBuffer.allocate(server.getSession().getApplicationBufferSize());
    ByteBuffer clientIn = ByteBuffer.allocate(client.getSession().getApplicationBufferSize());

    SSLEngineResult result;

    // start the client
    client.setUseClientMode(true);
    client.beginHandshake();
    Assert.assertEquals(HandshakeStatus.NEED_WRAP, client.getHandshakeStatus());

    // what if we try an unwrap?
    netS2C.flip();
    result = client.unwrap(netS2C, clientIn);
    // unwrap is a noop
    assertEquals(SSLEngineResult.Status.OK, result.getStatus());
    assertEquals(0, result.bytesConsumed());
    assertEquals(0, result.bytesProduced());
    assertEquals(HandshakeStatus.NEED_WRAP, result.getHandshakeStatus());
    netS2C.clear();

    // do the needed WRAP of empty buffer
    result = client.wrap(BufferUtil.EMPTY_BUFFER, netC2S);
    // unwrap is a noop
    assertEquals(SSLEngineResult.Status.OK, result.getStatus());
    assertEquals(0, result.bytesConsumed());
    assertThat(result.bytesProduced(), greaterThan(0));
    assertEquals(HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus());
    netC2S.flip();
    assertEquals(netC2S.remaining(), result.bytesProduced());

    // start the server
    server.setUseClientMode(false);
    server.beginHandshake();
    Assert.assertEquals(HandshakeStatus.NEED_UNWRAP, server.getHandshakeStatus());

    // what if we try a needless wrap?
    serverOut.put(BufferUtil.toBuffer("Hello World"));
    serverOut.flip();
    result = server.wrap(serverOut, netS2C);
    // wrap is a noop
    assertEquals(SSLEngineResult.Status.OK, result.getStatus());
    assertEquals(0, result.bytesConsumed());
    assertEquals(0, result.bytesProduced());
    assertEquals(HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus());

    // Do the needed unwrap, to an empty buffer
    result = server.unwrap(netC2S, BufferUtil.EMPTY_BUFFER);
    assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW, result.getStatus());
    assertEquals(0, result.bytesConsumed());
    assertEquals(0, result.bytesProduced());
    assertEquals(HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus());

    // Do the needed unwrap, to a full buffer
    serverIn.position(serverIn.limit());
    result = server.unwrap(netC2S, serverIn);
    assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW, result.getStatus());
    assertEquals(0, result.bytesConsumed());
    assertEquals(0, result.bytesProduced());
    assertEquals(HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus());

    // Do the needed unwrap, to an empty buffer
    serverIn.clear();
    result = server.unwrap(netC2S, serverIn);
    assertEquals(SSLEngineResult.Status.OK, result.getStatus());
    assertThat(result.bytesConsumed(), greaterThan(0));
    assertEquals(0, result.bytesProduced());
    assertEquals(HandshakeStatus.NEED_TASK, result.getHandshakeStatus());

    server.getDelegatedTask().run();

    assertEquals(HandshakeStatus.NEED_WRAP, server.getHandshakeStatus());
  }