openssl中ssl编程问题

zhengqiang7564 2011-05-12 08:52:03
客户端的程序如下:
#include "stdio.h"
#include "stdlib.h"
#include "memory.h"
#include "windows.h"
#include "winsock.h"
#include "openssl/evp.h"
#include "openssl/x509.h"
#include "openssl/pem.h"
#include "openssl/ssl.h"
#include "openssl/err.h"

#define CHK_NULL(x) if ((x)==NULL) exit (1)
#define CHK_ERR(err,s) if ((err)==-1) {perror(s); exit(1);}
#define CHK_SSL(err) if ((err)==-1) {ERR_print_errors_fp(stderr), exit(2);}

void main()
{
int err;
int sd;
struct sockaddr_in sa;//sochaddr_in结构体,用于保存服务器端协议和端口信息
SSL_CTX *ctx; //SSL上下文句柄
SSL *ssl; //SSL结构体指针
X509 *server_cert;//X509结构体,用于保留客户端的证书
char *str;
char buf[4096];
SSL_METHOD *meth;//SSL协议
WSADATA wsaData;

if(WSAStartup(MAKEWORD(1,1), &wsaData))
{
return;
}

//初始化Openssl环境
SSL_load_error_strings();
SSLeay_add_ssl_algorithms();
// SSL协议版本,V2,V3自适应
meth=SSLv23_client_method();
//新建SSL上下文句柄
ctx=SSL_CTX_new(meth);
CHK_NULL(ctx);
CHK_SSL(err);

sd=socket(AF_INET, SOCK_STREAM, 0);
CHE_ERR(sd,"socket");

memset(&sa, '\0', sizeof(sa));
sa.sin_family=AF_INET;
sa.sin_addr.s_addr=inet_addr("127.0.0.1");
sa.sin_port=htons(8443);
//链接服务器
err=connect(sd, (struct sockaddr*) &sa, sizeof(sa));
CHK_ERR(err,"connect");

//现在使用现有的TCP链接开启SSL协议
ssl=SSL_new(ctx);
CHK_NULL(ssl);

//设置ssl句柄到ssl结构体
SSL_set_fd(ssl,sd);

err=ssl_conect(ssl);
CHK_SSL(err);

//打印SSL链接的算法
printf("SSL connection using %s\n",SSL_get_cipher(ssl));

//获取服务器证书
server_cert=SSL_get_peer_certificate(ssl);
CHK_NULL(server_cert);
printf("server Certificate: \n");

str=X509_NAME_oneline(X509_get_subject_name(server_cert),0,0);
CHK_NULL(str);
printf("\t subject; %s \n", str);
OPENSSL_free(str);

str=X509_NAME_oneline(X509_get_issuer_name(server_cert),0,0);
CHK_NULL(str);
printf("\t issuer; %s \n", str);
OPENSSL_free(str);
X509_free(server_cert);

err=SSL_write(ssl, "Hello Workd!", strlen("Hello World!"));
CHK_SSL(err);
err=SSL_read(ssl, buf, sizeof(buf)-1);
CHK_SSL(err);
buf[err]='\0';
printf("got %d chars: '%s' \n", err,buf);
SSL_Shutdown(ssl); //发送SSL关闭消息

closesocket(sd);
SSL_free(ssl);
SSK_CTX_free(ctx);
}

服务器端的程序如下:
#include "stdio.h"
#include "stdlib.h"
#include "memory.h"
#include "windows.h"
#include "winsock.h"
#include "openssl/evp.h"
#include "openssl/x509.h"
#include "openssl/pem.h"
#include "openssl/ssl.h"
#include "openssl/err.h"



#define CERTF "cert.cer"
#define KEYF "key.pem"
#define ROOTCERTF "root.cer"
#define CHK_NULL(x) if ((x)==NULL) exit (1)
#define CHK_ERR(err,s) if ((err)==-1) {perror(s); exit(1);}
#define CHK_SSL(err) if ((err)==-1) {ERR_print_errors_fp(stderr), exit(2);}

int main()
{
int err;
int listen_sd; //监听句柄
int sd;
struct sockaddr_in sa_serv;//sochaddr_in结构体,用于保存服务器端协议和端口信息
struct sockaddr_in sa_cli;
size_t client_len;
SSL_CTX *ctx; //SSL上下文句柄
SSL *ssl; //SSL结构体指针
X509 *client_cert;//X509结构体,用于保留客户端的证书
char *str;
char buf[4096];
SSL_METHOD *meth;//SSL协议
WSADATA wsaData;

//初始化windows Socket环境
if(WSAStartup(MAKEWORD(1,1), &wsaData))
{
exit(1);
}

//初始化Openssl环境
SSL_load_error_strings();
SSLeay_add_ssl_algorithms();
// SSL协议版本,V2,V3自适应
meth=SSLv23_server_method();
//新建SSL上下文句柄
ctx=SSL_CTX_new(meth);
if(!ctx)
{
ERR_print_errors_fp(stderr);
exit(2);
}

//设置服务器证书
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(ctx, KEYF, SSL_FILETYPE_PEM)<=0)
{
ERR_print_errors_fp(stderr);
exit(4);
}

//检查私钥和证书是否匹配
if(SSL_CTX_check_private_key(ctx))
{
printf(stderr,"private key does not match the certificate public key\n");
exit(5);
}

//新建Socket
listen_sd=socket(AF_INET, SOCK_STREAM, 0);
CHE_ERR(listen_sd,"socket");
//初始化sa_serv,设置为TCP协议,端口为8443
memset(&sa_serv, '\0', sizeof(sa_serv));
sa_serv.sin_family=AF_INET;
sa_serv.sin_addr.s_addr=INADDR_ANY;
sa_serv.sin_port=htons(8443);
//绑定端口
err=bind(listen_sd, (struct sockaddr*) &sa_serv, sizeof(sa_serv));
CHK_ERR(err,"bind");

//开始接受TCP链接
err=listem(listen_sd,5);
CHK_ERR(err,"listen");
client_len=sizeof(sa_cli);
//接受客户端TCP链接
sd=accept(listen_sd, (struct sockaddr*) &sa_cli, &client_len);
CHK_ERR(sd,"accept");
vlisesocket(listen_sd);

//打印客户端信息
printf("connection from %lx, port %x\n", sa_cli.sin_addr.s_addr, sa_cli.sin_port);

//新建SSL
ssl=SSL_new(ctx);
CHK_NULL(ssl);
//设置ssl句柄到ssl结构体
SSL_set_fd(ssl,sd);
//接受ssl链接
err=ssl_accept(ssl);
CHK_SSL(err);
//活动ssl链接用到的算法
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 certififate\n");
//获取客户端发送的消息
err=SSL_read(ssl, buf,sizeof(buf)-1);
CHK_SSL(err);
buf[err]='\0';
printf("got %d chars: '%s' \n",err, buf);
err=SSL_write(ssl, "I heard you!", strlen("I heard you"));
CHK_SSL(err);

closesocket(sd);
SSL_free(ssl);
SSL_CTX_free(ssl);
return 0;

}

编译后服务器端出现的错误为:
server.obj : error LNK2001: unresolved external symbol _closesocket@4
server.obj : error LNK2001: unresolved external symbol _ssl_accept
server.obj : error LNK2001: unresolved external symbol _vlisesocket
server.obj : error LNK2001: unresolved external symbol _accept@12
server.obj : error LNK2001: unresolved external symbol _listem
server.obj : error LNK2001: unresolved external symbol _bind@12
server.obj : error LNK2001: unresolved external symbol _htons@4
server.obj : error LNK2001: unresolved external symbol _CHE_ERR
server.obj : error LNK2001: unresolved external symbol _socket@12
server.obj : error LNK2001: unresolved external symbol _WSAStartup@8
客户端出现的错误为
client.obj : error LNK2001: unresolved external symbol _SSK_CTX_free
client.obj : error LNK2001: unresolved external symbol _closesocket@4
client.obj : error LNK2001: unresolved external symbol _SSL_Shutdown
client.obj : error LNK2001: unresolved external symbol _ssl_conect
client.obj : error LNK2001: unresolved external symbol _connect@12
client.obj : error LNK2001: unresolved external symbol _htons@4
client.obj : error LNK2001: unresolved external symbol _inet_addr@4
client.obj : error LNK2001: unresolved external symbol _CHE_ERR
client.obj : error LNK2001: unresolved external symbol _socket@12
client.obj : error LNK2001: unresolved external symbol _WSAStartup@8
Debug/SSL_client.exe : fatal error LNK1120: 10 unresolved externals


我猜也许是找不到库ssleay32.lib,我觉得我在windows下安装openssl的过程是正确的,因为libeay32.lib库是可以找到的,而ssleay32.lib的库我也能找到。
洗碗大侠们能够帮忙解决一下。
...全文
491 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
aijianmeng 2011-05-13
  • 打赏
  • 举报
回复
客户端出现的错误为
client.obj : error LNK2001: unresolved external symbol _SSK_CTX_free ====>SSL_CTX_free
client.obj : error LNK2001: unresolved external symbol _closesocket@4
client.obj : error LNK2001: unresolved external symbol _SSL_Shutdown ====>SSL_shutdown
client.obj : error LNK2001: unresolved external symbol _ssl_conect ====>SSL_connect
client.obj : error LNK2001: unresolved external symbol _connect@12
client.obj : error LNK2001: unresolved external symbol _htons@4
client.obj : error LNK2001: unresolved external symbol _inet_addr@4
client.obj : error LNK2001: unresolved external symbol _CHE_ERR
client.obj : error LNK2001: unresolved external symbol _socket@12
client.obj : error LNK2001: unresolved external symbol _WSAStartup@8

剩下的是没有添加socket的库,添加#pragma comment(lib, "wsock32.lib")
具体的见下面。

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <windows.h>
#include <winsock.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#pragma comment(lib, "wsock32.lib")
#define CHK_NULL(x) if ((x)==NULL) exit (1)
#define CHK_ERR(err,s) if ((err)==-1) {perror(s); exit(1);}
#define CHK_SSL(err) if ((err)==-1) {ERR_print_errors_fp(stderr), exit(2);}

void main()
{
int err;
int sd;
struct sockaddr_in sa;//sochaddr_in结构体,用于保存服务器端协议和端口信息
SSL_CTX *ctx; //SSL上下文句柄
SSL *ssl; //SSL结构体指针
X509 *server_cert;//X509结构体,用于保留客户端的证书
char *str;
char buf[4096];
SSL_METHOD *meth;//SSL协议
WSADATA wsaData;

if(WSAStartup(MAKEWORD(1,1), &wsaData))
{
return;
}

//初始化Openssl环境
SSL_load_error_strings();
SSLeay_add_ssl_algorithms();
// SSL协议版本,V2,V3自适应
meth=SSLv23_client_method();
//新建SSL上下文句柄
ctx=SSL_CTX_new(meth);
CHK_NULL(ctx);
CHK_SSL(err);

sd=socket(AF_INET, SOCK_STREAM, 0);
CHK_ERR(sd,"socket");

memset(&sa, '\0', sizeof(sa));
sa.sin_family=AF_INET;
sa.sin_addr.s_addr=inet_addr("127.0.0.1");
sa.sin_port=htons(8443);
//链接服务器
err=connect(sd, (struct sockaddr*) &sa, sizeof(sa));
CHK_ERR(err,"connect");

//现在使用现有的TCP链接开启SSL协议
ssl=SSL_new(ctx);
CHK_NULL(ssl);

//设置ssl句柄到ssl结构体
SSL_set_fd(ssl,sd);

err=SSL_connect(ssl);
CHK_SSL(err);

//打印SSL链接的算法
printf("SSL connection using %s\n",SSL_get_cipher(ssl));

//获取服务器证书
server_cert=SSL_get_peer_certificate(ssl);
CHK_NULL(server_cert);
printf("server Certificate: \n");

str=X509_NAME_oneline(X509_get_subject_name(server_cert),0,0);
CHK_NULL(str);
printf("\t subject; %s \n", str);
OPENSSL_free(str);

str=X509_NAME_oneline(X509_get_issuer_name(server_cert),0,0);
CHK_NULL(str);
printf("\t issuer; %s \n", str);
OPENSSL_free(str);
X509_free(server_cert);

err=SSL_write(ssl, "Hello Workd!", strlen("Hello World!"));
CHK_SSL(err);
err=SSL_read(ssl, buf, sizeof(buf)-1);
CHK_SSL(err);
buf[err]='\0';
printf("got %d chars: '%s' \n", err,buf);
SSL_shutdown(ssl); //发送SSL关闭消息

closesocket(sd);
SSL_free(ssl);
SSL_CTX_free(ctx);
}

MSOKD 2011-05-12
  • 打赏
  • 举报
回复
函数名不对呗,注意大小写

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧