• 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

  • 相关阅读:
    一个主机下创建两个MySQL
    Chrome: Failed to read the 'localStorage' property from 'Window' 的解决办法
    Effective C++
    归并排序
    Daily Note
    关于Beta分布、二项分布与Dirichlet分布、多项分布的关系
    测试公式
    VLAN原理解释
    子网划分
    windows下制作debian U盘启动
  • 原文地址:https://www.cnblogs.com/findumars/p/4951415.html
Copyright © 2020-2023  润新知