aboutsummaryrefslogtreecommitdiff
path: root/openssl/trunk/demos/ssl/serv.cpp
blob: b142c758d2c26c03de36e880a401830aef088b3a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* serv.cpp  -  Minimal ssleay server 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 <unistd.h>
#include <stdlib.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/rsa.h>       /* SSLeay stuff */
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>


/* define HOME to be dir for key and cert files... */
#define HOME "./"
/* Make these what you want for cert & key files */
#define CERTF  HOME "foo-cert.pem"
#define KEYF  HOME  "foo-cert.pem"


#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 listen_sd;
  int sd;
  struct sockaddr_in sa_serv;
  struct sockaddr_in sa_cli;
  size_t client_len;
  SSL_CTX* ctx;
  SSL*     ssl;
  X509*    client_cert;
  char*    str;
  char     buf [4096];
  SSL_METHOD *meth;
  
  /* SSL preliminaries. We keep the certificate and key with the context. */

  SSL_load_error_strings();
  SSLeay_add_ssl_algorithms();
  meth = SSLv23_server_method();
  ctx = SSL_CTX_new (meth);
  if (!ctx) {
    ERR_print_errors_fp(stderr);
    exit(2);
  }
  
  if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0) {
    ERR_print_errors_fp(stderr);
    exit(3);
  }
  if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0) {
    ERR_print_errors_fp(stderr);
    exit(4);
  }

  if (!SSL_CTX_check_private_key(ctx)) {
    fprintf(stderr,"Private key does not match the certificate public key\n");
    exit(5);
  }

  /* ----------------------------------------------- */
  /* Prepare TCP socket for receiving connections */

  listen_sd = socket (AF_INET, SOCK_STREAM, 0);   CHK_ERR(listen_sd, "socket");
  
  memset (&sa_serv, '\0', sizeof(sa_serv));
  sa_serv.sin_family      = AF_INET;
  sa_serv.sin_addr.s_addr = INADDR_ANY;
  sa_serv.sin_port        = htons (1111);          /* Server Port number */
  
  err = bind(listen_sd, (struct sockaddr*) &sa_serv,
	     sizeof (sa_serv));                   CHK_ERR(err, "bind");
	     
  /* Receive a TCP connection. */
	     
  err = listen (listen_sd, 5);                    CHK_ERR(err, "listen");
  
  client_len = sizeof(sa_cli);
  sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len);
  CHK_ERR(sd, "accept");
  close (listen_sd);

  printf ("Connection from %lx, port %x\n",
	  sa_cli.sin_addr.s_addr, sa_cli.sin_port);
  
  /* ----------------------------------------------- */
  /* TCP connection is ready. Do server side SSL. */

  ssl = SSL_new (ctx);                           CHK_NULL(ssl);
  SSL_set_fd (ssl, sd);
  err = SSL_accept (ssl);                        CHK_SSL(err);
  
  /* Get the cipher - opt */
  
  printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
  
  /* Get client's certificate (note: beware of dynamic allocation) - opt */

  client_cert = SSL_get_peer_certificate (ssl);
  if (client_cert != NULL) {
    printf ("Client certificate:\n");
    
    str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
    CHK_NULL(str);
    printf ("\t subject: %s\n", str);
    OPENSSL_free (str);
    
    str = X509_NAME_oneline (X509_get_issuer_name  (client_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 (client_cert);
  } else
    printf ("Client does not have certificate.\n");

  /* DATA EXCHANGE - Receive message and send reply. */

  err = SSL_read (ssl, buf, sizeof(buf) - 1);                   CHK_SSL(err);
  buf[err] = '\0';
  printf ("Got %d chars:'%s'\n", err, buf);
  
  err = SSL_write (ssl, "I hear you.", strlen("I hear you."));  CHK_SSL(err);

  /* Clean up. */

  close (sd);
  SSL_free (ssl);
  SSL_CTX_free (ctx);
}
/* EOF - serv.cpp */
n class="p">(option = "server-port", section = "pubd") r["myrpki", "publication_base_directory"] = cfg.get(option = "publication-base", section = "pubd") if cfg.has_section("rootd"): r["myrpki", "rootd_server_port"] = cfg.get(option = "server-port", section = "rootd") u = urlparse.urlparse(cfg.get(option = "rpki-base-uri", section = "rootd")) r["myrpki", "publication_rsync_server"] = u.netloc for i in ("rpkid", "irdbd", "pubd"): if cfg.has_section(i): for j in ("sql-database", "sql-username", "sql-password"): r[i, j] = cfg.get(section = i, option = j) f = open(new_cfg_file, "w") f.write("# Automatically converted from %s using %s as a template.\n\n" % (cfg_file, template_file)) section = None for line in open(template_file): m = section_regexp.match(line) if m: section = m.group(1) m = variable_regexp.match(line) if m: option, whitespace = m.group(1, 2) else: option = None if (section, option) in r: line = "%s%s%s\n" % (option, whitespace, r[section, option]) f.write(line) f.close() print "Wrote", new_cfg_file # Get all of these from the new config file; in theory we just set all # of them, but we want to use values matching new config in any case. newcfg = rpki.config.parser(new_cfg_file, "myrpki") handle = newcfg.get("handle") bpki_resources_directory = newcfg.get("bpki_resources_directory") bpki_servers_directory = newcfg.get("bpki_servers_directory") pubd_server_host = newcfg.get("pubd_server_host") pubd_server_port = newcfg.get("pubd_server_port") rpkid_server_host = newcfg.get("rpkid_server_host") rpkid_server_port = newcfg.get("rpkid_server_port") entitydb_dir = newcfg.get("entitydb_dir", "entitydb") bpki_resources_pemfile = bpki_resources_directory + "/ca.cer" bpki_servers_pemfile = bpki_servers_directory + "/ca.cer" def entitydb(*args): return os.path.join(entitydb_dir, *args) # Now convert the .csv files. It'd be nice to have XML validation # enabled for this, so try to turn it on ourselves if the magic # environment variable hasn't already been set. rng_file = os.path.join(os.path.dirname(sys.argv[0]), "myrpki.rng") if not os.getenv("MYRPKI_RNG") and os.path.exists(rng_file): os.putenv("MYRPKI_RNG", rng_file) for d in map(entitydb, ("children", "parents", "repositories", "pubclients")): if not os.path.exists(d): os.makedirs(d) one_year_from_now = str(rpki.sundial.now() + rpki.sundial.timedelta(days = 365)) if os.path.exists(children_csv): for child_handle, valid_until, child_resource_pemfile in rpki.myrpki.csv_reader(children_csv, columns = 3): try: e = Element("parent", valid_until = valid_until if preserve_valid_until else one_year_from_now, service_uri = "https://%s:%s/up-down/%s/%s" % (rpkid_server_host, rpkid_server_port, handle, child_handle), child_handle = child_handle, parent_handle = handle) rpki.myrpki.PEMElement(e, "bpki_resource_ta", bpki_resources_pemfile) rpki.myrpki.PEMElement(e, "bpki_server_ta", bpki_servers_pemfile) rpki.myrpki.PEMElement(e, "bpki_child_ta", child_resource_pemfile) rpki.myrpki.etree_write(e, entitydb("children", "%s.xml" % child_handle)) except IOError: pass if os.path.exists(parents_csv): for parent_handle, parent_service_uri, parent_cms_pemfile, parent_https_pemfile, parent_myhandle, parent_sia_base in rpki.myrpki.csv_reader(parents_csv, columns = 6): try: e = Element("parent", valid_until = one_year_from_now, service_uri = parent_service_uri, child_handle = parent_myhandle, parent_handle = parent_handle) rpki.myrpki.PEMElement(e, "bpki_resource_ta", parent_cms_pemfile) rpki.myrpki.PEMElement(e, "bpki_server_ta", parent_https_pemfile) rpki.myrpki.PEMElement(e, "bpki_child_ta", bpki_resources_pemfile) rpki.myrpki.etree_write(e, entitydb("parents", "%s.xml" % parent_handle)) client_handle = "/".join(parent_sia_base.rstrip("/").split("/")[3:]) assert client_handle.startswith(repository_handle) e = Element("repository", parent_handle = parent_handle, client_handle = client_handle, service_uri = "%s/client/%s" % (pubd_base.rstrip("/"), client_handle), sia_base = parent_sia_base, type = "confirmed") rpki.myrpki.PEMElement(e, "bpki_server_ta", repository_bpki_certificate) rpki.myrpki.PEMElement(e, "bpki_client_ta", bpki_resources_pemfile) SubElement(e, "contact_info").text = "Automatically generated by convert-csv.py" rpki.myrpki.etree_write(e, entitydb("repositories", "%s.xml" % parent_handle)) except IOError: pass if os.path.exists(pubclients_csv): for client_handle, client_resource_pemfile, client_sia_base in rpki.myrpki.csv_reader(pubclients_csv, columns = 3): try: parent_handle = client_handle.split("/")[-2] if "/" in client_handle else handle e = Element("repository", parent_handle = parent_handle, client_handle = client_handle, service_uri = "https://%s:%s/client/%s" % (pubd_server_host, pubd_server_port, client_handle), sia_base = client_sia_base, type = "confirmed") rpki.myrpki.PEMElement(e, "bpki_server_ta", bpki_servers_pemfile) rpki.myrpki.PEMElement(e, "bpki_client_ta", client_resource_pemfile) SubElement(e, "contact_info").text = "Automatically generated by convert-csv.py" rpki.myrpki.etree_write(e, entitydb("pubclients", "%s.xml" % client_handle.replace("/", "."))) except IOError: pass