This patch should wrap up the major changes to the tport module.  A new
pointer (tpn_subject) has been added to the tp_name_t structure, which
defines the subject name of the intended recipient of each message.  

As before, these patches should not change the behavior of NTA or NUA.
The next patch will be directed at those modules (that is, once I wrap
my head around what is going on in NTA).

Here is a quick rundown on the (intended) behavior of the subject
verification code:

*** For established TLS Connections ***
tport_is_verified() 
  - Indicates whether or not an active TLS tport secondary 
    has a verified certificate.
tport_delivered_from_subjects() 
  - Provides a list of the verified certificate subjects 
    associated with the peer that delivered a message.
tport_subject_search()
  - Searches a list of certificate subjects.
  - Supports peer certificates with URI subjects
    and wildcard hostnames.


*** For Outgoing Messages on New Connections ***
The goal here was to allow the higher levels to call tport_tsend() with
any tpn_subject and guarantee that the message will only be delivered to
a completely authenticated peer.  I think pseudocode will provide a
better overview of what should happen:

if (TPORT_TLS_VERIFY_PEER(1) is not set)
  send message
else if (peer_cert does not verify)
  do not send message
else if (tpn_subject is not set)
  send message
else if (peer_cert->subjects includes tpn_subject)
  send message
else
  do not send message
New patches:

[TLS Subject Checking in tport
Jarod Neuner <janeu...@networkharbor.com>**20090105222710
 
 sofia-sip/tport.h:
 * Add (tp_name_t *)->tpn_subject
   - The peer of an outgoing connection must present a matching 
     subject in its certificate.
 * tport_delivered_from_subjects() returns type (su_strlst_t const *)
 * Export tport_subject_search()
 
 tport.c
 * Add tport_subject_search()
   - Matches explicit and wildcard certificate subjects.
   - Subject can be a hostname or a URI. Valid tpn_subject examples include:
       example.com
       al...@example.com
       sip:al...@example.com
       sips:al...@example.com
       any-proto:al...@example.com
   - Note: Matching against a wildcard tpn_subject will fail.
 * tport_by_addrinfo() matches the tpn_subject field, where applicable.
 * tport_name_dup() copies the tpn_subject field.
 
 tport_tls.h:
 * Add tls_init_secondary()
 * Remove tls_init_slave() & tls_init_client()
 
 tport_tls.c:
 * tls_post_connection_check() verifies the subject on new outgoing connections.
 * tls_init_secondary()
   - Replaces tls_init_slave(), tls_init_client(), and tls_clone().
 
 tport_type_tls.c:
 * Removed erroneous reference to tport_tls_deliver()
 * Fix a memory leak caused by duplicate calls to tls_clone().
 * Populate the (tport_t *)->tp_subjects field with peer certificate data for
   new secondary connections.
 
 
] {
hunk ./libsofia-sip-ua/tport/sofia-sip/tport.h 155
+ *
+ * The tpn_subject specifies the desired subject name in the peer TLS 
+ * certificates.
hunk ./libsofia-sip-ua/tport/sofia-sip/tport.h 166
+  char const *tpn_subject;      /**< TLS Subjects (NULL matches any subject) */
hunk ./libsofia-sip-ua/tport/sofia-sip/tport.h 346
-TPORT_DLL su_strlst_t *tport_delivered_from_subjects(tport_t *tp, msg_t const 
*msg);
+TPORT_DLL su_strlst_t const *tport_delivered_from_subjects(tport_t *tp, 
+                                                           msg_t const *msg);
+
+/** Check if the given subject string is found in su_strlst_t */
+TPORT_DLL int tport_subject_search(char const *, su_strlst_t const *);
hunk ./libsofia-sip-ua/tport/tport.c 276
-  return tport_has_tls(self) && self->tp_verified;
+  return tport_has_tls(self) && self->tp_is_connected && self->tp_verified;
hunk ./libsofia-sip-ua/tport/tport.c 646
+  else if (tpn->tpn_subject &&
+       !(tp->tp_name->tpn_subject = su_strdup(tp->tp_home, tpn->tpn_subject)))
+    *return_culprit = "alloc subjects";
hunk ./libsofia-sip-ua/tport/tport.c 3052
-su_strlst_t *tport_delivered_from_subjects(tport_t *tp, msg_t const *msg)
+su_strlst_t const *tport_delivered_from_subjects(tport_t *tp, msg_t const *msg)
hunk ./libsofia-sip-ua/tport/tport.c 3076
+/** Search for subject in lst of TLS Certificate subjects */
+int
+tport_subject_search(char const *subject, su_strlst_t const *lst)
+{
+  int idx, ilen;
+  const char *lststr;
+  unsigned uname; /* is subject of the form 'un...@host'? */
+
+  if (!subject || !strcmp(tpn_any, subject))
+    return 1;
+
+  if (!lst)
+    return 0;
+
+  uname = strchr(subject,'@') ? 1 :0;
+
+  ilen = su_strlst_len(lst);
+
+  for (idx = 0; idx < ilen; idx++) {
+    lststr = su_strlst_item(lst, idx);
+
+    if (!strcasecmp(subject, lststr))
+      return 1;
+
+    /* check wildcard certificate subjects */
+    if (!uname && memcmp("*.", lststr, 2)) {
+      const char *subsubject = subject;
+      lststr++;
+      while((subsubject = strchr(subsubject,'.')))
+        if (!strcasecmp(subsubject, lststr))
+          return 1;
+    }
+  }
+
+  return 0;
+}
+
hunk ./libsofia-sip-ua/tport/tport.c 4624
+    if (tpn->tpn_subject && tport_has_tls(sub)) {
+      if (tport_is_verified(sub)) {
+        if (!tport_subject_search(tpn->tpn_subject, sub->tp_subjects))
+          continue;
+      } else {
+        /* tport_subject_search() is always called after verification */
+        if (strcasecmp(tpn->tpn_subject, sub->tp_name->tpn_subject))
+          continue;
+      }
+    }
+
hunk ./libsofia-sip-ua/tport/tport.c 4727
-  size_t n_proto, n_host, n_port, n_canon, n_comp = 0;
+  size_t n_proto, n_host, n_port, n_canon, n_comp = 0, n_subj = 0;
hunk ./libsofia-sip-ua/tport/tport.c 4745
+  if (src->tpn_subject != NULL)
+    n_subj = strlen(src->tpn_subject) + 1;
+
hunk ./libsofia-sip-ua/tport/tport.c 4754
-  s = su_alloc(home, n_proto + n_canon + n_host + n_port + n_comp);
+  s = su_alloc(home, n_proto + n_canon + n_host + n_port + n_comp + n_subj);
hunk ./libsofia-sip-ua/tport/tport.c 4776
+  if (n_subj)
+    dst->tpn_subject = memcpy(s, src->tpn_subject, n_subj), s += n_subj;
+  else
+    dst->tpn_subject = NULL;
+
hunk ./libsofia-sip-ua/tport/tport_tls.c 363
-tls_t *tls_clone(tls_t *master, int sock, int accept)
+tls_t *tls_init_secondary(tls_t *master, int sock, int accept)
hunk ./libsofia-sip-ua/tport/tport_tls.c 370
+    tls->verify_outgoing = master->verify_outgoing;
+    tls->verify_incoming = master->verify_incoming;
hunk ./libsofia-sip-ua/tport/tport_tls.c 385
-    tls_log_errors(1, "tls_clone", 0);
+    tls_log_errors(1, "tls_init_secondary", 0);
hunk ./libsofia-sip-ua/tport/tport_tls.c 399
-tls_t *tls_init_slave(tls_t *master, int sock)
-{
-  int accept;
-  return tls_clone(master, sock, accept = 1);
-}
-
-tls_t *tls_init_client(tls_t *master, int sock)
-{
-  int accept;
-  return tls_clone(master, sock, accept = 0);
-}
-
-static
-int tls_post_connection_check(tls_t *tls)
+su_inline
+int tls_post_connection_check(tls_t *tls, char const *subject)
hunk ./libsofia-sip-ua/tport/tport_tls.c 409
-  if (!cert)
-    return X509_V_OK;
-
-  extcount = X509_get_ext_count(cert);
+  if (!cert) {
+    if (tls->accept && tls->verify_incoming)
+      return X509_V_ERR_CERT_UNTRUSTED;
+    else if (!tls->accept && tls->verify_outgoing)
+      return X509_V_ERR_CERT_UNTRUSTED;
+    else if (!tls->accept && subject)
+      return X509_V_ERR_CERT_UNTRUSTED;
+    else 
+      return X509_V_OK;
+  }
hunk ./libsofia-sip-ua/tport/tport_tls.c 420
+  tls->subject = su_strlst_create(tls->home);
hunk ./libsofia-sip-ua/tport/tport_tls.c 422
-    tls->subject = su_strlst_create(tls->home);
+    return X509_V_ERR_OUT_OF_MEM;
+
+  extcount = X509_get_ext_count(cert);
hunk ./libsofia-sip-ua/tport/tport_tls.c 449
+      if (strcmp(value->name, "IP") == 0)
+        su_strlst_dup_append(tls->subject, value->value);
hunk ./libsofia-sip-ua/tport/tport_tls.c 453
-       char const *url = strchr(uri, ':');
-       if (url++)
-         su_strlst_append(tls->subject, url);
+       char const *uname = strchr(uri, ':');
+       if (uname++)
+         su_strlst_append(tls->subject, uname);
hunk ./libsofia-sip-ua/tport/tport_tls.c 490
-    return X509_V_OK;
-  else if (!tls->accept && !tls->verify_outgoing)
-    return X509_V_OK;
+    return X509_V_OK; /* do not reject incoming connections */
+  if (tls->accept)
+    return error;     /* No subject matching on incoming connections */
+  if (!tls->accept && !tls->verify_outgoing)
+    return X509_V_OK; /* do not reject outgoing connections */
+  if (tls->verified && subject && tport_subject_search(subject, tls->subject))
+    return X509_V_OK; /* Subject match found in verified certificate chain */
+
hunk ./libsofia-sip-ua/tport/tport_tls.c 738
-    int ret, status;
+    int ret, status, ok;
hunk ./libsofia-sip-ua/tport/tport_tls.c 760
-       if ( tls_post_connection_check(tls) == X509_V_OK ) {
+       ok = tls_post_connection_check(tls, self->tp_name->tpn_subject);
+        if ( ok == X509_V_OK ) {
hunk ./libsofia-sip-ua/tport/tport_tls.c 781
-         self->tp_subjects = tls->subject == NULL ? NULL :
-                             su_strlst_dup(self->tp_home, tls->subject); 
+         self->tp_subjects = tls->subject;
hunk ./libsofia-sip-ua/tport/tport_tls.h 81
-tls_t *tls_init_slave(tls_t *tls_master, int sock);
-tls_t *tls_init_client(tls_t *tls_master, int sock);
+tls_t *tls_init_secondary(tls_t *tls_master, int sock, int accept);
hunk ./libsofia-sip-ua/tport/tport_type_tls.c 97
-#if notyet
-static void tport_tls_deliver(tport_t *self, msg_t *msg, su_time_t now);
-#endif
hunk ./libsofia-sip-ua/tport/tport_type_tls.c 246
-  if (accepted) {
-    tlstp->tlstp_context = tls_init_slave(master, socket);
-    if (!tlstp->tlstp_context)
-      return *return_reason = "tls_init_slave", -1;
-  }
+  tlstp->tlstp_context = tls_init_secondary(master, socket, accepted);
+  if (!tlstp->tlstp_context)
+    return *return_reason = "tls_init_slave", -1;
hunk ./libsofia-sip-ua/tport/tport_type_tls.c 436
-  tport_tls_primary_t *tlspri = (tport_tls_primary_t *)self->tp_pri;
hunk ./libsofia-sip-ua/tport/tport_type_tls.c 442
-  if (tlstp->tlstp_context == NULL) {
-    tls_t *master = tlspri->tlspri_master;
-    tlstp->tlstp_context = tls_init_client(master, self->tp_socket);
-    if (!tlstp->tlstp_context)
-      return -1;
-  }
-
hunk ./libsofia-sip-ua/tport/tport_type_tls.c 549
-    tport_tls_t *tlstp = (tport_tls_t *)self;
-    tport_tls_primary_t *tlspri = (tport_tls_primary_t *)self->tp_pri;
hunk ./libsofia-sip-ua/tport/tport_type_tls.c 562
-      tlstp->tlstp_context = tls_init_slave(tlspri->tlspri_master, s);
-
hunk ./libsofia-sip-ua/tport/tport_type_tls.c 625
-  if (tport_setname(self, tpn->tpn_proto, ai, tpn->tpn_canon) != -1
-      &&
-      tport_register_secondary(self, tls_connect, events) != -1) {
-    tport_tls_t *tlstp = (tport_tls_t *)self;
-    tport_tls_primary_t *tlspri = (tport_tls_primary_t *)self->tp_pri;
-    tlstp->tlstp_context = tls_init_client(tlspri->tlspri_master, s);
-  }
-  else
+  if (tport_setname(self, tpn->tpn_proto, ai, tpn->tpn_canon) == -1)
+    goto sys_error;
+  else if (tport_register_secondary(self, tls_connect, events) == -1)
hunk ./libsofia-sip-ua/tport/tport_type_tls.c 629
+  else if (tpn->tpn_subject) {
+    self->tp_name->tpn_subject = su_strdup(self->tp_home, tpn->tpn_subject);
+    if (!self->tp_name->tpn_subject)
+      goto sys_error;
+  }
}

Context:

[tport_type_tls.c: no tport_tls_deliver() yet
Pekka Pessi <first.l...@nokia.com>**20090105124324] 
[tport_tls.c: silences warnings on signedness
Pekka Pessi <first.l...@nokia.com>**20090105124304] 
[tport_tls.c: su_home_new() already zeros the allocated memory
Pekka Pessi <first.l...@nokia.com>**20090105124209] 
[nua_session.c: default to initiate session refreshes
Pekka Pessi <first.l...@nokia.com>**20090105123112
 
 Use local refresher unless remote end explicitly indicates that it takes
 care of refreshing the session. Bug reported and initial patch by Timo
 Bruhn.
] 
[RELEASE: added Jarod's description of TLS improvements
Pekka Pessi <first.l...@nokia.com>**20090105102201] 
[su_kqueue_port.c: explicit cast from int to (void *)
Michael Jerris <m...@jerris.com>**20090105100939
 
 Fix silly compiler warning caused by freebsd not making int same size as
 void* on some 64 bit amd (SFSIP-113).
] 
[tport_logging.c: do not use stamp as format string
Pekka Pessi <first.l...@nokia.com>**20081219165102
 
 Original patch by Mike Jerris.
] 
[nta.c: be consistent with maxsize and max_proceeding types
Pekka Pessi <first.l...@nokia.com>**20081219143853
 
 Original patch by Mike Jerris
] 
[su_alloc.c: always unlock home before destroying mutexes
Pekka Pessi <first.l...@nokia.com>**20081215151620] 
[sresolv: made sres_record_class static
Pekka Pessi <first.l...@nokia.com>**20081215165706
 
 Should never been global.
] 
[test_nua.c: made usage static
Pekka Pessi <first.l...@nokia.com>**20081215164317] 
[RELEASE: mention removed globals
Pekka Pessi <first.l...@nokia.com>**20081215165436] 
[sofia-resolv/sres_cache.h: added prototype for sres_cache_clean()
Pekka Pessi <first.l...@nokia.com>**20081215165021] 
[sofia-sip/heap.h: added protype for su_smoothsort()
Pekka Pessi <first.l...@nokia.com>**20081215163340] 
[su_tag.h: added prototype for tl_vllen()
Pekka Pessi <first.l...@nokia.com>**20081215163316] 
[su_tag_class.h: added prototypes for tag functions
Pekka Pessi <first.l...@nokia.com>**20081215163255
 
 Protypes for t_filter(), t_null_filter(), t_end_filter(),
 t_socket_snprintf(), t_socket_ref_set() have been missing.
] 
[Early TLS Handshake and Verification
Jarod Neuner <janeu...@networkharbor.com>**20081216221937
 
 tport_type_tls.c:
 * tport_tls_accept():
   - Replaces tport_accept for incoming TLS connections.
 * tport_tls_connect():
   - Replaces tport_base_connect() for outgoing TLS connections.
 
 tport_tls.c:
 * tls_t now use a memory home instead of malloc.
 * removed tls_check_hosts()
 * tls_connect():
   - Replaces tport_base_connect for TLS connection setup.
   - Completes TLS handshake and verifies peer certificates.
   - Destroys suspect TLS connections before sending/receiving payload.
   - Populates a su_strlst_t with subjects from the peer certificate.
 
 tport.c:
 * tport_is_verified()
   - true if peer certificate validated successfully
 * tport_delivered_from_subjects()
   - Certificate subjects listed in the peer certificate.
 
] 
[Helper functions for vtp_connect and vtp_wakeup_pri.
Jarod Neuner <janeu...@networkharbor.com>**20081216175826
 
 - Expose tport_setname() and tport_wakeup() via tport_internal.h
 - Add tport_register_secondary() for adding secondaries to a root, and
   to alleviate the need to export tprb_append.
 
] 
[nta: NULL host and port in user Via are filled automaticaly
Stas Maximov <smaxi...@ieee.org>**20081215143145
 
 NULL host or port in user-supplied Via header will be filled
 automaticaly by NTA, just like branch and rport params.
 
 Added related test case to test_nta_api.c.
] 
[su_taglist.c. removed globals which should have been static in first place
Pekka Pessi <first.l...@nokia.com>**20081211173213
 
 - t_null_next(), t_null_move(), t_null_dup(), t_null_copy(), t_null_find()
 - t_skip_next(), t_skip_move(), t_skip_len(), t_skip_dup(), t_skip_filter()
 - t_next_next(), t_next_move(), t_next_len(), t_next_dup(), t_next_filter()
] 
[su: removed private functions accidentally declared as globals
Pekka Pessi <first.l...@nokia.com>**20081208145904
 
 su_t64_to_time(), mutex_trylocker(), su_port_set_system_preferences()
] 
[sofia-sip/su_uniqueid.h: proper prototype for su_random()
Pekka Pessi <first.l...@nokia.com>**20081211173249] 
[su/addrinfo.c, su/localinfo.c: made usage() static
Pekka Pessi <first.l...@nokia.com>**20081211173029
 
 Make -Wmissing-prototypes happy.
] 
[sdp_print.c: print sdptl in lowercase, too
Pekka Pessi <first.l...@nokia.com>**20081211120209] 
[RELEASE, configure.ac: opening development head
Pekka Pessi <first.l...@nokia.com>**20081209171108] 
[TAG rel-sofia-sip-1_12_10
Pekka Pessi <first.l...@nokia.com>**20081209122326] 
Patch bundle hash:
176dd7a52efc58a954df69dcfada23aaf201a917
------------------------------------------------------------------------------
_______________________________________________
Sofia-sip-devel mailing list
Sofia-sip-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sofia-sip-devel

Reply via email to