您的位置:首页 > 运维架构

使用openssl编写服务端和客户端程序

2015-09-18 18:38 489 查看
1.使用相同的ca生成两个证书,一个是server.cer,一个是client.cer,注意生成server.cer的时候必须指明证书可以用于服务端的。

服务器代码:

#include "openssl/bio.h"  
#include "openssl/ssl.h"  
#include "openssl/err.h"  
 
#include <cutil.h>  
 
#define EXIT_IF_TRUE(x) if (x)                              \  
    do {                                                    \  
            fprintf(stderr, "Check '%s' is true\n", #x);    \  
            ERR_print_errors_fp(stderr);                    \  
            exit(2);                                        \  
    }while(0)  
 
int main(int argc, char **argv)  
{  
    SSL_CTX     *ctx;  
    SSL         *ssl;  
    X509        *client_cert;  
 
    char szBuffer[1024];  
    int nLen;  
 
    struct sockaddr_in addr;  
    int len;  
    int nListenFd, nAcceptFd;  
 
    // 初始化  
    cutil_init();  
    cutil_log_set_level(LOG_ALL);  
    cutil_log_set_stderr(1);  
    SSLeay_add_ssl_algorithms();  
    OpenSSL_add_all_algorithms();  
    SSL_load_error_strings();  
    ERR_load_BIO_strings();  
 
    // 我们使用SSL V3,V2  
    EXIT_IF_TRUE((ctx = SSL_CTX_new (SSLv23_method())) == NULL);  
 
    // 要求校验对方证书  
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);  
 
    // 加载CA的证书  
    EXIT_IF_TRUE (!SSL_CTX_load_verify_locations(ctx, "cacert.cer", NULL));  
 
    // 加载自己的证书  
    EXIT_IF_TRUE (SSL_CTX_use_certificate_file(ctx, "server.cer", SSL_FILETYPE_PEM) <= 0) ;  
 
    // 加载自己的私钥  
    EXIT_IF_TRUE (SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM) <= 0) ;  
 
    // 判定私钥是否正确  
    EXIT_IF_TRUE (!SSL_CTX_check_private_key(ctx));  
 
    // 创建并等待连接  
    nListenFd = cutil_socket_new(SOCK_STREAM);  
    cutil_socket_bind(nListenFd, NULL, 8812, 1);  
 
    memset(&addr, 0, sizeof(addr));  
    len = sizeof(addr);  
    nAcceptFd = accept(nListenFd, (struct sockaddr *)&addr, (size_t *)&len);  
    cutil_log_debug("Accept a connect from [%s:%d]\n",   
        inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));  
 
    // 将连接付给SSL  
    EXIT_IF_TRUE( (ssl = SSL_new (ctx)) == NULL);  
    SSL_set_fd (ssl, nAcceptFd);  
    EXIT_IF_TRUE( SSL_accept (ssl) != 1);  
 
    // 进行操作  
    memset(szBuffer, 0, sizeof(szBuffer));  
    nLen = SSL_read(ssl,szBuffer, sizeof(szBuffer));  
    fprintf(stderr, "Get Len %d %s ok\n", nLen, szBuffer);  
    strcat(szBuffer, " this is from server");  
    SSL_write(ssl, szBuffer, strlen(szBuffer));  
 
    // 释放资源  
    SSL_free (ssl);  
    SSL_CTX_free (ctx);  
    close(nAcceptFd);  
}  

客户端代码

#include "openssl/bio.h"  
#include "openssl/ssl.h"  
#include "openssl/err.h"  
 
#include <cutil.h>  
 
#define EXIT_IF_TRUE(x) if (x)                              \  
    do {                                                    \  
            fprintf(stderr, "Check '%s' is true\n", #x);    \  
            ERR_print_errors_fp(stderr);                    \  
            exit(2);                                        \  
    }while(0)  
 
int main(int argc, char **argv)  
{  
    SSL_METHOD  *meth;  
    SSL_CTX     *ctx;  
    SSL         *ssl;  
 
    int nFd;  
    int nLen;  
    char szBuffer[1024];  
 
    // 初始化  
    cutil_init();  
    cutil_log_set_level(LOG_ALL);  
    cutil_log_set_stderr(1);  
    SSLeay_add_ssl_algorithms();  
    OpenSSL_add_all_algorithms();  
    SSL_load_error_strings();  
    ERR_load_BIO_strings();  
 
    // 我们使用SSL V3,V2      
    EXIT_IF_TRUE((ctx = SSL_CTX_new (SSLv23_method())) == NULL);  
 
    // 要求校验对方证书  
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);  
 
    // 加载CA的证书  
    EXIT_IF_TRUE (!SSL_CTX_load_verify_locations(ctx, "cacert.cer", NULL));  
 
    // 加载自己的证书  
    EXIT_IF_TRUE (SSL_CTX_use_certificate_file(ctx, "client.cer", SSL_FILETYPE_PEM) <= 0) ;  
 
    // 加载自己的私钥  
    EXIT_IF_TRUE (SSL_CTX_use_PrivateKey_file(ctx, "client.key", SSL_FILETYPE_PEM) <= 0) ;  
 
    // 判定私钥是否正确  
    EXIT_IF_TRUE (!SSL_CTX_check_private_key(ctx));  
      
    // 创建连接  
    nFd = cutil_socket_new(SOCK_STREAM);  
    if(cutil_socket_connect(nFd, "127.0.0.1", 8812, 30) < 0)  
    {  
        cutil_log_error("连接服务器失败\n");  
        return -1;  
    }  
 
    // 将连接付给SSL  
    EXIT_IF_TRUE( (ssl = SSL_new (ctx)) == NULL);  
    SSL_set_fd (ssl, nFd);  
    EXIT_IF_TRUE( SSL_connect (ssl) != 1);  
 
    // 进行操作  
    sprintf(szBuffer, "this is from client %d", getpid());  
    SSL_write(ssl, szBuffer, strlen(szBuffer));  
 
    // 释放资源  
    memset(szBuffer, 0, sizeof(szBuffer));  
    nLen = SSL_read(ssl,szBuffer, sizeof(szBuffer));  
    fprintf(stderr, "Get Len %d %s ok\n", nLen, szBuffer);  
      
    SSL_free (ssl);  
    SSL_CTX_free (ctx);  
    close(nFd);  
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: