openSSL的应用

来源:互联网 发布:python学习手册 pdf 编辑:程序博客网 时间:2024/06/05 14:31

源码包地址:http://www.openssl.org/source/

编译源码包的方法:http://blog.163.com/hancker_31/blog/static/35587361201112125736855/

 

实例:

资源下载:http://download.csdn.net/detail/hui523hui523hui523/4395929

 

1.安装openssl库:  sudo sudo apt-get install libssl-dev2.服务器端实现代码#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/wait.h>#include <unistd.h>#include <arpa/inet.h>#include <openssl/ssl.h>#include <openssl/err.h>#define MAXBUF 1024int main(int argc, char **argv){    int sockfd, new_fd;    socklen_t len;    struct sockaddr_in my_addr, their_addr;    unsigned int myport, lisnum;    char buf[MAXBUF + 1];    SSL_CTX *ctx;    if (argv[1])        myport = atoi(argv[1]);    else        myport = 7838;    if (argv[2])        lisnum = atoi(argv[2]);    else        lisnum = 2;    /* SSL 库初始化 */    SSL_library_init();    /* 载入所有 SSL 算法 */    OpenSSL_add_all_algorithms();    /* 载入所有 SSL 错误消息 */    SSL_load_error_strings();    /* 以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text */    ctx = SSL_CTX_new(SSLv23_server_method());    /* 也可以用 SSLv2_server_method() 或 SSLv3_server_method() 单独表示 V2 或 V3标准 */    if (ctx == NULL) {        ERR_print_errors_fp(stdout);        exit(1);    }    /* 载入用户的数字证书, 此证书用来发送给客户端。 证书里包含有公钥 */    if (SSL_CTX_use_certificate_file(ctx, argv[3], SSL_FILETYPE_PEM) <= 0) {        ERR_print_errors_fp(stdout);        exit(1);    }    /* 载入用户私钥 */    if (SSL_CTX_use_PrivateKey_file(ctx, argv[4], SSL_FILETYPE_PEM) <= 0) {        ERR_print_errors_fp(stdout);        exit(1);    }    /* 检查用户私钥是否正确 */    if (!SSL_CTX_check_private_key(ctx)) {        ERR_print_errors_fp(stdout);        exit(1);    }    /* 开启一个 socket 监听 */    if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {        perror("socket");        exit(1);    } else        printf("socket created\n");    bzero(&my_addr, sizeof(my_addr));    my_addr.sin_family = PF_INET;    my_addr.sin_port = htons(myport);    my_addr.sin_addr.s_addr = INADDR_ANY;    if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))        == -1) {        perror("bind");        exit(1);    } else        printf("binded\n");    if (listen(sockfd, lisnum) == -1) {        perror("listen");        exit(1);    } else        printf("begin listen\n");    while (1) {        SSL *ssl;        len = sizeof(struct sockaddr);        /* 等待客户端连上来 */        if ((new_fd =             accept(sockfd, (struct sockaddr *) &their_addr,                    &len)) == -1) {            perror("accept");            exit(errno);        } else            printf("server: got connection from %s, port %d, socket %d\n",                   inet_ntoa(their_addr.sin_addr),                   ntohs(their_addr.sin_port), new_fd);        /* 基于 ctx 产生一个新的 SSL */        ssl = SSL_new(ctx);        /* 将连接用户的 socket 加入到 SSL */        SSL_set_fd(ssl, new_fd);        /* 建立 SSL 连接 */        if (SSL_accept(ssl) == -1) {            perror("accept");            close(new_fd);            break;        }        /* 开始处理每个新连接上的数据收发 */        bzero(buf, MAXBUF + 1);        strcpy(buf, "server->client");        /* 发消息给客户端 */        len = SSL_write(ssl, buf, strlen(buf));        if (len <= 0) {            printf                ("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",                 buf, errno, strerror(errno));            goto finish;        } else            printf("消息'%s'发送成功,共发送了%d个字节!\n",                   buf, len);        bzero(buf, MAXBUF + 1);        /* 接收客户端的消息 */        len = SSL_read(ssl, buf, MAXBUF);        if (len > 0)            printf("接收消息成功:'%s',共%d个字节的数据\n",                   buf, len);        else            printf                ("消息接收失败!错误代码是%d,错误信息是'%s'\n",                 errno, strerror(errno));        /* 处理每个新连接上的数据收发结束 */      finish:        /* 关闭 SSL 连接 */        SSL_shutdown(ssl);        /* 释放 SSL */        SSL_free(ssl);        /* 关闭 socket */        close(new_fd);    }    /* 关闭监听的 socket */    close(sockfd);    /* 释放 CTX */    SSL_CTX_free(ctx);    return 0;}


 

2. 客户端实现代码dfa#include <stdio.h>#include <string.h>#include <errno.h>#include <sys/socket.h>#include <resolv.h>#include <stdlib.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <openssl/ssl.h>#include <openssl/err.h>#define MAXBUF 1024void ShowCerts(SSL * ssl){    X509 *cert;    char *line;    cert = SSL_get_peer_certificate(ssl);// 该函数可以从SSL套接字中提取对方的证书信息,这些信息已经被SSL验证过了。X509_NAME *X509_get_subject_name(X509 *a);该函数得到证书所用者的名字。返回值是X509    if (cert != NULL) {        printf("数字证书信息:\n");        line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);        printf("证书: %s\n", line);        free(line);        line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);        printf("颁发者: %s\n", line);        free(line);        X509_free(cert);    } else        printf("无证书信息!\n");}int main(int argc, char **argv){    int sockfd, len;    struct sockaddr_in dest;    char buffer[MAXBUF + 1];    SSL_CTX *ctx;    SSL *ssl;    if (argc != 3) {        printf("参数格式错误!正确用法如下:\n\t\t%s IP地址 端口\n\t比如:\t%s 127.0.0.1 80\n此程序用来从某个"             "IP 地址的服务器某个端口接收最多 MAXBUF 个字节的消息",             argv[0], argv[0]);        exit(0);    }    /* SSL 库初始化,参看 ssl-server.c 代码 */    SSL_library_init();    OpenSSL_add_all_algorithms();    SSL_load_error_strings();ctx = SSL_CTX_new(SSLv23_client_method());当SSL会话环境申请成功后,还要根据实际的需要设置CTX的属性,通常的设置是指定SSL握手阶段证书的验证方式和加载自己的证书。    if (ctx == NULL) {        ERR_print_errors_fp(stdout);??????        exit(1);    }    /* 创建一个 socket 用于 tcp 通信 */    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {        perror("Socket");        exit(errno);    }    printf("socket created\n");    /* 初始化服务器端(对方)的地址和端口信息 */    bzero(&dest, sizeof(dest));    dest.sin_family = AF_INET;    dest.sin_port = htons(atoi(argv[2]));//7838if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) {inet_aton是一个改进的方法来将一个字符串IP地址转换为一个32位的网络序列IP地址        perror(argv[1]);        exit(errno);    }    printf("address created\n");    /* 连接服务器 */    if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {        perror("Connect ");        exit(errno);    }    printf("server connected\n");    /* 基于 ctx 产生一个新的 SSL */    ssl = SSL_new(ctx);// 申请一个SSL套接字    SSL_set_fd(ssl, sockfd);// //绑定读写套接字    /* 建立 SSL 连接 */    if (SSL_connect(ssl) == -1)// 而对服务器来讲,则应使用函数SSL_ accept ( )替代传统的函数accept ( )来完成握手过程:        ERR_print_errors_fp(stderr);??    else {        printf("Connected with %s encryption\n", SSL_get_cipher(ssl));        ShowCerts(ssl);这个时候从服务器接受服务器提供的本身认证!!!!    }    /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */    bzero(buffer, MAXBUF + 1);    /* 接收服务器来的消息 */    len = SSL_read(ssl, buffer, MAXBUF);    if (len > 0)        printf("接收消息成功:'%s',共%d个字节的数据\n",               buffer, len);    else {        printf            ("消息接收失败!错误代码是%d,错误信息是'%s'\n",             errno, strerror(errno));        goto finish;    }    bzero(buffer, MAXBUF + 1);    strcpy(buffer, "from client->server");    /* 发消息给服务器 */    len = SSL_write(ssl, buffer, strlen(buffer));    if (len < 0)        printf            ("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",             buffer, errno, strerror(errno));    else        printf("消息'%s'发送成功,共发送了%d个字节!\n",               buffer, len);  finish:    /* 关闭连接 */    SSL_shutdown(ssl);    SSL_free(ssl);    close(sockfd);    SSL_CTX_free(ctx);    return 0;}


 

3.编译方式:

gcc -o ssl_server ssl_server.c -Wall -g –lssl//gcc -Wall sever.c -o server -lssl -lcrypto -ldl

gcc -o ssl_client ssl_client.c -Wall -g -lssl

 

4.生产私钥和证书

openssl genrsa -out privkey.pem 1024

openssl req -new -x509 -key privkey.pem -out CAcert.pem -days 1095

 

5.程序运行方式:

./ssl_server 7838 1 CAcert.pem privkey.pem

./ssl_client 127.0.0.1 7838

 

本篇文章来源于 Linux公社网站(www.linuxidc.com) 原文链接:http://www.linuxidc.com/Linux/2011-04/34523.htm

 

OpenSSL的程序可以被分为两个部分:客户机和服务器,使用SSL协议使通信双方可以相互验证对方身份的真实性,并且能够保证数据的完整性和机密性。建立SSL通信的过程如图2所示。

   

     2  SSL通信过程

 

SSL通信模型采用标准的C/S结构,除了在TCP层上进行传输之外,与普通的网络通信协议没有太大的区别,基于OpenSSL的程序都要遵循以下几个步骤:

(1 ) OpenSSL初始化

在使用OpenSSL之前,必须进行相应的协议初始化工作,这可以通过下面的函数实现:

int SSL_library_int(void);

(2 ) 选择会话协议

在利用OpenSSL开始SSL会话之前,需要为客户端和服务器制定本次会话采用的协议,目前能够使用的协议包括TLSv1.0SSLv2SSLv3SSLv2/v3

需要注意的是,客户端和服务器必须使用相互兼容的协议,否则SSL会话将无法正常进行。

(3 ) 创建会话环境

OpenSSL中创建的SSL会话环境称为CTX,使用不同的协议会话,其环境也

不一样的。申请SSL会话环境的OpenSSL函数是:

SSL_CTX *SSL_CTX_new(SSL_METHOD * method);

SSL会话环境申请成功后,还要根据实际的需要设置CTX的属性,通常的设置是指定SSL握手阶段证书的验证方式和加载自己的证书。制定证书验证方式的函数是:

int SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int(*verify_callback),int(X509_STORE_CTX *));

SSL会话环境加载CA证书的函数是:

SSL_CTX_load_verify_location(SSL_CTX *ctx,const char *Cafile,const char *Capath);

SSL会话加载用户证书的函数是:

SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file,int type);

SSL会话加载用户私钥的函数是:

SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx,const char* file,int type);

在将证书和私钥加载到SSL会话环境之后,就可以调用下面的函数来验证私钥和证书是否相符:

int SSL_CTX_check_private_key(SSL_CTX *ctx);

(4) 建立SSL套接字

SSL套接字是建立在普通的TCP套接字基础之上,在建立SSL套接字时可以使用下面的一些函数:

SSL *SSl_new(SSL_CTX *ctx); 

//申请一个SSL套接字

int SSL_set_fd(SSL *ssl,int fd);) 

//绑定读写套接字

int SSL_set_rfd(SSL *ssl,int fd); 

//绑定只读套接字

int SSL_set_wfd(SSL *ssl,int fd);

//绑定只写套接字

(5) 完成SSL握手

在成功创建SSL套接字后,客户端应使用函数SSL_connect( )替代传统的函数connect( )来完成握手过程:

int SSL_connect(SSL *ssl);

而对服务器来讲,则应使用函数SSL_ accept ( )替代传统的函数accept ( )来完成握手过程:

int SSL_accept(SSL *ssl);

握手过程完成之后,通常需要询问通信双方的证书信息,以便进行相应的验证,这可以借助于下面的函数来实现:

X509 *SSL_get_peer_certificate(SSL *ssl);

该函数可以从SSL套接字中提取对方的证书信息,这些信息已经被SSL验证过了。

X509_NAME *X509_get_subject_name(X509 *a);

该函数得到证书所用者的名字。

(6) 进行数据传输

SSL握手完成之后,就可以进行安全的数据传输了,在数据传输阶段,需要使用SSL_read( )SSL_write( )来替代传统的read( )write( )函数,来完成对套接字的读写操作:

int SSL_read(SSL *ssl,void *buf,int num);

int SSL_write(SSL *ssl,const void *buf,int num);

(7 ) 结束SSL通信

当客户端和服务器之间的数据通信完成之后,调用下面的函数来释放已经申请的SSL资源:

int SSL_shutdown(SSL *ssl); 

//关闭SSL套接字

void SSl_free(SSL *ssl);

 //释放SSL套接字

void SSL_CTX_free(SSL_CTX *ctx);  

//释放SSL会话环境

结束语

SSL协议采用数字证书进行双端实体认证,用非对称加密算法进行密钥协商,用对称加密算法将数据加密后进行传输以保证数据的保密性,并且通过计算数字摘要来验证数据在传输过程中是否被篡改和伪造,从而为敏感数据在Internet上的传输提供了一种安全保障手段。

OpenSSL是一个开放源代码的SSL协议的产品实现,它采用C语言作为开发语言,具备了跨系统的性能。调用OpenSSL 的函数就可以实现一个SSL加密的安全数据传输通道,从而保护客户端和服务器之间数据的安全。

 

本示例用多线程实现了一个ssl服务端和一个客户端。服务端代码如下:#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" #defineCAFILE"certs/cacert.pem"pthread_mutex_tmlock=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");}#defineCAFILE"certs/cacert.pem"int  verify_callback_server(int ok, X509_STORE_CTX *ctx){printf("verify_callback_server \n");        return ok;}intSSL_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_inservice;interr;  size_tclient_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 (){interr;                inti;SOCKETs,AcceptSocket;WORDwVersionRequested;WSADATAwsaData;struct sockaddr_inservice;pthread_tpid;  size_tclient_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);}elsecontinue;}}  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>#defineMAX_T 1000#defineCLIENTCERT"certs/sslclientcert.pem"#defineCLIENTKEY"certs/sslclientkey.pem"#defineCAFILE"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]));}}intverify_callback(int ok, X509_STORE_CTX *ctx){printf("verify_callback\n");return ok;}intSSL_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;SOCKETsock;PHOSTENTphe;WORDwVersionRequested;WSADATAwsaData;  SSL*ssl;  X509*server_cert;  char   *str;  charbuf [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 0memset(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);}intmain (){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;  charbuf [1024];  SSL_METHOD *meth;inti;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;}

原创粉丝点击