OpenSSL, RSA и Winsock и C ++ - PullRequest
       31

OpenSSL, RSA и Winsock и C ++

1 голос
/ 20 февраля 2012

Я обнаружил, что этот источник распространяется по сети, и я надеялся, что кто-нибудь сможет решить, почему эта программа просто выключается, а не прослушивает соединение.Этот источник должен был открыть сокет сервера, но не делает этого.

#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;
}

1 Ответ

0 голосов
/ 20 февраля 2012

Вы никогда не запускаете ServerThread в основном

...