前面已经讲解了BIO通道的整体流程,对于SSL的流程是插在通道中的,在BIO通道的初始化的时候,根据Connector配置的SSLEnabled属性进行SSL的逻辑。

主要集中的位置在JIOEndpoint的bind方法中:
i.BIO方式的SSL通道流程-LMLPHP
这个特殊的ServerSocketFactory是SSLServerSocketFactory,我们看看其工厂创建之前做了什么内容,具体分解一下上述的这一行的代码:
i.BIO方式的SSL通道流程-LMLPHP
左侧是Tomcat的类,Tomcat类中有两套SSL的实现,一套就是JSSEImplement,也就是基于JSSE的(另外一套是APR集成openssl的),因此这个默认就走的是JSSEImplementation,这个实例可以进行切换并设置到协议Handler中。
对于JSSEImplementation的实现,其主要是JSSESocketFactory,这个类的主要作用就是和JSSE框架进行集成,并将server.xml中的Connector的SSL相关配置,传递到JSSE的类中,最后实例化出SSLServerSocketFactory,返回给JIOEndpoint的bind方法。

主要初始化在init方法中,可以归纳为下面的几个步骤:
1.基于Connector配置的协议,实例化SSLContext
i.BIO方式的SSL通道流程-LMLPHP

2.初始化Keystore和TrustStore
i.BIO方式的SSL通道流程-LMLPHP

3.将Keystore作为参数传给KeyManagerFactory,并获得KeyManager
i.BIO方式的SSL通道流程-LMLPHP
对于TrustStore,也是同样的方式传入进去,最后获得TrustManager

4.将KeyManager,TrustManager作为参数,调用SSLContext.init


i.BIO方式的SSL通道流程-LMLPHP

5.配置Tomcat的SSLSessionContext

i.BIO方式的SSL通道流程-LMLPHP


6.基于SSLContext获得SSLSeverSocketFactory
i.BIO方式的SSL通道流程-LMLPHP

7.根据Connector配置的cipers,与SSLContext默认的cipers取交集
i.BIO方式的SSL通道流程-LMLPHP

8.根据Connector配置的enableprotocol,与SSLContext默认的protocol取交集

这一步和上面的一步的思路是一样的,也是取二者支持的协议的一个交集:
i.BIO方式的SSL通道流程-LMLPHP

对于第7,8两步中得出的取完交集的enabledProtocol和enabledCipersuits,需要在最后一步,生成SSLServerSocket的时候进行设置

9.最后进行checkconfig,基于前面的配置进行检验
i.BIO方式的SSL通道流程-LMLPHP

需要注意的是,有几个属性需要在初始化SSLServerSocket的时候设置进去,可以看一下initserverSocket方法:
i.BIO方式的SSL通道流程-LMLPHP
一共是4个属性,enabledProtocol和enabledCipersuits,还有客户端的双向认证clientAuth,和只有JDK8支持的ciper顺序.

到此为止,整个SSL通道BIO的部分实现基本逻辑就完了,后续就是基于SSLServerSocket进行编程了,JSSE已经将SSL整个握手协议各种过程都封装起来了,和ServerSocket的程序区别不是很大。

总结
BIO方式的SSL逻辑的实现,也就是如果产生SSLServerSocket的,在这个过程中一共分成9个步骤,每一个步骤都调用JSSE的接口,将Tomcat的配置作为参数传递进去,在生成SSLServerSocket后,后续的操作就是基于socket编程了,和BIO的普通socket没有任何的区别。

04-16 04:57