c语言一个完整可执行的多线程openssl实例服务端+客户端
来源:互联网 发布:python 高斯曲线拟合 编辑:程序博客网 时间:2024/06/06 06:42
//服务器端#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 CERTF "/etc/pki/tls/misc/sslservercert.pem"//#define KEYF "certs/sslserverkey.pem"#define KEYF "/etc/pki/tls/misc/sslserverkey.pem"//#define CAFILE "certs/cacert.pem"#define CAFILE "/etc/pki/CA/cacert.pem"#define SOCKET_ERROR -1#define SOCKET int 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 "demoCA/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; //printf("line=%d\n",__LINE__); key=BIO_new(BIO_s_file()); //printf("pass=%s\n",pass); BIO_read_filename(key,filename); pkey=PEM_read_bio_PrivateKey(key,NULL,NULL,pass); if(pkey==NULL) { //printf("line=%d\n",__LINE__); printf("PEM_read_bio_PrivateKey err"); return -1; } //printf("line=%d\n",__LINE__); if (SSL_CTX_use_PrivateKey(ctx,pkey) <= 0) { printf("SSL_CTX_use_PrivateKey err\n"); return -1; } //printf("line=%d\n",__LINE__); BIO_free(key); return 1;}static int s_server_verify=SSL_VERIFY_NONE;void * thread_main(void *arg){ SOCKET s; SOCKET 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");while(1){ memset(buf,0,1024); err = SSL_read (ssl, buf, sizeof(buf) - 1); if(err<0) { printf("ssl read err\n"); //closesocket(s); close(s); //return; }else if(err>0) { printf("get : %s\n",buf); } else { printf("有客户端退出!\n"); break; }}#if 1 buf[err] = '\0'; buf[err] = '\0'; err = SSL_write (ssl, "I hear you.", strlen("I hear you.")); CHK_SSL(err);#endif SSL_free (ssl); //closesocket(s); close(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 (){/*FILE *fstream;fstream=fopen("/etc/pki/tls/misc/servercert.pem","at+");if(fstream==NULL){ printf("open file failed!\n"); exit(1);}else{ fclose(fstream); printf("file exit!\n");}*/ int err; int i; SOCKET s; SOCKET AcceptSocket; //int s,AcceptSocket; //WORD wVersionRequested; //WSADATA wsaData; struct sockaddr_in service; pthread_t pid; 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); } //printf("line=%d\n",__LINE__); if (SSL_CTX_use_PrivateKey_file_pass(ctx,KEYF,"phrase") <= 0) //if (SSL_CTX_use_PrivateKey_file_pass(ctx, KEYF, "1428795366") <= 0) { ERR_print_errors_fp(stderr); exit(4); } //printf("line=%d\n",__LINE__); 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) if (bind( s, (struct sockaddr *) &service, sizeof(service)) == SOCKET_ERROR) { printf("bind() failed.\n"); // closesocket(s); close(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;}//客户端#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 1 //set pthread num//#define CLIENTCERT "certs/sslclientcert.pem"#define CLIENTCERT "/etc/pki/tls/misc/sslclientcert.pem"//#define CLIENTKEY "clientkey.pem"#define CLIENTKEY "/etc/pki/tls/misc/sslclientkey.pem"//#define CAFILE "certs/cacert.pem"#define CAFILE "/etc/pki/CA/cacert.pem"#define SOCKET int #define SOCKET_ERROR -1 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)); err=connect( sock,(struct sockaddr *) &dest_sin, sizeof( dest_sin)); if(err<0){ //Sleep(1); 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); //new add while(1) { char ch_array[1024]; scanf("%s",ch_array); err = SSL_write(ssl,ch_array,strlen(ch_array)); } //new add //err = SSL_write (ssl, "Hello World!", strlen("Hello World!")); if(err<0) { printf("ssl write err\n"); return ; }#if 1 //memset(buf,0,ONE_BUF_SIZE); memset(buf,0,1024); 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); close(sock);}int main (){ int err,buflen,read; int sd; struct sockaddr_in dest_sin; SOCKET sock; /*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_t pid[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){ if (SSL_CTX_use_PrivateKey_file_pass(ctx, CLIENTKEY, "phrase") <= 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;}编译:gcc -o ssl_server ssl_server.c -Wall -g -lsslgcc -o ssl_client ssl_client.c -Wall -g -lssl生产私钥和证书:openssl genrsa -out privkey.pem 1024openssl req -new -x509 -key privkey.pem -out CAcert.pem -days 1095运行:在一个终端./ssl_server在多个终端./ssl_client
0 0
- c语言一个完整可执行的多线程openssl实例服务端+客户端
- 【C语言】【unix c】服务端与客户端建立通信的实例
- C语言实现服务端和客户端进行TCP通信实例
- C语言实现服务端和客户端进行TCP通信实例
- 基于OpenSSL颁发数字证书的一个完整实例
- Java多线程服务端与客户端的交互小实例
- 迟迟开始学习的网络编程,C语言客户端服务端,python客户端服务端和mini木马
- Android-------C语言可执行程序编译实例
- Android-------C语言可执行程序编译实例
- Android-------C语言可执行程序编译实例
- C语言简单的客户端和服务端程序
- 一个简单的TCP客户端、服务端会话程序(C#)
- 一个简单的TCP客户端、服务端会话程序(C#)
- 一个客户端的完整程序
- 客户端多线程向服务端的文件传输
- 一个C语言源程序是如何到一个可执行程序的
- TCP:客户端和服务端的使用实例
- php创建一个最简单的soap服务端与客户端测试的实例
- MySQL 获得当前日期时间 函数
- Android6.0源码分析之menu键弹出popupwindow菜单流程分析
- Flex 布局教程:语法篇
- 新手容易犯的错!!!
- androoid framework学习之 - RILd启动过程和如何接收framwork层的消息流程(二)
- c语言一个完整可执行的多线程openssl实例服务端+客户端
- html
- 一条insert语句批量插入多条记录
- logstash remove_field =>["message"]
- android开发:运行App,显示当前界面是哪个activity。
- 带宽计算方法
- FLEX与BISON构造一个高级计算器(未完成)
- Elasticsearch 的一些示例, 增删改查,映射,结构化查询,聚合
- 位运算和浮点数的简单思考