108 votes

Transformez un socket simple en un socket SSL

J'ai écrit simple, les programmes en c, qui sont à l'aide de sockets ("client" et "serveur"). (UNIX/Linux)

Le serveur crée un socket:

sockfd = socket(AF_INET, SOCK_STREAM, 0);

et puis le lie à sockaddr:

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

et à l'écoute (et accepte et lit):

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

Le client crée la socket, puis écrit.

Maintenant, je veux convertir cette connexion simple dans une connexion SSL, le plus simple, le plus idyllique, la plus fantastique et le plus rapide.

J'ai essayé d'ajouter openSSL pour mon projet, mais je ne peux pas trouver un moyen facile de mettre en œuvre ce que je veux.

140voto

CaptainBli Points 1046

Il y a plusieurs étapes lors de l'utilisation d'openSSL. Vous devez avoir un certificat SSL qui puissent contenir le certificat avec la clé privée assurez-vous de spécifier l'emplacement exact du certificat (cet exemple est à la racine du site). Il y a beaucoup de bons tutoriels.
Découvrez: https://thunked.org/programming/openssl-tutorial-server-t12.html

Et une de HP: http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04s03.html

Certains inclut:

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

Vous devez initialiser la ssl:

void InitializeSSL()
{
    SSL_load_error_strings();
    SSL_library_init();
    OpenSSL_add_all_algorithms();
}
void DestroySSL()
{
    ERR_free_strings();
    EVP_cleanup();
}
void ShutdownSSL()
{
        SSL_shutdown(ssl);
        SSL_free(ssl);
}

Maintenant, pour la majeure partie de la fonctionnalité. Vous souhaiterez peut-être ajouter une boucle while sur les connexions.

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 occured, log and close down ssl
    ShutdownSSL();
}

Vous êtes alors en mesure de lire ou d'écrire à l'aide de:

SSL_read(cSSL, (char *)charBuffer, nBytesToRead);
SSL_write(ssl, "Hi :3\n", 6);

16voto

BraveNewCurrency Points 4096

OpenSSL est assez difficile. Il est facile de accidentellement jeter tous votre sécurité en ne faisant pas de négociation exactement. (Zut, j'ai moi-même été mordu par un bug où curl n'était pas la lecture de la OpenSSL alertes exactement, et je ne pouvais pas parler à certains sites).

Si vous voulez vraiment simple et rapide, de mettre goujon en face de votre programme de l'appeler un jour. Ayant SSL dans un processus différent de ne pas vous ralentir: http://vincent.bernat.im/en/blog/2011-ssl-benchmark.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X