Tema:Introduccion a openssl. Autor:Icaro. Introduccion: Uno de los principales problemas de seguridad a los que se enfrentan los usuarios de una red diariamente es la captura de datos y una de las grandes soluciones es la encriptacion de los mismos,para ello actualmente contamos con ssl traducido como capa de sockets seguros. ¿que es openssl?: Openssl es una api que nos confiere un entorno adecuado para encriptar los datos que mandamos a otra maquina en una red y a su vez desencriptarlos adecuadamente por el receptor evitando asi el crackeado de la informacion.Podemos usar openssl en cualquier protocolo ftp,telnet,http, etc... Lo primero que tenemos que hacer es instalarla ya sea desde su pagina web www.openssl.org o bajandonos el paquete de nuestra distribución, el siguiente paso es leer la documentacion de la pagina y aqui esta el problema,... es inmensa y encima no esta completa, pero para eso esta badchecksum para divulgar este tipo de información técnica de forma amena. Iniciacion de openssl: Bien siempre creí que como mejor se aprende es con un buen ejemplo asi que iremos paso a paso explicando cada uno de los puntos a seguir para ello necesitaremos una base de programacion en c aunque con un poco de atencion no es tan necesario vereis que es muy facil. Lo primero que hay que hacer es declarar las cabeceras: #include #include #include y despues de esto iniciar openssl, SSL_load_error_strings(); //nos da informacion de errores en ssl ERR_load_BIO_strings(); //nos da errores del basic input output de openssl OpenSSL_add_all_algorithms(); //añade todos los algorritmos de encriptacion Iniciar una conexion insegura -------------------------------- BIO es una abstracción para realizar comunicaciones de varios tipos entre ellas ficheros y por supuesto sockets y a la vez puede servir de filtro para por ejemplo Base64. Asi que hay q declarar un puntero, BIO *bio; Bien despues de todo esto la parte que sigue es conectar a algun sitio, bio = BIO_new_connect("servidor:puerto"); Si el valor devuelto es NULL fallo el handle *bio y si su valor es negativo o cero fallo la conexion, es bueno controlar estas excepciones pero en vuestras manos esta. Una vez establecida la conexion (tcp) leeremos datos de esta forma, int x = BIO_read(bio, buf, len); al estilo que se hace con la funcion read en unix los valores devueltos son 0 para una desconexion y negativo con un fallo en el handle, la funcion BIO_should_retry(bio) intentara de nuevo leer es util a veces. y para escribir pues mas de lo mismo, BIO_write(bio, buf, len); Por ultimo nos queda cerrar y liberar bio, BIO_reset(bio); //desconecta de todo BIO_free_all(bio); //libera la memoria Inicio de una conexion segura ----------------------------- Bien esta parte solo requiere un par de lineas mas de codigo ;),lo primero es iniciar una estructura que se encarga de iniciar ssl sobre la conexion BIO que iniciabamos al inicio de este tutorial tambien lo mas comun es iniciar el tipo de encriptacion comunmente es SSLv23_client_method. SSL_CTX * ctx = SSL_CTX_new(SSLv23_client_method()); SSL * ssl; El siguente paso es leer los certificados de autenticidad que normalmente vienen con openssl en su version mas actualizada se puede leer cada certificado por separado pero lo mejor es leer el TrustStore.pem que es donde estan archivados el conjunto de estos aunque si tienes uno propio pues tambien puedes usarlo. Para leer el certificado usamos SSL_CTX_load_verify_locations por ejemplo: if(! SSL_CTX_load_verify_locations(ctx, "/ruta/a/TrustStore.pem", NULL)) { /*fallo del handler*/ } si usamos c_rehash es posible usar un directorio de certificados en una shell ponemos c_rehash /ruta/a/directorio/certificados/ y despues podremos llamar desde nuestro programa a ese directorio normalmente if(! SSL_CTX_load_verify_locations(ctx, NULL, "/ruta/a/directorio/certificados")) { /* error en el handler*/ } Bien comenzamos: iniciamos conexion, bio = BIO_new_ssl_connect(ctx); BIO_get_ssl(bio, & ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); //por si el server cambia el modo conectamos, BIO_set_conn_hostname(bio, "hostname:port"); comprobamos q todo vaya bien por ejemplo: if(BIO_do_connect(bio) <= 0){fallo} comprobamos certificado, if(SSL_get_verify_result(ssl) != X509_V_OK){fallo} por ultimo liberamos el ctx, SSL_CTX_free(ctx); Detección de errores -------------------- Para mas informacion podeis consultar la documentacion de openssl aqui solo pondre algunos ejemplos creo que es mas practico: printf("Error: %s\n", ERR_reason_error_string(ERR_get_error())); imprime el ultimo error. printf("%s\n", ERR_error_string(ERR_get_error(), NULL)); imprime el error con texto preformateado en plan chulo. y por ultimo ERR_print_errors_fp(FILE *); ERR_print_errors(BIO *); dumpea los errores a un fichero en el primer caso o los manda a una bio en el segundo. hay monton de aplicaciones q usan openssl por ejemplo unrealircd, apache, yo solo he hecho un resumen del lado del cliente basandome en textos que podeis encontrar por internet los codes en los q se basa este tutorial los podeis bajar de http://www.kennethballard.com/Download/intro-openssl.zip un ejemplo de una funcion q uso para el protocolo messenger concretamente para conseguir el ticket de passport, no comprueba certificados solo conecta de forma segura al 443 del host dado y hace la petidion que le pasemos: char *peticion_ssl(char peticion[1024],char *respuesta,char conexion[30]) { int p; char r[1024]; BIO * bio; SSL * ssl; SSL_CTX * ctx; ERR_load_BIO_strings(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); ctx = SSL_CTX_new(SSLv23_client_method()); bio = BIO_new_ssl_connect(ctx); BIO_get_ssl(bio, & ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); BIO_set_conn_hostname(bio, conexion); if(BIO_do_connect(bio) <= 0) { fprintf(stderr, "Error attempting to connect\n"); ERR_print_errors_fp(stderr); BIO_free_all(bio); SSL_CTX_free(ctx); return 0; } BIO_write(bio, peticion, strlen(peticion)); respuesta=malloc(5000); for(;;) { p = BIO_read(bio, r, 1023); if(p <= 0) break; r[p] = 0; strncat(respuesta,r,2047); // printf("%s", r); } BIO_free_all(bio); SSL_CTX_free(ctx); return respuesta; } despues hay q hacer un free(respuesta); fuera de la funcion para liberar;) Bueno espero que os guste este tuto q aunque corto creo q es muy practico de todas formas para cualquier duda podeis contactar con icaro ya sabeis donde. :) BADCHECKSUM.