/*
   * Using the SSLContext created during object creation,
   * create/configure the SSLEngines we'll use for this test.
   */
  private void createSSLEngines() throws Exception {
    /*
     * Configure the serverEngine to act as a server in the SSL/TLS
     * handshake.  Also, require SSL client authentication.
     */
    serverEngine = sslc.createSSLEngine();
    serverEngine.setUseClientMode(false);
    serverEngine.setNeedClientAuth(true);

    /*
     * Similar to above, but using client mode instead.
     */
    clientEngine = sslc.createSSLEngine("client", 80);
    clientEngine.setUseClientMode(true);
  }
  public ChannelPipeline getPipeline() throws Exception {
    log.debug("Creating client channel pipeline");

    ChannelPipeline pipeline = Channels.pipeline();

    SSLEngine engine = sslContext.createSSLEngine();
    engine.setUseClientMode(true);

    SslHandler sslHandler = new SslHandler(engine);
    sslHandler.setCloseOnSSLException(true);
    pipeline.addLast("ssl", sslHandler);

    pipeline.addLast("chunker", new ChunkedWriteHandler());

    pipeline.addLast(
        "framer",
        new DelimiterBasedFrameDecoder(protocol.maxHeaderLength(), protocol.headerDelimiter()));
    pipeline.addLast("stringDecoder", new StringDecoder(protocol.headerCharset()));
    pipeline.addLast("stringEncoder", new StringEncoder(protocol.headerCharset()));

    HeaderCodec headerCodec = new HeaderCodec(protocol);
    pipeline.addLast("headerDecoder", headerCodec.decoder());
    pipeline.addLast("headerEncoder", headerCodec.encoder());

    pipeline.addLast("client", new ClientHandler(store));

    return pipeline;
  }
  /**
   * Creates a new <code>TLSWrapper</code> instance.
   *
   * @param sslc
   * @param eventHandler
   * @param clientMode
   */
  public TLSWrapper(
      SSLContext sslc, TLSEventHandler eventHandler, String[] sslProtocols, boolean clientMode) {
    tlsEngine = sslc.createSSLEngine();
    tlsEngine.setUseClientMode(clientMode);

    if (tls_jdk_nss_workaround) {
      // Workaround for TLS/SSL bug in new JDK used with new version of
      // nss library see also:
      // http://stackoverflow.com/q/10687200/427545
      // http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=b509d9cb5d8164d90e6731f5fc44?bug_id=6928796
      tlsEngine.setEnabledCipherSuites(tls_workaround_ciphers);
    }

    if (sslProtocols != null) {
      tlsEngine.setEnabledProtocols(sslProtocols);
    }

    netBuffSize = tlsEngine.getSession().getPacketBufferSize();
    appBuffSize = tlsEngine.getSession().getApplicationBufferSize();
    this.eventHandler = eventHandler;

    if (!clientMode) {
      tlsEngine.setWantClientAuth(true);
    }
  }
Beispiel #4
0
 /**
  * Create a new client mode SSL engine, configured from an option map.
  *
  * @param sslContext the SSL context
  * @param optionMap the SSL options
  * @param peerAddress the peer address of the connection
  * @return the configured SSL engine
  */
 public static SSLEngine createSSLEngine(
     SSLContext sslContext, OptionMap optionMap, InetSocketAddress peerAddress) {
   final SSLEngine engine =
       sslContext.createSSLEngine(
           optionMap.get(Options.SSL_PEER_HOST_NAME, getHostNameNoResolve(peerAddress)),
           optionMap.get(Options.SSL_PEER_PORT, peerAddress.getPort()));
   engine.setUseClientMode(true);
   engine.setEnableSessionCreation(optionMap.get(Options.SSL_ENABLE_SESSION_CREATION, true));
   final Sequence<String> cipherSuites = optionMap.get(Options.SSL_ENABLED_CIPHER_SUITES);
   if (cipherSuites != null) {
     final Set<String> supported =
         new HashSet<String>(Arrays.asList(engine.getSupportedCipherSuites()));
     final List<String> finalList = new ArrayList<String>();
     for (String name : cipherSuites) {
       if (supported.contains(name)) {
         finalList.add(name);
       }
     }
     engine.setEnabledCipherSuites(finalList.toArray(new String[finalList.size()]));
   }
   final Sequence<String> protocols = optionMap.get(Options.SSL_ENABLED_PROTOCOLS);
   if (protocols != null) {
     final Set<String> supported =
         new HashSet<String>(Arrays.asList(engine.getSupportedProtocols()));
     final List<String> finalList = new ArrayList<String>();
     for (String name : protocols) {
       if (supported.contains(name)) {
         finalList.add(name);
       }
     }
     engine.setEnabledProtocols(finalList.toArray(new String[finalList.size()]));
   }
   return engine;
 }
Beispiel #5
0
  protected SSLEngine createSSLEngine(String sniHostName, List<Cipher> clientRequestedCiphers) {
    SSLHostConfig sslHostConfig = getSSLHostConfig(sniHostName);

    SSLHostConfigCertificate certificate = selectCertificate(sslHostConfig, clientRequestedCiphers);

    SSLContextWrapper sslContextWrapper = certificate.getSslContextWrapper();
    if (sslContextWrapper == null) {
      throw new IllegalStateException(sm.getString("endpoint.jsse.noSslContext", sniHostName));
    }

    SSLEngine engine = sslContextWrapper.getSSLContext().createSSLEngine();
    switch (sslHostConfig.getCertificateVerification()) {
      case NONE:
        engine.setNeedClientAuth(false);
        engine.setWantClientAuth(false);
        break;
      case OPTIONAL:
      case OPTIONAL_NO_CA:
        engine.setWantClientAuth(true);
        break;
      case REQUIRED:
        engine.setNeedClientAuth(true);
        break;
    }
    engine.setUseClientMode(false);
    engine.setEnabledCipherSuites(sslContextWrapper.getEnabledCiphers());
    engine.setEnabledProtocols(sslContextWrapper.getEnabledProtocols());

    SSLParameters sslParameters = engine.getSSLParameters();
    sslParameters.setUseCipherSuitesOrder(sslHostConfig.getHonorCipherOrder());
    // In case the getter returns a defensive copy
    engine.setSSLParameters(sslParameters);

    return engine;
  }
  public ChannelPipeline getPipeline() throws Exception {
    ChannelPipeline pipeline = pipeline();

    // Add SSL handler first to encrypt and decrypt everything.
    // In this example, we use a bogus certificate in the server side
    // and accept any invalid certificates in the client side.
    // You will need something more complicated to identify both
    // and server in the real world.
    //
    // Read SecureChatSslContextFactory
    // if you need client certificate authentication.

    SSLEngine engine = SecureChatSslContextFactory.getServerContext().createSSLEngine();
    engine.setUseClientMode(false);

    pipeline.addLast("ssl", new SslHandler(engine));

    // On top of the SSL handler, add the text line codec.
    pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
    pipeline.addLast("decoder", new StringDecoder());
    pipeline.addLast("encoder", new StringEncoder());

    // and then business logic.
    pipeline.addLast("handler", new SecureChatServerHandler());

    return pipeline;
  }
  public Channel createChannel(SocketChannel sc, SelectorThread st, ChannelListener l)
      throws IOException, SSLException {
    log.info("Creating SecureChannel. Client mode: " + clientMode);
    SSLEngine engine = sslContext.createSSLEngine();
    engine.setUseClientMode(clientMode);
    engine.setNeedClientAuth(true);

    return new SSLChannel(st, sc, l, engine);
  }
Beispiel #8
0
  @Test
  public void testGentleCloseDuringHandshake() throws Exception {
    InetSocketAddress address = startServer(version, null);
    SslContextFactory sslContextFactory = newSslContextFactory();
    sslContextFactory.start();
    SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
    sslEngine.setUseClientMode(true);
    NextProtoNego.put(
        sslEngine,
        new NextProtoNego.ClientProvider() {
          @Override
          public boolean supports() {
            return true;
          }

          @Override
          public void unsupported() {}

          @Override
          public String selectProtocol(List<String> protocols) {
            return null;
          }
        });
    sslEngine.beginHandshake();

    ByteBuffer encrypted = ByteBuffer.allocate(sslEngine.getSession().getPacketBufferSize());
    sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
    encrypted.flip();

    try (SocketChannel channel = SocketChannel.open(address)) {
      // Send ClientHello, immediately followed by TLS Close Alert and then by FIN
      channel.write(encrypted);
      sslEngine.closeOutbound();
      encrypted.clear();
      sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
      encrypted.flip();
      channel.write(encrypted);
      channel.shutdownOutput();

      // Read ServerHello from server
      encrypted.clear();
      int read = channel.read(encrypted);
      encrypted.flip();
      Assert.assertTrue(read > 0);
      // Cannot decrypt, as the SSLEngine has been already closed

      // Now if we read more, we should either read the TLS Close Alert, or directly -1
      encrypted.clear();
      read = channel.read(encrypted);
      // Sending a TLS Close Alert during handshake results in an exception when
      // unwrapping that the server react to by closing the connection abruptly.
      Assert.assertTrue(read < 0);
    }
  }
 @Override
 protected Connection newConnection(SelectableChannel channel, EndPoint endpoint) {
   SSLEngine engine = __sslCtxFactory.newSSLEngine();
   engine.setUseClientMode(false);
   SslConnection sslConnection =
       new SslConnection(__byteBufferPool, _threadPool, endpoint, engine);
   sslConnection.setRenegotiationAllowed(__sslCtxFactory.isRenegotiationAllowed());
   Connection appConnection = super.newConnection(channel, sslConnection.getDecryptedEndPoint());
   sslConnection.getDecryptedEndPoint().setConnection(appConnection);
   return sslConnection;
 }
 protected void decode(ChannelHandlerContext context, ByteBuf buffer) throws Exception {
   ChannelPipeline pipeline = context.pipeline();
   if (detectSsl && SslHandler.isEncrypted(buffer)) {
     SSLEngine engine = SSL_SERVER_CONTEXT.getValue().createSSLEngine();
     engine.setUseClientMode(false);
     pipeline.addLast(
         new SslHandler(engine),
         new ChunkedWriteHandler(),
         new PortUnificationServerHandler(delegatingHttpRequestHandler, false, detectGzip));
   } else {
     int magic1 = buffer.getUnsignedByte(buffer.readerIndex());
     int magic2 = buffer.getUnsignedByte(buffer.readerIndex() + 1);
     if (detectGzip && magic1 == 31 && magic2 == 139) {
       pipeline.addLast(
           new JZlibEncoder(ZlibWrapper.GZIP),
           new JdkZlibDecoder(ZlibWrapper.GZIP),
           new PortUnificationServerHandler(delegatingHttpRequestHandler, detectSsl, false));
     } else if (isHttp(magic1, magic2)) {
       NettyUtil.initHttpHandlers(pipeline);
       pipeline.addLast(delegatingHttpRequestHandler);
       if (BuiltInServer.LOG.isDebugEnabled()) {
         pipeline.addLast(
             new ChannelOutboundHandlerAdapter() {
               @Override
               public void write(
                   ChannelHandlerContext context, Object message, ChannelPromise promise)
                   throws Exception {
                 if (message instanceof HttpResponse) {
                   //                BuiltInServer.LOG.debug("OUT HTTP:\n" + message);
                   HttpResponse response = (HttpResponse) message;
                   BuiltInServer.LOG.debug(
                       "OUT HTTP: "
                           + response.getStatus().code()
                           + " "
                           + response.headers().get("Content-type"));
                 }
                 super.write(context, message, promise);
               }
             });
       }
     } else if (magic1 == 'C' && magic2 == 'H') {
       buffer.skipBytes(2);
       pipeline.addLast(new CustomHandlerDelegator());
     } else {
       BuiltInServer.LOG.warn("unknown request, first two bytes " + magic1 + " " + magic2);
       context.close();
     }
   }
   // must be after new channels handlers addition (netty bug?)
   ensureThatExceptionHandlerIsLast(pipeline);
   pipeline.remove(this);
   context.fireChannelRead(buffer);
 }
 @Override
 public void initChannel(SocketChannel ch) throws Exception {
   ChannelPipeline pipeline = ch.pipeline();
   SSLContext sslContext = Utils.createSSLContext();
   SSLEngine engine = sslContext.createSSLEngine();
   engine.setUseClientMode(true);
   pipeline.addLast("ssl", new SslHandler(engine));
   pipeline.addLast("framer", new LineBasedFrameDecoder(1000 * 1000 * 10, true, false));
   pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
   pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
   pipeline.addLast("handler", connection);
 }
 public SSLSocketChannelWrapper(SSLContext sslContext, SocketChannel sc, boolean client)
     throws Exception {
   super(sc);
   sslEngine = sslContext.createSSLEngine();
   sslEngine.setUseClientMode(client);
   sslEngine.setEnableSessionCreation(true);
   SSLSession session = sslEngine.getSession();
   in = ByteBuffer.allocate(64 * 1024);
   emptyBuffer = ByteBuffer.allocate(0);
   int netBufferMax = session.getPacketBufferSize();
   netOutBuffer = ByteBuffer.allocate(netBufferMax);
   netInBuffer = ByteBuffer.allocate(netBufferMax);
 }
  @Override
  public byte[] accept(byte[] token) throws IOException {
    checkState(!isEstablished());

    if (!isClientModeSet) {
      engine.setUseClientMode(false);
      isClientModeSet = true;
    }

    addInToken(token);
    handshake();
    return getOutToken();
  }
Beispiel #14
0
 private SSLEngine makeSSLEngine(TLSParams p, SSLContext ctx) {
   SSLEngine eng = ctx.createSSLEngine();
   if (p.getCiphers() != null) {
     eng.setEnabledCipherSuites(p.getCiphers().toArray(new String[p.getCiphers().size()]));
   }
   if (p.isClientAuthRequired()) {
     eng.setNeedClientAuth(true);
   } else if (p.isClientAuthRequested()) {
     eng.setWantClientAuth(true);
   }
   eng.setUseClientMode(false);
   return eng;
 }
Beispiel #15
0
  /**
   * Returns server ssl engine.
   *
   * @param context - SSLContext to get SSLEngine from.
   * @param useSNI - flag used to enable or disable using SNI extension. Needed for Kerberos.
   */
  public static SSLEngine getServerSSLEngine(SSLContext context, boolean useSNI) {

    SSLEngine serverEngine = context.createSSLEngine();
    serverEngine.setUseClientMode(false);
    if (useSNI) {
      SNIMatcher matcher = SNIHostName.createSNIMatcher(SNI_PATTERN);
      List<SNIMatcher> matchers = new ArrayList<>();
      matchers.add(matcher);
      SSLParameters params = serverEngine.getSSLParameters();
      params.setSNIMatchers(matchers);
      serverEngine.setSSLParameters(params);
    }
    return serverEngine;
  }
Beispiel #16
0
  /**
   * Returns client ssl engine.
   *
   * @param context - SSLContext to get SSLEngine from.
   * @param useSNI - flag used to enable or disable using SNI extension. Needed for Kerberos.
   */
  public static SSLEngine getClientSSLEngine(SSLContext context, boolean useSNI) {

    SSLEngine clientEngine = context.createSSLEngine(HOST, 80);
    clientEngine.setUseClientMode(true);
    if (useSNI) {
      SNIHostName serverName = new SNIHostName(SERVER_NAME);
      List<SNIServerName> serverNames = new ArrayList<>();
      serverNames.add(serverName);
      SSLParameters params = clientEngine.getSSLParameters();
      params.setServerNames(serverNames);
      clientEngine.setSSLParameters(params);
    }
    return clientEngine;
  }
Beispiel #17
0
  @Test
  public void testAbruptCloseDuringHandshake() throws Exception {
    InetSocketAddress address = startServer(version, null);
    SslContextFactory sslContextFactory = newSslContextFactory();
    sslContextFactory.start();
    SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
    sslEngine.setUseClientMode(true);
    NextProtoNego.put(
        sslEngine,
        new NextProtoNego.ClientProvider() {
          @Override
          public boolean supports() {
            return true;
          }

          @Override
          public void unsupported() {}

          @Override
          public String selectProtocol(List<String> protocols) {
            return null;
          }
        });
    sslEngine.beginHandshake();

    ByteBuffer encrypted = ByteBuffer.allocate(sslEngine.getSession().getPacketBufferSize());
    sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
    encrypted.flip();

    try (SocketChannel channel = SocketChannel.open(address)) {
      // Send ClientHello, immediately followed by FIN (no TLS Close Alert)
      channel.write(encrypted);
      channel.shutdownOutput();

      // Read ServerHello from server
      encrypted.clear();
      int read = channel.read(encrypted);
      encrypted.flip();
      Assert.assertTrue(read > 0);
      ByteBuffer decrypted = ByteBuffer.allocate(sslEngine.getSession().getApplicationBufferSize());
      sslEngine.unwrap(encrypted, decrypted);

      // Now if we read more, we should either read the TLS Close Alert, or directly -1
      encrypted.clear();
      read = channel.read(encrypted);
      // Since we have close the connection abruptly, the server also does so
      Assert.assertTrue(read < 0);
    }
  }
Beispiel #18
0
    private synchronized SSLEngine newSslEngine(SocketChannel channel) throws IOException {
      SslContextFactory sslContextFactory = _httpClient.getSslContextFactory();
      SSLEngine sslEngine;
      if (channel != null) {
        String peerHost = channel.socket().getInetAddress().getHostAddress();
        int peerPort = channel.socket().getPort();
        sslEngine = sslContextFactory.newSslEngine(peerHost, peerPort);
      } else {
        sslEngine = sslContextFactory.newSslEngine();
      }
      sslEngine.setUseClientMode(true);
      sslEngine.beginHandshake();

      return sslEngine;
    }
  @Override
  protected void initChannel(SocketChannel ch) throws Exception {
    ChannelPipeline pipeline = ch.pipeline();
    SSLEngine engine = SecureChatSslContextFactory.getServerContext().createSSLEngine();
    engine.setUseClientMode(false);

    pipeline.addLast("ssl", new SslHandler(engine));

    pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
    pipeline.addLast("decoder", new StringDecoder());
    pipeline.addLast("encoder", new StringEncoder());

    // and then business logic.
    pipeline.addLast("handler", new SecureChatServerHandler());
  }
Beispiel #20
0
  private ChannelFuture initializeChannel(InetSocketAddress addr) throws NntpClientConnectionError {
    final SSLEngine engine;
    if (this.ssl) {
      try {
        engine = this.initializeSsl();
        engine.setUseClientMode(true);
      } catch (NoSuchAlgorithmException | KeyManagementException ex) {
        throw new NntpClientConnectionError(ex);
      }
    } else {
      engine = null;
    }

    ClientBootstrap bootstrap = new ClientBootstrap(channelFactory());
    bootstrap.setOption("connectTimeoutMillis", this.connectTimeoutMillis);
    bootstrap.setOption("tcpNoDelay", true);
    bootstrap.setOption("keepAlive", true);
    bootstrap.setOption("reuseAddress", true);

    bootstrap.setPipelineFactory(
        new ChannelPipelineFactory() {
          @Override
          public ChannelPipeline getPipeline() throws Exception {
            ChannelPipeline pipeline = Channels.pipeline();

            pipeline.addLast("BANDWIDTH", trafficHandler);

            if (engine != null) {
              pipeline.addLast("ssl", new SslHandler(engine));
            }

            pipeline.addLast("stringenc", new StringEncoder(Charsets.UTF_8));
            pipeline.addLast("lineframer", new LineBasedFrameDecoder(4096));
            pipeline.addLast(
                "decoder",
                new ResponseDecoder(
                    new ResponseStateNotifierImpl(DefaultNntpClient.this.pipeline)));
            pipeline.addLast(
                HANDLER_PROCESSOR, new ResponseProcessor(DefaultNntpClient.this.pipeline));

            return pipeline;
          }
        });

    return bootstrap.connect(addr).awaitUninterruptibly();
  }
Beispiel #21
0
 static {
   try {
     SSLEngine temporary = getContext().createSSLEngine();
     temporary.setUseClientMode(true);
     String[] enabledCiphers = temporary.getEnabledCipherSuites();
     List<String> enabledCiphersList = new LinkedList<>();
     for (String cipher : enabledCiphers) {
       if (!cipher.contains("anon")
           && !cipher.contains("KRB5")
           && !cipher.contains("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) {
         enabledCiphersList.add(cipher);
       }
     }
     ENABLED_NON_KRB_NOT_ANON_CIPHERS = enabledCiphersList.toArray(new String[0]);
   } catch (Exception ex) {
     throw new Error("Unexpected issue", ex);
   }
 }
  @Override
  public ChannelPipeline getPipeline() throws Exception {
    ChannelPipeline pipeline = Channels.pipeline();

    pipeline.addLast("debug-client-head", new DebugHandler("CLIENT_HEAD"));
    if (this.clientContext.isSecure()) {
      SSLEngine sslEngine = this.clientContext.getSSLContext().createSSLEngine();
      sslEngine.setUseClientMode(true);
      SslHandler sslHandler = new SslHandler(sslEngine);
      sslHandler.setEnableRenegotiation(false);
      sslHandler.setIssueHandshake(true);
      pipeline.addLast("ssl", sslHandler);
      pipeline.addLast("client-post-ssl", new DebugHandler("SERVER-POST-SSL"));
    }
    if (this.handshake != null) {
      pipeline.addLast("http-encoder", new HttpRequestEncoder());
      pipeline.addLast("http-decoder", new WebSocketHttpResponseDecoder(this.handshake));
      pipeline.addLast(
          "websocket-connection-negotiator",
          new WebSocketConnectionNegotiator(
              this.clientContext.getWebSocketAddress(), this.handshake));
      pipeline.addLast("stomp-frame-decoder", new WebSocketStompFrameDecoder());
      pipeline.addLast("stomp-frame-encoder", new WebSocketStompFrameEncoder());
    } else {
      pipeline.addLast("stomp-frame-decoder", new StompFrameDecoder());
      pipeline.addLast("stomp-frame-encoder", new StompFrameEncoder());
    }

    pipeline.addLast("debug-client-mid", new DebugHandler("CLIENT_MID"));

    pipeline.addLast(
        "stomp-connection-negotiator", new StompConnectionNegotiator(clientContext, "localhost"));
    pipeline.addLast("stomp-client-receipt", new ClientReceiptHandler(clientContext));

    pipeline.addLast("stomp-message-encoder", new StompMessageEncoder());
    pipeline.addLast(
        "stomp-message-decoder",
        new StompMessageDecoder(new ClientStompMessageFactory(this.client)));

    pipeline.addLast("stomp-client-message-handler", new ClientMessageHandler(clientContext));
    pipeline.addLast("debug-client-tail", new DebugHandler("CLIENT_TAIL"));

    return pipeline;
  }
Beispiel #23
0
  protected SSLEngine initSocketSSLEngine(Socket socket) throws SSLException {
    SSLEngine engine = super.initSocketSSLEngine(socket);
    engine.setUseClientMode(false);

    switch (this.getSSLConfiguration().getClientAuthentication()) {
      case NONE:
        engine.setNeedClientAuth(false);
        engine.setWantClientAuth(false);
        break;
      case REQUEST:
        engine.setWantClientAuth(true);
        break;
      case REQUIRE:
        engine.setNeedClientAuth(true);
        break;
    }

    return engine;
  }
  private SSLEngine createSSLEngine(LDAPConnectionHandlerCfg config, SSLContext sslContext)
      throws DirectoryException {
    try {
      SSLEngine sslEngine = sslContext.createSSLEngine();
      sslEngine.setUseClientMode(false);

      final Set<String> protocols = config.getSSLProtocol();
      if (!protocols.isEmpty()) {
        sslEngine.setEnabledProtocols(protocols.toArray(new String[0]));
      }

      final Set<String> ciphers = config.getSSLCipherSuite();
      if (!ciphers.isEmpty()) {
        sslEngine.setEnabledCipherSuites(ciphers.toArray(new String[0]));
      }

      switch (config.getSSLClientAuthPolicy()) {
        case DISABLED:
          sslEngine.setNeedClientAuth(false);
          sslEngine.setWantClientAuth(false);
          break;
        case REQUIRED:
          sslEngine.setWantClientAuth(true);
          sslEngine.setNeedClientAuth(true);
          break;
        case OPTIONAL:
        default:
          sslEngine.setNeedClientAuth(false);
          sslEngine.setWantClientAuth(true);
          break;
      }

      return sslEngine;
    } catch (Exception e) {
      logger.traceException(e);
      ResultCode resCode = DirectoryServer.getServerErrorResultCode();
      LocalizableMessage message =
          ERR_CONNHANDLER_SSL_CANNOT_INITIALIZE.get(getExceptionMessage(e));
      throw new DirectoryException(resCode, message, e);
    }
  }
Beispiel #25
0
  /*
   * Constructor for a secure ChannelIO variant.
   */
  protected ChannelIOSecure(SocketChannel sc, boolean blocking, SSLContext sslc)
      throws IOException {
    super(sc, blocking);

    /*
     * We're a server, so no need to use host/port variant.
     *
     * The first call for a server is a NEED_UNWRAP.
     */
    sslEngine = sslc.createSSLEngine();
    sslEngine.setUseClientMode(false);
    initialHSStatus = HandshakeStatus.NEED_UNWRAP;
    initialHSComplete = false;

    // Create a buffer using the normal expected packet size we'll
    // be getting.  This may change, depending on the peer's
    // SSL implementation.
    netBBSize = sslEngine.getSession().getPacketBufferSize();
    inNetBB = ByteBuffer.allocate(netBBSize);
    outNetBB = ByteBuffer.allocate(netBBSize);
    outNetBB.position(0);
    outNetBB.limit(0);
  }
  @Override
  public ChannelPipeline getPipeline() throws Exception {
    // Create a default pipeline implementation.
    ChannelPipeline pipeline = pipeline();

    // Enable HTTPS if necessary.
    if (ssl) {
      SSLEngine engine = SecureChatSslContextFactory.getClientContext().createSSLEngine();
      engine.setUseClientMode(true);

      pipeline.addLast("ssl", new SslHandler(engine));
    }

    pipeline.addLast("codec", new HttpClientCodec());

    // Remove the following line if you don't want automatic content decompression.
    pipeline.addLast("inflater", new HttpContentDecompressor());

    // to be used since huge file transfer
    pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());

    pipeline.addLast("handler", new HttpUploadClientHandler());
    return pipeline;
  }
  @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());
  }
 @Override
 public void start() {
   eventLoopGroup = new NioEventLoopGroup(ioWorkerCount);
   eventExecutor = new NioEventLoopGroup(executorThreadCount);
   deployment.start();
   final RequestDispatcher dispatcher =
       new RequestDispatcher(
           (SynchronousDispatcher) deployment.getDispatcher(),
           deployment.getProviderFactory(),
           domain);
   // Configure the server.
   if (sslContext == null) {
     bootstrap
         .group(eventLoopGroup)
         .channel(NioServerSocketChannel.class)
         .childHandler(
             new ChannelInitializer<SocketChannel>() {
               @Override
               public void initChannel(SocketChannel ch) throws Exception {
                 ch.pipeline().addLast(new HttpRequestDecoder());
                 ch.pipeline().addLast(new HttpObjectAggregator(maxRequestSize));
                 ch.pipeline().addLast(new HttpResponseEncoder());
                 ch.pipeline()
                     .addLast(
                         new RestEasyHttpRequestDecoder(
                             dispatcher.getDispatcher(),
                             root,
                             RestEasyHttpRequestDecoder.Protocol.HTTP));
                 ch.pipeline().addLast(new CorsHeadersChannelHandler());
                 ch.pipeline().addLast(new RestEasyHttpResponseEncoder(dispatcher));
                 ch.pipeline().addLast(eventExecutor, new RequestHandler(dispatcher));
               }
             })
         .option(ChannelOption.SO_BACKLOG, backlog)
         .childOption(ChannelOption.SO_KEEPALIVE, true);
   } else {
     final SSLEngine engine = sslContext.createSSLEngine();
     engine.setUseClientMode(false);
     bootstrap
         .group(eventLoopGroup)
         .channel(NioServerSocketChannel.class)
         .childHandler(
             new ChannelInitializer<SocketChannel>() {
               @Override
               public void initChannel(SocketChannel ch) throws Exception {
                 ch.pipeline().addFirst(new SslHandler(engine));
                 ch.pipeline().addLast(new HttpRequestDecoder());
                 ch.pipeline().addLast(new HttpObjectAggregator(maxRequestSize));
                 ch.pipeline().addLast(new HttpResponseEncoder());
                 ch.pipeline()
                     .addLast(
                         new RestEasyHttpRequestDecoder(
                             dispatcher.getDispatcher(),
                             root,
                             RestEasyHttpRequestDecoder.Protocol.HTTPS));
                 ch.pipeline().addLast(new CorsHeadersChannelHandler());
                 ch.pipeline().addLast(new RestEasyHttpResponseEncoder(dispatcher));
                 ch.pipeline().addLast(eventExecutor, new RequestHandler(dispatcher));
               }
             })
         .option(ChannelOption.SO_BACKLOG, backlog)
         .childOption(ChannelOption.SO_KEEPALIVE, true);
   }
   bootstrap.bind(port).syncUninterruptibly();
 }
  @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());
  }
  @Test
  public void testSslEcho() throws Throwable {
    ServerBootstrap sb =
        new ServerBootstrap(newServerSocketChannelFactory(Executors.newCachedThreadPool()));
    ClientBootstrap cb =
        new ClientBootstrap(newClientSocketChannelFactory(Executors.newCachedThreadPool()));

    EchoHandler sh = new EchoHandler(true);
    EchoHandler ch = new EchoHandler(false);

    SSLEngine sse = SecureChatSslContextFactory.getServerContext().createSSLEngine();
    SSLEngine cse = SecureChatSslContextFactory.getClientContext().createSSLEngine();
    sse.setUseClientMode(false);
    cse.setUseClientMode(true);

    // Workaround for blocking I/O transport write-write dead lock.
    sb.setOption("receiveBufferSize", 1048576);
    sb.setOption("receiveBufferSize", 1048576);

    sb.getPipeline().addFirst("ssl", new SslHandler(sse));
    sb.getPipeline().addLast("handler", sh);
    cb.getPipeline().addFirst("ssl", new SslHandler(cse));
    cb.getPipeline().addLast("handler", ch);
    ExecutorService eventExecutor = null;
    if (isExecutorRequired()) {
      eventExecutor = new OrderedMemoryAwareThreadPoolExecutor(16, 0, 0);
      sb.getPipeline().addFirst("executor", new ExecutionHandler(eventExecutor));
      cb.getPipeline().addFirst("executor", new ExecutionHandler(eventExecutor));
    }

    Channel sc = sb.bind(new InetSocketAddress(0));
    int port = ((InetSocketAddress) sc.getLocalAddress()).getPort();

    ChannelFuture ccf = cb.connect(new InetSocketAddress(TestUtil.getLocalHost(), port));
    ccf.awaitUninterruptibly();
    if (!ccf.isSuccess()) {
      logger.error("Connection attempt failed", ccf.getCause());
      sc.close().awaitUninterruptibly();
    }
    assertTrue(ccf.isSuccess());

    Channel cc = ccf.getChannel();
    ChannelFuture hf = cc.getPipeline().get(SslHandler.class).handshake();
    hf.awaitUninterruptibly();
    if (!hf.isSuccess()) {
      logger.error("Handshake failed", hf.getCause());
      sh.channel.close().awaitUninterruptibly();
      ch.channel.close().awaitUninterruptibly();
      sc.close().awaitUninterruptibly();
    }

    assertTrue(hf.isSuccess());

    for (int i = 0; i < data.length; ) {
      int length = Math.min(random.nextInt(1024 * 64), data.length - i);
      cc.write(ChannelBuffers.wrappedBuffer(data, i, length));
      i += length;
    }

    while (ch.counter < data.length) {
      if (sh.exception.get() != null) {
        break;
      }
      if (ch.exception.get() != null) {
        break;
      }

      try {
        Thread.sleep(1);
      } catch (InterruptedException e) {
        // Ignore.
      }
    }

    while (sh.counter < data.length) {
      if (sh.exception.get() != null) {
        break;
      }
      if (ch.exception.get() != null) {
        break;
      }

      try {
        Thread.sleep(1);
      } catch (InterruptedException e) {
        // Ignore.
      }
    }

    sh.channel.close().awaitUninterruptibly();
    ch.channel.close().awaitUninterruptibly();
    sc.close().awaitUninterruptibly();
    cb.shutdown();
    sb.shutdown();
    cb.releaseExternalResources();
    sb.releaseExternalResources();

    if (eventExecutor != null) {
      eventExecutor.shutdown();
    }
    if (sh.exception.get() != null && !(sh.exception.get() instanceof IOException)) {
      throw sh.exception.get();
    }
    if (ch.exception.get() != null && !(ch.exception.get() instanceof IOException)) {
      throw ch.exception.get();
    }
    if (sh.exception.get() != null) {
      throw sh.exception.get();
    }
    if (ch.exception.get() != null) {
      throw ch.exception.get();
    }
  }