我正在編寫https代理。而我的程序有兩個錯誤。 15883:錯誤:0906D06C:PEM套路:PEM_read_bio:無從下手行:pem_lib.c:644:期待:證書 15883:錯誤:140AD009:SSL例程:SSL_CTX_use_certificate_file:PEM LIB:ssl_rsa.c:491:SSL:錯誤:0906D06C:PEM例程:PEM_read_bio:無起始行:pem_lib.c:644:預計:CERTIFICATE
。這是我的代碼,我不知道哪裏是wrong.please幫我
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <resolv.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <pthread.h>
#define SIZE 1024
#define PKEY "cacert.pem"
#define CERTT "privkey.pem"
pthread_mutex_t mut;
int counter = 0;
char url[400] = {0};
unsigned long GetIp(char domainname[250])
{
struct sockaddr_in sin;
struct hostent *phost;
if((phost = gethostbyname(domainname)) == NULL)
{
perror("gethostbyname error\n");
return 0;
}
sin.sin_addr = *((struct in_addr *)phost->h_addr_list[0]);
const char *ip = inet_ntoa(sin.sin_addr);
printf("ip is %s\n", ip);
return sin.sin_addr.s_addr;
}
void ShowCerts(SSL * ssl)
{
X509 *cert;
char *line;
cert = SSL_get_peer_certificate(ssl);
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");
}
char *SendWeb(char buf[])
{
char *buffer1 ;
int sockfd;
int len;
struct sockaddr_in web;
SSL_CTX *ctx;
SSL *ssl;
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
perror("socket create failed!\n");
exit(errno);
}
bzero(&web,sizeof(web));
web.sin_family = AF_INET;
web.sin_port = htons(443);
// web.sin_addr.s_addr = inet_addr("110.75.146.111");
web.sin_addr.s_addr = GetIp(url);
if(connect(sockfd,(struct sockaddr *)&web,sizeof(web)) != 0)
{
perror("connect error!\n");
exit(errno);
}
ssl = SSL_new(ctx);
SSL_set_fd(ssl,sockfd);
if(SSL_connect(ssl) == -1)
{
ERR_print_errors_fp(stderr);
}
ShowCerts(ssl);
bzero(buffer1,SIZE);
len = SSL_write(ssl,buf,SIZE);
if(len < 0)
{
printf("SendWeb error!\n");
}
else
{
printf("Send sucess is %s\n", buf);
}
len = SSL_read(ssl,buffer1,SIZE);
if(len > 0)
{
printf("Recv Web : %s\n", buffer1);
}
else
{
printf("Recv Web Error!錯誤代碼:%d,錯誤信息:%s.\n", errno,strerror(errno));
}
return buffer1;
}
char RecvBro()
{
//char url[400] = {0};
int i, sockfd , client_fd,new_fd;
struct sockaddr_in mim_ser,brow;
int len;
char *index_start,*index_end,*buf;
SSL_CTX *ctx;
ctx = SSL_CTX_new(SSLv23_server_method());//以ssl v2 v3 標準敬愛內容方式產生一個SSL_CTX
if(ctx == NULL)
{
ERR_print_errors_fp(stdout);
exit(1);
}
//載入用戶數字證書,發給客戶端,包含公鑰
if(!SSL_CTX_use_certificate_file(ctx,CERTT,SSL_FILETYPE_PEM))
{
ERR_print_errors_fp(stdout);
exit(1);
}
//載入用戶私鑰
if(SSL_CTX_use_PrivateKey_file(ctx,PKEY,SSL_FILETYPE_PEM))
{
ERR_print_errors_fp(stdout);
exit(1);
}
if(!SSL_CTX_check_private_key(ctx))
{
ERR_print_errors_fp(stdout);
exit(1);
}
if((sockfd=socket(PF_INET,SOCK_STREAM,0))== -1)
{
perror("socket create failed");
exit(1);
}
bzero(&mim_ser,sizeof(mim_ser));
mim_ser.sin_family = PF_INET;
mim_ser.sin_port = htons(443);
mim_ser.sin_addr.s_addr = INADDR_ANY;
if((bind(sockfd,(struct sockaddr *)&mim_ser,sizeof(struct sockaddr))) == -1)
{
perror("bind failed");
exit(1);
}
if(listen(sockfd,10) == -1)
{
perror("listen error");
exit(1);
}
SSL *ssl;
int len2 = sizeof (struct sockaddr);
if((new_fd = accept(sockfd,(struct sockaddr *)&brow,&len2)) == -1)
{
perror("accept error");
exit(1);
}
//基於ctx產生一個新的ssl
ssl = SSL_new(ctx);
SSL_set_fd(ssl,new_fd);//將連接用戶的socket加入SSL
if(SSL_accept(ssl) == -1)
{
perror("accept");
close(new_fd);
}
buf = (char *)malloc(SIZE);
// char buf[SIZE]= {0};
bzero(buf,SIZE);
len = SSL_read(ssl,buf,SIZE);
if(len > 0)
{
printf("recv from browser is %s\n",buf);
}
else
{
printf("RECV ERROR!錯誤代碼:%s,錯誤信息:%s\n",errno,strerror);
}
index_start = strstr(buf,"Host:");
index_end = strstr(index_end,"\r\n");
if(index_start == NULL ||index_end == NULL)
{
perror("index_start or index_end is NULL\n");
}
if((i = (int)(index_start - index_end)) <= 0)
{
perror("index_start - index_end <= 0 \n");
}
bzero(url,400);
strncpy(url,index_start + 6, i-6);
buf = SendWeb(buf);
len = SSL_write(ssl,buf,SIZE);
if(len <= 0)
{
printf("\nSend sucess!\n");
}
}
int main()
{
ERR_load_BIO_strings();
SSL_library_init();//ssl庫初始化
OpenSSL_add_all_algorithms();//載入所有ssl算法
SSL_load_error_strings();//載入所有ssl從錯誤消息
pthread_mutex_init(&mut,NULL);
while(1)
{
pthread_t work_thread;
if(pthread_create(&work_thread,NULL,(void *)&RecvBro,NULL))
{
perror("create thread error\n");
}
else
{
pthread_mutex_lock(&mut);
counter++;
pthread_mutex_unlock(&mut);
pthread_detach(work_thread);
}
}
pthread_mutex_destroy(&mut);
}
我這樣做就像你說的,但有更多的錯誤。 '9478:錯誤:0906D06C:PEM例程:PEM_read_bio:無起始行:pem_lib.c:644:預計:CERTIFICATE' ........更多..... – user3193163
我更新了我的答案,更多建議,請檢查。 – vond