1 /* serv.cpp - Minimal ssleay server for Unix
2 30.9.1996, Sampo Kellomaki <sampo@iki.fi> */
5 /* mangled to work with SSLeay-0.9.0b and OpenSSL 0.9.2b
6 Simplified to be even more minimal
7 12/98 - 4/99 Wade Scholine <wades@mail.cybg.com> */
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <netinet/in.h>
17 #include <arpa/inet.h>
20 #include <openssl/rsa.h> /* SSLeay stuff */
21 #include <openssl/crypto.h>
22 #include <openssl/x509.h>
23 #include <openssl/pem.h>
24 #include <openssl/ssl.h>
25 #include <openssl/err.h>
28 /* define HOME to be dir for key and cert files... */
30 /* Make these what you want for cert & key files */
31 #define CERTF HOME "foo-cert.pem"
32 #define KEYF HOME "foo-cert.pem"
35 #define CHK_NULL(x) if ((x)==NULL) exit (1)
36 #define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
37 #define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2); }
44 struct sockaddr_in sa_serv
;
45 struct sockaddr_in sa_cli
;
54 /* SSL preliminaries. We keep the certificate and key with the context. */
56 SSL_load_error_strings();
57 SSLeay_add_ssl_algorithms();
58 meth
= SSLv23_server_method();
59 ctx
= SSL_CTX_new (meth
);
61 ERR_print_errors_fp(stderr
);
65 if (SSL_CTX_use_certificate_file(ctx
, CERTF
, SSL_FILETYPE_PEM
) <= 0) {
66 ERR_print_errors_fp(stderr
);
69 if (SSL_CTX_use_PrivateKey_file(ctx
, KEYF
, SSL_FILETYPE_PEM
) <= 0) {
70 ERR_print_errors_fp(stderr
);
74 if (!SSL_CTX_check_private_key(ctx
)) {
75 fprintf(stderr
,"Private key does not match the certificate public key\n");
79 /* ----------------------------------------------- */
80 /* Prepare TCP socket for receiving connections */
82 listen_sd
= socket (AF_INET
, SOCK_STREAM
, 0); CHK_ERR(listen_sd
, "socket");
84 memset (&sa_serv
, '\0', sizeof(sa_serv
));
85 sa_serv
.sin_family
= AF_INET
;
86 sa_serv
.sin_addr
.s_addr
= INADDR_ANY
;
87 sa_serv
.sin_port
= htons (1111); /* Server Port number */
89 err
= bind(listen_sd
, (struct sockaddr
*) &sa_serv
,
90 sizeof (sa_serv
)); CHK_ERR(err
, "bind");
92 /* Receive a TCP connection. */
94 err
= listen (listen_sd
, 5); CHK_ERR(err
, "listen");
96 client_len
= sizeof(sa_cli
);
97 sd
= accept (listen_sd
, (struct sockaddr
*) &sa_cli
, &client_len
);
98 CHK_ERR(sd
, "accept");
101 printf ("Connection from %lx, port %x\n",
102 sa_cli
.sin_addr
.s_addr
, sa_cli
.sin_port
);
104 /* ----------------------------------------------- */
105 /* TCP connection is ready. Do server side SSL. */
107 ssl
= SSL_new (ctx
); CHK_NULL(ssl
);
108 SSL_set_fd (ssl
, sd
);
109 err
= SSL_accept (ssl
); CHK_SSL(err
);
111 /* Get the cipher - opt */
113 printf ("SSL connection using %s\n", SSL_get_cipher (ssl
));
115 /* Get client's certificate (note: beware of dynamic allocation) - opt */
117 client_cert
= SSL_get_peer_certificate (ssl
);
118 if (client_cert
!= NULL
) {
119 printf ("Client certificate:\n");
121 str
= X509_NAME_oneline (X509_get_subject_name (client_cert
), 0, 0);
123 printf ("\t subject: %s\n", str
);
126 str
= X509_NAME_oneline (X509_get_issuer_name (client_cert
), 0, 0);
128 printf ("\t issuer: %s\n", str
);
131 /* We could do all sorts of certificate verification stuff here before
132 deallocating the certificate. */
134 X509_free (client_cert
);
136 printf ("Client does not have certificate.\n");
138 /* DATA EXCHANGE - Receive message and send reply. */
140 err
= SSL_read (ssl
, buf
, sizeof(buf
) - 1); CHK_SSL(err
);
142 printf ("Got %d chars:'%s'\n", err
, buf
);
144 err
= SSL_write (ssl
, "I hear you.", strlen("I hear you.")); CHK_SSL(err
);