MINOR: ssl: free the crtlist and the ckch during the deinit()

Add some functions to deinit the whole crtlist and ckch architecture.

It will free all crtlist, crtlist_entry, ckch_store, ckch_inst and their
associated SNI, ssl_conf and SSL_CTX.

The SSL_CTX in the default_ctx and initial_ctx still needs to be free'd
separately.
diff --git a/include/haproxy/ssl_ckch.h b/include/haproxy/ssl_ckch.h
index 919389d..46b9167 100644
--- a/include/haproxy/ssl_ckch.h
+++ b/include/haproxy/ssl_ckch.h
@@ -61,5 +61,7 @@
 int ckch_inst_new_load_store(const char *path, struct ckch_store *ckchs, struct bind_conf *bind_conf,
                              struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount, struct ckch_inst **ckchi, char **err);
 
+void ckch_deinit();
+
 #endif /* USE_OPENSSL */
 #endif /* _HAPROXY_SSL_CRTLIST_H */
diff --git a/include/haproxy/ssl_crtlist.h b/include/haproxy/ssl_crtlist.h
index 1650ddc..c772839 100644
--- a/include/haproxy/ssl_crtlist.h
+++ b/include/haproxy/ssl_crtlist.h
@@ -41,5 +41,8 @@
 int crtlist_parse_line(char *line, char **crt_path, struct crtlist_entry *entry, const char *file, int linenum, char **err);
 int crtlist_parse_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, struct crtlist **crtlist, char **err);
 int crtlist_load_cert_dir(char *path, struct bind_conf *bind_conf, struct crtlist **crtlist, char **err);
+
+void crtlist_deinit();
+
 #endif /* USE_OPENSSL */
 #endif /* _HAPROXY_SSL_CRTLIST_H */
diff --git a/src/haproxy.c b/src/haproxy.c
index 802a88f..9e8ffa9 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -2785,6 +2785,10 @@
 			free(l);
 		}
 
+		/* SSL storage */
+		crtlist_deinit(); /* must be free'd before the ckchs */
+		ckch_deinit();
+
 		/* Release unused SSL configs. */
 		list_for_each_entry_safe(bind_conf, bind_back, &p->conf.bind, by_fe) {
 			if (bind_conf->xprt->destroy_bind_conf)
diff --git a/src/ssl_ckch.c b/src/ssl_ckch.c
index 7a92934..537c7ea 100644
--- a/src/ssl_ckch.c
+++ b/src/ssl_ckch.c
@@ -1889,6 +1889,19 @@
 	return cli_dynerr(appctx, err);
 }
 
+void ckch_deinit()
+{
+	struct eb_node *node, *next;
+	struct ckch_store *store;
+
+	node = eb_first(&ckchs_tree);
+	while (node) {
+		next = eb_next(node);
+		store = ebmb_entry(node, struct ckch_store, node);
+		ckch_store_free(store);
+		node = next;
+	}
+}
 
 /* register cli keywords */
 static struct cli_kw_list cli_kws = {{ },{
diff --git a/src/ssl_crtlist.c b/src/ssl_crtlist.c
index 0fbd3f0..1d282a9 100644
--- a/src/ssl_crtlist.c
+++ b/src/ssl_crtlist.c
@@ -1265,6 +1265,21 @@
 }
 
 
+/* unlink and free all crt-list and crt-list entries */
+void crtlist_deinit()
+{
+	struct eb_node *node, *next;
+	struct crtlist *crtlist;
+
+	node = eb_first(&crtlists_tree);
+	while (node) {
+		next = eb_next(node);
+		crtlist = ebmb_entry(node, struct crtlist, node);
+		crtlist_free(crtlist);
+		node = next;
+	}
+}
+
 
 /* register cli keywords */
 static struct cli_kw_list cli_kws = {{ },{