OpenSSL VPN Serveurs de messagerie |
OpenSSL/ClientTCPAvecSSLclient TCP avec SSL // client.cpp : application console // #include "stdafx.h" #include <openssl/crypto.h> #include <openssl/x509.h> #include <openssl/pem.h> #include <openssl/ssl.h> #include <openssl/err.h> #define CA_FILE "C:\\TEMP\\openssl\\CA_CDN.crt" #define CA_DIR NULL //#define CA_FILE NULL //#define CA_DIR "C:\\temp\\openssl" #define CLIENT_CRT "C:\\TEMP\\openssl\\NET208WEB001_crt.pem" //#define CLIENT_PVK "C:\\temp2\\cert\\client1_ca2_pvk.pem" static char pass[]="MjYxQUNERjE="; // // insérer Ws2_32.lib dans Link>General>Library Modules // insérer C:\OpenSSL\include dans C/C++>PreProcessor>Additional include directories // insérer C:\OpenSSL\out32.dbg Link>Input>Additional library path: // C/C++>Code Generation>Use Runtime library>Debug Multithread DLL // #define CHK_NULL(x) if ((x)==NULL) exit (1) #define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); } #define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2); } #pragma comment(lib, "ssleay32.lib") #pragma comment(lib, "libeay32.lib") static int password_cb(char *buf,int num,int rwflag,void *userdata) { if(num<strlen(pass)+1) return(0); strcpy(buf,pass); return(strlen(pass)); } void PrintSSLError(){ int sslerror = ERR_get_error(); char error_buffer[120]; ERR_error_string(sslerror, error_buffer); printf("%s",error_buffer); } int verify_callback(int ok, X509_STORE_CTX *store) { char data[256]; printf("verify_callback\r\n"); if (!ok) { X509 *cert = X509_STORE_CTX_get_current_cert(store); int depth = X509_STORE_CTX_get_error_depth(store); int err = X509_STORE_CTX_get_error(store); //printf("-Error with certificate at depth: %i\n", depth); //X509_NAME_oneline(X509_get_issuer_name(cert), data, 256); //printf(" issuer = %s\n", data); //X509_NAME_oneline(X509_get_subject_name(cert), data, 256); //printf(" subject = %s\n", data); //printf("err %i:%s\n", err, X509_verify_cert_error_string(err)); PrintSSLError(); } return ok; } int main(int argc, char* argv[]) { WSADATA wsaData; SOCKET sd; struct sockaddr_in sa; hostent* remoteHost; int err; char buf [4096]; SSL_CTX* ctx; SSL* ssl; X509* server_cert; SSL_METHOD *meth; X509_STORE *store; X509_LOOKUP *lookup; X509_STORE_CTX *verify_ctx; X509 *cert; FILE *fp=NULL; //----------------------------------------------- // Initialize Winsock WSAStartup(MAKEWORD(2,2), &wsaData); sd = socket(AF_INET, SOCK_STREAM, 0); CHK_ERR(sd, "socket"); memset (&sa, '\0', sizeof(sa)); sa.sin_family = AF_INET; //sa.sin_addr.s_addr = inet_addr ("172.31.198.15"); /* Server IP */ remoteHost = gethostbyname("sec030dev146"); sa.sin_addr.s_addr = *((u_long*)remoteHost->h_addr_list[0]); sa.sin_port= htons(2907); /* Server Port number */ err = connect(sd,(struct sockaddr*) &sa,sizeof(sa)); CHK_ERR(err, "connect"); // INIT SSL_library_init(); SSLeay_add_ssl_algorithms(); meth = SSLv3_client_method(); SSL_load_error_strings(); ctx = SSL_CTX_new(meth); CHK_NULL(ctx); printf("SSL_CTX_load_verify_locations\r\n"); if (SSL_CTX_load_verify_locations(ctx, CA_FILE, CA_DIR) != 1) printf("Error loading CA file and/or directory"); //if(!(SSL_CTX_use_certificate_file(ctx,"c:\\client2_crt.pem",SSL_FILETYPE_PEM))){ // printf("Couldn't read certificate file"); // int sslerror = ERR_get_error(); // char error_buffer[120]; // ERR_error_string(sslerror, error_buffer); // printf("%s",error_buffer); //} if(!SSL_CTX_use_certificate_chain_file(ctx, CLIENT_CRT)){ printf("Couldn't read certificate file"); int sslerror = ERR_get_error(); char error_buffer[120]; ERR_error_string(sslerror, error_buffer); printf("%s",error_buffer); } printf("SSL_CTX_set_default_passwd_cb\r\n"); SSL_CTX_set_default_passwd_cb(ctx,password_cb); printf("SSL_CTX_use_PrivateKey_file\r\n"); //if(!(SSL_CTX_use_PrivateKey_file(ctx,CLIENT_PVK,SSL_FILETYPE_PEM))){ if(!(SSL_CTX_use_PrivateKey_file(ctx,CLIENT_CRT,SSL_FILETYPE_PEM))){ printf("Couldn't read private key file"); } SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,verify_callback); CHK_SSL(err); // first read the client certificate printf("opening client certificate ...\r\n"); if ((fp = fopen(CLIENT_CRT, "r")) == NULL){ printf("Error reading client certificate file"); return 0; } printf("PEM_read_X509...\r\n"); cert = PEM_read_X509(fp, NULL, NULL, NULL); //if ((cert = PEM_read_X509(fp, NULL, NULL, NULL)) == NULL){ // printf("Error reading client certificate in file"); // return 0; //} fclose(fp); printf("creating store..."); if (!(store = X509_STORE_new ())){ printf("error initialize store certificat"); return 1; } X509_STORE_set_verify_cb_func (store, verify_callback); printf("reading CA ..."); if (X509_STORE_load_locations (store, CA_FILE, CA_DIR) != 1){ PrintSSLError(); printf("Error loading the CA file or directory"); } if (X509_STORE_set_default_paths (store) != 1) printf ("Error loading the system-wide CA certificates"); if (!(lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file ()))) printf ("Error creating X509_LOOKUP object"); //if (X509_load_crl_file (lookup, CRL_FILE, X509_FILETYPE_PEM) != 1){ // PrintSSLError(); // printf ("Error reading the CRL file"); //} // enabling verification against CRLs is not possible in prior versions #if (OPENSSL_VERSION_NUMBER > 0x00907000L) // set the flags of the store so that CRLs are consulted //X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); X509_STORE_set_flags (store,NULL); #endif // create a verification context and initialize it if (!(verify_ctx = X509_STORE_CTX_new ())) printf ("Error creating X509_STORE_CTX object"); // X509_STORE_CTX_init did not return an error condition in prior versions #if (OPENSSL_VERSION_NUMBER > 0x00907000L) if (X509_STORE_CTX_init (verify_ctx, store, cert, NULL) != 1) printf("Error initializing verification context"); #else X509_STORE_CTX_init (verify_ctx, store, cert, NULL); #endif // verify the certificate if (X509_verify_cert (verify_ctx) != 1){ printf("Error verifying the certificate"); PrintSSLError(); } else{ printf ("Certificate verified correctly!\n");} ssl = SSL_new(ctx); CHK_NULL(ssl); printf("connect ...\r\n"); SSL_set_fd(ssl, sd); err = SSL_connect(ssl); CHK_SSL(err); printf ("SSL connection using %s\n", SSL_get_cipher (ssl)); /* Get server's certificate (note: beware of dynamic allocation) - opt */ server_cert = SSL_get_peer_certificate (ssl); CHK_NULL(server_cert); printf ("Server certificate:\n"); char *str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0); CHK_NULL(str); printf ("\t subject: %s\n", str); OPENSSL_free (str); str = X509_NAME_oneline (X509_get_issuer_name (server_cert),0,0); CHK_NULL(str); printf ("\t issuer: %s\n", str); OPENSSL_free (str); /* We could do all sorts of certificate verification stuff here before deallocating the certificate. */ X509_free(server_cert); // --------------------------------------------------- // DATA EXCHANGE - Send a message and receive a reply. err = SSL_write (ssl, "GET / HTTP/1.0\r\n\r\n", strlen("GET / HTTP/1.1\r\n\r\n")); CHK_SSL(err); err = SSL_read (ssl, buf, sizeof(buf) - 1); CHK_SSL(err); buf[err] = '\0'; printf ("Got %d chars:'%s'\n", err, buf); //BIO_free(sbio); SSL_shutdown(ssl); // send SSL/TLS close_notify SSL_free (ssl); SSL_CTX_free(ctx); closesocket(sd); cleanUp: WSACleanup(); return 0; } |