本文介绍了OpenSSL,RSA和Winsock和C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我发现这个源浮在网上,我希望有人可以解决为什么这个程序只是关闭而不是监听连接。这个来源是打开一个服务器套接字,但不是。
I found this source floating about the net and I was hoping someone could solve why this program simply shuts down instead of listening for a connection. This source was meant to open a server socket but, doesn't.
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <iostream>
#include <stdio.h>
#include <winsock2.h>
#define PASSWORD "passme"
int main(int argc, char** argv)
{
CRYPTO_malloc_init(); // Initialize malloc, free, etc for OpenSSL's use
SSL_library_init(); // Initialize OpenSSL's SSL libraries
SSL_load_error_strings(); // Load SSL error strings
ERR_load_BIO_strings(); // Load BIO error strings
OpenSSL_add_all_algorithms(); // Load all available encryption algorithms
return 0;
}
void serverThread()
{
// First, we need to initialize Winsock.
WSADATA wsadata;
int ret = WSAStartup(0x101, &wsadata);
if (ret != 0) {
printf("WSAStartup() failed with: %d!\n", GetLastError());
return;
}
// Next we need to create a server socket.
SOCKET server = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in sockaddrin;
// Internet socket
sockaddrin.sin_family = AF_INET;
// Accept any IP
sockaddrin.sin_addr.s_addr = INADDR_ANY;
// Use port 6789
sockaddrin.sin_port = htons(6789);
// Valid socket?
if (server == INVALID_SOCKET) {
printf("Error creating server socket!");
return;
}
// Now bind to the port
ret = bind(server, (sockaddr*) &(sockaddrin), sizeof(sockaddrin));
if (ret != 0) {
printf("Error binding to port!\n");
return;
}
// Start listening for connections
// Second param is max number of connections
ret = listen(server, 50);
if (ret != 0) {
printf("Error listening for connections!\n");
return;
}
// Set up to accept connections
SOCKET client;
sockaddr_in clientsockaddrin;
int len = sizeof(clientsockaddrin);
printf("Server ready to accept connections!\n");
while (1) {
// Block until a connection is ready
client = accept(server, (sockaddr*) &clientsockaddrin, &len);
printf("Connection recieved from %s!\n", inet_ntoa(clientsockaddrin.sin_addr));
// Notice that we use server_method instead of client_method
SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
BIO* bio = BIO_new_file("dh1024.pem", "r");
// Did we get a handle to the file?
if (bio == NULL) {
printf("Couldn't open DH param file!\n");
break;
}
// Read in the DH params.
DH* ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
// Free up the BIO object.
BIO_free(bio);
// Set up our SSL_CTX to use the DH parameters.
if (SSL_CTX_set_tmp_dh(ctx, ret) < 0) {
printf("Couldn't set DH parameters!\n");
break;
}
// Now we need to generate a RSA key for use.
// 1024-bit key. If you want to use something stronger, go ahead but it must be a power of 2. Upper limit should be 4096.
RSA* rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL);
// Set up our SSL_CTX to use the generated RSA key.
if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) {
printf("Couldn't set RSA key!\n");
// We don't break out here because it's not a requirement for the RSA key to be set. It does help to have it.
}
// Free up the RSA structure.
RSA_free(rsa);
SSL_CTX_set_cipher_list(ctx, "ALL");
// Set up our SSL object as before
SSL* ssl = SSL_new(ctx);
// Set up our BIO object to use the client socket
BIO* sslclient = BIO_new_socket(client, BIO_NOCLOSE);
// Set up our SSL object to use the BIO.
SSL_set_bio(ssl, sslclient, sslclient);
// Do SSL handshaking.
int r = SSL_accept(ssl);
// Something failed. Print out all the error information, since all of it may be relevant to the problem.
if (r != 1) {
printf("SSL_accept() returned %d\n", r);
printf("Error in SSL_accept(): %d\n", SSL_get_error(ssl, r));
char error[65535];
ERR_error_string_n(ERR_get_error(), error, 65535);
printf("Error: %s\n\n", error);
ERR_print_errors(sslclient);
int err = WSAGetLastError();
printf("WSA: %d\n", err);
break;
}
}
}
int password_callback(char* buffer, int num, int rwflag, void* userdata)
{
if (num < (strlen(PASSWORD) + 1)) {
return(0);
}
strcpy(buffer, PASSWORD);
return strlen(PASSWORD);
}
int verify_callback(int ok, X509_STORE_CTX* store)
{
char data[255];
if (!ok) {
X509* cert = X509_STORE_CTX_get_current_cert(store);
int depth = X509_STORE_CTX_get_error_depth(store);
int err = X509_STORE_CTX_get_error(store);
printf("Error with certificate at depth: %d!\n", depth);
X509_NAME_oneline(X509_get_issuer_name(cert), data, 255);
printf("\tIssuer: %s\n", data);
X509_NAME_oneline(X509_get_subject_name(cert), data, 255);
printf("\tSubject: %s\n", data);
printf("\tError %d: %s\n", err, X509_verify_cert_error_string(err));
}
return ok;
}
推荐答案
主
这篇关于OpenSSL,RSA和Winsock和C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!