struct ckch_node {
struct cert_key_and_chain *ckch;
int multi; /* is it a multi-cert bundle ? */
+ struct ebmb_node node;
+ char path[0];
};
+/*
+ * tree used to store the ckchn ordered by filename/bundle name
+ */
+struct eb_root ckchn_tree = EB_ROOT_UNIQUE;
+
#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
struct key_combo_ctx {
}
+/*
+ * lookup a path into the ckchn tree.
+ */
+static inline struct ckch_node *ckchn_lookup(char *path)
+{
+ struct ebmb_node *eb;
+
+ eb = ebst_lookup(&ckchn_tree, path);
+ if (!eb)
+ return NULL;
+
+ return ebmb_entry(eb, struct ckch_node, node);
+}
+
/*
* This function allocate a ckch_node and populate it with certificates from files.
*/
char fp[MAXPATHLEN+1] = {0};
int n = 0;
- ckchn = calloc(1, sizeof(*ckchn));
+ ckchn = calloc(1, sizeof(*ckchn) + strlen(path) + 1);
if (!ckchn) {
memprintf(err, "%sunable to allocate memory.\n", err && *err ? *err : "");
goto end;
if (ssl_sock_load_crt_file_into_ckch(path, ckchn->ckch, err) == 1)
goto end;
+ /* insert into the ckchn tree */
+ memcpy(ckchn->path, path, strlen(path) + 1);
+ ebst_insert(&ckchn_tree, &ckchn->node);
} else {
int found = 0;
memprintf(err, "%sDidn't find any certificate.\n", err && *err ? *err : "");
goto end;
}
+ /* insert into the ckchn tree */
+ memcpy(ckchn->path, path, strlen(path) + 1);
+ ebst_insert(&ckchn_tree, &ckchn->node);
}
return ckchn;
end:
- if (ckchn)
+ if (ckchn) {
free(ckchn->ckch);
+ ebmb_delete(&ckchn->node);
+ }
+
free(ckchn);
return NULL;
int j;
#endif
+ if ((ckchn = ckchn_lookup(path))) {
+
+ /* we found the ckchn in the tree, we can use it directly */
+ if (ckchn->multi)
+ return ssl_sock_load_multi_ckchn(path, ckchn, bind_conf, NULL, NULL, 0, err);
+ else
+ return ssl_sock_load_ckchn(path, ckchn, bind_conf, NULL, NULL, 0, err);
+
+ }
+
if (stat(path, &buf) == 0) {
dir = opendir(path);
if (!dir) {
}
snprintf(fp, sizeof(fp), "%s/%s", path, dp);
- ckchn = ckchn_load_cert_file(fp, 1, err);
+ if ((ckchn = ckchn_lookup(fp)) == NULL)
+ ckchn = ckchn_load_cert_file(fp, 1, err);
if (!ckchn)
return 1;
cfgerr += ssl_sock_load_multi_ckchn(fp, ckchn, bind_conf, NULL, NULL, 0, err);
}
#endif
- ckchn = ckchn_load_cert_file(fp, 0, err);
+ if ((ckchn = ckchn_lookup(fp)) == NULL)
+ ckchn = ckchn_load_cert_file(fp, 0, err);
if (!ckchn)
return 1;
cfgerr += ssl_sock_load_ckchn(fp, ckchn, bind_conf, NULL, NULL, 0, err);