openssl 调用实例

13 篇文章 0 订阅
12 篇文章 0 订阅


openssl C/C++ SSL安全套接层SOCKET示例,各个API功能详见OPENSSL官方文档。


客户端:

/* g++ -o client ssl_client.cpp -lssl -lcrypt */
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

// openssl header file
#include <openssl/x509.h>
#include <openssl/ssl.h>
//#include <openssl/srtp.h>

#define CA_CERT		"cacert.pem"
#define CLIENT_KEY	"clientkey.pem"
#define CLIENT_CERT	"clientcert.pem"
#define SERVER_IP	"127.0.0.1"
#define SERVER_PORT	12345

#define RET_IF_EQ(key,val,ret,msg){\
    if(key == val){\
        fprintf(stderr,"%s failed.\n",msg);\
	return ret;\
    }else{\
	fprintf(stderr,"%s success.\n",msg);\
    }\
}
#define RET_IF_LT(key,val,ret,msg){\
    if(key < val){\
        fprintf(stderr,"%s failed.\n",msg);\
        return ret;\
    }else{\
        fprintf(stderr,"%s success.\n",msg);\
    }\
}

int ssl_init(SSL_CTX **ctx,char *pass){
    int ret = 0;
    OpenSSL_add_ssl_algorithms();
    const SSL_METHOD *meth = SSLv23_client_method();
    *ctx = SSL_CTX_new(meth);
    RET_IF_EQ(*ctx,NULL,-1,"SSL_CTX_new()");

    SSL_CTX_set_verify(*ctx,SSL_VERIFY_PEER,NULL);// set verify
    SSL_CTX_load_verify_locations(*ctx,CA_CERT,NULL); //load ca cert

    ret = SSL_CTX_use_certificate_file(*ctx,CLIENT_CERT,SSL_FILETYPE_PEM);
    RET_IF_LT(ret,1,-1,"SSL_CTX_use_certificate_file()");

    (*ctx)->default_passwd_callback_userdata = pass;
    ret = SSL_CTX_use_PrivateKey_file(*ctx,CLIENT_KEY,SSL_FILETYPE_PEM);
    RET_IF_LT(ret,1,-1,"SSL_CTX_use_PrivateKey_file()");

    ret = SSL_CTX_check_private_key(*ctx);
    RET_IF_EQ(ret,0,-1,"SSL_CTX_check_private_key()");
    return 0;    
}
int ssl_destroy(SSL_CTX **ctx){
    int ret = 0;
    SSL_CTX_free(*ctx);
    *ctx = NULL;
    return ret;
}
int ssl_connect(char *ip,int port,int *fd,SSL **ssl,SSL_CTX *ctx){
    int ret = 0;
    *fd = socket(AF_INET,SOCK_STREAM,0);
    RET_IF_LT(*fd,0,-1,"init_socket()");

    struct sockaddr_in sa;
    memset(&sa,0,sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = inet_addr(ip);
    sa.sin_port = htons(port);

    ret = connect(*fd,(struct sockaddr*)&sa,sizeof(sa));
    RET_IF_LT(ret,0,-1,"connect()");

    *ssl = SSL_new(ctx);
    RET_IF_EQ(*ssl,NULL,-1,"SSL_new");
    SSL_set_fd(*ssl,*fd);
    ret = SSL_connect(*ssl);
    RET_IF_LT(ret,0,-1,"SSL_connect()");
    X509 *server_cert = SSL_get_peer_certificate(*ssl);
    RET_IF_EQ(server_cert,NULL,-1,"SSL_get_peer_certificate()");
    char *str = X509_NAME_oneline(X509_get_subject_name(server_cert),0,0);
    fprintf(stderr,"subject:[%s]\n",str);
    free(str);
    str =  X509_NAME_oneline(X509_get_issuer_name(server_cert),0,0);
    fprintf(stderr,"issuer:[%s]\n",str);
    free(str);
    X509_free(server_cert);
        
    return 0;
}
int ssl_disconnect(SSL *ssl,int fd){
    SSL_shutdown(ssl);
    close(fd);
    SSL_free(ssl);
    return 0;
}

int main(){
    int ret = 0;
    SSL_CTX *ctx     = NULL;
    SSL_METHOD *meth = NULL;
    SSL *ssl         = NULL;
    int fd = 0;
    char ip[] = "127.0.0.1";
    int  port = 12345;
    char pass[] = "abc123";

    ssl_init(&ctx,pass);
    ssl_connect(ip,port,&fd,&ssl,ctx);
   
    int i = 0;
    char buf[1025];
    for(i=0;i<10;i++){
	memset(buf,0,1025);
	snprintf(buf,1024,"ssl test send message index:[%d]",i);
	ret = SSL_write(ssl,buf,strlen(buf));
	fprintf(stderr,"send ret:[%d] msg:[%s]\n",ret,buf);
	memset(buf,0,1025);
	ret = SSL_read(ssl,buf,1024);
	if(ret < 1){
	    break;
	}
	fprintf(stderr,"recv ret:[%d] msg:[%s]\n",ret,buf);
    }
    ssl_disconnect(ssl,fd);
    ssl_destroy(&ctx);    
    return ret;
}



服务端:

/* g++ -o server ssl_server.cpp -lssl -lcrypt */

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

// openssl header file
#include <openssl/x509.h>
#include <openssl/ssl.h>

#define CA_CERT		"cacert.pem"
#define CLIENT_KEY	"serverkey.pem"
#define CLIENT_CERT	"servercert.pem"
#define SERVER_IP	"127.0.0.1"
#define SERVER_PORT	12345

#define RET_IF_EQ(key,val,ret,msg){\
    if(key == val){\
        fprintf(stderr,"%s failed.\n",msg);\
	return ret;\
    }else{\
	fprintf(stderr,"%s success.\n",msg);\
    }\
}
#define RET_IF_LT(key,val,ret,msg){\
    if(key < val){\
        fprintf(stderr,"%s failed.\n",msg);\
        return ret;\
    }else{\
        fprintf(stderr,"%s success.\n",msg);\
    }\
}

int ssl_init(SSL_CTX **ctx,char *pass){
    int ret = 0;
    OpenSSL_add_ssl_algorithms();
    const SSL_METHOD *meth = SSLv23_server_method();
    *ctx = SSL_CTX_new(meth);
    RET_IF_EQ(*ctx,NULL,-1,"SSL_CTX_new()");

    SSL_CTX_set_verify(*ctx,SSL_VERIFY_PEER,NULL);// set verify
    SSL_CTX_load_verify_locations(*ctx,CA_CERT,NULL); //load ca cert

    ret = SSL_CTX_use_certificate_file(*ctx,CLIENT_CERT,SSL_FILETYPE_PEM);
    RET_IF_LT(ret,1,-1,"SSL_CTX_use_certificate_file()");
    
    (*ctx)->default_passwd_callback_userdata = pass;
    ret = SSL_CTX_use_PrivateKey_file(*ctx,CLIENT_KEY,SSL_FILETYPE_PEM);
    RET_IF_LT(ret,1,-1,"SSL_CTX_use_PrivateKey_file()");

    ret = SSL_CTX_check_private_key(*ctx);
    RET_IF_EQ(ret,0,-1,"SSL_CTX_check_private_key()");
    return 0;    
}
int ssl_destroy(SSL_CTX **ctx){
    int ret = 0;
    SSL_CTX_free(*ctx);
    *ctx = NULL;
    return ret;
}
int server_init(char *ip,int port,int *fd){
    int ret = 0;
    *fd = socket(AF_INET,SOCK_STREAM,0);
    RET_IF_LT(*fd,0,-1,"init_sock()");
    struct sockaddr_in serv_sa;
    memset(&serv_sa,0,sizeof(serv_sa));
    serv_sa.sin_family = AF_INET;
    serv_sa.sin_addr.s_addr = INADDR_ANY;
    serv_sa.sin_port = htons(port);
    ret = bind(*fd,(struct sockaddr*)&serv_sa,sizeof(serv_sa));
    RET_IF_LT(ret,0,-1,"bind()");
    ret = listen(*fd,5);
    RET_IF_LT(ret,0,-1,"listen()");
    return ret;
}
int server_destroy(int fd){
    close(fd);
    return 0;
}
int ssl_accept(int listen_fd,int *fd,SSL **ssl,SSL_CTX *ctx){
    int ret = 0;

    struct sockaddr_in sa;
    memset(&sa,0,sizeof(sa));
  
    socklen_t cli_len = sizeof(sa);
    *fd = accept(listen_fd,(struct sockaddr*)&sa,&cli_len);
    RET_IF_LT(*fd,0,-1,"accept()");
    //fprintf(stderr,"accept client fd:[%d] ip:[%s] port:[%d]\n",*fd,sa.sin_addr.s_addr,sa.sin_port);

    *ssl = SSL_new(ctx);
    RET_IF_EQ(*ssl,NULL,-1,"SSL_new");
    SSL_set_fd(*ssl,*fd);
    ret = SSL_accept(*ssl);
    RET_IF_LT(ret,0,-1,"SSL_connect()");
    X509 *server_cert = SSL_get_peer_certificate(*ssl);
    RET_IF_EQ(server_cert,NULL,-1,"SSL_get_peer_certificate()");
    char *str = X509_NAME_oneline(X509_get_subject_name(server_cert),0,0);
    fprintf(stderr,"subject:[%s]\n",str);
    free(str);
    str =  X509_NAME_oneline(X509_get_issuer_name(server_cert),0,0);
    fprintf(stderr,"issuer:[%s]\n",str);
    free(str);
    X509_free(server_cert);
        
    return 0;
}
int ssl_disconnect(SSL *ssl,int fd){
    SSL_shutdown(ssl);
    close(fd);
    SSL_free(ssl);
    return 0;
}

int main(){
    int ret = 0;
    SSL_CTX *ctx     = NULL;
    SSL *ssl         = NULL;
    int listen_fd=0,fd = 0;
    char ip[] = "127.0.0.1";
    int  port = 12345;
    char pass[] = "abc123";
    ssl_init(&ctx,pass);
    server_init(ip,port,&listen_fd);
    int i =0; 
    while(1){
	ssl_accept(listen_fd,&fd,&ssl,ctx);
	i=0;
    	while(1){
	    char buf[1025];
            memset(buf,0,1025);
	    ret = SSL_read(ssl,buf,1024);
            fprintf(stderr,"recv ret:[%d] msg:[%s]\n",ret,buf);
	    if(ret < 1) break;
	    memset(buf,0,1025);
	    snprintf(buf,1024,"server ssl test send message index:[%d]",i);
	    ret = SSL_write(ssl,buf,strlen(buf));
	    fprintf(stderr,"send ret:[%d] msg:[%s]\n",ret,buf);
	    i++;
	}
	ssl_disconnect(ssl,fd);
    }
    ssl_destroy(&ctx);
    server_destroy(listen_fd);
    return ret;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值