Ejemplo n.º 1
0
  private void wrap(ChannelHandlerContext ctx, boolean inUnwrap) throws SSLException {
    ByteBuf out = null;
    ChannelPromise promise = null;
    ByteBufAllocator alloc = ctx.alloc();
    try {
      for (; ; ) {
        Object msg = pendingUnencryptedWrites.current();
        if (msg == null) {
          break;
        }

        ByteBuf buf = (ByteBuf) msg;
        if (out == null) {
          out = allocateOutNetBuf(ctx, buf.readableBytes());
        }

        SSLEngineResult result = wrap(alloc, engine, buf, out);
        if (!buf.isReadable()) {
          promise = pendingUnencryptedWrites.remove();
        } else {
          promise = null;
        }

        if (result.getStatus() == Status.CLOSED) {
          // SSLEngine has been closed already.
          // Any further write attempts should be denied.
          pendingUnencryptedWrites.removeAndFailAll(SSLENGINE_CLOSED);
          return;
        } else {
          switch (result.getHandshakeStatus()) {
            case NEED_TASK:
              runDelegatedTasks();
              break;
            case FINISHED:
              setHandshakeSuccess();
              // deliberate fall-through
            case NOT_HANDSHAKING:
              setHandshakeSuccessIfStillHandshaking();
              // deliberate fall-through
            case NEED_WRAP:
              finishWrap(ctx, out, promise, inUnwrap);
              promise = null;
              out = null;
              break;
            case NEED_UNWRAP:
              return;
            default:
              throw new IllegalStateException(
                  "Unknown handshake status: " + result.getHandshakeStatus());
          }
        }
      }
    } catch (SSLException e) {
      setHandshakeFailure(ctx, e);
      throw e;
    } finally {
      finishWrap(ctx, out, promise, inUnwrap);
    }
  }
Ejemplo n.º 2
0
  private void wrapNonAppData(ChannelHandlerContext ctx, boolean inUnwrap) throws SSLException {
    ByteBuf out = null;
    try {
      for (; ; ) {
        if (out == null) {
          out = ctx.alloc().buffer(maxPacketBufferSize);
        }
        SSLEngineResult result = wrap(engine, Unpooled.EMPTY_BUFFER, out);

        if (result.bytesProduced() > 0) {
          ctx.write(out);
          if (inUnwrap) {
            needsFlush = true;
          }
          out = null;
        }

        switch (result.getHandshakeStatus()) {
          case FINISHED:
            setHandshakeSuccess();
            break;
          case NEED_TASK:
            runDelegatedTasks();
            break;
          case NEED_UNWRAP:
            if (!inUnwrap) {
              unwrapNonApp(ctx);
            }
            break;
          case NEED_WRAP:
            break;
          case NOT_HANDSHAKING:
            setHandshakeSuccessIfStillHandshaking();
            // Workaround for TLS False Start problem reported at:
            // https://github.com/netty/netty/issues/1108#issuecomment-14266970
            if (!inUnwrap) {
              unwrapNonApp(ctx);
            }
            break;
          default:
            throw new IllegalStateException(
                "Unknown handshake status: " + result.getHandshakeStatus());
        }

        if (result.bytesProduced() == 0) {
          break;
        }
      }
    } catch (SSLException e) {
      setHandshakeFailure(e);
      throw e;
    } finally {
      if (out != null) {
        out.release();
      }
    }
  }
Ejemplo n.º 3
0
  private void wrapNonAppData(ChannelHandlerContext ctx, boolean inUnwrap) throws SSLException {
    ByteBuf out = null;
    ByteBufAllocator alloc = ctx.alloc();
    try {
      for (; ; ) {
        if (out == null) {
          out = allocateOutNetBuf(ctx, 0);
        }
        SSLEngineResult result = wrap(alloc, engine, Unpooled.EMPTY_BUFFER, out);

        if (result.bytesProduced() > 0) {
          ctx.write(out);
          if (inUnwrap) {
            needsFlush = true;
          }
          out = null;
        }

        switch (result.getHandshakeStatus()) {
          case FINISHED:
            setHandshakeSuccess();
            break;
          case NEED_TASK:
            runDelegatedTasks();
            break;
          case NEED_UNWRAP:
            if (!inUnwrap) {
              unwrapNonAppData(ctx);
            }
            break;
          case NEED_WRAP:
            break;
          case NOT_HANDSHAKING:
            setHandshakeSuccessIfStillHandshaking();
            // Workaround for TLS False Start problem reported at:
            // https://github.com/netty/netty/issues/1108#issuecomment-14266970
            if (!inUnwrap) {
              unwrapNonAppData(ctx);
            }
            break;
          default:
            throw new IllegalStateException(
                "Unknown handshake status: " + result.getHandshakeStatus());
        }

        if (result.bytesProduced() == 0) {
          break;
        }

        // It should not consume empty buffers when it is not handshaking
        // Fix for Android, where it was encrypting empty buffers even when not handshaking
        if (result.bytesConsumed() == 0
            && result.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING) {
          break;
        }
      }
    } catch (SSLException e) {
      setHandshakeFailure(ctx, e);
      throw e;
    } finally {
      if (out != null) {
        out.release();
      }
    }
  }
Ejemplo n.º 4
0
  private void wrap(ChannelHandlerContext ctx, boolean inUnwrap) throws SSLException {
    ByteBuf out = null;
    ChannelPromise promise = null;
    try {
      for (; ; ) {
        PendingWrite pending = pendingUnencryptedWrites.peek();
        if (pending == null) {
          break;
        }
        if (out == null) {
          out = ctx.alloc().buffer(maxPacketBufferSize);
        }

        if (!(pending.msg() instanceof ByteBuf)) {
          ctx.write(pending.msg(), (ChannelPromise) pending.recycleAndGet());
          pendingUnencryptedWrites.remove();
          continue;
        }
        ByteBuf buf = (ByteBuf) pending.msg();
        SSLEngineResult result = wrap(engine, buf, out);

        if (!buf.isReadable()) {
          buf.release();
          promise = (ChannelPromise) pending.recycleAndGet();
          pendingUnencryptedWrites.remove();
        } else {
          promise = null;
        }

        if (result.getStatus() == Status.CLOSED) {
          // SSLEngine has been closed already.
          // Any further write attempts should be denied.
          for (; ; ) {
            PendingWrite w = pendingUnencryptedWrites.poll();
            if (w == null) {
              break;
            }
            w.failAndRecycle(SSLENGINE_CLOSED);
          }
          return;
        } else {
          switch (result.getHandshakeStatus()) {
            case NEED_TASK:
              runDelegatedTasks();
              break;
            case FINISHED:
              setHandshakeSuccess();
              // deliberate fall-through
            case NOT_HANDSHAKING:
              setHandshakeSuccessIfStillHandshaking();
              // deliberate fall-through
            case NEED_WRAP:
              finishWrap(ctx, out, promise, inUnwrap);
              promise = null;
              out = null;
              break;
            case NEED_UNWRAP:
              return;
            default:
              throw new IllegalStateException(
                  "Unknown handshake status: " + result.getHandshakeStatus());
          }
        }
      }
    } catch (SSLException e) {
      setHandshakeFailure(e);
      throw e;
    } finally {
      finishWrap(ctx, out, promise, inUnwrap);
    }
  }