Introduction `a OpenSSL (en C) - Jean-Matthieu

Mar 12, 2002 - dans mod ssl d'Apache, dans gpg, openssh . ...... Server: Microsoft-IIS/4.0 .... which the general network-using public has access to download ...
482KB taille 4 téléchargements 240 vues
Introduction a` OpenSSL (en C)

Labo-Unix - http://www.labo-unix.net 2001-2002

1

Introduction a` OpenSSL (en C)

Table des mati`eres

2

Labo-Unix - Supinfo Paris - 2001/2002

Introduction a` OpenSSL (en C)

Droits de ce document Copyright (c) 2001 labo-unix.org Permission vous est donn´ee de copier, distribuer et/ou modifier ce document selon les termes de la Licence GNU Free Documentation License, Version 1.1 ou ult´erieure publi´ee par la Free Software Foundation ; avec les sections inalt´erables suivantes : - pas de section inalt`erable Une copie de cette Licence est incluse dans la section appel´ee GNU Free Documentation License de ce document.

3

Labo-Unix - Supinfo Paris - 2001/2002

Introduction a` OpenSSL (en C)

1

Introduction

Par soucis de s´ecurit´e et de confidentialit´e, la plupart des applications actuelles ne peuvent se priver du cryptage des donn´ees. Une fois encore, dans le monde du logiciel libre, une e´ quipe a pens´e a` nous en cr`eant une lib et de petits utilitaires assosci´es dans un projet d´enomm´e OpenSSL. Son utilisation est des plus fr´equente, vous la retrouverez dans mod ssl d’Apache, dans gpg, openssh . . . Nous allons dans le document qui suit vous initier aux joies du cryptages de flux de donnees en utilisant SSL (Secure Sockets Layer) et TLS (Transport Layer Security). Pour ce qui est des connaissances requises pour comprendre ce qui se trouve dans ce document, il est necessaire de connaˆıtre les bases unix, savoir utiliser des sockets reseaux et utiliser gcc (ou tout autre compilateur C). Comme pour les autres documents fournis par le Labo-UNIX, n’hesitez pas a` nous contacter pour nous faire part de vos remarques et critiques (qu’elles soient constructives ou non) a` [email protected] afin d’am´eliorer la qualit´e de nos support. De mˆeme, si vous souhaitiez ajouter du contenu, contactez nous par mail a` la mˆeme l’adresse.

2

Initialisation

Dans les parties qui vont suivre, nous allons cr´eer un application cliente qui se contentera d’envoyer une requˆete HTTP/1.0 a` un hˆote de notre choix et d’afficher sa r´eponse. Nous devons, avant d’utiliser les fonctions principales d’OpenSSL, initialiser quelques donn´ees. Tout d’abord, SSL library init() va initialiser les diff`erents algorithmes de cryptages. Ensuite, nous devons charger ce que nous allons utiliser, par exemple avec OpenSSL add all algorithms(). A noter que si nous souhaitons obtenir les chaˆınes de caract`eres assosci´ees aux erreurs rencontr´ees, il aurait fallut ajouter SSL load error strings(). D’apr`es ce qui a e´ t´e dit : cat client.c #include #include #include int main (int argc, char **argv) { /***************************** SSL ***********************************/ /*** Initialisation de ce qui est utile pour que la lib fonctionne ***/ /*********************************************************************/ SSL_library_init(); OpenSSL_add_all_algorithms(); /*********************************************************************/

/********************* SSL ************************/ /*** Nettoyage de ce qui est utilse pour la lib ***/ /**************************************************/

4

Labo-Unix - Supinfo Paris - 2001/2002

Introduction a` OpenSSL (en C)

EVP_cleanup(); /**************************************************/ return 0; } gcc -o ssl_client ssl_client.c ./ssl_client

Comme vous pouvez le constater, c’est un programme qui ne fait, pour l’instant, absolument rien. Il ne sera veritablement operationnel qu’´a la fin, mais vous pouvez essayer de le compiler et de le lancer, vous verez ainsi les probl`emes au fur et a` mesure que nous allons avancer. Il faut desormais indiquer quelle version de SSL et dans quelle contexte nous allons utiliser la lib (en tant que client ou serveur). Il y a a` notre disposition toute une panoplie de fonctions disponibles pour indiquer la version. Certainement la plus pratique dans notre cas s’av`ere eˆ tre SSL v23 client method(). Celle-ci a l’avantage de tester diff´erentes versions permettant ainsi une grande compatibilit´e avec les diverses implementations de SSL disponibles sur les serveurs web (entre autres). Nous obtenons alors : #include #include #include #include #include #include #include



int main (int argc, char **argv) { int chaussette; // Futur descripteur de socket struct sockaddr_in infos_hote; // Informations sur l’hote struct hostent *str_hostent; // Va contenir l’adresse de l’hote SSL_METHOD SSL_CTX SSL

*ssl_method; *ssl_ctx; *ssl;

// Methode d’utilisation d’OpenSSL // Contexte d’utilisation d’OpenSSL // Structure d’utilisation d’OpenSSL

if (argc != 3) { puts ("Utilisation : s_client \n"); return 0; }

/***************************** SSL ***********************************/ /*** Initialisation de ce qui est utile pour que la lib fonctionne ***/ /*********************************************************************/ SSL_library_init(); OpenSSL_add_all_algorithms();

5

Labo-Unix - Supinfo Paris - 2001/2002

Introduction a` OpenSSL (en C) /*********************************************************************/

/************************** SSL ***************************/ /*** Initialisation du contexte d’utilisation d’OpenSSL ***/ /**********************************************************/ if ((ssl_method = SSLv23_client_method()) == NULL) { puts ("Erreur SSLv23_client_method()"); return -1; } if ((ssl_ctx = SSL_CTX_new (ssl_method)) == NULL) { puts ("Erreur SSL_CTX_new(...)"); return -1; } if ((ssl = SSL_new (ssl_ctx)) == NULL) { puts ("Erreur SSL_new (...)"); SSL_CTX_free (ssl_ctx); return -1; } /**********************************************************/

/********************* SSL ************************/ /*** Nettoyage de ce qui est utilse pour la lib ***/ /**************************************************/ EVP_cleanup(); SSL_CTX_free (ssl_ctx); SSL_free (ssl); /**************************************************/ return 0; }

3

Connexion

Une fois toutes les structures n´ecessaires au bon fonctionnement de la “libssl” initialis´ees, il nous reste a` nous connecter au serveur web pr´esent sur l’hˆote. La premi`ere e´ tape de l’operation consiste en l’utilisation de la fonction classique connect(...). Il faudra ensuite indiquer au programme que nous souhaitons dialoguer via le descripteur de socket que nous avons pr´ec´edemment initialis´e avec connect (...) en utilisant SSL set fd(...). Ceci fait, il ne reste alors qu’`a utiliser SSL connect(...) pour cr´eer le tunnel SSL. Here we go ! ! ! : #include #include #include #include



6

Labo-Unix - Supinfo Paris - 2001/2002

Introduction a` OpenSSL (en C) #include #include #include

int main (int argc, char **argv) { int chaussette; // Futur descripteur de socket struct sockaddr_in infos_hote; // Informations sur l’hote struct hostent *str_hostent; // Va contenir l’adresse de l’hote SSL_METHOD SSL_CTX SSL

*ssl_method; *ssl_ctx; *ssl;

// Methode d’utilisation d’OpenSSL // Contexte d’utilisation d’OpenSSL // Structure d’utilisation d’OpenSSL

if (argc != 3) { puts ("Utilisation : s_client \n"); return 0; }

/***************************** SSL ***********************************/ /*** Initialisation de ce qui est utile pour que la lib fonctionne ***/ /*********************************************************************/ SSL_library_init(); OpenSSL_add_all_algorithms(); /*********************************************************************/

/************************** SSL ***************************/ /*** Initialisation du contexte d’utilisation d’OpenSSL ***/ /**********************************************************/ if ((ssl_method = SSLv23_client_method()) == NULL) { puts ("Erreur SSLv23_client_method()"); return -1; } if ((ssl_ctx = SSL_CTX_new (ssl_method)) == NULL) { puts ("Erreur SSL_CTX_new(...)"); return -1; } if ((ssl = SSL_new (ssl_ctx)) == NULL) { puts ("Erreur SSL_new (...)"); SSL_CTX_free (ssl_ctx); return -1; } /**********************************************************/

7

Labo-Unix - Supinfo Paris - 2001/2002

Introduction a` OpenSSL (en C)

infos_hote.sin_family = AF_INET; infos_hote.sin_port = htons(atoi (argv[2])); if ((str_hostent = gethostbyname (argv[1])) == NULL) { perror ("Oups ..."); EVP_cleanup(); SSL_CTX_free (ssl_ctx); SSL_free (ssl); return -1; }

memcpy ((struct sockaddr *)&infos_hote.sin_addr, str_hostent->h_addr_list[0], str_hostent->h_length);

if ((chaussette = socket (PF_INET, SOCK_STREAM, IPPROTO_IP)) == -1) { perror ("Pb de socket"); EVP_cleanup(); SSL_CTX_free (ssl_ctx); SSL_free (ssl); return -1; } if ((connect (chaussette, (struct sockaddr *)&infos_hote, sizeof (struct sockaddr_in))) == -1) { perror ("Pb lors de la connexion"); EVP_cleanup(); SSL_CTX_free (ssl_ctx); SSL_free (ssl); return -1; }

/************************** SSL *****************************/ /*** On assoscie la descripteur de socket au contexte ssl ***/ /************************************************************/ if (SSL_set_fd(ssl, chaussette) == 0) { puts ("Pb SSL_set_fd(...)"); EVP_cleanup(); SSL_CTX_free (ssl_ctx); SSL_free (ssl); return -1; } /************************************************************/

8

Labo-Unix - Supinfo Paris - 2001/2002

Introduction a` OpenSSL (en C)

/*************** SSL ****************/ /*** Etablissement du tunnel SSL ***/ /************************************/ if ((SSL_connect (ssl)) h_addr_list[0], str_hostent->h_length);

if ((chaussette = socket (PF_INET, SOCK_STREAM, IPPROTO_IP)) == -1) { perror ("Pb de socket"); EVP_cleanup(); SSL_CTX_free (ssl_ctx); SSL_free (ssl); return -1; } if ((connect (chaussette, (struct sockaddr *)&infos_hote, sizeof (struct sockaddr_in))) == -1) { perror ("Pb lors de la connexion"); EVP_cleanup(); SSL_CTX_free (ssl_ctx); SSL_free (ssl); return -1; }

/************************** SSL *****************************/ /*** On assoscie la descripteur de socket au contexte ssl ***/ /************************************************************/ if (SSL_set_fd(ssl, chaussette) == 0) { puts ("Pb SSL_set_fd(...)"); EVP_cleanup(); SSL_CTX_free (ssl_ctx); SSL_free (ssl); return -1; } /************************************************************/

/*************** SSL ****************/ /*** Etablissement du tunnel SSL ***/ /************************************/ if ((SSL_connect (ssl)) h_addr_list[0], str_hostent->h_length);

if ((chaussette = socket (PF_INET, SOCK_STREAM, IPPROTO_IP)) == -1) { perror ("Pb de socket"); EVP_cleanup(); SSL_CTX_free (ssl_ctx); SSL_free (ssl); return -1; } if ((connect (chaussette, (struct sockaddr *)&infos_hote, sizeof (struct sockaddr_in))) == -1) { perror ("Pb lors de la connexion"); EVP_cleanup(); SSL_CTX_free (ssl_ctx); SSL_free (ssl); return -1; }

14

Labo-Unix - Supinfo Paris - 2001/2002

Introduction a` OpenSSL (en C) /************************** SSL *****************************/ /*** On assoscie la descripteur de socket au contexte ssl ***/ /************************************************************/ if (SSL_set_fd(ssl, chaussette) == 0) { puts ("Pb SSL_set_fd(...)"); EVP_cleanup(); SSL_CTX_free (ssl_ctx); SSL_free (ssl); return -1; } /************************************************************/

/*************** SSL ****************/ /*** Etablissement du tunnel SSL ***/ /************************************/ if ((SSL_connect (ssl))