Transformar um 'socket' simples num 'socket' de SSL

eu escrevi programas C simples, que estão usando sockets ('cliente' e 'servidor'). (Utilização do UNIX/Linux)

o lado do servidor simplesmente cria um 'socket':

sockfd = socket(AF_INET, SOCK_STREAM, 0);

e depois liga - o ao sockaddr:

bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));

e ouve (e aceita e lê):

listen(sockfd,5);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
read(newsockfd,buffer,255);

o cliente cria o 'socket', e depois escreve-lhe.

Agora, eu quero converter essa conexão simples em uma conexão SSL, da maneira mais simples, mais idílica, mais elegante e mais rápida.

eu tenho tentei adicionar OpenSSL ao meu projecto, mas não consigo encontrar uma maneira fácil de implementar o que quero.

Author: Peter Mortensen, 2011-10-08

4 answers

Existem vários passos ao usar o OpenSSL. Deve ter feito um certificado SSL que possa conter o certificado com a chave privada, certifique-se de indicar a localização exacta do certificado (este exemplo tem-no no root). Há muitos bons tutoriais por aí.

Alguns incluem:

#include <openssl/applink.c>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

Terá de inicializar o OpenSSL:

void InitializeSSL()
{
    SSL_load_error_strings();
    SSL_library_init();
    OpenSSL_add_all_algorithms();
}

void DestroySSL()
{
    ERR_free_strings();
    EVP_cleanup();
}

void ShutdownSSL()
{
    SSL_shutdown(cSSL);
    SSL_free(cSSL);
}

Agora para a maior parte da funcionalidade. Você pode querer adicionar um ao mesmo tempo em que divulga as ligações.

int sockfd, newsockfd;
SSL_CTX *sslctx;
SSL *cSSL;

InitializeSSL();
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd< 0)
{
    //Log and Error
    return;
}
struct sockaddr_in saiServerAddress;
bzero((char *) &saiServerAddress, sizeof(saiServerAddress));
saiServerAddress.sin_family = AF_INET;
saiServerAddress.sin_addr.s_addr = serv_addr;
saiServerAddress.sin_port = htons(aPortNumber);

bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));

listen(sockfd,5);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);

sslctx = SSL_CTX_new( SSLv23_server_method());
SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_DH_USE);
int use_cert = SSL_CTX_use_certificate_file(sslctx, "/serverCertificate.pem" , SSL_FILETYPE_PEM);

int use_prv = SSL_CTX_use_PrivateKey_file(sslctx, "/serverCertificate.pem", SSL_FILETYPE_PEM);

cSSL = SSL_new(sslctx);
SSL_set_fd(cSSL, newsockfd );
//Here is the SSL Accept portion.  Now all reads and writes must use SSL
ssl_err = SSL_accept(cSSL);
if(ssl_err <= 0)
{
    //Error occurred, log and close down ssl
    ShutdownSSL();
}

Você é capaz de ler ou escrever usando:

SSL_read(cSSL, (char *)charBuffer, nBytesToRead);
SSL_write(cSSL, "Hi :3\n", 6);
 114
Author: CaptainBli, 2018-05-14 06:59:35
O OpenSSL é muito difícil. É fácil deitar fora acidentalmente toda a sua segurança ao não fazer a negociação exatamente certo. (Heck, i've been personally bitten by a bug where curl was not reading the OpenSSL alertas exactly right, and couldn't talk to some sites.)

Se você realmente quer rápido e simples, coloque stud na frente do seu programa e chame-o por dia. Ter SSL num processo diferente não te vai atrasar.: http://vincent.bernat.im/en/blog/2011-ssl-benchmark.html

 15
Author: BraveNewCurrency, 2013-04-26 03:40:38

Para outros como eu:

Se transferir a fonte de SSL, existe uma pasta demos/ssl/ com o código de exemplo em c++: https://github.com/openssl/openssl/tree/master/demos/ssl

UPDATE: {[11] } eles removeram essa demonstração. Agora está disponível apenas através do histórico: https://github.com/openssl/openssl/tree/691064c47fd6a7d11189df00a0d1b94d8051cbe0/demos/ssl Você provavelmente terá que encontrar uma versão de trabalho, eu originalmente postei esta resposta em 6 de Novembro de 2015. E Tive de editar a fonte.não muito.

Certificados:.pem in demos/certs/apps/: https://github.com/openssl/openssl/tree/master/demos/certs/apps

 7
Author: 18446744073709551615, 2016-04-18 07:05:07

Aqui o meu exemplo SSL 'socket server threads' (ligação múltipla) https://github.com/breakermind/CppLinux/blob/master/QtSslServerThreads/breakermindsslserver.cpp

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <unistd.h>
#include <iostream>

#include <breakermindsslserver.h>

using namespace std;

int main(int argc, char *argv[])
{
    BreakermindSslServer boom;
    boom.Start(123,"/home/user/c++/qt/BreakermindServer/certificate.crt", "/home/user/c++/qt/BreakermindServer/private.key");
    return 0;
}
 0
Author: Fanex, 2017-11-08 11:06:00