最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

openssl一个简单的实例

来源:动视网 责编:小OO 时间:2025-09-23 13:12:07
文档

openssl一个简单的实例

1.安装openssl库:sudosudoapt-getinstalllibssl-dev2.服务器端实现代码#include#include#include#include#include#include#include#include#include#include#include#include#defineMAXBUF1024intmain(intargc,char**argv){intsockfd,new_fd;socklen_tlen;structsockaddr_inmy_add
推荐度:
导读1.安装openssl库:sudosudoapt-getinstalllibssl-dev2.服务器端实现代码#include#include#include#include#include#include#include#include#include#include#include#include#defineMAXBUF1024intmain(intargc,char**argv){intsockfd,new_fd;socklen_tlen;structsockaddr_inmy_add
1.安装openssl库:

  sudo sudo apt-get install libssl-dev

2.服务器端实现代码

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAXBUF 1024

int 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

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAXBUF 1024

void 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\\%s IP地址 端口\\n\比如:\%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]));//7838

if (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.0、SSLv2、SSLv3、SSLv2/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会话环境

4  结束语

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

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

本示例用多线程实现了一个ssl服务端和一个客户端。

服务端代码如下:

#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) <= 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 ("\ subject: %s\\n", str);

               OPENSSL_free (str);

            str = X509_NAME_oneline (X509_get_issuer_name  (client_cert), 0, 0);

               CHK_NULL(str);

               printf ("\ 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_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);

      }

   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    {

        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

#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) <= 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 ("\ subject: %s\\n", str);

      OPENSSL_free (str);

      str = X509_NAME_oneline (X509_get_issuer_name  (server_cert),0,0);

      printf ("\ 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;

    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)

    {

         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[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    {        

        err=pthread_create(&(pid[i]),NULL,&thread_main,(void *)ctx);

        if(err!=0)

        {

            printf("pthread_create err\\n");

            continue;

        }

    }

for (i=0; i    {

        pthread_join(pid[i],NULL);

    }

      SSL_CTX_free (ctx);

      printf("test ok\\n");

    return 0;

}

文档

openssl一个简单的实例

1.安装openssl库:sudosudoapt-getinstalllibssl-dev2.服务器端实现代码#include#include#include#include#include#include#include#include#include#include#include#include#defineMAXBUF1024intmain(intargc,char**argv){intsockfd,new_fd;socklen_tlen;structsockaddr_inmy_add
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top