jabberd2  2.2.17
ssl.c
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  * Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
26 #include "sx.h"
27 #include <openssl/x509_vfy.h>
28 
29 
30 /* code stolen from SSL_CTX_set_verify(3) */
31 static int _sx_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
32 {
33  char buf[256];
34  X509 *err_cert;
35  int err, depth;
36  SSL *ssl;
37 
38  err_cert = X509_STORE_CTX_get_current_cert(ctx);
39  err = X509_STORE_CTX_get_error(ctx);
40  depth = X509_STORE_CTX_get_error_depth(ctx);
41 
42  /*
43  * Ignore errors when we can't get CRLs in the certificate
44  */
45  if (!preverify_ok && err == X509_V_ERR_UNABLE_TO_GET_CRL) {
46  _sx_debug(ZONE, "ignoring verify error:num=%d:%s:depth=%d:%s\n", err,
47  X509_verify_cert_error_string(err), depth, buf);
48  preverify_ok = 1;
49  }
50 
51  /*
52  * Retrieve the pointer to the SSL of the connection currently treated
53  * and the application specific data stored into the SSL object.
54  */
55  ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
56  X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
57 
58  if (!preverify_ok) {
59  _sx_debug(ZONE, "verify error:num=%d:%s:depth=%d:%s\n", err,
60  X509_verify_cert_error_string(err), depth, buf);
61  }
62  else
63  {
64  _sx_debug(ZONE, "OK! depth=%d:%s", depth, buf);
65  }
66 
67  /*
68  * At this point, err contains the last verification error. We can use
69  * it for something special
70  */
71  if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT))
72  {
73  X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
74  _sx_debug(ZONE, "issuer= %s\n", buf);
75  }
76 
77  return preverify_ok;
78  }
79 
80 static void _sx_ssl_starttls_notify_proceed(sx_t s, void *arg) {
81  char *to = NULL;
82  _sx_debug(ZONE, "preparing for starttls");
83 
84  /* store the destination so we can select an ssl context */
85  if(s->req_to != NULL) to = strdup(s->req_to);
86 
87  _sx_reset(s);
88 
89  /* restore destination */
90  if(s->req_to == NULL)
91  s->req_to = to;
92  else /* ? */
93  free(to);
94 
95  /* start listening */
97 }
98 
99 static int _sx_ssl_process(sx_t s, sx_plugin_t p, nad_t nad) {
100  int flags;
101  char *ns = NULL, *to = NULL, *from = NULL, *version = NULL;
102  sx_error_t sxe;
103 
104  /* not interested if we're a server and we never offered it */
105  if(s->type == type_SERVER && !(s->flags & SX_SSL_STARTTLS_OFFER))
106  return 1;
107 
108  /* only want tls packets */
109  if(NAD_ENS(nad, 0) < 0 || NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_TLS) || strncmp(NAD_NURI(nad, NAD_ENS(nad, 0)), uri_TLS, strlen(uri_TLS)) != 0)
110  return 1;
111 
112  /* starttls from client */
113  if(s->type == type_SERVER) {
114  if(NAD_ENAME_L(nad, 0) == 8 && strncmp(NAD_ENAME(nad, 0), "starttls", 8) == 0) {
115  nad_free(nad);
116 
117  /* can't go on if we've been here before */
118  if(s->ssf > 0) {
119  _sx_debug(ZONE, "starttls requested on already encrypted channel, dropping packet");
120  return 0;
121  }
122 
123  /* can't go on if we're on compressed stream */
124  if(s->compressed > 0) {
125  _sx_debug(ZONE, "starttls requested on already compressed channel, dropping packet");
126  return 0;
127  }
128 
129  _sx_debug(ZONE, "starttls requested, setting up");
130 
131  /* go ahead */
132  jqueue_push(s->wbufq, _sx_buffer_new("<proceed xmlns='" uri_TLS "'/>", strlen(uri_TLS) + 19, _sx_ssl_starttls_notify_proceed, NULL), 0);
133  s->want_write = 1;
134 
135  /* handled the packet */
136  return 0;
137  }
138  }
139 
140  else if(s->type == type_CLIENT) {
141  /* kick off the handshake */
142  if(NAD_ENAME_L(nad, 0) == 7 && strncmp(NAD_ENAME(nad, 0), "proceed", 7) == 0) {
143  nad_free(nad);
144 
145  /* save interesting bits */
146  flags = s->flags;
147 
148  if(s->ns != NULL) ns = strdup(s->ns);
149 
150  if(s->req_to != NULL) to = strdup(s->req_to);
151  if(s->req_from != NULL) from = strdup(s->req_from);
152  if(s->req_version != NULL) version = strdup(s->req_version);
153 
154  /* reset state */
155  _sx_reset(s);
156 
157  _sx_debug(ZONE, "server ready for ssl, starting");
158 
159  /* second time round */
160  sx_client_init(s, flags | SX_SSL_WRAPPER, ns, to, from, version);
161 
162  /* free bits */
163  if(ns != NULL) free(ns);
164  if(to != NULL) free(to);
165  if(from != NULL) free(from);
166  if(version != NULL) free(version);
167 
168  return 0;
169  }
170 
171  /* busted server */
172  if(NAD_ENAME_L(nad, 0) == 7 && strncmp(NAD_ENAME(nad, 0), "failure", 7) == 0) {
173  nad_free(nad);
174 
175  /* free the pemfile arg */
176  if(s->plugin_data[p->index] != NULL) {
177  if( ((_sx_ssl_conn_t)s->plugin_data[p->index])->pemfile != NULL )
178  free(((_sx_ssl_conn_t)s->plugin_data[p->index])->pemfile);
179  free(s->plugin_data[p->index]);
180  s->plugin_data[p->index] = NULL;
181  }
182 
183  _sx_debug(ZONE, "server can't handle ssl, business as usual");
184 
185  _sx_gen_error(sxe, SX_ERR_STARTTLS_FAILURE, "STARTTLS failure", "Server was unable to prepare for the TLS handshake");
186  _sx_event(s, event_ERROR, (void *) &sxe);
187 
188  return 0;
189  }
190  }
191 
192  _sx_debug(ZONE, "unknown starttls namespace element '%.*s', dropping packet", NAD_ENAME_L(nad, 0), NAD_ENAME(nad, 0));
193  nad_free(nad);
194  return 0;
195 }
196 
197 static void _sx_ssl_features(sx_t s, sx_plugin_t p, nad_t nad) {
198  int ns;
199 
200  /* if the session is already encrypted, or the app told us not to,
201  * or session is compressed then we don't offer anything */
202  if(s->state > state_STREAM || s->ssf > 0 || !(s->flags & SX_SSL_STARTTLS_OFFER) || s->compressed)
203  return;
204 
205  _sx_debug(ZONE, "offering starttls");
206 
207  ns = nad_add_namespace(nad, uri_TLS, NULL);
208  nad_append_elem(nad, ns, "starttls", 1);
209 
211  nad_append_elem(nad, ns, "required", 2);
212 }
213 
214 /* Extract id-on-xmppAddr from the certificate */
215 static void _sx_ssl_get_external_id(sx_t s, _sx_ssl_conn_t sc) {
216  X509 *cert;
217  X509_NAME *name;
218  X509_NAME_ENTRY *entry;
219  // subjectAltName parsing
220  X509_EXTENSION *extension;
221  STACK_OF(GENERAL_NAME) *altnames;
222  GENERAL_NAME *altname;
223  OTHERNAME *othername;
224  char * buff;
225  // new object identifiers
226  int id_on_xmppAddr_nid;
227  ASN1_OBJECT *id_on_xmppAddr_obj;
228  // iterators
229  int i, j, count, id = 0, len;
230 
231  /* If there's not peer cert, quit */
232  if ((cert = SSL_get_peer_certificate(sc->ssl) ) == NULL)
233  return;
234  _sx_debug(ZONE, "external_id: Got peer certificate");
235 
236  /* Allocate new id-on-xmppAddr object. See rfc3921bis 15.2.1.2 */
237  id_on_xmppAddr_nid = OBJ_create("1.3.6.1.5.5.7.8.5", "id-on-xmppAddr", "XMPP Address Identity");
238  id_on_xmppAddr_obj = OBJ_nid2obj(id_on_xmppAddr_nid);
239  _sx_debug(ZONE, "external_id: Created id-on-xmppAddr SSL object");
240 
241  /* Iterate through all subjectAltName x509v3 extensions. Get id-on-xmppAddr and dDnsName */
242  for (i = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
243  i != -1;
244  i = X509_get_ext_by_NID(cert, NID_subject_alt_name, i)) {
245  // Get this subjectAltName x509v3 extension
246  if ((extension = X509_get_ext(cert, i)) == NULL) {
247  _sx_debug(ZONE, "external_id: Can't get subjectAltName. Possibly malformed cert.");
248  goto end;
249  }
250  // Get the collection of AltNames
251  if ((altnames = X509V3_EXT_d2i(extension)) == NULL) {
252  _sx_debug(ZONE, "external_id: Can't get all AltNames. Possibly malformed cert.");
253  goto end;
254  }
255  /* Iterate through all altNames and get id-on-xmppAddr and dNSName */
256  count = sk_GENERAL_NAME_num(altnames);
257  for (j = 0; j < count; j++) {
258  if ((altname = sk_GENERAL_NAME_value(altnames, j)) == NULL) {
259  _sx_debug(ZONE, "external_id: Can't get AltName. Possibly malformed cert.");
260  goto end;
261  }
262  /* Check if its otherName id-on-xmppAddr */
263  if (altname->type == GEN_OTHERNAME &&
264  OBJ_cmp(altname->d.otherName->type_id, id_on_xmppAddr_obj) == 0) {
265  othername = altname->d.otherName;
266  len = ASN1_STRING_to_UTF8((unsigned char **) &buff, othername->value->value.utf8string);
267  if (len <= 0)
268  continue;
269  sc->external_id[id] = (char *) malloc(sizeof(char) * (len + 1));
270  memcpy(sc->external_id[id], buff, len);
271  sc->external_id[id][len] = '\0'; // just to make sure
272  _sx_debug(ZONE, "external_id: Found(%d) subjectAltName/id-on-xmppAddr: '%s'", id, sc->external_id[id]);
273  id++;
274  OPENSSL_free(buff);
275  } else if (altname->type == GEN_DNS) {
276  len = ASN1_STRING_length(altname->d.dNSName);
277  sc->external_id[id] = (char *) malloc(sizeof(char) * (len + 1));
278  memcpy(sc->external_id[id], ASN1_STRING_data(altname->d.dNSName), len);
279  sc->external_id[id][len] = '\0'; // just to make sure
280  _sx_debug(ZONE, "external_id: Found(%d) subjectAltName/dNSName: '%s'", id, sc->external_id[id]);
281  id++;
282  }
283  /* Check if we're not out of space */
284  if (id == SX_CONN_EXTERNAL_ID_MAX_COUNT) {
285  sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free);
286  goto end;
287  }
288  }
289 
290  sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free);
291  }
292  /* Get CNs */
293  name = X509_get_subject_name(cert);
294  for (i = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
295  i != -1;
296  i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) {
297  // Get the commonName entry
298  if ((entry = X509_NAME_get_entry(name, i)) == NULL) {
299  _sx_debug(ZONE, "external_id: Can't get commonName(%d). Possibly malformed cert. Continuing.", i);
300  continue;
301  }
302  // Get the commonName as UTF8 string
303  len = ASN1_STRING_to_UTF8((unsigned char **) &buff, X509_NAME_ENTRY_get_data(entry));
304  if (len <= 0) {
305  continue;
306  }
307  sc->external_id[id] = (char *) malloc(sizeof(char) * (len + 1));
308  memcpy(sc->external_id[id], buff, len);
309  sc->external_id[id][len] = '\0'; // just to make sure
310  _sx_debug(ZONE, "external_id: Found(%d) commonName: '%s'", id, sc->external_id[id]);
311  OPENSSL_free(buff);
312  /* Check if we're not out of space */
314  goto end;
315  }
316 
317 end:
318  X509_free(cert);
319  return;
320 }
321 
322 static int _sx_ssl_handshake(sx_t s, _sx_ssl_conn_t sc) {
323  int ret, err;
324  char *errstring;
325  sx_error_t sxe;
326 
327  /* work on establishing the channel */
328  while(!SSL_is_init_finished(sc->ssl)) {
329  _sx_debug(ZONE, "secure channel not established, handshake in progress");
330 
331  /* we can't handshake if they want to read, but there's nothing to read */
332  if(sc->last_state == SX_SSL_STATE_WANT_READ && BIO_pending(sc->rbio) == 0)
333  return 0;
334 
335  /* more handshake */
336  if(s->type == type_CLIENT)
337  ret = SSL_connect(sc->ssl);
338  else
339  ret = SSL_accept(sc->ssl);
340 
341  /* check if we're done */
342  if(ret == 1) {
343  _sx_debug(ZONE, "secure channel established");
344  sc->last_state = SX_SSL_STATE_NONE;
345 
346  s->ssf = SSL_get_cipher_bits(sc->ssl, NULL);
347 
348  _sx_debug(ZONE, "using cipher %s (%d bits)", SSL_get_cipher_name(sc->ssl), s->ssf);
350 
351  return 1;
352  }
353 
354  /* error checking */
355  else if(ret <= 0) {
356  err = SSL_get_error(sc->ssl, ret);
357 
358  if(err == SSL_ERROR_WANT_READ)
359  sc->last_state = SX_SSL_STATE_WANT_READ;
360  else if(err == SSL_ERROR_WANT_WRITE)
361  sc->last_state = SX_SSL_STATE_WANT_WRITE;
362 
363  else {
364  /* fatal error */
365  sc->last_state = SX_SSL_STATE_ERROR;
366 
367  errstring = ERR_error_string(ERR_get_error(), NULL);
368  _sx_debug(ZONE, "openssl error: %s", errstring);
369 
370  /* do not throw an error if in wrapper mode and pre-stream */
371  if(!(s->state < state_STREAM && s->flags & SX_SSL_WRAPPER)) {
372  _sx_gen_error(sxe, SX_ERR_SSL, "SSL handshake error", errstring);
373  _sx_event(s, event_ERROR, (void *) &sxe);
375  }
376 
377  sx_close(s);
378 
379  /* !!! drop queue */
380 
381  return -1;
382  }
383  }
384  }
385 
386  return 1;
387 }
388 
389 static int _sx_ssl_wio(sx_t s, sx_plugin_t p, sx_buf_t buf) {
390  _sx_ssl_conn_t sc = (_sx_ssl_conn_t) s->plugin_data[p->index];
391  int est, ret, err;
392  sx_buf_t wbuf;
393  char *errstring;
394  sx_error_t sxe;
395 
396  /* do not encrypt when error */
397  if(sc->last_state == SX_SSL_STATE_ERROR)
398  return 1;
399 
400  _sx_debug(ZONE, "in _sx_ssl_wio");
401 
402  /* queue the buffer */
403  if(buf->len > 0) {
404  _sx_debug(ZONE, "queueing buffer for write");
405 
406  jqueue_push(sc->wq, _sx_buffer_new(buf->data, buf->len, buf->notify, buf->notify_arg), 0);
407  _sx_buffer_clear(buf);
408  buf->notify = NULL;
409  buf->notify_arg = NULL;
410  }
411 
412  /* handshake */
413  est = _sx_ssl_handshake(s, sc);
414  if(est < 0)
415  return -2; /* fatal error */
416 
417  /* channel established, do some real writing */
418  wbuf = NULL;
419  if(est > 0 && jqueue_size(sc->wq) > 0) {
420  _sx_debug(ZONE, "preparing queued buffer for write");
421 
422  wbuf = jqueue_pull(sc->wq);
423 
424  ret = SSL_write(sc->ssl, wbuf->data, wbuf->len);
425  if(ret <= 0) {
426  /* something's wrong */
427  _sx_debug(ZONE, "write failed, requeuing buffer");
428 
429  /* requeue the buffer */
430  jqueue_push(sc->wq, wbuf, (sc->wq->front != NULL) ? sc->wq->front->priority + 1 : 0);
431 
432  /* error checking */
433  err = SSL_get_error(sc->ssl, ret);
434 
435  if(err == SSL_ERROR_ZERO_RETURN) {
436  /* ssl channel closed, we're done */
437  _sx_close(s);
438  }
439 
440  if(err == SSL_ERROR_WANT_READ) {
441  /* we'll be renegotiating next time */
442  _sx_debug(ZONE, "renegotiation started");
443  sc->last_state = SX_SSL_STATE_WANT_READ;
444  }
445 
446  else {
447  sc->last_state = SX_SSL_STATE_ERROR;
448 
449  /* something very bad */
450  errstring = ERR_error_string(ERR_get_error(), NULL);
451  _sx_debug(ZONE, "openssl error: %s", errstring);
452 
453  /* do not throw an error if in wrapper mode and pre-stream */
454  if(!(s->state < state_STREAM && s->flags & SX_SSL_WRAPPER)) {
455  _sx_gen_error(sxe, SX_ERR_SSL, "SSL handshake error", errstring);
456  _sx_event(s, event_ERROR, (void *) &sxe);
458  }
459 
460  sx_close(s);
461 
462  /* !!! drop queue */
463 
464  return -2; /* fatal */
465  }
466  }
467  }
468 
469  /* prepare the buffer with stuff to write */
470  if(BIO_pending(sc->wbio) > 0) {
471  int bytes_pending = BIO_pending(sc->wbio);
472  assert(buf->len == 0);
473  _sx_buffer_alloc_margin(buf, 0, bytes_pending);
474  BIO_read(sc->wbio, buf->data, bytes_pending);
475  buf->len += bytes_pending;
476 
477  /* restore notify and clean up */
478  if(wbuf != NULL) {
479  buf->notify = wbuf->notify;
480  buf->notify_arg = wbuf->notify_arg;
481  _sx_buffer_free(wbuf);
482  }
483 
484  _sx_debug(ZONE, "prepared %d ssl bytes for write", buf->len);
485  }
486 
487  /* flag if we want to read */
488  if(sc->last_state == SX_SSL_STATE_WANT_READ || sc->last_state == SX_SSL_STATE_NONE)
489  s->want_read = 1;
490 
491  return 1;
492 }
493 
494 static int _sx_ssl_rio(sx_t s, sx_plugin_t p, sx_buf_t buf) {
495  _sx_ssl_conn_t sc = (_sx_ssl_conn_t) s->plugin_data[p->index];
496  int est, ret, err, pending;
497  char *errstring;
498  sx_error_t sxe;
499 
500  /* sanity */
501  if(sc->last_state == SX_SSL_STATE_ERROR)
502  return -1;
503 
504  _sx_debug(ZONE, "in _sx_ssl_rio");
505 
506  /* move the data into the ssl read buffer */
507  if(buf->len > 0) {
508  _sx_debug(ZONE, "loading %d bytes into ssl read buffer", buf->len);
509 
510  BIO_write(sc->rbio, buf->data, buf->len);
511 
512  _sx_buffer_clear(buf);
513  }
514 
515  /* handshake */
516  est = _sx_ssl_handshake(s, sc);
517  if(est < 0)
518  return -1; /* fatal error */
519 
520  /* channel is up, slurp up the read buffer */
521  if(est > 0) {
522 
523  pending = SSL_pending(sc->ssl);
524  if(pending == 0)
525  pending = BIO_pending(sc->rbio);
526 
527  /* get it all */
528  while((pending = SSL_pending(sc->ssl)) > 0 || (pending = BIO_pending(sc->rbio)) > 0) {
529  _sx_buffer_alloc_margin(buf, 0, pending);
530 
531  ret = SSL_read(sc->ssl, &(buf->data[buf->len]), pending);
532 
533  if (ret == 0)
534  {
535  /* ret will equal zero if the SSL stream was closed.
536  (See the SSL_read manpage.) */
537 
538  /* If the SSL Shutdown happened properly,
539  (i.e. we got an SSL "close notify")
540  then proccess the last packet recieved. */
541  if (SSL_get_shutdown(sc->ssl) == SSL_RECEIVED_SHUTDOWN)
542  {
543  _sx_close(s);
544  break;
545  }
546 
547  /* If the SSL stream was just closed and not shutdown,
548  drop the last packet recieved.
549  WARNING: This may cause clients that use SSLv2 and
550  earlier to not log out properly. */
551 
552  err = SSL_get_error(sc->ssl, ret);
553 
554  _sx_buffer_clear(buf);
555 
556 
557  if(err == SSL_ERROR_ZERO_RETURN) {
558  /* ssl channel closed, we're done */
559  _sx_close(s);
560  }
561 
562  return -1;
563  }
564  else if(ret < 0) {
565  /* ret will be negative if the SSL stream needs
566  more data, or if there was a SSL error.
567  (See the SSL_read manpage.) */
568  err = SSL_get_error(sc->ssl, ret);
569 
570  /* ssl block incomplete, need more */
571  if(err == SSL_ERROR_WANT_READ) {
572  sc->last_state = SX_SSL_STATE_WANT_READ;
573 
574  break;
575  }
576 
577  /* something's wrong */
578  _sx_buffer_clear(buf);
579 
580 
581  /* !!! need checks for renegotiation */
582 
583  sc->last_state = SX_SSL_STATE_ERROR;
584 
585  errstring = ERR_error_string(ERR_get_error(), NULL);
586  _sx_debug(ZONE, "openssl error: %s", errstring);
587 
588  /* do not throw an error if in wrapper mode and pre-stream */
589  if(!(s->state < state_STREAM && s->flags & SX_SSL_WRAPPER)) {
590  _sx_gen_error(sxe, SX_ERR_SSL, "SSL handshake error", errstring);
591  _sx_event(s, event_ERROR, (void *) &sxe);
593  }
594 
595  sx_close(s);
596 
597  /* !!! drop queue */
598 
599  return -1;
600  }
601 
602  buf->len += ret;
603  }
604  }
605 
606  /* flag if stuff to write */
607  if(BIO_pending(sc->wbio) > 0 || (est > 0 && jqueue_size(sc->wq) > 0))
608  s->want_write = 1;
609 
610  /* flag if we want to read */
611  if(sc->last_state == SX_SSL_STATE_WANT_READ || sc->last_state == SX_SSL_STATE_NONE)
612  s->want_read = 1;
613 
614  if(buf->len == 0)
615  return 0;
616 
617  return 1;
618 }
619 
620 static void _sx_ssl_client(sx_t s, sx_plugin_t p) {
621  _sx_ssl_conn_t sc;
622  SSL_CTX *ctx;
623  char *pemfile = NULL;
624  int ret, i;
625 
626  /* only bothering if they asked for wrappermode */
627  if(!(s->flags & SX_SSL_WRAPPER) || s->ssf > 0)
628  return;
629 
630  _sx_debug(ZONE, "preparing for ssl connect for %d from %s", s->tag, s->req_from);
631 
632  /* find the ssl context for this source */
633  ctx = xhash_get((xht) p->private, s->req_from);
634  if(ctx == NULL) {
635  _sx_debug(ZONE, "using default ssl context for %d", s->tag);
636  ctx = xhash_get((xht) p->private, "*");
637  } else {
638  _sx_debug(ZONE, "using configured ssl context for %d", s->tag);
639  }
640  assert((int) (ctx != NULL));
641 
642  sc = (_sx_ssl_conn_t) calloc(1, sizeof(struct _sx_ssl_conn_st));
643 
644  /* create the buffers */
645  sc->rbio = BIO_new(BIO_s_mem());
646  sc->wbio = BIO_new(BIO_s_mem());
647 
648  /* new ssl conn */
649  sc->ssl = SSL_new(ctx);
650  SSL_set_bio(sc->ssl, sc->rbio, sc->wbio);
651  SSL_set_connect_state(sc->ssl);
652  SSL_set_ssl_method(sc->ssl, TLSv1_client_method());
653  SSL_set_options(sc->ssl, SSL_OP_NO_TICKET);
654 
655  /* empty external_id */
656  for (i = 0; i < SX_CONN_EXTERNAL_ID_MAX_COUNT; i++)
657  sc->external_id[i] = NULL;
658 
659  /* alternate pemfile */
660  /* !!! figure out how to error correctly here - just returning will cause
661  * us to send a normal unencrypted stream start while the server is
662  * waiting for ClientHelo. the server will flag an error, but it won't
663  * help the admin at all to figure out what happened */
664  if(s->plugin_data[p->index] != NULL) {
665  pemfile = ((_sx_ssl_conn_t)s->plugin_data[p->index])->pemfile;
666  free(s->plugin_data[p->index]);
667  s->plugin_data[p->index] = NULL;
668  }
669  if(pemfile != NULL) {
670  /* load the certificate */
671  ret = SSL_use_certificate_file(sc->ssl, pemfile, SSL_FILETYPE_PEM);
672  if(ret != 1) {
673  _sx_debug(ZONE, "couldn't load alternate certificate from %s", pemfile);
674  SSL_free(sc->ssl);
675  free(sc);
676  free(pemfile);
677  return;
678  }
679 
680  /* load the private key */
681  ret = SSL_use_PrivateKey_file(sc->ssl, pemfile, SSL_FILETYPE_PEM);
682  if(ret != 1) {
683  _sx_debug(ZONE, "couldn't load alternate private key from %s", pemfile);
684  SSL_free(sc->ssl);
685  free(sc);
686  free(pemfile);
687  return;
688  }
689 
690  /* check the private key matches the certificate */
691  ret = SSL_check_private_key(sc->ssl);
692  if(ret != 1) {
693  _sx_debug(ZONE, "private key does not match certificate public key");
694  SSL_free(sc->ssl);
695  free(sc);
696  free(pemfile);
697  return;
698  }
699 
700  _sx_debug(ZONE, "loaded alternate pemfile %s", pemfile);
701 
702  free(pemfile);
703  }
704 
705  /* buffer queue */
706  sc->wq = jqueue_new();
707 
708  s->plugin_data[p->index] = (void *) sc;
709 
710  /* bring the plugin online */
711  _sx_chain_io_plugin(s, p);
712 }
713 
714 static void _sx_ssl_server(sx_t s, sx_plugin_t p) {
715  _sx_ssl_conn_t sc;
716  SSL_CTX *ctx;
717  int i;
718 
719  /* only bothering if they asked for wrappermode */
720  if(!(s->flags & SX_SSL_WRAPPER) || s->ssf > 0)
721  return;
722 
723  _sx_debug(ZONE, "preparing for ssl accept for %d to %s", s->tag, s->req_to);
724 
725  /* find the ssl context for this destination */
726  ctx = xhash_get((xht) p->private, s->req_to);
727  if(ctx == NULL) {
728  _sx_debug(ZONE, "using default ssl context for %d", s->tag);
729  ctx = xhash_get((xht) p->private, "*");
730  } else {
731  _sx_debug(ZONE, "using configured ssl context for %d", s->tag);
732  }
733  assert((int) (ctx != NULL));
734 
735  sc = (_sx_ssl_conn_t) calloc(1, sizeof(struct _sx_ssl_conn_st));
736 
737  /* create the buffers */
738  sc->rbio = BIO_new(BIO_s_mem());
739  sc->wbio = BIO_new(BIO_s_mem());
740 
741  /* new ssl conn */
742  sc->ssl = SSL_new(ctx);
743  SSL_set_bio(sc->ssl, sc->rbio, sc->wbio);
744  SSL_set_accept_state(sc->ssl);
745 
746  /* empty external_id */
747  for (i = 0; i < SX_CONN_EXTERNAL_ID_MAX_COUNT; i++)
748  sc->external_id[i] = NULL;
749 
750  /* buffer queue */
751  sc->wq = jqueue_new();
752 
753  s->plugin_data[p->index] = (void *) sc;
754 
755  /* bring the plugin online */
756  _sx_chain_io_plugin(s, p);
757 }
758 
760 static void _sx_ssl_free(sx_t s, sx_plugin_t p) {
761  _sx_ssl_conn_t sc = (_sx_ssl_conn_t) s->plugin_data[p->index];
762  sx_buf_t buf;
763  int i;
764 
765  if(sc == NULL)
766  return;
767 
768  log_debug(ZONE, "cleaning up conn state");
769 
770  if(s->type == type_NONE) {
771  free(sc);
772  return;
773  }
774 
775  for (i = 0; i < SX_CONN_EXTERNAL_ID_MAX_COUNT; i++)
776  if(sc->external_id[i] != NULL)
777  free(sc->external_id[i]);
778  else
779  break;
780 
781  if(sc->pemfile != NULL) free(sc->pemfile);
782 
783  if(sc->ssl != NULL) SSL_free(sc->ssl); /* frees wbio and rbio too */
784 
785  if(sc->wq != NULL) {
786  while((buf = jqueue_pull(sc->wq)) != NULL)
787  _sx_buffer_free(buf);
788 
789  jqueue_free(sc->wq);
790  }
791 
792  free(sc);
793 
794  s->plugin_data[p->index] = NULL;
795 }
796 
797 static void _sx_ssl_unload(sx_plugin_t p) {
798  xht contexts = (xht) p->private;
799  void *ctx;
800 
801  if(xhash_iter_first(contexts))
802  do {
803  xhash_iter_get(contexts, NULL, NULL, &ctx);
804  SSL_CTX_free((SSL_CTX *) ctx);
805  } while(xhash_iter_next(contexts));
806 
807  xhash_free(contexts);
808 }
809 
811 
813 int sx_ssl_init(sx_env_t env, sx_plugin_t p, va_list args) {
814  char *name, *pemfile, *cachain;
815  int ret;
816  int mode;
817 
818  _sx_debug(ZONE, "initialising ssl plugin");
819 
820  name = va_arg(args, char *);
821  pemfile = va_arg(args, char *);
822  if(pemfile == NULL)
823  return 1;
824 
825  if(p->private != NULL)
826  return 1;
827 
828  cachain = va_arg(args, char *);
829  mode = va_arg(args, int);
830 
831  /* !!! output openssl error messages to the debug log */
832 
833  /* openssl startup */
835  SSL_library_init();
836  SSL_load_error_strings();
837  }
839 
840  ret = sx_ssl_server_addcert(p, name, pemfile, cachain, mode);
841  if(ret)
842  return 1;
843 
844  p->magic = SX_SSL_MAGIC;
845 
846  p->unload = _sx_ssl_unload;
847 
848  p->client = _sx_ssl_client;
849  p->server = _sx_ssl_server;
850  p->rio = _sx_ssl_rio;
851  p->wio = _sx_ssl_wio;
854  p->free = _sx_ssl_free;
855 
856  return 0;
857 }
858 
860 int sx_ssl_server_addcert(sx_plugin_t p, char *name, char *pemfile, char *cachain, int mode) {
861  xht contexts = (xht) p->private;
862  SSL_CTX *ctx;
863  SSL_CTX *tmp;
864  STACK_OF(X509_NAME) *cert_names;
865  X509_STORE * store;
866  int ret;
867 
869  _sx_debug(ZONE, "ssl plugin not initialised");
870  return 1;
871  }
872 
873  if(name == NULL)
874  name = "*";
875 
876  if(pemfile == NULL)
877  return 1;
878 
879  /* begin with fresh error stack */
880  ERR_clear_error();
881 
882  /* create the context */
883  ctx = SSL_CTX_new(SSLv23_method());
884  if(ctx == NULL) {
885  _sx_debug(ZONE, "ssl context creation failed; %s", ERR_error_string(ERR_get_error(), NULL));
886  return 1;
887  }
888 
889  // Set allowed ciphers
890  if (SSL_CTX_set_cipher_list(ctx, "ALL:!LOW:!SSLv2:!EXP:!aNULL") != 1) {
891  _sx_debug(ZONE, "Can't set cipher list for SSL context: %s", ERR_error_string(ERR_get_error(), NULL));
892  SSL_CTX_free(ctx);
893  return 1;
894  }
895 
896  /* Load the CA chain, if configured */
897  if (cachain != NULL) {
898  ret = SSL_CTX_load_verify_locations (ctx, cachain, NULL);
899  if(ret != 1) {
900  _sx_debug(ZONE, "WARNING: couldn't load CA chain: %s; %s", cachain, ERR_error_string(ERR_get_error(), NULL));
901  } else {
902  _sx_debug(ZONE, "Loaded CA verify location chain: %s", cachain);
903  }
904  cert_names = SSL_load_client_CA_file(cachain);
905  if (cert_names != NULL) {
906  SSL_CTX_set_client_CA_list(ctx, cert_names);
907  _sx_debug(ZONE, "Loaded client CA chain: %s", cachain);
908  } else {
909  _sx_debug(ZONE, "WARNING: couldn't load client CA chain: %s", cachain);
910  }
911  } else {
912  /* Load the default OpenlSSL certs from /etc/ssl/certs
913  We must assume that the client certificate's CA is there
914 
915  Note: We don't send client_CA_list here. Will possibly break some clients.
916  */
917  SSL_CTX_set_default_verify_paths(ctx);
918  _sx_debug(ZONE, "No CA chain specified. Loading SSL default CA certs: /etc/ssl/certs");
919  }
920  /* Add server CRL verificaition */
921  store = SSL_CTX_get_cert_store(ctx);
922  // Not sure if this should be X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL
923  // or only X509_V_FLAG_CRL_CHECK
924  X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK);
925 
926  /* load the certificate */
927  ret = SSL_CTX_use_certificate_chain_file(ctx, pemfile);
928  if(ret != 1) {
929  _sx_debug(ZONE, "couldn't load certificate from %s; %s", pemfile, ERR_error_string(ERR_get_error(), NULL));
930  SSL_CTX_free(ctx);
931  return 1;
932  }
933 
934  /* load the private key */
935  ret = SSL_CTX_use_PrivateKey_file(ctx, pemfile, SSL_FILETYPE_PEM);
936  if(ret != 1) {
937  _sx_debug(ZONE, "couldn't load private key from %s; %s", pemfile, ERR_error_string(ERR_get_error(), NULL));
938  SSL_CTX_free(ctx);
939  return 1;
940  }
941 
942  /* check the private key matches the certificate */
943  ret = SSL_CTX_check_private_key(ctx);
944  if(ret != 1) {
945  _sx_debug(ZONE, "private key does not match certificate public key; %s", ERR_error_string(ERR_get_error(), NULL));
946  SSL_CTX_free(ctx);
947  return 1;
948  }
949 
950  _sx_debug(ZONE, "setting ssl context '%s' verify mode to %02x", name, mode);
951  SSL_CTX_set_verify(ctx, mode, _sx_ssl_verify_callback);
952 
953  /* create hash and create default context */
954  if(contexts == NULL) {
955  contexts = xhash_new(1021);
956  p->private = (void *) contexts;
957 
958  /* this is the first context, if it's not the default then make a copy of it as the default */
959  if(!(name[0] == '*' && name[1] == 0)) {
960  int ret = sx_ssl_server_addcert(p, "*", pemfile, cachain, mode);
961 
962  if(ret) {
963  /* uh-oh */
964  xhash_free(contexts);
965  p->private = NULL;
966  return 1;
967  }
968  }
969  }
970 
971  _sx_debug(ZONE, "ssl context '%s' initialised; certificate and key loaded from %s", name, pemfile);
972 
973  /* remove an existing context with the same name before replacing it */
974  tmp = xhash_get(contexts, name);
975  if(tmp != NULL)
976  SSL_CTX_free((SSL_CTX *) tmp);
977 
978  xhash_put(contexts, name, ctx);
979 
980  return 0;
981 }
982 
983 int sx_ssl_client_starttls(sx_plugin_t p, sx_t s, char *pemfile) {
984  assert((int) (p != NULL));
985  assert((int) (s != NULL));
986 
987  /* sanity */
988  if(s->type != type_CLIENT || s->state != state_STREAM) {
989  _sx_debug(ZONE, "wrong conn type or state for client starttls");
990  return 1;
991  }
992 
993  /* check if we're already encrypted or compressed */
994  if(s->ssf > 0 || s->compressed) {
995  _sx_debug(ZONE, "encrypted channel already established");
996  return 1;
997  }
998 
999  _sx_debug(ZONE, "initiating starttls sequence");
1000 
1001  /* save the given pemfile for later */
1002  if(pemfile != NULL) {
1003  s->plugin_data[p->index] = (_sx_ssl_conn_t) calloc(1, sizeof(struct _sx_ssl_conn_st));
1004  ((_sx_ssl_conn_t)s->plugin_data[p->index])->pemfile = strdup(pemfile);
1005  }
1006 
1007  /* go */
1008  jqueue_push(s->wbufq, _sx_buffer_new("<starttls xmlns='" uri_TLS "'/>", strlen(uri_TLS) + 20, NULL, NULL), 0);
1009  s->want_write = 1;
1010  _sx_event(s, event_WANT_WRITE, NULL);
1011 
1012  return 0;
1013 }