|
|
|
| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
AnimAlf Forista

Registrado: 18 Ago 2008 Mensajes: 722 Ubicación: tgn
|
Publicado: Vie Dic 28, 2012 3:21 pm Asunto: Un poco de libssl |
|
|
Aquí tenéis un code funcional, que muestra los pasos a seguir para un primer contacto. Realiza una conexión remota al puerto 443, recibe el certificado y envia y recibe información cifrada.
Se debe enlazar con libssl y libcrypto, por lo que para construirlo añadiremos -lssl -lcrypto
| Código: | #include <stdio.h>
#include <memory.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define TIEMPO_DE_SESION 300
#define PUERTO_HTTPS 443
static void info_devuelta ( const SSL *s, int lugar, int ret )
{
printf ( "\t%s\n", SSL_state_string_long ( s ) );
}
static void errorssl ( char *cadena )
{
char msgerror [120];
ERR_error_string ( ERR_get_error(), msgerror );
printf ( "%s: %s", cadena, msgerror );
}
int main ( int argc, const char * argv[] )
{
SSL * ssl;
SSL_CTX * ctx;
X509 * certificado_server;
int sd, err;
char *str, *urlremota, bufferSalida[4096],
bufferEntrada[4096], peticionAlServer[512];
struct hostent * host_entry;
struct sockaddr_in direcion_socket_server;
struct in_addr ip;
/*
* si no se indica la url la pedimos
*/
if(argc != 2)
{
urlremota = ( char * ) malloc ( 255 );
printf( "https://" );
scanf ( "%s", urlremota );
} else urlremota = ( char * ) argv[1];
/*
* iniciamos la librería SSL
*/
SSLeay_add_ssl_algorithms ();
SSL_load_error_strings ();
ctx = SSL_CTX_new ( SSLv3_client_method () );
SSL_CTX_set_session_cache_mode ( ctx, SSL_SESS_CACHE_BOTH );
SSL_CTX_set_timeout ( ctx, TIEMPO_DE_SESION );
SSL_CTX_set_info_callback ( ctx, info_devuelta );
printf ( "Entorno SSL iniciado\n\n" );
/*
* adquirimos la dirección ip de la URL
*/
host_entry = gethostbyname ( urlremota );
bcopy ( host_entry->h_addr, &( ip.s_addr ), host_entry->h_length );
printf ( "'%s' tiene la siguiente IP '%s'\n\n", urlremota, inet_ntoa ( ip ) );
/*
* abrimos la conexión TCP al puerto remoto
*/
sd = socket ( AF_INET,SOCK_STREAM, 0 );
memset ( &direcion_socket_server, '\0', sizeof ( direcion_socket_server ) );
direcion_socket_server.sin_family = AF_INET;
direcion_socket_server.sin_port = htons ( PUERTO_HTTPS );
memcpy ( &( direcion_socket_server.sin_addr.s_addr ), host_entry->h_addr,
host_entry->h_length );
err = connect(sd, (const struct sockaddr * ) &direcion_socket_server,
sizeof ( direcion_socket_server ) );
if(err < 0)
{
perror ( "no se pueder connectar con el puerto remoto" );
exit (1);
}
printf ( "Conexión TCP iniciada con '%s' a traves de puerto local %d \n\n",
urlremota, direcion_socket_server.sin_port );
/*
* iniciar la negociación SSL sobre la conexión TCP
*/
if ( ! ( ssl = SSL_new (ctx) ) ) { /*punto final pila SSL */
errorssl ( "SSL_new" );
close ( sd );
exit (1);
}
SSL_set_fd ( ssl, sd ); /* añadimos la pila SSL al socket */
puts ( "Información retornada durante el proceso de sonexión:" );
err = SSL_connect ( ssl ); /* Iniciamos la negociación SSL */
if ( err <= 0 ) {
errorssl ( "SSL_connect" );
SSL_shutdown ( ssl );
SSL_free ( ssl );
SSL_CTX_free ( ctx );
close ( sd );
exit (1);
}
printf("\nSSL endpoint creado & negociación completeda. err = %d\n\n", err);
/*
* mostramos el metodo de cifrado para la comunicación
*/
printf("SSL conectado con cifrado: %s\n\n", SSL_get_cipher ( ssl ) );
/*
* mostramos el certificado del server
*/
certificado_server = SSL_get_peer_certificate ( ssl );
printf("Certificado del server recibido:\n\n");
str = X509_NAME_oneline ( X509_get_subject_name ( certificado_server ), 0, 0 );
printf("\tasunto: %s\n",str);
str = X509_NAME_oneline ( X509_get_issuer_name ( certificado_server ), 0, 0 );
printf ( "\temisor: %s\n",str );
printf ( "\n" );
/* la verificación del certificado ocurrió aquí. */
X509_free ( certificado_server );
/*
* negociación completada --- enviar petición HTTP sobre SSL
*/
strcpy ( bufferSalida,"GET / HTTP/1.0\r\n" );
sprintf ( peticionAlServer, "Host: %s:%d\r\n", urlremota, PUERTO_HTTPS );
strcat ( bufferSalida, peticionAlServer );
strcat ( bufferSalida, "Connection: close\r\n");
strcat ( bufferSalida, "\r\n");
err = SSL_write ( ssl, bufferSalida, strlen ( bufferSalida ) );
shutdown ( sd, 1 ); /* enviamos EOF al server */
printf("Enviar petición HTTP por un canal cifrado:\n\n%s\n", bufferSalida );
/*
* leermos la respuesta HTTP a traves de la pila SSL
*/
err = SSL_read ( ssl, bufferEntrada, sizeof ( bufferEntrada ) -1 );
bufferEntrada[err] = '\0';
printf ( "recibidos %d bytes como respuesta HTTP:\n\n%s\n", err, bufferEntrada );
/*
* terminamos cerrando la sesión y liberando
*/
printf ( " salida y cierre de sesion.\n\nPulsa Return para terminar" );
getchar ();
SSL_shutdown ( ssl );
close ( sd );
SSL_free ( ssl );
SSL_CTX_free ( ctx );
return 0;
} |
SaludOS _________________ En busca del TuXeR perdido |
|
| Volver arriba |
|
 |
|
|
Puede publicar nuevos temas en este foro No puede responder a temas en este foro No puede editar sus mensajes en este foro No puede borrar sus mensajes en este foro No puede votar en encuestas en este foro
|
La marca registrada Linux (R) se usa siguiendo la sublicensia obtenida del "Linux Mark Institute", el LICENCIATARIO exclusivo de Linus Torvalds, propietario de la marca en EEUU y otros países
The registered trademark Linux (R) is used pursuant to a sublicense from the Linux Mark Institute, the exclusive LICENSEE of Linus Torvalds, owner of the mark in the U.S. and other countries
Powered by phpBB © 2001, 2002 phpBB Group
Contactos
|