zoukankan      html  css  js  c++  java
  • Qt中调用PolarSSL库(一)

         最近一直在学习SSL相关的知识,也是先了解理论相关的知识,主要是SSL相关的基本概念和连接建立过程,主要是基于PolarSSL开源库进行学习。学习完了之后就希望能给有所运用,就想用Qt写一个简单的程序,增加对SSL相关概念的把握和对PolarSSL库的运用。当然,最终希望是可以使用Qt做一个比较完善的工具,帮助大家更好的理解和学习SSL相关知识。这都是后话,在第一篇里面,我们就简单用例子展示如何在Qt里面调用PolarSSL库。

    这篇博客主要是讲解Qt里面调用PolarSSL库,至于SSL相关概念在后面的博客再详细介绍。

    SSL握手需要客户端和服务器端交互,这里我们分别介绍。

    1、编译PolarSSL库

    我们准备使用的方式就是编译PolarSSL为.a静态库,然后在Qt中连接,使用的PolarSSL的版本是0.10.1。

    下载对应的软件版本,解压缩后在library目录下执行make即可生成libpolarssl.a库文件,如下图:

    2、服务器端

    使用Qt设计一个简单的界面,在按钮的槽函数中进行相关的操作,也就是调用PolarSSL库函数进行编程,初始化ssl相关结构体,监听端口,等等。

    SSL中最重要的就是执行握手操作。这里需要注意一点,由于涉及到socket编程,像accept函数都是阻塞的,如果在gui主线程中调用会造成界面冻结,也就是我们常说的ANR。解决方法就是将这些操作放在一个线程中,Qt中创建一个线程比较容易,创建一个类,继承自QThread,实现run函数,即可,最后启动线程也比较简单,调用该类的start()

    函数即可。好了,不多说了,上代码,首先看看服务器端的代码结构:workThread即是线程,实现SSL相关的功能,监听套接字,实现SSL握手,读取客户端发来的消息,向客户端发送消息。

    mianwindow即是主窗口界面,有个按钮,在按钮的槽函数中启动线程

    代码:

    工程文件:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. #-------------------------------------------------  
    2. #  
    3. # Project created by QtCreator 2014-05-11T22:28:07  
    4. #  
    5. #-------------------------------------------------  
    6.   
    7. QT       += core gui  
    8.   
    9. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets  
    10.   
    11. TARGET = MyPolarSSLToolSrv  
    12. TEMPLATE = app  
    13.   
    14. INCLUDEPATH += /home/chenlong12580/develop/polarTool/polarssl/include  
    15. LIBS += -L "/home/chenlong12580/develop/polarTool/polarssl/lib/" -lpolarssl  
    16.   
    17. SOURCES += main.cpp  
    18.         widget.cpp   
    19.     workthread.cpp  
    20.   
    21. HEADERS  += widget.h   
    22.     workthread.h  
    23.   
    24. FORMS    += widget.ui  


    线程类:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. void WorkThread::run()  
    2. {  
    3.     qDebug() << "I am a thread!";  
    4.   
    5.     int listen_fd = 0;  
    6.     int client_fd =0;  
    7.     int ret= 0;  
    8.     havege_state hs;  
    9.     ssl_context ssl;  
    10.     ssl_session ssn;  
    11.     x509_cert srvcert;  
    12.     rsa_context rsa;  
    13.     unsigned char buf[1024];  
    14.     int len = 0;  
    15.   
    16.     memset( &srvcert, 0, sizeof( x509_cert ) );  
    17.   
    18.     ret = x509parse_crt( &srvcert, (unsigned char *) test_srv_crt,  
    19.                          strlen( test_srv_crt ) );  
    20.     if( ret != 0 )  
    21.     {  
    22.         printf( " failed   !  x509parse_crt returned %d ", ret );  
    23.         return;  
    24.     }  
    25.   
    26.     ret = x509parse_crt( &srvcert, (unsigned char *) test_ca_crt,  
    27.                          strlen( test_ca_crt ) );  
    28.     if( ret != 0 )  
    29.     {  
    30.         printf( " failed   !  x509parse_crt returned %d ", ret );  
    31.         return;  
    32.     }  
    33.   
    34.     ret =  x509parse_key( &rsa, (unsigned char *) test_srv_key,  
    35.                           strlen( test_srv_key ), NULL, 0 );  
    36.     if( ret != 0 )  
    37.     {  
    38.         printf( " failed   !  x509parse_key returned %d ", ret );  
    39.         return;  
    40.     }  
    41.   
    42.     ret = net_bind( &listen_fd, NULL, 8443 );  
    43.     if (0 != ret)  
    44.     {  
    45.         qDebug() << ret;  
    46.         return;  
    47.     }  
    48.   
    49.     qDebug() << "bind ok";  
    50.   
    51.     /* socket is block */  
    52.     ret = net_accept( listen_fd, &client_fd, NULL );  
    53.     if (0 != ret)  
    54.     {  
    55.         return;  
    56.     }  
    57.   
    58.     qDebug() << "accept ok";  
    59.   
    60.     havege_init( &hs );  
    61.   
    62.     ret = ssl_init( &ssl );  
    63.     if (0 != ret)  
    64.     {  
    65.         return;  
    66.     }  
    67.   
    68.     ssl_set_endpoint( &ssl, SSL_IS_SERVER );  
    69.     ssl_set_authmode( &ssl, SSL_VERIFY_NONE );  
    70.   
    71.     ssl_set_rng( &ssl, havege_rand, &hs );  
    72.     ssl_set_dbg( &ssl, my_debug, stdout );  
    73.     ssl_set_bio( &ssl, net_recv, &client_fd,  
    74.                  net_send, &client_fd );  
    75.     ssl_set_scb( &ssl, my_get_session,  
    76.                  my_set_session );  
    77.   
    78.     ssl_set_ciphers( &ssl, my_ciphers );  
    79.     ssl_set_session( &ssl, 1, 0, &ssn );  
    80.   
    81.     memset( &ssn, 0, sizeof( ssl_session ) );  
    82.   
    83.     ssl_set_ca_chain( &ssl, srvcert.next, NULL );  
    84.     ssl_set_own_cert( &ssl, &srvcert, &rsa );  
    85.     ssl_set_dh_param( &ssl, my_dhm_P, my_dhm_G );  
    86.   
    87.     qDebug() << "before ssl_handshake ok";  
    88.   
    89.     while( ( ret = ssl_handshake( &ssl ) ) != 0 )  
    90.     {  
    91.         ;  
    92.     }  
    93.   
    94.     qDebug() << "ssl_handshake ok";  
    95.   
    96.     do  
    97.     {  
    98.         len = sizeof( buf ) - 1;  
    99.         memset( buf, 0, sizeof( buf ) );  
    100.         ret = ssl_read( &ssl, buf, len );  
    101.   
    102.         if( ret == POLARSSL_ERR_NET_TRY_AGAIN )  
    103.             continue;  
    104.   
    105.         if( ret <= 0 )  
    106.         {  
    107.             switch( ret )  
    108.             {  
    109.             case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY:  
    110.                 printf( " connection was closed gracefully " );  
    111.                 break;  
    112.   
    113.             case POLARSSL_ERR_NET_CONN_RESET:  
    114.                 printf( " connection was reset by peer " );  
    115.                 break;  
    116.   
    117.             default:  
    118.                 printf( " ssl_read returned %d ", ret );  
    119.                 break;  
    120.             }  
    121.   
    122.             break;  
    123.         }  
    124.   
    125.         len = ret;  
    126.         printf( " %d bytes read %s", len, (char *) buf );  
    127.     }while( 0 );  
    128.   
    129.     char *cc = (char *)buf;  
    130.     QString ss(cc);  
    131.   
    132.     qDebug() << ss;  
    133.   
    134.     (void)sprintf( (char *) buf, HTTP_RESPONSE,  
    135.                        ssl_get_cipher( &ssl ) );  
    136.   
    137.     while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 )  
    138.     {  
    139.         if( ret == POLARSSL_ERR_NET_CONN_RESET )  
    140.         {  
    141.             printf( " failed   ! peer closed the connection " );  
    142.             return;  
    143.         }  
    144.   
    145.         if( ret != POLARSSL_ERR_NET_TRY_AGAIN )  
    146.         {  
    147.             printf( " failed   ! ssl_write returned %d ", ret );  
    148.             return;  
    149.         }  
    150.     }  
    151.   
    152.     ssl_close_notify( &ssl );  
    153.   
    154.     net_close( client_fd );  
    155.     x509_free( &srvcert );  
    156.     rsa_free( &rsa );  
    157.     ssl_free( &ssl );  
    158.   
    159.     cur = s_list_1st;  
    160.     while( cur != NULL )  
    161.     {  
    162.         prv = cur;  
    163.         cur = cur->next;  
    164.         memset( prv, 0, sizeof( ssl_session ) );  
    165.         free( prv );  
    166.     }  
    167.   
    168.     memset( &ssl, 0, sizeof( ssl_context ) );  
    169. }  


    主窗口类:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. #include "widget.h"  
    2. #include "ui_widget.h"  
    3. #include <QFileDialog>  
    4. #include <QDebug>  
    5. #include <QMessageBox>  
    6. #include "workthread.h"  
    7. #include "polarssl/havege.h"  
    8. #include "polarssl/certs.h"  
    9. #include "polarssl/x509.h"  
    10. #include "polarssl/ssl.h"  
    11. #include "polarssl/net.h"  
    12.   
    13. Widget::Widget(QWidget *parent) :  
    14.     QWidget(parent),  
    15.     ui(new Ui::Widget)  
    16. {  
    17.     ui->setupUi(this);  
    18.   
    19.     qDebug() << "server";  
    20.   
    21.     connect(this, SIGNAL(emit_parse_cer()), this, SLOT(slot_parse_cer()));  
    22. }  
    23.   
    24. Widget::~Widget()  
    25. {  
    26.     delete ui;  
    27. }  
    28.   
    29. void Widget::on_BrowseBtn_clicked()  
    30. {  
    31.     QString pathStr = QFileDialog::getOpenFileName(this, QString("选择证书文件"), QString("C:\Users\Administrator\Desktop"), QString("*.*"));  
    32.     if (pathStr.length() == 0)  
    33.     {  
    34.         qDebug() << "please select a cer file!";  
    35.         return;  
    36.     }  
    37.   
    38.     ui->PathEdit->setText(pathStr);  
    39.   
    40.     emit emit_parse_cer();  
    41. }  
    42.   
    43. void Widget::slot_parse_cer()  
    44. {  
    45.     x509_cert crt;  
    46.     memset(&crt, 0, sizeof(crt));  
    47.   
    48.     int res = x509parse_crtfile( &crt, ui->PathEdit->text().toLatin1().data());  
    49.     if (0 != res)  
    50.     {  
    51.         QMessageBox::warning(this, "警告", "解析证书失败,请选择正确的证书文件", QMessageBox::Ok);  
    52.         return;  
    53.     }  
    54.   
    55.     ui->CrtInfo->setText(QString("是否为根证书:") + QString::number(crt.ca_istrue));  
    56.     ui->CrtInfo->append(QString("证书版本号:") + QString::number(crt.version));  
    57.     ui->CrtInfo->append(QString("有效期:") + QString::number(crt.valid_from.year) + "-" + QString::number(crt.valid_from.mon)  
    58.     + QString("  到:") + QString::number(crt.valid_to.year) + "-" + QString::number(crt.valid_to.mon));  
    59.   
    60.     qDebug() << crt.ca_istrue;  
    61.     qDebug() << crt.valid_from.year;  
    62. }  
    63.   
    64. void Widget::on_pushButton_clicked()  
    65. {  
    66.     WorkThread *workThread = new WorkThread;  
    67.     workThread->start();  
    68. }  

    3、客户端

    客户端比较简单,直接在界面类进行的SSL功能相关的实现,就是创建套接字,链接服务器,进行SSL握手,向服务器发消息,读取服务器发来的消息。

    工程文件:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. #-------------------------------------------------  
    2. #  
    3. # Project created by QtCreator 2014-05-11T22:28:07  
    4. #  
    5. #-------------------------------------------------  
    6.   
    7. QT       += core gui  
    8.   
    9. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets  
    10.   
    11. TARGET = MyPolarSSLToolCli  
    12. TEMPLATE = app  
    13.   
    14. INCLUDEPATH += /home/chenlong12580/develop/polarTool/polarssl/include  
    15. LIBS += -L "/home/chenlong12580/develop/polarTool/polarssl/lib/" -lpolarssl  
    16.   
    17. SOURCES += main.cpp  
    18.         widget.cpp  
    19.   
    20. HEADERS  += widget.h  
    21.   
    22. FORMS    += widget.ui  


    主窗口类:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. #include "widget.h"  
    2. #include "ui_widget.h"  
    3. #include <QFileDialog>  
    4. #include <QDebug>  
    5. #include <QMessageBox>  
    6. #include "polarssl/havege.h"  
    7. #include "polarssl/certs.h"  
    8. #include "polarssl/x509.h"  
    9. #include "polarssl/ssl.h"  
    10. #include "polarssl/net.h"  
    11.   
    12. #define SERVER_PORT 8443  
    13. /* 
    14. #define SERVER_NAME "localhost" 
    15. #define GET_REQUEST "GET / HTTP/1.0 " 
    16. */  
    17. #define SERVER_NAME "polarssl.org"  
    18. #define GET_REQUEST   
    19.     "GET /hello/ HTTP/1.1 "   
    20.     "Host: polarssl.org "  
    21.   
    22. #define DEBUG_LEVEL 0  
    23.   
    24. void my_debug( void *ctx, int level, char *str )  
    25. {  
    26.     if( level < DEBUG_LEVEL )  
    27.     {  
    28.         fprintf( (FILE *) ctx, "%s", str );  
    29.         fflush(  (FILE *) ctx  );  
    30.     }  
    31. }  
    32.   
    33. Widget::Widget(QWidget *parent) :  
    34.     QWidget(parent),  
    35.     ui(new Ui::Widget)  
    36. {  
    37.     ui->setupUi(this);  
    38.   
    39.     qDebug() << "client";  
    40.   
    41.     connect(this, SIGNAL(emit_parse_cer()), this, SLOT(slot_parse_cer()));  
    42. }  
    43.   
    44. Widget::~Widget()  
    45. {  
    46.     delete ui;  
    47. }  
    48.   
    49. void Widget::on_BrowseBtn_clicked()  
    50. {  
    51.     QString pathStr = QFileDialog::getOpenFileName(this, QString("选择证书文件"), QString("C:\Users\Administrator\Desktop"), QString("*.*"));  
    52.     if (pathStr.length() == 0)  
    53.     {  
    54.         qDebug() << "please select a cer file!";  
    55.         return;  
    56.     }  
    57.   
    58.     ui->PathEdit->setText(pathStr);  
    59.   
    60.     emit emit_parse_cer();  
    61. }  
    62.   
    63. void Widget::slot_parse_cer()  
    64. {  
    65.     x509_cert crt;  
    66.     memset(&crt, 0, sizeof(crt));  
    67.   
    68.     int res = x509parse_crtfile( &crt, ui->PathEdit->text().toLatin1().data());  
    69.     if (0 != res)  
    70.     {  
    71.         QMessageBox::warning(this, "警告", "解析证书失败,请选择正确的证书文件", QMessageBox::Ok);  
    72.         return;  
    73.     }  
    74.   
    75.     ui->CrtInfo->setText(QString("是否为根证书:") + QString::number(crt.ca_istrue));  
    76.     ui->CrtInfo->append(QString("证书版本号:") + QString::number(crt.version));  
    77.     ui->CrtInfo->append(QString("有效期:") + QString::number(crt.valid_from.year) + "-" + QString::number(crt.valid_from.mon)  
    78.     + QString("  到:") + QString::number(crt.valid_to.year) + "-" + QString::number(crt.valid_to.mon));  
    79.   
    80.     qDebug() << crt.ca_istrue;  
    81.     qDebug() << crt.valid_from.year;  
    82. }  
    83.   
    84. void Widget::on_pushButton_clicked()  
    85. {  
    86.     int ret, len, server_fd;  
    87.     unsigned char buf[1024];  
    88.     havege_state hs;  
    89.     ssl_context ssl;  
    90.     ssl_session ssn;  
    91.   
    92.     /* 
    93.          * 0. Initialize the RNG and the session data 
    94.          */  
    95.     havege_init( &hs );  
    96.     memset( &ssn, 0, sizeof( ssl_session ) );  
    97.   
    98.     /* 
    99.          * 1. Start the connection 
    100.          */  
    101.     printf( "   . Connecting to tcp/%s/%4d...", SERVER_NAME,  
    102.             SERVER_PORT );  
    103.     fflush( stdout );  
    104.   
    105.     if( ( ret = net_connect( &server_fd, "127.0.0.1",  
    106.                              SERVER_PORT ) ) != 0 )  
    107.     {  
    108.         printf( " failed   ! net_connect returned %d ", ret );  
    109.         return;  
    110.     }  
    111.   
    112.     printf( " ok " );  
    113.   
    114.     /* 
    115.          * 2. Setup stuff 
    116.          */  
    117.     printf( "  . Setting up the SSL/TLS structure..." );  
    118.     fflush( stdout );  
    119.   
    120.     if( ( ret = ssl_init( &ssl ) ) != 0 )  
    121.     {  
    122.         printf( " failed   ! ssl_init returned %d ", ret );  
    123.         return;  
    124.     }  
    125.   
    126.     printf( " ok " );  
    127.   
    128.     ssl_set_endpoint( &ssl, SSL_IS_CLIENT );  
    129.     ssl_set_authmode( &ssl, SSL_VERIFY_NONE );  
    130.   
    131.     ssl_set_rng( &ssl, havege_rand, &hs );  
    132.     ssl_set_dbg( &ssl, my_debug, stdout );  
    133.     ssl_set_bio( &ssl, net_recv, &server_fd,  
    134.                  net_send, &server_fd );  
    135.   
    136.     ssl_set_ciphers( &ssl, ssl_default_ciphers );  
    137.     ssl_set_session( &ssl, 1, 600, &ssn );  
    138.   
    139.     /* 
    140.          * 3. Write the GET request 
    141.          */  
    142.     printf( "  > Write to server:" );  
    143.     fflush( stdout );  
    144.   
    145.     len = sprintf( (char *) buf, GET_REQUEST );  
    146.   
    147.     while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 )  
    148.     {  
    149.         if( ret != POLARSSL_ERR_NET_TRY_AGAIN )  
    150.         {  
    151.             printf( " failed   ! ssl_write returned %d ", ret );  
    152.             return;  
    153.         }  
    154.     }  
    155.   
    156.     len = ret;  
    157.     printf( " %d bytes written %s", len, (char *) buf );  
    158.   
    159.     /* 
    160.          * 7. Read the HTTP response 
    161.          */  
    162.     printf( "  < Read from server:" );  
    163.     fflush( stdout );  
    164.   
    165.     do  
    166.     {  
    167.         len = sizeof( buf ) - 1;  
    168.         memset( buf, 0, sizeof( buf ) );  
    169.         ret = ssl_read( &ssl, buf, len );  
    170.   
    171.         if( ret == POLARSSL_ERR_NET_TRY_AGAIN )  
    172.             continue;  
    173.   
    174.         if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY )  
    175.             break;  
    176.   
    177.         if( ret <= 0 )  
    178.         {  
    179.             printf( "failed   ! ssl_read returned %d ", ret );  
    180.             break;  
    181.         }  
    182.   
    183.         len = ret;  
    184.         printf( " %d bytes read %s", len, (char *) buf );  
    185.     }  
    186.     while( 0 );  
    187.   
    188.    char *cc= (char *)buf;  
    189.    QString ss(cc);  
    190.   
    191.     qDebug() << ss;  
    192.   
    193.     ssl_close_notify( &ssl );  
    194.   
    195.     return;  
    196. }  

    4、运行效果

    下面说说运行的效果,首先启动服务器端,服务器端启动线程,监听套接字:

    接着启动客户端,客户端链接服务器端,写入消息,读取服务器端的响应:

    最后根据打印可以看出服务器端和客户端握手成功,写入读取消息成功:

    我们可以根据抓包来看看SSL握手的过程,如下:

    通过抓包可以看到服务器端和客户端的握手过程,以及在不同的握手阶段中做得事情:

    服务器端:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. /* 
    2.  * SSL handshake -- server side 
    3.  */  
    4. int ssl_handshake_server( ssl_context *ssl )  
    5. {  
    6.     int ret = 0;  
    7.   
    8.     SSL_DEBUG_MSG( 2, ( "=> handshake server" ) );  
    9.   
    10.     while( ssl->state != SSL_HANDSHAKE_OVER )  
    11.     {  
    12.         SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) );  
    13.   
    14.         if( ( ret = ssl_flush_output( ssl ) ) != 0 )  
    15.             break;  
    16.   
    17.         switch( ssl->state )  
    18.         {  
    19.             case SSL_HELLO_REQUEST:  
    20.                 ssl->state = SSL_CLIENT_HELLO;  
    21.                 break;  
    22.   
    23.             /* 
    24.              *  <==   ClientHello 
    25.              */  
    26.             case SSL_CLIENT_HELLO:  
    27.                 ret = ssl_parse_client_hello( ssl );  
    28.                 break;  
    29.   
    30.             /* 
    31.              *  ==>   ServerHello 
    32.              *        Certificate 
    33.              *      ( ServerKeyExchange  ) 
    34.              *      ( CertificateRequest ) 
    35.              *        ServerHelloDone 
    36.              */  
    37.             case SSL_SERVER_HELLO:  
    38.                 ret = ssl_write_server_hello( ssl );  
    39.                 break;  
    40.   
    41.             case SSL_SERVER_CERTIFICATE:  
    42.                 ret = ssl_write_certificate( ssl );  
    43.                 break;  
    44.   
    45.             case SSL_SERVER_KEY_EXCHANGE:  
    46.                 ret = ssl_write_server_key_exchange( ssl );  
    47.                 break;  
    48.   
    49.             case SSL_CERTIFICATE_REQUEST:  
    50.                 ret = ssl_write_certificate_request( ssl );  
    51.                 break;  
    52.   
    53.             case SSL_SERVER_HELLO_DONE:  
    54.                 ret = ssl_write_server_hello_done( ssl );  
    55.                 break;  
    56.   
    57.             /* 
    58.              *  <== ( Certificate/Alert  ) 
    59.              *        ClientKeyExchange 
    60.              *      ( CertificateVerify  ) 
    61.              *        ChangeCipherSpec 
    62.              *        Finished 
    63.              */  
    64.             case SSL_CLIENT_CERTIFICATE:  
    65.                 ret = ssl_parse_certificate( ssl );  
    66.                 break;  
    67.   
    68.             case SSL_CLIENT_KEY_EXCHANGE:  
    69.                 ret = ssl_parse_client_key_exchange( ssl );  
    70.                 break;  
    71.   
    72.             case SSL_CERTIFICATE_VERIFY:  
    73.                 ret = ssl_parse_certificate_verify( ssl );  
    74.                 break;  
    75.   
    76.             case SSL_CLIENT_CHANGE_CIPHER_SPEC:  
    77.                 ret = ssl_parse_change_cipher_spec( ssl );  
    78.                 break;  
    79.   
    80.             case SSL_CLIENT_FINISHED:  
    81.                 ret = ssl_parse_finished( ssl );  
    82.                 break;  
    83.   
    84.             /* 
    85.              *  ==>   ChangeCipherSpec 
    86.              *        Finished 
    87.              */  
    88.             case SSL_SERVER_CHANGE_CIPHER_SPEC:  
    89.                 ret = ssl_write_change_cipher_spec( ssl );  
    90.                 break;  
    91.   
    92.             case SSL_SERVER_FINISHED:  
    93.                 ret = ssl_write_finished( ssl );  
    94.                 break;  
    95.   
    96.             case SSL_FLUSH_BUFFERS:  
    97.                 SSL_DEBUG_MSG( 2, ( "handshake: done" ) );  
    98.                 ssl->state = SSL_HANDSHAKE_OVER;  
    99.                 break;  
    100.   
    101.             default:  
    102.                 SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );  
    103.                 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );  
    104.         }  
    105.   
    106.         if( ret != 0 )  
    107.             break;  
    108.     }  
    109.   
    110.     SSL_DEBUG_MSG( 2, ( "<= handshake server" ) );  
    111.   
    112.     return( ret );  
    113. }  


    客户端:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
      1. /* 
      2.  * SSL handshake -- client side 
      3.  */  
      4. int ssl_handshake_client( ssl_context *ssl )  
      5. {  
      6.     int ret = 0;  
      7.   
      8.     SSL_DEBUG_MSG( 2, ( "=> handshake client" ) );  
      9.   
      10.     while( ssl->state != SSL_HANDSHAKE_OVER )  
      11.     {  
      12.         SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );  
      13.   
      14.         if( ( ret = ssl_flush_output( ssl ) ) != 0 )  
      15.             break;  
      16.   
      17.         switch( ssl->state )  
      18.         {  
      19.             case SSL_HELLO_REQUEST:  
      20.                 ssl->state = SSL_CLIENT_HELLO;  
      21.                 break;  
      22.   
      23.             /* 
      24.              *  ==>   ClientHello 
      25.              */  
      26.             case SSL_CLIENT_HELLO:  
      27.                 ret = ssl_write_client_hello( ssl );  
      28.                 break;  
      29.   
      30.             /* 
      31.              *  <==   ServerHello 
      32.              *        Certificate 
      33.              *      ( ServerKeyExchange  ) 
      34.              *      ( CertificateRequest ) 
      35.              *        ServerHelloDone 
      36.              */  
      37.             case SSL_SERVER_HELLO:  
      38.                 ret = ssl_parse_server_hello( ssl );  
      39.                 break;  
      40.   
      41.             case SSL_SERVER_CERTIFICATE:  
      42.                 ret = ssl_parse_certificate( ssl );  
      43.                 break;  
      44.   
      45.             case SSL_SERVER_KEY_EXCHANGE:  
      46.                 ret = ssl_parse_server_key_exchange( ssl );  
      47.                 break;  
      48.   
      49.             case SSL_CERTIFICATE_REQUEST:  
      50.                 ret = ssl_parse_certificate_request( ssl );  
      51.                 break;  
      52.   
      53.             case SSL_SERVER_HELLO_DONE:  
      54.                 ret = ssl_parse_server_hello_done( ssl );  
      55.                 break;  
      56.   
      57.             /* 
      58.              *  ==> ( Certificate/Alert  ) 
      59.              *        ClientKeyExchange 
      60.              *      ( CertificateVerify  ) 
      61.              *        ChangeCipherSpec 
      62.              *        Finished 
      63.              */  
      64.             case SSL_CLIENT_CERTIFICATE:  
      65.                 ret = ssl_write_certificate( ssl );  
      66.                 break;  
      67.   
      68.             case SSL_CLIENT_KEY_EXCHANGE:  
      69.                 ret = ssl_write_client_key_exchange( ssl );  
      70.                 break;  
      71.   
      72.             case SSL_CERTIFICATE_VERIFY:  
      73.                 ret = ssl_write_certificate_verify( ssl );  
      74.                 break;  
      75.   
      76.             case SSL_CLIENT_CHANGE_CIPHER_SPEC:  
      77.                 ret = ssl_write_change_cipher_spec( ssl );  
      78.                 break;  
      79.   
      80.             case SSL_CLIENT_FINISHED:  
      81.                 ret = ssl_write_finished( ssl );  
      82.                 break;  
      83.   
      84.             /* 
      85.              *  <==   ChangeCipherSpec 
      86.              *        Finished 
      87.              */  
      88.             case SSL_SERVER_CHANGE_CIPHER_SPEC:  
      89.                 ret = ssl_parse_change_cipher_spec( ssl );  
      90.                 break;  
      91.   
      92.             case SSL_SERVER_FINISHED:  
      93.                 ret = ssl_parse_finished( ssl );  
      94.                 break;  
      95.   
      96.             case SSL_FLUSH_BUFFERS:  
      97.                 SSL_DEBUG_MSG( 2, ( "handshake: done" ) );  
      98.                 ssl->state = SSL_HANDSHAKE_OVER;  
      99.                 break;  
      100.   
      101.             default:  
      102.                 SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );  
      103.                 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );  
      104.         }  
      105.   
      106.         if( ret != 0 )  
      107.             break;  
      108.     }  
      109.   
      110.     SSL_DEBUG_MSG( 2, ( "<= handshake client" ) );  
      111.   
      112.     return( ret );  
      113. }  

    http://blog.csdn.net/chenlong12580/article/details/30556955

  • 相关阅读:
    eclipse如何与git 配合工作。
    git托管代码(二)
    PPC2003 安装 CFNET 3.5成功
    我的Window Mobile WCF 項目 第三篇 WM窗体设计
    我的Window Mobile WCF 項目 第一篇Mobile开发和WinForm开发的区别
    我的Window Mobile WCF 項目 第七天
    我的Window Mobile WCF 項目 第二篇 WindowsMobile访问WCF
    WCF 用vs2010 和 vs2008的简单对比测试
    vs2010beta1 和 搜狗输入法 冲突,按下 Ctrl 键就报错,重装搜狗解决
    我的Window Mobile WCF 項目 第六天 (二)
  • 原文地址:https://www.cnblogs.com/findumars/p/4951415.html
Copyright © 2011-2022 走看看