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