Conexión HTTPS con openssl C++

Iniciado por Kaxperday, 10 Noviembre 2015, 10:03 AM

0 Miembros y 1 Visitante están viendo este tema.

Kaxperday

Hola, estaba probando con openssl a realizar una conexión https visto que no conseguí curl, de hecho no me hace falta si se usar openssl que de momento no es el caso.

Lo primero una duda, cuando me conecto con google.com de la forma:

Código (cpp) [Seleccionar]
int sd;
struct hostent *host;
struct sockaddr_in addr;

host = gethostbyname("google.com"); /* convert hostname ‡ IP addr */
sd = socket(PF_INET, SOCK_STREAM, 0);  /* create TCP socket */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(80);     /* set the desired port */
addr.sin_addr.s_addr = *(long*)(host->h_addr); /* and address */
connect(sd, (struct sockaddr*)&addr, sizeof(addr));/* connect */
//send .. recv..


Los datos que obtengo son descifrados, esto es porque me conecto a el puerto 80 que usa HTTP ¿verdad?, ¿pero google no forzaba a usar https?, no entiendo porque una conexión normal no me la cifra, ¿será que es la primera interacción?.

Me he puesto a probar una conexión https siguiendo un tutorial, que encontré aquí:

http://www.informit.com/articles/article.aspx?p=22078&seqNum=3

Muy bueno por cierto, porque hay poca documentación sobre openssl y ejemplos.

Código (cpp) [Seleccionar]
SSL_METHOD *method;
SSL_CTX *ctx;
OpenSSL_add_all_algorithms();   /* load & register cryptos */
SSL_load_error_strings();     /* load all error messages */
method = (SSL_METHOD*)SSLv2_client_method();   /* create client instance */
ctx = SSL_CTX_new(method);         /* create context */
int sd;
struct hostent *host;
struct sockaddr_in addr;

host = gethostbyname("google.com"); /* convert hostname ‡ IP addr */
sd = socket(PF_INET, SOCK_STREAM, 0);  /* create TCP socket */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(80);     /* set the desired port */
addr.sin_addr.s_addr = inet_addr("216.58.211.238"); /* and address */
connect(sd, (struct sockaddr*)&addr, sizeof(addr));/* connect */
SSL *ssl;
ssl = SSL_new(ctx);    /* create new SSL connection state */
SSL_set_fd(ssl, sd);   /* attach the socket descriptor */
SSL_connect(ssl);          /* perform the connection */
SSL_write(ssl, "ola que ase", 0);
char rec[1000];
SSL_read(ssl, rec, 0);
cout << rec;


Me salta un error en ejecución en SSL_set_fd(ssl, sd);, donde he pasado de segundo argumento un socket, ¿que se supone que tengo que pasar ahí?.

¿Se supone que hago una conexión http y luego paso a https? ¿o como va?.

Seguiré probando, un saludo.

Edito: Bueno he estado probando y resulta que le pasaba el primer argumento null, el segundo argumento creo que es lo que devuelve connect, fui probando porque devolvia null y probando variable a variable hasta que ví que me faltaba una función de inicializar la librería tal que:

SSL_library_init();

Tras ponerlo no dio error, pero devolvió basura, seguiré probando a ver. Creo que es porque nunca he usado write() a ver de que va..

Código (cpp) [Seleccionar]
char *post = "POST / HTTP/1.1\r\ncontent-type:application/x-www-form-urlencoded;charset=utf-8\r\nhost: google.com\r\n";

SSL_METHOD *method;
SSL_CTX *ctx;
SSL_library_init();
OpenSSL_add_all_algorithms();   /* load & register cryptos */
SSL_load_error_strings();     /* load all error messages */
method = const_cast<SSL_METHOD*>(SSLv2_client_method());   /* create client instance */
ctx = SSL_CTX_new(method);         /* create context */
int sd, server;
sockaddr_in addr;
WSADATA wsa;
WSAStartup(MAKEWORD(2, 0), &wsa);
if (sd = socket(AF_INET, SOCK_STREAM, 0) == SOCKET_ERROR)
cout << "error crear socket";/* create TCP socket */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(80);     /* set the desired port */
addr.sin_addr.s_addr = inet_addr("216.58.211.238"); /* and address */
if (server = connect(sd, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR){
cout << "error conectar: " << WSAGetLastError();/* connect */
}
cout << "conectado";
SSL *ssl;
ssl = SSL_new(ctx);    /* create new SSL connection state */
SSL_set_fd(ssl, server);   /* attach the socket descriptor */
SSL_connect(ssl);          /* perform the connection */
SSL_write(ssl, post, strlen(post));
char rec[1000];
SSL_read(ssl, rec, 0);
cout << rec;
/*...*/
SSL_free(ssl);              /* release SSL state */
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

nepa

Kasperday: Yo estoy en el mismo trabajo. estoy tratando de conectarme a una pagina de internet que es https. Lo que he podido entender es que el puerto para conexiones https es el 443.

Kaxperday

Toma socio, este código es funcional que tengo, por supuesto necesitas openssl, gracias a ivancea, yo no quería hacerlo con BIO, pero al final no encontré otra manera, esta si funciona.

Código (cpp) [Seleccionar]

CRYPTO_malloc_init();
SSL_library_init();
OpenSSL_add_all_algorithms();

SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method());
SSL* ssl;
BIO* bio = BIO_new_ssl_connect(ctx);
if (bio == NULL) {
SSL_CTX_free(ctx);
return 0;
}
BIO_get_ssl(bio, &ssl);
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
BIO_set_conn_hostname(bio, "www.google.com:443");

if (BIO_do_connect(bio) <= 0) {
BIO_free_all(bio);
SSL_CTX_free(ctx);
return 0;
}

if (BIO_do_handshake(bio) <= 0) {
BIO_free_all(bio);
SSL_CTX_free(ctx);
return 0;
}
char buf[1024];
memset(buf, 0, sizeof(buf));
BIO_puts(bio, "GET /index.html HTTP/1.1\r\nHost: www.google.com\r\n\Connection: close\r\n\r\n");
string respuesta = "";
while (1) {
int x = BIO_read(bio, buf, sizeof(buf)-1);
if (x == 0) {
break;
}
else if (x < 0) {
if (!BIO_should_retry(bio)) {
BIO_free_all(bio);
SSL_CTX_free(ctx);
return 0;
}
}
else{
respuesta += buf;
}
}
BIO_free_all(bio);
SSL_CTX_free(ctx);


Un saludo.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

nepa

Gracias por tu ayuda. tuve que cambiar algunas parametros pero me funciono.

Kaxperday

Cita de: nepa en 21 Diciembre 2015, 17:36 PM
Gracias por tu ayuda. tuve que cambiar algunas parametros pero me funciono.

De nada hijo, un placer ayudar.

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.