session server tls BUGFIX check all matching CTNs
diff --git a/src/session_server_tls.c b/src/session_server_tls.c
index 040836f..9b9b3f1 100644
--- a/src/session_server_tls.c
+++ b/src/session_server_tls.c
@@ -215,7 +215,7 @@
         *username = strdup(common_name);
         if (!*username) {
             ERRMEM;
-            return 1;
+            return -1;
         }
         free(subject);
     } else {
@@ -240,7 +240,7 @@
 #endif
                 if (!*username) {
                     ERRMEM;
-                    return 1;
+                    return -1;
                 }
                 break;
             }
@@ -255,7 +255,7 @@
 #endif
                 if (!*username) {
                     ERRMEM;
-                    return 1;
+                    return -1;
                 }
                 break;
             }
@@ -314,7 +314,7 @@
 
 /* return: 0 - OK, 1 - no match, -1 - error */
 static int
-nc_tls_cert_to_name(struct nc_ctn *ctn_first, X509 *cert, NC_TLS_CTN_MAPTYPE *map_type, const char **name)
+nc_tls_cert_to_name(struct nc_session *session, struct nc_ctn *ctn_first, X509 *cert)
 {
     char *digest_md5 = NULL, *digest_sha1 = NULL, *digest_sha224 = NULL;
     char *digest_sha256 = NULL, *digest_sha384 = NULL, *digest_sha512 = NULL;
@@ -322,18 +322,23 @@
     unsigned int buf_len = 64;
     int ret = 0;
     struct nc_ctn *ctn;
+    NC_TLS_CTN_MAPTYPE map_type;
+    char *username = NULL;
 
     if (!buf) {
         ERRMEM;
         return -1;
     }
 
-    if (!ctn_first || !cert || !map_type || !name) {
+    if (!session || !ctn_first || !cert) {
         free(buf);
         return -1;
     }
 
     for (ctn = ctn_first; ctn; ctn = ctn->next) {
+        /* reset map_type */
+        map_type = NC_TLS_CTN_UNKNOWN;
+
         /* first make sure the entry is valid */
         if (!ctn->fingerprint || !ctn->map_type || ((ctn->map_type == NC_TLS_CTN_SPECIFIED) && !ctn->name)) {
             VRB(NULL, "Cert verify CTN: entry with id %u not valid, skipping.", ctn->id);
@@ -352,13 +357,9 @@
             }
 
             if (!strcasecmp(ctn->fingerprint + 3, digest_md5)) {
-                /* we got ourselves a winner! */
+                /* we got ourselves a potential winner! */
                 VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
-                *map_type = ctn->map_type;
-                if (ctn->map_type == NC_TLS_CTN_SPECIFIED) {
-                    *name = ctn->name;
-                }
-                break;
+                map_type = ctn->map_type;
             }
 
             /* SHA-1 */
@@ -373,13 +374,9 @@
             }
 
             if (!strcasecmp(ctn->fingerprint + 3, digest_sha1)) {
-                /* we got ourselves a winner! */
+                /* we got ourselves a potential winner! */
                 VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
-                *map_type = ctn->map_type;
-                if (ctn->map_type == NC_TLS_CTN_SPECIFIED) {
-                    *name = ctn->name;
-                }
-                break;
+                map_type = ctn->map_type;
             }
 
             /* SHA-224 */
@@ -394,13 +391,9 @@
             }
 
             if (!strcasecmp(ctn->fingerprint + 3, digest_sha224)) {
-                /* we got ourselves a winner! */
+                /* we got ourselves a potential winner! */
                 VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
-                *map_type = ctn->map_type;
-                if (ctn->map_type == NC_TLS_CTN_SPECIFIED) {
-                    *name = ctn->name;
-                }
-                break;
+                map_type = ctn->map_type;
             }
 
             /* SHA-256 */
@@ -415,13 +408,9 @@
             }
 
             if (!strcasecmp(ctn->fingerprint + 3, digest_sha256)) {
-                /* we got ourselves a winner! */
+                /* we got ourselves a potential winner! */
                 VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
-                *map_type = ctn->map_type;
-                if (ctn->map_type == NC_TLS_CTN_SPECIFIED) {
-                    *name = ctn->name;
-                }
-                break;
+                map_type = ctn->map_type;
             }
 
             /* SHA-384 */
@@ -436,13 +425,9 @@
             }
 
             if (!strcasecmp(ctn->fingerprint + 3, digest_sha384)) {
-                /* we got ourselves a winner! */
+                /* we got ourselves a potential winner! */
                 VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
-                *map_type = ctn->map_type;
-                if (ctn->map_type == NC_TLS_CTN_SPECIFIED) {
-                    *name = ctn->name;
-                }
-                break;
+                map_type = ctn->map_type;
             }
 
             /* SHA-512 */
@@ -457,18 +442,45 @@
             }
 
             if (!strcasecmp(ctn->fingerprint + 3, digest_sha512)) {
-                /* we got ourselves a winner! */
+                /* we got ourselves a potential winner! */
                 VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
-                *map_type = ctn->map_type;
-                if (ctn->map_type == NC_TLS_CTN_SPECIFIED) {
-                    *name = ctn->name;
-                }
-                break;
+                map_type = ctn->map_type;
             }
 
             /* unknown */
         } else {
             WRN(NULL, "Unknown fingerprint algorithm used (%s), skipping.", ctn->fingerprint);
+            continue;
+        }
+
+        if (map_type != NC_TLS_CTN_UNKNOWN) {
+            /* found a fingerprint match */
+            if (map_type == NC_TLS_CTN_SPECIFIED) {
+                /* specified -> get username from the ctn entry */
+                session->username = strdup(ctn->name);
+                if (!session->username) {
+                    ERRMEM;
+                    ret = -1;
+                    goto cleanup;
+                }
+            } else {
+                /* try to get the username from the cert with this ctn's map type */
+                ret = nc_tls_ctn_get_username_from_cert(session->opts.server.client_cert, map_type, &username);
+                if (ret == -1) {
+                    /* fatal error */
+                    goto cleanup;
+                } else if (ret) {
+                    /* didn't get username, try next ctn entry */
+                    continue;
+                }
+
+                /* success */
+                session->username = username;
+            }
+
+            /* matching fingerprint found and username obtained, success */
+            ret = 0;
+            goto cleanup;
         }
     }
 
@@ -507,8 +519,6 @@
     const ASN1_INTEGER *serial;
     int i, n, rc, depth;
     char *cp;
-    const char *username = NULL;
-    NC_TLS_CTN_MAPTYPE map_type = 0;
     const ASN1_TIME *last_update = NULL, *next_update = NULL;
 
     /* get the thread session */
@@ -655,8 +665,7 @@
     }
 
     /* cert-to-name */
-    rc = nc_tls_cert_to_name(opts->ctn, cert, &map_type, &username);
-
+    rc = nc_tls_cert_to_name(session, opts->ctn, cert);
     if (rc) {
         if (rc == -1) {
             /* fatal error */
@@ -666,20 +675,6 @@
         goto fail;
     }
 
-    /* cert-to-name match, now to extract the specific field from the peer cert */
-    if (map_type == NC_TLS_CTN_SPECIFIED) {
-        session->username = strdup(username);
-    } else {
-        rc = nc_tls_ctn_get_username_from_cert(session->opts.server.client_cert, map_type, &cp);
-        if (rc) {
-            if (rc == -1) {
-                depth = 0;
-            }
-            goto fail;
-        }
-        session->username = cp;
-    }
-
     VRB(NULL, "Cert verify CTN: new client username recognized as \"%s\".", session->username);
 
     if (server_opts.user_verify_clb && !server_opts.user_verify_clb(session)) {
@@ -721,8 +716,6 @@
     long serial;
     int i, n, rc, depth;
     char *cp;
-    const char *username = NULL;
-    NC_TLS_CTN_MAPTYPE map_type = 0;
     ASN1_TIME *last_update = NULL, *next_update = NULL;
 
     /* get the thread session */
@@ -869,8 +862,7 @@
     }
 
     /* cert-to-name */
-    rc = nc_tls_cert_to_name(opts->ctn, cert, &map_type, &username);
-
+    rc = nc_tls_cert_to_name(session, opts->ctn, cert);
     if (rc) {
         if (rc == -1) {
             /* fatal error */
@@ -880,20 +872,6 @@
         goto fail;
     }
 
-    /* cert-to-name match, now to extract the specific field from the peer cert */
-    if (map_type == NC_TLS_CTN_SPECIFIED) {
-        session->username = strdup(username);
-    } else {
-        rc = nc_tls_ctn_get_username_from_cert(session->opts.server.client_cert, map_type, &cp);
-        if (rc) {
-            if (rc == -1) {
-                depth = 0;
-            }
-            goto fail;
-        }
-        session->username = cp;
-    }
-
     VRB(session, "Cert verify CTN: new client username recognized as \"%s\".", session->username);
 
     if (server_opts.user_verify_clb && !server_opts.user_verify_clb(session)) {