openssl/demos/ssl/cli.cpp
Matt Caswell 13c9bb3ece Client side version negotiation rewrite
Continuing from the previous commit this changes the way we do client side
version negotiation. Similarly all of the s23* "up front" state machine code
has been avoided and again things now work much the same way as they already
did for DTLS, i.e. we just do most of the work in the
ssl3_get_server_hello() function.

Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2015-05-16 09:20:31 +01:00

109 lines
3.1 KiB
C++

/* cli.cpp - Minimal ssleay client for Unix
30.9.1996, Sampo Kellomaki <sampo@iki.fi> */
/* mangled to work with SSLeay-0.9.0b and OpenSSL 0.9.2b
Simplified to be even more minimal
12/98 - 4/99 Wade Scholine <wades@mail.cybg.com> */
#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 <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#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); }
void main ()
{
int err;
int sd;
struct sockaddr_in sa;
SSL_CTX* ctx;
SSL* ssl;
X509* server_cert;
char* str;
char buf [4096];
SSL_METHOD *meth;
SSLeay_add_ssl_algorithms();
meth = TLS_client_method();
SSL_load_error_strings();
ctx = SSL_CTX_new (meth); CHK_NULL(ctx);
/* ----------------------------------------------- */
/* Create a socket and connect to server using normal socket calls. */
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 ("127.0.0.1"); /* Server IP */
sa.sin_port = htons (1111); /* Server Port number */
err = connect(sd, (struct sockaddr*) &sa,
sizeof(sa)); CHK_ERR(err, "connect");
/* ----------------------------------------------- */
/* Now we have TCP conncetion. Start SSL negotiation. */
ssl = SSL_new (ctx); CHK_NULL(ssl);
SSL_set_fd (ssl, sd);
err = SSL_connect (ssl); CHK_SSL(err);
/* Following two steps are optional and not required for
data exchange to be successful. */
/* Get the cipher - opt */
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");
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, "Hello World!", strlen("Hello World!")); 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);
SSL_shutdown (ssl); /* send SSL/TLS close_notify */
/* Clean up. */
close (sd);
SSL_free (ssl);
SSL_CTX_free (ctx);
}
/* EOF - cli.cpp */