首页 OPENSSL多线程实例

OPENSSL多线程实例

举报
开通vip

OPENSSL多线程实例OPENSSL多线程实例 服务端代码如下: #include #include #include #include #ifndef _WIN32 #include #include #include #include #include #include #else #include #include #endif #include "pthread.h" #include #include #include #include #include #include #de...

OPENSSL多线程实例
OPENSSL多线程实例 服务端代码如下: #include #include #include #include #ifndef _WIN32 #include #include #include #include #include #include #else #include #include #endif #include "pthread.h" #include #include #include #include #include #include #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) { 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 { 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 { 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) { ERR_print_errors_fp(stderr); exit(3); } if (SSL_CTX_use_PrivateKey_file_pass(ctx, KEYF, "123456") { 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 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 { lock_count=0; pthread_mutex_init(&(lock_cs),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; } 客户端代码如下: #include #include #include #ifndef _WIN32 #include #include #include #include #include #include #else #include #endif #include "pthread.h" #include #include #include #include #include #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) { 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 { 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 { 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 { printf("ssl write err\n"); return ; } #if 0 memset(buf,0,ONE_BUF_SIZE); err = SSL_read (ssl, buf, sizeof(buf) - 1); if(err { 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) { ERR_print_errors_fp(stderr); exit(3); } if (SSL_CTX_use_PrivateKey_file_pass(ctx, CLIENTKEY, "123456") { 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 { lock_count=0; pthread_mutex_init(&(lock_cs),NULL); } CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id); CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback); for(i=0;i { err=pthread_create(&(pid),NULL,&thread_main,(void *)ctx); if(err!=0) { printf("pthread_create err\n"); continue; } } for (i=0; i { pthread_join(pid,NULL); } SSL_CTX_free (ctx); printf("test ok\n"); return 0; } 上述程序在windows下运行成功,采用了windows下的开源pthread库。 需要注意的是,如果多线程用openssl,需要设置两个回调函数 CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id); CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback); 本文来自ChinaUnix博客,如果查看原文请点:
本文档为【OPENSSL多线程实例】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_597436
暂无简介~
格式:doc
大小:43KB
软件:Word
页数:0
分类:工学
上传时间:2017-11-19
浏览量:20