ventajas solucion servidor que puerto protocolo funciona error entre desventajas comunicación como cliente certificado caracteristicas asegura c++ c sockets openssl ssl-certificate

solucion - Comunicación entre el cliente y el servidor mediante ssl c/c++: el protocolo SSL no funciona



protocolo ssl puerto (3)

Estoy intentando usar un ejemplo de cliente / servidor SSL de: http://simplestcodings.blogspot.com.br/2010/08/secure-server-client-using-openssl-in-c.html para crear una conexión segura usando SSLv3. Hice algunos cambios para solicitar el certificado en el lado del servidor, la comunicación funciona bien y se entiende en ambos lados. Por lo tanto, mi problema es que cuando el cliente se conecta al servidor, la comunicación de protocolo SSLv3 no funciona, verifiqué utilizando wirkeshark y en el campo de protocolo solo se muestra TCP, o IPA (RSL Malformed Packet). ¿Alguien puede ayudarme? ¡Gracias!

He creado mis certificados siguiendo el tutorial https://help.ubuntu.com/community/OpenSSL .

Aquí está mi código de cliente:

//SSL-Client.c #include <stdio.h> #include <errno.h> #include <unistd.h> #include <malloc.h> #include <string.h> #include <sys/socket.h> #include <resolv.h> #include <netdb.h> #include <openssl/ssl.h> #include <openssl/err.h> #define FAIL -1 //Added the LoadCertificates how in the server-side makes. void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile) { /* set the local certificate from CertFile */ if ( SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0 ) { ERR_print_errors_fp(stderr); abort(); } /* set the private key from KeyFile (may be the same as CertFile) */ if ( SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM) <= 0 ) { ERR_print_errors_fp(stderr); abort(); } /* verify private key */ if ( !SSL_CTX_check_private_key(ctx) ) { fprintf(stderr, "Private key does not match the public certificate/n"); abort(); } } int OpenConnection(const char *hostname, int port) { int sd; struct hostent *host; struct sockaddr_in addr; if ( (host = gethostbyname(hostname)) == NULL ) { perror(hostname); abort(); } sd = socket(PF_INET, SOCK_STREAM, 0); bzero(&addr, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = *(long*)(host->h_addr); if ( connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 ) { close(sd); perror(hostname); abort(); } return sd; } SSL_CTX* InitCTX(void) { SSL_METHOD *method; SSL_CTX *ctx; OpenSSL_add_all_algorithms(); /* Load cryptos, et.al. */ SSL_load_error_strings(); /* Bring in and register error messages */ method = SSLv3_client_method(); /* Create new client-method instance */ ctx = SSL_CTX_new(method); /* Create new context */ if ( ctx == NULL ) { ERR_print_errors_fp(stderr); abort(); } return ctx; } void ShowCerts(SSL* ssl) { X509 *cert; char *line; cert = SSL_get_peer_certificate(ssl); /* get the server''s certificate */ if ( cert != NULL ) { printf("Server certificates:/n"); line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); printf("Subject: %s/n", line); free(line); /* free the malloc''ed string */ line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); printf("Issuer: %s/n", line); free(line); /* free the malloc''ed string */ X509_free(cert); /* free the malloc''ed certificate copy */ } else printf("No certificates./n"); } int main() { SSL_CTX *ctx; int server; SSL *ssl; char buf[1024]; int bytes; char hostname[]="127.0.0.1"; char portnum[]="5000"; char CertFile[] = "/home/myCA/cacert.pem"; char KeyFile[] = "/home/myCA/private/cakey.pem"; SSL_library_init(); ctx = InitCTX(); LoadCertificates(ctx, CertFile, KeyFile); server = OpenConnection(hostname, atoi(portnum)); ssl = SSL_new(ctx); /* create new SSL connection state */ SSL_set_fd(ssl, server); /* attach the socket descriptor */ if ( SSL_connect(ssl) == FAIL ) /* perform the connection */ ERR_print_errors_fp(stderr); else { char *msg = "Hello???"; printf("Connected with %s encryption/n", SSL_get_cipher(ssl)); ShowCerts(ssl); /* get any certs */ SSL_write(ssl, msg, strlen(msg)); /* encrypt & send message */ bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */ buf[bytes] = 0; printf("Received: /"%s/"/n", buf); SSL_free(ssl); /* release connection state */ } close(server); /* close socket */ SSL_CTX_free(ctx); /* release context */ return 0; }

Y el servidor:

//SSL-Server.c #include <errno.h> #include <unistd.h> #include <malloc.h> #include <string.h> #include <arpa/inet.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <resolv.h> #include "openssl/ssl.h" #include "openssl/err.h" #define FAIL -1 int OpenListener(int port) { int sd; struct sockaddr_in addr; sd = socket(PF_INET, SOCK_STREAM, 0); bzero(&addr, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = INADDR_ANY; if ( bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 ) { perror("can''t bind port"); abort(); } if ( listen(sd, 10) != 0 ) { perror("Can''t configure listening port"); abort(); } return sd; } SSL_CTX* InitServerCTX(void) { SSL_METHOD *method; SSL_CTX *ctx; OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */ SSL_load_error_strings(); /* load all error messages */ method = SSLv3_server_method(); /* create new server-method instance */ ctx = SSL_CTX_new(method); /* create new context from method */ if ( ctx == NULL ) { ERR_print_errors_fp(stderr); abort(); } return ctx; } void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile) { //New lines if (SSL_CTX_load_verify_locations(ctx, CertFile, KeyFile) != 1) ERR_print_errors_fp(stderr); if (SSL_CTX_set_default_verify_paths(ctx) != 1) ERR_print_errors_fp(stderr); //End new lines /* set the local certificate from CertFile */ if (SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); abort(); } /* set the private key from KeyFile (may be the same as CertFile) */ if (SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); abort(); } /* verify private key */ if (!SSL_CTX_check_private_key(ctx)) { fprintf(stderr, "Private key does not match the public certificate/n"); abort(); } //New lines - Force the client-side have a certificate SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); SSL_CTX_set_verify_depth(ctx, 4); //End new lines } void ShowCerts(SSL* ssl) { X509 *cert; char *line; cert = SSL_get_peer_certificate(ssl); /* Get certificates (if available) */ if ( cert != NULL ) { printf("Server certificates:/n"); line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); printf("Subject: %s/n", line); free(line); line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); printf("Issuer: %s/n", line); free(line); X509_free(cert); } else printf("No certificates./n"); } void Servlet(SSL* ssl) /* Serve the connection -- threadable */ { char buf[1024]; char reply[1024]; int sd, bytes; const char* HTMLecho="<html><body><pre>%s</pre></body></html>/n/n"; if ( SSL_accept(ssl) == FAIL ) /* do SSL-protocol accept */ ERR_print_errors_fp(stderr); else { ShowCerts(ssl); /* get any certificates */ bytes = SSL_read(ssl, buf, sizeof(buf)); /* get request */ if ( bytes > 0 ) { buf[bytes] = 0; printf("Client msg: /"%s/"/n", buf); sprintf(reply, HTMLecho, buf); /* construct reply */ SSL_write(ssl, reply, strlen(reply)); /* send reply */ } else ERR_print_errors_fp(stderr); } sd = SSL_get_fd(ssl); /* get socket connection */ SSL_free(ssl); /* release SSL state */ close(sd); /* close connection */ } int main() { SSL_CTX *ctx; int server; char portnum[]="5000"; char CertFile[] = "/home/myCA/mycert.pem"; char KeyFile[] = "/home/myCA/mycert.pem"; SSL_library_init(); ctx = InitServerCTX(); /* initialize SSL */ LoadCertificates(ctx, CertFile, KeyFile); /* load certs */ server = OpenListener(atoi(portnum)); /* create server socket */ while (1) { struct sockaddr_in addr; socklen_t len = sizeof(addr); SSL *ssl; int client = accept(server, (struct sockaddr*)&addr, &len); /* accept connection as usual */ printf("Connection: %s:%d/n",inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); ssl = SSL_new(ctx); /* get new SSL state with context */ SSL_set_fd(ssl, client); /* set connection socket to SSL state */ Servlet(ssl); /* service connection */ } close(server); /* close server socket */ SSL_CTX_free(ctx); /* release context */ }


Como dije en los comentarios a una de sus preguntas anteriores , el hecho de que obtenga un " Paquete con formato incorrecto: GSM sobre IP " o algo extraño aquí es normal.

Está utilizando el puerto 5000, que normalmente está reservado para el protocolo commplex-main . Por lo tanto, sin ningún tipo de información adicional, Wireshark intenta analizar el tráfico que ve con los decodificadores commplex-main .

Por supuesto, dado que los datos que está intercambiando en ese puerto son de hecho SSL / TLS (porque está usando un puerto que normalmente no se usa para eso), descodifíquelos como si commplex-main a una cantidad de datos impares. Mensajes sobre paquetes mal formados.

Wireshark solo adivina el protocolo usando el número de puerto que ve. Debe indicarle que pruebe un decodificador diferente, si no está utilizando el puerto estándar para ese protocolo.

Más específicamente, haga clic derecho en un paquete y elija Decodificar como ... -> Transporte -> SSL .


Con los programas de servidor y cliente anteriores, estaba recibiendo el siguiente error:

140671281543104: error: 140890B2: Rutinas SSL: SSL3_GET_CLIENT_CERTIFICATE: no se devolvió el certificado: s3_srvr.c: 3292:

Yo había generado certificados autofirmados usando el procedimiento mencionado en https://help.ubuntu.com/community/OpenSSL .

Después de hacer malabares con el error durante un día, descubrí que el error se debía a que la CA autogenerada no estaba en la cadena de confianza de la máquina que estaba usando.

Para agregar la CA a la cadena de confianza en RHEL-7, se puede seguir el siguiente procedimiento:

To add a certificate in the simple PEM or DER file formats to the list of CAs trusted on the system: Copy it to the /etc/pki/ca-trust/source/anchors/ subdirectory, and run the update-ca-trust command. If your certificate is in the extended BEGIN TRUSTED file format, then place it into the main source/ directory instead.

Creo que el procedimiento anterior puede seguirse también para fedora. Si esto no funciona, puede ser útil explorar los comandos como "update-ca-certificados". Espero que esto le sea útil a alguien.


debe modificar su código (servidor): su código:

int main() { SSL_CTX *ctx; int server; **char portnum[]="5000";** char CertFile[] = "/home/myCA/mycert.pem"; char KeyFile[] = "/home/myCA/mycert.pem"; SSL_library_init(); **portnum = strings[1];**

en su lugar deberías usar esto:

int main(int argc, char **argv) { SSL_CTX *ctx; int server; //char portnum[]="5000"; ---> You can pass it as an argument char CertFile[] = "/home/myCA/mycert.pem"; char KeyFile[] = "/home/myCA/mycert.pem"; SSL_library_init(); //portnum = strings[1]; portnum = argv[1]; // ---> You can pass port number here, instead of put it in the code

Tengo esta salida (cliente):

toc@UnixServer:~$ ./ssl_client Connected with AES256-SHA encryption Server certificates: Subject: /C=FR/ST=Some-State/L=PARIS/O=TOC/OU=TOC/CN=TOC/[email protected] Issuer: /C=FR/ST=Some-State/L=PARIS/O=TOC/OU=TOC/CN=TOC/[email protected] Received: "<html><body><pre>Hello???</pre></body></html> "

Y esta salida (servidor):

Connection: 127.0.0.1:59066 Server certificates: Subject: /C=FR/ST=Some-State/L=PARIS/O=TOC/OU=TOC/CN=TOC/[email protected] Issuer: /C=FR/ST=Some-State/L=PARIS/O=TOC/OU=TOC/CN=TOC/[email protected] Client msg: "Hello???"

Cuando usa una herramienta como ssldump (http://www.rtfm.com/ssldump/) (en el cuadro de Unix), puede ver claramente lo que está pasando:

toc@UnixServer:~$sudo ssldump -i lo port 5000 New TCP connection #1: localhost(59071) <-> localhost(5000) 1 1 0.0012 (0.0012) C>S Handshake ClientHello Version 3.0 cipher suites Unknown value 0xc014 Unknown value 0xc00a SSL_DHE_RSA_WITH_AES_256_CBC_SHA SSL_DHE_DSS_WITH_AES_256_CBC_SHA Unknown value 0x88 Unknown value 0x87 Unknown value 0xc00f Unknown value 0xc005 SSL_RSA_WITH_AES_256_CBC_SHA Unknown value 0x84 Unknown value 0xc012 Unknown value 0xc008 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA Unknown value 0xc00d Unknown value 0xc003 SSL_RSA_WITH_3DES_EDE_CBC_SHA Unknown value 0xc013 Unknown value 0xc009 SSL_DHE_RSA_WITH_AES_128_CBC_SHA SSL_DHE_DSS_WITH_AES_128_CBC_SHA Unknown value 0x9a Unknown value 0x99 Unknown value 0x45 Unknown value 0x44 Unknown value 0xc00e Unknown value 0xc004 SSL_RSA_WITH_AES_128_CBC_SHA Unknown value 0x96 Unknown value 0x41 Unknown value 0xc011 Unknown value 0xc007 Unknown value 0xc00c Unknown value 0xc002 SSL_RSA_WITH_RC4_128_SHA SSL_RSA_WITH_RC4_128_MD5 SSL_DHE_RSA_WITH_DES_CBC_SHA SSL_DHE_DSS_WITH_DES_CBC_SHA SSL_RSA_WITH_DES_CBC_SHA SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA SSL_RSA_EXPORT_WITH_DES40_CBC_SHA SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 SSL_RSA_EXPORT_WITH_RC4_40_MD5 Unknown value 0xff compression methods unknown value NULL 1 2 0.0019 (0.0006) S>C Handshake ServerHello Version 3.0 session_id[32]= 13 e2 5a f0 10 93 18 56 c8 66 54 94 29 ab 8b 2d 7b c6 9c 3b 7b ea c7 54 e6 86 7d 3a 56 8c 96 14 cipherSuite SSL_RSA_WITH_AES_256_CBC_SHA compressionMethod unknown value 1 3 0.0019 (0.0000) S>C Handshake Certificate 1 4 0.0019 (0.0000) S>C Handshake CertificateRequest certificate_types rsa_sign certificate_types dss_sign ServerHelloDone 1 5 0.0155 (0.0136) C>S Handshake Certificate 1 6 0.0155 (0.0000) C>S Handshake ClientKeyExchange 1 7 0.0155 (0.0000) C>S Handshake CertificateVerify Signature[128]= ac 94 31 89 64 75 20 5f 4f 00 73 4e e8 de 51 b7 f1 bb 16 da 63 b1 8d e9 15 9b af f8 32 d7 84 f5 b5 7d 4f 48 1c 2b 41 58 81 d3 a8 50 40 25 90 95 44 de 9d bb c4 79 5c 64 a8 a9 28 f4 16 7c 0e 17 b2 77 cf b0 8c a9 90 50 34 a5 76 a2 57 39 8d 37 12 d8 a5 8d f4 08 3a 1e 83 7e 6c 0a e9 75 ec 85 3d 56 f2 2e 4a 7d 71 88 29 26 99 40 43 4e f3 29 26 bf eb 15 be 36 22 72 f3 d9 be 4a e3 c9 0b cc 1 8 0.0155 (0.0000) C>S ChangeCipherSpec 1 9 0.0155 (0.0000) C>S Handshake 1 10 0.0245 (0.0089) S>C ChangeCipherSpec 1 11 0.0245 (0.0000) S>C Handshake 1 12 0.0250 (0.0005) C>S application_data 1 13 0.0250 (0.0000) C>S application_data 1 14 0.0258 (0.0007) S>C application_data 1 15 0.0258 (0.0000) S>C application_data 1 0.0261 (0.0002) C>S TCP FIN 1 0.0275 (0.0013) S>C TCP FIN

Saludos.