Communication client et serveur à l’aide de ssl c / c ++ – le protocole SSL ne fonctionne pas

J’essaie d’utiliser un exemple client / serveur SSL de: http://simplestcodings.blogspot.com.br/2010/08/secure-server-client-using-openssl-in-c.html pour créer une connexion sécurisée à l’aide de SSLv3. J’ai apporté quelques modifications pour demander le certificate côté serveur, la communication fonctionne bien et est comprise des deux côtés. Ainsi, mon problème est que lorsque le client se connecte au serveur, la communication de protocole SSLv3 ne fonctionne pas, je vérifie à l’aide de wirkeshark et dans le champ de protocole indique simplement TCP ou IPA (RSL Malformed Packet) quelqu’un peut m’aider? Merci!

J’ai créé mes certificates en suivant le tutoriel https://help.ubuntu.com/community/OpenSSL .

Voici mon code client:

//SSL-Client.c #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #define FAIL -1 //Added the LoadCertificates how in the server-side makes. void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile) { /* set the local certificatee from CertFile */ if ( SSL_CTX_use_certificatee_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) 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_ssortingngs(); /* 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_certificatee(ssl); /* get the server's certificatee */ if ( cert != NULL ) { printf("Server certificatees:\n"); line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); printf("Subject: %s\n", line); free(line); /* free the malloc'ed ssortingng */ line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); printf("Issuer: %s\n", line); free(line); /* free the malloc'ed ssortingng */ X509_free(cert); /* free the malloc'ed certificatee copy */ } else printf("No certificatees.\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; } 

Et le serveur:

 //SSL-Server.c #include  #include  #include  #include  #include  #include  #include  #include  #include  #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_ssortingngs(); /* 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 certificatee from CertFile */ if (SSL_CTX_use_certificatee_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="
%s

\n\n"; if ( SSL_accept(ssl) == FAIL ) /* do SSL-protocol accept */ ERR_print_errors_fp(stderr); else { ShowCerts(ssl); /* get any certificatees */ 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 */ }

Avec les programmes serveur et client ci-dessus, j’obtenais l’erreur suivante:

140671281543104: erreur: 140890B2: routines SSL: SSL3_GET_CLIENT_CERTIFICATE: aucun certificate renvoyé: s3_srvr.c: 3292:

J’avais généré des certificates auto-signés en utilisant la procédure mentionnée dans https://help.ubuntu.com/community/OpenSSL .

Après avoir jonglé avec l’erreur pendant un jour, j’ai constaté que l’erreur était due au fait que l’autorité de certificateion auto-générée ne faisait pas partie de la chaîne de confiance de la machine que j’utilisais.

Pour append l’autorité de certificateion à la chaîne de confiance dans RHEL-7, suivez la procédure ci-dessous:

  To add a certificatee 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 certificatee is in the extended BEGIN TRUSTED file format, then place it into the main source/ directory instead. 

Je pense que la procédure ci-dessus peut également être suivie pour fedora. Si cela ne fonctionne pas, il peut être utile d’explorer des commandes telles que “update-ca-certificatees”. J’espère que cela sera utile à quelqu’un.

vous devez modifier votre code (côté serveur): votre code:

 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 = ssortingngs[1];** 

à la place, vous devriez utiliser ceci:

 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 = ssortingngs[1]; portnum = argv[1]; // ---> You can pass port number here, instead of put it in the code 

J’ai eu cette sortie (client):

 toc@UnixServer:~$ ./ssl_client Connected with AES256-SHA encryption Server certificatees: Subject: /C=FR/ST=Some-State/L=PARIS/O=TOC/OU=TOC/CN=TOC/emailAddress=toc@toc.com Issuer: /C=FR/ST=Some-State/L=PARIS/O=TOC/OU=TOC/CN=TOC/emailAddress=toc@toc.com Received: "
Hello???

"

Et cette sortie (serveur):

 Connection: 127.0.0.1:59066 Server certificatees: Subject: /C=FR/ST=Some-State/L=PARIS/O=TOC/OU=TOC/CN=TOC/emailAddress=toc@toc.com Issuer: /C=FR/ST=Some-State/L=PARIS/O=TOC/OU=TOC/CN=TOC/emailAddress=toc@toc.com Client msg: "Hello???" 

Lorsque vous utilisez un outil comme ssldump (http://www.rtfm.com/ssldump/) (sous Unix), vous pouvez voir clairement ce qui se passe:

 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 certificatee_types rsa_sign certificatee_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 

Cordialement.

Comme je le disais dans les commentaires sur l’ une de vos questions précédentes , le fait que vous obteniez un ” paquet malformé: GSM sur IP ” ou quelque chose de bizarre ici est normal.

Vous utilisez le port 5000, qui est normalement réservé au protocole commplex-main . Par conséquent, sans aucune information supplémentaire, Wireshark tente d’parsingr le trafic commplex-main avec les décodeurs commplex-main .

Bien sûr, puisque les données que vous échangez sur ce port sont en fait SSL / TLS (parce que vous utilisez un port qui n’est normalement pas utilisé pour cela), le décodage comme s’il s’agissait de commplex-main conduit à un certain nombre de messages concernant les paquets mal formés.

Wireshark ne devine que le protocole en utilisant le numéro de port qu’il voit. Vous devez lui dire d’essayer un autre décodeur si vous n’utilisez pas le port standard pour ce protocole.

Plus précisément, cliquez avec le bouton droit sur un paquet et choisissez Décoder en tant que … -> Transport -> SSL .