在c中使用openssl库读取ssl数据时出现问题
此程序使用openssl保护http连接:在c中使用openssl库读取ssl数据时出现问题,c,sockets,ssl,openssl,C,Sockets,Ssl,Openssl,此程序使用openssl保护http连接: #include <openssl/ssl.h> #include <openssl/bio.h> #include <openssl/err.h> #include <openssl/crypto.h> #include <openssl/bn.h> #include <string.h> #include <sys/socket.h> #include <ne
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/crypto.h>
#include <openssl/bn.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define IP_ADDR INADDR_ANY
#define PORT 8081
int password_cb(char *buf, int size, int rwflag, void *password);
EVP_PKEY *generatePrivateKey();
X509 *generateCertificate(EVP_PKEY *pkey);
/**
* Example SSL server that accepts a client and echos back anything it receives.
* Test using `curl -I https://127.0.0.1:8081 --insecure --sslv3`
*/
int main(int arc, char **argv)
{
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
printf("opening socket\n");
return -4;
}
struct sockaddr_in s_addr;
bzero((char *)&s_addr, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_addr.s_addr = IP_ADDR;
s_addr.sin_port = htons(PORT);
if (bind(fd, (struct sockaddr*)&s_addr, sizeof(s_addr)) < 0) {
printf("binding\n");
return -5;
}
listen(fd, 2);
int cfd;
while (cfd = accept(fd, 0, 0))
{
SSL_load_error_strings();
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
SSL_library_init();
SSL_CTX *ctx = SSL_CTX_new(SSLv3_server_method());
//SSL_CTX *ctx = SSL_CTX_new(TLS_server_method());
if (ctx == NULL) {
printf("errored; unable to load context.\n");
ERR_print_errors_fp(stderr);
return -3;
}
EVP_PKEY *pkey = generatePrivateKey();
X509 *x509 = generateCertificate(pkey);
SSL_CTX_use_certificate(ctx, x509);
SSL_CTX_set_default_passwd_cb(ctx, password_cb);
SSL_CTX_use_PrivateKey(ctx, pkey);
RSA *rsa=RSA_generate_key(512, RSA_F4, NULL, NULL);
SSL_CTX_set_tmp_rsa(ctx, rsa);
RSA_free(rsa);
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
SSL *ssl = SSL_new(ctx);
BIO *accept_bio = BIO_new_socket(cfd, BIO_CLOSE);
SSL_set_bio(ssl, accept_bio, accept_bio);
SSL_accept(ssl);
BIO *bio = BIO_pop(accept_bio);
char buf[1024];
FILE *file1 = fopen("logfile", "a");
while (1)
{
// first read data
int r = SSL_read(ssl, buf, 1024);
ERR_print_errors_fp(file1);
printf ("\nsize of read data : %d\n", r);
printf ("actual data : %s\n", buf);
switch (SSL_get_error(ssl, r))
{
case SSL_ERROR_NONE:
break;
case SSL_ERROR_ZERO_RETURN:
goto end;
default:
printf("SSL read problem");
goto end;
}
int len = r;
// now keep writing until we've written everything
int offset = 0;
while (len)
{
r = SSL_write(ssl, buf + offset, len);
switch (SSL_get_error(ssl, r))
{
case SSL_ERROR_NONE:
len -= r;
offset += r;
break;
default:
printf("SSL write problem");
goto end;
}
}
}
end:
SSL_shutdown(ssl);
BIO_free_all(bio);
BIO_free_all(accept_bio);
}
return 0;
}
int password_cb(char *buf, int size, int rwflag, void *password)
{
strncpy(buf, (char *)(password), size);
buf[size - 1] = '\0';
return strlen(buf);
}
EVP_PKEY *generatePrivateKey()
{
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
EVP_PKEY_keygen_init(pctx);
EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, 2048);
EVP_PKEY_keygen(pctx, &pkey);
return pkey;
}
X509 *generateCertificate(EVP_PKEY *pkey)
{
X509 *x509 = X509_new();
X509_set_version(x509, 2);
ASN1_INTEGER_set(X509_get_serialNumber(x509), 0);
X509_gmtime_adj(X509_get_notBefore(x509), 0);
X509_gmtime_adj(X509_get_notAfter(x509), (long)60*60*24*365);
X509_set_pubkey(x509, pkey);
X509_NAME *name = X509_get_subject_name(x509);
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (const unsigned char*)"US", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const unsigned char*)"YourCN", -1, -1, 0);
X509_set_issuer_name(x509, name);
X509_sign(x509, pkey, EVP_md5());
return x509;
}
变量r是ssl_读取并存储在buf变量中的数据长度。当我打印它们时,我得到以下结果:
r : -1
buf : �zvԞ
该程序在具有相同操作系统和openssl版本的另一个系统上正确运行。
两个系统上的cat/etc/问题输出:
Debian GNU/Linux 8 \n \l
两个系统上的openssl版本-a的输出:
OpenSSL 1.0.1t 3 May 2016
built on: Wed Sep 25 17:53:16 2019
platform: debian-amd64
options: bn(64,64) rc4(16x,int) des(idx,cisc,16,int blowfish(idx)
compiler: gcc -I. -I.. -I../include -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
OPENSSLDIR: "/usr/lib/ssl"
但在有问题的系统上,openssl版本的顶部还有一行输出:
WARNING: can't open config file: /usr/lib/ssl/openssl.cnf
但路径中存在openssl.cnf。为什么程序不能正确读取https请求
编辑出现问题的系统是一个lxc容器,我在其上安装了openssl,并复制了openssl文件和目录 路径中存在openssl.cnf。为什么程序不能正确读取https请求-检查文件
/usr/lib/ssl/openssl.cnf
的权限。可能您的库/进程无法访问它。我已授予openssl.conf 777权限,但警告消息存在,ssl数据无法读取。@alk该程序在其他系统上正常工作。我认为acceptForget没有问题忘记我以前的评论(已经删除)。我被破损的压痕弄糊涂了。现在修复这个问题。我不知道这是否有帮助,但每次我停止程序并再次运行它时,buf都会改变。一次�j+�, 下次�Jb� ...路径中存在openssl.cnf。为什么程序不能正确读取https请求-检查文件/usr/lib/ssl/openssl.cnf
的权限。可能您的库/进程无法访问它。我已授予openssl.conf 777权限,但警告消息存在,ssl数据无法读取。@alk该程序在其他系统上正常工作。我认为acceptForget没有问题忘记我以前的评论(已经删除)。我被破损的压痕弄糊涂了。现在修复这个问题。我不知道这是否有帮助,但每次我停止程序并再次运行它时,buf都会改变。一次�j+�, 下次�Jb� ...
WARNING: can't open config file: /usr/lib/ssl/openssl.cnf