Lo primero una duda, cuando me conecto con google.com de la forma:
Código
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
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
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 */