Lecture / écriture directe des données de prise de contact avec la mémoire BIO

J’ai besoin de créer une connexion OpenSSL sur laquelle je peux directement lire / écrire des données de prise de contact. La raison en est que les données de prise de contact seront transscopes dans une connexion UDP (DTLS n’est pas une option, car les données ne sont pas directement dans le datagramme, mais dans un autre paquet de protocole, EAP si vous êtes curieux). Jusqu’à présent, j’ai créé une connexion OpenSSL mais je n’ai même pas été en mesure de lire la poignée de main du client à envoyer au serveur.

Dans mes recherches, j’ai découvert qu’il me fallait une mémoire BIO pour lire / écrire sur la connexion, mais je ne sais pas comment extraire les données de prise de contact. Voici comment j’initialise la connexion client :

SSL_library_init(); SSL_load_error_ssortingngs(); OpenSSL_add_all_algorithms(); ctx = SSL_CTX_new(SSLv3_client_method()); SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); ssl = SSL_new(ctx); rbio = BIO_new(BIO_s_mem()); wbio = BIO_new(BIO_s_mem()); SSL_set_bio(ssl, rbio, wbio); SSL_set_connect_state(ssl); 

J’ai essayé doint SSL_connect , pour initier la poignée de main:

 int ret = SSL_connect(ssl); 

Mais retourne -1 , et en faisant SSL_get_error(ssl, res) je reçois un code d’erreur 2 , puis ERR_error_ssortingng avec ce code et j’obtiens:

 error:00000002:lib(0):func(0):system lib 

De plus, si j’utilise SSL_do_handshake au lieu de SSL_connect j’obtiens exactement la même erreur.

J’ai pu configurer une connexion OpenSSL sur TCP, mais je n’ai jamais fait cela avec les BIO de mémoire, toute aide à cet égard serait donc très appréciée. Merci!

Finalement je le fais fonctionner, j’étais dans le bon sens:

La fonction SSL_set_connect_state(ssl) est nécessaire pour indiquer à la connexion à préparer pour l’initiation de prise de contact. Ensuite, nous appelons SSL_do_handshake(ssl) pour lancer la négociation. Cette fonction retournera -1 car la poignée de main n’a pas été finie, mais nous pouvons en réalité lire à partir du graveur BIO de connexion ssl client et envoyer les données en utilisant le protocole souhaité (dans mon cas, les paquets EAP RADIUS sur UDP).

Client

 ctx = SSL_CTX_new(SSLv3_client_method()); SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); ssl = SSL_new(ctx); rbio = BIO_new(BIO_s_mem()); wbio = BIO_new(BIO_s_mem()); SSL_set_bio(ssl, rbio, wbio); SSL_set_connect_state(ssl); SSL_do_handshake(ssl); // This will return -1 (error) as the handshake is not finished, we can ignore it. char buf[4096]; BIO_read(wbio, buf, 4096); // Read from BIO, put data in buffer // Then use data in buffer to send to the server 

Le serveur, d’autre part, doit être configuré à l’aide des informations d’identification et de la clé privée. De plus, au lieu de SSL_set_connect_state() nous devrions utiliser SSL_set_accept_state() car le serveur attendra le bonjour du client. Ensuite, nous écrivons simplement les données de transfert de la main du client au lecteur BIO du serveur:

Serveur

 ctx = SSL_CTX_new(SSLv3_server_method()); // This is the server! SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); ssl = SSL_new(ctx); rbio = BIO_new(BIO_s_mem()); wbio = BIO_new(BIO_s_mem()); SSL_set_bio(ssl, rbio, wbio); SSL_set_accept_state(ssl); // The server uses SSL_set_accept_state // Here we get the data from the client suppose it's in the variable buf // and write it to the connection reader BIO. BIO_write(rbio, buf, strlen(buf)); if (!SSL_is_init_finished(ssl)) { SSL_do_handshake(ssl); } 

Nous pouvons utiliser la fonction SSL_is_init_finished(ssl) pour vérifier si la prise de contact a été effectuée. SSL_do_handshake(ssl) nous appelons SSL_do_handshake(ssl) , puis nous lisons à nouveau à partir de BIO_writer pour envoyer des données au client.

Ce processus entre le client et le serveur doit être effectué jusqu’à ce que la connexion soit SSL_is_init_finished(ssl) c’est-à-dire que SSL_is_init_finished(ssl) renvoie true ).

Ensuite, une fois la SSL_read SSL_write , vous pouvez envoyer des données sécurisées entre client / serveur, à l’aide des fonctions SSL_read et SSL_write . J’espère que cette courte explication est utile pour quelqu’un!

Essayez de faire ça

 // Connect the TCP socket (this is client side) int sock = tcp_connect(host, port); // Create BIO around the connected TCP socket BIO *sbio = BIO_new_socket(sock, BIO_NOCLOSE); SSL_set_bio(ssl,sbio,sbio); int ret = SSL_connect(ssl); 

Pensez à BIO comme une enveloppe autour de la prise. Pour le côté client, vous devez lui atsortingbuer un socket connecté à l’hôte et au port souhaités à l’aide de l’appel connect (…). Pour le côté serveur, utilisez simplement le socket renvoyé par un appel accept (…).