Beispiel #1
0
  /** Notify all the handshake futures about the failure during the handshake. */
  private void setHandshakeFailure(Throwable cause) {
    // Release all resources such as internal buffers that SSLEngine
    // is managing.
    engine.closeOutbound();

    try {
      engine.closeInbound();
    } catch (SSLException e) {
      // only log in debug mode as it most likely harmless and latest chrome still trigger
      // this all the time.
      //
      // See https://github.com/netty/netty/issues/1340
      String msg = e.getMessage();
      if (msg == null || !msg.contains("possible truncation attack")) {
        logger.debug("SSLEngine.closeInbound() raised an exception.", e);
      }
    }
    notifyHandshakeFailure(cause);
    for (; ; ) {
      PendingWrite write = pendingUnencryptedWrites.poll();
      if (write == null) {
        break;
      }
      write.failAndRecycle(cause);
    }
  }
Beispiel #2
0
  /** Notify all the handshake futures about the failure during the handshake. */
  private void setHandshakeFailure(ChannelHandlerContext ctx, Throwable cause) {
    // Release all resources such as internal buffers that SSLEngine
    // is managing.
    engine.closeOutbound();

    try {
      engine.closeInbound();
    } catch (SSLException e) {
      // only log in debug mode as it most likely harmless and latest chrome still trigger
      // this all the time.
      //
      // See https://github.com/netty/netty/issues/1340
      String msg = e.getMessage();
      if (msg == null || !msg.contains("possible truncation attack")) {
        logger.debug("{} SSLEngine.closeInbound() raised an exception.", ctx.channel(), e);
      }
    }
    notifyHandshakeFailure(cause);
    pendingUnencryptedWrites.removeAndFailAll(cause);
  }
Beispiel #3
0
  private Future<Channel> handshake() {
    final ScheduledFuture<?> timeoutFuture;
    if (handshakeTimeoutMillis > 0) {
      timeoutFuture =
          ctx.executor()
              .schedule(
                  new Runnable() {
                    @Override
                    public void run() {
                      if (handshakePromise.isDone()) {
                        return;
                      }
                      notifyHandshakeFailure(HANDSHAKE_TIMED_OUT);
                    }
                  },
                  handshakeTimeoutMillis,
                  TimeUnit.MILLISECONDS);
    } else {
      timeoutFuture = null;
    }

    handshakePromise.addListener(
        new GenericFutureListener<Future<Channel>>() {
          @Override
          public void operationComplete(Future<Channel> f) throws Exception {
            if (timeoutFuture != null) {
              timeoutFuture.cancel(false);
            }
          }
        });
    try {
      engine.beginHandshake();
      wrapNonAppData(ctx, false);
      ctx.flush();
    } catch (Exception e) {
      notifyHandshakeFailure(e);
    }
    return handshakePromise;
  }
Beispiel #4
0
  /**
   * Performs TLS (re)negotiation.
   *
   * @param newHandshakePromise if {@code null}, use the existing {@link #handshakePromise},
   *     assuming that the current negotiation has not been finished. Currently, {@code null} is
   *     expected only for the initial handshake.
   */
  private void handshake(final Promise<Channel> newHandshakePromise) {
    final Promise<Channel> p;
    if (newHandshakePromise != null) {
      final Promise<Channel> oldHandshakePromise = handshakePromise;
      if (!oldHandshakePromise.isDone()) {
        // There's no need to handshake because handshake is in progress already.
        // Merge the new promise into the old one.
        oldHandshakePromise.addListener(
            new FutureListener<Channel>() {
              @Override
              public void operationComplete(Future<Channel> future) throws Exception {
                if (future.isSuccess()) {
                  newHandshakePromise.setSuccess(future.getNow());
                } else {
                  newHandshakePromise.setFailure(future.cause());
                }
              }
            });
        return;
      }

      handshakePromise = p = newHandshakePromise;
    } else {
      // Forced to reuse the old handshake.
      p = handshakePromise;
      assert !p.isDone();
    }

    // Begin handshake.
    final ChannelHandlerContext ctx = this.ctx;
    try {
      engine.beginHandshake();
      wrapNonAppData(ctx, false);
      ctx.flush();
    } catch (Exception e) {
      notifyHandshakeFailure(e);
    }

    // Set timeout if necessary.
    final long handshakeTimeoutMillis = this.handshakeTimeoutMillis;
    if (handshakeTimeoutMillis <= 0 || p.isDone()) {
      return;
    }

    final ScheduledFuture<?> timeoutFuture =
        ctx.executor()
            .schedule(
                new Runnable() {
                  @Override
                  public void run() {
                    if (p.isDone()) {
                      return;
                    }
                    notifyHandshakeFailure(HANDSHAKE_TIMED_OUT);
                  }
                },
                handshakeTimeoutMillis,
                TimeUnit.MILLISECONDS);

    // Cancel the handshake timeout when handshake is finished.
    p.addListener(
        new FutureListener<Channel>() {
          @Override
          public void operationComplete(Future<Channel> f) throws Exception {
            timeoutFuture.cancel(false);
          }
        });
  }