最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用pthread庫實(shí)現(xiàn)openssl多線程ssl服務(wù)端和客戶端

 更新時(shí)間:2014年01月28日 16:49:37   作者:  
使用pthread庫實(shí)現(xiàn)openssl多線程ssl服務(wù)端和客戶端,大家參考使用吧

服務(wù)端代碼如下:

復(fù)制代碼 代碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <errno.h>
#ifndef    _WIN32
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#else
#include <winsock2.h>
#include <windows.h>
#endif
#include "pthread.h"
#include <openssl/rsa.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define CERTF "certs/sslservercert.pem"
#define KEYF  "certs/sslserverkey.pem"
#define    CAFILE  "certs/cacert.pem"
pthread_mutex_t    mlock=PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t *lock_cs;
static long *lock_count;
#define CHK_NULL(x) if ((x)==NULL) { printf("null\n"); }
#define CHK_ERR(err,s) if ((err)==-1) { printf(" -1 \n"); }
#define CHK_SSL(err) if ((err)==-1) {  printf(" -1 \n");}
#define    CAFILE  "certs/cacert.pem"

int  verify_callback_server(int ok, X509_STORE_CTX *ctx)
{
              printf("verify_callback_server \n");
        return ok;
}

int    SSL_CTX_use_PrivateKey_file_pass(SSL_CTX *ctx,char *filename,char *pass)
{
       EVP_PKEY     *pkey=NULL;
       BIO               *key=NULL;

       key=BIO_new(BIO_s_file());
       BIO_read_filename(key,filename);
       pkey=PEM_read_bio_PrivateKey(key,NULL,NULL,pass);
       if(pkey==NULL)
       {
              printf("PEM_read_bio_PrivateKey err");
              return -1;
       }
       if (SSL_CTX_use_PrivateKey(ctx,pkey) <= 0)
       {
              printf("SSL_CTX_use_PrivateKey err\n");
              return -1;
       }
       BIO_free(key);
       return 1;
}

static int s_server_verify=SSL_VERIFY_NONE;
void * thread_main(void *arg)

       SOCKET s,AcceptSocket;
       WORD wVersionRequested;
       WSADATA wsaData;
       struct sockaddr_in  service;
       int    err;
      size_t             client_len;                                                                                           SSL_CTX             *ctx;
      SSL        *ssl;
      X509             *client_cert;
      char        *str;
      char    buf[1024];
      SSL_METHOD     *meth;

       ssl=(SSL *)arg;
       s=SSL_get_fd(ssl);
       err = SSL_accept (ssl);
      if(err<0)
       {
              printf("ssl accerr\n");
              return ;
       }
      printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
      client_cert = SSL_get_peer_certificate (ssl);
      if (client_cert != NULL)
      {
                   printf ("Client certificate:\n");
                     str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
                   CHK_NULL(str);
                   printf ("\t subject: %s\n", str);
                   OPENSSL_free (str);
                     str = X509_NAME_oneline (X509_get_issuer_name  (client_cert), 0, 0);
                   CHK_NULL(str);
                   printf ("\t issuer: %s\n", str);
                   OPENSSL_free (str);
                     X509_free (client_cert);
      }
      else
                  printf ("Client does not have certificate.\n");
       memset(buf,0,1024);
       err = SSL_read (ssl, buf, sizeof(buf) - 1);
       if(err<0)
       {
              printf("ssl read err\n");
              closesocket(s);
              return;
       }
       printf("get : %s\n",buf);
#if 0
      buf[err] = '\0';
      err = SSL_write (ssl, "I hear you.", strlen("I hear you."));  CHK_SSL(err);
#endif
      SSL_free (ssl);
       closesocket(s);
}

pthread_t pthreads_thread_id(void)
{
       pthread_t ret;

       ret=pthread_self();
       return(ret);
}

void pthreads_locking_callback(int mode, int type, char *file,
            int line)
{
       if (mode & CRYPTO_LOCK)
              {
              pthread_mutex_lock(&(lock_cs[type]));
              lock_count[type]++;
              }
       else
              {
              pthread_mutex_unlock(&(lock_cs[type]));
              }
}

int main ()
{
       int                  err;                
       int                  i;
       SOCKET        s,AcceptSocket;
       WORD           wVersionRequested;
       WSADATA            wsaData;
       struct sockaddr_in  service;
       pthread_tpid;
      size_t             client_len;
      SSL_CTX             *ctx;
      SSL               *ssl;
      X509             *client_cert;
       char        *str;
      char    buf[1024];
      SSL_METHOD     *meth;

      SSL_load_error_strings();
      SSLeay_add_ssl_algorithms();
      meth = SSLv3_server_method();
      ctx = SSL_CTX_new (meth);
      if (!ctx)
      {
                  ERR_print_errors_fp(stderr);
                  exit(2);
      }
       if ((!SSL_CTX_load_verify_locations(ctx,CAFILE,NULL)) ||
                (!SSL_CTX_set_default_verify_paths(ctx)))
    {
              printf("err\n");
              exit(1);
    }
      if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0)
      {
           ERR_print_errors_fp(stderr);
           exit(3);
      }
      if (SSL_CTX_use_PrivateKey_file_pass(ctx, KEYF, "123456") <= 0)
      {
                  ERR_print_errors_fp(stderr);
                  exit(4);
      }
       if (!SSL_CTX_check_private_key(ctx))
       {
                  fprintf(stderr,"Private key does not match the certificate public key\n");
                  exit(5);
      }
       s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
                                SSL_VERIFY_CLIENT_ONCE;
       SSL_CTX_set_verify(ctx,s_server_verify,verify_callback_server);
       SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAFILE));
       wVersionRequested = MAKEWORD( 2, 2 );
       err = WSAStartup( wVersionRequested, &wsaData );
       if ( err != 0 )
       {
              printf("err\n");     
              return -1;
       }
       s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
       if(s<0) return -1;
       service.sin_family = AF_INET;
       service.sin_addr.s_addr = inet_addr("127.0.0.1");
       service.sin_port = htons(1111);
       if (bind( s, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR)
       {
              printf("bind() failed.\n");
              closesocket(s);
              return -1;
       }
    if (listen( s, 1 ) == SOCKET_ERROR)
              printf("Error listening on socket.\n");

       printf("recv .....\n");
       lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
       lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
       for (i=0; i<CRYPTO_num_locks(); i++)
       {
              lock_count[i]=0;
              pthread_mutex_init(&(lock_cs[i]),NULL);
       }
       CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
       CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
       while(1)
       {
              struct timeval tv;
              fd_set fdset;
              tv.tv_sec = 1;
              tv.tv_usec = 0;
              FD_ZERO(&fdset);
              FD_SET(s, &fdset);
           select(s+1, &fdset, NULL, NULL, (struct timeval *)&tv);
           if(FD_ISSET(s, &fdset))
              {
                     AcceptSocket=accept(s, NULL,NULL);
                     ssl = SSL_new (ctx);     
                    CHK_NULL(ssl);
                     err=SSL_set_fd (ssl, AcceptSocket);
                     if(err>0)
                     {
                            err=pthread_create(&pid,NULL,&thread_main,(void *)ssl);
                            pthread_detach(pid);
                     }
                     else
                            continue;
              }
       }
      SSL_CTX_free (ctx);
      return 0;
}

客戶端代碼如下:

復(fù)制代碼 代碼如下:

#include <stdio.h>
#include <memory.h>
#include <errno.h>
#ifndef    _WIN32
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#else
#include <windows.h>
#endif
#include "pthread.h"
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define    MAX_T 1000
#define    CLIENTCERT       "certs/sslclientcert.pem"
#define    CLIENTKEY  "certs/sslclientkey.pem"
#define    CAFILE         "certs/cacert.pem"
static pthread_mutex_t *lock_cs;
static long *lock_count;

pthread_t pthreads_thread_id(void)
{
       pthread_t ret;

       ret=pthread_self();
       return(ret);
}

void pthreads_locking_callback(int mode, int type, char *file,
            int line)
{
       if (mode & CRYPTO_LOCK)
              {
              pthread_mutex_lock(&(lock_cs[type]));
              lock_count[type]++;
              }
       else
              {
              pthread_mutex_unlock(&(lock_cs[type]));
              }
}

int    verify_callback(int ok, X509_STORE_CTX *ctx)
{
       printf("verify_callback\n");
       return ok;
}

int    SSL_CTX_use_PrivateKey_file_pass(SSL_CTX *ctx,char *filename,char *pass)
{
       EVP_PKEY     *pkey=NULL;
       BIO               *key=NULL;

       key=BIO_new(BIO_s_file());
       BIO_read_filename(key,filename);
       pkey=PEM_read_bio_PrivateKey(key,NULL,NULL,pass);
       if(pkey==NULL)
       {
              printf("PEM_read_bio_PrivateKey err");
              return -1;
       }
       if (SSL_CTX_use_PrivateKey(ctx,pkey) <= 0)
       {
              printf("SSL_CTX_use_PrivateKey err\n");
              return -1;
       }
       BIO_free(key);
       return 1;
}

void*thread_main(void *arg)
{
       int          err,buflen,read;
      int          sd;
       SSL_CTX             *ctx=(SSL_CTX *)arg;
       struct            sockaddr_in dest_sin;
       SOCKET        sock;
       PHOSTENT   phe;
       WORD           wVersionRequested;
       WSADATA            wsaData;
      SSL               *ssl;
      X509             *server_cert;
      char     *str;
      char        buf [1024];
      SSL_METHOD     *meth;
       FILE              *fp;

       wVersionRequested = MAKEWORD( 2, 2 );
       err = WSAStartup( wVersionRequested, &wsaData );
       if ( err != 0 )
       {
              printf("WSAStartup err\n");     
              return -1;
       }
       sock = socket(AF_INET, SOCK_STREAM, 0);
       dest_sin.sin_family = AF_INET;
       dest_sin.sin_addr.s_addr = inet_addr( "127.0.0.1" );
       dest_sin.sin_port = htons( 1111 );

again:
       err=connect( sock,(PSOCKADDR) &dest_sin, sizeof( dest_sin));
       if(err<0)
       {
              Sleep(1);
              goto again;
       }
    ssl = SSL_new (ctx);                       
       if(ssl==NULL)
       {
              printf("ss new err\n");
              return ;
       }
       SSL_set_fd(ssl,sock);
      err = SSL_connect (ssl);                   
      if(err<0)
       {
              printf("SSL_connect err\n");
              return;
       }
      printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
      server_cert = SSL_get_peer_certificate (ssl);     
      printf ("Server certificate:\n");
      str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0);
      printf ("\t subject: %s\n", str);
      OPENSSL_free (str);
      str = X509_NAME_oneline (X509_get_issuer_name  (server_cert),0,0);
      printf ("\t issuer: %s\n", str);
      OPENSSL_free (str); 
      X509_free (server_cert);
       err = SSL_write (ssl, "Hello World!", strlen("Hello World!"));
       if(err<0)
       {
              printf("ssl write err\n");
              return ;
       }
#if 0
       memset(buf,0,ONE_BUF_SIZE);
      err = SSL_read (ssl, buf, sizeof(buf) - 1);                 
       if(err<0)
       {
              printf("ssl read err\n");
              return ;
       }
      buf[err] = '\0';
      printf ("Got %d chars:'%s'\n", err, buf);
#endif
      SSL_shutdown (ssl);  /* send SSL/TLS close_notify */
      SSL_free (ssl);
       closesocket(sock);
}

int    main ()
{
       int          err,buflen,read;
      int          sd;

       struct            sockaddr_in dest_sin;
       SOCKETsock;
       PHOSTENT phe;
       WORD wVersionRequested;
       WSADATA wsaData;
      SSL_CTX             *ctx;
      SSL        *ssl;
      X509             *server_cert;
      char     *str;
      char        buf [1024];
      SSL_METHOD     *meth;
       int           i;
       pthread_tpid[MAX_T];

      SSLeay_add_ssl_algorithms();
      meth = SSLv3_client_method();
      SSL_load_error_strings();
      ctx = SSL_CTX_new (meth);                     
       if(ctx==NULL)
       {
              printf("ssl ctx new eer\n");
              return -1;
       }

       if (SSL_CTX_use_certificate_file(ctx, CLIENTCERT, SSL_FILETYPE_PEM) <= 0)
    {
        ERR_print_errors_fp(stderr);
        exit(3);
    }
    if (SSL_CTX_use_PrivateKey_file_pass(ctx, CLIENTKEY, "123456") <= 0)
    {
         ERR_print_errors_fp(stderr);
         exit(4);
     }
       lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
       lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
       for (i=0; i<CRYPTO_num_locks(); i++)
       {
              lock_count[i]=0;
              pthread_mutex_init(&(lock_cs[i]),NULL);
       }
       CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
       CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
       for(i=0;i<MAX_T;i++)
       {          
              err=pthread_create(&(pid[i]),NULL,&thread_main,(void *)ctx);
              if(err!=0)
              {
                     printf("pthread_create err\n");
                     continue;
              }
       }
       for (i=0; i<MAX_T; i++)
       {
              pthread_join(pid[i],NULL);
       }
      SSL_CTX_free (ctx);
      printf("test ok\n");
       return 0;
}

上述程序在windows下運(yùn)行成功,采用了windows下的開源pthread庫。
需要注意的是,如果多線程用openssl,需要設(shè)置兩個(gè)回調(diào)函數(shù)

復(fù)制代碼 代碼如下:

CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);

相關(guān)文章

  • OpenCV去除綠幕摳圖源碼

    OpenCV去除綠幕摳圖源碼

    這篇文章主要介紹了OpenCV去除綠幕摳圖,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • 關(guān)于UDP服務(wù)器客戶端編程流程介紹

    關(guān)于UDP服務(wù)器客戶端編程流程介紹

    大家好,本篇文章主要講的是關(guān)于UDP服務(wù)器客戶端編程流程介紹,感興趣的同學(xué)趕快來看看吧,對你有幫助的話記得收藏
    2021-12-12
  • 詳解C++中typedef 和 #define 的區(qū)別

    詳解C++中typedef 和 #define 的區(qū)別

    這篇文章主要介紹了C++中typedef 與 #define 的區(qū)別,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • C語言實(shí)現(xiàn)刮刮樂效果是示例代碼

    C語言實(shí)現(xiàn)刮刮樂效果是示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何C語言模擬實(shí)現(xiàn)刮刮樂的效果,只要按下鼠標(biāo)左鍵并移動就可以刮開刮卡層,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-01-01
  • C/C++中多重繼承詳解及其作用介紹

    C/C++中多重繼承詳解及其作用介紹

    這篇文章主要介紹了C/C++中多重繼承詳解及其作用介紹,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • C語言實(shí)現(xiàn)簡單的停車場管理系統(tǒng)

    C語言實(shí)現(xiàn)簡單的停車場管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)簡單的停車場管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C語言 運(yùn)算符詳細(xì)介紹及示例代碼

    C語言 運(yùn)算符詳細(xì)介紹及示例代碼

    本文介紹C語言 運(yùn)算符,這里整理了運(yùn)算符的基礎(chǔ)知識,并附示例代碼,希望能幫助剛剛開始學(xué)習(xí) C語言的同學(xué)
    2016-08-08
  • 談?wù)凜語言中位運(yùn)算你要知道的那些事兒

    談?wù)凜語言中位運(yùn)算你要知道的那些事兒

    C語言中的各種運(yùn)算都是以字節(jié)的形式進(jìn)行,在編寫很多系統(tǒng)程序時(shí),如驅(qū)動程序、磁盤文件管理程序等,常要求將數(shù)據(jù)按位(bit)進(jìn)行運(yùn)算或者處理,下面這篇文章主要給大家介紹了關(guān)于C語言中位運(yùn)算的相關(guān)資料,需要的朋友可以參考下
    2022-02-02
  • 基于C語言實(shí)現(xiàn)學(xué)生成績管理系統(tǒng)

    基于C語言實(shí)現(xiàn)學(xué)生成績管理系統(tǒng)

    這篇文章主要介紹了基于C語言實(shí)現(xiàn)學(xué)生成績管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C++ 網(wǎng)絡(luò)編程 總結(jié)

    C++ 網(wǎng)絡(luò)編程 總結(jié)

    這篇文章主要介紹了C++ 網(wǎng)絡(luò)編程的一些詳細(xì)相關(guān)內(nèi)容,有需要的小伙伴可以參考下。
    2015-06-06

最新評論

淄博市| 石门县| 微山县| 修武县| 庆云县| 家居| 集贤县| 台州市| 江山市| 城口县| 天峻县| 巴塘县| 夏河县| 甘南县| 九龙城区| 南投县| 兴义市| 天门市| 东乡族自治县| 罗城| 宜兰县| 阜新市| 雅江县| 青冈县| 凤冈县| 宁武县| 潞西市| 吉水县| 区。| 迁安市| 武功县| 铜山县| 射洪县| 徐水县| 武穴市| 简阳市| 衡水市| 淮南市| 北碚区| 神木县| 贺州市|