OpenSSL编程实例.doc

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

客户端程序

// OpenSSLClient.cpp

#include

#include

using namespace std;

#pragma comment (lib, "Ws2_32.lib")

#include "openssl/ssl.h"

#pragma comment(lib, "ssleay32.lib")

#pragma comment(lib, "libeay32.lib")

#define SERVICE_PORT 10000

const int nBufSize = 512;

// 初始化2.2版本Winsock

int InitWinsock(){

WSADATA wsaData = {0};

WORD wVer = MAKEWORD(2,2);

int nRet = WSAStartup(wVer, &wsaData);

if(nRet != 0){

cout<<"Winsock初始化失败,错误代码是"<

}

return nRet;

}

// 创建一个套接字

SOCKET CreateSocket(){

SOCKET hSocket = INVALID_SOCKET;

hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if(hSocket == INVALID_SOCKET){

int last_err = WSAGetLastError();

cout<<"创建套接字失败,错误代码是"<

}

return hSocket;

}

// 连接到服务器

int ConnectServer(SOCKET hSocket){

// 填充远程套接字地址

SOCKADDR_IN saServer = {0};

saServer.sin_family = AF_INET;

saServer.sin_port = htons(SERVICE_PORT);

saServer.sin_addr.s_addr = inet_addr("127.0.0.1");

// 使用远程套接字地址连接到服务器

int nRet = connect(hSocket, (SOCKADDR *)&saServer, sizeof(saServer));

if(nRet == SOCKET_ERROR){

int last_err = WSAGetLastError();

cout<<"连接失败,错误代码是"<

}

return nRet;

}

bool InitOpenSSL(){

if(!SSL_library_init())

return false;

SSL_load_error_strings();

return true;

}

int PasswordCB(char *buf, int size, int flag, void *userdata){

// 作者所创建的客户端程序私匙密码是12345678

const char* pass = "12345678";

if(size < strlen(pass) + 1)

return(0);

strcpy(buf, pass);

return(strlen(pass));

}

int VerifyCB(int ok, X509_STORE_CTX *store){

if(!ok){

int err = X509_STORE_CTX_get_error(store);

cout<

}

return ok;

}

SSL_CTX* InitSSLContext(){

const SSL_METHOD *meth = NULL;

SSL_CTX* ctx = NULL;

meth = SSLv23_method();

ctx = SSL_CTX_new(meth);

// 加载客户端程序证书链

if(!SSL_CTX_use_certificate_chain_file(ctx, "ClientAppChain.pem")){ cout<<"加载客户端程序证书链失败"<

return NULL;

}

SSL_CTX_set_default_passwd_cb(ctx, PasswordCB);

// 加载客户端程序私匙文件

if(!SSL_CTX_use_PrivateKey_file(ctx, "ClientApp_PrivateKey.pem",

SSL_FILETYPE_PEM)){

cout<<"加载客户端程序私匙文件失败"<

return NULL;

}

// 加载客户端程序所信任的CA

if(!SSL_CTX_load_verify_locations(ctx, "MyTestCA_Certificate.pem",

NULL)){

cout<<"加载客户端程序所信任的CA失败"<

return NULL;

}

// 加载OpenSSL缺省信任的CA

if(!SSL_CTX_set_default_verify_paths(ctx)){

cout<<" 加载OpenSSL缺省信任的CA失败"<

return NULL;

}

// 我们知道,服务器的证书链是serverApp-->ServerCA-->MyTestCA,

// 所以可以明确验证深度是2,即最多检查ServerCA和MyTestCA两个CA SSL_CTX_set_verify_depth(ctx, 2);

// SSL_VERIFY_PEER要求服务器提供证书,VerifyCB用于输出OpenSSL

// 握手过程中验证服务器证书链失败时的错误信息

SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, VerifyCB);

SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);

return ctx;

}

// 简单的校验,仅检查common name

bool CheckCertificate(SSL* ssl){

X509* cert = SSL_get_peer_certificate(ssl);

if(cert == NULL)

return false;

X509_NAME* subjectName = X509_get_subject_name(cert);

if(subjectName == NULL)

return false;

char buf[256];

相关文档
最新文档