转SSL连接建立过程分析_第1页
转SSL连接建立过程分析_第2页
转SSL连接建立过程分析_第3页
转SSL连接建立过程分析_第4页
转SSL连接建立过程分析_第5页
已阅读5页,还剩28页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、.转 SSL连接建立过程分析 42.13 SSL_connect  SSL_connect这个函数完成SSL协商的客户端操作:/* ssl/ssl_lib.c */int SSL_connectSSL *s  if s->handshake_func = 0  /* Not properly initialized yet */  SSL_set_connect_states; returns->method->ssl_connects; 其中SSL_set_connect_states

2、函数初始化SSL协商处理:void SSL_set_connect_stateSSL *s / 客户端 s->server=0; s->shutdown=0;/ 初始化客户端状态值 s->state=SSL_ST_CONNECT|SSL_ST_BEFORE;/ 握手函数即是ssl_connect函数 s->handshake_func=s->method->ssl_connect; /* clear the current cipher */ 去除SSL读写加密算法上下文 ssl_clea

3、r_cipher_ctxs; 因此最重要的就是ssl_connect这两个成员函数,是前面SSLv23_client_method函数中定义的,如对于SSLv23方法,处理函数分别为ssl23_connect函数,其它SSLv2和SSLv3方法分别对应ssl2_connect和ssl3_connect,后两者就没有协商过程了,ssl23_connect实际在协商确定协议版本后也是调用ssl23_connect。掌握了服务器端的accept过程,理解客户端的connect过程就简单了。/* ssl/s23_clnt.c */int ssl23_connectSSL *s &#

4、160;BUF_MEM *buf=NULL; unsigned long Time=timeNULL; void *cbconst SSL *ssl,int type,int val=NULL; int ret= -1; int new_state,state;/ 和服务器端一样进行根本的初始化 RAND_add&Time,sizeofTime,0; ERR_clear_error; clear_sys_error; if s->info_callback != NULL  cb=

5、s->info_callback; else if s->ctx->info_callback != NULL  cb=s->ctx->info_callback; s->in_handshake+; if !SSL_in_inits | SSL_in_befores SSL_clears;  for ;    state=s->state;/ 在SSL_set_connect_state中s->state被初始化为SSL_ST_CONNECT|S

6、SL_ST_BEFORE  switchs->state     case SSL_ST_BEFORE:  case SSL_ST_CONNECT:  case SSL_ST_BEFORE|SSL_ST_CONNECT:  case SSL_ST_OK|SSL_ST_CONNECT:/ 进行根本初始化,分配缓冲区   if s->session != NULL     

7、60;  SSLerrSSL_F_SSL23_CONNECT,SSL_R_SSL23_DOING_SESSION_ID_REUSE;    ret= -1;    goto end;       s->server=0;   if cb != NULL cbs,SSL_CB_HANDSHAKE_START,1;   /* s->version=TLS1_V

8、ERSION; */   s->type=SSL_ST_CONNECT;   if s->init_buf = NULL        if buf=BUF_MEM_new = NULL          ret= -1;     goto end;    

9、     if !BUF_MEM_growbuf,SSL3_RT_MAX_PLAIN_LENGTH          ret= -1;     goto end;         s->init_buf=buf;    buf=NULL;  &

10、#160;    if !ssl3_setup_bufferss ret= -1; goto end;    ssl3_init_finished_macs;/ SSL客户端状态转为准备发送HELLO信息   s->state=SSL23_ST_CW_CLNT_HELLO_A;   s->ctx->stats.sess_connect+;   s->init_num=0;   bre

11、ak;  case SSL23_ST_CW_CLNT_HELLO_A:  case SSL23_ST_CW_CLNT_HELLO_B:/ 发送客户端的HELLO信息   s->shutdown=0;   ret=ssl23_client_hellos;   if ret <= 0 goto end;/ 转为准备接收服务器端的HELLO状态   s->state=SSL23_ST_CR_SRVR_HELLO_A;

12、0;  s->init_num=0;   break;  case SSL23_ST_CR_SRVR_HELLO_A:  case SSL23_ST_CR_SRVR_HELLO_B:/ 读取服务器端的HELLO信息,完成SSL握手协商   ret=ssl23_get_server_hellos;   if ret >= 0 cb=NULL;   goto end;   /*

13、break; */  default:   SSLerrSSL_F_SSL23_CONNECT,SSL_R_UNKNOWN_STATE;   ret= -1;   goto end;   /* break; */     if s->debug voidBIO_flushs->wbio;   if cb != NULL && s->state != st

14、ate      new_state=s->state;   s->state=state;   cbs,SSL_CB_CONNECT_LOOP,1;   s->state=new_state;     end: s->in_handshake-; if buf != NULL  BUF_MEM_freebuf; if cb

15、 != NULL  cbs,SSL_CB_CONNECT_EXIT,ret; returnret;  ssl23_client_hello函数发送客户端的HELLO信息:/* ssl/s23_clnt.c */static int ssl23_client_helloSSL *s  unsigned char *buf; unsigned char *p,*d; int i,ch_len; int ret; buf=unsigned char *s->init_buf->d

16、ata; if s->state = SSL23_ST_CW_CLNT_HELLO_A  / 准备发送HELLO, 构造发送缓冲区的数据,数据格式见SSL_accept一节中的说明  p=s->s3->client_random;  RAND_pseudo_bytesp,SSL3_RANDOM_SIZE;  /* Do the message type and length last */  d= &buf2;/ p指向SSL握手记录头11字节长后的第一字节处

17、  p=d+9;/ 消息类型  *d+=SSL2_MT_CLIENT_HELLO;/ 填写客户端版本号  if !s->options & SSL_OP_NO_TLSv1      *d+=TLS1_VERSION_MAJOR;   *d+=TLS1_VERSION_MINOR;   s->client_version=TLS1_VERSION;    &#

18、160;else if !s->options & SSL_OP_NO_SSLv3      *d+=SSL3_VERSION_MAJOR;   *d+=SSL3_VERSION_MINOR;   s->client_version=SSL3_VERSION;     else if !s->options & SSL_OP_NO_SSLv2    &#

19、160; *d+=SSL2_VERSION_MAJOR;   *d+=SSL2_VERSION_MINOR;   s->client_version=SSL2_VERSION;     else      SSLerrSSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_PROTOCOLS_AVAILABLE;   return-1;   

20、;/ 填写cipher_specs信息  /* Ciphers supported */  i=ssl_cipher_list_to_bytess,SSL_get_cipherss,p;  if i = 0      /* no ciphers */   SSLerrSSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE;   return-1;  

21、   s2ni,d;  p+=i;/ 填写会话ID  /* put in the session-id, zero since there is no   * reuse. */  s2n0,d;  if s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG   ch_len=SSL2_CHALLENGE_LENGTH;  else   ch

22、_len=SSL2_MAX_CHALLENGE_LENGTH;/ 填写挑战信息  /* write out sslv2 challenge */  if SSL3_RANDOM_SIZE < ch_len   i=SSL3_RANDOM_SIZE;  else   i=ch_len;  s2ni,d;  memset&s->s3->client_random0,0,SSL3_RANDOM_SIZE; 

23、 RAND_pseudo_bytes&s->s3->client_randomSSL3_RANDOM_SIZE-i,i;  memcpyp,&s->s3->client_randomSSL3_RANDOM_SIZE-i,i;  p+=i;/ 数据长度  i= p- &buf2;  buf0=i>>8&0xff|0x80;  buf1=i&0xff;/ 数据完成,状态转为HELLO B准备发送 

24、0;s->state=SSL23_ST_CW_CLNT_HELLO_B;  /* number of bytes to write */  s->init_num=i+2;  s->init_off=0;  ssl3_finish_macs,&buf2,i;   /* SSL3_ST_CW_CLNT_HELLO_B */ 发送HELLO数据 ret = ssl23_write_bytess; if ret >= 2 

25、0;if s->msg_callback   s->msg_callback1, SSL2_VERSION, 0, s->init_buf->data+2, ret-2, s, s->msg_callback_arg; /* CLIENT-HELLO */ return ret; ssl23_get_server_hello接收服务器端的回应,识别服务器的SSL版本,最后再相应调用ssl2_connect或ssl3_connect函数。/* ssl/s23_clnt.c */static int ssl23_get

26、_server_helloSSL *s  char buf8; unsigned char *p; int i; int n;/ 读7字节的服务器端数据 n=ssl23_read_bytess,7; if n != 7 returnn; p=s->packet; memcpybuf,p,n; if p0 & 0x80 && p2 = SSL2_MT_SERVER_HELLO &&  p5 = 0x00 && p6

27、= 0x02  / 服务器是SSL2版本#ifdef OPENSSL_NO_SSL2  SSLerrSSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL;  goto err;#else  /* we are talking sslv2 */  /* we need to clean up the SSLv3 setup and put in the   * sslv2 stuff. */  int

28、 ch_len;  if s->options & SSL_OP_NO_SSLv2      SSLerrSSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL;   goto err;   / 初始化SSL结构中的SSL2支持,ssl_connect将为ssl2_connect  if s->s2 = NULL    &

29、#160; if !ssl2_news    goto err;     else   ssl2_clears;  if s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG   ch_len=SSL2_CHALLENGE_LENGTH;  else   ch_len=SSL2_MAX_CHALLENGE_LENGTH;&

30、#160; /* write out sslv2 challenge */  i=SSL3_RANDOM_SIZE < ch_len   ?SSL3_RANDOM_SIZE:ch_len;  s->s2->challenge_length=i;  memcpys->s2->challenge,   &s->s3->client_randomSSL3_RANDOM_SIZE-i,i;  if s-&

31、gt;s3 != NULL ssl3_frees;  if !BUF_MEM_grow_cleans->init_buf,   SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER      SSLerrSSL_F_SSL23_GET_SERVER_HELLO,ERR_R_BUF_LIB;   goto err;     s->state=SSL2_ST_GET_SERVER

32、_HELLO_A;  if !s->client_version = SSL2_VERSION   /* use special padding SSL 3.0 draft/RFC 2246, App. E.2 */   s->s2->ssl2_rollback=1;  /* setup the 5 bytes we have read so we get them from   * the sslv2 buffer */  s->

33、rstate=SSL_ST_READ_HEADER;  s->packet_length=n;  s->packet= &s->s2->rbuf0;  memcpys->packet,buf,n;  s->s2->rbuf_left=n;  s->s2->rbuf_offs=0;  /* we have already written one */  s->s2->write_seq

34、uence=1;  s->method=SSLv2_client_method;  s->handshake_func=s->method->ssl_connect;#endif   else if p0 = SSL3_RT_HANDSHAKE &&   p1 = SSL3_VERSION_MAJOR &&   p2 = SSL3_VERSION_MINOR |    p2 = TLS1_VERSIO

35、N_MINOR &&   p5 = SSL3_MT_SERVER_HELLO  / 服务器版本为SSL3或TLS1,ssl_connect将为ssl3_connect  /* we have sslv3 or tls1 */  if !ssl_init_wbio_buffers,1 goto err;  /* we are in this state */  s->state=SSL3_ST_CR_SRVR_HELLO_A;  /*

36、put the 5 bytes we have read into the input buffer   * for SSLv3 */  s->rstate=SSL_ST_READ_HEADER;  s->packet_length=n;  s->packet= &s->s3->rbuf.buf0;  memcpys->packet,buf,n;  s->s3->rbuf.left=n;  s->

37、;s3->rbuf.offset=0;  if p2 = SSL3_VERSION_MINOR &&   !s->options & SSL_OP_NO_SSLv3      s->version=SSL3_VERSION;   s->method=SSLv3_client_method;     else if p2 = TLS1_VERSION_MINOR

38、 &&   !s->options & SSL_OP_NO_TLSv1      s->version=TLS1_VERSION;   s->method=TLSv1_client_method;     else      SSLerrSSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTE

39、D_PROTOCOL;   goto err;        s->handshake_func=s->method->ssl_connect;   else if p0 = SSL3_RT_ALERT &&   p1 = SSL3_VERSION_MAJOR &&   p2 = SSL3_VERSION_MINOR |    p2 =

40、TLS1_VERSION_MINOR &&   p3 = 0 &&   p4 = 2  / SSL告警信息  void *cbconst SSL *ssl,int type,int val=NULL;  int j;  /* An alert */  if s->info_callback != NULL   cb=s->info_callback;  else

41、if s->ctx->info_callback != NULL   cb=s->ctx->info_callback;   i=p5;  if cb != NULL      j=i<<8|p6;   cbs,SSL_CB_READ_ALERT,j;     s->rwstate=SSL_NOTHING;  SSL

42、errSSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p6;  goto err;   else    SSLerrSSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNKNOWN_PROTOCOL;  goto err;   s->init_num=0; /* Since, if we are sending a ssl23 client hello, we are

43、not  * reusing a session-id */ if !ssl_get_new_sessions,0  goto err; s->first_packet=1;/ 递归调用SSL_connect,实际将执行ssl2_connect或ssl3_connect returnSSL_connects;err: return-1;  举例ssl3_conect函数定义如下,ssl2_connect就不分析了:/* ssl/s3_clnt.c */int ssl3_connectSSL *s&#

44、160; BUF_MEM *buf=NULL; unsigned long Time=timeNULL,l; long num1; void *cbconst SSL *ssl,int type,int val=NULL; int ret= -1; int new_state,state,skip=0;/ 对SSL3连接的初始化 RAND_add&Time,sizeofTime,0; ERR_clear_error; clear_sys_error; if s->info_call

45、back != NULL  cb=s->info_callback; else if s->ctx->info_callback != NULL  cb=s->ctx->info_callback;  s->in_handshake+; if !SSL_in_inits | SSL_in_befores SSL_clears;  for ;    state=s->state;  switchs->

46、state     case SSL_ST_RENEGOTIATE:/ 重协商的话从头开场, 注意break是注释掉的   s->new_session=1;   s->state=SSL_ST_CONNECT;   s->ctx->stats.sess_connect_renegotiate+;   /* break */ 初始状态应该是SSL_ST_BEFORE|SSL_ST_CONNECT

47、0; case SSL_ST_BEFORE:  case SSL_ST_CONNECT:  case SSL_ST_BEFORE|SSL_ST_CONNECT:  case SSL_ST_OK|SSL_ST_CONNECT:/ server=0表示是客户端   s->server=0;   if cb != NULL cbs,SSL_CB_HANDSHAKE_START,1;/ 假设本地版本不是SSL3那么出错   if s-&g

48、t;version & 0xff00 != 0x0300        SSLerrSSL_F_SSL3_CONNECT, ERR_R_INTERNAL_ERROR;    ret = -1;    goto end;       /* s->version=SSL3_VERSION; */   s->type=SSL

49、_ST_CONNECT;/ 初始化连接缓冲区   if s->init_buf = NULL        if buf=BUF_MEM_new = NULL          ret= -1;     goto end;         if

50、 !BUF_MEM_growbuf,SSL3_RT_MAX_PLAIN_LENGTH          ret= -1;     goto end;         s->init_buf=buf;    buf=NULL;       if

51、!ssl3_setup_bufferss ret= -1; goto end;    /* setup buffing BIO */   if !ssl_init_wbio_buffers,0 ret= -1; goto end;    /* don't push the buffering BIO quite yet */   ssl3_init_finished_macs;/ 准备发送HELLO信息   s->state=SSL

52、3_ST_CW_CLNT_HELLO_A;   s->ctx->stats.sess_connect+;   s->init_num=0;   break;  case SSL3_ST_CW_CLNT_HELLO_A:  case SSL3_ST_CW_CLNT_HELLO_B:/ 该状态发送客户端SSL3信息   s->shutdown=0;   ret=ssl3_client_h

53、ellos;   if ret <= 0 goto end;/ 发送成功,状态转为准备接收服务器的HELLO回应   s->state=SSL3_ST_CR_SRVR_HELLO_A;   s->init_num=0;   /* turn on buffering for the next lot of output */   if s->bbio != s->wbio    

54、s->wbio=BIO_pushs->bbio,s->wbio;   break;  case SSL3_ST_CR_SRVR_HELLO_A:  case SSL3_ST_CR_SRVR_HELLO_B:/ 该状态下接收服务器发送的HELLO信息   ret=ssl3_get_server_hellos;   if ret <= 0 goto end;   if s->hit/ 假设是reuse的连接,状

55、态转为接收结束    s->state=SSL3_ST_CR_FINISHED_A;   else/ 否那么状态转为准备接收服务器的证书    s->state=SSL3_ST_CR_CERT_A;   s->init_num=0;   break;  case SSL3_ST_CR_CERT_A:  case SSL3_ST_CR_CERT_B:/ 该状态下接收服务器

56、发送的证书   /* Check if it is anon DH */   if !s->s3->tmp.new_cipher->algorithms & SSL_aNULL        ret=ssl3_get_server_certificates;    if ret <= 0 goto end;      

57、0;else    skip=1;/ 状态转为接收密钥交换信息   s->state=SSL3_ST_CR_KEY_EXCH_A;   s->init_num=0;   break;  case SSL3_ST_CR_KEY_EXCH_A:  case SSL3_ST_CR_KEY_EXCH_B:/ 该状态下接收密钥交换信息   ret=ssl3_get_key_exchanges;&

58、#160;  if ret <= 0 goto end;/ 状态转为接收证书请求   s->state=SSL3_ST_CR_CERT_REQ_A;   s->init_num=0;   /* at this point we check that we have the    * required stuff from the server */   if !ssl3_check_cert_and_algo

59、rithms        ret= -1;    goto end;       break;  case SSL3_ST_CR_CERT_REQ_A:  case SSL3_ST_CR_CERT_REQ_B:/ 该状态下接收服务器的证书请求   ret=ssl3_get_certificate_requests;  

60、; if ret <= 0 goto end;   s->state=SSL3_ST_CR_SRVR_DONE_A;   s->init_num=0;   break;  case SSL3_ST_CR_SRVR_DONE_A:  case SSL3_ST_CR_SRVR_DONE_B:/ 该状态下接收服务器信息结束   ret=ssl3_get_server_dones;   

61、if ret <= 0 goto end;   if s->s3->tmp.cert_req/ 发送客户端证书    s->state=SSL3_ST_CW_CERT_A;   else/ 发送密钥交换信息    s->state=SSL3_ST_CW_KEY_EXCH_A;   s->init_num=0;   break;  case S

62、SL3_ST_CW_CERT_A:  case SSL3_ST_CW_CERT_B:  case SSL3_ST_CW_CERT_C:  case SSL3_ST_CW_CERT_D:/ 该状态下发送客户端证书   ret=ssl3_send_client_certificates;   if ret <= 0 goto end;/ 状态转为发送密钥交换信息   s->state=SSL3_ST_CW_KEY_EXCH_A; 

63、;  s->init_num=0;   break;  case SSL3_ST_CW_KEY_EXCH_A:  case SSL3_ST_CW_KEY_EXCH_B:/ 该状态下发送密钥交换信息   ret=ssl3_send_client_key_exchanges;   if ret <= 0 goto end;/ 加密算法   l=s->s3->tmp.new_cipher->a

64、lgorithms;   /* EAY EAY EAY need to check for DH fix cert    * sent back */   /* For TLS, cert_req is set to 2, so a cert chain    * of nothing is sent, but no verify packet is sent */   if s->s3->tmp.cert_req = 1 

65、   / 发送证书验证    s->state=SSL3_ST_CW_CERT_VRFY_A;       else    / TLS, 不用发送证书认证信息,直接转为修改算法状态    s->state=SSL3_ST_CW_CHANGE_A;    s->s3->change_cipher_spec=0;

66、60;      s->init_num=0;   break;  case SSL3_ST_CW_CERT_VRFY_A:  case SSL3_ST_CW_CERT_VRFY_B:/ 该状态发送证书验证信息   ret=ssl3_send_client_verifys;   if ret <= 0 goto end;/ 状态转为发送修改算法信息   s->

67、state=SSL3_ST_CW_CHANGE_A;   s->init_num=0;   s->s3->change_cipher_spec=0;   break;  case SSL3_ST_CW_CHANGE_A:  case SSL3_ST_CW_CHANGE_B:/ 该状态下发送修改算法信息   ret=ssl3_send_change_cipher_specs,    

68、;SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B;   if ret <= 0 goto end;/ 状态转为发送结束   s->state=SSL3_ST_CW_FINISHED_A;   s->init_num=0;/ 设置会话加密算法   s->session->cipher=s->s3->tmp.new_cipher;   if s->s3->tmp.n

69、ew_compression = NULL    s->session->compress_meth=0;   else    s->session->compress_meth=     s->s3->tmp.new_compression->id;   if !s->method->ssl3_enc->setup_key_blocks 

70、;       ret= -1;    goto end;       if !s->method->ssl3_enc->change_cipher_states,    SSL3_CHANGE_CIPHER_CLIENT_WRITE        ret= -1; &#

71、160;  goto end;       break;  case SSL3_ST_CW_FINISHED_A:  case SSL3_ST_CW_FINISHED_B:/ 该状态下发送协商结束信息   ret=ssl3_send_finisheds,    SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,    s

72、->method->ssl3_enc->client_finished_label,    s->method->ssl3_enc->client_finished_label_len;   if ret <= 0 goto end;/ 转为刷新写缓冲状态   s->state=SSL3_ST_CW_FLUSH;   /* clear flags */   s->s3->fla

73、gs&= SSL3_FLAGS_POP_BUFFER;   if s->hit    / 假设是reuse的会话, FLUSH后的下一个状态转为协商成功    s->s3->tmp.next_state=SSL_ST_OK;    if s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED      

74、    s->state=SSL_ST_OK;     s->s3->flags|=SSL3_FLAGS_POP_BUFFER;     s->s3->delay_buf_pop_ret=0;            else    / 否那么状态转为准备接收服务器的协商

75、结束信息    s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;       s->init_num=0;   break;  case SSL3_ST_CR_FINISHED_A:  case SSL3_ST_CR_FINISHED_B:/ 该状态接收服务器发送的协商结束信息   ret=ssl3_get_finisheds,S

76、SL3_ST_CR_FINISHED_A,    SSL3_ST_CR_FINISHED_B;   if ret <= 0 goto end;   if s->hit/ 假设会话是reuse的,状态转为发送算法    s->state=SSL3_ST_CW_CHANGE_A;   else/ 否那么协商成功    s->state=SSL_ST_OK;   s->init_num=0;   break;  case SSL3_ST_CW_FLUSH:/ 该状态下刷新写缓冲区   /* number of bytes to be flushed */   num1=BIO_ctrls->wbi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论