SSL_load_error_strings()
时间: 2023-08-15 11:06:55 浏览: 290
SSL_load_error_strings() 是一个函数,它用于加载 OpenSSL 库中的错误字符串信息。在使用 OpenSSL 进行 SSL/TLS 通信时,如果出现错误,可以通过调用 SSL_load_error_strings() 函数来获取相应的错误信息。
这个函数会将错误信息加载到 OpenSSL 库的错误堆栈中,以便在需要时可以通过其他函数获取并打印错误信息。这些错误信息包括错误码和相关的文本描述,可以帮助开发人员进行故障排查和错误处理。
示例代码:
```c
#include <openssl/ssl.h>
#include <openssl/err.h>
int main() {
// 初始化 OpenSSL 库
SSL_library_init();
// 加载 OpenSSL 错误字符串
SSL_load_error_strings();
// 其他操作...
return 0;
}
```
调用 SSL_load_error_strings() 函数后,可以使用 ERR_get_error()、ERR_reason_error_string() 等函数来获取和打印具体的错误信息。这些函数可以帮助开发人员定位和解决 SSL/TLS 通信过程中可能出现的错误。
相关问题
将如下代码改成一个函数#include <string.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #include <openssl/ssl.h> #include <openssl/err.h> #define MAX_BUF_SIZE 1024 int main(int argc, char *argv[]) { int sockfd, ret; char *url = argv[1]; // 输入的 url char *cert_path = argv[2]; // 输入的证书路径 struct sockaddr_in servaddr; SSL_CTX *ctx; SSL *ssl; char buf[MAX_BUF_SIZE]; // 初始化 SSL 库 SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); // 创建 SSL 上下文 ctx = SSL_CTX_new(TLS_client_method()); if (ctx == NULL) { printf("SSL_CTX_new error.\n"); return -1; } // 加载证书 ret = SSL_CTX_load_verify_locations(ctx, cert_path, NULL); if (ret != 1) { printf("SSL_CTX_load_verify_locations error.\n"); return -1; } // 创建 socket sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { printf("socket error.\n"); return -1; } // 设置服务器地址 memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(443); inet_pton(AF_INET, url, &servaddr.sin_addr); // 连接服务器 ret = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); if (ret < 0) { printf("connect error.\n"); return -1; } // 创建 SSL 对象 ssl = SSL_new(ctx); if (ssl == NULL) { printf("SSL_new error.\n"); return -1; } SSL_set_fd(ssl, sockfd); // 建立 SSL 连接 ret = SSL_connect(ssl); if (ret != 1) { printf("SSL_connect error.\n"); return -1; } // 发送请求 char *request = "GET / HTTP/1.1\r\nHost: %s\r\n\r\n"; sprintf(buf, request, url); SSL_write(ssl, buf, strlen(buf)); // 接收响应 while (1) { memset(buf, 0, sizeof(buf)); ret = SSL_read(ssl, buf, sizeof(buf) - 1); if (ret < 0) { printf("SSL_read error.\n"); break; } else if (ret == 0) { break; } else { printf("%s", buf); } } // 关闭 SSL 连接 SSL_shutdown(ssl); SSL_free(ssl); // 关闭 socket close(sockfd); // 清理 SSL 上下文 SSL_CTX_free(ctx); return 0; }
好的,下面是将代码改写成一个函数的结果:
```
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define MAX_BUF_SIZE 1024
int https_request(const char *url, const char *cert_path) {
int sockfd, ret;
struct sockaddr_in servaddr;
SSL_CTX *ctx;
SSL *ssl;
char buf[MAX_BUF_SIZE];
// 初始化 SSL 库
SSL_library_init();
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
// 创建 SSL 上下文
ctx = SSL_CTX_new(TLS_client_method());
if (ctx == NULL) {
printf("SSL_CTX_new error.\n");
return -1;
}
// 加载证书
ret = SSL_CTX_load_verify_locations(ctx, cert_path, NULL);
if (ret != 1) {
printf("SSL_CTX_load_verify_locations error.\n");
return -1;
}
// 创建 socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
printf("socket error.\n");
return -1;
}
// 设置服务器地址
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(443);
inet_pton(AF_INET, url, &servaddr.sin_addr);
// 连接服务器
ret = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
if (ret < 0) {
printf("connect error.\n");
return -1;
}
// 创建 SSL 对象
ssl = SSL_new(ctx);
if (ssl == NULL) {
printf("SSL_new error.\n");
return -1;
}
SSL_set_fd(ssl, sockfd);
// 建立 SSL 连接
ret = SSL_connect(ssl);
if (ret != 1) {
printf("SSL_connect error.\n");
return -1;
}
// 发送请求
char *request = "GET / HTTP/1.1\r\nHost: %s\r\n\r\n";
sprintf(buf, request, url);
SSL_write(ssl, buf, strlen(buf));
// 接收响应
while (1) {
memset(buf, 0, sizeof(buf));
ret = SSL_read(ssl, buf, sizeof(buf) - 1);
if (ret < 0) {
printf("SSL_read error.\n");
break;
} else if (ret == 0) {
break;
} else {
printf("%s", buf);
}
}
// 关闭 SSL 连接
SSL_shutdown(ssl);
SSL_free(ssl);
// 关闭 socket
close(sockfd);
// 清理 SSL 上下文
SSL_CTX_free(ctx);
return 0;
}
```
函数名称为 `https_request`,接受两个参数,分别是 `url` 和 `cert_path`。函数返回值为整型,表示函数执行结果。在函数内部,我们使用了原始代码中的大部分代码,只是将 `main` 函数中的一些变量名做了一些修改,以符合函数的参数列表。
下面函数 第四个参数是什么意思, char *https_request(const char *url, const char *payload, const char *cert_path, const char *key_path, const char *ca_path) { SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); // 加载 CA 证书 X509_STORE *store = X509_STORE_new(); X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); X509_LOOKUP_load_file(lookup, ca_path, X509_FILETYPE_PEM); // 加载客户端证书和私钥 SSL_CTX *ctx = SSL_CTX_new(TLS_method()); if (ctx == NULL) { perror("SSL_CTX_new"); return ("A"); } // 设置支持的协议版本为 TLSv1.2 SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION); //SSL_CTX *ctx = SSL_CTX_new(TLSv1_2_client_method()); SSL_CTX_use_certificate_file(ctx, cert_path, SSL_FILETYPE_PEM); SSL_CTX_use_PrivateKey_file(ctx, key_path, SSL_FILETYPE_PEM); // 创建 SSL 连接 SSL *ssl = SSL_new(ctx); // 解析 URL char host[256]; char path[4096]; int port = 443; if (sscanf(url, "https://%255[^/]/%4095s", host, path) != 2) { fprintf(stderr, "Error: Invalid URL\n"); return NULL; } // 创建 TCP 连接 int sockfd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in dest_addr; dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(port); dest_addr.sin_addr.s_addr = inet_addr(host); // 建立连接 connect(sockfd, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); // 将 SSL 连接和 TCP 连接关联 SSL_set_fd(ssl, sockfd); // 进行 SSL 握手 SSL_connect(ssl); // 发送 HTTPS 请求 char request[8192]; snprintf(request, sizeof(request), "POST %s HTTP/1.1\r\n" "Host: %s\r\n" "Content-Type: application/json\r\n" "Content-Length: %zu\r\n" "\r\n" "%s", path, host, strlen(payload), payload); SSL_write(ssl, request, strlen(request)); // 接收 HTTPS 响应 char buf[8192]; int bytes; size_t response_size = 0; char *response_buf = NULL; while ((bytes = SSL_read(ssl, buf, sizeof(buf))) > 0) { response_buf = realloc(response_buf, response_size + bytes + 1); memcpy(response_buf + response_size, buf, bytes); response_size += bytes; } response_buf[response_size] = '\0'; // 关闭 SSL 连接 SSL_shutdown(ssl); // 释放资源 SSL_free(ssl); close(sockfd); SSL_CTX_free(ctx); X509_STORE_free(store); ERR_free_strings(); return response_buf; }
第四个参数是客户端证书的路径,用于进行 HTTPS 请求时的身份认证。在一些安全性要求较高的场景中,客户端需要提供自己的身份证明以便服务端进行验证。客户端证书一般由 CA 机构签发,证明了客户端的身份和可信性。该函数中使用 SSL_CTX_use_certificate_file 和 SSL_CTX_use_PrivateKey_file 加载客户端证书和私钥,然后在 SSL 连接中使用这些证书和私钥进行身份认证。
阅读全文