1、概述

DTLS即Datagram Transport Layer Security (RFC4347),AP加入AC前,先进行DTLS验证,当AP与AC之间的DTLS握手成功后,AP发出Join请求开始请求加入。这个过程里面的所有报文均为加密报文。以下为报文格式(摘自RFC5418):

                       

在我们的代码中是在CWWTPEnterJoin()函数中来实现的。

2、代码分析

主要的函数以下几个过程:

CWStateTransition CWWTPEnterJoin() {

    //初始化socket  gWTPSocket

    /* Init DTLS session */

    if(!CWErr(CWNetworkInitSocketClient(&gWTPSocket,

                        &(gACInfoPtr->preferredAddress))) ) {

       

        timer_rem(waitJoinTimer, NULL);

        return CW_ENTER_DISCOVERY;

    }

 

#ifndef CW_NO_DTLS

    if(gACInfoPtr->security == CW_X509_CERTIFICATE) {//需要授权书

        if(!CWErr(CWSecurityInitContext(&gWTPSecurityContext,//初始化wtp本地加密策略

                        "root.pem",

                        "client.pem",

                        "prova",

                        CW_TRUE,

                        NULL)))

    }

#endif

    CWThread thread_receiveFrame;

    if(!CWErr(CWCreateThread(&thread_receiveFrame, //开启接受dtls数据的线程

                 CWWTPReceiveDtlsPacket,

                 (void*)gWTPSocket)))

   

#ifndef CW_NO_DTLS

 

    if(!CWErr(CWSecurityInitSessionClient(gWTPSocket,//初始化DTSL会话

                          &(gACInfoPtr->preferredAddress),

                          gPacketReceiveList,

                          gWTPSecurityContext,

                          &gWTPSession,

                          &gWTPPathMTU)))

   

    if(!CWErr(CWWTPSendAcknowledgedPacket(seqNum, //发起Join 会话请求。

                          NULL,

                          CWAssembleJoinRequest,

                          (void*)CWParseJoinResponseMessage,

                          (void*)CWSaveJoinResponseMessage,

                          &values)))

 

 

    CWLog("Join Completed");

   

    return CW_ENTER_CONFIGURE;

}

DTSL会话初始化主要在CWSecurityInitSessionClient中完成。

3DTLS 握手

根据协议介绍,DTLS 握手包含如下几个步骤:

  1. WTP首先发送一个ClientHello消息来发起握手,说明它支持的密码算法列表、压缩方法及最高协议版本和其他一些需要的消息。
  2. AC回复一个HelloVerifyReuqest 消息,client必须重传添加了cookie的ClientHello。server然后验证cookie,如果有效的话才开始进行握手。
  3. AC回应一个ServerHello消息,包含服务器选择的连接参数,源自客户端初期所提供的ClientHello,确定了这次通信所需要的算法,然后发过去自己的证书(里面包含了身份和自己的公钥)。
  4. Client在收到这个消息后会生成一个秘密消息,用SSL服务器的公钥加密后传过去,SSL服务器端用自己的私钥解密后,会话密钥协商成功,双方可以用同一份会话密钥来通信了。

而在我们的代码中,

CWDebugLog("Before HS");

    CWSecurityManageSSLError(SSL_do_handshake(*sessionPtr),

                 *sessionPtr,

                 SSL_free(*sessionPtr););

    CWDebugLog("After HS");

   

    if (SSL_get_verify_result(*sessionPtr) == X509_V_OK) {

 

        CWDebugLog("Certificate Verified");

    } else {

 

        CWDebugLog("Certificate Error (%d)",

               SSL_get_verify_result(*sessionPtr));

}

 

总结:

DTLS 握手是通过SSL_do_handshake这个函数来实现的,而在我们上次的调试过程中发现也是这个地方出错。但是这个函数是openSSL加密库的函数,在openCawwap中没有实现。

posted on 2013-09-05 18:55  物联互通  阅读(2307)  评论(5编辑  收藏  举报